diff --git a/MIT.LICENSE b/MIT.LICENSE new file mode 100644 index 0000000..aff8ed4 --- /dev/null +++ b/MIT.LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008-2014 Pivotal Labs + +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/linked_list/00-implement.js b/linked_list/00-implement.js new file mode 100644 index 0000000..2e35559 --- /dev/null +++ b/linked_list/00-implement.js @@ -0,0 +1,49 @@ +'use strict'; + +class LinkedListNode{ + constructor(val){ + this._value = val; + } + get value() { + return this._value; + } + set value(val) { + this._value = val; + } + get next(){ + return this._next; + } + set next(nxt){ + this._next = nxt; + } +} + +class LinkedList { + constructor(){ + this.sentinel = new LinkedListNode(null); + } + get head(){ + return this.sentinel.next; + } + insert(val) { + var node = new LinkedListNode(val); + node.next = this.sentinel.next; + this.sentinel.next = node; + } + delete(){ + if(this.sentinel.next){ + this.sentinel.next=this.sentinel.next.next; + } + } +} + + +// var ll = new LinkedList(); +// ll.insert(1); +// console.log(ll); +// ll.insert(2); +// console.log(ll); +// ll.insert(2); + + +module.exports.LinkedList = LinkedList; \ No newline at end of file diff --git a/linked_list/01-find-nth-node-value.js b/linked_list/01-find-nth-node-value.js new file mode 100644 index 0000000..b383a57 --- /dev/null +++ b/linked_list/01-find-nth-node-value.js @@ -0,0 +1,17 @@ +// Write a function that takes 2 arguments; a linked list (ll) and on integer(n). +// The function should return the value of the nth node in the linked list. +// +// Assume that the linked is in non-empty and is of length at least 'n' + +var ll = require('./00-implement'); + +function valueOfNthNode(ll, n){ + var currentNode = ll.head; + for(var i=0;i=0.2.0", + "highlight.js": "~8.0.0", + "underscore": "~1.5.2", + "docco": "~0.6.2" + }, + "author": { + "name": "Jeremy Ashkenas" + }, + "ignore": [ + "test" + ] +} diff --git a/node_modules/coffee-script/lib/coffee-script/browser.js b/node_modules/coffee-script/lib/coffee-script/browser.js new file mode 100644 index 0000000..abf75d3 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/browser.js @@ -0,0 +1,135 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var CoffeeScript, compile, runScripts, + 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; }; + + CoffeeScript = require('./coffee-script'); + + CoffeeScript.require = require; + + compile = CoffeeScript.compile; + + CoffeeScript["eval"] = function(code, options) { + if (options == null) { + options = {}; + } + if (options.bare == null) { + options.bare = true; + } + return eval(compile(code, options)); + }; + + CoffeeScript.run = function(code, options) { + if (options == null) { + options = {}; + } + options.bare = true; + options.shiftLine = true; + return Function(compile(code, options))(); + }; + + if (typeof window === "undefined" || window === null) { + return; + } + + if ((typeof btoa !== "undefined" && btoa !== null) && (typeof JSON !== "undefined" && JSON !== null) && (typeof unescape !== "undefined" && unescape !== null) && (typeof encodeURIComponent !== "undefined" && encodeURIComponent !== null)) { + compile = function(code, options) { + var js, ref, v3SourceMap; + if (options == null) { + options = {}; + } + options.sourceMap = true; + options.inline = true; + ref = CoffeeScript.compile(code, options), js = ref.js, v3SourceMap = ref.v3SourceMap; + return js + "\n//# sourceMappingURL=data:application/json;base64," + (btoa(unescape(encodeURIComponent(v3SourceMap)))) + "\n//# sourceURL=coffeescript"; + }; + } + + CoffeeScript.load = function(url, callback, options, hold) { + var xhr; + if (options == null) { + options = {}; + } + if (hold == null) { + hold = false; + } + options.sourceFiles = [url]; + xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP') : new window.XMLHttpRequest(); + xhr.open('GET', url, true); + if ('overrideMimeType' in xhr) { + xhr.overrideMimeType('text/plain'); + } + xhr.onreadystatechange = function() { + var param, ref; + if (xhr.readyState === 4) { + if ((ref = xhr.status) === 0 || ref === 200) { + param = [xhr.responseText, options]; + if (!hold) { + CoffeeScript.run.apply(CoffeeScript, param); + } + } else { + throw new Error("Could not load " + url); + } + if (callback) { + return callback(param); + } + } + }; + return xhr.send(null); + }; + + runScripts = function() { + var coffees, coffeetypes, execute, fn, i, index, j, len, s, script, scripts; + scripts = window.document.getElementsByTagName('script'); + coffeetypes = ['text/coffeescript', 'text/literate-coffeescript']; + coffees = (function() { + var j, len, ref, results; + results = []; + for (j = 0, len = scripts.length; j < len; j++) { + s = scripts[j]; + if (ref = s.type, indexOf.call(coffeetypes, ref) >= 0) { + results.push(s); + } + } + return results; + })(); + index = 0; + execute = function() { + var param; + param = coffees[index]; + if (param instanceof Array) { + CoffeeScript.run.apply(CoffeeScript, param); + index++; + return execute(); + } + }; + fn = function(script, i) { + var options, source; + options = { + literate: script.type === coffeetypes[1] + }; + source = script.src || script.getAttribute('data-src'); + if (source) { + return CoffeeScript.load(source, function(param) { + coffees[i] = param; + return execute(); + }, options, true); + } else { + options.sourceFiles = ['embedded']; + return coffees[i] = [script.innerHTML, options]; + } + }; + for (i = j = 0, len = coffees.length; j < len; i = ++j) { + script = coffees[i]; + fn(script, i); + } + return execute(); + }; + + if (window.addEventListener) { + window.addEventListener('DOMContentLoaded', runScripts, false); + } else { + window.attachEvent('onload', runScripts); + } + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/cake.js b/node_modules/coffee-script/lib/coffee-script/cake.js new file mode 100644 index 0000000..fe227b5 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/cake.js @@ -0,0 +1,114 @@ +// Generated by CoffeeScript 1.10.0 +(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'); + + CoffeeScript.register(); + + 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, e, error, 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 (error) { + e = error; + 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 (fs.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/node_modules/coffee-script/lib/coffee-script/coffee-script.js b/node_modules/coffee-script/lib/coffee-script/coffee-script.js new file mode 100644 index 0000000..1a30d49 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/coffee-script.js @@ -0,0 +1,376 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var Lexer, SourceMap, base, compile, ext, formatSourcePosition, fs, getSourceMap, helpers, i, len, lexer, parser, path, ref, sourceMaps, vm, withPrettyErrors, + hasProp = {}.hasOwnProperty, + 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; }; + + fs = require('fs'); + + vm = require('vm'); + + path = require('path'); + + Lexer = require('./lexer').Lexer; + + parser = require('./parser').parser; + + helpers = require('./helpers'); + + SourceMap = require('./sourcemap'); + + exports.VERSION = '1.10.0'; + + exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md']; + + exports.helpers = helpers; + + withPrettyErrors = function(fn) { + return function(code, options) { + var err, error; + if (options == null) { + options = {}; + } + try { + return fn.call(this, code, options); + } catch (error) { + err = error; + if (typeof code !== 'string') { + throw err; + } + throw helpers.updateSyntaxError(err, code, options.filename); + } + }; + }; + + exports.compile = compile = withPrettyErrors(function(code, options) { + var answer, currentColumn, currentLine, extend, fragment, fragments, header, i, js, len, map, merge, newLines, token, tokens; + merge = helpers.merge, extend = helpers.extend; + options = extend({}, options); + if (options.sourceMap) { + map = new SourceMap; + } + tokens = lexer.tokenize(code, options); + options.referencedVars = (function() { + var i, len, results; + results = []; + for (i = 0, len = tokens.length; i < len; i++) { + token = tokens[i]; + if (token.variable) { + results.push(token[1]); + } + } + return results; + })(); + fragments = parser.parse(tokens).compileToFragments(options); + currentLine = 0; + if (options.header) { + currentLine += 1; + } + if (options.shiftLine) { + currentLine += 1; + } + currentColumn = 0; + js = ""; + for (i = 0, len = fragments.length; i < len; i++) { + fragment = fragments[i]; + if (options.sourceMap) { + if (fragment.locationData && !/^[;\s]*$/.test(fragment.code)) { + map.add([fragment.locationData.first_line, fragment.locationData.first_column], [currentLine, currentColumn], { + noReplace: true + }); + } + newLines = helpers.count(fragment.code, "\n"); + currentLine += newLines; + if (newLines) { + currentColumn = fragment.code.length - (fragment.code.lastIndexOf("\n") + 1); + } else { + currentColumn += fragment.code.length; + } + } + js += fragment.code; + } + if (options.header) { + header = "Generated by CoffeeScript " + this.VERSION; + js = "// " + header + "\n" + js; + } + if (options.sourceMap) { + answer = { + js: js + }; + answer.sourceMap = map; + answer.v3SourceMap = map.generate(options, code); + return answer; + } else { + return js; + } + }); + + exports.tokens = withPrettyErrors(function(code, options) { + return lexer.tokenize(code, options); + }); + + exports.nodes = withPrettyErrors(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 answer, dir, mainModule, ref; + if (options == null) { + options = {}; + } + mainModule = require.main; + mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.'; + mainModule.moduleCache && (mainModule.moduleCache = {}); + dir = options.filename ? path.dirname(fs.realpathSync(options.filename)) : fs.realpathSync('.'); + mainModule.paths = require('module')._nodeModulePaths(dir); + if (!helpers.isCoffee(mainModule.filename) || require.extensions) { + answer = compile(code, options); + code = (ref = answer.js) != null ? ref : answer; + } + return mainModule._compile(code, mainModule.filename); + }; + + exports["eval"] = function(code, options) { + var Module, _module, _require, createContext, i, isContext, js, k, len, o, r, ref, ref1, ref2, ref3, sandbox, v; + if (options == null) { + options = {}; + } + if (!(code = code.trim())) { + return; + } + createContext = (ref = vm.Script.createContext) != null ? ref : vm.createContext; + isContext = (ref1 = vm.isContext) != null ? ref1 : function(ctx) { + return options.sandbox instanceof createContext().constructor; + }; + if (createContext) { + if (options.sandbox != null) { + if (isContext(options.sandbox)) { + sandbox = options.sandbox; + } else { + sandbox = createContext(); + ref2 = options.sandbox; + for (k in ref2) { + if (!hasProp.call(ref2, k)) continue; + v = ref2[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; + ref3 = Object.getOwnPropertyNames(require); + for (i = 0, len = ref3.length; i < len; i++) { + r = ref3[i]; + if (r !== 'paths' && r !== 'arguments' && r !== 'caller') { + _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); + } + }; + + exports.register = function() { + return require('./register'); + }; + + if (require.extensions) { + ref = this.FILE_EXTENSIONS; + for (i = 0, len = ref.length; i < len; i++) { + ext = ref[i]; + if ((base = require.extensions)[ext] == null) { + base[ext] = function() { + throw new Error("Use CoffeeScript.register() or require the coffee-script/register module to require " + ext + " files."); + }; + } + } + } + + exports._compileFile = function(filename, sourceMap) { + var answer, err, error, raw, stripped; + if (sourceMap == null) { + sourceMap = false; + } + raw = fs.readFileSync(filename, 'utf8'); + stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw; + try { + answer = compile(stripped, { + filename: filename, + sourceMap: sourceMap, + literate: helpers.isLiterate(filename) + }); + } catch (error) { + err = error; + throw helpers.updateSyntaxError(err, stripped, filename); + } + return answer; + }; + + lexer = new Lexer; + + parser.lexer = { + lex: function() { + var tag, token; + token = parser.tokens[this.pos++]; + if (token) { + tag = token[0], this.yytext = token[1], this.yylloc = token[2]; + parser.errorToken = token.origin || token; + this.yylineno = this.yylloc.first_line; + } else { + tag = ''; + } + return tag; + }, + setInput: function(tokens) { + parser.tokens = tokens; + return this.pos = 0; + }, + upcomingInput: function() { + return ""; + } + }; + + parser.yy = require('./nodes'); + + parser.yy.parseError = function(message, arg) { + var errorLoc, errorTag, errorText, errorToken, token, tokens; + token = arg.token; + errorToken = parser.errorToken, tokens = parser.tokens; + errorTag = errorToken[0], errorText = errorToken[1], errorLoc = errorToken[2]; + errorText = (function() { + switch (false) { + case errorToken !== tokens[tokens.length - 1]: + return 'end of input'; + case errorTag !== 'INDENT' && errorTag !== 'OUTDENT': + return 'indentation'; + case errorTag !== 'IDENTIFIER' && errorTag !== 'NUMBER' && errorTag !== 'STRING' && errorTag !== 'STRING_START' && errorTag !== 'REGEX' && errorTag !== 'REGEX_START': + return errorTag.replace(/_START$/, '').toLowerCase(); + default: + return helpers.nameWhitespaceCharacter(errorText); + } + })(); + return helpers.throwSyntaxError("unexpected " + errorText, errorLoc); + }; + + formatSourcePosition = function(frame, getSourceMapping) { + var as, column, fileLocation, fileName, functionName, isConstructor, isMethodCall, line, methodName, source, tp, typeName; + fileName = void 0; + fileLocation = ''; + if (frame.isNative()) { + fileLocation = "native"; + } else { + if (frame.isEval()) { + fileName = frame.getScriptNameOrSourceURL(); + if (!fileName) { + fileLocation = (frame.getEvalOrigin()) + ", "; + } + } else { + fileName = frame.getFileName(); + } + fileName || (fileName = ""); + line = frame.getLineNumber(); + column = frame.getColumnNumber(); + source = getSourceMapping(fileName, line, column); + fileLocation = source ? fileName + ":" + source[0] + ":" + source[1] : fileName + ":" + line + ":" + column; + } + functionName = frame.getFunctionName(); + isConstructor = frame.isConstructor(); + isMethodCall = !(frame.isToplevel() || isConstructor); + if (isMethodCall) { + methodName = frame.getMethodName(); + typeName = frame.getTypeName(); + if (functionName) { + tp = as = ''; + if (typeName && functionName.indexOf(typeName)) { + tp = typeName + "."; + } + if (methodName && functionName.indexOf("." + methodName) !== functionName.length - methodName.length - 1) { + as = " [as " + methodName + "]"; + } + return "" + tp + functionName + as + " (" + fileLocation + ")"; + } else { + return typeName + "." + (methodName || '') + " (" + fileLocation + ")"; + } + } else if (isConstructor) { + return "new " + (functionName || '') + " (" + fileLocation + ")"; + } else if (functionName) { + return functionName + " (" + fileLocation + ")"; + } else { + return fileLocation; + } + }; + + sourceMaps = {}; + + getSourceMap = function(filename) { + var answer, ref1; + if (sourceMaps[filename]) { + return sourceMaps[filename]; + } + if (ref1 = path != null ? path.extname(filename) : void 0, indexOf.call(exports.FILE_EXTENSIONS, ref1) < 0) { + return; + } + answer = exports._compileFile(filename, true); + return sourceMaps[filename] = answer.sourceMap; + }; + + Error.prepareStackTrace = function(err, stack) { + var frame, frames, getSourceMapping; + getSourceMapping = function(filename, line, column) { + var answer, sourceMap; + sourceMap = getSourceMap(filename); + if (sourceMap) { + answer = sourceMap.sourceLocation([line - 1, column - 1]); + } + if (answer) { + return [answer[0] + 1, answer[1] + 1]; + } else { + return null; + } + }; + frames = (function() { + var j, len1, results; + results = []; + for (j = 0, len1 = stack.length; j < len1; j++) { + frame = stack[j]; + if (frame.getFunction() === exports.run) { + break; + } + results.push(" at " + (formatSourcePosition(frame, getSourceMapping))); + } + return results; + })(); + return (err.toString()) + "\n" + (frames.join('\n')) + "\n"; + }; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/command.js b/node_modules/coffee-script/lib/coffee-script/command.js new file mode 100644 index 0000000..623c37c --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/command.js @@ -0,0 +1,610 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, findDirectoryIndex, forkNode, fs, helpers, hidden, joinTimeout, makePrelude, mkdirp, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, ref, removeSource, removeSourceDir, silentUnlink, sourceCode, sources, spawn, timeLog, usage, useWinPathSep, version, wait, watch, watchDir, watchedDirs, writeJs, + 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; }; + + 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; + + useWinPathSep = path.sep === '\\'; + + 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'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffee-script'], ['-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 = {}; + + watchedDirs = {}; + + optionParser = null; + + exports.run = function() { + var i, len, literals, ref1, replCliOpts, results, source; + parseOptions(); + replCliOpts = { + useGlobal: true + }; + if (opts.require) { + opts.prelude = makePrelude(opts.require); + } + replCliOpts.prelude = opts.prelude; + if (opts.nodejs) { + return forkNode(); + } + if (opts.help) { + return usage(); + } + if (opts.version) { + return version(); + } + if (opts.interactive) { + return require('./repl').start(replCliOpts); + } + if (opts.stdio) { + return compileStdio(); + } + if (opts["eval"]) { + return compileScript(null, opts["arguments"][0]); + } + if (!opts["arguments"].length) { + return require('./repl').start(replCliOpts); + } + literals = opts.run ? opts["arguments"].splice(1) : []; + process.argv = process.argv.slice(0, 2).concat(literals); + process.argv[0] = 'coffee'; + if (opts.output) { + opts.output = path.resolve(opts.output); + } + if (opts.join) { + opts.join = path.resolve(opts.join); + console.error('\nThe --join option is deprecated and will be removed in a future version.\n\nIf for some reason it\'s necessary to share local variables between files,\nreplace...\n\n $ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee\n\nwith...\n\n $ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js\n'); + } + ref1 = opts["arguments"]; + results = []; + for (i = 0, len = ref1.length; i < len; i++) { + source = ref1[i]; + source = path.resolve(source); + results.push(compilePath(source, true, source)); + } + return results; + }; + + makePrelude = function(requires) { + return requires.map(function(module) { + var _, match, name; + if (match = module.match(/^(.*)=(.*)$/)) { + _ = match[0], name = match[1], module = match[2]; + } + name || (name = helpers.baseFileName(module, true, useWinPathSep)); + return name + " = require('" + module + "')"; + }).join(';'); + }; + + compilePath = function(source, topLevel, base) { + var code, err, error, error1, error2, file, files, i, len, results, stats; + if (indexOf.call(sources, source) >= 0 || watchedDirs[source] || !topLevel && (notSources[source] || hidden(source))) { + return; + } + try { + stats = fs.statSync(source); + } catch (error) { + err = error; + if (err.code === 'ENOENT') { + console.error("File not found: " + source); + process.exit(1); + } + throw err; + } + if (stats.isDirectory()) { + if (path.basename(source) === 'node_modules') { + notSources[source] = true; + return; + } + if (opts.run) { + compilePath(findDirectoryIndex(source), topLevel, base); + return; + } + if (opts.watch) { + watchDir(source, base); + } + try { + files = fs.readdirSync(source); + } catch (error1) { + err = error1; + if (err.code === 'ENOENT') { + return; + } else { + throw err; + } + } + results = []; + for (i = 0, len = files.length; i < len; i++) { + file = files[i]; + results.push(compilePath(path.join(source, file), false, base)); + } + return results; + } else if (topLevel || helpers.isCoffee(source)) { + sources.push(source); + sourceCode.push(null); + delete notSources[source]; + if (opts.watch) { + watch(source, base); + } + try { + code = fs.readFileSync(source); + } catch (error2) { + err = error2; + if (err.code === 'ENOENT') { + return; + } else { + throw err; + } + } + return compileScript(source, code.toString(), base); + } else { + return notSources[source] = true; + } + }; + + findDirectoryIndex = function(source) { + var err, error, ext, i, index, len, ref1; + ref1 = CoffeeScript.FILE_EXTENSIONS; + for (i = 0, len = ref1.length; i < len; i++) { + ext = ref1[i]; + index = path.join(source, "index" + ext); + try { + if ((fs.statSync(index)).isFile()) { + return index; + } + } catch (error) { + err = error; + if (err.code !== 'ENOENT') { + throw err; + } + } + } + console.error("Missing index.coffee or index.litcoffee in " + source); + return process.exit(1); + }; + + compileScript = function(file, input, base) { + var compiled, err, error, message, o, options, t, task; + if (base == null) { + base = null; + } + o = opts; + options = compileOptions(file, base); + try { + t = task = { + file: file, + input: input, + options: options + }; + CoffeeScript.emit('compile', task); + if (o.tokens) { + return printTokens(CoffeeScript.tokens(t.input, t.options)); + } else if (o.nodes) { + return printLine(CoffeeScript.nodes(t.input, t.options).toString().trim()); + } else if (o.run) { + CoffeeScript.register(); + if (opts.prelude) { + CoffeeScript["eval"](opts.prelude, t.options); + } + return CoffeeScript.run(t.input, t.options); + } else if (o.join && t.file !== o.join) { + if (helpers.isLiterate(file)) { + t.input = helpers.invertLiterate(t.input); + } + sourceCode[sources.indexOf(t.file)] = t.input; + return compileJoin(); + } else { + compiled = CoffeeScript.compile(t.input, t.options); + t.output = compiled; + if (o.map) { + t.output = compiled.js; + t.sourceMap = compiled.v3SourceMap; + } + CoffeeScript.emit('success', task); + if (o.print) { + return printLine(t.output.trim()); + } else if (o.compile || o.map) { + return writeJs(base, t.file, t.output, options.jsPath, t.sourceMap); + } + } + } catch (error) { + err = error; + CoffeeScript.emit('failure', err, task); + if (CoffeeScript.listeners('failure').length) { + return; + } + message = err.stack || ("" + err); + if (o.watch) { + return printLine(message + '\x07'); + } else { + printWarn(message); + 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); + }); + } + }; + + watch = function(source, base) { + var compile, compileTimeout, err, error, prevStats, rewatch, startWatcher, watchErr, watcher; + watcher = null; + prevStats = null; + compileTimeout = null; + watchErr = function(err) { + var error; + if (err.code !== 'ENOENT') { + throw err; + } + if (indexOf.call(sources, source) < 0) { + return; + } + try { + rewatch(); + return compile(); + } catch (error) { + removeSource(source, base); + return compileJoin(); + } + }; + 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(); + }); + }); + }); + }; + startWatcher = function() { + return watcher = fs.watch(source).on('change', compile).on('error', function(err) { + if (err.code !== 'EPERM') { + throw err; + } + return removeSource(source, base); + }); + }; + rewatch = function() { + if (watcher != null) { + watcher.close(); + } + return startWatcher(); + }; + try { + return startWatcher(); + } catch (error) { + err = error; + return watchErr(err); + } + }; + + watchDir = function(source, base) { + var err, error, readdirTimeout, startWatcher, stopWatcher, watcher; + watcher = null; + readdirTimeout = null; + startWatcher = function() { + return watcher = fs.watch(source).on('error', function(err) { + if (err.code !== 'EPERM') { + throw err; + } + return stopWatcher(); + }).on('change', function() { + clearTimeout(readdirTimeout); + return readdirTimeout = wait(25, function() { + var err, error, file, files, i, len, results; + try { + files = fs.readdirSync(source); + } catch (error) { + err = error; + if (err.code !== 'ENOENT') { + throw err; + } + return stopWatcher(); + } + results = []; + for (i = 0, len = files.length; i < len; i++) { + file = files[i]; + results.push(compilePath(path.join(source, file), false, base)); + } + return results; + }); + }); + }; + stopWatcher = function() { + watcher.close(); + return removeSourceDir(source, base); + }; + watchedDirs[source] = true; + try { + return startWatcher(); + } catch (error) { + err = error; + if (err.code !== 'ENOENT') { + throw err; + } + } + }; + + removeSourceDir = function(source, base) { + var file, i, len, sourcesChanged; + delete watchedDirs[source]; + sourcesChanged = false; + for (i = 0, len = sources.length; i < len; i++) { + file = sources[i]; + if (!(source === path.dirname(file))) { + continue; + } + removeSource(file, base); + sourcesChanged = true; + } + if (sourcesChanged) { + return compileJoin(); + } + }; + + removeSource = function(source, base) { + var index; + index = sources.indexOf(source); + sources.splice(index, 1); + sourceCode.splice(index, 1); + if (!opts.join) { + silentUnlink(outputPath(source, base)); + silentUnlink(outputPath(source, base, '.js.map')); + return timeLog("removed " + source); + } + }; + + silentUnlink = function(path) { + var err, error, ref1; + try { + return fs.unlinkSync(path); + } catch (error) { + err = error; + if ((ref1 = err.code) !== 'ENOENT' && ref1 !== 'EPERM') { + throw err; + } + } + }; + + outputPath = function(source, base, extension) { + var basename, dir, srcDir; + if (extension == null) { + extension = ".js"; + } + basename = helpers.baseFileName(source, true, useWinPathSep); + srcDir = path.dirname(source); + if (!opts.output) { + dir = srcDir; + } else if (source === base) { + dir = opts.output; + } else { + dir = path.join(opts.output, path.relative(base, srcDir)); + } + return path.join(dir, basename + extension); + }; + + mkdirp = function(dir, fn) { + var mkdirs, mode; + mode = 0x1ff & ~process.umask(); + return (mkdirs = function(p, fn) { + return fs.exists(p, function(exists) { + if (exists) { + return fn(); + } else { + return mkdirs(path.dirname(p), function() { + return fs.mkdir(p, mode, function(err) { + if (err) { + return fn(err); + } + return fn(); + }); + }); + } + }); + })(dir, fn); + }; + + writeJs = function(base, sourcePath, js, jsPath, generatedSourceMap) { + var compile, jsDir, sourceMapPath; + if (generatedSourceMap == null) { + generatedSourceMap = null; + } + sourceMapPath = outputPath(sourcePath, base, ".js.map"); + jsDir = path.dirname(jsPath); + compile = function() { + if (opts.compile) { + if (js.length <= 0) { + js = ' '; + } + if (generatedSourceMap) { + js = js + "\n//# sourceMappingURL=" + (helpers.baseFileName(sourceMapPath, false, useWinPathSep)) + "\n"; + } + fs.writeFile(jsPath, js, function(err) { + if (err) { + printLine(err.message); + return process.exit(1); + } else if (opts.compile && opts.watch) { + return timeLog("compiled " + sourcePath); + } + }); + } + if (generatedSourceMap) { + return fs.writeFile(sourceMapPath, generatedSourceMap, function(err) { + if (err) { + printLine("Could not write source map: " + err.message); + return process.exit(1); + } + }); + } + }; + return fs.exists(jsDir, function(itExists) { + if (itExists) { + return compile(); + } else { + return mkdirp(jsDir, compile); + } + }); + }; + + wait = function(milliseconds, func) { + return setTimeout(func, milliseconds); + }; + + timeLog = function(message) { + return console.log(((new Date).toLocaleTimeString()) + " - " + message); + }; + + printTokens = function(tokens) { + var strings, tag, token, value; + strings = (function() { + var i, len, results; + results = []; + for (i = 0, len = tokens.length; i < len; i++) { + token = tokens[i]; + tag = token[0]; + value = token[1].toString().replace(/\n/, '\\n'); + results.push("[" + tag + " " + value + "]"); + } + return results; + })(); + return printLine(strings.join(' ')); + }; + + parseOptions = function() { + var o; + 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.map); + return o.print = !!(o.print || (o["eval"] || o.stdio && o.compile)); + }; + + compileOptions = function(filename, base) { + var answer, cwd, jsDir, jsPath; + answer = { + filename: filename, + literate: opts.literate || helpers.isLiterate(filename), + bare: opts.bare, + header: opts.compile && !opts['no-header'], + sourceMap: opts.map + }; + if (filename) { + if (base) { + cwd = process.cwd(); + jsPath = outputPath(filename, base); + jsDir = path.dirname(jsPath); + answer = helpers.merge(answer, { + jsPath: jsPath, + sourceRoot: path.relative(jsDir, cwd), + sourceFiles: [path.relative(cwd, filename)], + generatedFile: helpers.baseFileName(jsPath, false, useWinPathSep) + }); + } else { + answer = helpers.merge(answer, { + sourceRoot: "", + sourceFiles: [helpers.baseFileName(filename, false, useWinPathSep)], + generatedFile: helpers.baseFileName(filename, true, useWinPathSep) + ".js" + }); + } + } + return answer; + }; + + forkNode = function() { + var args, nodeArgs, p; + nodeArgs = opts.nodejs.split(/\s+/); + args = process.argv.slice(1); + args.splice(args.indexOf('--nodejs'), 2); + p = spawn(process.execPath, nodeArgs.concat(args), { + cwd: process.cwd(), + env: process.env, + stdio: [0, 1, 2] + }); + return p.on('exit', function(code) { + return process.exit(code); + }); + }; + + usage = function() { + return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help()); + }; + + version = function() { + return printLine("CoffeeScript version " + CoffeeScript.VERSION); + }; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/grammar.js b/node_modules/coffee-script/lib/coffee-script/grammar.js new file mode 100644 index 0000000..3dc79d9 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/grammar.js @@ -0,0 +1,665 @@ +// Generated by CoffeeScript 1.10.0 +(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 addLocationDataFn, match, patternCount; + patternString = patternString.replace(/\s{2,}/g, ' '); + patternCount = patternString.split(' ').length; + 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.$&'); + addLocationDataFn = function(first, last) { + if (!last) { + return "yy.addLocationDataFn(@" + first + ")"; + } else { + return "yy.addLocationDataFn(@" + first + ", @" + last + ")"; + } + }; + action = action.replace(/LOC\(([0-9]*)\)/g, addLocationDataFn('$1')); + action = action.replace(/LOC\(([0-9]*),\s*([0-9]*)\)/g, addLocationDataFn('$1', '$2')); + return [patternString, "$$ = " + (addLocationDataFn(1, patternCount)) + "(" + action + ");", options]; + }; + + grammar = { + Root: [ + o('', function() { + return new Block; + }), o('Body') + ], + 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') + ], + String: [ + o('STRING', function() { + return new Literal($1); + }), o('STRING_START Body STRING_END', function() { + return new Parens($2); + }) + ], + Regex: [ + o('REGEX', function() { + return new Literal($1); + }), o('REGEX_START Invocation REGEX_END', function() { + return $2; + }) + ], + Literal: [ + o('AlphaNumeric'), o('JS', function() { + return new Literal($1); + }), o('Regex'), 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(LOC(1)(new Value($1)), $3, 'object', { + operatorToken: LOC(2)(new Literal($2)) + }); + }), o('ObjAssignable : INDENT Expression OUTDENT', function() { + return new Assign(LOC(1)(new Value($1)), $4, 'object', { + operatorToken: LOC(2)(new Literal($2)) + }); + }), o('SimpleObjAssignable = Expression', function() { + return new Assign(LOC(1)(new Value($1)), $3, null, { + operatorToken: LOC(2)(new Literal($2)) + }); + }), o('SimpleObjAssignable = INDENT Expression OUTDENT', function() { + return new Assign(LOC(1)(new Value($1)), $4, null, { + operatorToken: LOC(2)(new Literal($2)) + }); + }), o('Comment') + ], + SimpleObjAssignable: [o('Identifier'), o('ThisProperty')], + ObjAssignable: [o('SimpleObjAssignable'), o('AlphaNumeric')], + 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); + }), o('...', function() { + return new Expansion; + }) + ], + 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 [LOC(1)(new Access(new Literal('prototype'))), LOC(2)(new Access($2))]; + }), o('?:: Identifier', function() { + return [LOC(1)(new Access(new Literal('prototype'), 'soak')), LOC(2)(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(LOC(1)(new Literal('this')), [LOC(2)(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'), o('...', function() { + return new Expansion; + }) + ], + 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]; + }), o('CATCH Object Block', function() { + return [LOC(2)(new Value($2)), $3]; + }), o('CATCH Block', function() { + return [null, $2]; + }) + ], + 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(LOC(1)(Block.wrap([$1]))); + }), o('Expression WhileSource', function() { + return $2.addBody(LOC(1)(Block.wrap([$1]))); + }), o('Loop', function() { + return $1; + }) + ], + Loop: [ + o('LOOP Block', function() { + return new While(LOC(1)(new Literal('true'))).addBody($2); + }), o('LOOP Expression', function() { + return new While(LOC(1)(new Literal('true'))).addBody(LOC(2)(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: LOC(2)(new Value($2)) + }; + }), o('FOR Range BY Expression', function() { + return { + source: LOC(2)(new Value($2)), + step: $4 + }; + }), 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(LOC(3, 5)(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, LOC(1)(Block.wrap([$1])), { + type: $2, + statement: true + }); + }), o('Expression POST_IF Expression', function() { + return new If($3, LOC(1)(Block.wrap([$1])), { + type: $2, + statement: true + }); + }) + ], + Operation: [ + o('UNARY Expression', function() { + return new Op($1, $2); + }), o('UNARY_MATH Expression', function() { + return new Op($1, $2); + }), o('- Expression', (function() { + return new Op('-', $2); + }), { + prec: 'UNARY_MATH' + }), o('+ Expression', (function() { + return new Op('+', $2); + }), { + prec: 'UNARY_MATH' + }), o('YIELD Statement', function() { + return new Op($1, $2); + }), o('YIELD Expression', function() { + return new Op($1, $2); + }), o('YIELD FROM Expression', function() { + return new Op($1.concat($2), $3); + }), 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 ** 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 COMPOUND_ASSIGN TERMINATOR Expression', 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'], ['right', '**'], ['right', 'UNARY_MATH'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', 'YIELD'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['left', '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/node_modules/coffee-script/lib/coffee-script/helpers.js b/node_modules/coffee-script/lib/coffee-script/helpers.js new file mode 100644 index 0000000..6e3d13b --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/helpers.js @@ -0,0 +1,248 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var buildLocationData, extend, flatten, ref, repeat, syntaxErrorToString; + + 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.repeat = repeat = function(str, n) { + var res; + res = ''; + while (n > 0) { + if (n & 1) { + res += str; + } + n >>>= 1; + str += str; + } + return res; + }; + + exports.compact = function(array) { + var i, item, len1, results; + results = []; + for (i = 0, len1 = array.length; i < len1; 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, len1; + flattened = []; + for (i = 0, len1 = array.length; i < len1; i++) { + element = array[i]; + if ('[object Array]' === Object.prototype.toString.call(element)) { + 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.some = (ref = Array.prototype.some) != null ? ref : function(fn) { + var e, i, len1; + for (i = 0, len1 = this.length; i < len1; i++) { + e = this[i]; + if (fn(e)) { + return true; + } + } + return false; + }; + + exports.invertLiterate = function(code) { + var line, lines, maybe_code; + maybe_code = true; + lines = (function() { + var i, len1, ref1, results; + ref1 = code.split('\n'); + results = []; + for (i = 0, len1 = ref1.length; i < len1; i++) { + line = ref1[i]; + if (maybe_code && /^([ ]{4}|[ ]{0,3}\t)/.test(line)) { + results.push(line); + } else if (maybe_code = /^\s*$/.test(line)) { + results.push(line); + } else { + results.push('# ' + line); + } + } + return results; + })(); + return lines.join('\n'); + }; + + buildLocationData = function(first, last) { + if (!last) { + return first; + } else { + return { + first_line: first.first_line, + first_column: first.first_column, + last_line: last.last_line, + last_column: last.last_column + }; + } + }; + + exports.addLocationDataFn = function(first, last) { + return function(obj) { + if (((typeof obj) === 'object') && (!!obj['updateLocationDataIfMissing'])) { + obj.updateLocationDataIfMissing(buildLocationData(first, last)); + } + return obj; + }; + }; + + exports.locationDataToString = function(obj) { + var locationData; + if (("2" in obj) && ("first_line" in obj[2])) { + locationData = obj[2]; + } else if ("first_line" in obj) { + locationData = obj; + } + if (locationData) { + return ((locationData.first_line + 1) + ":" + (locationData.first_column + 1) + "-") + ((locationData.last_line + 1) + ":" + (locationData.last_column + 1)); + } else { + return "No location data"; + } + }; + + exports.baseFileName = function(file, stripExt, useWinPathSep) { + var parts, pathSep; + if (stripExt == null) { + stripExt = false; + } + if (useWinPathSep == null) { + useWinPathSep = false; + } + pathSep = useWinPathSep ? /\\|\// : /\//; + parts = file.split(pathSep); + file = parts[parts.length - 1]; + if (!(stripExt && file.indexOf('.') >= 0)) { + return file; + } + parts = file.split('.'); + parts.pop(); + if (parts[parts.length - 1] === 'coffee' && parts.length > 1) { + parts.pop(); + } + return parts.join('.'); + }; + + exports.isCoffee = function(file) { + return /\.((lit)?coffee|coffee\.md)$/.test(file); + }; + + exports.isLiterate = function(file) { + return /\.(litcoffee|coffee\.md)$/.test(file); + }; + + exports.throwSyntaxError = function(message, location) { + var error; + error = new SyntaxError(message); + error.location = location; + error.toString = syntaxErrorToString; + error.stack = error.toString(); + throw error; + }; + + exports.updateSyntaxError = function(error, code, filename) { + if (error.toString === syntaxErrorToString) { + error.code || (error.code = code); + error.filename || (error.filename = filename); + error.stack = error.toString(); + } + return error; + }; + + syntaxErrorToString = function() { + var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, ref1, ref2, ref3, ref4, start; + if (!(this.code && this.location)) { + return Error.prototype.toString.call(this); + } + ref1 = this.location, first_line = ref1.first_line, first_column = ref1.first_column, last_line = ref1.last_line, last_column = ref1.last_column; + if (last_line == null) { + last_line = first_line; + } + if (last_column == null) { + last_column = first_column; + } + filename = this.filename || '[stdin]'; + codeLine = this.code.split('\n')[first_line]; + start = first_column; + end = first_line === last_line ? last_column + 1 : codeLine.length; + marker = codeLine.slice(0, start).replace(/[^\s]/g, ' ') + repeat('^', end - start); + if (typeof process !== "undefined" && process !== null) { + colorsEnabled = ((ref2 = process.stdout) != null ? ref2.isTTY : void 0) && !((ref3 = process.env) != null ? ref3.NODE_DISABLE_COLORS : void 0); + } + if ((ref4 = this.colorful) != null ? ref4 : colorsEnabled) { + colorize = function(str) { + return "\x1B[1;31m" + str + "\x1B[0m"; + }; + codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end); + marker = colorize(marker); + } + return filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + this.message + "\n" + codeLine + "\n" + marker; + }; + + exports.nameWhitespaceCharacter = function(string) { + switch (string) { + case ' ': + return 'space'; + case '\n': + return 'newline'; + case '\r': + return 'carriage return'; + case '\t': + return 'tab'; + default: + return string; + } + }; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/index.js b/node_modules/coffee-script/lib/coffee-script/index.js new file mode 100644 index 0000000..bcfc8ac --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/index.js @@ -0,0 +1,11 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var key, ref, val; + + ref = require('./coffee-script'); + for (key in ref) { + val = ref[key]; + exports[key] = val; + } + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/lexer.js b/node_modules/coffee-script/lib/coffee-script/lexer.js new file mode 100644 index 0000000..857bf29 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/lexer.js @@ -0,0 +1,1011 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVALID_ESCAPE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, VALID_FLAGS, WHITESPACE, compact, count, invertLiterate, key, locationDataToString, ref, ref1, repeat, starts, throwSyntaxError, + 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, repeat = ref1.repeat, invertLiterate = ref1.invertLiterate, locationDataToString = ref1.locationDataToString, throwSyntaxError = ref1.throwSyntaxError; + + exports.Lexer = Lexer = (function() { + function Lexer() {} + + Lexer.prototype.tokenize = function(code, opts) { + var consumed, end, i, ref2; + if (opts == null) { + opts = {}; + } + this.literate = opts.literate; + this.indent = 0; + this.baseIndent = 0; + this.indebt = 0; + this.outdebt = 0; + this.indents = []; + this.ends = []; + this.tokens = []; + this.seenFor = false; + this.chunkLine = opts.line || 0; + this.chunkColumn = opts.column || 0; + code = this.clean(code); + i = 0; + while (this.chunk = code.slice(i)) { + consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken(); + ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = ref2[0], this.chunkColumn = ref2[1]; + i += consumed; + if (opts.untilBalanced && this.ends.length === 0) { + return { + tokens: this.tokens, + index: i + }; + } + } + this.closeIndentation(); + if (end = this.ends.pop()) { + this.error("missing " + end.tag, end.origin[2]); + } + if (opts.rewrite === false) { + return this.tokens; + } + return (new Rewriter).rewrite(this.tokens); + }; + + Lexer.prototype.clean = function(code) { + if (code.charCodeAt(0) === BOM) { + code = code.slice(1); + } + code = code.replace(/\r/g, '').replace(TRAILING_SPACES, ''); + if (WHITESPACE.test(code)) { + code = "\n" + code; + this.chunkLine--; + } + if (this.literate) { + code = invertLiterate(code); + } + return code; + }; + + Lexer.prototype.identifierToken = function() { + var alias, colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, ref5, tag, tagToken; + if (!(match = IDENTIFIER.exec(this.chunk))) { + return 0; + } + input = match[0], id = match[1], colon = match[2]; + idLength = id.length; + poppedToken = void 0; + if (id === 'own' && this.tag() === 'FOR') { + this.token('OWN', id); + return id.length; + } + if (id === 'from' && this.tag() === 'YIELD') { + this.token('FROM', id); + return id.length; + } + ref2 = this.tokens, prev = ref2[ref2.length - 1]; + forcedIdentifier = colon || (prev != null) && (((ref3 = prev[0]) === '.' || ref3 === '?.' || ref3 === '::' || ref3 === '?::') || !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' && (ref4 = this.tag(), indexOf.call(LINE_BREAK, ref4) >= 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() === '!') { + poppedToken = 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 + "'", { + length: id.length + }); + } + } + if (!forcedIdentifier) { + if (indexOf.call(COFFEE_ALIASES, id) >= 0) { + alias = id; + 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; + } + })(); + } + tagToken = this.token(tag, id, 0, idLength); + if (alias) { + tagToken.origin = [tag, alias, tagToken[2]]; + } + tagToken.variable = !forcedIdentifier; + if (poppedToken) { + ref5 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = ref5[0], tagToken[2].first_column = ref5[1]; + } + if (colon) { + colonOffset = input.lastIndexOf(':'); + this.token(':', ':', colonOffset, colon.length); + } + return input.length; + }; + + Lexer.prototype.numberToken = function() { + var binaryLiteral, lexedLength, match, number, octalLiteral; + if (!(match = NUMBER.exec(this.chunk))) { + return 0; + } + number = match[0]; + lexedLength = number.length; + if (/^0[BOX]/.test(number)) { + this.error("radix prefix in '" + number + "' must be lowercase", { + offset: 1 + }); + } else if (/E/.test(number) && !/^0x/.test(number)) { + this.error("exponential notation in '" + number + "' must be indicated with a lowercase 'e'", { + offset: number.indexOf('E') + }); + } else if (/^0\d*[89]/.test(number)) { + this.error("decimal literal '" + number + "' must not be prefixed with '0'", { + length: lexedLength + }); + } else if (/^0\d+/.test(number)) { + this.error("octal literal '" + number + "' must be prefixed with '0o'", { + length: lexedLength + }); + } + 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, 0, lexedLength); + return lexedLength; + }; + + Lexer.prototype.stringToken = function() { + var $, attempt, delimiter, doc, end, heredoc, i, indent, indentRegex, match, quote, ref2, ref3, regex, token, tokens; + quote = (STRING_START.exec(this.chunk) || [])[0]; + if (!quote) { + return 0; + } + regex = (function() { + switch (quote) { + case "'": + return STRING_SINGLE; + case '"': + return STRING_DOUBLE; + case "'''": + return HEREDOC_SINGLE; + case '"""': + return HEREDOC_DOUBLE; + } + })(); + heredoc = quote.length === 3; + ref2 = this.matchWithInterpolations(regex, quote), tokens = ref2.tokens, end = ref2.index; + $ = tokens.length - 1; + delimiter = quote.charAt(0); + if (heredoc) { + indent = null; + doc = ((function() { + var j, len, results; + results = []; + for (i = j = 0, len = tokens.length; j < len; i = ++j) { + token = tokens[i]; + if (token[0] === 'NEOSTRING') { + results.push(token[1]); + } + } + return results; + })()).join('#{}'); + while (match = HEREDOC_INDENT.exec(doc)) { + attempt = match[1]; + if (indent === null || (0 < (ref3 = attempt.length) && ref3 < indent.length)) { + indent = attempt; + } + } + if (indent) { + indentRegex = RegExp("^" + indent, "gm"); + } + this.mergeInterpolationTokens(tokens, { + delimiter: delimiter + }, (function(_this) { + return function(value, i) { + value = _this.formatString(value); + if (i === 0) { + value = value.replace(LEADING_BLANK_LINE, ''); + } + if (i === $) { + value = value.replace(TRAILING_BLANK_LINE, ''); + } + if (indentRegex) { + value = value.replace(indentRegex, ''); + } + return value; + }; + })(this)); + } else { + this.mergeInterpolationTokens(tokens, { + delimiter: delimiter + }, (function(_this) { + return function(value, i) { + value = _this.formatString(value); + value = value.replace(SIMPLE_STRING_OMIT, function(match, offset) { + if ((i === 0 && offset === 0) || (i === $ && offset + match.length === value.length)) { + return ''; + } else { + return ' '; + } + }); + return value; + }; + })(this)); + } + return end; + }; + + Lexer.prototype.commentToken = function() { + var comment, here, match; + if (!(match = this.chunk.match(COMMENT))) { + return 0; + } + comment = match[0], here = match[1]; + if (here) { + if (match = HERECOMMENT_ILLEGAL.exec(comment)) { + this.error("block comments cannot contain " + match[0], { + offset: match.index, + length: match[0].length + }); + } + if (here.indexOf('\n') >= 0) { + here = here.replace(RegExp("\\n" + (repeat(' ', this.indent)), "g"), '\n'); + } + this.token('HERECOMMENT', here, 0, comment.length); + } + 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), 0, script.length); + return script.length; + }; + + Lexer.prototype.regexToken = function() { + var body, closed, end, flags, index, match, origin, prev, ref2, ref3, ref4, regex, tokens; + switch (false) { + case !(match = REGEX_ILLEGAL.exec(this.chunk)): + this.error("regular expressions cannot begin with " + match[2], { + offset: match.index + match[1].length + }); + break; + case !(match = this.matchWithInterpolations(HEREGEX, '///')): + tokens = match.tokens, index = match.index; + break; + case !(match = REGEX.exec(this.chunk)): + regex = match[0], body = match[1], closed = match[2]; + this.validateEscapes(body, { + isRegex: true, + offsetInChunk: 1 + }); + index = regex.length; + ref2 = this.tokens, prev = ref2[ref2.length - 1]; + if (prev) { + if (prev.spaced && (ref3 = prev[0], indexOf.call(CALLABLE, ref3) >= 0)) { + if (!closed || POSSIBLY_DIVISION.test(regex)) { + return 0; + } + } else if (ref4 = prev[0], indexOf.call(NOT_REGEX, ref4) >= 0) { + return 0; + } + } + if (!closed) { + this.error('missing / (unclosed regex)'); + } + break; + default: + return 0; + } + flags = REGEX_FLAGS.exec(this.chunk.slice(index))[0]; + end = index + flags.length; + origin = this.makeToken('REGEX', null, 0, end); + switch (false) { + case !!VALID_FLAGS.test(flags): + this.error("invalid regular expression flags " + flags, { + offset: index, + length: flags.length + }); + break; + case !(regex || tokens.length === 1): + if (body == null) { + body = this.formatHeregex(tokens[0][1]); + } + this.token('REGEX', "" + (this.makeDelimitedLiteral(body, { + delimiter: '/' + })) + flags, 0, end, origin); + break; + default: + this.token('REGEX_START', '(', 0, 0, origin); + this.token('IDENTIFIER', 'RegExp', 0, 0); + this.token('CALL_START', '(', 0, 0); + this.mergeInterpolationTokens(tokens, { + delimiter: '"', + double: true + }, this.formatHeregex); + if (flags) { + this.token(',', ',', index, 0); + this.token('STRING', '"' + flags + '"', index, flags.length); + } + this.token(')', ')', end, 0); + this.token('REGEX_END', ')', end, 0); + } + return end; + }; + + Lexer.prototype.lineToken = function() { + var diff, indent, match, noNewlines, size; + if (!(match = MULTI_DENT.exec(this.chunk))) { + return 0; + } + indent = match[0]; + this.seenFor = false; + size = indent.length - 1 - indent.lastIndexOf('\n'); + noNewlines = this.unfinished(); + if (size - this.indebt === this.indent) { + if (noNewlines) { + this.suppressNewlines(); + } else { + this.newlineToken(0); + } + return indent.length; + } + if (size > this.indent) { + if (noNewlines) { + this.indebt = size - this.indent; + this.suppressNewlines(); + return indent.length; + } + if (!this.tokens.length) { + this.baseIndent = this.indent = size; + return indent.length; + } + diff = size - this.indent + this.outdebt; + this.token('INDENT', diff, indent.length - size, size); + this.indents.push(diff); + this.ends.push({ + tag: 'OUTDENT' + }); + this.outdebt = this.indebt = 0; + this.indent = size; + } else if (size < this.baseIndent) { + this.error('missing indentation', { + offset: indent.length + }); + } else { + this.indebt = 0; + this.outdentToken(this.indent - size, noNewlines, indent.length); + } + return indent.length; + }; + + Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) { + var decreasedIndent, dent, lastIndent, ref2; + decreasedIndent = this.indent - moveOut; + while (moveOut > 0) { + lastIndent = this.indents[this.indents.length - 1]; + if (!lastIndent) { + moveOut = 0; + } else if (lastIndent === this.outdebt) { + moveOut -= this.outdebt; + this.outdebt = 0; + } else if (lastIndent < this.outdebt) { + this.outdebt -= lastIndent; + moveOut -= lastIndent; + } else { + dent = this.indents.pop() + this.outdebt; + if (outdentLength && (ref2 = this.chunk[outdentLength], indexOf.call(INDENTABLE_CLOSERS, ref2) >= 0)) { + decreasedIndent -= dent - moveOut; + moveOut = dent; + } + this.outdebt = 0; + this.pair('OUTDENT'); + this.token('OUTDENT', moveOut, 0, outdentLength); + moveOut -= dent; + } + } + if (dent) { + this.outdebt -= moveOut; + } + while (this.value() === ';') { + this.tokens.pop(); + } + if (!(this.tag() === 'TERMINATOR' || noNewlines)) { + this.token('TERMINATOR', '\n', outdentLength, 0); + } + this.indent = decreasedIndent; + return this; + }; + + Lexer.prototype.whitespaceToken = function() { + var match, nline, prev, ref2; + if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) { + return 0; + } + ref2 = this.tokens, prev = ref2[ref2.length - 1]; + if (prev) { + prev[match ? 'spaced' : 'newLine'] = true; + } + if (match) { + return match[0].length; + } else { + return 0; + } + }; + + Lexer.prototype.newlineToken = function(offset) { + while (this.value() === ';') { + this.tokens.pop(); + } + if (this.tag() !== 'TERMINATOR') { + this.token('TERMINATOR', '\n', offset, 0); + } + return this; + }; + + Lexer.prototype.suppressNewlines = function() { + if (this.value() === '\\') { + this.tokens.pop(); + } + return this; + }; + + Lexer.prototype.literalToken = function() { + var match, prev, ref2, ref3, ref4, ref5, ref6, tag, token, value; + if (match = OPERATOR.exec(this.chunk)) { + value = match[0]; + if (CODE.test(value)) { + this.tagParameters(); + } + } else { + value = this.chunk.charAt(0); + } + tag = value; + ref2 = this.tokens, prev = ref2[ref2.length - 1]; + if (value === '=' && prev) { + if (!prev[1].reserved && (ref3 = prev[1], indexOf.call(JS_FORBIDDEN, ref3) >= 0)) { + if (prev.origin) { + prev = prev.origin; + } + this.error("reserved word '" + prev[1] + "' can't be assigned", prev[2]); + } + if ((ref4 = prev[1]) === '||' || ref4 === '&&') { + 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(UNARY_MATH, value) >= 0) { + tag = 'UNARY_MATH'; + } 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 === '(' && (ref5 = prev[0], indexOf.call(CALLABLE, ref5) >= 0)) { + if (prev[0] === '?') { + prev[0] = 'FUNC_EXIST'; + } + tag = 'CALL_START'; + } else if (value === '[' && (ref6 = prev[0], indexOf.call(INDEXABLE, ref6) >= 0)) { + tag = 'INDEX_START'; + switch (prev[0]) { + case '?': + prev[0] = 'INDEX_SOAK'; + } + } + } + token = this.makeToken(tag, value); + switch (value) { + case '(': + case '{': + case '[': + this.ends.push({ + tag: INVERSES[value], + origin: token + }); + break; + case ')': + case '}': + case ']': + this.pair(value); + } + this.tokens.push(token); + return value.length; + }; + + 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.matchWithInterpolations = function(regex, delimiter) { + var close, column, firstToken, index, lastToken, line, nested, offsetInChunk, open, ref2, ref3, ref4, str, strPart, tokens; + tokens = []; + offsetInChunk = delimiter.length; + if (this.chunk.slice(0, offsetInChunk) !== delimiter) { + return null; + } + str = this.chunk.slice(offsetInChunk); + while (true) { + strPart = regex.exec(str)[0]; + this.validateEscapes(strPart, { + isRegex: delimiter.charAt(0) === '/', + offsetInChunk: offsetInChunk + }); + tokens.push(this.makeToken('NEOSTRING', strPart, offsetInChunk)); + str = str.slice(strPart.length); + offsetInChunk += strPart.length; + if (str.slice(0, 2) !== '#{') { + break; + } + ref2 = this.getLineAndColumnFromChunk(offsetInChunk + 1), line = ref2[0], column = ref2[1]; + ref3 = new Lexer().tokenize(str.slice(1), { + line: line, + column: column, + untilBalanced: true + }), nested = ref3.tokens, index = ref3.index; + index += 1; + open = nested[0], close = nested[nested.length - 1]; + open[0] = open[1] = '('; + close[0] = close[1] = ')'; + close.origin = ['', 'end of interpolation', close[2]]; + if (((ref4 = nested[1]) != null ? ref4[0] : void 0) === 'TERMINATOR') { + nested.splice(1, 1); + } + tokens.push(['TOKENS', nested]); + str = str.slice(index); + offsetInChunk += index; + } + if (str.slice(0, delimiter.length) !== delimiter) { + this.error("missing " + delimiter, { + length: delimiter.length + }); + } + firstToken = tokens[0], lastToken = tokens[tokens.length - 1]; + firstToken[2].first_column -= delimiter.length; + lastToken[2].last_column += delimiter.length; + if (lastToken[1].length === 0) { + lastToken[2].last_column -= 1; + } + return { + tokens: tokens, + index: offsetInChunk + delimiter.length + }; + }; + + Lexer.prototype.mergeInterpolationTokens = function(tokens, options, fn) { + var converted, firstEmptyStringIndex, firstIndex, i, j, lastToken, len, locationToken, lparen, plusToken, ref2, rparen, tag, token, tokensToPush, value; + if (tokens.length > 1) { + lparen = this.token('STRING_START', '(', 0, 0); + } + firstIndex = this.tokens.length; + for (i = j = 0, len = tokens.length; j < len; i = ++j) { + token = tokens[i]; + tag = token[0], value = token[1]; + switch (tag) { + case 'TOKENS': + if (value.length === 2) { + continue; + } + locationToken = value[0]; + tokensToPush = value; + break; + case 'NEOSTRING': + converted = fn(token[1], i); + if (converted.length === 0) { + if (i === 0) { + firstEmptyStringIndex = this.tokens.length; + } else { + continue; + } + } + if (i === 2 && (firstEmptyStringIndex != null)) { + this.tokens.splice(firstEmptyStringIndex, 2); + } + token[0] = 'STRING'; + token[1] = this.makeDelimitedLiteral(converted, options); + locationToken = token; + tokensToPush = [token]; + } + if (this.tokens.length > firstIndex) { + plusToken = this.token('+', '+'); + plusToken[2] = { + first_line: locationToken[2].first_line, + first_column: locationToken[2].first_column, + last_line: locationToken[2].first_line, + last_column: locationToken[2].first_column + }; + } + (ref2 = this.tokens).push.apply(ref2, tokensToPush); + } + if (lparen) { + lastToken = tokens[tokens.length - 1]; + lparen.origin = [ + 'STRING', null, { + first_line: lparen[2].first_line, + first_column: lparen[2].first_column, + last_line: lastToken[2].last_line, + last_column: lastToken[2].last_column + } + ]; + rparen = this.token('STRING_END', ')'); + return rparen[2] = { + first_line: lastToken[2].last_line, + first_column: lastToken[2].last_column, + last_line: lastToken[2].last_line, + last_column: lastToken[2].last_column + }; + } + }; + + Lexer.prototype.pair = function(tag) { + var lastIndent, prev, ref2, ref3, wanted; + ref2 = this.ends, prev = ref2[ref2.length - 1]; + if (tag !== (wanted = prev != null ? prev.tag : void 0)) { + if ('OUTDENT' !== wanted) { + this.error("unmatched " + tag); + } + ref3 = this.indents, lastIndent = ref3[ref3.length - 1]; + this.outdentToken(lastIndent, true); + return this.pair(tag); + } + return this.ends.pop(); + }; + + Lexer.prototype.getLineAndColumnFromChunk = function(offset) { + var column, lastLine, lineCount, ref2, string; + if (offset === 0) { + return [this.chunkLine, this.chunkColumn]; + } + if (offset >= this.chunk.length) { + string = this.chunk; + } else { + string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9); + } + lineCount = count(string, '\n'); + column = this.chunkColumn; + if (lineCount > 0) { + ref2 = string.split('\n'), lastLine = ref2[ref2.length - 1]; + column = lastLine.length; + } else { + column += string.length; + } + return [this.chunkLine + lineCount, column]; + }; + + Lexer.prototype.makeToken = function(tag, value, offsetInChunk, length) { + var lastCharacter, locationData, ref2, ref3, token; + if (offsetInChunk == null) { + offsetInChunk = 0; + } + if (length == null) { + length = value.length; + } + locationData = {}; + ref2 = this.getLineAndColumnFromChunk(offsetInChunk), locationData.first_line = ref2[0], locationData.first_column = ref2[1]; + lastCharacter = Math.max(0, length - 1); + ref3 = this.getLineAndColumnFromChunk(offsetInChunk + lastCharacter), locationData.last_line = ref3[0], locationData.last_column = ref3[1]; + token = [tag, value, locationData]; + return token; + }; + + Lexer.prototype.token = function(tag, value, offsetInChunk, length, origin) { + var token; + token = this.makeToken(tag, value, offsetInChunk, length); + if (origin) { + token.origin = origin; + } + this.tokens.push(token); + return token; + }; + + Lexer.prototype.tag = function() { + var ref2, token; + ref2 = this.tokens, token = ref2[ref2.length - 1]; + return token != null ? token[0] : void 0; + }; + + Lexer.prototype.value = function() { + var ref2, token; + ref2 = this.tokens, token = ref2[ref2.length - 1]; + return token != null ? token[1] : void 0; + }; + + Lexer.prototype.unfinished = function() { + var ref2; + return LINE_CONTINUER.test(this.chunk) || ((ref2 = this.tag()) === '\\' || ref2 === '.' || ref2 === '?.' || ref2 === '?::' || ref2 === 'UNARY' || ref2 === 'MATH' || ref2 === 'UNARY_MATH' || ref2 === '+' || ref2 === '-' || ref2 === 'YIELD' || ref2 === '**' || ref2 === 'SHIFT' || ref2 === 'RELATION' || ref2 === 'COMPARE' || ref2 === 'LOGIC' || ref2 === 'THROW' || ref2 === 'EXTENDS'); + }; + + Lexer.prototype.formatString = function(str) { + return str.replace(STRING_OMIT, '$1'); + }; + + Lexer.prototype.formatHeregex = function(str) { + return str.replace(HEREGEX_OMIT, '$1$2'); + }; + + Lexer.prototype.validateEscapes = function(str, options) { + var before, hex, invalidEscape, match, message, octal, ref2, unicode; + if (options == null) { + options = {}; + } + match = INVALID_ESCAPE.exec(str); + if (!match) { + return; + } + match[0], before = match[1], octal = match[2], hex = match[3], unicode = match[4]; + if (options.isRegex && octal && octal.charAt(0) !== '0') { + return; + } + message = octal ? "octal escape sequences are not allowed" : "invalid escape sequence"; + invalidEscape = "\\" + (octal || hex || unicode); + return this.error(message + " " + invalidEscape, { + offset: ((ref2 = options.offsetInChunk) != null ? ref2 : 0) + match.index + before.length, + length: invalidEscape.length + }); + }; + + Lexer.prototype.makeDelimitedLiteral = function(body, options) { + var regex; + if (options == null) { + options = {}; + } + if (body === '' && options.delimiter === '/') { + body = '(?:)'; + } + regex = RegExp("(\\\\\\\\)|(\\\\0(?=[1-7]))|\\\\?(" + options.delimiter + ")|\\\\?(?:(\\n)|(\\r)|(\\u2028)|(\\u2029))|(\\\\.)", "g"); + body = body.replace(regex, function(match, backslash, nul, delimiter, lf, cr, ls, ps, other) { + switch (false) { + case !backslash: + if (options.double) { + return backslash + backslash; + } else { + return backslash; + } + case !nul: + return '\\x00'; + case !delimiter: + return "\\" + delimiter; + case !lf: + return '\\n'; + case !cr: + return '\\r'; + case !ls: + return '\\u2028'; + case !ps: + return '\\u2029'; + case !other: + if (options.double) { + return "\\" + other; + } else { + return other; + } + } + }); + return "" + options.delimiter + body + options.delimiter; + }; + + Lexer.prototype.error = function(message, options) { + var first_column, first_line, location, ref2, ref3, ref4; + if (options == null) { + options = {}; + } + location = 'first_line' in options ? options : ((ref3 = this.getLineAndColumnFromChunk((ref2 = options.offset) != null ? ref2 : 0), first_line = ref3[0], first_column = ref3[1], ref3), { + first_line: first_line, + first_column: first_column, + last_column: first_column + ((ref4 = options.length) != null ? ref4 : 1) - 1 + }); + return throwSyntaxError(message, location); + }; + + return Lexer; + + })(); + + JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'yield', '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', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static']; + + STRICT_PROSCRIBED = ['arguments', 'eval', 'yield*']; + + 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; + + BOM = 65279; + + IDENTIFIER = /^(?!\d)((?:(?!\s)[$\w\x7f-\uffff])+)([^\n\S]*:(?!:))?/; + + NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; + + OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?(\.|::)|\.{2,3})/; + + WHITESPACE = /^[^\n\S]+/; + + COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/; + + CODE = /^[-=]>/; + + MULTI_DENT = /^(?:\n[^\n\S]*)+/; + + JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/; + + STRING_START = /^(?:'''|"""|'|")/; + + STRING_SINGLE = /^(?:[^\\']|\\[\s\S])*/; + + STRING_DOUBLE = /^(?:[^\\"#]|\\[\s\S]|\#(?!\{))*/; + + HEREDOC_SINGLE = /^(?:[^\\']|\\[\s\S]|'(?!''))*/; + + HEREDOC_DOUBLE = /^(?:[^\\"#]|\\[\s\S]|"(?!"")|\#(?!\{))*/; + + STRING_OMIT = /((?:\\\\)+)|\\[^\S\n]*\n\s*/g; + + SIMPLE_STRING_OMIT = /\s*\n\s*/g; + + HEREDOC_INDENT = /\n+([^\n\S]*)(?=\S)/g; + + REGEX = /^\/(?!\/)((?:[^[\/\n\\]|\\[^\n]|\[(?:\\[^\n]|[^\]\n\\])*\])*)(\/)?/; + + REGEX_FLAGS = /^\w*/; + + VALID_FLAGS = /^(?!.*(.).*\1)[imgy]*$/; + + HEREGEX = /^(?:[^\\\/#]|\\[\s\S]|\/(?!\/\/)|\#(?!\{))*/; + + HEREGEX_OMIT = /((?:\\\\)+)|\\(\s)|\s+(?:#.*)?/g; + + REGEX_ILLEGAL = /^(\/|\/{3}\s*)(\*)/; + + POSSIBLY_DIVISION = /^\/=?\s/; + + HERECOMMENT_ILLEGAL = /\*\//; + + LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/; + + INVALID_ESCAPE = /((?:^|[^\\])(?:\\\\)*)\\(?:(0[0-7]|[1-7])|(x(?![\da-fA-F]{2}).{0,2})|(u(?![\da-fA-F]{4}).{0,4}))/; + + LEADING_BLANK_LINE = /^[^\n\S]*\n/; + + TRAILING_BLANK_LINE = /\n[^\n\S]*$/; + + TRAILING_SPACES = /\s+$/; + + COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=', '**=', '//=', '%%=']; + + UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO']; + + UNARY_MATH = ['!', '~']; + + LOGIC = ['&&', '||', '&', '|', '^']; + + SHIFT = ['<<', '>>', '>>>']; + + COMPARE = ['==', '!=', '<', '>', '<=', '>=']; + + MATH = ['*', '/', '%', '//', '%%']; + + RELATION = ['IN', 'OF', 'INSTANCEOF']; + + BOOL = ['TRUE', 'FALSE']; + + CALLABLE = ['IDENTIFIER', ')', ']', '?', '@', 'THIS', 'SUPER']; + + INDEXABLE = CALLABLE.concat(['NUMBER', 'STRING', 'STRING_END', 'REGEX', 'REGEX_END', 'BOOL', 'NULL', 'UNDEFINED', '}', '::']); + + NOT_REGEX = INDEXABLE.concat(['++', '--']); + + LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']; + + INDENTABLE_CLOSERS = [')', '}', ']']; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/nodes.js b/node_modules/coffee-script/lib/coffee-script/nodes.js new file mode 100644 index 0000000..534811e --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/nodes.js @@ -0,0 +1,3307 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, NEGATE, NO, NUMBER, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isComplexOrAssignable, isLiteralArguments, isLiteralThis, locationDataToString, merge, multident, parseNum, ref1, ref2, some, starts, throwSyntaxError, unfoldSoak, utility, + extend1 = 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; }, + hasProp = {}.hasOwnProperty, + 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; + + Error.stackTraceLimit = Infinity; + + Scope = require('./scope').Scope; + + ref1 = require('./lexer'), RESERVED = ref1.RESERVED, STRICT_PROSCRIBED = ref1.STRICT_PROSCRIBED; + + ref2 = require('./helpers'), compact = ref2.compact, flatten = ref2.flatten, extend = ref2.extend, merge = ref2.merge, del = ref2.del, starts = ref2.starts, ends = ref2.ends, some = ref2.some, addLocationDataFn = ref2.addLocationDataFn, locationDataToString = ref2.locationDataToString, throwSyntaxError = ref2.throwSyntaxError; + + exports.extend = extend; + + exports.addLocationDataFn = addLocationDataFn; + + YES = function() { + return true; + }; + + NO = function() { + return false; + }; + + THIS = function() { + return this; + }; + + NEGATE = function() { + this.negated = !this.negated; + return this; + }; + + exports.CodeFragment = CodeFragment = (function() { + function CodeFragment(parent, code) { + var ref3; + this.code = "" + code; + this.locationData = parent != null ? parent.locationData : void 0; + this.type = (parent != null ? (ref3 = parent.constructor) != null ? ref3.name : void 0 : void 0) || 'unknown'; + } + + CodeFragment.prototype.toString = function() { + return "" + this.code + (this.locationData ? ": " + locationDataToString(this.locationData) : ''); + }; + + return CodeFragment; + + })(); + + fragmentsToText = function(fragments) { + var fragment; + return ((function() { + var j, len1, results; + results = []; + for (j = 0, len1 = fragments.length; j < len1; j++) { + fragment = fragments[j]; + results.push(fragment.code); + } + return results; + })()).join(''); + }; + + exports.Base = Base = (function() { + function Base() {} + + Base.prototype.compile = function(o, lvl) { + return fragmentsToText(this.compileToFragments(o, lvl)); + }; + + Base.prototype.compileToFragments = 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) { + var args, argumentsNode, func, jumpNode, meth, parts, ref3; + if (jumpNode = this.jumps()) { + jumpNode.error('cannot use a pure statement in an expression'); + } + o.sharedScope = true; + func = new Code([], Block.wrap([this])); + args = []; + if ((argumentsNode = this.contains(isLiteralArguments)) || this.contains(isLiteralThis)) { + args = [new Literal('this')]; + if (argumentsNode) { + meth = 'apply'; + args.push(new Literal('arguments')); + } else { + meth = 'call'; + } + func = new Value(func, [new Access(new Literal(meth))]); + } + parts = (new Call(func, args)).compileNode(o); + if (func.isGenerator || ((ref3 = func.base) != null ? ref3.isGenerator : void 0)) { + parts.unshift(this.makeCode("(yield* ")); + parts.push(this.makeCode(")")); + } + return parts; + }; + + Base.prototype.cache = function(o, level, isComplex) { + var complex, ref, sub; + complex = isComplex != null ? isComplex(this) : this.isComplex(); + if (complex) { + ref = new Literal(o.scope.freeVariable('ref')); + sub = new Assign(ref, this); + if (level) { + return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]]; + } else { + return [sub, ref]; + } + } else { + ref = level ? this.compileToFragments(o, level) : this; + return [ref, ref]; + } + }; + + Base.prototype.cacheToCodeFragments = function(cacheValues) { + return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])]; + }; + + 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 node; + node = void 0; + this.traverseChildren(false, function(n) { + if (pred(n)) { + node = n; + return false; + } + }); + return node; + }; + + 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, j, k, len1, len2, ref3, ref4; + if (!this.children) { + return this; + } + ref3 = this.children; + for (j = 0, len1 = ref3.length; j < len1; j++) { + attr = ref3[j]; + if (this[attr]) { + ref4 = flatten([this[attr]]); + for (k = 0, len2 = ref4.length; k < len2; k++) { + child = ref4[k]; + if (func(child) === false) { + return this; + } + } + } + } + return this; + }; + + Base.prototype.traverseChildren = function(crossScope, func) { + return this.eachChild(function(child) { + var recur; + recur = func(child); + if (recur !== 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; + + Base.prototype.updateLocationDataIfMissing = function(locationData) { + if (this.locationData) { + return this; + } + this.locationData = locationData; + return this.eachChild(function(child) { + return child.updateLocationDataIfMissing(locationData); + }); + }; + + Base.prototype.error = function(message) { + return throwSyntaxError(message, this.locationData); + }; + + Base.prototype.makeCode = function(code) { + return new CodeFragment(this, code); + }; + + Base.prototype.wrapInBraces = function(fragments) { + return [].concat(this.makeCode('('), fragments, this.makeCode(')')); + }; + + Base.prototype.joinFragmentArrays = function(fragmentsList, joinStr) { + var answer, fragments, i, j, len1; + answer = []; + for (i = j = 0, len1 = fragmentsList.length; j < len1; i = ++j) { + fragments = fragmentsList[i]; + if (i) { + answer.push(this.makeCode(joinStr)); + } + answer = answer.concat(fragments); + } + return answer; + }; + + return Base; + + })(); + + exports.Block = Block = (function(superClass1) { + extend1(Block, superClass1); + + 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, j, len1, ref3; + ref3 = this.expressions; + for (j = 0, len1 = ref3.length; j < len1; j++) { + exp = ref3[j]; + if (exp.isStatement(o)) { + return true; + } + } + return false; + }; + + Block.prototype.jumps = function(o) { + var exp, j, jumpNode, len1, ref3; + ref3 = this.expressions; + for (j = 0, len1 = ref3.length; j < len1; j++) { + exp = ref3[j]; + if (jumpNode = exp.jumps(o)) { + return jumpNode; + } + } + }; + + 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.compileToFragments = function(o, level) { + if (o == null) { + o = {}; + } + if (o.scope) { + return Block.__super__.compileToFragments.call(this, o, level); + } else { + return this.compileRoot(o); + } + }; + + Block.prototype.compileNode = function(o) { + var answer, compiledNodes, fragments, index, j, len1, node, ref3, top; + this.tab = o.indent; + top = o.level === LEVEL_TOP; + compiledNodes = []; + ref3 = this.expressions; + for (index = j = 0, len1 = ref3.length; j < len1; index = ++j) { + node = ref3[index]; + node = node.unwrapAll(); + node = node.unfoldSoak(o) || node; + if (node instanceof Block) { + compiledNodes.push(node.compileNode(o)); + } else if (top) { + node.front = true; + fragments = node.compileToFragments(o); + if (!node.isStatement(o)) { + fragments.unshift(this.makeCode("" + this.tab)); + fragments.push(this.makeCode(";")); + } + compiledNodes.push(fragments); + } else { + compiledNodes.push(node.compileToFragments(o, LEVEL_LIST)); + } + } + if (top) { + if (this.spaced) { + return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n")); + } else { + return this.joinFragmentArrays(compiledNodes, '\n'); + } + } + if (compiledNodes.length) { + answer = this.joinFragmentArrays(compiledNodes, ', '); + } else { + answer = [this.makeCode("void 0")]; + } + if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + Block.prototype.compileRoot = function(o) { + var exp, fragments, i, j, len1, name, prelude, preludeExps, ref3, ref4, rest; + o.indent = o.bare ? '' : TAB; + o.level = LEVEL_TOP; + this.spaced = true; + o.scope = new Scope(null, this, null, (ref3 = o.referencedVars) != null ? ref3 : []); + ref4 = o.locals || []; + for (j = 0, len1 = ref4.length; j < len1; j++) { + name = ref4[j]; + o.scope.parameter(name); + } + prelude = []; + if (!o.bare) { + preludeExps = (function() { + var k, len2, ref5, results; + ref5 = this.expressions; + results = []; + for (i = k = 0, len2 = ref5.length; k < len2; i = ++k) { + exp = ref5[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: '' + })); + prelude.push(this.makeCode("\n")); + } + this.expressions = rest; + } + fragments = this.compileWithDeclarations(o); + if (o.bare) { + return fragments; + } + return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n")); + }; + + Block.prototype.compileWithDeclarations = function(o) { + var assigns, declars, exp, fragments, i, j, len1, post, ref3, ref4, ref5, rest, scope, spaced; + fragments = []; + post = []; + ref3 = this.expressions; + for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { + exp = ref3[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); + ref4 = [this.spaced, false], spaced = ref4[0], this.spaced = ref4[1]; + ref5 = [this.compileNode(o), spaced], fragments = ref5[0], this.spaced = ref5[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) { + fragments.push(this.makeCode('\n')); + } + fragments.push(this.makeCode(this.tab + "var ")); + if (declars) { + fragments.push(this.makeCode(scope.declaredVariables().join(', '))); + } + if (assigns) { + if (declars) { + fragments.push(this.makeCode(",\n" + (this.tab + TAB))); + } + fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB)))); + } + fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : ''))); + } else if (fragments.length && post.length) { + fragments.push(this.makeCode("\n")); + } + } + return fragments.concat(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(superClass1) { + extend1(Literal, superClass1); + + function Literal(value1) { + this.value = value1; + } + + 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 ref3; + return (ref3 = this.value) === 'break' || ref3 === 'continue' || ref3 === '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 answer, code, ref3; + code = this.value === 'this' ? ((ref3 = o.scope.method) != null ? ref3.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value; + answer = this.isStatement() ? "" + this.tab + code + ";" : code; + return [this.makeCode(answer)]; + }; + + Literal.prototype.toString = function() { + return ' "' + this.value + '"'; + }; + + return Literal; + + })(Base); + + exports.Undefined = (function(superClass1) { + extend1(Undefined, superClass1); + + function Undefined() { + return Undefined.__super__.constructor.apply(this, arguments); + } + + Undefined.prototype.isAssignable = NO; + + Undefined.prototype.isComplex = NO; + + Undefined.prototype.compileNode = function(o) { + return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')]; + }; + + return Undefined; + + })(Base); + + exports.Null = (function(superClass1) { + extend1(Null, superClass1); + + function Null() { + return Null.__super__.constructor.apply(this, arguments); + } + + Null.prototype.isAssignable = NO; + + Null.prototype.isComplex = NO; + + Null.prototype.compileNode = function() { + return [this.makeCode("null")]; + }; + + return Null; + + })(Base); + + exports.Bool = (function(superClass1) { + extend1(Bool, superClass1); + + Bool.prototype.isAssignable = NO; + + Bool.prototype.isComplex = NO; + + Bool.prototype.compileNode = function() { + return [this.makeCode(this.val)]; + }; + + function Bool(val1) { + this.val = val1; + } + + return Bool; + + })(Base); + + exports.Return = Return = (function(superClass1) { + extend1(Return, superClass1); + + function Return(expression) { + this.expression = expression; + } + + Return.prototype.children = ['expression']; + + Return.prototype.isStatement = YES; + + Return.prototype.makeReturn = THIS; + + Return.prototype.jumps = THIS; + + Return.prototype.compileToFragments = function(o, level) { + var expr, ref3; + expr = (ref3 = this.expression) != null ? ref3.makeReturn() : void 0; + if (expr && !(expr instanceof Return)) { + return expr.compileToFragments(o, level); + } else { + return Return.__super__.compileToFragments.call(this, o, level); + } + }; + + Return.prototype.compileNode = function(o) { + var answer, exprIsYieldReturn, ref3; + answer = []; + exprIsYieldReturn = (ref3 = this.expression) != null ? typeof ref3.isYieldReturn === "function" ? ref3.isYieldReturn() : void 0 : void 0; + if (!exprIsYieldReturn) { + answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : "")))); + } + if (this.expression) { + answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN)); + } + if (!exprIsYieldReturn) { + answer.push(this.makeCode(";")); + } + return answer; + }; + + return Return; + + })(Base); + + exports.Value = Value = (function(superClass1) { + extend1(Value, superClass1); + + 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.bareLiteral = function(type) { + return !this.properties.length && this.base instanceof type; + }; + + Value.prototype.isArray = function() { + return this.bareLiteral(Arr); + }; + + Value.prototype.isRange = function() { + return this.bareLiteral(Range); + }; + + 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.bareLiteral(Literal) && SIMPLENUM.test(this.base.value); + }; + + Value.prototype.isString = function() { + return this.bareLiteral(Literal) && IS_STRING.test(this.base.value); + }; + + Value.prototype.isRegex = function() { + return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value); + }; + + Value.prototype.isAtomic = function() { + var j, len1, node, ref3; + ref3 = this.properties.concat(this.base); + for (j = 0, len1 = ref3.length; j < len1; j++) { + node = ref3[j]; + if (node.soak || node instanceof Call) { + return false; + } + } + return true; + }; + + Value.prototype.isNotCallable = function() { + return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject(); + }; + + 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() { + var lastProp, ref3; + ref3 = this.properties, lastProp = ref3[ref3.length - 1]; + return lastProp instanceof Slice; + }; + + Value.prototype.looksStatic = function(className) { + var ref3; + return this.base.value === className && this.properties.length === 1 && ((ref3 = this.properties[0].name) != null ? ref3.value : void 0) !== 'prototype'; + }; + + Value.prototype.unwrap = function() { + if (this.properties.length) { + return this; + } else { + return this.base; + } + }; + + Value.prototype.cacheReference = function(o) { + var base, bref, name, nref, ref3; + ref3 = this.properties, name = ref3[ref3.length - 1]; + 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 fragments, j, len1, prop, props; + this.base.front = this.front; + props = this.properties; + fragments = this.base.compileToFragments(o, (props.length ? LEVEL_ACCESS : null)); + if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(fragmentsToText(fragments))) { + fragments.push(this.makeCode('.')); + } + for (j = 0, len1 = props.length; j < len1; j++) { + prop = props[j]; + fragments.push.apply(fragments, prop.compileToFragments(o)); + } + return fragments; + }; + + Value.prototype.unfoldSoak = function(o) { + return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function(_this) { + return function() { + var fst, i, ifn, j, len1, prop, ref, ref3, ref4, snd; + if (ifn = _this.base.unfoldSoak(o)) { + (ref3 = ifn.body.properties).push.apply(ref3, _this.properties); + return ifn; + } + ref4 = _this.properties; + for (i = j = 0, len1 = ref4.length; j < len1; i = ++j) { + prop = ref4[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 false; + }; + })(this)(); + }; + + return Value; + + })(Base); + + exports.Comment = Comment = (function(superClass1) { + extend1(Comment, superClass1); + + function Comment(comment1) { + this.comment = comment1; + } + + Comment.prototype.isStatement = YES; + + Comment.prototype.makeReturn = THIS; + + Comment.prototype.compileNode = function(o, level) { + var code, comment; + comment = this.comment.replace(/^(\s*)#(?=\s)/gm, "$1 *"); + code = "/*" + (multident(comment, this.tab)) + (indexOf.call(comment, '\n') >= 0 ? "\n" + this.tab : '') + " */"; + if ((level || o.level) === LEVEL_TOP) { + code = o.indent + code; + } + return [this.makeCode("\n"), this.makeCode(code)]; + }; + + return Comment; + + })(Base); + + exports.Call = Call = (function(superClass1) { + extend1(Call, superClass1); + + function Call(variable, args1, soak) { + this.args = args1 != null ? args1 : []; + this.soak = soak; + this.isNew = false; + this.isSuper = variable === 'super'; + this.variable = this.isSuper ? null : variable; + if (variable instanceof Value && variable.isNotCallable()) { + variable.error("literal is not a function"); + } + } + + Call.prototype.children = ['variable', 'args']; + + Call.prototype.newInstance = function() { + var base, ref3; + base = ((ref3 = this.variable) != null ? ref3.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, base, bref, klass, method, name, nref, variable; + method = o.scope.namedMethod(); + if (method != null ? method.klass : void 0) { + klass = method.klass, name = method.name, variable = method.variable; + if (klass.isComplex()) { + bref = new Literal(o.scope.parent.freeVariable('base')); + base = new Value(new Parens(new Assign(bref, klass))); + variable.base = base; + variable.properties.splice(0, klass.properties.length); + } + if (name.isComplex() || (name instanceof Index && name.index.isAssignable())) { + nref = new Literal(o.scope.parent.freeVariable('name')); + name = new Index(new Assign(nref, name.index)); + variable.properties.pop(); + variable.properties.push(name); + } + accesses = [new Access(new Literal('__super__'))]; + if (method["static"]) { + accesses.push(new Access(new Literal('constructor'))); + } + accesses.push(nref != null ? new Index(nref) : name); + return (new Value(bref != null ? bref : klass, accesses)).compile(o); + } else if (method != null ? method.ctor : void 0) { + return method.name + ".__super__.constructor"; + } else { + return this.error('cannot call super outside of an instance method.'); + } + }; + + 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, j, left, len1, list, ref3, ref4, rite; + if (this.soak) { + if (this.variable) { + if (ifn = unfoldSoak(o, this, 'variable')) { + return ifn; + } + ref3 = new Value(this.variable).cacheReference(o), left = ref3[0], rite = ref3[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; + } + } + ref4 = list.reverse(); + for (j = 0, len1 = ref4.length; j < len1; j++) { + call = ref4[j]; + if (ifn) { + if (call.variable instanceof Call) { + call.variable = ifn; + } else { + call.variable.base = ifn; + } + } + ifn = unfoldSoak(o, call, 'variable'); + } + return ifn; + }; + + Call.prototype.compileNode = function(o) { + var arg, argIndex, compiledArgs, compiledArray, fragments, j, len1, preface, ref3, ref4; + if ((ref3 = this.variable) != null) { + ref3.front = this.front; + } + compiledArray = Splat.compileSplattedArray(o, this.args, true); + if (compiledArray.length) { + return this.compileSplat(o, compiledArray); + } + compiledArgs = []; + ref4 = this.args; + for (argIndex = j = 0, len1 = ref4.length; j < len1; argIndex = ++j) { + arg = ref4[argIndex]; + if (argIndex) { + compiledArgs.push(this.makeCode(", ")); + } + compiledArgs.push.apply(compiledArgs, arg.compileToFragments(o, LEVEL_LIST)); + } + fragments = []; + if (this.isSuper) { + preface = this.superReference(o) + (".call(" + (this.superThis(o))); + if (compiledArgs.length) { + preface += ", "; + } + fragments.push(this.makeCode(preface)); + } else { + if (this.isNew) { + fragments.push(this.makeCode('new ')); + } + fragments.push.apply(fragments, this.variable.compileToFragments(o, LEVEL_ACCESS)); + fragments.push(this.makeCode("(")); + } + fragments.push.apply(fragments, compiledArgs); + fragments.push(this.makeCode(")")); + return fragments; + }; + + Call.prototype.compileSplat = function(o, splatArgs) { + var answer, base, fun, idt, name, ref; + if (this.isSuper) { + return [].concat(this.makeCode((this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")")); + } + if (this.isNew) { + idt = this.tab + TAB; + return [].concat(this.makeCode("(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return Object(result) === result ? result : child;\n" + this.tab + "})("), this.variable.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), splatArgs, this.makeCode(", function(){})")); + } + answer = []; + base = new Value(this.variable); + if ((name = base.properties.pop()) && base.isComplex()) { + ref = o.scope.freeVariable('ref'); + answer = answer.concat(this.makeCode("(" + ref + " = "), base.compileToFragments(o, LEVEL_LIST), this.makeCode(")"), name.compileToFragments(o)); + } else { + fun = base.compileToFragments(o, LEVEL_ACCESS); + if (SIMPLENUM.test(fragmentsToText(fun))) { + fun = this.wrapInBraces(fun); + } + if (name) { + ref = fragmentsToText(fun); + fun.push.apply(fun, name.compileToFragments(o)); + } else { + ref = 'null'; + } + answer = answer.concat(fun); + } + return answer = answer.concat(this.makeCode(".apply(" + ref + ", "), splatArgs, this.makeCode(")")); + }; + + return Call; + + })(Base); + + exports.Extends = Extends = (function(superClass1) { + extend1(Extends, superClass1); + + function Extends(child1, parent1) { + this.child = child1; + this.parent = parent1; + } + + Extends.prototype.children = ['child', 'parent']; + + Extends.prototype.compileToFragments = function(o) { + return new Call(new Value(new Literal(utility('extend', o))), [this.child, this.parent]).compileToFragments(o); + }; + + return Extends; + + })(Base); + + exports.Access = Access = (function(superClass1) { + extend1(Access, superClass1); + + function Access(name1, tag) { + this.name = name1; + this.name.asKey = true; + this.soak = tag === 'soak'; + } + + Access.prototype.children = ['name']; + + Access.prototype.compileToFragments = function(o) { + var name; + name = this.name.compileToFragments(o); + if (IDENTIFIER.test(fragmentsToText(name))) { + name.unshift(this.makeCode(".")); + } else { + name.unshift(this.makeCode("[")); + name.push(this.makeCode("]")); + } + return name; + }; + + Access.prototype.isComplex = NO; + + return Access; + + })(Base); + + exports.Index = Index = (function(superClass1) { + extend1(Index, superClass1); + + function Index(index1) { + this.index = index1; + } + + Index.prototype.children = ['index']; + + Index.prototype.compileToFragments = function(o) { + return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]")); + }; + + Index.prototype.isComplex = function() { + return this.index.isComplex(); + }; + + return Index; + + })(Base); + + exports.Range = Range = (function(superClass1) { + extend1(Range, superClass1); + + Range.prototype.children = ['from', 'to']; + + function Range(from1, to1, tag) { + this.from = from1; + this.to = to1; + this.exclusive = tag === 'exclusive'; + this.equals = this.exclusive ? '' : '='; + } + + Range.prototype.compileVariables = function(o) { + var isComplex, ref3, ref4, ref5, ref6, step; + o = merge(o, { + top: true + }); + isComplex = del(o, 'isComplex'); + ref3 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST, isComplex)), this.fromC = ref3[0], this.fromVar = ref3[1]; + ref4 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST, isComplex)), this.toC = ref4[0], this.toVar = ref4[1]; + if (step = del(o, 'step')) { + ref5 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST, isComplex)), this.step = ref5[0], this.stepVar = ref5[1]; + } + ref6 = [this.fromVar.match(NUMBER), this.toVar.match(NUMBER)], this.fromNum = ref6[0], this.toNum = ref6[1]; + if (this.stepVar) { + return this.stepNum = this.stepVar.match(NUMBER); + } + }; + + Range.prototype.compileNode = function(o) { + var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, ref3, ref4, stepPart, to, varPart; + 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; + } + ref3 = [idx + " <" + this.equals, idx + " >" + this.equals], lt = ref3[0], gt = ref3[1]; + condPart = this.stepNum ? parseNum(this.stepNum[0]) > 0 ? lt + " " + this.toVar : gt + " " + this.toVar : known ? ((ref4 = [parseNum(this.fromNum[0]), parseNum(this.toNum[0])], from = ref4[0], to = ref4[1], ref4), from <= to ? lt + " " + to : gt + " " + to) : (cond = this.stepVar ? this.stepVar + " > 0" : 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 [this.makeCode(varPart + "; " + condPart + "; " + stepPart)]; + }; + + Range.prototype.compileArray = function(o) { + var args, body, cond, hasArgs, i, idt, j, post, pre, range, ref3, ref4, result, results, vars; + if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) { + range = (function() { + results = []; + for (var j = ref3 = +this.fromNum, ref4 = +this.toNum; ref3 <= ref4 ? j <= ref4 : j >= ref4; ref3 <= ref4 ? j++ : j--){ results.push(j); } + return results; + }).apply(this); + if (this.exclusive) { + range.pop(); + } + return [this.makeCode("[" + (range.join(', ')) + "]")]; + } + idt = this.tab + TAB; + i = o.scope.freeVariable('i', { + single: true + }); + result = o.scope.freeVariable('results'); + pre = "\n" + idt + result + " = [];"; + if (this.fromNum && this.toNum) { + o.index = i; + body = fragmentsToText(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(isLiteralArguments) : void 0; + }; + if (hasArgs(this.from) || hasArgs(this.to)) { + args = ', arguments'; + } + return [this.makeCode("(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")")]; + }; + + return Range; + + })(Base); + + exports.Slice = Slice = (function(superClass1) { + extend1(Slice, superClass1); + + Slice.prototype.children = ['range']; + + function Slice(range1) { + this.range = range1; + Slice.__super__.constructor.call(this); + } + + Slice.prototype.compileNode = function(o) { + var compiled, compiledText, from, fromCompiled, ref3, to, toStr; + ref3 = this.range, to = ref3.to, from = ref3.from; + fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')]; + if (to) { + compiled = to.compileToFragments(o, LEVEL_PAREN); + compiledText = fragmentsToText(compiled); + if (!(!this.range.exclusive && +compiledText === -1)) { + toStr = ', ' + (this.range.exclusive ? compiledText : SIMPLENUM.test(compiledText) ? "" + (+compiledText + 1) : (compiled = to.compileToFragments(o, LEVEL_ACCESS), "+" + (fragmentsToText(compiled)) + " + 1 || 9e9")); + } + } + return [this.makeCode(".slice(" + (fragmentsToText(fromCompiled)) + (toStr || '') + ")")]; + }; + + return Slice; + + })(Base); + + exports.Obj = Obj = (function(superClass1) { + extend1(Obj, superClass1); + + 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 answer, dynamicIndex, hasDynamic, i, idt, indent, j, join, k, key, l, lastNoncom, len1, len2, len3, node, oref, prop, props, ref3, value; + props = this.properties; + if (this.generated) { + for (j = 0, len1 = props.length; j < len1; j++) { + node = props[j]; + if (node instanceof Value) { + node.error('cannot have an implicit value in an implicit object'); + } + } + } + for (dynamicIndex = k = 0, len2 = props.length; k < len2; dynamicIndex = ++k) { + prop = props[dynamicIndex]; + if ((prop.variable || prop).base instanceof Parens) { + break; + } + } + hasDynamic = dynamicIndex < props.length; + idt = o.indent += TAB; + lastNoncom = this.lastNonComment(this.properties); + answer = []; + if (hasDynamic) { + oref = o.scope.freeVariable('obj'); + answer.push(this.makeCode("(\n" + idt + oref + " = ")); + } + answer.push(this.makeCode("{" + (props.length === 0 || dynamicIndex === 0 ? '}' : '\n'))); + for (i = l = 0, len3 = props.length; l < len3; i = ++l) { + prop = props[i]; + if (i === dynamicIndex) { + if (i !== 0) { + answer.push(this.makeCode("\n" + idt + "}")); + } + answer.push(this.makeCode(',\n')); + } + join = i === props.length - 1 || i === dynamicIndex - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; + indent = prop instanceof Comment ? '' : idt; + if (hasDynamic && i < dynamicIndex) { + indent += TAB; + } + if (prop instanceof Assign) { + if (prop.context !== 'object') { + prop.operatorToken.error("unexpected " + prop.operatorToken.value); + } + if (prop.variable instanceof Value && prop.variable.hasProperties()) { + prop.variable.error('invalid object key'); + } + } + if (prop instanceof Value && prop["this"]) { + prop = new Assign(prop.properties[0].name, prop, 'object'); + } + if (!(prop instanceof Comment)) { + if (i < dynamicIndex) { + if (!(prop instanceof Assign)) { + prop = new Assign(prop, prop, 'object'); + } + (prop.variable.base || prop.variable).asKey = true; + } else { + if (prop instanceof Assign) { + key = prop.variable; + value = prop.value; + } else { + ref3 = prop.base.cache(o), key = ref3[0], value = ref3[1]; + } + prop = new Assign(new Value(new Literal(oref), [new Access(key)]), value); + } + } + if (indent) { + answer.push(this.makeCode(indent)); + } + answer.push.apply(answer, prop.compileToFragments(o, LEVEL_TOP)); + if (join) { + answer.push(this.makeCode(join)); + } + } + if (hasDynamic) { + answer.push(this.makeCode(",\n" + idt + oref + "\n" + this.tab + ")")); + } else { + if (props.length !== 0) { + answer.push(this.makeCode("\n" + this.tab + "}")); + } + } + if (this.front && !hasDynamic) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + Obj.prototype.assigns = function(name) { + var j, len1, prop, ref3; + ref3 = this.properties; + for (j = 0, len1 = ref3.length; j < len1; j++) { + prop = ref3[j]; + if (prop.assigns(name)) { + return true; + } + } + return false; + }; + + return Obj; + + })(Base); + + exports.Arr = Arr = (function(superClass1) { + extend1(Arr, superClass1); + + function Arr(objs) { + this.objects = objs || []; + } + + Arr.prototype.children = ['objects']; + + Arr.prototype.compileNode = function(o) { + var answer, compiledObjs, fragments, index, j, len1, obj; + if (!this.objects.length) { + return [this.makeCode('[]')]; + } + o.indent += TAB; + answer = Splat.compileSplattedArray(o, this.objects); + if (answer.length) { + return answer; + } + answer = []; + compiledObjs = (function() { + var j, len1, ref3, results; + ref3 = this.objects; + results = []; + for (j = 0, len1 = ref3.length; j < len1; j++) { + obj = ref3[j]; + results.push(obj.compileToFragments(o, LEVEL_LIST)); + } + return results; + }).call(this); + for (index = j = 0, len1 = compiledObjs.length; j < len1; index = ++j) { + fragments = compiledObjs[index]; + if (index) { + answer.push(this.makeCode(", ")); + } + answer.push.apply(answer, fragments); + } + if (fragmentsToText(answer).indexOf('\n') >= 0) { + answer.unshift(this.makeCode("[\n" + o.indent)); + answer.push(this.makeCode("\n" + this.tab + "]")); + } else { + answer.unshift(this.makeCode("[")); + answer.push(this.makeCode("]")); + } + return answer; + }; + + Arr.prototype.assigns = function(name) { + var j, len1, obj, ref3; + ref3 = this.objects; + for (j = 0, len1 = ref3.length; j < len1; j++) { + obj = ref3[j]; + if (obj.assigns(name)) { + return true; + } + } + return false; + }; + + return Arr; + + })(Base); + + exports.Class = Class = (function(superClass1) { + extend1(Class, superClass1); + + function Class(variable1, parent1, body1) { + this.variable = variable1; + this.parent = parent1; + this.body = body1 != null ? body1 : new Block; + this.boundFuncs = []; + this.body.classBody = true; + } + + Class.prototype.children = ['variable', 'parent', 'body']; + + Class.prototype.determineName = function() { + var decl, ref3, tail; + if (!this.variable) { + return null; + } + ref3 = this.variable.properties, tail = ref3[ref3.length - 1]; + decl = tail ? tail instanceof Access && tail.name.value : this.variable.base.value; + if (indexOf.call(STRICT_PROSCRIBED, decl) >= 0) { + this.variable.error("class 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) { + if (node.bound) { + return node.context = name; + } + } + }); + }; + + Class.prototype.addBoundFunctions = function(o) { + var bvar, j, len1, lhs, ref3; + ref3 = this.boundFuncs; + for (j = 0, len1 = ref3.length; j < len1; j++) { + bvar = ref3[j]; + lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o); + this.ctor.body.unshift(new Literal(lhs + " = " + (utility('bind', o)) + "(" + lhs + ", this)")); + } + }; + + Class.prototype.addProperties = function(node, name, o) { + var acc, 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) { + assign.error('cannot define more than one constructor in a class'); + } + if (func.bound) { + assign.error('cannot define a constructor as a bound function'); + } + if (func instanceof Code) { + assign = this.ctor = func; + } else { + this.externalCtor = o.classScope.freeVariable('class'); + assign = new Assign(new Literal(this.externalCtor), func); + } + } else { + if (assign.variable["this"]) { + func["static"] = true; + } else { + acc = base.isComplex() ? new Index(base) : new Access(base); + assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), acc]); + 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) { + return this.traverseChildren(false, (function(_this) { + return function(child) { + var cont, exps, i, j, len1, node, ref3; + cont = true; + if (child instanceof Class) { + return false; + } + if (child instanceof Block) { + ref3 = exps = child.expressions; + for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { + node = ref3[i]; + if (node instanceof Assign && node.variable.looksStatic(name)) { + node.value["static"] = true; + } else if (node instanceof Value && node.isObject(true)) { + cont = false; + exps[i] = _this.addProperties(node, name, o); + } + } + child.expressions = exps = flatten(exps); + } + return cont && !(child instanceof Class); + }; + })(this)); + }; + + 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.externalCtor) { + this.ctor.body.push(new Literal(this.externalCtor + ".apply(this, arguments)")); + } else if (this.parent) { + this.ctor.body.push(new Literal(name + ".__super__.constructor.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 args, argumentsNode, func, jumpNode, klass, lname, name, ref3, superClass; + if (jumpNode = this.body.jumps()) { + jumpNode.error('Class bodies cannot contain pure statements'); + } + if (argumentsNode = this.body.contains(isLiteralArguments)) { + argumentsNode.error("Class bodies shouldn't reference arguments"); + } + name = this.determineName() || '_Class'; + if (name.reserved) { + name = "_" + name; + } + lname = new Literal(name); + func = new Code([], Block.wrap([this.body])); + args = []; + o.classScope = func.makeScope(o.scope); + this.hoistDirectivePrologue(); + this.setContext(name); + this.walkBody(name, o); + this.ensureConstructor(name); + this.addBoundFunctions(o); + this.body.spaced = true; + this.body.expressions.push(lname); + if (this.parent) { + superClass = new Literal(o.classScope.freeVariable('superClass', { + reserve: false + })); + this.body.expressions.unshift(new Extends(lname, superClass)); + func.params.push(new Param(superClass)); + args.push(this.parent); + } + (ref3 = this.body.expressions).unshift.apply(ref3, this.directives); + klass = new Parens(new Call(func, args)); + if (this.variable) { + klass = new Assign(this.variable, klass); + } + return klass.compileToFragments(o); + }; + + return Class; + + })(Base); + + exports.Assign = Assign = (function(superClass1) { + extend1(Assign, superClass1); + + function Assign(variable1, value1, context, options) { + var forbidden, name, ref3; + this.variable = variable1; + this.value = value1; + this.context = context; + if (options == null) { + options = {}; + } + this.param = options.param, this.subpattern = options.subpattern, this.operatorToken = options.operatorToken; + forbidden = (ref3 = (name = this.variable.unwrapAll().value), indexOf.call(STRICT_PROSCRIBED, ref3) >= 0); + if (forbidden && this.context !== 'object') { + this.variable.error("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 answer, compiledName, isValue, j, name, properties, prototype, ref3, ref4, ref5, ref6, ref7, val, varBase; + 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 ((ref3 = this.context) === '||=' || ref3 === '&&=' || ref3 === '?=') { + return this.compileConditional(o); + } + if ((ref4 = this.context) === '**=' || ref4 === '//=' || ref4 === '%%=') { + return this.compileSpecialMath(o); + } + } + if (this.value instanceof Code) { + if (this.value["static"]) { + this.value.klass = this.variable.base; + this.value.name = this.variable.properties[0]; + this.value.variable = this.variable; + } else if (((ref5 = this.variable.properties) != null ? ref5.length : void 0) >= 2) { + ref6 = this.variable.properties, properties = 3 <= ref6.length ? slice.call(ref6, 0, j = ref6.length - 2) : (j = 0, []), prototype = ref6[j++], name = ref6[j++]; + if (((ref7 = prototype.name) != null ? ref7.value : void 0) === 'prototype') { + this.value.klass = new Value(this.variable.base, properties); + this.value.name = name; + this.value.variable = this.variable; + } + } + } + if (!this.context) { + varBase = this.variable.unwrapAll(); + if (!varBase.isAssignable()) { + this.variable.error("\"" + (this.variable.compile(o)) + "\" cannot be assigned"); + } + if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) { + if (this.param) { + o.scope.add(varBase.value, 'var'); + } else { + o.scope.find(varBase.value); + } + } + } + val = this.value.compileToFragments(o, LEVEL_LIST); + if (isValue && this.variable.base instanceof Obj) { + this.variable.front = true; + } + compiledName = this.variable.compileToFragments(o, LEVEL_LIST); + if (this.context === 'object') { + return compiledName.concat(this.makeCode(": "), val); + } + answer = compiledName.concat(this.makeCode(" " + (this.context || '=') + " "), val); + if (o.level <= LEVEL_LIST) { + return answer; + } else { + return this.wrapInBraces(answer); + } + }; + + Assign.prototype.compilePatternMatch = function(o) { + var acc, assigns, code, defaultValue, expandedIdx, fragments, i, idx, isObject, ivar, j, len1, name, obj, objects, olen, ref, ref3, ref4, ref5, ref6, ref7, rest, top, val, value, vvar, vvarText; + top = o.level === LEVEL_TOP; + value = this.value; + objects = this.variable.base.objects; + if (!(olen = objects.length)) { + code = value.compileToFragments(o); + if (o.level >= LEVEL_OP) { + return this.wrapInBraces(code); + } else { + return code; + } + } + obj = objects[0]; + if (olen === 1 && obj instanceof Expansion) { + obj.error('Destructuring assignment has no target'); + } + isObject = this.variable.isObject(); + if (top && olen === 1 && !(obj instanceof Splat)) { + defaultValue = null; + if (obj instanceof Assign && obj.context === 'object') { + ref3 = obj, (ref4 = ref3.variable, idx = ref4.base), obj = ref3.value; + if (obj instanceof Assign) { + defaultValue = obj.value; + obj = obj.variable; + } + } else { + if (obj instanceof Assign) { + defaultValue = obj.value; + obj = obj.variable; + } + idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0); + } + acc = IDENTIFIER.test(idx.unwrap().value); + value = new Value(value); + value.properties.push(new (acc ? Access : Index)(idx)); + if (ref5 = obj.unwrap().value, indexOf.call(RESERVED, ref5) >= 0) { + obj.error("assignment to a reserved word: " + (obj.compile(o))); + } + if (defaultValue) { + value = new Op('?', value, defaultValue); + } + return new Assign(obj, value, null, { + param: this.param + }).compileToFragments(o, LEVEL_TOP); + } + vvar = value.compileToFragments(o, LEVEL_LIST); + vvarText = fragmentsToText(vvar); + assigns = []; + expandedIdx = false; + if (!IDENTIFIER.test(vvarText) || this.variable.assigns(vvarText)) { + assigns.push([this.makeCode((ref = o.scope.freeVariable('ref')) + " = ")].concat(slice.call(vvar))); + vvar = [this.makeCode(ref)]; + vvarText = ref; + } + for (i = j = 0, len1 = objects.length; j < len1; i = ++j) { + obj = objects[i]; + idx = i; + if (!expandedIdx && obj instanceof Splat) { + name = obj.name.unwrap().value; + obj = obj.unwrap(); + val = olen + " <= " + vvarText + ".length ? " + (utility('slice', o)) + ".call(" + vvarText + ", " + i; + if (rest = olen - i - 1) { + ivar = o.scope.freeVariable('i', { + single: true + }); + val += ", " + ivar + " = " + vvarText + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])"; + } else { + val += ") : []"; + } + val = new Literal(val); + expandedIdx = ivar + "++"; + } else if (!expandedIdx && obj instanceof Expansion) { + if (rest = olen - i - 1) { + if (rest === 1) { + expandedIdx = vvarText + ".length - 1"; + } else { + ivar = o.scope.freeVariable('i', { + single: true + }); + val = new Literal(ivar + " = " + vvarText + ".length - " + rest); + expandedIdx = ivar + "++"; + assigns.push(val.compileToFragments(o, LEVEL_LIST)); + } + } + continue; + } else { + if (obj instanceof Splat || obj instanceof Expansion) { + obj.error("multiple splats/expansions are disallowed in an assignment"); + } + defaultValue = null; + if (obj instanceof Assign && obj.context === 'object') { + ref6 = obj, (ref7 = ref6.variable, idx = ref7.base), obj = ref6.value; + if (obj instanceof Assign) { + defaultValue = obj.value; + obj = obj.variable; + } + } else { + if (obj instanceof Assign) { + defaultValue = obj.value; + obj = obj.variable; + } + idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(expandedIdx || idx); + } + name = obj.unwrap().value; + acc = IDENTIFIER.test(idx.unwrap().value); + val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]); + if (defaultValue) { + val = new Op('?', val, defaultValue); + } + } + if ((name != null) && indexOf.call(RESERVED, name) >= 0) { + obj.error("assignment to a reserved word: " + (obj.compile(o))); + } + assigns.push(new Assign(obj, val, null, { + param: this.param, + subpattern: true + }).compileToFragments(o, LEVEL_LIST)); + } + if (!(top || this.subpattern)) { + assigns.push(vvar); + } + fragments = this.joinFragmentArrays(assigns, ', '); + if (o.level < LEVEL_LIST) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + }; + + Assign.prototype.compileConditional = function(o) { + var fragments, left, ref3, right; + ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1]; + if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) { + this.variable.error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been declared before"); + } + if (indexOf.call(this.context, "?") >= 0) { + o.isExistentialEquals = true; + return new If(new Existence(left), right, { + type: 'if' + }).addElse(new Assign(right, this.value, '=')).compileToFragments(o); + } else { + fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o); + if (o.level <= LEVEL_LIST) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + } + }; + + Assign.prototype.compileSpecialMath = function(o) { + var left, ref3, right; + ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1]; + return new Assign(left, new Op(this.context.slice(0, -1), right, this.value)).compileToFragments(o); + }; + + Assign.prototype.compileSplice = function(o) { + var answer, exclusive, from, fromDecl, fromRef, name, ref3, ref4, ref5, to, valDef, valRef; + ref3 = this.variable.properties.pop().range, from = ref3.from, to = ref3.to, exclusive = ref3.exclusive; + name = this.variable.compile(o); + if (from) { + ref4 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = ref4[0], fromRef = ref4[1]; + } else { + fromDecl = fromRef = '0'; + } + if (to) { + if (from instanceof Value && from.isSimpleNumber() && to instanceof Value && 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"; + } + ref5 = this.value.cache(o, LEVEL_LIST), valDef = ref5[0], valRef = ref5[1]; + answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef); + if (o.level > LEVEL_TOP) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + return Assign; + + })(Base); + + exports.Code = Code = (function(superClass1) { + extend1(Code, superClass1); + + function Code(params, body, tag) { + this.params = params || []; + this.body = body || new Block; + this.bound = tag === 'boundfunc'; + this.isGenerator = !!this.body.contains(function(node) { + var ref3; + return node instanceof Op && ((ref3 = node.operator) === 'yield' || ref3 === 'yield*'); + }); + } + + Code.prototype.children = ['params', 'body']; + + Code.prototype.isStatement = function() { + return !!this.ctor; + }; + + Code.prototype.jumps = NO; + + Code.prototype.makeScope = function(parentScope) { + return new Scope(parentScope, this.body, this); + }; + + Code.prototype.compileNode = function(o) { + var answer, boundfunc, code, exprs, i, j, k, l, len1, len2, len3, len4, len5, len6, lit, m, p, param, params, q, r, ref, ref3, ref4, ref5, ref6, ref7, ref8, splats, uniqs, val, wasEmpty, wrapper; + if (this.bound && ((ref3 = o.scope.method) != null ? ref3.bound : void 0)) { + this.context = o.scope.method.context; + } + if (this.bound && !this.context) { + this.context = '_this'; + wrapper = new Code([new Param(new Literal(this.context))], new Block([this])); + boundfunc = new Call(wrapper, [new Literal('this')]); + boundfunc.updateLocationDataIfMissing(this.locationData); + return boundfunc.compileNode(o); + } + o.scope = del(o, 'classScope') || this.makeScope(o.scope); + o.scope.shared = del(o, 'sharedScope'); + o.indent += TAB; + delete o.bare; + delete o.isExistentialEquals; + params = []; + exprs = []; + ref4 = this.params; + for (j = 0, len1 = ref4.length; j < len1; j++) { + param = ref4[j]; + if (!(param instanceof Expansion)) { + o.scope.parameter(param.asReference(o)); + } + } + ref5 = this.params; + for (k = 0, len2 = ref5.length; k < len2; k++) { + param = ref5[k]; + if (!(param.splat || param instanceof Expansion)) { + continue; + } + ref6 = this.params; + for (l = 0, len3 = ref6.length; l < len3; l++) { + p = ref6[l]; + if (!(p instanceof Expansion) && p.name.value) { + o.scope.add(p.name.value, 'var', true); + } + } + splats = new Assign(new Value(new Arr((function() { + var len4, m, ref7, results; + ref7 = this.params; + results = []; + for (m = 0, len4 = ref7.length; m < len4; m++) { + p = ref7[m]; + results.push(p.asReference(o)); + } + return results; + }).call(this))), new Value(new Literal('arguments'))); + break; + } + ref7 = this.params; + for (m = 0, len4 = ref7.length; m < len4; m++) { + param = ref7[m]; + 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) { + (ref8 = this.body.expressions).unshift.apply(ref8, exprs); + } + for (i = q = 0, len5 = params.length; q < len5; i = ++q) { + p = params[i]; + params[i] = p.compileToFragments(o); + o.scope.parameter(fragmentsToText(params[i])); + } + uniqs = []; + this.eachParamName(function(name, node) { + if (indexOf.call(uniqs, name) >= 0) { + node.error("multiple parameters named " + name); + } + return uniqs.push(name); + }); + if (!(wasEmpty || this.noReturn)) { + this.body.makeReturn(); + } + code = 'function'; + if (this.isGenerator) { + code += '*'; + } + if (this.ctor) { + code += ' ' + this.name; + } + code += '('; + answer = [this.makeCode(code)]; + for (i = r = 0, len6 = params.length; r < len6; i = ++r) { + p = params[i]; + if (i) { + answer.push(this.makeCode(", ")); + } + answer.push.apply(answer, p); + } + answer.push(this.makeCode(') {')); + if (!this.body.isEmpty()) { + answer = answer.concat(this.makeCode("\n"), this.body.compileWithDeclarations(o), this.makeCode("\n" + this.tab)); + } + answer.push(this.makeCode('}')); + if (this.ctor) { + return [this.makeCode(this.tab)].concat(slice.call(answer)); + } + if (this.front || (o.level >= LEVEL_ACCESS)) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + Code.prototype.eachParamName = function(iterator) { + var j, len1, param, ref3, results; + ref3 = this.params; + results = []; + for (j = 0, len1 = ref3.length; j < len1; j++) { + param = ref3[j]; + results.push(param.eachName(iterator)); + } + return results; + }; + + Code.prototype.traverseChildren = function(crossScope, func) { + if (crossScope) { + return Code.__super__.traverseChildren.call(this, crossScope, func); + } + }; + + return Code; + + })(Base); + + exports.Param = Param = (function(superClass1) { + extend1(Param, superClass1); + + function Param(name1, value1, splat) { + var name, ref3, token; + this.name = name1; + this.value = value1; + this.splat = splat; + if (ref3 = (name = this.name.unwrapAll().value), indexOf.call(STRICT_PROSCRIBED, ref3) >= 0) { + this.name.error("parameter name \"" + name + "\" is not allowed"); + } + if (this.name instanceof Obj && this.name.generated) { + token = this.name.objects[0].operatorToken; + token.error("unexpected " + token.value); + } + } + + Param.prototype.children = ['name', 'value']; + + Param.prototype.compileToFragments = function(o) { + return this.name.compileToFragments(o, LEVEL_LIST); + }; + + Param.prototype.asReference = function(o) { + var name, node; + if (this.reference) { + return this.reference; + } + node = this.name; + if (node["this"]) { + name = node.properties[0].name.value; + if (name.reserved) { + name = "_" + name; + } + node = new Literal(o.scope.freeVariable(name)); + } else if (node.isComplex()) { + node = new Literal(o.scope.freeVariable('arg')); + } + node = new Value(node); + if (this.splat) { + node = new Splat(node); + } + node.updateLocationDataIfMissing(this.locationData); + return this.reference = node; + }; + + Param.prototype.isComplex = function() { + return this.name.isComplex(); + }; + + Param.prototype.eachName = function(iterator, name) { + var atParam, j, len1, node, obj, ref3; + if (name == null) { + name = this.name; + } + atParam = function(obj) { + return iterator("@" + obj.properties[0].name.value, obj); + }; + if (name instanceof Literal) { + return iterator(name.value, name); + } + if (name instanceof Value) { + return atParam(name); + } + ref3 = name.objects; + for (j = 0, len1 = ref3.length; j < len1; j++) { + obj = ref3[j]; + if (obj instanceof Assign && (obj.context == null)) { + obj = obj.variable; + } + if (obj instanceof Assign) { + this.eachName(iterator, obj.value.unwrap()); + } else if (obj instanceof Splat) { + node = obj.name.unwrap(); + iterator(node.value, node); + } else if (obj instanceof Value) { + if (obj.isArray() || obj.isObject()) { + this.eachName(iterator, obj.base); + } else if (obj["this"]) { + atParam(obj); + } else { + iterator(obj.base.value, obj.base); + } + } else if (!(obj instanceof Expansion)) { + obj.error("illegal parameter " + (obj.compile())); + } + } + }; + + return Param; + + })(Base); + + exports.Splat = Splat = (function(superClass1) { + extend1(Splat, superClass1); + + 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.compileToFragments = function(o) { + return this.name.compileToFragments(o); + }; + + Splat.prototype.unwrap = function() { + return this.name; + }; + + Splat.compileSplattedArray = function(o, list, apply) { + var args, base, compiledNode, concatPart, fragments, i, index, j, last, len1, node; + index = -1; + while ((node = list[++index]) && !(node instanceof Splat)) { + continue; + } + if (index >= list.length) { + return []; + } + if (list.length === 1) { + node = list[0]; + fragments = node.compileToFragments(o, LEVEL_LIST); + if (apply) { + return fragments; + } + return [].concat(node.makeCode((utility('slice', o)) + ".call("), fragments, node.makeCode(")")); + } + args = list.slice(index); + for (i = j = 0, len1 = args.length; j < len1; i = ++j) { + node = args[i]; + compiledNode = node.compileToFragments(o, LEVEL_LIST); + args[i] = node instanceof Splat ? [].concat(node.makeCode((utility('slice', o)) + ".call("), compiledNode, node.makeCode(")")) : [].concat(node.makeCode("["), compiledNode, node.makeCode("]")); + } + if (index === 0) { + node = list[0]; + concatPart = node.joinFragmentArrays(args.slice(1), ', '); + return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")")); + } + base = (function() { + var k, len2, ref3, results; + ref3 = list.slice(0, index); + results = []; + for (k = 0, len2 = ref3.length; k < len2; k++) { + node = ref3[k]; + results.push(node.compileToFragments(o, LEVEL_LIST)); + } + return results; + })(); + base = list[0].joinFragmentArrays(base, ', '); + concatPart = list[index].joinFragmentArrays(args, ', '); + last = list[list.length - 1]; + return [].concat(list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, last.makeCode(")")); + }; + + return Splat; + + })(Base); + + exports.Expansion = Expansion = (function(superClass1) { + extend1(Expansion, superClass1); + + function Expansion() { + return Expansion.__super__.constructor.apply(this, arguments); + } + + Expansion.prototype.isComplex = NO; + + Expansion.prototype.compileNode = function(o) { + return this.error('Expansion must be used inside a destructuring assignment or parameter list'); + }; + + Expansion.prototype.asReference = function(o) { + return this; + }; + + Expansion.prototype.eachName = function(iterator) {}; + + return Expansion; + + })(Base); + + exports.While = While = (function(superClass1) { + extend1(While, superClass1); + + 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(body1) { + this.body = body1; + return this; + }; + + While.prototype.jumps = function() { + var expressions, j, jumpNode, len1, node; + expressions = this.body.expressions; + if (!expressions.length) { + return false; + } + for (j = 0, len1 = expressions.length; j < len1; j++) { + node = expressions[j]; + if (jumpNode = node.jumps({ + loop: true + })) { + return jumpNode; + } + } + return false; + }; + + While.prototype.compileNode = function(o) { + var answer, body, rvar, set; + o.indent += TAB; + set = ''; + body = this.body; + if (body.isEmpty()) { + body = this.makeCode(''); + } 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 = [].concat(this.makeCode("\n"), body.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab)); + } + answer = [].concat(this.makeCode(set + this.tab + "while ("), this.condition.compileToFragments(o, LEVEL_PAREN), this.makeCode(") {"), body, this.makeCode("}")); + if (this.returns) { + answer.push(this.makeCode("\n" + this.tab + "return " + rvar + ";")); + } + return answer; + }; + + return While; + + })(Base); + + exports.Op = Op = (function(superClass1) { + var CONVERSIONS, INVERSIONS; + + extend1(Op, superClass1); + + 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', + 'yieldfrom': 'yield*' + }; + + INVERSIONS = { + '!==': '===', + '===': '!==' + }; + + Op.prototype.children = ['first', 'second']; + + Op.prototype.isSimpleNumber = NO; + + Op.prototype.isYield = function() { + var ref3; + return (ref3 = this.operator) === 'yield' || ref3 === 'yield*'; + }; + + Op.prototype.isYieldReturn = function() { + return this.isYield() && this.first instanceof Return; + }; + + Op.prototype.isUnary = function() { + return !this.second; + }; + + Op.prototype.isComplex = function() { + var ref3; + return !(this.isUnary() && ((ref3 = this.operator) === '+' || ref3 === '-') && this.first instanceof Value && this.first.isSimpleNumber()); + }; + + Op.prototype.isChainable = function() { + var ref3; + return (ref3 = this.operator) === '<' || ref3 === '>' || ref3 === '>=' || ref3 === '<=' || ref3 === '===' || ref3 === '!=='; + }; + + Op.prototype.invert = function() { + var allInvertable, curr, fst, op, ref3; + 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 && ((ref3 = fst.operator) === '!' || ref3 === 'in' || ref3 === 'instanceof')) { + return fst; + } else { + return new Op('!', this); + } + }; + + Op.prototype.unfoldSoak = function(o) { + var ref3; + return ((ref3 = this.operator) === '++' || ref3 === '--' || ref3 === 'delete') && unfoldSoak(o, this, 'first'); + }; + + Op.prototype.generateDo = function(exp) { + var call, func, j, len1, param, passedParams, ref, ref3; + passedParams = []; + func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp; + ref3 = func.params || []; + for (j = 0, len1 = ref3.length; j < len1; j++) { + param = ref3[j]; + 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 answer, isChain, lhs, ref3, ref4, rhs; + isChain = this.isChainable() && this.first.isChainable(); + if (!isChain) { + this.first.front = this.front; + } + if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) { + this.error('delete operand may not be argument or var'); + } + if (((ref3 = this.operator) === '--' || ref3 === '++') && (ref4 = this.first.unwrapAll().value, indexOf.call(STRICT_PROSCRIBED, ref4) >= 0)) { + this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\""); + } + if (this.isYield()) { + return this.compileYield(o); + } + if (this.isUnary()) { + return this.compileUnary(o); + } + if (isChain) { + return this.compileChain(o); + } + switch (this.operator) { + case '?': + return this.compileExistence(o); + case '**': + return this.compilePower(o); + case '//': + return this.compileFloorDivision(o); + case '%%': + return this.compileModulo(o); + default: + lhs = this.first.compileToFragments(o, LEVEL_OP); + rhs = this.second.compileToFragments(o, LEVEL_OP); + answer = [].concat(lhs, this.makeCode(" " + this.operator + " "), rhs); + if (o.level <= LEVEL_OP) { + return answer; + } else { + return this.wrapInBraces(answer); + } + } + }; + + Op.prototype.compileChain = function(o) { + var fragments, fst, ref3, shared; + ref3 = this.first.second.cache(o), this.first.second = ref3[0], shared = ref3[1]; + fst = this.first.compileToFragments(o, LEVEL_OP); + fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP)); + return this.wrapInBraces(fragments); + }; + + 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).compileToFragments(o); + }; + + Op.prototype.compileUnary = function(o) { + var op, parts, plusMinus; + parts = []; + op = this.operator; + parts.push([this.makeCode(op)]); + if (op === '!' && this.first instanceof Existence) { + this.first.negated = !this.first.negated; + return this.first.compileToFragments(o); + } + if (o.level >= LEVEL_ACCESS) { + return (new Parens(this)).compileToFragments(o); + } + plusMinus = op === '+' || op === '-'; + if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) { + parts.push([this.makeCode(' ')]); + } + if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) { + this.first = new Parens(this.first); + } + parts.push(this.first.compileToFragments(o, LEVEL_OP)); + if (this.flip) { + parts.reverse(); + } + return this.joinFragmentArrays(parts, ''); + }; + + Op.prototype.compileYield = function(o) { + var op, parts; + parts = []; + op = this.operator; + if (o.scope.parent == null) { + this.error('yield statements must occur within a function generator.'); + } + if (indexOf.call(Object.keys(this.first), 'expression') >= 0 && !(this.first instanceof Throw)) { + if (this.isYieldReturn()) { + parts.push(this.first.compileToFragments(o, LEVEL_TOP)); + } else if (this.first.expression != null) { + parts.push(this.first.expression.compileToFragments(o, LEVEL_OP)); + } + } else { + parts.push([this.makeCode("(" + op + " ")]); + parts.push(this.first.compileToFragments(o, LEVEL_OP)); + parts.push([this.makeCode(")")]); + } + return this.joinFragmentArrays(parts, ''); + }; + + Op.prototype.compilePower = function(o) { + var pow; + pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]); + return new Call(pow, [this.first, this.second]).compileToFragments(o); + }; + + Op.prototype.compileFloorDivision = function(o) { + var div, floor; + floor = new Value(new Literal('Math'), [new Access(new Literal('floor'))]); + div = new Op('/', this.first, this.second); + return new Call(floor, [div]).compileToFragments(o); + }; + + Op.prototype.compileModulo = function(o) { + var mod; + mod = new Value(new Literal(utility('modulo', o))); + return new Call(mod, [this.first, this.second]).compileToFragments(o); + }; + + Op.prototype.toString = function(idt) { + return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); + }; + + return Op; + + })(Base); + + exports.In = In = (function(superClass1) { + extend1(In, superClass1); + + 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, j, len1, obj, ref3; + if (this.array instanceof Value && this.array.isArray() && this.array.base.objects.length) { + ref3 = this.array.base.objects; + for (j = 0, len1 = ref3.length; j < len1; j++) { + obj = ref3[j]; + 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, j, len1, ref, ref3, ref4, ref5, sub, tests; + ref3 = this.object.cache(o, LEVEL_OP), sub = ref3[0], ref = ref3[1]; + ref4 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = ref4[0], cnj = ref4[1]; + tests = []; + ref5 = this.array.base.objects; + for (i = j = 0, len1 = ref5.length; j < len1; i = ++j) { + item = ref5[i]; + if (i) { + tests.push(this.makeCode(cnj)); + } + tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS)); + } + if (o.level < LEVEL_OP) { + return tests; + } else { + return this.wrapInBraces(tests); + } + }; + + In.prototype.compileLoopTest = function(o) { + var fragments, ref, ref3, sub; + ref3 = this.object.cache(o, LEVEL_LIST), sub = ref3[0], ref = ref3[1]; + fragments = [].concat(this.makeCode(utility('indexOf', o) + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0'))); + if (fragmentsToText(sub) === fragmentsToText(ref)) { + return fragments; + } + fragments = sub.concat(this.makeCode(', '), fragments); + if (o.level < LEVEL_LIST) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + }; + + In.prototype.toString = function(idt) { + return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : '')); + }; + + return In; + + })(Base); + + exports.Try = Try = (function(superClass1) { + extend1(Try, superClass1); + + function Try(attempt, errorVariable, recovery, ensure) { + this.attempt = attempt; + this.errorVariable = errorVariable; + this.recovery = recovery; + this.ensure = ensure; + } + + Try.prototype.children = ['attempt', 'recovery', 'ensure']; + + Try.prototype.isStatement = YES; + + Try.prototype.jumps = function(o) { + var ref3; + return this.attempt.jumps(o) || ((ref3 = this.recovery) != null ? ref3.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, generatedErrorVariableName, placeholder, tryPart; + o.indent += TAB; + tryPart = this.attempt.compileToFragments(o, LEVEL_TOP); + catchPart = this.recovery ? (generatedErrorVariableName = o.scope.freeVariable('error'), placeholder = new Literal(generatedErrorVariableName), this.errorVariable ? this.recovery.unshift(new Assign(this.errorVariable, placeholder)) : void 0, [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}"))) : !(this.ensure || this.recovery) ? [this.makeCode(" catch (" + generatedErrorVariableName + ") {}")] : []; + ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : []; + return [].concat(this.makeCode(this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart); + }; + + return Try; + + })(Base); + + exports.Throw = Throw = (function(superClass1) { + extend1(Throw, superClass1); + + 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 [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";")); + }; + + return Throw; + + })(Base); + + exports.Existence = Existence = (function(superClass1) { + extend1(Existence, superClass1); + + function Existence(expression) { + this.expression = expression; + } + + Existence.prototype.children = ['expression']; + + Existence.prototype.invert = NEGATE; + + Existence.prototype.compileNode = function(o) { + var cmp, cnj, code, ref3; + this.expression.front = this.front; + code = this.expression.compile(o, LEVEL_OP); + if (IDENTIFIER.test(code) && !o.scope.check(code)) { + ref3 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = ref3[0], cnj = ref3[1]; + code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null"; + } else { + code = code + " " + (this.negated ? '==' : '!=') + " null"; + } + return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")]; + }; + + return Existence; + + })(Base); + + exports.Parens = Parens = (function(superClass1) { + extend1(Parens, superClass1); + + function Parens(body1) { + this.body = body1; + } + + 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, expr, fragments; + expr = this.body.unwrap(); + if (expr instanceof Value && expr.isAtomic()) { + expr.front = this.front; + return expr.compileToFragments(o); + } + fragments = expr.compileToFragments(o, LEVEL_PAREN); + bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns)); + if (bare) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + }; + + return Parens; + + })(Base); + + exports.For = For = (function(superClass1) { + extend1(For, superClass1); + + function For(body, source) { + var ref3; + 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) { + ref3 = [this.index, this.name], this.name = ref3[0], this.index = ref3[1]; + } + if (this.index instanceof Value) { + this.index.error('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) { + this.index.error('indexes do not apply to range loops'); + } + if (this.range && this.pattern) { + this.name.error('cannot pattern match over range loops'); + } + if (this.own && !this.object) { + this.name.error('cannot use own with for-in'); + } + this.returns = false; + } + + For.prototype.children = ['body', 'source', 'guard', 'step']; + + For.prototype.compileNode = function(o) { + var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, last, lvar, name, namePart, ref, ref3, ref4, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart; + body = Block.wrap([this.body]); + ref3 = body.expressions, last = ref3[ref3.length - 1]; + if ((last != null ? last.jumps() : void 0) instanceof Return) { + this.returns = false; + } + source = this.range ? this.source.base : this.source; + scope = o.scope; + if (!this.pattern) { + 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', { + single: true + }); + kvar = (this.range && name) || index || ivar; + kvarAssign = kvar !== ivar ? kvar + " = " : ""; + if (this.step && !this.range) { + ref4 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST, isComplexOrAssignable)), step = ref4[0], stepVar = ref4[1]; + stepNum = stepVar.match(NUMBER); + } + if (this.pattern) { + name = ivar; + } + varPart = ''; + guardPart = ''; + defPart = ''; + idt1 = this.tab + TAB; + if (this.range) { + forPartFragments = source.compileToFragments(merge(o, { + index: ivar, + name: name, + step: this.step, + isComplex: isComplexOrAssignable + })); + } 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) { + if (step !== stepVar) { + defPart += "" + this.tab + step + ";\n"; + } + if (!(this.step && stepNum && (down = parseNum(stepNum[0]) < 0))) { + lvar = scope.freeVariable('len'); + } + declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length"; + declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1"; + compare = ivar + " < " + lvar; + compareDown = ivar + " >= 0"; + if (this.step) { + if (stepNum) { + if (down) { + compare = compareDown; + declare = declareDown; + } + } else { + compare = stepVar + " > 0 ? " + compare + " : " + compareDown; + declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")"; + } + increment = ivar + " += " + stepVar; + } else { + increment = "" + (kvar !== ivar ? "++" + ivar : ivar + "++"); + } + forPartFragments = [this.makeCode(declare + "; " + compare + "; " + kvarAssign + increment)]; + } + } + 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 + "]"))); + } + defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body)); + if (namePart) { + varPart = "\n" + idt1 + namePart + ";"; + } + if (this.object) { + forPartFragments = [this.makeCode(kvar + " in " + svar)]; + if (this.own) { + guardPart = "\n" + idt1 + "if (!" + (utility('hasProp', o)) + ".call(" + svar + ", " + kvar + ")) continue;"; + } + } + bodyFragments = body.compileToFragments(merge(o, { + indent: idt1 + }), LEVEL_TOP); + if (bodyFragments && (bodyFragments.length > 0)) { + bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n")); + } + return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode(this.tab + "}" + (returnResult || ''))); + }; + + For.prototype.pluckDirectCall = function(o, body) { + var base, defs, expr, fn, idx, j, len1, ref, ref3, ref4, ref5, ref6, ref7, ref8, ref9, val; + defs = []; + ref3 = body.expressions; + for (idx = j = 0, len1 = ref3.length; j < len1; idx = ++j) { + expr = ref3[idx]; + expr = expr.unwrapAll(); + if (!(expr instanceof Call)) { + continue; + } + val = (ref4 = expr.variable) != null ? ref4.unwrapAll() : void 0; + if (!((val instanceof Code) || (val instanceof Value && ((ref5 = val.base) != null ? ref5.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((ref6 = (ref7 = val.properties[0].name) != null ? ref7.value : void 0) === 'call' || ref6 === 'apply')))) { + continue; + } + fn = ((ref8 = val.base) != null ? ref8.unwrapAll() : void 0) || val; + ref = new Literal(o.scope.freeVariable('fn')); + base = new Value(ref); + if (val.base) { + ref9 = [base, val], val.base = ref9[0], base = ref9[1]; + } + body.expressions[idx] = new Call(base, expr.args); + defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n')); + } + return defs; + }; + + return For; + + })(While); + + exports.Switch = Switch = (function(superClass1) { + extend1(Switch, superClass1); + + 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, j, jumpNode, len1, ref3, ref4, ref5; + if (o == null) { + o = { + block: true + }; + } + ref3 = this.cases; + for (j = 0, len1 = ref3.length; j < len1; j++) { + ref4 = ref3[j], conds = ref4[0], block = ref4[1]; + if (jumpNode = block.jumps(o)) { + return jumpNode; + } + } + return (ref5 = this.otherwise) != null ? ref5.jumps(o) : void 0; + }; + + Switch.prototype.makeReturn = function(res) { + var j, len1, pair, ref3, ref4; + ref3 = this.cases; + for (j = 0, len1 = ref3.length; j < len1; j++) { + pair = ref3[j]; + pair[1].makeReturn(res); + } + if (res) { + this.otherwise || (this.otherwise = new Block([new Literal('void 0')])); + } + if ((ref4 = this.otherwise) != null) { + ref4.makeReturn(res); + } + return this; + }; + + Switch.prototype.compileNode = function(o) { + var block, body, cond, conditions, expr, fragments, i, idt1, idt2, j, k, len1, len2, ref3, ref4, ref5; + idt1 = o.indent + TAB; + idt2 = o.indent = idt1 + TAB; + fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n")); + ref3 = this.cases; + for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { + ref4 = ref3[i], conditions = ref4[0], block = ref4[1]; + ref5 = flatten([conditions]); + for (k = 0, len2 = ref5.length; k < len2; k++) { + cond = ref5[k]; + if (!this.subject) { + cond = cond.invert(); + } + fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n")); + } + if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) { + fragments = fragments.concat(body, this.makeCode('\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; + } + fragments.push(cond.makeCode(idt2 + 'break;\n')); + } + if (this.otherwise && this.otherwise.expressions.length) { + fragments.push.apply(fragments, [this.makeCode(idt1 + "default:\n")].concat(slice.call(this.otherwise.compileToFragments(o, LEVEL_TOP)), [this.makeCode("\n")])); + } + fragments.push(this.makeCode(this.tab + '}')); + return fragments; + }; + + return Switch; + + })(Base); + + exports.If = If = (function(superClass1) { + extend1(If, superClass1); + + function If(condition, body1, options) { + this.body = body1; + 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 ref3; + return (ref3 = this.body) != null ? ref3.unwrap() : void 0; + }; + + If.prototype.elseBodyNode = function() { + var ref3; + return (ref3 = this.elseBody) != null ? ref3.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); + this.elseBody.updateLocationDataIfMissing(elseBody.locationData); + } + return this; + }; + + If.prototype.isStatement = function(o) { + var ref3; + return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((ref3 = this.elseBodyNode()) != null ? ref3.isStatement(o) : void 0); + }; + + If.prototype.jumps = function(o) { + var ref3; + return this.body.jumps(o) || ((ref3 = this.elseBody) != null ? ref3.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 answer, body, child, cond, exeq, ifPart, indent; + child = del(o, 'chainChild'); + exeq = del(o, 'isExistentialEquals'); + if (exeq) { + return new If(this.condition.invert(), this.elseBodyNode(), { + type: 'if' + }).compileToFragments(o); + } + indent = o.indent + TAB; + cond = this.condition.compileToFragments(o, LEVEL_PAREN); + body = this.ensureBlock(this.body).compileToFragments(merge(o, { + indent: indent + })); + ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode("\n" + this.tab + "}")); + if (!child) { + ifPart.unshift(this.makeCode(this.tab)); + } + if (!this.elseBody) { + return ifPart; + } + answer = ifPart.concat(this.makeCode(' else ')); + if (this.isChain) { + o.chainChild = true; + answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP)); + } else { + answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, { + indent: indent + }), LEVEL_TOP), this.makeCode("\n" + this.tab + "}")); + } + return answer; + }; + + If.prototype.compileExpression = function(o) { + var alt, body, cond, fragments; + cond = this.condition.compileToFragments(o, LEVEL_COND); + body = this.bodyNode().compileToFragments(o, LEVEL_LIST); + alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')]; + fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt); + if (o.level >= LEVEL_COND) { + return this.wrapInBraces(fragments); + } else { + return fragments; + } + }; + + If.prototype.unfoldSoak = function() { + return this.soak && this; + }; + + return If; + + })(Base); + + UTILITIES = { + extend: function(o) { + return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp', o)) + ".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; }"; + }, + modulo: function() { + return "function(a, b) { return (+a % (b = +b) + b) % b; }"; + }, + 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 = /^(?!\d)[$\w\x7f-\uffff]+$/; + + SIMPLENUM = /^[+-]?\d+$/; + + HEXNUM = /^[+-]?0x[\da-f]+/i; + + NUMBER = /^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i; + + IS_STRING = /^['"]/; + + IS_REGEX = /^\//; + + utility = function(name, o) { + var ref, root; + root = o.scope.root; + if (name in root.utilities) { + return root.utilities[name]; + } else { + ref = root.freeVariable(name); + root.assign(ref, UTILITIES[name](o)); + return root.utilities[name] = ref; + } + }; + + multident = function(code, tab) { + code = code.replace(/\n/g, '$&' + tab); + return code.replace(/\s+$/, ''); + }; + + parseNum = function(x) { + if (x == null) { + return 0; + } else if (x.match(HEXNUM)) { + return parseInt(x, 16); + } else { + return parseFloat(x); + } + }; + + isLiteralArguments = function(node) { + return node instanceof Literal && node.value === 'arguments' && !node.asKey; + }; + + isLiteralThis = function(node) { + return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper); + }; + + isComplexOrAssignable = function(node) { + return node.isComplex() || (typeof node.isAssignable === "function" ? node.isAssignable() : void 0); + }; + + 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; + }; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/optparse.js b/node_modules/coffee-script/lib/coffee-script/optparse.js new file mode 100644 index 0000000..1790c46 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/optparse.js @@ -0,0 +1,139 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat; + + repeat = require('./helpers').repeat; + + exports.OptionParser = OptionParser = (function() { + function OptionParser(rules, banner) { + this.banner = banner; + this.rules = buildRules(rules); + } + + OptionParser.prototype.parse = function(args) { + var arg, i, isOption, j, k, len, len1, matchedRule, options, originalArgs, pos, ref, rule, seenNonOptionArg, skippingArgument, value; + options = { + "arguments": [] + }; + skippingArgument = false; + originalArgs = args; + args = normalizeArguments(args); + for (i = j = 0, len = args.length; j < len; i = ++j) { + 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 (k = 0, len1 = ref.length; k < len1; k++) { + rule = ref[k]; + 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 j, len, letPart, lines, ref, rule, spaces; + lines = []; + if (this.banner) { + lines.unshift(this.banner + "\n"); + } + ref = this.rules; + for (j = 0, len = ref.length; j < len; j++) { + rule = ref[j]; + spaces = 15 - rule.longFlag.length; + spaces = spaces > 0 ? repeat(' ', spaces) : ''; + 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 j, len, results, tuple; + results = []; + for (j = 0, len = rules.length; j < len; j++) { + tuple = rules[j]; + 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, j, k, l, len, len1, match, ref, result; + args = args.slice(0); + result = []; + for (j = 0, len = args.length; j < len; j++) { + arg = args[j]; + if (match = arg.match(MULTI_FLAG)) { + ref = match[1].split(''); + for (k = 0, len1 = ref.length; k < len1; k++) { + l = ref[k]; + result.push('-' + l); + } + } else { + result.push(arg); + } + } + return result; + }; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/parser.js b/node_modules/coffee-script/lib/coffee-script/parser.js new file mode 100755 index 0000000..e33f0ad --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/parser.js @@ -0,0 +1,735 @@ +/* parser generated by jison 0.4.15 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +var parser = (function(){ +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,20],$V1=[1,75],$V2=[1,71],$V3=[1,76],$V4=[1,77],$V5=[1,73],$V6=[1,74],$V7=[1,50],$V8=[1,52],$V9=[1,53],$Va=[1,54],$Vb=[1,55],$Vc=[1,45],$Vd=[1,46],$Ve=[1,27],$Vf=[1,60],$Vg=[1,61],$Vh=[1,70],$Vi=[1,43],$Vj=[1,26],$Vk=[1,58],$Vl=[1,59],$Vm=[1,57],$Vn=[1,38],$Vo=[1,44],$Vp=[1,56],$Vq=[1,65],$Vr=[1,66],$Vs=[1,67],$Vt=[1,68],$Vu=[1,42],$Vv=[1,64],$Vw=[1,29],$Vx=[1,30],$Vy=[1,31],$Vz=[1,32],$VA=[1,33],$VB=[1,34],$VC=[1,35],$VD=[1,78],$VE=[1,6,26,34,109],$VF=[1,88],$VG=[1,81],$VH=[1,80],$VI=[1,79],$VJ=[1,82],$VK=[1,83],$VL=[1,84],$VM=[1,85],$VN=[1,86],$VO=[1,87],$VP=[1,91],$VQ=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],$VR=[1,97],$VS=[1,98],$VT=[1,99],$VU=[1,100],$VV=[1,102],$VW=[1,103],$VX=[1,96],$VY=[2,115],$VZ=[1,6,25,26,34,56,61,64,73,74,75,76,78,80,81,85,91,92,93,98,100,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],$V_=[2,82],$V$=[1,108],$V01=[2,61],$V11=[1,112],$V21=[1,117],$V31=[1,118],$V41=[1,120],$V51=[1,6,25,26,34,46,56,61,64,73,74,75,76,78,80,81,85,91,92,93,98,100,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],$V61=[2,79],$V71=[1,6,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],$V81=[1,155],$V91=[1,157],$Va1=[1,152],$Vb1=[1,6,25,26,34,46,56,61,64,73,74,75,76,78,80,81,85,87,91,92,93,98,100,109,111,112,113,117,118,133,136,137,140,141,142,143,144,145,146,147,148,149],$Vc1=[2,98],$Vd1=[1,6,25,26,34,49,56,61,64,73,74,75,76,78,80,81,85,91,92,93,98,100,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],$Ve1=[1,6,25,26,34,46,49,56,61,64,73,74,75,76,78,80,81,85,87,91,92,93,98,100,109,111,112,113,117,118,124,125,133,136,137,140,141,142,143,144,145,146,147,148,149],$Vf1=[1,207],$Vg1=[1,206],$Vh1=[1,6,25,26,34,38,56,61,64,73,74,75,76,78,80,81,85,91,92,93,98,100,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],$Vi1=[2,59],$Vj1=[1,217],$Vk1=[6,25,26,56,61],$Vl1=[6,25,26,46,56,61,64],$Vm1=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,136,137,143,145,146,147,148],$Vn1=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133],$Vo1=[73,74,75,76,78,81,91,92],$Vp1=[1,236],$Vq1=[2,136],$Vr1=[1,6,25,26,34,46,56,61,64,73,74,75,76,78,80,81,85,91,92,93,98,100,109,111,112,113,117,118,124,125,133,136,137,142,143,144,145,146,147,148],$Vs1=[1,245],$Vt1=[6,25,26,61,93,98],$Vu1=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,118,133],$Vv1=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,112,118,133],$Vw1=[124,125],$Vx1=[61,124,125],$Vy1=[1,256],$Vz1=[6,25,26,61,85],$VA1=[6,25,26,49,61,85],$VB1=[6,25,26,46,49,61,85],$VC1=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,136,137,145,146,147,148],$VD1=[11,28,30,32,33,36,37,40,41,42,43,44,52,53,54,58,59,80,83,86,90,95,96,97,103,107,108,111,113,115,117,126,132,134,135,136,137,138,140,141],$VE1=[2,125],$VF1=[6,25,26],$VG1=[2,60],$VH1=[1,270],$VI1=[1,271],$VJ1=[1,6,25,26,34,56,61,64,80,85,93,98,100,105,106,109,111,112,113,117,118,128,130,133,136,137,142,143,144,145,146,147,148],$VK1=[26,128,130],$VL1=[1,6,26,34,56,61,64,80,85,93,98,100,109,112,118,133],$VM1=[2,74],$VN1=[1,293],$VO1=[1,294],$VP1=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,128,133,136,137,142,143,144,145,146,147,148],$VQ1=[1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,113,117,118,133],$VR1=[1,305],$VS1=[1,306],$VT1=[6,25,26,61],$VU1=[1,6,25,26,34,56,61,64,80,85,93,98,100,105,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],$VV1=[25,61]; +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"Root":3,"Body":4,"Line":5,"TERMINATOR":6,"Expression":7,"Statement":8,"Return":9,"Comment":10,"STATEMENT":11,"Value":12,"Invocation":13,"Code":14,"Operation":15,"Assign":16,"If":17,"Try":18,"While":19,"For":20,"Switch":21,"Class":22,"Throw":23,"Block":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"String":31,"STRING":32,"STRING_START":33,"STRING_END":34,"Regex":35,"REGEX":36,"REGEX_START":37,"REGEX_END":38,"Literal":39,"JS":40,"DEBUGGER":41,"UNDEFINED":42,"NULL":43,"BOOL":44,"Assignable":45,"=":46,"AssignObj":47,"ObjAssignable":48,":":49,"SimpleObjAssignable":50,"ThisProperty":51,"RETURN":52,"HERECOMMENT":53,"PARAM_START":54,"ParamList":55,"PARAM_END":56,"FuncGlyph":57,"->":58,"=>":59,"OptComma":60,",":61,"Param":62,"ParamVar":63,"...":64,"Array":65,"Object":66,"Splat":67,"SimpleAssignable":68,"Accessor":69,"Parenthetical":70,"Range":71,"This":72,".":73,"?.":74,"::":75,"?::":76,"Index":77,"INDEX_START":78,"IndexValue":79,"INDEX_END":80,"INDEX_SOAK":81,"Slice":82,"{":83,"AssignList":84,"}":85,"CLASS":86,"EXTENDS":87,"OptFuncExist":88,"Arguments":89,"SUPER":90,"FUNC_EXIST":91,"CALL_START":92,"CALL_END":93,"ArgList":94,"THIS":95,"@":96,"[":97,"]":98,"RangeDots":99,"..":100,"Arg":101,"SimpleArgs":102,"TRY":103,"Catch":104,"FINALLY":105,"CATCH":106,"THROW":107,"(":108,")":109,"WhileSource":110,"WHILE":111,"WHEN":112,"UNTIL":113,"Loop":114,"LOOP":115,"ForBody":116,"FOR":117,"BY":118,"ForStart":119,"ForSource":120,"ForVariables":121,"OWN":122,"ForValue":123,"FORIN":124,"FOROF":125,"SWITCH":126,"Whens":127,"ELSE":128,"When":129,"LEADING_WHEN":130,"IfBlock":131,"IF":132,"POST_IF":133,"UNARY":134,"UNARY_MATH":135,"-":136,"+":137,"YIELD":138,"FROM":139,"--":140,"++":141,"?":142,"MATH":143,"**":144,"SHIFT":145,"COMPARE":146,"LOGIC":147,"RELATION":148,"COMPOUND_ASSIGN":149,"$accept":0,"$end":1}, +terminals_: {2:"error",6:"TERMINATOR",11:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",32:"STRING",33:"STRING_START",34:"STRING_END",36:"REGEX",37:"REGEX_START",38:"REGEX_END",40:"JS",41:"DEBUGGER",42:"UNDEFINED",43:"NULL",44:"BOOL",46:"=",49:":",52:"RETURN",53:"HERECOMMENT",54:"PARAM_START",56:"PARAM_END",58:"->",59:"=>",61:",",64:"...",73:".",74:"?.",75:"::",76:"?::",78:"INDEX_START",80:"INDEX_END",81:"INDEX_SOAK",83:"{",85:"}",86:"CLASS",87:"EXTENDS",90:"SUPER",91:"FUNC_EXIST",92:"CALL_START",93:"CALL_END",95:"THIS",96:"@",97:"[",98:"]",100:"..",103:"TRY",105:"FINALLY",106:"CATCH",107:"THROW",108:"(",109:")",111:"WHILE",112:"WHEN",113:"UNTIL",115:"LOOP",117:"FOR",118:"BY",122:"OWN",124:"FORIN",125:"FOROF",126:"SWITCH",128:"ELSE",130:"LEADING_WHEN",132:"IF",133:"POST_IF",134:"UNARY",135:"UNARY_MATH",136:"-",137:"+",138:"YIELD",139:"FROM",140:"--",141:"++",142:"?",143:"MATH",144:"**",145:"SHIFT",146:"COMPARE",147:"LOGIC",148:"RELATION",149:"COMPOUND_ASSIGN"}, +productions_: [0,[3,0],[3,1],[4,1],[4,3],[4,2],[5,1],[5,1],[8,1],[8,1],[8,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[24,2],[24,3],[27,1],[29,1],[29,1],[31,1],[31,3],[35,1],[35,3],[39,1],[39,1],[39,1],[39,1],[39,1],[39,1],[39,1],[16,3],[16,4],[16,5],[47,1],[47,3],[47,5],[47,3],[47,5],[47,1],[50,1],[50,1],[48,1],[48,1],[9,2],[9,1],[10,1],[14,5],[14,2],[57,1],[57,1],[60,0],[60,1],[55,0],[55,1],[55,3],[55,4],[55,6],[62,1],[62,2],[62,3],[62,1],[63,1],[63,1],[63,1],[63,1],[67,2],[68,1],[68,2],[68,2],[68,1],[45,1],[45,1],[45,1],[12,1],[12,1],[12,1],[12,1],[12,1],[69,2],[69,2],[69,2],[69,2],[69,1],[69,1],[77,3],[77,2],[79,1],[79,1],[66,4],[84,0],[84,1],[84,3],[84,4],[84,6],[22,1],[22,2],[22,3],[22,4],[22,2],[22,3],[22,4],[22,5],[13,3],[13,3],[13,1],[13,2],[88,0],[88,1],[89,2],[89,4],[72,1],[72,1],[51,2],[65,2],[65,4],[99,1],[99,1],[71,5],[82,3],[82,2],[82,2],[82,1],[94,1],[94,3],[94,4],[94,4],[94,6],[101,1],[101,1],[101,1],[102,1],[102,3],[18,2],[18,3],[18,4],[18,5],[104,3],[104,3],[104,2],[23,2],[70,3],[70,5],[110,2],[110,4],[110,2],[110,4],[19,2],[19,2],[19,2],[19,1],[114,2],[114,2],[20,2],[20,2],[20,2],[116,2],[116,4],[116,2],[119,2],[119,3],[123,1],[123,1],[123,1],[123,1],[121,1],[121,3],[120,2],[120,2],[120,4],[120,4],[120,4],[120,6],[120,6],[21,5],[21,7],[21,4],[21,6],[127,1],[127,2],[129,3],[129,4],[131,3],[131,5],[17,1],[17,3],[17,3],[17,3],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,3],[15,2],[15,2],[15,2],[15,2],[15,2],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,5],[15,4],[15,3]], +performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { +/* this == yyval */ + +var $0 = $$.length - 1; +switch (yystate) { +case 1: +return this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Block); +break; +case 2: +return this.$ = $$[$0]; +break; +case 3: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Block.wrap([$$[$0]])); +break; +case 4: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].push($$[$0])); +break; +case 5: +this.$ = $$[$0-1]; +break; +case 6: case 7: case 8: case 9: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 27: case 32: case 34: case 47: case 48: case 49: case 50: case 51: case 59: case 60: case 70: case 71: case 72: case 73: case 78: case 79: case 82: case 86: case 92: case 136: case 137: case 139: case 169: case 170: case 186: case 192: +this.$ = $$[$0]; +break; +case 10: case 25: case 26: case 28: case 30: case 33: case 35: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 23: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Block); +break; +case 24: case 31: case 93: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]); +break; +case 29: case 149: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Parens($$[$0-1])); +break; +case 36: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Undefined); +break; +case 37: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Null); +break; +case 38: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Bool($$[$0])); +break; +case 39: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0])); +break; +case 40: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0])); +break; +case 41: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1])); +break; +case 42: case 75: case 80: case 81: case 83: case 84: case 85: case 171: case 172: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 43: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(new yy.Value($$[$0-2])), $$[$0], 'object', { + operatorToken: yy.addLocationDataFn(_$[$0-1])(new yy.Literal($$[$0-1])) + })); +break; +case 44: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], 'object', { + operatorToken: yy.addLocationDataFn(_$[$0-3])(new yy.Literal($$[$0-3])) + })); +break; +case 45: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(new yy.Value($$[$0-2])), $$[$0], null, { + operatorToken: yy.addLocationDataFn(_$[$0-1])(new yy.Literal($$[$0-1])) + })); +break; +case 46: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], null, { + operatorToken: yy.addLocationDataFn(_$[$0-3])(new yy.Literal($$[$0-3])) + })); +break; +case 52: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Return($$[$0])); +break; +case 53: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Return); +break; +case 54: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Comment($$[$0])); +break; +case 55: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Code($$[$0-3], $$[$0], $$[$0-1])); +break; +case 56: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Code([], $$[$0], $$[$0-1])); +break; +case 57: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('func'); +break; +case 58: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('boundfunc'); +break; +case 61: case 98: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]); +break; +case 62: case 99: case 131: case 173: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]); +break; +case 63: case 100: case 132: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0])); +break; +case 64: case 101: case 133: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0])); +break; +case 65: case 102: case 135: +this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2])); +break; +case 66: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Param($$[$0])); +break; +case 67: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Param($$[$0-1], null, true)); +break; +case 68: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Param($$[$0-2], $$[$0])); +break; +case 69: case 138: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Expansion); +break; +case 74: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Splat($$[$0-1])); +break; +case 76: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].add($$[$0])); +break; +case 77: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value($$[$0-1], [].concat($$[$0]))); +break; +case 87: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0])); +break; +case 88: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0], 'soak')); +break; +case 89: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'))), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]); +break; +case 90: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'), 'soak')), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]); +break; +case 91: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Access(new yy.Literal('prototype'))); +break; +case 94: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.extend($$[$0], { + soak: true + })); +break; +case 95: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Index($$[$0])); +break; +case 96: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Slice($$[$0])); +break; +case 97: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Obj($$[$0-2], $$[$0-3].generated)); +break; +case 103: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Class); +break; +case 104: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class(null, null, $$[$0])); +break; +case 105: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class(null, $$[$0])); +break; +case 106: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class(null, $$[$0-1], $$[$0])); +break; +case 107: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class($$[$0])); +break; +case 108: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class($$[$0-1], null, $$[$0])); +break; +case 109: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class($$[$0-2], $$[$0])); +break; +case 110: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Class($$[$0-3], $$[$0-1], $$[$0])); +break; +case 111: case 112: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1])); +break; +case 113: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))])); +break; +case 114: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Call('super', $$[$0])); +break; +case 115: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(false); +break; +case 116: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(true); +break; +case 117: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([]); +break; +case 118: case 134: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]); +break; +case 119: case 120: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this'))); +break; +case 121: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('this')), [yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))], 'this')); +break; +case 122: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Arr([])); +break; +case 123: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Arr($$[$0-2])); +break; +case 124: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('inclusive'); +break; +case 125: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('exclusive'); +break; +case 126: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Range($$[$0-3], $$[$0-1], $$[$0-2])); +break; +case 127: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Range($$[$0-2], $$[$0], $$[$0-1])); +break; +case 128: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range($$[$0-1], null, $$[$0])); +break; +case 129: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range(null, $$[$0], $$[$0-1])); +break; +case 130: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Range(null, null, $$[$0])); +break; +case 140: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([].concat($$[$0-2], $$[$0])); +break; +case 141: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Try($$[$0])); +break; +case 142: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Try($$[$0-1], $$[$0][0], $$[$0][1])); +break; +case 143: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Try($$[$0-2], null, null, $$[$0])); +break; +case 144: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0])); +break; +case 145: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-1], $$[$0]]); +break; +case 146: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Value($$[$0-1])), $$[$0]]); +break; +case 147: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([null, $$[$0]]); +break; +case 148: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Throw($$[$0])); +break; +case 150: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Parens($$[$0-2])); +break; +case 151: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0])); +break; +case 152: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], { + guard: $$[$0] + })); +break; +case 153: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0], { + invert: true + })); +break; +case 154: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], { + invert: true, + guard: $$[$0] + })); +break; +case 155: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].addBody($$[$0])); +break; +case 156: case 157: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]])))); +break; +case 158: +this.$ = yy.addLocationDataFn(_$[$0], _$[$0])($$[$0]); +break; +case 159: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody($$[$0])); +break; +case 160: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody(yy.addLocationDataFn(_$[$0])(yy.Block.wrap([$$[$0]])))); +break; +case 161: case 162: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0])); +break; +case 163: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0], $$[$0-1])); +break; +case 164: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({ + source: yy.addLocationDataFn(_$[$0])(new yy.Value($$[$0])) + }); +break; +case 165: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({ + source: yy.addLocationDataFn(_$[$0-2])(new yy.Value($$[$0-2])), + step: $$[$0] + }); +break; +case 166: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])((function () { + $$[$0].own = $$[$0-1].own; + $$[$0].name = $$[$0-1][0]; + $$[$0].index = $$[$0-1][1]; + return $$[$0]; + }())); +break; +case 167: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0]); +break; +case 168: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () { + $$[$0].own = true; + return $$[$0]; + }())); +break; +case 174: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-2], $$[$0]]); +break; +case 175: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({ + source: $$[$0] + }); +break; +case 176: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({ + source: $$[$0], + object: true + }); +break; +case 177: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({ + source: $$[$0-2], + guard: $$[$0] + }); +break; +case 178: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({ + source: $$[$0-2], + guard: $$[$0], + object: true + }); +break; +case 179: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({ + source: $$[$0-2], + step: $$[$0] + }); +break; +case 180: +this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({ + source: $$[$0-4], + guard: $$[$0-2], + step: $$[$0] + }); +break; +case 181: +this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({ + source: $$[$0-4], + step: $$[$0-2], + guard: $$[$0] + }); +break; +case 182: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Switch($$[$0-3], $$[$0-1])); +break; +case 183: +this.$ = yy.addLocationDataFn(_$[$0-6], _$[$0])(new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1])); +break; +case 184: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Switch(null, $$[$0-1])); +break; +case 185: +this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])(new yy.Switch(null, $$[$0-3], $$[$0-1])); +break; +case 187: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].concat($$[$0])); +break; +case 188: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([[$$[$0-1], $$[$0]]]); +break; +case 189: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])([[$$[$0-2], $$[$0-1]]]); +break; +case 190: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], { + type: $$[$0-2] + })); +break; +case 191: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])($$[$0-4].addElse(yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], { + type: $$[$0-2] + })))); +break; +case 193: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].addElse($$[$0])); +break; +case 194: case 195: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), { + type: $$[$0-1], + statement: true + })); +break; +case 196: case 197: case 200: case 201: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0])); +break; +case 198: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('-', $$[$0])); +break; +case 199: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('+', $$[$0])); +break; +case 202: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-2].concat($$[$0-1]), $$[$0])); +break; +case 203: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0])); +break; +case 204: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0])); +break; +case 205: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0-1], null, true)); +break; +case 206: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0-1], null, true)); +break; +case 207: +this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Existence($$[$0-1])); +break; +case 208: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('+', $$[$0-2], $$[$0])); +break; +case 209: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('-', $$[$0-2], $$[$0])); +break; +case 210: case 211: case 212: case 213: case 214: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0])); +break; +case 215: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((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 216: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0], $$[$0-1])); +break; +case 217: +this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3])); +break; +case 218: +this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0], $$[$0-2])); +break; +case 219: +this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Extends($$[$0-2], $$[$0])); +break; +} +}, +table: [{1:[2,1],3:1,4:2,5:3,7:4,8:5,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{1:[3]},{1:[2,2],6:$VD},o($VE,[2,3]),o($VE,[2,6],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VE,[2,7],{119:69,110:92,116:93,111:$Vq,113:$Vr,117:$Vt,133:$VP}),o($VQ,[2,11],{88:94,69:95,77:101,73:$VR,74:$VS,75:$VT,76:$VU,78:$VV,81:$VW,91:$VX,92:$VY}),o($VQ,[2,12],{77:101,88:104,69:105,73:$VR,74:$VS,75:$VT,76:$VU,78:$VV,81:$VW,91:$VX,92:$VY}),o($VQ,[2,13]),o($VQ,[2,14]),o($VQ,[2,15]),o($VQ,[2,16]),o($VQ,[2,17]),o($VQ,[2,18]),o($VQ,[2,19]),o($VQ,[2,20]),o($VQ,[2,21]),o($VQ,[2,22]),o($VQ,[2,8]),o($VQ,[2,9]),o($VQ,[2,10]),o($VZ,$V_,{46:[1,106]}),o($VZ,[2,83]),o($VZ,[2,84]),o($VZ,[2,85]),o($VZ,[2,86]),o([1,6,25,26,34,38,56,61,64,73,74,75,76,78,80,81,85,91,93,98,100,109,111,112,113,117,118,133,136,137,142,143,144,145,146,147,148],[2,113],{89:107,92:$V$}),o([6,25,56,61],$V01,{55:109,62:110,63:111,27:113,51:114,65:115,66:116,28:$V1,64:$V11,83:$Vh,96:$V21,97:$V31}),{24:119,25:$V41},{7:121,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:123,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:124,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:125,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:127,8:126,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,139:[1,128],140:$VB,141:$VC},{12:130,13:131,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:132,51:63,65:47,66:48,68:129,70:23,71:24,72:25,83:$Vh,90:$Vj,95:$Vk,96:$Vl,97:$Vm,108:$Vp},{12:130,13:131,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:132,51:63,65:47,66:48,68:133,70:23,71:24,72:25,83:$Vh,90:$Vj,95:$Vk,96:$Vl,97:$Vm,108:$Vp},o($V51,$V61,{87:[1,137],140:[1,134],141:[1,135],149:[1,136]}),o($VQ,[2,192],{128:[1,138]}),{24:139,25:$V41},{24:140,25:$V41},o($VQ,[2,158]),{24:141,25:$V41},{7:142,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($V71,[2,103],{39:22,70:23,71:24,72:25,65:47,66:48,29:49,35:51,27:62,51:63,31:72,12:130,13:131,45:132,24:144,68:146,25:$V41,28:$V1,30:$V2,32:$V3,33:$V4,36:$V5,37:$V6,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,83:$Vh,87:[1,145],90:$Vj,95:$Vk,96:$Vl,97:$Vm,108:$Vp}),{7:147,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,142,143,144,145,146,147,148],[2,53],{12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,9:18,10:19,45:21,39:22,70:23,71:24,72:25,57:28,68:36,131:37,110:39,114:40,116:41,65:47,66:48,29:49,35:51,27:62,51:63,119:69,31:72,8:122,7:148,11:$V0,28:$V1,30:$V2,32:$V3,33:$V4,36:$V5,37:$V6,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,52:$Vc,53:$Vd,54:$Ve,58:$Vf,59:$Vg,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,115:$Vs,126:$Vu,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC}),o($VQ,[2,54]),o($V51,[2,80]),o($V51,[2,81]),o($VZ,[2,32]),o($VZ,[2,33]),o($VZ,[2,34]),o($VZ,[2,35]),o($VZ,[2,36]),o($VZ,[2,37]),o($VZ,[2,38]),{4:149,5:3,7:4,8:5,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,150],27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:151,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:$V81,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,64:$V91,65:47,66:48,67:156,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,94:153,95:$Vk,96:$Vl,97:$Vm,98:$Va1,101:154,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VZ,[2,119]),o($VZ,[2,120],{27:158,28:$V1}),{25:[2,57]},{25:[2,58]},o($Vb1,[2,75]),o($Vb1,[2,78]),{7:159,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:160,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:161,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:163,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:162,25:$V41,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{27:168,28:$V1,51:169,65:170,66:171,71:164,83:$Vh,96:$V21,97:$Vm,121:165,122:[1,166],123:167},{120:172,124:[1,173],125:[1,174]},o([6,25,61,85],$Vc1,{31:72,84:175,47:176,48:177,50:178,10:179,29:180,27:181,51:182,28:$V1,30:$V2,32:$V3,33:$V4,53:$Vd,96:$V21}),o($Vd1,[2,26]),o($Vd1,[2,27]),o($VZ,[2,30]),{12:130,13:183,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:132,51:63,65:47,66:48,68:184,70:23,71:24,72:25,83:$Vh,90:$Vj,95:$Vk,96:$Vl,97:$Vm,108:$Vp},o($Ve1,[2,25]),o($Vd1,[2,28]),{4:185,5:3,7:4,8:5,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VE,[2,5],{7:4,8:5,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,9:18,10:19,45:21,39:22,70:23,71:24,72:25,57:28,68:36,131:37,110:39,114:40,116:41,65:47,66:48,29:49,35:51,27:62,51:63,119:69,31:72,5:186,11:$V0,28:$V1,30:$V2,32:$V3,33:$V4,36:$V5,37:$V6,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,52:$Vc,53:$Vd,54:$Ve,58:$Vf,59:$Vg,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,111:$Vq,113:$Vr,115:$Vs,117:$Vt,126:$Vu,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC}),o($VQ,[2,207]),{7:187,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:188,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:189,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:190,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:191,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:192,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:193,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:194,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:195,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VQ,[2,157]),o($VQ,[2,162]),{7:196,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VQ,[2,156]),o($VQ,[2,161]),{89:197,92:$V$},o($Vb1,[2,76]),{92:[2,116]},{27:198,28:$V1},{27:199,28:$V1},o($Vb1,[2,91],{27:200,28:$V1}),{27:201,28:$V1},o($Vb1,[2,92]),{7:203,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,64:$Vf1,65:47,66:48,68:36,70:23,71:24,72:25,79:202,82:204,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,99:205,100:$Vg1,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{77:208,78:$VV,81:$VW},{89:209,92:$V$},o($Vb1,[2,77]),{6:[1,211],7:210,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,212],27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vh1,[2,114]),{7:215,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:$V81,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,64:$V91,65:47,66:48,67:156,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,93:[1,213],94:214,95:$Vk,96:$Vl,97:$Vm,101:154,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o([6,25],$Vi1,{60:218,56:[1,216],61:$Vj1}),o($Vk1,[2,62]),o($Vk1,[2,66],{46:[1,220],64:[1,219]}),o($Vk1,[2,69]),o($Vl1,[2,70]),o($Vl1,[2,71]),o($Vl1,[2,72]),o($Vl1,[2,73]),{27:158,28:$V1},{7:215,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:$V81,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,64:$V91,65:47,66:48,67:156,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,94:153,95:$Vk,96:$Vl,97:$Vm,98:$Va1,101:154,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VQ,[2,56]),{4:222,5:3,7:4,8:5,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[1,221],27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,136,137,143,144,145,146,147,148],[2,196],{119:69,110:89,116:90,142:$VI}),{110:92,111:$Vq,113:$Vr,116:93,117:$Vt,119:69,133:$VP},o($Vm1,[2,197],{119:69,110:89,116:90,142:$VI,144:$VK}),o($Vm1,[2,198],{119:69,110:89,116:90,142:$VI,144:$VK}),o($Vm1,[2,199],{119:69,110:89,116:90,142:$VI,144:$VK}),o($VQ,[2,200],{119:69,110:92,116:93}),o($Vn1,[2,201],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{7:223,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VQ,[2,203],{73:$V61,74:$V61,75:$V61,76:$V61,78:$V61,81:$V61,91:$V61,92:$V61}),{69:95,73:$VR,74:$VS,75:$VT,76:$VU,77:101,78:$VV,81:$VW,88:94,91:$VX,92:$VY},{69:105,73:$VR,74:$VS,75:$VT,76:$VU,77:101,78:$VV,81:$VW,88:104,91:$VX,92:$VY},o($Vo1,$V_),o($VQ,[2,204],{73:$V61,74:$V61,75:$V61,76:$V61,78:$V61,81:$V61,91:$V61,92:$V61}),o($VQ,[2,205]),o($VQ,[2,206]),{6:[1,226],7:224,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,225],27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:227,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{24:228,25:$V41,132:[1,229]},o($VQ,[2,141],{104:230,105:[1,231],106:[1,232]}),o($VQ,[2,155]),o($VQ,[2,163]),{25:[1,233],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},{127:234,129:235,130:$Vp1},o($VQ,[2,104]),{7:237,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($V71,[2,107],{24:238,25:$V41,73:$V61,74:$V61,75:$V61,76:$V61,78:$V61,81:$V61,91:$V61,92:$V61,87:[1,239]}),o($Vn1,[2,148],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vn1,[2,52],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{6:$VD,109:[1,240]},{4:241,5:3,7:4,8:5,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o([6,25,61,98],$Vq1,{119:69,110:89,116:90,99:242,64:[1,243],100:$Vg1,111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vr1,[2,122]),o([6,25,98],$Vi1,{60:244,61:$Vs1}),o($Vt1,[2,131]),{7:215,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:$V81,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,64:$V91,65:47,66:48,67:156,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,94:246,95:$Vk,96:$Vl,97:$Vm,101:154,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vt1,[2,137]),o($Vt1,[2,138]),o($Ve1,[2,121]),{24:247,25:$V41,110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},o($Vu1,[2,151],{119:69,110:89,116:90,111:$Vq,112:[1,248],113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vu1,[2,153],{119:69,110:89,116:90,111:$Vq,112:[1,249],113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VQ,[2,159]),o($Vv1,[2,160],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,133,136,137,142,143,144,145,146,147,148],[2,164],{118:[1,250]}),o($Vw1,[2,167]),{27:168,28:$V1,51:169,65:170,66:171,83:$Vh,96:$V21,97:$V31,121:251,123:167},o($Vw1,[2,173],{61:[1,252]}),o($Vx1,[2,169]),o($Vx1,[2,170]),o($Vx1,[2,171]),o($Vx1,[2,172]),o($VQ,[2,166]),{7:253,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:254,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o([6,25,85],$Vi1,{60:255,61:$Vy1}),o($Vz1,[2,99]),o($Vz1,[2,42],{49:[1,257]}),o($VA1,[2,50],{46:[1,258]}),o($Vz1,[2,47]),o($VA1,[2,51]),o($VB1,[2,48]),o($VB1,[2,49]),{38:[1,259],69:105,73:$VR,74:$VS,75:$VT,76:$VU,77:101,78:$VV,81:$VW,88:104,91:$VX,92:$VY},o($Vo1,$V61),{6:$VD,34:[1,260]},o($VE,[2,4]),o($VC1,[2,208],{119:69,110:89,116:90,142:$VI,143:$VJ,144:$VK}),o($VC1,[2,209],{119:69,110:89,116:90,142:$VI,143:$VJ,144:$VK}),o($Vm1,[2,210],{119:69,110:89,116:90,142:$VI,144:$VK}),o($Vm1,[2,211],{119:69,110:89,116:90,142:$VI,144:$VK}),o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,145,146,147,148],[2,212],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK}),o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,146,147],[2,213],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,148:$VO}),o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,147],[2,214],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,148:$VO}),o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,118,133,146,147,148],[2,215],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL}),o($Vv1,[2,195],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vv1,[2,194],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vh1,[2,111]),o($Vb1,[2,87]),o($Vb1,[2,88]),o($Vb1,[2,89]),o($Vb1,[2,90]),{80:[1,261]},{64:$Vf1,80:[2,95],99:262,100:$Vg1,110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},{80:[2,96]},{7:263,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,80:[2,130],83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VD1,[2,124]),o($VD1,$VE1),o($Vb1,[2,94]),o($Vh1,[2,112]),o($Vn1,[2,39],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{7:264,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:265,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vh1,[2,117]),o([6,25,93],$Vi1,{60:266,61:$Vs1}),o($Vt1,$Vq1,{119:69,110:89,116:90,64:[1,267],111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{57:268,58:$Vf,59:$Vg},o($VF1,$VG1,{63:111,27:113,51:114,65:115,66:116,62:269,28:$V1,64:$V11,83:$Vh,96:$V21,97:$V31}),{6:$VH1,25:$VI1},o($Vk1,[2,67]),{7:272,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VJ1,[2,23]),{6:$VD,26:[1,273]},o($Vn1,[2,202],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vn1,[2,216],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{7:274,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:275,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vn1,[2,219],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VQ,[2,193]),{7:276,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VQ,[2,142],{105:[1,277]}),{24:278,25:$V41},{24:281,25:$V41,27:279,28:$V1,66:280,83:$Vh},{127:282,129:235,130:$Vp1},{26:[1,283],128:[1,284],129:285,130:$Vp1},o($VK1,[2,186]),{7:287,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,102:286,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VL1,[2,105],{119:69,110:89,116:90,24:288,25:$V41,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VQ,[2,108]),{7:289,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VZ,[2,149]),{6:$VD,26:[1,290]},{7:291,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o([11,28,30,32,33,36,37,40,41,42,43,44,52,53,54,58,59,83,86,90,95,96,97,103,107,108,111,113,115,117,126,132,134,135,136,137,138,140,141],$VE1,{6:$VM1,25:$VM1,61:$VM1,98:$VM1}),{6:$VN1,25:$VO1,98:[1,292]},o([6,25,26,93,98],$VG1,{12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,9:18,10:19,45:21,39:22,70:23,71:24,72:25,57:28,68:36,131:37,110:39,114:40,116:41,65:47,66:48,29:49,35:51,27:62,51:63,119:69,31:72,8:122,67:156,7:215,101:295,11:$V0,28:$V1,30:$V2,32:$V3,33:$V4,36:$V5,37:$V6,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,52:$Vc,53:$Vd,54:$Ve,58:$Vf,59:$Vg,64:$V91,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,111:$Vq,113:$Vr,115:$Vs,117:$Vt,126:$Vu,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC}),o($VF1,$Vi1,{60:296,61:$Vs1}),o($VP1,[2,190]),{7:297,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:298,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:299,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vw1,[2,168]),{27:168,28:$V1,51:169,65:170,66:171,83:$Vh,96:$V21,97:$V31,123:300},o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,113,117,133],[2,175],{119:69,110:89,116:90,112:[1,301],118:[1,302],136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VQ1,[2,176],{119:69,110:89,116:90,112:[1,303],136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{6:$VR1,25:$VS1,85:[1,304]},o([6,25,26,85],$VG1,{31:72,48:177,50:178,10:179,29:180,27:181,51:182,47:307,28:$V1,30:$V2,32:$V3,33:$V4,53:$Vd,96:$V21}),{7:308,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,309],27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:310,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,311],27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VZ,[2,31]),o($Vd1,[2,29]),o($Vb1,[2,93]),{7:312,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,80:[2,128],83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{80:[2,129],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},o($Vn1,[2,40],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{26:[1,313],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},{6:$VN1,25:$VO1,93:[1,314]},o($Vt1,$VM1),{24:315,25:$V41},o($Vk1,[2,63]),{27:113,28:$V1,51:114,62:316,63:111,64:$V11,65:115,66:116,83:$Vh,96:$V21,97:$V31},o($VT1,$V01,{62:110,63:111,27:113,51:114,65:115,66:116,55:317,28:$V1,64:$V11,83:$Vh,96:$V21,97:$V31}),o($Vk1,[2,68],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VJ1,[2,24]),{26:[1,318],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},o($Vn1,[2,218],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{24:319,25:$V41,110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},{24:320,25:$V41},o($VQ,[2,143]),{24:321,25:$V41},{24:322,25:$V41},o($VU1,[2,147]),{26:[1,323],128:[1,324],129:285,130:$Vp1},o($VQ,[2,184]),{24:325,25:$V41},o($VK1,[2,187]),{24:326,25:$V41,61:[1,327]},o($VV1,[2,139],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VQ,[2,106]),o($VL1,[2,109],{119:69,110:89,116:90,24:328,25:$V41,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{109:[1,329]},{98:[1,330],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},o($Vr1,[2,123]),{7:215,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,64:$V91,65:47,66:48,67:156,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,101:331,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:215,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:$V81,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,64:$V91,65:47,66:48,67:156,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,94:332,95:$Vk,96:$Vl,97:$Vm,101:154,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vt1,[2,132]),{6:$VN1,25:$VO1,26:[1,333]},o($Vv1,[2,152],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vv1,[2,154],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vv1,[2,165],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vw1,[2,174]),{7:334,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:335,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:336,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vr1,[2,97]),{10:179,27:181,28:$V1,29:180,30:$V2,31:72,32:$V3,33:$V4,47:337,48:177,50:178,51:182,53:$Vd,96:$V21},o($VT1,$Vc1,{31:72,47:176,48:177,50:178,10:179,29:180,27:181,51:182,84:338,28:$V1,30:$V2,32:$V3,33:$V4,53:$Vd,96:$V21}),o($Vz1,[2,100]),o($Vz1,[2,43],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{7:339,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($Vz1,[2,45],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{7:340,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{80:[2,127],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},o($VQ,[2,41]),o($Vh1,[2,118]),o($VQ,[2,55]),o($Vk1,[2,64]),o($VF1,$Vi1,{60:341,61:$Vj1}),o($VQ,[2,217]),o($VP1,[2,191]),o($VQ,[2,144]),o($VU1,[2,145]),o($VU1,[2,146]),o($VQ,[2,182]),{24:342,25:$V41},{26:[1,343]},o($VK1,[2,188],{6:[1,344]}),{7:345,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},o($VQ,[2,110]),o($VZ,[2,150]),o($VZ,[2,126]),o($Vt1,[2,133]),o($VF1,$Vi1,{60:346,61:$Vs1}),o($Vt1,[2,134]),o([1,6,25,26,34,56,61,64,80,85,93,98,100,109,111,112,113,117,133],[2,177],{119:69,110:89,116:90,118:[1,347],136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($VQ1,[2,179],{119:69,110:89,116:90,112:[1,348],136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vn1,[2,178],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vz1,[2,101]),o($VF1,$Vi1,{60:349,61:$Vy1}),{26:[1,350],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},{26:[1,351],110:89,111:$Vq,113:$Vr,116:90,117:$Vt,119:69,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO},{6:$VH1,25:$VI1,26:[1,352]},{26:[1,353]},o($VQ,[2,185]),o($VK1,[2,189]),o($VV1,[2,140],{119:69,110:89,116:90,111:$Vq,113:$Vr,117:$Vt,133:$VF,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),{6:$VN1,25:$VO1,26:[1,354]},{7:355,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{7:356,8:122,9:18,10:19,11:$V0,12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:62,28:$V1,29:49,30:$V2,31:72,32:$V3,33:$V4,35:51,36:$V5,37:$V6,39:22,40:$V7,41:$V8,42:$V9,43:$Va,44:$Vb,45:21,51:63,52:$Vc,53:$Vd,54:$Ve,57:28,58:$Vf,59:$Vg,65:47,66:48,68:36,70:23,71:24,72:25,83:$Vh,86:$Vi,90:$Vj,95:$Vk,96:$Vl,97:$Vm,103:$Vn,107:$Vo,108:$Vp,110:39,111:$Vq,113:$Vr,114:40,115:$Vs,116:41,117:$Vt,119:69,126:$Vu,131:37,132:$Vv,134:$Vw,135:$Vx,136:$Vy,137:$Vz,138:$VA,140:$VB,141:$VC},{6:$VR1,25:$VS1,26:[1,357]},o($Vz1,[2,44]),o($Vz1,[2,46]),o($Vk1,[2,65]),o($VQ,[2,183]),o($Vt1,[2,135]),o($Vn1,[2,180],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vn1,[2,181],{119:69,110:89,116:90,136:$VG,137:$VH,142:$VI,143:$VJ,144:$VK,145:$VL,146:$VM,147:$VN,148:$VO}),o($Vz1,[2,102])], +defaultActions: {60:[2,57],61:[2,58],96:[2,116],204:[2,96]}, +parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + throw new Error(str); + } +}, +parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + _token_stack: + function lex() { + var token; + token = lexer.lex() || EOF; + 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) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + 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: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + 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 + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + 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]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; +}}; + +function Parser () { + this.yy = {}; +} +Parser.prototype = parser;parser.Parser = Parser; +return new Parser; +})(); + + +if (typeof require !== 'undefined' && typeof exports !== 'undefined') { +exports.parser = parser; +exports.Parser = parser.Parser; +exports.parse = function () { return parser.parse.apply(parser, arguments); }; +exports.main = function commonjsMain(args) { + if (!args[1]) { + console.log('Usage: '+args[0]+' FILE'); + process.exit(1); + } + var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); + return exports.parser.parse(source); +}; +if (typeof module !== 'undefined' && require.main === module) { + exports.main(process.argv.slice(1)); +} +} \ No newline at end of file diff --git a/node_modules/coffee-script/lib/coffee-script/register.js b/node_modules/coffee-script/lib/coffee-script/register.js new file mode 100644 index 0000000..14f75a1 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/register.js @@ -0,0 +1,66 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, helpers, i, len, loadFile, path, ref; + + CoffeeScript = require('./coffee-script'); + + child_process = require('child_process'); + + helpers = require('./helpers'); + + path = require('path'); + + loadFile = function(module, filename) { + var answer; + answer = CoffeeScript._compileFile(filename, false); + return module._compile(answer, filename); + }; + + if (require.extensions) { + ref = CoffeeScript.FILE_EXTENSIONS; + for (i = 0, len = ref.length; i < len; i++) { + ext = ref[i]; + require.extensions[ext] = loadFile; + } + Module = require('module'); + findExtension = function(filename) { + var curExtension, extensions; + extensions = path.basename(filename).split('.'); + if (extensions[0] === '') { + extensions.shift(); + } + while (extensions.shift()) { + curExtension = '.' + extensions.join('.'); + if (Module._extensions[curExtension]) { + return curExtension; + } + } + return '.js'; + }; + Module.prototype.load = function(filename) { + var extension; + this.filename = filename; + this.paths = Module._nodeModulePaths(path.dirname(filename)); + extension = findExtension(filename); + Module._extensions[extension](this, filename); + return this.loaded = true; + }; + } + + if (child_process) { + fork = child_process.fork; + binary = require.resolve('../../bin/coffee'); + child_process.fork = function(path, args, options) { + if (helpers.isCoffee(path)) { + if (!Array.isArray(args)) { + options = args || {}; + args = []; + } + args = [path].concat(args); + path = binary; + } + return fork(path, args, options); + }; + } + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/repl.js b/node_modules/coffee-script/lib/coffee-script/repl.js new file mode 100644 index 0000000..f4aa4ef --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/repl.js @@ -0,0 +1,202 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, ref, replDefaults, runInContext, updateSyntaxError, vm; + + fs = require('fs'); + + path = require('path'); + + vm = require('vm'); + + nodeREPL = require('repl'); + + CoffeeScript = require('./coffee-script'); + + ref = require('./helpers'), merge = ref.merge, updateSyntaxError = ref.updateSyntaxError; + + replDefaults = { + prompt: 'coffee> ', + historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0, + historyMaxInputSize: 10240, + "eval": function(input, context, filename, cb) { + var Assign, Block, Literal, Value, ast, err, error, js, ref1, referencedVars, token, tokens; + input = input.replace(/\uFF00/g, '\n'); + input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1'); + ref1 = require('./nodes'), Block = ref1.Block, Assign = ref1.Assign, Value = ref1.Value, Literal = ref1.Literal; + try { + tokens = CoffeeScript.tokens(input); + referencedVars = (function() { + var i, len, results; + results = []; + for (i = 0, len = tokens.length; i < len; i++) { + token = tokens[i]; + if (token.variable) { + results.push(token[1]); + } + } + return results; + })(); + ast = CoffeeScript.nodes(tokens); + ast = new Block([new Assign(new Value(new Literal('_')), ast, '=')]); + js = ast.compile({ + bare: true, + locals: Object.keys(context), + referencedVars: referencedVars + }); + return cb(null, runInContext(js, context, filename)); + } catch (error) { + err = error; + updateSyntaxError(err, input); + return cb(err); + } + } + }; + + runInContext = function(js, context, filename) { + if (context === global) { + return vm.runInThisContext(js, filename); + } else { + return vm.runInContext(js, context, filename); + } + }; + + addMultilineHandler = function(repl) { + var inputStream, multiline, nodeLineListener, origPrompt, outputStream, ref1, rli; + rli = repl.rli, inputStream = repl.inputStream, outputStream = repl.outputStream; + origPrompt = (ref1 = repl._prompt) != null ? ref1 : repl.prompt; + multiline = { + enabled: false, + initialPrompt: origPrompt.replace(/^[^> ]*/, function(x) { + return x.replace(/./g, '-'); + }), + prompt: origPrompt.replace(/^[^> ]*>?/, function(x) { + return x.replace(/./g, '.'); + }), + buffer: '' + }; + nodeLineListener = rli.listeners('line')[0]; + rli.removeListener('line', nodeLineListener); + rli.on('line', function(cmd) { + if (multiline.enabled) { + multiline.buffer += cmd + "\n"; + rli.setPrompt(multiline.prompt); + rli.prompt(true); + } else { + rli.setPrompt(origPrompt); + nodeLineListener(cmd); + } + }); + return inputStream.on('keypress', function(char, key) { + if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'v')) { + return; + } + if (multiline.enabled) { + if (!multiline.buffer.match(/\n/)) { + multiline.enabled = !multiline.enabled; + rli.setPrompt(origPrompt); + rli.prompt(true); + return; + } + if ((rli.line != null) && !rli.line.match(/^\s*$/)) { + return; + } + multiline.enabled = !multiline.enabled; + rli.line = ''; + rli.cursor = 0; + rli.output.cursorTo(0); + rli.output.clearLine(1); + multiline.buffer = multiline.buffer.replace(/\n/g, '\uFF00'); + rli.emit('line', multiline.buffer); + multiline.buffer = ''; + } else { + multiline.enabled = !multiline.enabled; + rli.setPrompt(multiline.initialPrompt); + rli.prompt(true); + } + }); + }; + + addHistory = function(repl, filename, maxSize) { + var buffer, fd, lastLine, readFd, size, stat; + lastLine = null; + try { + stat = fs.statSync(filename); + size = Math.min(maxSize, stat.size); + readFd = fs.openSync(filename, 'r'); + buffer = new Buffer(size); + fs.readSync(readFd, buffer, 0, size, stat.size - size); + fs.close(readFd); + repl.rli.history = buffer.toString().split('\n').reverse(); + if (stat.size > maxSize) { + repl.rli.history.pop(); + } + if (repl.rli.history[0] === '') { + repl.rli.history.shift(); + } + repl.rli.historyIndex = -1; + lastLine = repl.rli.history[0]; + } catch (undefined) {} + fd = fs.openSync(filename, 'a'); + repl.rli.addListener('line', function(code) { + if (code && code.length && code !== '.history' && lastLine !== code) { + fs.write(fd, code + "\n"); + return lastLine = code; + } + }); + repl.on('exit', function() { + return fs.close(fd); + }); + return repl.commands[getCommandId(repl, 'history')] = { + help: 'Show command history', + action: function() { + repl.outputStream.write((repl.rli.history.slice(0).reverse().join('\n')) + "\n"); + return repl.displayPrompt(); + } + }; + }; + + getCommandId = function(repl, commandName) { + var commandsHaveLeadingDot; + commandsHaveLeadingDot = repl.commands['.help'] != null; + if (commandsHaveLeadingDot) { + return "." + commandName; + } else { + return commandName; + } + }; + + module.exports = { + start: function(opts) { + var build, major, minor, ref1, repl; + if (opts == null) { + opts = {}; + } + ref1 = process.versions.node.split('.').map(function(n) { + return parseInt(n); + }), major = ref1[0], minor = ref1[1], build = ref1[2]; + if (major === 0 && minor < 8) { + console.warn("Node 0.8.0+ required for CoffeeScript REPL"); + process.exit(1); + } + CoffeeScript.register(); + process.argv = ['coffee'].concat(process.argv.slice(2)); + opts = merge(replDefaults, opts); + repl = nodeREPL.start(opts); + if (opts.prelude) { + runInContext(opts.prelude, repl.context, 'prelude'); + } + repl.on('exit', function() { + if (!repl.rli.closed) { + return repl.outputStream.write('\n'); + } + }); + addMultilineHandler(repl); + if (opts.historyFile) { + addHistory(repl, opts.historyFile, opts.historyMaxInputSize); + } + repl.commands[getCommandId(repl, 'load')].help = 'Load code from a file into this REPL session'; + return repl; + } + }; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/rewriter.js b/node_modules/coffee-script/lib/coffee-script/rewriter.js new file mode 100644 index 0000000..007bb87 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/rewriter.js @@ -0,0 +1,504 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, k, left, len, ref, rite, + 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; + + generate = function(tag, value, origin) { + var tok; + tok = [tag, value]; + tok.generated = true; + if (origin) { + tok.origin = origin; + } + return tok; + }; + + exports.Rewriter = (function() { + function Rewriter() {} + + Rewriter.prototype.rewrite = function(tokens1) { + this.tokens = tokens1; + this.removeLeadingNewlines(); + this.closeOpenCalls(); + this.closeOpenIndexes(); + this.normalizeLines(); + this.tagPostfixConditionals(); + this.addImplicitBracesAndParens(); + this.addLocationDataToGeneratedTokens(); + 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, ref, ref1, token, tokens; + 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, k, len, ref, tag; + ref = this.tokens; + for (i = k = 0, len = ref.length; k < len; i = ++k) { + tag = ref[i][0]; + if (tag !== 'TERMINATOR') { + break; + } + } + if (i) { + return this.tokens.splice(0, i); + } + }; + + 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.indexOfTag = function() { + var fuzz, i, j, k, pattern, ref, ref1; + i = arguments[0], pattern = 2 <= arguments.length ? slice.call(arguments, 1) : []; + fuzz = 0; + for (j = k = 0, ref = pattern.length; 0 <= ref ? k < ref : k > ref; j = 0 <= ref ? ++k : --k) { + while (this.tag(i + j + fuzz) === 'HERECOMMENT') { + fuzz += 2; + } + if (pattern[j] == null) { + continue; + } + if (typeof pattern[j] === 'string') { + pattern[j] = [pattern[j]]; + } + if (ref1 = this.tag(i + j + fuzz), indexOf.call(pattern[j], ref1) < 0) { + return -1; + } + } + return i + j + fuzz - 1; + }; + + Rewriter.prototype.looksObjectish = function(j) { + var end, index; + if (this.indexOfTag(j, '@', null, ':') > -1 || this.indexOfTag(j, null, ':') > -1) { + return true; + } + index = this.indexOfTag(j, EXPRESSION_START); + if (index > -1) { + end = null; + this.detectEnd(index + 1, (function(token) { + var ref; + return ref = token[0], indexOf.call(EXPRESSION_END, ref) >= 0; + }), (function(token, i) { + return end = i; + })); + if (this.tag(end + 1) === ':') { + return true; + } + } + return false; + }; + + Rewriter.prototype.findTagsBackwards = function(i, tags) { + var backStack, ref, ref1, ref2, ref3, ref4, ref5; + backStack = []; + while (i >= 0 && (backStack.length || (ref2 = this.tag(i), indexOf.call(tags, ref2) < 0) && ((ref3 = this.tag(i), indexOf.call(EXPRESSION_START, ref3) < 0) || this.tokens[i].generated) && (ref4 = this.tag(i), indexOf.call(LINEBREAKS, ref4) < 0))) { + if (ref = this.tag(i), indexOf.call(EXPRESSION_END, ref) >= 0) { + backStack.push(this.tag(i)); + } + if ((ref1 = this.tag(i), indexOf.call(EXPRESSION_START, ref1) >= 0) && backStack.length) { + backStack.pop(); + } + i -= 1; + } + return ref5 = this.tag(i), indexOf.call(tags, ref5) >= 0; + }; + + Rewriter.prototype.addImplicitBracesAndParens = function() { + var stack, start; + stack = []; + start = null; + return this.scanTokens(function(token, i, tokens) { + var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, newLine, nextTag, offset, prevTag, prevToken, ref, ref1, ref2, ref3, ref4, ref5, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag; + tag = token[0]; + prevTag = (prevToken = i > 0 ? tokens[i - 1] : [])[0]; + nextTag = (i < tokens.length - 1 ? tokens[i + 1] : [])[0]; + stackTop = function() { + return stack[stack.length - 1]; + }; + startIdx = i; + forward = function(n) { + return i - startIdx + n; + }; + inImplicit = function() { + var ref, ref1; + return (ref = stackTop()) != null ? (ref1 = ref[2]) != null ? ref1.ours : void 0 : void 0; + }; + inImplicitCall = function() { + var ref; + return inImplicit() && ((ref = stackTop()) != null ? ref[0] : void 0) === '('; + }; + inImplicitObject = function() { + var ref; + return inImplicit() && ((ref = stackTop()) != null ? ref[0] : void 0) === '{'; + }; + inImplicitControl = function() { + var ref; + return inImplicit && ((ref = stackTop()) != null ? ref[0] : void 0) === 'CONTROL'; + }; + startImplicitCall = function(j) { + var idx; + idx = j != null ? j : i; + stack.push([ + '(', idx, { + ours: true + } + ]); + tokens.splice(idx, 0, generate('CALL_START', '(')); + if (j == null) { + return i += 1; + } + }; + endImplicitCall = function() { + stack.pop(); + tokens.splice(i, 0, generate('CALL_END', ')', ['', 'end of input', token[2]])); + return i += 1; + }; + startImplicitObject = function(j, startsLine) { + var idx, val; + if (startsLine == null) { + startsLine = true; + } + idx = j != null ? j : i; + stack.push([ + '{', idx, { + sameLine: true, + startsLine: startsLine, + ours: true + } + ]); + val = new String('{'); + val.generated = true; + tokens.splice(idx, 0, generate('{', val, token)); + if (j == null) { + return i += 1; + } + }; + endImplicitObject = function(j) { + j = j != null ? j : i; + stack.pop(); + tokens.splice(j, 0, generate('}', '}', token)); + return i += 1; + }; + if (inImplicitCall() && (tag === 'IF' || tag === 'TRY' || tag === 'FINALLY' || tag === 'CATCH' || tag === 'CLASS' || tag === 'SWITCH')) { + stack.push([ + 'CONTROL', i, { + ours: true + } + ]); + return forward(1); + } + if (tag === 'INDENT' && inImplicit()) { + if (prevTag !== '=>' && prevTag !== '->' && prevTag !== '[' && prevTag !== '(' && prevTag !== ',' && prevTag !== '{' && prevTag !== 'TRY' && prevTag !== 'ELSE' && prevTag !== '=') { + while (inImplicitCall()) { + endImplicitCall(); + } + } + if (inImplicitControl()) { + stack.pop(); + } + stack.push([tag, i]); + return forward(1); + } + if (indexOf.call(EXPRESSION_START, tag) >= 0) { + stack.push([tag, i]); + return forward(1); + } + if (indexOf.call(EXPRESSION_END, tag) >= 0) { + while (inImplicit()) { + if (inImplicitCall()) { + endImplicitCall(); + } else if (inImplicitObject()) { + endImplicitObject(); + } else { + stack.pop(); + } + } + start = stack.pop(); + } + if ((indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced || tag === '?' && i > 0 && !tokens[i - 1].spaced) && (indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !((ref = tokens[i + 1]) != null ? ref.spaced : void 0) && !((ref1 = tokens[i + 1]) != null ? ref1.newLine : void 0))) { + if (tag === '?') { + tag = token[0] = 'FUNC_EXIST'; + } + startImplicitCall(i + 1); + return forward(2); + } + if (indexOf.call(IMPLICIT_FUNC, tag) >= 0 && this.indexOfTag(i + 1, 'INDENT') > -1 && this.looksObjectish(i + 2) && !this.findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH', 'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL'])) { + startImplicitCall(i + 1); + stack.push(['INDENT', i + 2]); + return forward(3); + } + if (tag === ':') { + s = (function() { + var ref2; + switch (false) { + case ref2 = this.tag(i - 1), indexOf.call(EXPRESSION_END, ref2) < 0: + return start[1]; + case this.tag(i - 2) !== '@': + return i - 2; + default: + return i - 1; + } + }).call(this); + while (this.tag(s - 2) === 'HERECOMMENT') { + s -= 2; + } + this.insideForDeclaration = nextTag === 'FOR'; + startsLine = s === 0 || (ref2 = this.tag(s - 1), indexOf.call(LINEBREAKS, ref2) >= 0) || tokens[s - 1].newLine; + if (stackTop()) { + ref3 = stackTop(), stackTag = ref3[0], stackIdx = ref3[1]; + if ((stackTag === '{' || stackTag === 'INDENT' && this.tag(stackIdx - 1) === '{') && (startsLine || this.tag(s - 1) === ',' || this.tag(s - 1) === '{')) { + return forward(1); + } + } + startImplicitObject(s, !!startsLine); + return forward(2); + } + if (inImplicitObject() && indexOf.call(LINEBREAKS, tag) >= 0) { + stackTop()[2].sameLine = false; + } + newLine = prevTag === 'OUTDENT' || prevToken.newLine; + if (indexOf.call(IMPLICIT_END, tag) >= 0 || indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) { + while (inImplicit()) { + ref4 = stackTop(), stackTag = ref4[0], stackIdx = ref4[1], (ref5 = ref4[2], sameLine = ref5.sameLine, startsLine = ref5.startsLine); + if (inImplicitCall() && prevTag !== ',') { + endImplicitCall(); + } else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':') { + endImplicitObject(); + } else if (inImplicitObject() && tag === 'TERMINATOR' && prevTag !== ',' && !(startsLine && this.looksObjectish(i + 1))) { + if (nextTag === 'HERECOMMENT') { + return forward(1); + } + endImplicitObject(); + } else { + break; + } + } + } + if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && !this.insideForDeclaration && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) { + offset = nextTag === 'OUTDENT' ? 1 : 0; + while (inImplicitObject()) { + endImplicitObject(i + offset); + } + } + return forward(1); + }); + }; + + Rewriter.prototype.addLocationDataToGeneratedTokens = function() { + return this.scanTokens(function(token, i, tokens) { + var column, line, nextLocation, prevLocation, ref, ref1; + if (token[2]) { + return 1; + } + if (!(token.generated || token.explicit)) { + return 1; + } + if (token[0] === '{' && (nextLocation = (ref = tokens[i + 1]) != null ? ref[2] : void 0)) { + line = nextLocation.first_line, column = nextLocation.first_column; + } else if (prevLocation = (ref1 = tokens[i - 1]) != null ? ref1[2] : void 0) { + line = prevLocation.last_line, column = prevLocation.last_column; + } else { + line = column = 0; + } + token[2] = { + first_line: line, + first_column: column, + last_line: line, + last_column: column + }; + return 1; + }); + }; + + Rewriter.prototype.normalizeLines = function() { + var action, condition, indent, outdent, starter; + starter = indent = outdent = null; + condition = function(token, i) { + var ref, ref1, ref2, ref3; + return token[1] !== ';' && (ref = token[0], indexOf.call(SINGLE_CLOSERS, ref) >= 0) && !(token[0] === 'TERMINATOR' && (ref1 = this.tag(i + 1), indexOf.call(EXPRESSION_CLOSE, ref1) >= 0)) && !(token[0] === 'ELSE' && starter !== 'THEN') && !(((ref2 = token[0]) === 'CATCH' || ref2 === 'FINALLY') && (starter === '->' || starter === '=>')) || (ref3 = token[0], indexOf.call(CALL_CLOSERS, ref3) >= 0) && this.tokens[i - 1].newLine; + }; + 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 j, k, ref, ref1, ref2, tag; + tag = token[0]; + if (tag === 'TERMINATOR') { + if (this.tag(i + 1) === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { + tokens.splice.apply(tokens, [i, 1].concat(slice.call(this.indentation()))); + return 1; + } + if (ref = this.tag(i + 1), indexOf.call(EXPRESSION_CLOSE, ref) >= 0) { + tokens.splice(i, 1); + return 0; + } + } + if (tag === 'CATCH') { + for (j = k = 1; k <= 2; j = ++k) { + if (!((ref1 = this.tag(i + j)) === 'OUTDENT' || ref1 === 'TERMINATOR' || ref1 === 'FINALLY')) { + continue; + } + tokens.splice.apply(tokens, [i + j, 0].concat(slice.call(this.indentation()))); + return 2 + j; + } + } + if (indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { + starter = tag; + ref2 = this.indentation(tokens[i]), indent = ref2[0], outdent = ref2[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 prevTag, tag; + tag = token[0]; + prevTag = this.tokens[i - 1][0]; + return tag === 'TERMINATOR' || (tag === 'INDENT' && indexOf.call(SINGLE_LINERS, prevTag) < 0); + }; + 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(origin) { + var indent, outdent; + indent = ['INDENT', 2]; + outdent = ['OUTDENT', 2]; + if (origin) { + indent.generated = outdent.generated = true; + indent.origin = outdent.origin = origin; + } else { + indent.explicit = outdent.explicit = true; + } + return [indent, outdent]; + }; + + Rewriter.prototype.generate = generate; + + 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'], ['STRING_START', 'STRING_END'], ['REGEX_START', 'REGEX_END']]; + + exports.INVERSES = INVERSES = {}; + + EXPRESSION_START = []; + + EXPRESSION_END = []; + + for (k = 0, len = BALANCED_PAIRS.length; k < len; k++) { + ref = BALANCED_PAIRS[k], left = ref[0], rite = ref[1]; + EXPRESSION_START.push(INVERSES[rite] = left); + EXPRESSION_END.push(INVERSES[left] = rite); + } + + EXPRESSION_CLOSE = ['CATCH', 'THEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); + + IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; + + IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'STRING_START', 'JS', 'REGEX', 'REGEX_START', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'YIELD', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++']; + + IMPLICIT_UNSPACED_CALL = ['+', '-']; + + 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_CLOSERS = ['.', '?.', '::', '?::']; + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/scope.js b/node_modules/coffee-script/lib/coffee-script/scope.js new file mode 100644 index 0000000..0f9835a --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/scope.js @@ -0,0 +1,155 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var Scope, + 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; }; + + exports.Scope = Scope = (function() { + function Scope(parent, expressions, method, referencedVars) { + var ref, ref1; + this.parent = parent; + this.expressions = expressions; + this.method = method; + this.referencedVars = referencedVars; + this.variables = [ + { + name: 'arguments', + type: 'arguments' + } + ]; + this.positions = {}; + if (!this.parent) { + this.utilities = {}; + } + this.root = (ref = (ref1 = this.parent) != null ? ref1.root : void 0) != null ? ref : 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() { + var ref; + if (((ref = this.method) != null ? ref.name : void 0) || !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 ref; + return !!(this.type(name) || ((ref = this.parent) != null ? ref.check(name) : void 0)); + }; + + Scope.prototype.temporary = function(name, index, single) { + if (single == null) { + single = false; + } + if (single) { + return (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a'); + } else { + return name + (index || ''); + } + }; + + Scope.prototype.type = function(name) { + var i, len, ref, v; + ref = this.variables; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + if (v.name === name) { + return v.type; + } + } + return null; + }; + + Scope.prototype.freeVariable = function(name, options) { + var index, ref, temp; + if (options == null) { + options = {}; + } + index = 0; + while (true) { + temp = this.temporary(name, index, options.single); + if (!(this.check(temp) || indexOf.call(this.root.referencedVars, temp) >= 0)) { + break; + } + index++; + } + if ((ref = options.reserve) != null ? ref : true) { + 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 v; + return ((function() { + var i, len, ref, results; + ref = this.variables; + results = []; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + if (v.type === 'var') { + results.push(v.name); + } + } + return results; + }).call(this)).sort(); + }; + + Scope.prototype.assignedVariables = function() { + var i, len, ref, results, v; + ref = this.variables; + results = []; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + if (v.type.assigned) { + results.push(v.name + " = " + v.type.value); + } + } + return results; + }; + + return Scope; + + })(); + +}).call(this); diff --git a/node_modules/coffee-script/lib/coffee-script/sourcemap.js b/node_modules/coffee-script/lib/coffee-script/sourcemap.js new file mode 100644 index 0000000..ec703e1 --- /dev/null +++ b/node_modules/coffee-script/lib/coffee-script/sourcemap.js @@ -0,0 +1,161 @@ +// Generated by CoffeeScript 1.10.0 +(function() { + var LineMap, SourceMap; + + LineMap = (function() { + function LineMap(line1) { + this.line = line1; + this.columns = []; + } + + LineMap.prototype.add = function(column, arg, options) { + var sourceColumn, sourceLine; + sourceLine = arg[0], sourceColumn = arg[1]; + if (options == null) { + options = {}; + } + if (this.columns[column] && options.noReplace) { + return; + } + return this.columns[column] = { + line: this.line, + column: column, + sourceLine: sourceLine, + sourceColumn: sourceColumn + }; + }; + + LineMap.prototype.sourceLocation = function(column) { + var mapping; + while (!((mapping = this.columns[column]) || (column <= 0))) { + column--; + } + return mapping && [mapping.sourceLine, mapping.sourceColumn]; + }; + + return LineMap; + + })(); + + SourceMap = (function() { + var BASE64_CHARS, VLQ_CONTINUATION_BIT, VLQ_SHIFT, VLQ_VALUE_MASK; + + function SourceMap() { + this.lines = []; + } + + SourceMap.prototype.add = function(sourceLocation, generatedLocation, options) { + var base, column, line, lineMap; + if (options == null) { + options = {}; + } + line = generatedLocation[0], column = generatedLocation[1]; + lineMap = ((base = this.lines)[line] || (base[line] = new LineMap(line))); + return lineMap.add(column, sourceLocation, options); + }; + + SourceMap.prototype.sourceLocation = function(arg) { + var column, line, lineMap; + line = arg[0], column = arg[1]; + while (!((lineMap = this.lines[line]) || (line <= 0))) { + line--; + } + return lineMap && lineMap.sourceLocation(column); + }; + + SourceMap.prototype.generate = function(options, code) { + var buffer, i, j, lastColumn, lastSourceColumn, lastSourceLine, len, len1, lineMap, lineNumber, mapping, needComma, ref, ref1, v3, writingline; + if (options == null) { + options = {}; + } + if (code == null) { + code = null; + } + writingline = 0; + lastColumn = 0; + lastSourceLine = 0; + lastSourceColumn = 0; + needComma = false; + buffer = ""; + ref = this.lines; + for (lineNumber = i = 0, len = ref.length; i < len; lineNumber = ++i) { + lineMap = ref[lineNumber]; + if (lineMap) { + ref1 = lineMap.columns; + for (j = 0, len1 = ref1.length; j < len1; j++) { + mapping = ref1[j]; + if (!(mapping)) { + continue; + } + while (writingline < mapping.line) { + lastColumn = 0; + needComma = false; + buffer += ";"; + writingline++; + } + if (needComma) { + buffer += ","; + needComma = false; + } + buffer += this.encodeVlq(mapping.column - lastColumn); + lastColumn = mapping.column; + buffer += this.encodeVlq(0); + buffer += this.encodeVlq(mapping.sourceLine - lastSourceLine); + lastSourceLine = mapping.sourceLine; + buffer += this.encodeVlq(mapping.sourceColumn - lastSourceColumn); + lastSourceColumn = mapping.sourceColumn; + needComma = true; + } + } + } + v3 = { + version: 3, + file: options.generatedFile || '', + sourceRoot: options.sourceRoot || '', + sources: options.sourceFiles || [''], + names: [], + mappings: buffer + }; + if (options.inline) { + v3.sourcesContent = [code]; + } + return JSON.stringify(v3, null, 2); + }; + + VLQ_SHIFT = 5; + + VLQ_CONTINUATION_BIT = 1 << VLQ_SHIFT; + + VLQ_VALUE_MASK = VLQ_CONTINUATION_BIT - 1; + + SourceMap.prototype.encodeVlq = function(value) { + var answer, nextChunk, signBit, valueToEncode; + answer = ''; + signBit = value < 0 ? 1 : 0; + valueToEncode = (Math.abs(value) << 1) + signBit; + while (valueToEncode || !answer) { + nextChunk = valueToEncode & VLQ_VALUE_MASK; + valueToEncode = valueToEncode >> VLQ_SHIFT; + if (valueToEncode) { + nextChunk |= VLQ_CONTINUATION_BIT; + } + answer += this.encodeBase64(nextChunk); + } + return answer; + }; + + BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + SourceMap.prototype.encodeBase64 = function(value) { + return BASE64_CHARS[value] || (function() { + throw new Error("Cannot Base64 encode value: " + value); + })(); + }; + + return SourceMap; + + })(); + + module.exports = SourceMap; + +}).call(this); diff --git a/node_modules/coffee-script/package.json b/node_modules/coffee-script/package.json new file mode 100644 index 0000000..9a8e9d0 --- /dev/null +++ b/node_modules/coffee-script/package.json @@ -0,0 +1,97 @@ +{ + "_args": [ + [ + "coffee-script@>=1.0.1", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-node" + ] + ], + "_from": "coffee-script@>=1.0.1", + "_id": "coffee-script@1.10.0", + "_inCache": true, + "_installable": true, + "_location": "/coffee-script", + "_npmUser": { + "email": "jashkenas@gmail.com", + "name": "jashkenas" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "name": "coffee-script", + "raw": "coffee-script@>=1.0.1", + "rawSpec": ">=1.0.1", + "scope": null, + "spec": ">=1.0.1", + "type": "range" + }, + "_requiredBy": [ + "/jasmine-node" + ], + "_resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz", + "_shasum": "12938bcf9be1948fa006f92e0c4c9e81705108c0", + "_shrinkwrap": null, + "_spec": "coffee-script@>=1.0.1", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-node", + "author": { + "name": "Jeremy Ashkenas" + }, + "bin": { + "cake": "./bin/cake", + "coffee": "./bin/coffee" + }, + "bugs": { + "url": "https://github.com/jashkenas/coffeescript/issues" + }, + "dependencies": {}, + "description": "Unfancy JavaScript", + "devDependencies": { + "docco": "~0.7.0", + "highlight.js": "~8.0.0", + "jison": ">=0.2.0", + "uglify-js": "~2.2", + "underscore": "~1.5.2" + }, + "directories": { + "lib": "./lib/coffee-script" + }, + "dist": { + "shasum": "12938bcf9be1948fa006f92e0c4c9e81705108c0", + "tarball": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz" + }, + "engines": { + "node": ">=0.8.0" + }, + "gitHead": "f26d33d418dcdcfcc6ad3ab774d9cabbf7af659c", + "homepage": "http://coffeescript.org", + "keywords": [ + "coffeescript", + "compiler", + "javascript", + "language" + ], + "license": "MIT", + "main": "./lib/coffee-script/coffee-script", + "maintainers": [ + { + "name": "jashkenas", + "email": "jashkenas@gmail.com" + }, + { + "name": "michaelficarra", + "email": "npm@michael.ficarra.me" + } + ], + "name": "coffee-script", + "optionalDependencies": {}, + "preferGlobal": true, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jashkenas/coffeescript.git" + }, + "scripts": { + "test": "node ./bin/cake test", + "test-harmony": "node --harmony ./bin/cake test" + }, + "version": "1.10.0" +} diff --git a/node_modules/coffee-script/register.js b/node_modules/coffee-script/register.js new file mode 100644 index 0000000..97b33d7 --- /dev/null +++ b/node_modules/coffee-script/register.js @@ -0,0 +1 @@ +require('./lib/coffee-script/register'); diff --git a/node_modules/coffee-script/repl.js b/node_modules/coffee-script/repl.js new file mode 100644 index 0000000..d2706a7 --- /dev/null +++ b/node_modules/coffee-script/repl.js @@ -0,0 +1 @@ +module.exports = require('./lib/coffee-script/repl'); diff --git a/node_modules/fileset/.npmignore b/node_modules/fileset/.npmignore new file mode 100644 index 0000000..08b2553 --- /dev/null +++ b/node_modules/fileset/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/fileset/.travis.yml b/node_modules/fileset/.travis.yml new file mode 100644 index 0000000..a4b0e3c --- /dev/null +++ b/node_modules/fileset/.travis.yml @@ -0,0 +1,5 @@ +language: node_js + +node_js: + - 0.4 + - 0.6 \ No newline at end of file diff --git a/node_modules/fileset/LICENSE-MIT b/node_modules/fileset/LICENSE-MIT new file mode 100644 index 0000000..63f400b --- /dev/null +++ b/node_modules/fileset/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2012 Mickael Daniel + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/fileset/README.md b/node_modules/fileset/README.md new file mode 100644 index 0000000..98f50ba --- /dev/null +++ b/node_modules/fileset/README.md @@ -0,0 +1,87 @@ +# node-fileset + +Exposes a basic wrapper on top of +[Glob](https://github.com/isaacs/node-glob) / +[minimatch](https://github.com/isaacs/minimatch) combo both written by +@isaacs. Glob now uses JavaScript instead of C++ bindings which makes it +usable in Node.js 0.6.x and Windows platforms. + +[![Build Status](https://secure.travis-ci.org/mklabs/node-fileset.png)](http://travis-ci.org/mklabs/node-fileset) + +Adds multiples patterns matching and exlude ability. This is +basically just a sugar API syntax where you can specify a list of includes +and optional exclude patterns. It works by setting up the necessary +miniglob "fileset" and filtering out the results using minimatch. + +## Install + + npm install fileset + +## Usage + +Can be used with callback or emitter style. + +* **include**: list of glob patterns `foo/**/*.js *.md src/lib/**/*` +* **exclude**: *optional* list of glob patterns to filter include + results `foo/**/*.js *.md` +* **callback**: *optional* function that gets called with an error if + something wrong happend, otherwise null with an array of results + +The callback is optional since the fileset method return an instance of +EventEmitter which emit different events you might use: + +* *match*: Every time a match is found, miniglob emits this event with + the pattern. +* *include*: Emitted each time an include match is found. +* *exclude*: Emitted each time an exclude match is found and filtered + out from the fileset. +* *end*: Emitted when the matching is finished with all the matches + found, optionally filtered by the exclude patterns. + +#### Callback + +```js +var fileset = require('fileset'); + +fileset('**/*.js', '**.min.js', function(err, files) { + if (err) return console.error(err); + + console.log('Files: ', files.length); + console.log(files); +}); +``` + +#### Event emitter + +```js +var fileset = require('fileset'); + +fileset('**.coffee README.md *.json Cakefile **.js', 'node_modules/**') + .on('match', console.log.bind(console, 'error')) + .on('include', console.log.bind(console, 'includes')) + .on('exclude', console.log.bind(console, 'excludes')) + .on('end', console.log.bind(console, 'end')); +``` + +`fileset` returns an instance of EventEmitter, with an `includes` property +which is the array of Fileset objects (inheriting from +`miniglob.Miniglob`) that were used during the mathing process, should +you want to use them individually. + +Check out the +[tests](https://github.com/mklabs/node-fileset/tree/master/tests) for +more examples. + +## Tests + +Run `npm test` + +## Why + +Mainly for a build tool with cake files, to provide me an easy way to get +a list of files by either using glob or path patterns, optionally +allowing exclude patterns to filter out the results. + +All the magic is happening in +[Glob](https://github.com/isaacs/node-glob) and +[minimatch](https://github.com/isaacs/minimatch). Check them out! diff --git a/node_modules/fileset/lib/fileset.js b/node_modules/fileset/lib/fileset.js new file mode 100644 index 0000000..5ec4870 --- /dev/null +++ b/node_modules/fileset/lib/fileset.js @@ -0,0 +1,64 @@ +var util = require('util'), + minimatch = require('minimatch'), + Glob = require('glob').Glob, + EventEmitter = require('events').EventEmitter; + +module.exports = fileset; + +function fileset(include, exclude, options, cb) { + if (typeof exclude === 'function') cb = exclude, exclude = ''; + else if (typeof options === 'function') cb = options, options = {}; + + var includes = (typeof include === 'string') ? include.split(' ') : include; + var excludes = (typeof exclude === 'string') ? exclude.split(' ') : exclude; + + var em = new EventEmitter, + remaining = includes.length, + results = []; + + if(!includes.length) return cb(new Error('Must provide an include pattern')); + + em.includes = includes.map(function(pattern) { + return new fileset.Fileset(pattern, options) + .on('error', cb ? cb : em.emit.bind(em, 'error')) + .on('match', em.emit.bind(em, 'match')) + .on('match', em.emit.bind(em, 'include')) + .on('end', next.bind({}, pattern)) + }); + + function next(pattern, matches) { + results = results.concat(matches); + + if(!(--remaining)) { + results = results.filter(function(file) { + return !excludes.filter(function(glob) { + var match = minimatch(file, glob, { matchBase: true }); + if(match) em.emit('exclude', file); + return match; + }).length; + }); + + if(cb) cb(null, results); + em.emit('end', results); + } + } + + return em; +} + +fileset.Fileset = function Fileset(pattern, options, cb) { + + if (typeof options === 'function') cb = options, options = {}; + if (!options) options = {}; + + Glob.call(this, pattern, options); + + if(typeof cb === 'function') { + this.on('error', cb); + this.on('end', function(matches) { cb(null, matches); }); + } +}; + +util.inherits(fileset.Fileset, Glob); + + diff --git a/node_modules/fileset/package.json b/node_modules/fileset/package.json new file mode 100644 index 0000000..4a597e9 --- /dev/null +++ b/node_modules/fileset/package.json @@ -0,0 +1,79 @@ +{ + "_args": [ + [ + "fileset@~0.1.5", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/gaze" + ] + ], + "_from": "fileset@>=0.1.5 <0.2.0", + "_id": "fileset@0.1.8", + "_inCache": true, + "_installable": true, + "_location": "/fileset", + "_nodeVersion": "0.12.4", + "_npmUser": { + "email": "daniel.mickael@gmail.com", + "name": "mklabs" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "name": "fileset", + "raw": "fileset@~0.1.5", + "rawSpec": "~0.1.5", + "scope": null, + "spec": ">=0.1.5 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/gaze" + ], + "_resolved": "https://registry.npmjs.org/fileset/-/fileset-0.1.8.tgz", + "_shasum": "506b91a9396eaa7e32fb42a84077c7a0c736b741", + "_shrinkwrap": null, + "_spec": "fileset@~0.1.5", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/gaze", + "author": { + "name": "mklabs" + }, + "bugs": { + "url": "https://github.com/mklabs/node-fileset/issues" + }, + "dependencies": { + "glob": "3.x", + "minimatch": "0.x" + }, + "description": "Wrapper around miniglob / minimatch combo to allow multiple patterns matching and include-exclude ability", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "506b91a9396eaa7e32fb42a84077c7a0c736b741", + "tarball": "http://registry.npmjs.org/fileset/-/fileset-0.1.8.tgz" + }, + "gitHead": "1f78d5ecba35aef294ea726511c1daa5b07a6b5d", + "homepage": "https://github.com/mklabs/node-fileset", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/mklabs/node-fileset/blob/master/LICENSE-MIT" + } + ], + "main": "./lib/fileset", + "maintainers": [ + { + "name": "mklabs", + "email": "daniel.mickael@gmail.com" + } + ], + "name": "fileset", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/mklabs/node-fileset.git" + }, + "scripts": { + "test": "node tests/test.js" + }, + "version": "0.1.8" +} diff --git a/node_modules/fileset/tests/fixtures/an (odd) filename.js b/node_modules/fileset/tests/fixtures/an (odd) filename.js new file mode 100644 index 0000000..fbf9f2b --- /dev/null +++ b/node_modules/fileset/tests/fixtures/an (odd) filename.js @@ -0,0 +1 @@ +var odd = true; \ No newline at end of file diff --git a/node_modules/fileset/tests/helper.js b/node_modules/fileset/tests/helper.js new file mode 100644 index 0000000..0fb0b25 --- /dev/null +++ b/node_modules/fileset/tests/helper.js @@ -0,0 +1,61 @@ + +var EventEmitter = require('events').EventEmitter, + assert = require('assert'), + tests = {}; + +module.exports = test; +test.run = run; + +// ## Test helpers + +function test(msg, handler) { + tests[msg] = handler; +} + +function run() { + var specs = Object.keys(tests), + specsRemaining = specs.length; + + specs.forEach(function(spec) { + var handler = tests[spec]; + + // grab the set of asserts for this spec + var shoulds = handler(), + keys = Object.keys(shoulds), + remaining = keys.length; + + keys.forEach(function(should) { + var em = new EventEmitter(), + to = setTimeout(function() { + assert.fail('never ended'); + }, 5000); + + em + .on('error', function assertFail(err) { assert.fail(err) }) + .on('end', function assertOk() { + clearTimeout(to); + shoulds[should].status = true; + + // till we get to 0 + if(!(--remaining)) { + console.log([ + '', + '» ' + spec, + keys.map(function(k) { return ' » ' + k; }).join('\n'), + '', + ' Total: ' + keys.length, + ' Failed: ' + keys.map(function(item) { return shoulds[should].status; }).filter(function(status) { return !status; }).length, + '' + ].join('\n')); + + if(!(--specsRemaining)) { + console.log('All done'); + } + + } + }); + + shoulds[should](em); + }); + }); +} diff --git a/node_modules/fileset/tests/test.js b/node_modules/fileset/tests/test.js new file mode 100644 index 0000000..3df267a --- /dev/null +++ b/node_modules/fileset/tests/test.js @@ -0,0 +1,133 @@ + +var EventEmitter = require('events').EventEmitter, + fileset = require('../'), + assert = require('assert'), + test = require('./helper'); + +// Given a **.coffee pattern +test('Given a **.md pattern', function() { + + return { + 'should return the list of matching file in this repo': function(em) { + fileset('*.md', function(err, results) { + if(err) return em.emit('error', err); + assert.ok(Array.isArray(results), 'should be an array'); + assert.ok(results.length, 'should return at least one element'); + assert.equal(results.length, 1, 'actually, should return only one'); + em.emit('end'); + }); + } + } +}); + +test('Say we want the **.js files, but not those in node_modules', function() { + + return { + 'Should recursively walk the dir and return the matching list': function(em) { + fileset('**/*.js', 'node_modules/**', function(err, results) { + if(err) return em.emit('error', err); + assert.ok(Array.isArray(results), 'should be an array'); + assert.equal(results.length, 4); + em.emit('end'); + }); + }, + + 'Should support multiple paths at once': function(em) { + fileset('**/*.js *.md', 'node_modules/**', function(err, results) { + if(err) return em.emit('error', err); + assert.ok(Array.isArray(results), 'should be an array'); + assert.equal(results.length, 5); + + assert.deepEqual(results, [ + 'README.md', + 'lib/fileset.js', + 'tests/fixtures/an (odd) filename.js', + 'tests/helper.js', + 'tests/test.js' + ]); + + em.emit('end'); + }); + }, + + 'Should support multiple paths for excludes as well': function(em) { + fileset('**/*.js *.md', 'node_modules/** **.md tests/*.js', function(err, results) { + if(err) return em.emit('error', err); + assert.ok(Array.isArray(results), 'should be an array'); + assert.equal(results.length, 2); + + assert.deepEqual(results, [ + 'lib/fileset.js', + 'tests/fixtures/an (odd) filename.js', + ]); + + em.emit('end'); + }); + } + } +}); + + +test('Testing out emmited events', function() { + + // todos: the tests for match, include, exclude events, but seems like it's ok + return { + 'Should recursively walk the dir and return the matching list': function(em) { + fileset('**/*.js', 'node_modules/**') + .on('error', em.emit.bind(em, 'error')) + .on('end', function(results) { + assert.ok(Array.isArray(results), 'should be an array'); + assert.equal(results.length, 4); + em.emit('end'); + }); + }, + + 'Should support multiple paths at once': function(em) { + fileset('**/*.js *.md', 'node_modules/**') + .on('error', em.emit.bind(em, 'error')) + .on('end', function(results) { + assert.ok(Array.isArray(results), 'should be an array'); + assert.equal(results.length, 5); + + assert.deepEqual(results, [ + 'README.md', + 'lib/fileset.js', + 'tests/fixtures/an (odd) filename.js', + 'tests/helper.js', + 'tests/test.js' + ]); + + em.emit('end'); + }); + } + } +}); + + +test('Testing patterns passed as arrays', function() { + + return { + 'Should match files passed as an array with odd filenames': function(em) { + fileset(['lib/*.js', 'tests/fixtures/an (odd) filename.js'], ['node_modules/**']) + .on('error', em.emit.bind(em, 'error')) + .on('end', function(results) { + assert.ok(Array.isArray(results), 'should be an array'); + assert.equal(results.length, 2); + + assert.deepEqual(results, [ + 'lib/fileset.js', + 'tests/fixtures/an (odd) filename.js', + ]); + + em.emit('end'); + }); + } + } + +}); + + + +test.run(); + + diff --git a/node_modules/gaze/.editorconfig b/node_modules/gaze/.editorconfig new file mode 100644 index 0000000..0f09989 --- /dev/null +++ b/node_modules/gaze/.editorconfig @@ -0,0 +1,10 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/node_modules/gaze/.jshintrc b/node_modules/gaze/.jshintrc new file mode 100644 index 0000000..6b4c1a9 --- /dev/null +++ b/node_modules/gaze/.jshintrc @@ -0,0 +1,14 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "boss": true, + "eqnull": true, + "node": true, + "es5": true +} diff --git a/node_modules/gaze/.npmignore b/node_modules/gaze/.npmignore new file mode 100644 index 0000000..2ccbe46 --- /dev/null +++ b/node_modules/gaze/.npmignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/node_modules/gaze/.travis.yml b/node_modules/gaze/.travis.yml new file mode 100644 index 0000000..343380c --- /dev/null +++ b/node_modules/gaze/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - 0.8 + - 0.9 +before_script: + - npm install -g grunt-cli diff --git a/node_modules/gaze/AUTHORS b/node_modules/gaze/AUTHORS new file mode 100644 index 0000000..69d9663 --- /dev/null +++ b/node_modules/gaze/AUTHORS @@ -0,0 +1,5 @@ +Kyle Robinson Young (http://dontkry.com) +Sam Day (http://sam.is-super-awesome.com) +Roarke Gaskill (http://starkinvestments.com) +Lance Pollard (http://lancepollard.com/) +Daniel Fagnan (http://hydrocodedesign.com/) diff --git a/node_modules/gaze/Gruntfile.js b/node_modules/gaze/Gruntfile.js new file mode 100644 index 0000000..0206147 --- /dev/null +++ b/node_modules/gaze/Gruntfile.js @@ -0,0 +1,32 @@ +module.exports = function(grunt) { + 'use strict'; + grunt.initConfig({ + benchmark: { + all: { + src: ['benchmarks/*.js'], + options: { times: 10 } + } + }, + nodeunit: { + files: ['test/**/*_test.js'], + }, + jshint: { + options: { + jshintrc: '.jshintrc' + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib: { + src: ['lib/**/*.js'] + }, + test: { + src: ['test/**/*_test.js'] + }, + } + }); + grunt.loadNpmTasks('grunt-benchmark'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-nodeunit'); + grunt.registerTask('default', ['jshint', 'nodeunit']); +}; diff --git a/node_modules/gaze/LICENSE-MIT b/node_modules/gaze/LICENSE-MIT new file mode 100644 index 0000000..8c1a833 --- /dev/null +++ b/node_modules/gaze/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 Kyle Robinson Young + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/gaze/README.md b/node_modules/gaze/README.md new file mode 100644 index 0000000..ed2acbe --- /dev/null +++ b/node_modules/gaze/README.md @@ -0,0 +1,172 @@ +# gaze [![Build Status](https://secure.travis-ci.org/shama/gaze.png?branch=master)](http://travis-ci.org/shama/gaze) + +A globbing fs.watch wrapper built from the best parts of other fine watch libs. + +Compatible with NodeJS v0.8/0.6, Windows, OSX and Linux. + +## Usage +Install the module with: `npm install gaze` or place into your `package.json` +and run `npm install`. + +```javascript +var gaze = require('gaze'); + +// Watch all .js files/dirs in process.cwd() +gaze('**/*.js', function(err, watcher) { + // Files have all started watching + // watcher === this + + // Get all watched files + console.log(this.watched()); + + // On file changed + this.on('changed', function(filepath) { + console.log(filepath + ' was changed'); + }); + + // On file added + this.on('added', function(filepath) { + console.log(filepath + ' was added'); + }); + + // On file deleted + this.on('deleted', function(filepath) { + console.log(filepath + ' was deleted'); + }); + + // On changed/added/deleted + this.on('all', function(event, filepath) { + console.log(filepath + ' was ' + event); + }); + + // Get watched files with relative paths + console.log(this.relative()); +}); + +// Also accepts an array of patterns +gaze(['stylesheets/*.css', 'images/**/*.png'], function() { + // Add more patterns later to be watched + this.add(['js/*.js']); +}); +``` + +### Alternate Interface + +```javascript +var Gaze = require('gaze').Gaze; + +var gaze = new Gaze('**/*'); + +// Files have all started watching +gaze.on('ready', function(watcher) { }); + +// A file has been added/changed/deleted has occurred +gaze.on('all', function(event, filepath) { }); +``` + +### Errors + +```javascript +gaze('**/*', function() { + this.on('error', function(err) { + // Handle error here + }); +}); +``` + +### Minimatch / Glob + +See [isaacs's minimatch](https://github.com/isaacs/minimatch) for more +information on glob patterns. + +## Documentation + +### gaze(patterns, [options], callback) + +* `patterns` {String|Array} File patterns to be matched +* `options` {Object} +* `callback` {Function} + * `err` {Error | null} + * `watcher` {Object} Instance of the Gaze watcher + +### Class: gaze.Gaze + +Create a Gaze object by instanting the `gaze.Gaze` class. + +```javascript +var Gaze = require('gaze').Gaze; +var gaze = new Gaze(pattern, options, callback); +``` + +#### Properties + +* `options` The options object passed in. + * `interval` {integer} Interval to pass to fs.watchFile + * `debounceDelay` {integer} Delay for events called in succession for the same + file/event + +#### Events + +* `ready(watcher)` When files have been globbed and watching has begun. +* `all(event, filepath)` When an `added`, `changed` or `deleted` event occurs. +* `added(filepath)` When a file has been added to a watch directory. +* `changed(filepath)` When a file has been changed. +* `deleted(filepath)` When a file has been deleted. +* `renamed(newPath, oldPath)` When a file has been renamed. +* `end()` When the watcher is closed and watches have been removed. +* `error(err)` When an error occurs. + +#### Methods + +* `emit(event, [...])` Wrapper for the EventEmitter.emit. + `added`|`changed`|`deleted` events will also trigger the `all` event. +* `close()` Unwatch all files and reset the watch instance. +* `add(patterns, callback)` Adds file(s) patterns to be watched. +* `remove(filepath)` removes a file or directory from being watched. Does not + recurse directories. +* `watched()` Returns the currently watched files. +* `relative([dir, unixify])` Returns the currently watched files with relative paths. + * `dir` {string} Only return relative files for this directory. + * `unixify` {boolean} Return paths with `/` instead of `\\` if on Windows. + +## FAQs + +### Why Another `fs.watch` Wrapper? +I liked parts of other `fs.watch` wrappers but none had all the features I +needed. This lib combines the features I needed from other fine watch libs: +Speedy data behavior from +[paulmillr's chokidar](https://github.com/paulmillr/chokidar), API interface +from [mikeal's watch](https://github.com/mikeal/watch) and file globbing using +[isaacs's glob](https://github.com/isaacs/node-glob) which is also used by +[cowboy's Grunt](https://github.com/gruntjs/grunt). + +### How do I fix the error `EMFILE: Too many opened files.`? +This is because of your system's max opened file limit. For OSX the default is +very low (256). Increase your limit temporarily with `ulimit -n 10480`, the +number being the new max limit. + +## 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 +* 0.3.4 - Code clean up. Fix path must be strings errors (@groner). Fix incorrect added events (@groner). +* 0.3.3 - Fix for multiple patterns with negate. +* 0.3.2 - Emit `end` before removeAllListeners. +* 0.3.1 - Fix added events within subfolder patterns. +* 0.3.0 - Handle safewrite events, `forceWatchMethod` option removed, bug fixes and watch optimizations (@rgaskill). +* 0.2.2 - Fix issue where subsequent add calls dont get watched (@samcday). removeAllListeners on close. +* 0.2.1 - Fix issue with invalid `added` events in current working dir. +* 0.2.0 - Support and mark folders with `path.sep`. Add `forceWatchMethod` option. Support `renamed` events. +* 0.1.6 - Recognize the `cwd` option properly +* 0.1.5 - Catch too many open file errors +* 0.1.4 - Really fix the race condition with 2 watches +* 0.1.3 - Fix race condition with 2 watches +* 0.1.2 - Read triggering changed event fix +* 0.1.1 - Minor fixes +* 0.1.0 - Initial release + +## License +Copyright (c) 2013 Kyle Robinson Young +Licensed under the MIT license. diff --git a/node_modules/gaze/benchmarks/gaze100s.js b/node_modules/gaze/benchmarks/gaze100s.js new file mode 100644 index 0000000..1ada219 --- /dev/null +++ b/node_modules/gaze/benchmarks/gaze100s.js @@ -0,0 +1,46 @@ +'use strict'; + +var gaze = require('../lib/gaze'); +var grunt = require('grunt'); +var path = require('path'); + +// Folder to watch +var watchDir = path.resolve(__dirname, 'watch'); + +// Helper for creating mock files +function createFiles(num, dir) { + for (var i = 0; i < num; i++) { + grunt.file.write(path.join(dir, 'test-' + i + '.js'), 'var test = ' + i + ';'); + } +} + +module.exports = { + 'setUp': function(done) { + // ensure that your `ulimit -n` is higher than amount of files + if (grunt.file.exists(watchDir)) { + grunt.file.delete(watchDir, {force:true}); + } + createFiles(100, path.join(watchDir, 'one')); + createFiles(100, path.join(watchDir, 'two')); + createFiles(100, path.join(watchDir, 'three')); + createFiles(100, path.join(watchDir, 'three', 'four')); + createFiles(100, path.join(watchDir, 'three', 'four', 'five', 'six')); + process.chdir(watchDir); + done(); + }, + 'tearDown': function(done) { + if (grunt.file.exists(watchDir)) { + grunt.file.delete(watchDir, {force:true}); + } + done(); + }, + changed: function(done) { + gaze('**/*', {maxListeners:0}, function(err, watcher) { + this.on('changed', done); + setTimeout(function() { + var rand = String(new Date().getTime()).replace(/[^\w]+/g, ''); + grunt.file.write(path.join(watchDir, 'one', 'test-99.js'), 'var test = "' + rand + '"'); + }, 100); + }); + } +}; \ No newline at end of file diff --git a/node_modules/gaze/lib/gaze.js b/node_modules/gaze/lib/gaze.js new file mode 100644 index 0000000..85da897 --- /dev/null +++ b/node_modules/gaze/lib/gaze.js @@ -0,0 +1,466 @@ +/* + * gaze + * https://github.com/shama/gaze + * + * Copyright (c) 2013 Kyle Robinson Young + * Licensed under the MIT license. + */ + +'use strict'; + +// libs +var util = require('util'); +var EE = require('events').EventEmitter; +var fs = require('fs'); +var path = require('path'); +var fileset = require('fileset'); +var minimatch = require('minimatch'); + +// globals +var delay = 10; + +// `Gaze` EventEmitter object to return in the callback +function Gaze(patterns, opts, done) { + var _this = this; + EE.call(_this); + + // If second arg is the callback + if (typeof opts === 'function') { + done = opts; + opts = {}; + } + + // Default options + opts = opts || {}; + opts.mark = true; + opts.interval = opts.interval || 100; + opts.debounceDelay = opts.debounceDelay || 500; + opts.cwd = opts.cwd || process.cwd(); + this.options = opts; + + // Default done callback + done = done || function() {}; + + // Remember our watched dir:files + this._watched = Object.create(null); + + // Store watchers + this._watchers = Object.create(null); + + // Store patterns + this._patterns = []; + + // Cached events for debouncing + this._cached = Object.create(null); + + // Set maxListeners + if (this.options.maxListeners) { + this.setMaxListeners(this.options.maxListeners); + Gaze.super_.prototype.setMaxListeners(this.options.maxListeners); + delete this.options.maxListeners; + } + + // Initialize the watch on files + if (patterns) { + this.add(patterns, done); + } + + return this; +} +util.inherits(Gaze, EE); + +// Main entry point. Start watching and call done when setup +module.exports = function gaze(patterns, opts, done) { + return new Gaze(patterns, opts, done); +}; +module.exports.Gaze = Gaze; + +// Node v0.6 compat +fs.existsSync = fs.existsSync || path.existsSync; +path.sep = path.sep || path.normalize('/'); + +/** + * Lo-Dash 1.0.1 + * 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 unique() { var array = Array.prototype.concat.apply(Array.prototype, arguments); var result = []; for (var i = 0; i < array.length; i++) { if (result.indexOf(array[i]) === -1) { result.push(array[i]); } } return result; } + +/** + * Copyright (c) 2010 Caolan McMahon + * Available under MIT license + */ +function forEachSeries(arr, iterator, callback) { + 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(); +} + +// other helpers + +// Returns boolean whether filepath is dir terminated +function _isDir(dir) { + if (typeof dir !== 'string') { return false; } + return (dir.slice(-(path.sep.length)) === path.sep); +} + +// Create a `key:[]` if doesnt exist on `obj` then push or concat the `val` +function _objectPush(obj, key, val) { + if (obj[key] == null) { obj[key] = []; } + if (Array.isArray(val)) { obj[key] = obj[key].concat(val); } + else if (val) { obj[key].push(val); } + return obj[key] = unique(obj[key]); +} + +// Ensures the dir is marked with path.sep +function _markDir(dir) { + if (typeof dir === 'string' && + dir.slice(-(path.sep.length)) !== path.sep && + dir !== '.') { + dir += path.sep; + } + return dir; +} + +// Changes path.sep to unix ones for testing +function _unixifyPathSep(filepath) { + return (process.platform === 'win32') ? String(filepath).replace(/\\/g, '/') : filepath; +} + +// Override the emit function to emit `all` events +// and debounce on duplicate events per file +Gaze.prototype.emit = function() { + var _this = this; + var args = arguments; + + var e = args[0]; + var filepath = args[1]; + var timeoutId; + + // If not added/deleted/changed/renamed then just emit the event + if (e.slice(-2) !== 'ed') { + Gaze.super_.prototype.emit.apply(_this, args); + return this; + } + + // Detect rename event, if added and previous deleted is in the cache + if (e === 'added') { + Object.keys(this._cached).forEach(function(oldFile) { + if (_this._cached[oldFile].indexOf('deleted') !== -1) { + args[0] = e = 'renamed'; + [].push.call(args, oldFile); + delete _this._cached[oldFile]; + return false; + } + }); + } + + // If cached doesnt exist, create a delay before running the next + // then emit the event + var cache = this._cached[filepath] || []; + if (cache.indexOf(e) === -1) { + _objectPush(_this._cached, filepath, e); + clearTimeout(timeoutId); + timeoutId = setTimeout(function() { + delete _this._cached[filepath]; + }, this.options.debounceDelay); + // Emit the event and `all` event + Gaze.super_.prototype.emit.apply(_this, args); + Gaze.super_.prototype.emit.apply(_this, ['all', e].concat([].slice.call(args, 1))); + } + + return this; +}; + +// Close watchers +Gaze.prototype.close = function(_reset) { + var _this = this; + _reset = _reset === false ? false : true; + Object.keys(_this._watchers).forEach(function(file) { + _this._watchers[file].close(); + }); + _this._watchers = Object.create(null); + Object.keys(this._watched).forEach(function(dir) { + fs.unwatchFile(dir); + _this._watched[dir].forEach(function(uFile) { + fs.unwatchFile(uFile); + }); + }); + if (_reset) { + _this._watched = Object.create(null); + setTimeout(function() { + _this.emit('end'); + _this.removeAllListeners(); + }, delay + 100); + } + return _this; +}; + +// Add file patterns to be watched +Gaze.prototype.add = function(files, done) { + var _this = this; + if (typeof files === 'string') { + files = [files]; + } + this._patterns = unique.apply(null, [this._patterns, files]); + + var include = [], exclude = []; + this._patterns.forEach(function(p) { + if (p.slice(0, 1) === '!') { + exclude.push(p.slice(1)); + } else { + include.push(p); + } + }); + + fileset(include, exclude, _this.options, function(err, files) { + if (err) { + _this.emit('error', err); + return done(err); + } + _this._addToWatched(files); + _this.close(false); + _this._initWatched(done); + }); +}; + +// Remove file/dir from `watched` +Gaze.prototype.remove = function(file) { + var _this = this; + if (this._watched[file]) { + // is dir, remove all files + fs.unwatchFile(file); + this._watched[file].forEach(fs.unwatchFile); + delete this._watched[file]; + } else { + // is a file, find and remove + Object.keys(this._watched).forEach(function(dir) { + var index = _this._watched[dir].indexOf(file); + if (index !== -1) { + fs.unwatchFile(file); + _this._watched[dir].splice(index, 1); + return false; + } + }); + } + if (this._watchers[file]) { + this._watchers[file].close(); + } + return this; +}; + +// Return watched files +Gaze.prototype.watched = function() { + return this._watched; +}; + +// Returns `watched` files with relative paths to process.cwd() +Gaze.prototype.relative = function(dir, unixify) { + var _this = this; + var relative = Object.create(null); + var relDir, relFile, unixRelDir; + var cwd = this.options.cwd || process.cwd(); + if (dir === '') { dir = '.'; } + dir = _markDir(dir); + unixify = unixify || false; + Object.keys(this._watched).forEach(function(dir) { + relDir = path.relative(cwd, dir) + path.sep; + if (relDir === path.sep) { relDir = '.'; } + unixRelDir = unixify ? _unixifyPathSep(relDir) : relDir; + relative[unixRelDir] = _this._watched[dir].map(function(file) { + relFile = path.relative(path.join(cwd, relDir), file); + if (_isDir(file)) { + relFile = _markDir(relFile); + } + if (unixify) { + relFile = _unixifyPathSep(relFile); + } + return relFile; + }); + }); + if (dir && unixify) { + dir = _unixifyPathSep(dir); + } + return dir ? relative[dir] || [] : relative; +}; + +// Adds files and dirs to watched +Gaze.prototype._addToWatched = function(files) { + var _this = this; + files.forEach(function(file) { + var filepath = path.resolve(_this.options.cwd, file); + if (file.slice(-1) === '/') { filepath += path.sep; } + _objectPush(_this._watched, path.dirname(filepath) + path.sep, filepath); + }); + return this; +}; + +// Returns true if the file matches this._patterns +Gaze.prototype._isMatch = function(file) { + var include = [], exclude = []; + this._patterns.forEach(function(p) { + if (p.slice(0, 1) === '!') { + exclude.push(p.slice(1)); + } else { + include.push(p); + } + }); + var matched = false, i = 0; + for (i = 0; i < include.length; i++) { + if (minimatch(file, include[i])) { + matched = true; + break; + } + } + for (i = 0; i < exclude.length; i++) { + if (minimatch(file, exclude[i])) { + matched = false; + break; + } + } + return matched; +}; + +Gaze.prototype._watchDir = function(dir, done) { + var _this = this; + try { + _this._watchers[dir] = fs.watch(dir, function(event) { + // race condition. Let's give the fs a little time to settle down. so we + // don't fire events on non existent files. + setTimeout(function() { + if (fs.existsSync(dir)) { + done(null, dir); + } + }, delay + 100); + }); + } catch (err) { + return this._handleError(err); + } + return this; +}; + +Gaze.prototype._pollFile = function(file, done) { + var _this = this; + var opts = { persistent: true, interval: _this.options.interval }; + try { + fs.watchFile(file, opts, function(curr, prev) { + done(null, file); + }); + } catch (err) { + return this._handleError(err); + } + return this; +}; + +// Initialize the actual watch on `watched` files +Gaze.prototype._initWatched = function(done) { + var _this = this; + var cwd = this.options.cwd || process.cwd(); + var curWatched = Object.keys(_this._watched); + forEachSeries(curWatched, function(dir, next) { + var files = _this._watched[dir]; + // Triggered when a watched dir has an event + _this._watchDir(dir, function(event, dirpath) { + var relDir = cwd === dir ? '.' : path.relative(cwd, dir); + + fs.readdir(dirpath, function(err, current) { + if (err) { return _this.emit('error', err); } + if (!current) { return; } + + try { + // append path.sep to directories so they match previous. + current = current.map(function(curPath) { + if (fs.existsSync(path.join(dir, curPath)) && fs.statSync(path.join(dir, curPath)).isDirectory()) { + return curPath + path.sep; + } else { + return curPath; + } + }); + } catch (err) { + // race condition-- sometimes the file no longer exists + } + + // Get watched files for this dir + var previous = _this.relative(relDir); + + // If file was deleted + previous.filter(function(file) { + return current.indexOf(file) < 0; + }).forEach(function(file) { + if (!_isDir(file)) { + var filepath = path.join(dir, file); + _this.remove(filepath); + _this.emit('deleted', filepath); + } + }); + + // If file was added + current.filter(function(file) { + return previous.indexOf(file) < 0; + }).forEach(function(file) { + // Is it a matching pattern? + var relFile = path.join(relDir, file); + // TODO: this can be optimized more + // we shouldnt need isMatch() and could just use add() + if (_this._isMatch(relFile)) { + // Add to watch then emit event + _this.add(relFile, function() { + _this.emit('added', path.join(dir, file)); + }); + } + }); + + }); + }); + + // Watch for change/rename events on files + files.forEach(function(file) { + if (_isDir(file)) { return; } + _this._pollFile(file, function(err, filepath) { + // Only emit changed if the file still exists + // Prevents changed/deleted duplicate events + // TODO: This ignores changed events on folders, maybe support this? + // When a file is added, a folder changed event emits first + if (fs.existsSync(filepath)) { + _this.emit('changed', filepath); + } + }); + }); + + next(); + }, function() { + + // Return this instance of Gaze + // delay before ready solves a lot of issues + setTimeout(function() { + _this.emit('ready', _this); + done.call(_this, null, _this); + }, delay + 100); + + }); +}; + +// If an error, handle it here +Gaze.prototype._handleError = function(err) { + if (err.code === 'EMFILE') { + return this.emit('error', new Error('EMFILE: Too many opened files.')); + } + return this.emit('error', err); +}; diff --git a/node_modules/gaze/package.json b/node_modules/gaze/package.json new file mode 100644 index 0000000..2da53e0 --- /dev/null +++ b/node_modules/gaze/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + "gaze@~0.3.2", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-node" + ] + ], + "_from": "gaze@>=0.3.2 <0.4.0", + "_id": "gaze@0.3.4", + "_inCache": true, + "_installable": true, + "_location": "/gaze", + "_npmUser": { + "email": "kyle@dontkry.com", + "name": "shama" + }, + "_npmVersion": "1.2.18", + "_phantomChildren": {}, + "_requested": { + "name": "gaze", + "raw": "gaze@~0.3.2", + "rawSpec": "~0.3.2", + "scope": null, + "spec": ">=0.3.2 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine-node" + ], + "_resolved": "https://registry.npmjs.org/gaze/-/gaze-0.3.4.tgz", + "_shasum": "5f94bdda0afe53bc710969bcd6f282548d60c279", + "_shrinkwrap": null, + "_spec": "gaze@~0.3.2", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-node", + "author": { + "email": "kyle@dontkry.com", + "name": "Kyle Robinson Young" + }, + "bugs": { + "url": "https://github.com/shama/gaze/issues" + }, + "contributors": [ + { + "name": "Kyle Robinson Young", + "url": "http://dontkry.com" + }, + { + "name": "Sam Day", + "url": "http://sam.is-super-awesome.com" + }, + { + "name": "Roarke Gaskill", + "url": "http://starkinvestments.com" + }, + { + "name": "Lance Pollard", + "url": "http://lancepollard.com/" + }, + { + "name": "Daniel Fagnan", + "url": "http://hydrocodedesign.com/" + } + ], + "dependencies": { + "fileset": "~0.1.5", + "minimatch": "~0.2.9" + }, + "description": "A globbing fs.watch wrapper built from the best parts of other fine watch libs.", + "devDependencies": { + "grunt": "~0.4.0rc7", + "grunt-benchmark": "~0.1.1", + "grunt-contrib-jshint": "~0.1.1rc6", + "grunt-contrib-nodeunit": "~0.1.2rc6" + }, + "directories": {}, + "dist": { + "shasum": "5f94bdda0afe53bc710969bcd6f282548d60c279", + "tarball": "https://registry.npmjs.org/gaze/-/gaze-0.3.4.tgz" + }, + "engines": { + "node": ">= 0.6.0" + }, + "homepage": "https://github.com/shama/gaze", + "keywords": [ + "glob", + "watch" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/shama/gaze/blob/master/LICENSE-MIT" + } + ], + "main": "lib/gaze", + "maintainers": [ + { + "name": "shama", + "email": "kyle@dontkry.com" + } + ], + "name": "gaze", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/shama/gaze.git" + }, + "scripts": { + "test": "grunt nodeunit -v" + }, + "version": "0.3.4" +} diff --git a/node_modules/gaze/test/add_test.js b/node_modules/gaze/test/add_test.js new file mode 100644 index 0000000..6949ac9 --- /dev/null +++ b/node_modules/gaze/test/add_test.js @@ -0,0 +1,50 @@ +'use strict'; + +var Gaze = require('../lib/gaze.js').Gaze; +var path = require('path'); +var fs = require('fs'); + +exports.add = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + done(); + }, + addToWatched: function(test) { + test.expect(1); + var files = [ + 'Project (LO)/', + 'Project (LO)/one.js', + 'nested/', + 'nested/one.js', + 'nested/three.js', + 'nested/sub/', + 'nested/sub/two.js', + 'one.js' + ]; + var expected = { + 'Project (LO)/': ['one.js'], + '.': ['Project (LO)/', 'nested/', 'one.js'], + 'nested/': ['one.js', 'three.js', 'sub/'], + 'nested/sub/': ['two.js'] + }; + var gaze = new Gaze('addnothingtowatch'); + gaze._addToWatched(files); + test.deepEqual(gaze.relative(null, true), expected); + test.done(); + }, + addLater: function(test) { + test.expect(3); + new Gaze('sub/one.js', function(err, watcher) { + test.deepEqual(watcher.relative('sub'), ['one.js']); + watcher.add('sub/*.js', function() { + test.deepEqual(watcher.relative('sub'), ['one.js', 'two.js']); + watcher.on('changed', function(filepath) { + test.equal('two.js', path.basename(filepath)); + watcher.close(); + test.done(); + }); + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'two.js'), 'var two = true;'); + }); + }); + } +}; diff --git a/node_modules/gaze/test/api_test.js b/node_modules/gaze/test/api_test.js new file mode 100644 index 0000000..42d258e --- /dev/null +++ b/node_modules/gaze/test/api_test.js @@ -0,0 +1,38 @@ +'use strict'; + +var gaze = require('../lib/gaze.js'); +var path = require('path'); + +exports.api = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + done(); + }, + newGaze: function(test) { + test.expect(2); + new gaze.Gaze('**/*', {}, function() { + var result = this.relative(null, true); + test.deepEqual(result['.'], ['Project (LO)/', 'nested/', 'one.js', 'sub/']); + test.deepEqual(result['sub/'], ['one.js', 'two.js']); + this.close(); + test.done(); + }); + }, + func: function(test) { + test.expect(1); + var g = gaze('**/*', function(err, watcher) { + test.deepEqual(watcher.relative('sub', true), ['one.js', 'two.js']); + g.close(); + test.done(); + }); + }, + ready: function(test) { + test.expect(1); + var g = new gaze.Gaze('**/*'); + g.on('ready', function(watcher) { + test.deepEqual(watcher.relative('sub', true), ['one.js', 'two.js']); + this.close(); + test.done(); + }); + } +}; diff --git a/node_modules/gaze/test/fixtures/Project (LO)/one.js b/node_modules/gaze/test/fixtures/Project (LO)/one.js new file mode 100644 index 0000000..fefeeea --- /dev/null +++ b/node_modules/gaze/test/fixtures/Project (LO)/one.js @@ -0,0 +1 @@ +var one = true; \ No newline at end of file diff --git a/node_modules/gaze/test/fixtures/nested/one.js b/node_modules/gaze/test/fixtures/nested/one.js new file mode 100644 index 0000000..fefeeea --- /dev/null +++ b/node_modules/gaze/test/fixtures/nested/one.js @@ -0,0 +1 @@ +var one = true; \ No newline at end of file diff --git a/node_modules/gaze/test/fixtures/nested/sub/two.js b/node_modules/gaze/test/fixtures/nested/sub/two.js new file mode 100644 index 0000000..24ad8a3 --- /dev/null +++ b/node_modules/gaze/test/fixtures/nested/sub/two.js @@ -0,0 +1 @@ +var two = true; \ No newline at end of file diff --git a/node_modules/gaze/test/fixtures/nested/sub2/two.js b/node_modules/gaze/test/fixtures/nested/sub2/two.js new file mode 100644 index 0000000..24ad8a3 --- /dev/null +++ b/node_modules/gaze/test/fixtures/nested/sub2/two.js @@ -0,0 +1 @@ +var two = true; \ No newline at end of file diff --git a/node_modules/gaze/test/fixtures/nested/three.js b/node_modules/gaze/test/fixtures/nested/three.js new file mode 100644 index 0000000..3392956 --- /dev/null +++ b/node_modules/gaze/test/fixtures/nested/three.js @@ -0,0 +1 @@ +var three = true; \ No newline at end of file diff --git a/node_modules/gaze/test/fixtures/one.js b/node_modules/gaze/test/fixtures/one.js new file mode 100644 index 0000000..517f09f --- /dev/null +++ b/node_modules/gaze/test/fixtures/one.js @@ -0,0 +1 @@ +var test = true; \ No newline at end of file diff --git a/node_modules/gaze/test/fixtures/sub/one.js b/node_modules/gaze/test/fixtures/sub/one.js new file mode 100644 index 0000000..fefeeea --- /dev/null +++ b/node_modules/gaze/test/fixtures/sub/one.js @@ -0,0 +1 @@ +var one = true; \ No newline at end of file diff --git a/node_modules/gaze/test/fixtures/sub/two.js b/node_modules/gaze/test/fixtures/sub/two.js new file mode 100644 index 0000000..24ad8a3 --- /dev/null +++ b/node_modules/gaze/test/fixtures/sub/two.js @@ -0,0 +1 @@ +var two = true; \ No newline at end of file diff --git a/node_modules/gaze/test/matching_test.js b/node_modules/gaze/test/matching_test.js new file mode 100644 index 0000000..9e01cd2 --- /dev/null +++ b/node_modules/gaze/test/matching_test.js @@ -0,0 +1,57 @@ +'use strict'; + +var gaze = require('../lib/gaze.js'); +var path = require('path'); + +exports.matching = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + done(); + }, + globAll: function(test) { + test.expect(2); + gaze('**/*', function() { + var result = this.relative(null, true); + test.deepEqual(result['.'], ['Project (LO)/', 'nested/', 'one.js', 'sub/']); + test.deepEqual(result['sub/'], ['one.js', 'two.js']); + this.close(); + test.done(); + }); + }, + relativeDir: function(test) { + test.expect(1); + gaze('**/*', function() { + test.deepEqual(this.relative('sub', true), ['one.js', 'two.js']); + this.close(); + test.done(); + }); + }, + globArray: function(test) { + test.expect(2); + gaze(['*.js', 'sub/*.js'], function() { + var result = this.relative(null, true); + test.deepEqual(result['.'], ['one.js']); + test.deepEqual(result['sub/'], ['one.js', 'two.js']); + this.close(); + test.done(); + }); + }, + globArrayDot: function(test) { + test.expect(1); + gaze(['./sub/*.js'], function() { + var result = this.relative(null, true); + test.deepEqual(result['sub/'], ['one.js', 'two.js']); + this.close(); + test.done(); + }); + }, + oddName: function(test) { + test.expect(1); + gaze(['Project (LO)/*.js'], function() { + var result = this.relative(null, true); + test.deepEqual(result['Project (LO)/'], ['one.js']); + this.close(); + test.done(); + }); + } +}; diff --git a/node_modules/gaze/test/patterns_test.js b/node_modules/gaze/test/patterns_test.js new file mode 100644 index 0000000..46b94e4 --- /dev/null +++ b/node_modules/gaze/test/patterns_test.js @@ -0,0 +1,42 @@ +'use strict'; + +var gaze = require('../lib/gaze.js'); +var path = require('path'); +var fs = require('fs'); + +// Clean up helper to call in setUp and tearDown +function cleanUp(done) { + [ + 'added.js', + 'nested/added.js', + ].forEach(function(d) { + var p = path.resolve(__dirname, 'fixtures', d); + if (fs.existsSync(p)) { fs.unlinkSync(p); } + }); + done(); +} + +exports.patterns = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + cleanUp(done); + }, + tearDown: cleanUp, + negate: function(test) { + test.expect(1); + gaze(['**/*.js', '!nested/**/*.js'], function(err, watcher) { + watcher.on('added', function(filepath) { + var expected = path.relative(process.cwd(), filepath); + test.equal(path.join('added.js'), expected); + watcher.close(); + }); + // dont add + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'nested', 'added.js'), 'var added = true;'); + setTimeout(function() { + // should add + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'added.js'), 'var added = true;'); + }, 1000); + watcher.on('end', test.done); + }); + } +}; diff --git a/node_modules/gaze/test/relative_test.js b/node_modules/gaze/test/relative_test.js new file mode 100644 index 0000000..52e5a57 --- /dev/null +++ b/node_modules/gaze/test/relative_test.js @@ -0,0 +1,28 @@ +'use strict'; + +var Gaze = require('../lib/gaze.js').Gaze; +var path = require('path'); + +exports.relative = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + done(); + }, + relative: function(test) { + test.expect(1); + var files = [ + 'Project (LO)/', + 'Project (LO)/one.js', + 'nested/', + 'nested/one.js', + 'nested/three.js', + 'nested/sub/', + 'nested/sub/two.js', + 'one.js' + ]; + var gaze = new Gaze('addnothingtowatch'); + gaze._addToWatched(files); + test.deepEqual(gaze.relative('.', true), ['Project (LO)/', 'nested/', 'one.js']); + test.done(); + } +}; diff --git a/node_modules/gaze/test/rename_test.js b/node_modules/gaze/test/rename_test.js new file mode 100644 index 0000000..028b344 --- /dev/null +++ b/node_modules/gaze/test/rename_test.js @@ -0,0 +1,43 @@ +'use strict'; + +var gaze = require('../lib/gaze.js'); +var path = require('path'); +var fs = require('fs'); + +// Node v0.6 compat +fs.existsSync = fs.existsSync || path.existsSync; + +// Clean up helper to call in setUp and tearDown +function cleanUp(done) { + [ + 'sub/rename.js', + 'sub/renamed.js' + ].forEach(function(d) { + var p = path.resolve(__dirname, 'fixtures', d); + if (fs.existsSync(p)) { fs.unlinkSync(p); } + }); + done(); +} + +exports.watch = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + cleanUp(done); + }, + tearDown: cleanUp, + rename: function(test) { + test.expect(2); + var oldPath = path.join(__dirname, 'fixtures', 'sub', 'rename.js'); + var newPath = path.join(__dirname, 'fixtures', 'sub', 'renamed.js'); + fs.writeFileSync(oldPath, 'var rename = true;'); + gaze('**/*', function(err, watcher) { + watcher.on('renamed', function(newFile, oldFile) { + test.equal(newFile, newPath); + test.equal(oldFile, oldPath); + watcher.close(); + test.done(); + }); + fs.renameSync(oldPath, newPath); + }); + } +}; diff --git a/node_modules/gaze/test/safewrite_test.js b/node_modules/gaze/test/safewrite_test.js new file mode 100644 index 0000000..9200f11 --- /dev/null +++ b/node_modules/gaze/test/safewrite_test.js @@ -0,0 +1,61 @@ +'use strict'; + +var gaze = require('../lib/gaze.js'); +var path = require('path'); +var fs = require('fs'); + +// Node v0.6 compat +fs.existsSync = fs.existsSync || path.existsSync; + +// Clean up helper to call in setUp and tearDown +function cleanUp(done) { + [ + 'safewrite.js' + ].forEach(function(d) { + var p = path.resolve(__dirname, 'fixtures', d); + if (fs.existsSync(p)) { fs.unlinkSync(p); } + }); + done(); +} + +exports.safewrite = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + cleanUp(done); + }, + tearDown: cleanUp, + safewrite: function(test) { + test.expect(4); + + var times = 0; + var file = path.resolve(__dirname, 'fixtures', 'safewrite.js'); + var backup = path.resolve(__dirname, 'fixtures', 'safewrite.ext~'); + fs.writeFileSync(file, 'var safe = true;'); + + function simSafewrite() { + fs.writeFileSync(backup, fs.readFileSync(file)); + fs.unlinkSync(file); + fs.renameSync(backup, file); + times++; + } + + gaze('**/*', function() { + this.on('all', function(action, filepath) { + test.equal(action, 'changed'); + test.equal(path.basename(filepath), 'safewrite.js'); + + if (times < 2) { + setTimeout(simSafewrite, 1000); + } else { + this.close(); + test.done(); + } + }); + + setTimeout(function() { + simSafewrite(); + }, 1000); + + }); + } +}; diff --git a/node_modules/gaze/test/watch_test.js b/node_modules/gaze/test/watch_test.js new file mode 100644 index 0000000..9d58521 --- /dev/null +++ b/node_modules/gaze/test/watch_test.js @@ -0,0 +1,207 @@ +'use strict'; + +var gaze = require('../lib/gaze.js'); +var grunt = require('grunt'); +var path = require('path'); +var fs = require('fs'); + +// Node v0.6 compat +fs.existsSync = fs.existsSync || path.existsSync; + +// Clean up helper to call in setUp and tearDown +function cleanUp(done) { + [ + 'sub/tmp.js', + 'sub/tmp', + 'sub/renamed.js', + 'added.js', + 'nested/added.js', + 'nested/.tmp', + 'nested/sub/added.js' + ].forEach(function(d) { + var p = path.resolve(__dirname, 'fixtures', d); + if (fs.existsSync(p)) { fs.unlinkSync(p); } + }); + done(); +} + +exports.watch = { + setUp: function(done) { + process.chdir(path.resolve(__dirname, 'fixtures')); + cleanUp(done); + }, + tearDown: cleanUp, + remove: function(test) { + test.expect(2); + gaze('**/*', function() { + this.remove(path.resolve(__dirname, 'fixtures', 'sub', 'two.js')); + this.remove(path.resolve(__dirname, 'fixtures')); + var result = this.relative(null, true); + test.deepEqual(result['sub/'], ['one.js']); + test.notDeepEqual(result['.'], ['one.js']); + this.close(); + test.done(); + }); + }, + changed: function(test) { + test.expect(1); + gaze('**/*', function(err, watcher) { + watcher.on('changed', function(filepath) { + var expected = path.relative(process.cwd(), filepath); + test.equal(path.join('sub', 'one.js'), expected); + watcher.close(); + }); + this.on('added', function() { test.ok(false, 'added event should not have emitted.'); }); + this.on('deleted', function() { test.ok(false, 'deleted event should not have emitted.'); }); + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js'), 'var one = true;'); + watcher.on('end', test.done); + }); + }, + added: function(test) { + test.expect(1); + gaze('**/*', function(err, watcher) { + watcher.on('added', function(filepath) { + var expected = path.relative(process.cwd(), filepath); + test.equal(path.join('sub', 'tmp.js'), expected); + watcher.close(); + }); + this.on('changed', function() { test.ok(false, 'changed event should not have emitted.'); }); + this.on('deleted', function() { test.ok(false, 'deleted event should not have emitted.'); }); + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'tmp.js'), 'var tmp = true;'); + watcher.on('end', test.done); + }); + }, + dontAddUnmatchedFiles: function(test) { + test.expect(2); + gaze('**/*.js', function(err, watcher) { + setTimeout(function() { + test.ok(true, 'Ended without adding a file.'); + watcher.close(); + }, 1000); + this.on('added', function(filepath) { + test.equal(path.relative(process.cwd(), filepath), path.join('sub', 'tmp.js')); + }); + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'tmp'), 'Dont add me!'); + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'tmp.js'), 'add me!'); + watcher.on('end', test.done); + }); + }, + dontAddMatchedDirectoriesThatArentReallyAdded: function(test) { + // This is a regression test for a bug I ran into where a matching directory would be reported + // added when a non-matching file was created along side it. This only happens if the + // directory name doesn't occur in $PWD. + test.expect(1); + gaze('**/*', function(err, watcher) { + setTimeout(function() { + test.ok(true, 'Ended without adding a file.'); + watcher.close(); + }, 1000); + this.on('added', function(filepath) { + test.notEqual(path.relative(process.cwd(), filepath), path.join('nested', 'sub2')); + }); + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'nested', '.tmp'), 'Wake up!'); + watcher.on('end', test.done); + }); + }, + deleted: function(test) { + test.expect(1); + var tmpfile = path.resolve(__dirname, 'fixtures', 'sub', 'deleted.js'); + fs.writeFileSync(tmpfile, 'var tmp = true;'); + gaze('**/*', function(err, watcher) { + watcher.on('deleted', function(filepath) { + test.equal(path.join('sub', 'deleted.js'), path.relative(process.cwd(), filepath)); + watcher.close(); + }); + this.on('changed', function() { test.ok(false, 'changed event should not have emitted.'); }); + this.on('added', function() { test.ok(false, 'added event should not have emitted.'); }); + fs.unlinkSync(tmpfile); + watcher.on('end', test.done); + }); + }, + dontEmitTwice: function(test) { + test.expect(2); + gaze('**/*', function(err, watcher) { + watcher.on('all', function(status, filepath) { + var expected = path.relative(process.cwd(), filepath); + test.equal(path.join('sub', 'one.js'), expected); + test.equal(status, 'changed'); + fs.readFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js')); + setTimeout(function() { + fs.readFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js')); + }, 1000); + // Give some time to accidentally emit before we close + setTimeout(function() { watcher.close(); }, 5000); + }); + setTimeout(function() { + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js'), 'var one = true;'); + }, 1000); + watcher.on('end', test.done); + }); + }, + emitTwice: function(test) { + test.expect(2); + var times = 0; + gaze('**/*', function(err, watcher) { + watcher.on('all', function(status, filepath) { + test.equal(status, 'changed'); + times++; + setTimeout(function() { + if (times < 2) { + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js'), 'var one = true;'); + } else { + watcher.close(); + } + }, 1000); + }); + setTimeout(function() { + fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js'), 'var one = true;'); + }, 1000); + watcher.on('end', test.done); + }); + }, + nonExistent: function(test) { + test.expect(1); + gaze('non/existent/**/*', function(err, watcher) { + test.ok(true); + test.done(); + }); + }, + differentCWD: function(test) { + test.expect(1); + var cwd = path.resolve(__dirname, 'fixtures', 'sub'); + gaze('two.js', { + cwd: cwd + }, function(err, watcher) { + watcher.on('changed', function(filepath) { + test.deepEqual(this.relative(), {'.':['two.js']}); + watcher.close(); + }); + fs.writeFileSync(path.resolve(cwd, 'two.js'), 'var two = true;'); + watcher.on('end', test.done); + }); + }, + addedEmitInSubFolders: function(test) { + test.expect(4); + var adds = [ + { pattern: '**/*', file: path.resolve(__dirname, 'fixtures', 'nested', 'sub', 'added.js') }, + { pattern: '**/*', file: path.resolve(__dirname, 'fixtures', 'added.js') }, + { pattern: 'nested/**/*', file: path.resolve(__dirname, 'fixtures', 'nested', 'added.js') }, + { pattern: 'nested/sub/*.js', file: path.resolve(__dirname, 'fixtures', 'nested', 'sub', 'added.js') }, + ]; + grunt.util.async.forEachSeries(adds, function(add, next) { + new gaze.Gaze(add.pattern, function(err, watcher) { + watcher.on('added', function(filepath) { + test.equal('added.js', path.basename(filepath)); + fs.unlinkSync(filepath); + watcher.close(); + next(); + }); + watcher.on('changed', function() { test.ok(false, 'changed event should not have emitted.'); }); + watcher.on('deleted', function() { test.ok(false, 'deleted event should not have emitted.'); }); + fs.writeFileSync(add.file, 'var added = true;'); + }); + }, function() { + test.done(); + }); + }, +}; diff --git a/node_modules/glob/.npmignore b/node_modules/glob/.npmignore new file mode 100644 index 0000000..2af4b71 --- /dev/null +++ b/node_modules/glob/.npmignore @@ -0,0 +1,2 @@ +.*.swp +test/a/ diff --git a/node_modules/glob/.travis.yml b/node_modules/glob/.travis.yml new file mode 100644 index 0000000..baa0031 --- /dev/null +++ b/node_modules/glob/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.8 diff --git a/node_modules/glob/LICENSE b/node_modules/glob/LICENSE new file mode 100644 index 0000000..0c44ae7 --- /dev/null +++ b/node_modules/glob/LICENSE @@ -0,0 +1,27 @@ +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/node_modules/glob/README.md b/node_modules/glob/README.md new file mode 100644 index 0000000..cc69164 --- /dev/null +++ b/node_modules/glob/README.md @@ -0,0 +1,250 @@ +# 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/node_modules/glob/examples/g.js b/node_modules/glob/examples/g.js new file mode 100644 index 0000000..be122df --- /dev/null +++ b/node_modules/glob/examples/g.js @@ -0,0 +1,9 @@ +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/node_modules/glob/examples/usr-local.js b/node_modules/glob/examples/usr-local.js new file mode 100644 index 0000000..327a425 --- /dev/null +++ b/node_modules/glob/examples/usr-local.js @@ -0,0 +1,9 @@ +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/node_modules/glob/glob.js b/node_modules/glob/glob.js new file mode 100644 index 0000000..f646c44 --- /dev/null +++ b/node_modules/glob/glob.js @@ -0,0 +1,728 @@ +// 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/node_modules/glob/node_modules/minimatch/.npmignore b/node_modules/glob/node_modules/minimatch/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/glob/node_modules/minimatch/LICENSE b/node_modules/glob/node_modules/minimatch/LICENSE new file mode 100644 index 0000000..05a4010 --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/LICENSE @@ -0,0 +1,23 @@ +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/node_modules/glob/node_modules/minimatch/README.md b/node_modules/glob/node_modules/minimatch/README.md new file mode 100644 index 0000000..5b3967e --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/README.md @@ -0,0 +1,218 @@ +# 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/node_modules/glob/node_modules/minimatch/minimatch.js b/node_modules/glob/node_modules/minimatch/minimatch.js new file mode 100644 index 0000000..4539678 --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/minimatch.js @@ -0,0 +1,1061 @@ +;(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/node_modules/glob/node_modules/minimatch/package.json b/node_modules/glob/node_modules/minimatch/package.json new file mode 100644 index 0000000..6c1f56f --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/package.json @@ -0,0 +1,82 @@ +{ + "_args": [ + [ + "minimatch@0.3", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/glob" + ] + ], + "_from": "minimatch@>=0.3.0 <0.4.0", + "_id": "minimatch@0.3.0", + "_inCache": true, + "_installable": true, + "_location": "/glob/minimatch", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.4.10", + "_phantomChildren": {}, + "_requested": { + "name": "minimatch", + "raw": "minimatch@0.3", + "rawSpec": "0.3", + "scope": null, + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", + "_shrinkwrap": null, + "_spec": "minimatch@0.3", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/glob", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me" + }, + "bugs": { + "url": "https://github.com/isaacs/minimatch/issues" + }, + "dependencies": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "description": "a glob matcher in javascript", + "devDependencies": { + "tap": "" + }, + "directories": {}, + "dist": { + "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", + "tarball": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/isaacs/minimatch", + "license": { + "type": "MIT", + "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE" + }, + "main": "minimatch.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "minimatch", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/minimatch.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "0.3.0" +} diff --git a/node_modules/glob/node_modules/minimatch/test/basic.js b/node_modules/glob/node_modules/minimatch/test/basic.js new file mode 100644 index 0000000..ae7ac73 --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/test/basic.js @@ -0,0 +1,399 @@ +// 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/node_modules/glob/node_modules/minimatch/test/brace-expand.js b/node_modules/glob/node_modules/minimatch/test/brace-expand.js new file mode 100644 index 0000000..7ee278a --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/test/brace-expand.js @@ -0,0 +1,33 @@ +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/node_modules/glob/node_modules/minimatch/test/caching.js b/node_modules/glob/node_modules/minimatch/test/caching.js new file mode 100644 index 0000000..0fec4b0 --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/test/caching.js @@ -0,0 +1,14 @@ +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/node_modules/glob/node_modules/minimatch/test/defaults.js b/node_modules/glob/node_modules/minimatch/test/defaults.js new file mode 100644 index 0000000..75e0571 --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/test/defaults.js @@ -0,0 +1,274 @@ +// 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/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js b/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js new file mode 100644 index 0000000..6676e26 --- /dev/null +++ b/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js @@ -0,0 +1,8 @@ +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/node_modules/glob/package.json b/node_modules/glob/package.json new file mode 100644 index 0000000..32237cf --- /dev/null +++ b/node_modules/glob/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + "glob@3.x", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/fileset" + ] + ], + "_from": "glob@>=3.0.0 <4.0.0", + "_id": "glob@3.2.11", + "_inCache": true, + "_installable": true, + "_location": "/glob", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.4.10", + "_phantomChildren": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + }, + "_requested": { + "name": "glob", + "raw": "glob@3.x", + "rawSpec": "3.x", + "scope": null, + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fileset" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "_shrinkwrap": null, + "_spec": "glob@3.x", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/fileset", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inherits": "2", + "minimatch": "0.3" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "1", + "tap": "~0.4.0" + }, + "directories": {}, + "dist": { + "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "tarball": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2", + "homepage": "https://github.com/isaacs/node-glob", + "license": "BSD", + "main": "glob.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "test": "tap test/*.js", + "test-regen": "TEST_REGEN=1 node test/00-setup.js" + }, + "version": "3.2.11" +} diff --git a/node_modules/glob/test/00-setup.js b/node_modules/glob/test/00-setup.js new file mode 100644 index 0000000..245afaf --- /dev/null +++ b/node_modules/glob/test/00-setup.js @@ -0,0 +1,176 @@ +// 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/node_modules/glob/test/bash-comparison.js b/node_modules/glob/test/bash-comparison.js new file mode 100644 index 0000000..239ed1a --- /dev/null +++ b/node_modules/glob/test/bash-comparison.js @@ -0,0 +1,63 @@ +// 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/node_modules/glob/test/bash-results.json b/node_modules/glob/test/bash-results.json new file mode 100644 index 0000000..8051c72 --- /dev/null +++ b/node_modules/glob/test/bash-results.json @@ -0,0 +1,351 @@ +{ + "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/node_modules/glob/test/cwd-test.js b/node_modules/glob/test/cwd-test.js new file mode 100644 index 0000000..352c27e --- /dev/null +++ b/node_modules/glob/test/cwd-test.js @@ -0,0 +1,55 @@ +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/node_modules/glob/test/globstar-match.js b/node_modules/glob/test/globstar-match.js new file mode 100644 index 0000000..9b234fa --- /dev/null +++ b/node_modules/glob/test/globstar-match.js @@ -0,0 +1,19 @@ +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/node_modules/glob/test/mark.js b/node_modules/glob/test/mark.js new file mode 100644 index 0000000..bf411c0 --- /dev/null +++ b/node_modules/glob/test/mark.js @@ -0,0 +1,118 @@ +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/node_modules/glob/test/new-glob-optional-options.js b/node_modules/glob/test/new-glob-optional-options.js new file mode 100644 index 0000000..3e7dc5a --- /dev/null +++ b/node_modules/glob/test/new-glob-optional-options.js @@ -0,0 +1,10 @@ +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/node_modules/glob/test/nocase-nomagic.js b/node_modules/glob/test/nocase-nomagic.js new file mode 100644 index 0000000..2503f23 --- /dev/null +++ b/node_modules/glob/test/nocase-nomagic.js @@ -0,0 +1,113 @@ +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/node_modules/glob/test/pause-resume.js b/node_modules/glob/test/pause-resume.js new file mode 100644 index 0000000..e1ffbab --- /dev/null +++ b/node_modules/glob/test/pause-resume.js @@ -0,0 +1,73 @@ +// 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/node_modules/glob/test/readme-issue.js b/node_modules/glob/test/readme-issue.js new file mode 100644 index 0000000..0b4e0be --- /dev/null +++ b/node_modules/glob/test/readme-issue.js @@ -0,0 +1,36 @@ +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/node_modules/glob/test/root-nomount.js b/node_modules/glob/test/root-nomount.js new file mode 100644 index 0000000..3ac5979 --- /dev/null +++ b/node_modules/glob/test/root-nomount.js @@ -0,0 +1,39 @@ +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/node_modules/glob/test/root.js b/node_modules/glob/test/root.js new file mode 100644 index 0000000..95c23f9 --- /dev/null +++ b/node_modules/glob/test/root.js @@ -0,0 +1,46 @@ +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/node_modules/glob/test/stat.js b/node_modules/glob/test/stat.js new file mode 100644 index 0000000..6291711 --- /dev/null +++ b/node_modules/glob/test/stat.js @@ -0,0 +1,32 @@ +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/node_modules/glob/test/zz-cleanup.js b/node_modules/glob/test/zz-cleanup.js new file mode 100644 index 0000000..e085f0f --- /dev/null +++ b/node_modules/glob/test/zz-cleanup.js @@ -0,0 +1,11 @@ +// 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/node_modules/growl/History.md b/node_modules/growl/History.md new file mode 100644 index 0000000..a4b7b49 --- /dev/null +++ b/node_modules/growl/History.md @@ -0,0 +1,63 @@ + +1.7.0 / 2012-12-30 +================== + + * support transient notifications in Gnome + +1.6.1 / 2012-09-25 +================== + + * restore compatibility with node < 0.8 [fgnass] + +1.6.0 / 2012-09-06 +================== + + * add notification center support [drudge] + +1.5.1 / 2012-04-08 +================== + + * Merge pull request #16 from KyleAMathews/patch-1 + * Fixes #15 + +1.5.0 / 2012-02-08 +================== + + * Added windows support [perfusorius] + +1.4.1 / 2011-12-28 +================== + + * Fixed: dont exit(). Closes #9 + +1.4.0 / 2011-12-17 +================== + + * Changed API: `growl.notify()` -> `growl()` + +1.3.0 / 2011-12-17 +================== + + * Added support for Ubuntu/Debian/Linux users [niftylettuce] + * Fixed: send notifications even if title not specified [alessioalex] + +1.2.0 / 2011-10-06 +================== + + * Add support for priority. + +1.1.0 / 2011-03-15 +================== + + * Added optional callbacks + * Added parsing of version + +1.0.1 / 2010-03-26 +================== + + * Fixed; sys.exec -> child_process.exec to support latest node + +1.0.0 / 2010-03-19 +================== + + * Initial release diff --git a/node_modules/growl/Readme.md b/node_modules/growl/Readme.md new file mode 100644 index 0000000..48d717c --- /dev/null +++ b/node_modules/growl/Readme.md @@ -0,0 +1,99 @@ +# Growl for nodejs + +Growl support for Nodejs. This is essentially a port of my [Ruby Growl Library](http://github.com/visionmedia/growl). Ubuntu/Linux support added thanks to [@niftylettuce](http://github.com/niftylettuce). + +## Installation + +### Install + +### Mac OS X (Darwin): + + Install [growlnotify(1)](http://growl.info/extras.php#growlnotify). On OS X 10.8, Notification Center is supported using [terminal-notifier](https://github.com/alloy/terminal-notifier). To install: + + $ sudo gem install terminal-notifier + + Install [npm](http://npmjs.org/) and run: + + $ npm install growl + +### Ubuntu (Linux): + + Install `notify-send` through the [libnotify-bin](http://packages.ubuntu.com/libnotify-bin) package: + + $ sudo apt-get install libnotify-bin + + Install [npm](http://npmjs.org/) and run: + + $ npm install growl + +### Windows: + + Download and install [Growl for Windows](http://www.growlforwindows.com/gfw/default.aspx) + + Download [growlnotify](http://www.growlforwindows.com/gfw/help/growlnotify.aspx) - **IMPORTANT :** Unpack growlnotify to a folder that is present in your path! + + Install [npm](http://npmjs.org/) and run: + + $ npm install growl + +## Examples + +Callback functions are optional + + var growl = require('growl') + growl('You have mail!') + growl('5 new messages', { sticky: true }) + growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true }) + growl('Message with title', { title: 'Title'}) + growl('Set priority', { priority: 2 }) + growl('Show Safari icon', { image: 'Safari' }) + growl('Show icon', { image: 'path/to/icon.icns' }) + growl('Show image', { image: 'path/to/my.image.png' }) + growl('Show png filesystem icon', { image: 'png' }) + growl('Show pdf filesystem icon', { image: 'article.pdf' }) + growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(err){ + // ... notified + }) + +## Options + + - title + - notification title + - name + - application name + - priority + - priority for the notification (default is 0) + - sticky + - weither or not the notification should remainin until closed + - image + - Auto-detects the context: + - path to an icon sets --iconpath + - path to an image sets --image + - capitalized word sets --appIcon + - filename uses extname as --icon + - otherwise treated as --icon + +## License + +(The MIT License) + +Copyright (c) 2009 TJ Holowaychuk + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/growl/lib/growl.js b/node_modules/growl/lib/growl.js new file mode 100644 index 0000000..04f4f9b --- /dev/null +++ b/node_modules/growl/lib/growl.js @@ -0,0 +1,234 @@ +// Growl - Copyright TJ Holowaychuk (MIT Licensed) + +/** + * Module dependencies. + */ + +var exec = require('child_process').exec + , fs = require('fs') + , path = require('path') + , exists = fs.existsSync || path.existsSync + , os = require('os') + , quote = JSON.stringify + , cmd; + +function which(name) { + var paths = process.env.PATH.split(':'); + var loc; + + for (var i = 0, len = paths.length; i < len; ++i) { + loc = path.join(paths[i], name); + if (exists(loc)) return loc; + } +} + +switch(os.type()) { + case 'Darwin': + if (which('terminal-notifier')) { + cmd = { + type: "Darwin-NotificationCenter" + , pkg: "terminal-notifier" + , msg: '-message' + , title: '-title' + , subtitle: '-subtitle' + , priority: { + cmd: '-execute' + , range: [] + } + }; + } else { + cmd = { + type: "Darwin-Growl" + , pkg: "growlnotify" + , msg: '-m' + , sticky: '--sticky' + , priority: { + cmd: '--priority' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + , "Very Low" + , "Moderate" + , "Normal" + , "High" + , "Emergency" + ] + } + }; + } + break; + case 'Linux': + cmd = { + type: "Linux" + , pkg: "notify-send" + , msg: '' + , sticky: '-t 0' + , icon: '-i' + , priority: { + cmd: '-u' + , range: [ + "low" + , "normal" + , "critical" + ] + } + }; + break; + case 'Windows_NT': + cmd = { + type: "Windows" + , pkg: "growlnotify" + , msg: '' + , sticky: '/s:true' + , title: '/t:' + , icon: '/i:' + , priority: { + cmd: '/p:' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + ] + } + }; + break; +} + +/** + * Expose `growl`. + */ + +exports = module.exports = growl; + +/** + * Node-growl version. + */ + +exports.version = '1.4.1' + +/** + * Send growl notification _msg_ with _options_. + * + * Options: + * + * - title Notification title + * - sticky Make the notification stick (defaults to false) + * - priority Specify an int or named key (default is 0) + * - name Application name (defaults to growlnotify) + * - image + * - path to an icon sets --iconpath + * - path to an image sets --image + * - capitalized word sets --appIcon + * - filename uses extname as --icon + * - otherwise treated as --icon + * + * Examples: + * + * growl('New email') + * growl('5 new emails', { title: 'Thunderbird' }) + * growl('Email sent', function(){ + * // ... notification sent + * }) + * + * @param {string} msg + * @param {object} options + * @param {function} fn + * @api public + */ + +function growl(msg, options, fn) { + var image + , args + , options = options || {} + , fn = fn || function(){}; + + // noop + if (!cmd) return fn(new Error('growl not supported on this platform')); + args = [cmd.pkg]; + + // image + if (image = options.image) { + switch(cmd.type) { + case 'Darwin-Growl': + var flag, ext = path.extname(image).substr(1) + flag = flag || ext == 'icns' && 'iconpath' + flag = flag || /^[A-Z]/.test(image) && 'appIcon' + flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' + flag = flag || ext && (image = ext) && 'icon' + flag = flag || 'icon' + args.push('--' + flag, image) + break; + case 'Linux': + args.push(cmd.icon + " " + image); + // libnotify defaults to sticky, set a hint for transient notifications + if (!options.sticky) args.push('--hint=int:transient:1'); + break; + case 'Windows': + args.push(cmd.icon + quote(image)); + break; + } + } + + // sticky + if (options.sticky) args.push(cmd.sticky); + + // priority + if (options.priority) { + var priority = options.priority + ''; + var checkindexOf = cmd.priority.range.indexOf(priority); + if (~cmd.priority.range.indexOf(priority)) { + args.push(cmd.priority, options.priority); + } + } + + // name + if (options.name && cmd.type === "Darwin-Growl") { + args.push('--name', options.name); + } + + switch(cmd.type) { + case 'Darwin-Growl': + args.push(cmd.msg); + args.push(quote(msg)); + if (options.title) args.push(quote(options.title)); + break; + case 'Darwin-NotificationCenter': + args.push(cmd.msg); + args.push(quote(msg)); + if (options.title) { + args.push(cmd.title); + args.push(quote(options.title)); + } + if (options.subtitle) { + args.push(cmd.subtitle); + args.push(quote(options.title)); + } + break; + case 'Darwin-Growl': + args.push(cmd.msg); + args.push(quote(msg)); + if (options.title) args.push(quote(options.title)); + break; + case 'Linux': + if (options.title) { + args.push(quote(options.title)); + args.push(cmd.msg); + args.push(quote(msg)); + } else { + args.push(quote(msg)); + } + break; + case 'Windows': + args.push(quote(msg)); + if (options.title) args.push(cmd.title + quote(options.title)); + break; + } + + // execute + exec(args.join(' '), fn); +}; diff --git a/node_modules/growl/package.json b/node_modules/growl/package.json new file mode 100644 index 0000000..89a35ab --- /dev/null +++ b/node_modules/growl/package.json @@ -0,0 +1,58 @@ +{ + "_args": [ + [ + "growl@~1.7.0", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-growl-reporter" + ] + ], + "_from": "growl@>=1.7.0 <1.8.0", + "_id": "growl@1.7.0", + "_inCache": true, + "_installable": true, + "_location": "/growl", + "_npmUser": { + "email": "tj@vision-media.ca", + "name": "tjholowaychuk" + }, + "_npmVersion": "1.1.66", + "_phantomChildren": {}, + "_requested": { + "name": "growl", + "raw": "growl@~1.7.0", + "rawSpec": "~1.7.0", + "scope": null, + "spec": ">=1.7.0 <1.8.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine-growl-reporter" + ], + "_resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz", + "_shasum": "de2d66136d002e112ba70f3f10c31cf7c350b2da", + "_shrinkwrap": null, + "_spec": "growl@~1.7.0", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-growl-reporter", + "author": { + "email": "tj@vision-media.ca", + "name": "TJ Holowaychuk" + }, + "dependencies": {}, + "description": "Growl unobtrusive notifications", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "de2d66136d002e112ba70f3f10c31cf7c350b2da", + "tarball": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz" + }, + "main": "./lib/growl.js", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + } + ], + "name": "growl", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "version": "1.7.0" +} diff --git a/node_modules/growl/test.js b/node_modules/growl/test.js new file mode 100644 index 0000000..cf22d90 --- /dev/null +++ b/node_modules/growl/test.js @@ -0,0 +1,20 @@ + +var growl = require('./lib/growl') + +growl('You have mail!') +growl('5 new messages', { sticky: true }) +growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true }) +growl('Message with title', { title: 'Title'}) +growl('Set priority', { priority: 2 }) +growl('Show Safari icon', { image: 'Safari' }) +growl('Show icon', { image: 'path/to/icon.icns' }) +growl('Show image', { image: 'path/to/my.image.png' }) +growl('Show png filesystem icon', { image: 'png' }) +growl('Show pdf filesystem icon', { image: 'article.pdf' }) +growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(){ + console.log('callback'); +}) +growl('Show pdf filesystem icon', { title: 'Use show()', image: 'article.pdf' }) +growl('here \' are \n some \\ characters that " need escaping', {}, function(error, stdout, stderr) { + if (error !== null) throw new Error('escaping failed:\n' + stdout + stderr); +}) diff --git a/node_modules/inherits/LICENSE b/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +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/node_modules/inherits/README.md b/node_modules/inherits/README.md new file mode 100644 index 0000000..b1c5665 --- /dev/null +++ b/node_modules/inherits/README.md @@ -0,0 +1,42 @@ +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/node_modules/inherits/inherits.js b/node_modules/inherits/inherits.js new file mode 100644 index 0000000..29f5e24 --- /dev/null +++ b/node_modules/inherits/inherits.js @@ -0,0 +1 @@ +module.exports = require('util').inherits diff --git a/node_modules/inherits/inherits_browser.js b/node_modules/inherits/inherits_browser.js new file mode 100644 index 0000000..c1e78a7 --- /dev/null +++ b/node_modules/inherits/inherits_browser.js @@ -0,0 +1,23 @@ +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/node_modules/inherits/package.json b/node_modules/inherits/package.json new file mode 100644 index 0000000..ec0c64d --- /dev/null +++ b/node_modules/inherits/package.json @@ -0,0 +1,77 @@ +{ + "_args": [ + [ + "inherits@2", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/glob" + ] + ], + "_from": "inherits@>=2.0.0 <3.0.0", + "_id": "inherits@2.0.1", + "_inCache": true, + "_installable": true, + "_location": "/inherits", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.3.8", + "_phantomChildren": {}, + "_requested": { + "name": "inherits", + "raw": "inherits@2", + "rawSpec": "2", + "scope": null, + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "_shrinkwrap": null, + "_spec": "inherits@2", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/glob", + "browser": "./inherits_browser.js", + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "dependencies": {}, + "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "tarball": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "homepage": "https://github.com/isaacs/inherits#readme", + "keywords": [ + "browser", + "browserify", + "class", + "inheritance", + "inherits", + "klass", + "object-oriented", + "oop" + ], + "license": "ISC", + "main": "./inherits.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "inherits", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inherits.git" + }, + "scripts": { + "test": "node test" + }, + "version": "2.0.1" +} diff --git a/node_modules/inherits/test.js b/node_modules/inherits/test.js new file mode 100644 index 0000000..fc53012 --- /dev/null +++ b/node_modules/inherits/test.js @@ -0,0 +1,25 @@ +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/node_modules/jasmine-growl-reporter/.npmignore b/node_modules/jasmine-growl-reporter/.npmignore new file mode 100644 index 0000000..74e6e72 --- /dev/null +++ b/node_modules/jasmine-growl-reporter/.npmignore @@ -0,0 +1,5 @@ +*.swp +*.log +build +node_modules +tmp diff --git a/node_modules/jasmine-growl-reporter/.travis.yml b/node_modules/jasmine-growl-reporter/.travis.yml new file mode 100644 index 0000000..8963590 --- /dev/null +++ b/node_modules/jasmine-growl-reporter/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - 0.10 +before_script: + - npm install -g grunt-cli diff --git a/node_modules/jasmine-growl-reporter/Gruntfile.js b/node_modules/jasmine-growl-reporter/Gruntfile.js new file mode 100644 index 0000000..acf5832 --- /dev/null +++ b/node_modules/jasmine-growl-reporter/Gruntfile.js @@ -0,0 +1,33 @@ + +module.exports = function(grunt) { + + grunt.initConfig({ + + pkg: grunt.file.readJSON('package.json'), + + jshint: { + all: [ 'lib/**/*.js' ] + }, + + jasmine_node: { + projectRoot: '.', + requirejs: false, + forceExit: true + }, + + watch: { + + src: { + files: [ 'lib/**/*.js', 'spec/**/*.js' ], + tasks: [ 'jshint', 'jasmine_node' ] + } + } + }); + + grunt.loadNpmTasks('grunt-bump'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-jasmine-node'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + grunt.registerTask('default', [ 'jshint', 'jasmine_node' ]); +}; diff --git a/node_modules/jasmine-growl-reporter/LICENSE.txt b/node_modules/jasmine-growl-reporter/LICENSE.txt new file mode 100644 index 0000000..8074075 --- /dev/null +++ b/node_modules/jasmine-growl-reporter/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2013 Simon Oulevay (Alpha Hydrae) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/jasmine-growl-reporter/README.md b/node_modules/jasmine-growl-reporter/README.md new file mode 100644 index 0000000..f5fb34b --- /dev/null +++ b/node_modules/jasmine-growl-reporter/README.md @@ -0,0 +1,9 @@ +# Jasmine Growl Reporter + +Growl notifications when running your Jasmine specs. + +## Meta + +* **Author:** Simon Oulevay (Alpha Hydrae) +* **License:** MIT (see [LICENSE.txt](https://raw.github.com/AlphaHydrae/jasmine-growl-reporter/master/LICENSE.txt)) +* **Icons:** http://www.visualpharm.com/must_have_icon_set/ diff --git a/node_modules/jasmine-growl-reporter/index.js b/node_modules/jasmine-growl-reporter/index.js new file mode 100644 index 0000000..157db24 --- /dev/null +++ b/node_modules/jasmine-growl-reporter/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/reporter').inject(); diff --git a/node_modules/jasmine-growl-reporter/lib/reporter.js b/node_modules/jasmine-growl-reporter/lib/reporter.js new file mode 100644 index 0000000..fc894b4 --- /dev/null +++ b/node_modules/jasmine-growl-reporter/lib/reporter.js @@ -0,0 +1,77 @@ + +exports.inject = function(deps) { + + deps = deps || {}; + var growl = deps.growl || require('growl'), + path = require('path'); + + var GrowlReporter = function() { + }; + + GrowlReporter.prototype = { + + reportRunnerStarting: function() { + this.startedAt = new Date(); + this.passedSpecs = 0; + this.totalSpecs = 0; + }, + + reportSpecStarting: function() { + this.totalSpecs++; + }, + + reportSpecResults: function(spec) { + if (spec.results().passed()) { + this.passedSpecs++; + } + }, + + reportRunnerResults: function() { + + growl(growlMessage(this.passedSpecs, this.totalSpecs), { + name: growlName, + title: growlTitle(this.passedSpecs, this.totalSpecs, this.startedAt), + image: growlImage(this.passedSpecs, this.totalSpecs) + }); + } + }; + + var growlName = 'Jasmine', + resDir = path.resolve(__dirname, '../res'); + + var growlTitle = function(passedSpecs, totalSpecs, startedAt) { + + var title = passed(passedSpecs, totalSpecs) ? 'PASSED' : 'FAILED'; + title += ' in ' + ((new Date().getTime() - startedAt.getTime()) / 1000) + 's'; + + return title; + }; + + var growlMessage = function(passedSpecs, totalSpecs) { + + var description = passedSpecs + ' tests passed'; + + var failedSpecs = totalSpecs - passedSpecs; + if (failedSpecs) { + description += ', ' + failedSpecs + ' tests failed'; + } + + description += ', ' + totalSpecs + ' total'; + + return description; + }; + + var growlImage = function(passedSpecs, totalSpecs) { + if (passed(passedSpecs, totalSpecs)) { + return path.join(resDir, 'passed.png'); + } else { + return path.join(resDir, 'failed.png'); + } + }; + + var passed = function(passedSpecs, totalSpecs) { + return passedSpecs == totalSpecs; + }; + + return GrowlReporter; +}; diff --git a/node_modules/jasmine-growl-reporter/package.json b/node_modules/jasmine-growl-reporter/package.json new file mode 100644 index 0000000..217ec2c --- /dev/null +++ b/node_modules/jasmine-growl-reporter/package.json @@ -0,0 +1,85 @@ +{ + "_args": [ + [ + "jasmine-growl-reporter@~0.0.2", + "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-node" + ] + ], + "_from": "jasmine-growl-reporter@>=0.0.2 <0.1.0", + "_id": "jasmine-growl-reporter@0.0.3", + "_inCache": true, + "_installable": true, + "_location": "/jasmine-growl-reporter", + "_npmUser": { + "email": "hydrae.alpha@gmail.com", + "name": "alphahydrae" + }, + "_npmVersion": "1.4.7", + "_phantomChildren": {}, + "_requested": { + "name": "jasmine-growl-reporter", + "raw": "jasmine-growl-reporter@~0.0.2", + "rawSpec": "~0.0.2", + "scope": null, + "spec": ">=0.0.2 <0.1.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine-node" + ], + "_resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-0.0.3.tgz", + "_shasum": "b87ae551e359d28ad5217765eaef6c07b763f6c8", + "_shrinkwrap": null, + "_spec": "jasmine-growl-reporter@~0.0.2", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures/node_modules/jasmine-node", + "author": { + "name": "Alpha Hydrae", + "url": "https://github.com/AlphaHydrae" + }, + "bugs": { + "url": "https://github.com/AlphaHydrae/jasmine-growl-reporter/issues" + }, + "dependencies": { + "growl": "~1.7.0" + }, + "description": "Growl notifications when running your Jasmine specs.", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-bump": "~0.0.11", + "grunt-contrib-jshint": "~0.6.0", + "grunt-contrib-watch": "~0.5.1", + "grunt-jasmine-node": "~0.1.0", + "jasmine-node": "~1.10.2", + "underscore": "~1.5.1" + }, + "directories": {}, + "dist": { + "shasum": "b87ae551e359d28ad5217765eaef6c07b763f6c8", + "tarball": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-0.0.3.tgz" + }, + "homepage": "https://github.com/AlphaHydrae/jasmine-growl-reporter", + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/AlphaHydrae/jasmine-growl-reporter/master/LICENSE.txt" + } + ], + "main": "./index.js", + "maintainers": [ + { + "name": "alphahydrae", + "email": "hydrae.alpha@gmail.com" + } + ], + "name": "jasmine-growl-reporter", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/AlphaHydrae/jasmine-growl-reporter.git" + }, + "scripts": { + "test": "grunt" + }, + "version": "0.0.3" +} diff --git a/node_modules/jasmine-growl-reporter/res/failed.png b/node_modules/jasmine-growl-reporter/res/failed.png new file mode 100644 index 0000000..6c10e11 Binary files /dev/null and b/node_modules/jasmine-growl-reporter/res/failed.png differ diff --git a/node_modules/jasmine-growl-reporter/res/passed.png b/node_modules/jasmine-growl-reporter/res/passed.png new file mode 100644 index 0000000..9cb5174 Binary files /dev/null and b/node_modules/jasmine-growl-reporter/res/passed.png differ diff --git a/node_modules/jasmine-growl-reporter/spec/matchers.js b/node_modules/jasmine-growl-reporter/spec/matchers.js new file mode 100644 index 0000000..3bb39ae --- /dev/null +++ b/node_modules/jasmine-growl-reporter/spec/matchers.js @@ -0,0 +1,53 @@ + +var _ = require('underscore'); + +beforeEach(function() { + + this.addMatchers({ + + toHaveNotified: function(message, options) { + + var actual = this.actual; + + var called = actual.calls.length, + messageMatches = false, + optionsMatch = true; + + if (called) { + var actualMessage = actual.calls[0].args[0]; + messageMatches = _.isRegExp(message) ? _.isString(actualMessage) && actualMessage.match(message) : actualMessage == message; + + var actualOptions = actual.calls[0].args[1]; + if (options || actualOptions) { + if (!options != !actualOptions) { + optionsMatch = false; + } else if (!_.isEqual(_.keys(options), _.keys(actualOptions))) { + optionsMatch = false; + } else { + for (var name in options) { + + var matcher = options[name], + value = actualOptions[name]; + if (!(_.isRegExp(matcher) ? _.isString(value) && value.match(matcher) : value == matcher)) { + optionsMatch = false; + break; + } + } + } + } + } + + this.message = function() { + if (!called) { + return 'Expected ' + actual + ' to have been called'; + } else if (!messageMatches) { + return 'Expected ' + actual + ' to have been called with message "' + message + '", got "' + actual.calls[0].args[0] + '"'; + } else if (!optionsMatch) { + return 'Expected ' + actual + ' to have been called with options ' + JSON.stringify(options) + ', got ' + JSON.stringify(actual.calls[0].args[1]); + } + }; + + return called && messageMatches && optionsMatch; + } + }); +}); diff --git a/node_modules/jasmine-growl-reporter/spec/reporter.spec.js b/node_modules/jasmine-growl-reporter/spec/reporter.spec.js new file mode 100644 index 0000000..b42853c --- /dev/null +++ b/node_modules/jasmine-growl-reporter/spec/reporter.spec.js @@ -0,0 +1,90 @@ + +var _ = require('underscore'); +require('./matchers'); + +describe("GrowlReporter", function() { + + var injector = require('../lib/reporter').inject, + path = require('path'), + growl = null, + reporter = null; + + var fakeSpecResults = function(passed) { + return { + results: function() { + return { + passed: function() { + return passed; + } + } + } + }; + }; + + var title = 'Jasmine', + passedRegexp = /^PASSED in [\d\.]+s$/, + failedRegexp = /^FAILED in [\d\.]+s$/, + passedImage = path.resolve(__dirname, '../res/passed.png'), + failedImage = path.resolve(__dirname, '../res/failed.png'); + + beforeEach(function() { + growl = jasmine.createSpy(); + reporter = new (injector({ growl: growl }))(); + }); + + it("should report 0 results", function() { + reporter.reportRunnerStarting(); + reporter.reportRunnerResults(); + expect(growl).toHaveNotified('0 tests passed, 0 total', { + name: title, + title: passedRegexp, + image: passedImage + }); + }); + + it("should report 2 successful results", function() { + reporter.reportRunnerStarting(); + _.times(2, function() { + reporter.reportSpecStarting(); + reporter.reportSpecResults(fakeSpecResults(true)); + }); + reporter.reportRunnerResults(); + expect(growl).toHaveNotified('2 tests passed, 2 total', { + name: title, + title: passedRegexp, + image: passedImage + }); + }); + + it("should report 3 failed results", function() { + reporter.reportRunnerStarting(); + _.times(3, function() { + reporter.reportSpecStarting(); + reporter.reportSpecResults(fakeSpecResults(false)); + }); + reporter.reportRunnerResults(); + expect(growl).toHaveNotified('0 tests passed, 3 tests failed, 3 total', { + name: title, + title: failedRegexp, + image: failedImage + }); + }); + + it("should report 2 passed and 4 failed results", function() { + reporter.reportRunnerStarting(); + _.times(2, function() { + reporter.reportSpecStarting(); + reporter.reportSpecResults(fakeSpecResults(true)); + }); + _.times(4, function() { + reporter.reportSpecStarting(); + reporter.reportSpecResults(fakeSpecResults(false)); + }); + reporter.reportRunnerResults(); + expect(growl).toHaveNotified('2 tests passed, 4 tests failed, 6 total', { + name: title, + title: failedRegexp, + image: failedImage + }); + }); +}); diff --git a/node_modules/jasmine-node/.npmignore b/node_modules/jasmine-node/.npmignore new file mode 100755 index 0000000..ec8ac7f --- /dev/null +++ b/node_modules/jasmine-node/.npmignore @@ -0,0 +1,13 @@ +.DS_Store +.idea +*.iml +*.ipr +*.iws +*.tmproj +.project +.settings +.externalToolBuilders +*.swp +node_modules +*~ +/.c9revisions/ diff --git a/node_modules/jasmine-node/.travis.yml b/node_modules/jasmine-node/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/node_modules/jasmine-node/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/node_modules/jasmine-node/LICENSE b/node_modules/jasmine-node/LICENSE new file mode 100755 index 0000000..b6ad6d3 --- /dev/null +++ b/node_modules/jasmine-node/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/node_modules/jasmine-node/README.md b/node_modules/jasmine-node/README.md new file mode 100644 index 0000000..4acc3dc --- /dev/null +++ b/node_modules/jasmine-node/README.md @@ -0,0 +1,286 @@ +jasmine-node +====== + +[![Build Status](https://secure.travis-ci.org/spaghetticode/jasmine-node.png)](http://travis-ci.org/spaghetticode/jasmine-node) + +This node.js module makes the wonderful [Pivotal Lab's jasmine](http://github.com/pivotal/jasmine) +spec framework available in node.js. + +jasmine +------- + +Version `1.3.1` of Jasmine is currently included with node-jasmine. This is a forked version from the +[Karma project](https://github.com/karma-runner/karma-jasmine), which allows you to use the +`ddescribe` and `iit` functions to run individual suites or specs. + +BETA `2.0.0` Support is available in the `Jasmine2.0` branch. + +what's new +---------- +* Growl notifications with the `--growl` flag (requires Growl to be installed) +* Ability to test specs written in Literate Coffee-Script +* Teamcity Reporter reinstated. +* Ability to specify multiple files to test via list in command line +* Ability to suppress stack trace with `--noStack` +* Async tests now run in the expected context instead of the global one +* `--config` flag that allows you to assign variables to process.env +* Terminal Reporters are now available in the Jasmine Object #184 +* Done is now available in all timeout specs #199 +* `afterEach` is available in requirejs #179 +* Editors that replace instead of changing files should work with autotest #198 +* Jasmine Mock Clock now works! +* Autotest now works! +* Using the latest Jasmine! +* Verbose mode tabs `describe` blocks much more accurately! +* `--coffee` now allows specs written in Literate CoffeeScript (`.litcoffee`) + +install +------ + +To install the latest official version, use NPM: + +```sh +npm install jasmine-node -g +``` + +To install the latest _bleeding edge_ version, clone this repository and check +out the `beta` branch. + +usage +------ + +Write the specifications for your code in `*.js` and `*.coffee` files in the `spec/` directory. +You can use sub-directories to better organise your specs. In the specs use `describe()`, `it()` etc. exactly +as you would in client-side jasmine specs. + +**Note**: your specification files must be named as `*spec.js`, `*spec.coffee` or `*spec.litcoffee`, +which matches the regular expression `/spec\.(js|coffee|litcoffee)$/i`; +otherwise jasmine-node won't find them! +For example, `sampleSpecs.js` is wrong, `sampleSpec.js` is right. + +If you have installed the npm package, you can run it with: + +```sh +jasmine-node spec/ +``` + +If you aren't using npm, you should add `pwd`/lib to the `$NODE_PATH` +environment variable, then run: + +```sh +node lib/jasmine-node/cli.js +``` + + +You can supply the following arguments: + + * `--autotest`, provides automatic execution of specs after each change + * `--watch`, when used with `--autotest`, paths after `--watch` will be +watched for changes, allowing to watch for changes outside of specs directory + * `--coffee`, allow execution of `.coffee` and `.litcoffee` specs + * `--color`, indicates spec output should uses color to +indicates passing (green) or failing (red) specs + * `--noColor`, do not use color in the output + * `-m, --match REGEXP`, match only specs containing "REGEXPspec" + * `--matchall`, relax requirement of "spec" in spec file names + * `--verbose`, verbose output as the specs are run + * `--junitreport`, export tests results as junitreport xml format + * `--output FOLDER`, defines the output folder for junitreport files + * `--teamcity`, converts all console output to teamcity custom test runner commands. (Normally auto detected.) + * `--growl`, display test run summary in a growl notification (in addition to other outputs) + * `--runWithRequireJs`, loads all specs using requirejs instead of node's native require method + * `--requireJsSetup`, file run before specs to include and configure RequireJS + * `--test-dir`, the absolute root directory path where tests are located + * `--nohelpers`, does not load helpers + * `--forceexit`, force exit once tests complete + * `--captureExceptions`, listen to global exceptions, report them and exit (interferes with Domains in NodeJs, so do not use if using Domains as well + * `--config NAME VALUE`, set a global variable in `process.env` + * `--noStack`, suppress the stack trace generated from a test failure + +Individual files to test can be added as bare arguments to the end of the args. + +Example: + +```bash +jasmine-node --coffee spec/AsyncSpec.coffee spec/CoffeeSpec.coffee spec/SampleSpec.js +``` + +async tests +----------- + +jasmine-node includes an alternate syntax for writing asynchronous tests. Accepting +a done callback in the specification will trigger jasmine-node to run the test +asynchronously waiting until the `done()` callback is called. + +```javascript +var request = require('request'); + +it("should respond with hello world", function(done) { + request("http://localhost:3000/hello", function(error, response, body){ + expect(body).toEqual("hello world"); + done(); + }); +}); +``` + +An asynchronous test will fail after `5000` ms if `done()` is not called. This timeout +can be changed by setting `jasmine.getEnv().defaultTimeoutInterval` or by passing a timeout +interval in the specification. + +```javascript +var request = require('request'); + +it("should respond with hello world", function(done) { + request("http://localhost:3000/hello", function(error, response, body){ + done(); + }); +}, 250); // timeout after 250 ms +``` + +or + +```javascript +var request = require('request'); + +jasmine.getEnv().defaultTimeoutInterval = 500; + +it("should respond with hello world", function(done) { + request("http://localhost:3000/hello", function(error, response, body){ + done(); + }); // timeout after 500 ms +}); +``` + +Checkout [`spec/SampleSpecs.js`](https://github.com/mhevery/jasmine-node/blob/master/spec/SampleSpecs.js) to see how to use it. + + +requirejs +--------- + +There is a sample project in `/spec-requirejs`. It is comprised of: + +1. `requirejs-setup.js`, this pulls in our wrapper template (next) +1. `requirejs-wrapper-template`, this builds up requirejs settings +1. `requirejs.sut.js`, this is a __SU__bject To __T__est, something required by requirejs +1. `requirejs.spec.js`, the actual jasmine spec for testing + +To run it: + +```sh +node lib/jasmine-node/cli.js --runWithRequireJs --requireJsSetup ./spec-requirejs/requirejs-setup.js ./spec-requirejs/ +``` + +exceptions +---------- + +Often you'll want to capture an uncaught exception and log it to the console, +this is accomplished by using the `--captureExceptions` flag. Exceptions will +be reported to the console, but jasmine-node will attempt to recover and +continue. It was decided to not change the current functionality until `2.0`. So, +until then, jasmine-node will still return `0` and continue on without this flag. + +### Scenario ### + +You require a module, but it doesn't exist, ie `require('Q')` instead of +`require('q')`. Jasmine-Node reports the error to the console, but carries on +and returns `0`. This messes up Travis-CI because you need it to return a +non-zero status while doing CI tests. + +### Mitigation ### + +Before `--captureExceptions` + +```sh +> jasmine-node --coffee spec +> echo $status +0 +``` + +Run jasmine node with the `--captureExceptions` flag. + +```sh +> jasmine-node --coffee --captureExceptions spec +> echo $status +1 +``` + + +growl notifications +------------------- + +Jasmine node can display [Growl](http://growl.info) notifications of test +run summaries in addition to other reports. +Growl must be installed separately, see [node-growl](https://github.com/visionmedia/node-growl) +for platform-specific instructions. Pass the `--growl` flag to enable the notifications. + + +development +----------- + +Install the dependent packages by running: + +```sh +npm install +``` + +Run the specs before you send your pull request: + +```sh +specs.sh +``` + +__Note:__ Some tests are designed to fail in the specs.sh. After each of the +individual runs completes, there is a line that lists what the expected +Pass/Assert/Fail count should be. If you add/remove/edit tests, please be sure +to update this with your PR. + + +changelog +--------- + +* _1.14.5_ Using ~ instead of ^ for reporter version (thanks to [Maxim-Filimonov](https://github.com/Maxim-Filimonov)) +* _1.14.4_ Rolled back jasmine reporter version (thanks to [tjmcduffie](https://github.com/tjmcduffie)) +* _1.14.3_ Added 'onComplete' callback to TeamCityReporter (thanks to [JoergFiedler](https://github.com/JoergFiedler)) +* _1.14.2_ Uhhh...not sure what happened here. +* _1.14.1_ Default to noColors if not in a TTY +* _1.14.0_ Add support for `iit`, `ddescribe` (thanks to [mgcrea](https://github.com/mgcrea)) +* _1.13.1_ Add coffee-script support for 1.7.x (thanks to [nathancarter](https://github.com/nathancarter)) +* _1.13.0_ Added timing to the verbose reporter (thanks to [rick-kilgore](https://github.com/rick-kilgore)) +* _1.12.1_ Fixed an issue where an undefined variable caused an unhelpful + exception in --watch Resolves #278 +* _1.12.0_ + * Changed `util.print` to `stdout.write` (thanks to [nrstott](https://github.com/nrstott)) + * Don’t affect line numbers with --requireJsSetup (thanks to [daviddaurelio](https://github.com/davidaurelio)) + * Catch errors when loading helpers (thanks to [pimterry](https://github.com/pimterry)) + * Keep autotesting until all tests have passed (thanks to [notclive](https://github.com/notclive)) +* _1.11.0 - Added Growl notification option `--growl` (thanks to + [AlphaHydrae](https://github.com/AlphaHydrae))_ +* _1.10.2 - Restored stack filter which was accidentally removed (thanks to + [kevinsawicki](https://github.com/kevinsawicki))_ +* _1.10.1 - `beforeEach` and `afterEach` now properly handle the async-timeout function_ +* _1.10.0 - Skipped tests now show in the terminal reporter's output (thanks + to [kevinsawicki](https://github.com/kevinsawicki))_ +* _1.9.1 - Timeout now consistent between Async and Non-Async Calls (thanks to + [codemnky](https://github.com/codemnky))_ +* _1.9.0 - Now re-throwing the file-not-found error, added info to README.md, + printing version with `--version`_ +* _1.8.1 - Fixed silent failure due to invalid REGEX (thanks to + [pimterry](https://github.com/pimterry))_ +* _1.8.0 - Fixed bug in autotest with multiple paths and added `--watch` feature + (thanks to [davegb3](https://github.com/davegb3))_ +* _1.7.1 - Removed unneeded fs dependency (thanks to + [kevinsawicki](https://github.com/kevinsawicki)) Fixed broken fs call in + node `0.6` (thanks to [abe33](https://github.com/abe33))_ +* _1.7.0 - Literate Coffee-Script now testable (thanks to [magicmoose](https://github.com/magicmoose))_ +* _1.6.0 - Teamcity Reporter Reinstated (thanks to [bhcleek](https://github.com/bhcleek))_ +* _1.5.1 - Missing files and require exceptions will now report instead of failing silently_ +* _1.5.0 - Now takes multiple files for execution. (thanks to [abe33](https://github.com/abe33))_ +* _1.4.0 - Optional flag to suppress stack trace on test failure (thanks to [Lastalas](https://github.com/Lastalas))_ +* _1.3.1 - Fixed context for async tests (thanks to [omryn](https://github.com/omryn))_ +* _1.3.0 - Added `--config` flag for changeable testing environments_ +* _1.2.3 - Fixed #179, #184, #198, #199. Fixes autotest, afterEach in requirejs, terminal reporter is in jasmine object, done function missing in async tests_ +* _1.2.2 - Revert Exception Capturing to avoid Breaking Domain Tests_ +* _1.2.1 - Emergency fix for path reference missing_ +* _1.2.0 - Fixed #149, #152, #171, #181, #195. `--autotest` now works as expected, jasmine clock now responds to the fake ticking as requested, and removed the path.exists warning_ +* _1.1.1 - Fixed #173, #169 (Blocks were not indented in verbose properly, added more documentation to address #180_ +* _1.1.0 - Updated Jasmine to `1.3.1`, fixed fs missing, catching uncaught exceptions, other fixes_ diff --git a/node_modules/jasmine-node/bin/jasmine-node b/node_modules/jasmine-node/bin/jasmine-node new file mode 100755 index 0000000..33d4873 --- /dev/null +++ b/node_modules/jasmine-node/bin/jasmine-node @@ -0,0 +1,6 @@ +#!/usr/bin/env node + +if( !process.env.NODE_ENV ) process.env.NODE_ENV = 'test'; + +var path = require('path'); +require(path.join(__dirname,'../lib/jasmine-node/cli.js')); diff --git a/node_modules/jasmine-node/bower.json b/node_modules/jasmine-node/bower.json new file mode 100644 index 0000000..0893e5e --- /dev/null +++ b/node_modules/jasmine-node/bower.json @@ -0,0 +1,19 @@ +{ + "name": "jasmine-node", + "version": "1.12.0", + "homepage": "https://github.com/mhevery/jasmine-node", + "authors": [ + "Misko Hevery ", + "Chris M " + ], + "description": "Integration of Jasmine Spec framework with Node.js", + "main": "lib/jasmine-node", + "keywords": [ + "jasmine", + "node", + "commonjs", + "node" + ], + "license": "MIT", + "private": true +} diff --git a/node_modules/jasmine-node/lib/jasmine-node/async-callback.js b/node_modules/jasmine-node/lib/jasmine-node/async-callback.js new file mode 100644 index 0000000..d9a94c4 --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/async-callback.js @@ -0,0 +1,61 @@ +(function() { + var withoutAsync = {}; + + ["it", "beforeEach", "afterEach"].forEach(function(jasmineFunction) { + withoutAsync[jasmineFunction] = jasmine.Env.prototype[jasmineFunction]; + return jasmine.Env.prototype[jasmineFunction] = function() { + var args = Array.prototype.slice.call(arguments, 0); + var timeout = null; + if (isLastArgumentATimeout(args)) { + timeout = args.pop(); + // The changes to the jasmine test runner causes undef to be passed when + // calling all it()'s now. If the last argument isn't a timeout and the + // last argument IS undefined, let's just pop it off. Since out of bounds + // items are undefined anyways, *hopefully* removing an undef item won't + // hurt. + } else if (args[args.length-1] == undefined) { + args.pop(); + } + if (isLastArgumentAnAsyncSpecFunction(args)) + { + var specFunction = args.pop(); + args.push(function() { + return asyncSpec(specFunction, this, timeout); + }); + } + return withoutAsync[jasmineFunction].apply(this, args); + }; + }); + + function isLastArgumentATimeout(args) + { + return args.length > 0 && (typeof args[args.length-1]) === "number"; + } + + function isLastArgumentAnAsyncSpecFunction(args) + { + return args.length > 0 && (typeof args[args.length-1]) === "function" && args[args.length-1].length > 0; + } + + function asyncSpec(specFunction, spec, timeout) { + if (timeout == null) timeout = jasmine.getEnv().defaultTimeoutInterval || 1000; + var done = false; + spec.runs(function() { + try { + return specFunction.call(spec, function(error) { + done = true; + if (error != null) return spec.fail(error); + }); + } catch (e) { + done = true; + throw e; + } + }); + return spec.waitsFor(function() { + if (done === true) { + return true; + } + }, "spec to complete", timeout); + }; + +}).call(this); diff --git a/node_modules/jasmine-node/lib/jasmine-node/autotest.js b/node_modules/jasmine-node/lib/jasmine-node/autotest.js new file mode 100755 index 0000000..362dcb7 --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/autotest.js @@ -0,0 +1,118 @@ +var walkdir = require('walkdir'); +var collection = require('./spec-collection'); +var path = require('path'); +var fs = require('fs'); +var child_process = require('child_process'); +var gaze = require('gaze'); +var _ = require('underscore'); + +var baseArgv = []; + +for(var i = 0; i < process.argv.length; i++) { + if(process.argv[i] !== '--autotest') { + baseArgv.push(process.argv[i]); + } +} + +var run_external = function(command, args, callback) { + var child = child_process.spawn(command, args); + child.stdout.on('data', function(data) { + process.stdout.write(data); + }); + child.stderr.on('data', function(data) { + process.stderr.write(data); + }); + if(typeof callback == 'function') { + child.on('exit', callback); + } +} + +var last_run_successful = false; + +var run_everything = function() { + // run the suite when it starts + var argv = [].concat(baseArgv); + run_external(argv.shift(), argv, function (code) { + last_run_successful = code === 0 + }); +} + +exports.start = function(loadpaths, watchFolders, patterns) { + var watchPatterns; + + loadpaths.forEach(function(loadpath){ + + // If loadpath is just a single file, we should just watch that file + stats = fs.statSync(loadpath); + if (stats.isFile()) { + watchPatterns = loadpath; + } else { + watchPatterns = patterns.map(function(p) { + return path.join(loadpath, p); + }); + } + + changedFunc = function(event, file) { + console.log(file + ' was changed'); + + var match = path.basename(file, path.extname(file)) + ".*"; + match = match.replace(new RegExp("spec", "i"), ""); + + var argv = [].concat(baseArgv, ["--match", match]); + run_external(argv.shift(), argv, function(code) { + // run everything if we fixed some bugs + if(code == 0) { + if(!last_run_successful) { + run_everything(); + } + } else { + last_run_successful = false; + } + }); + } + + // Vim seems to change a file multiple times, with non-scientific testing + // the only time we didn't duplicate the call to onChanged was at 2.5s + // Passing true to have onChanged run on the leading edge of the timeout + var onChanged = _.debounce(changedFunc, 2500, true); + + gaze(watchPatterns, function(err, watcher) { + // Get all watched files + console.log("Watching for changes in " + loadpath); + + // On file changed + this.on('all', onChanged); + }); + + + + }); + + + watchFolders.forEach(function(watchPath) { + // If watchPath is just a single file, we should just watch that file + stats = fs.statSync(watchPath); + if (stats.isFile()) { + watchPatterns = watchPath; + } else { + watchPatterns = patterns.map(function(p) { + return path.join(watchPath, p); + }); + } + + // We debounce run_everything here due to the Vim issue described above. + var onChanged = _.debounce(run_everything, 2500, true); + + + gaze(watchPatterns, function(err, watcher) { + console.log("Watching for changes in " + watchPath); + + this.on('all', onChanged); + }); + + + + }); + + run_everything(); +}; diff --git a/node_modules/jasmine-node/lib/jasmine-node/cli.js b/node_modules/jasmine-node/lib/jasmine-node/cli.js new file mode 100755 index 0000000..4a1e525 --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/cli.js @@ -0,0 +1,287 @@ +var util, + Path= require('path'), + fs = require('fs'); + +var jasmine = require('./index'); + + +try { + util = require('util') +} catch(e) { + util = require('sys') +} + +var helperCollection = require('./spec-collection'); + +var specFolders = []; +var watchFolders = []; + +// The following line keeps the jasmine setTimeout in the proper scope +jasmine.setTimeout = jasmine.getGlobal().setTimeout; +jasmine.setInterval = jasmine.getGlobal().setInterval; +for (var key in jasmine) + global[key] = jasmine[key]; + +var isVerbose = false; +var showColors = true; +// Disable if we're not on a TTY +if (!process.stdout.isTTY) { + showColors = false; +} +var teamcity = process.env.TEAMCITY_PROJECT_NAME || false; +var useRequireJs = false; +var extensions = "js"; +var match = '.'; +var matchall = false; +var autotest = false; +var useHelpers = true; +var forceExit = false; +var captureExceptions = false; +var includeStackTrace = true; +var growl = false; + +var junitreport = { + report: false, + savePath : "./reports/", + useDotNotation: true, + consolidate: true +} + +var args = process.argv.slice(2); +var existsSync = fs.existsSync || Path.existsSync; + +while(args.length) { + var arg = args.shift(); + + switch(arg) + { + case '--version': + printVersion(); + case '--color': + showColors = true; + break; + case '--noColor': + case '--nocolor': + showColors = false; + break; + case '--verbose': + isVerbose = true; + break; + case '--coffee': + try { + require('coffee-script/register'); // support CoffeeScript >=1.7.0 + } catch ( e ) { + require('coffee-script'); // support CoffeeScript <=1.6.3 + } + extensions = "js|coffee|litcoffee"; + break; + case '-m': + case '--match': + match = args.shift(); + break; + case '--matchall': + matchall = true; + break; + case '--junitreport': + junitreport.report = true; + break; + case '--output': + junitreport.savePath = args.shift(); + break; + case '--teamcity': + teamcity = true; + break; + case '--requireJsSetup': + var setup = args.shift(); + + if(!existsSync(setup)) + throw new Error("RequireJS setup '" + setup + "' doesn't exist!"); + + useRequireJs = setup; + break; + case '--runWithRequireJs': + useRequireJs = useRequireJs || true; + break; + case '--nohelpers': + useHelpers = false; + break; + case '--test-dir': + var dir = args.shift(); + + if(!existsSync(dir)) + throw new Error("Test root path '" + dir + "' doesn't exist!"); + + specFolders.push(dir); // NOTE: Does not look from current working directory. + break; + case '--autotest': + autotest = true; + break; + case '--watch': + var nextWatchDir; + + // Add the following arguments, until we see another argument starting with '-' + while (args[0] && args[0][0] !== '-') { + nextWatchDir = args.shift(); + watchFolders.push(nextWatchDir); + + if (!existsSync(nextWatchDir)) + throw new Error("Watch path '" + nextWatchDir + "' doesn't exist!"); + } + break; + + case '--forceexit': + forceExit = true; + break; + case '--captureExceptions': + captureExceptions = true; + break; + case '--noStack': + includeStackTrace = false; + break; + case '--growl': + growl = true; + break; + case '--config': + var configKey = args.shift(); + var configValue = args.shift(); + process.env[configKey]=configValue; + break; + case '-h': + help(); + default: + if (arg.match(/^--params=.*/)) { + break; + } + if (arg.match(/^--/)) help(); + if (arg.match(/^\/.*/)) { + specFolders.push(arg); + } else { + specFolders.push(Path.join(process.cwd(), arg)); + } + break; + } +} + +if (specFolders.length === 0) { + help(); +} else { + // Check to see if all our files exist + for (var idx = 0; idx < specFolders.length; idx++) { + if (!existsSync(specFolders[idx])) { + console.log("File: " + specFolders[idx] + " is missing."); + return; + } + } +} + +if (autotest) { + + var patterns = ['**/*.js']; + + if (extensions.indexOf("coffee") !== -1) { + patterns.push('**/*.coffee'); + } + + require('./autotest').start(specFolders, watchFolders, patterns); + + return; +} + +var exitCode = 0; + +if (captureExceptions) { + process.on('uncaughtException', function(e) { + console.error(e.stack || e); + exitCode = 1; + process.exit(exitCode); + }); +} + +process.on("exit", onExit); + +function onExit() { + process.removeListener("exit", onExit); + process.exit(exitCode); +} + +var onComplete = function(runner, log) { + process.stdout.write('\n'); + if (runner.results().failedCount == 0) { + exitCode = 0; + } else { + exitCode = 1; + } + if (forceExit) { + process.exit(exitCode); + } +}; + +if(useHelpers){ + specFolders.forEach(function(path){ + jasmine.loadHelpersInFolder(path, + new RegExp("helpers?\\.(" + extensions + ")$", 'i')); + + }) +} + +try { + var regExpSpec = new RegExp(match + (matchall ? "" : "spec\\.") + "(" + extensions + ")$", 'i') +} catch (error) { + console.error("Failed to build spec-matching regex: " + error); + process.exit(2); +} + + +var options = { + specFolders: specFolders, + onComplete: onComplete, + isVerbose: isVerbose, + showColors: showColors, + teamcity: teamcity, + useRequireJs: useRequireJs, + regExpSpec: regExpSpec, + junitreport: junitreport, + includeStackTrace: includeStackTrace, + growl: growl +} + +jasmine.executeSpecsInFolder(options); + + +function help(){ + process.stdout.write([ + 'USAGE: jasmine-node [--color|--noColor] [--verbose] [--coffee] directory' + , '' + , 'Options:' + , ' --autotest - rerun automatically the specs when a file changes' + , ' --watch PATH - when used with --autotest, watches the given path(s) and runs all tests if a change is detected' + , ' --color - use color coding for output' + , ' --noColor - do not use color coding for output' + , ' -m, --match REGEXP - load only specs containing "REGEXPspec"' + , ' --matchall - relax requirement of "spec" in spec file names' + , ' --verbose - print extra information per each test run' + , ' --coffee - load coffee-script which allows execution .coffee files' + , ' --junitreport - export tests results as junitreport xml format' + , ' --output - defines the output folder for junitreport files' + , ' --teamcity - converts all console output to teamcity custom test runner commands. (Normally auto detected.)' + , ' --growl - display test run summary in a growl notification (in addition to other outputs)' + , ' --runWithRequireJs - loads all specs using requirejs instead of node\'s native require method' + , ' --requireJsSetup - file run before specs to include and configure RequireJS' + , ' --test-dir - the absolute root directory path where tests are located' + , ' --nohelpers - does not load helpers.' + , ' --forceexit - force exit once tests complete.' + , ' --captureExceptions- listen to global exceptions, report them and exit (interferes with Domains)' + , ' --config NAME VALUE- set a global variable in process.env' + , ' --noStack - suppress the stack trace generated from a test failure' + , ' --version - show the current version' + , ' -h, --help - display this help and exit' + , '' + ].join("\n")); + + process.exit(-1); +} + +function printVersion(){ + console.log("1.14.3"); + process.exit(0); +} diff --git a/node_modules/jasmine-node/lib/jasmine-node/cs.js b/node_modules/jasmine-node/lib/jasmine-node/cs.js new file mode 100644 index 0000000..0d7ff76 --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/cs.js @@ -0,0 +1,160 @@ +/** + * @license cs 0.4.2 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. + * Available via the MIT or new BSD license. + * see: http://github.com/jrburke/require-cs for details + */ + +/*jslint */ +/*global define, window, XMLHttpRequest, importScripts, Packages, java, + ActiveXObject, process, require */ + +define(['coffee-script'], function (CoffeeScript) { + 'use strict'; + var fs, getXhr, + progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], + fetchText = function () { + throw new Error('Environment unsupported.'); + }, + buildMap = {}; + + if (typeof process !== "undefined" && + process.versions && + !!process.versions.node) { + //Using special require.nodeRequire, something added by r.js. + fs = require.nodeRequire('fs'); + fetchText = function (path, callback) { + callback(fs.readFileSync(path, 'utf8')); + }; + } else if ((typeof window !== "undefined" && window.navigator && window.document) || typeof importScripts !== "undefined") { + // Browser action + getXhr = function () { + //Would love to dump the ActiveX crap in here. Need IE 6 to die first. + var xhr, i, progId; + if (typeof XMLHttpRequest !== "undefined") { + return new XMLHttpRequest(); + } else { + for (i = 0; i < 3; i++) { + progId = progIds[i]; + try { + xhr = new ActiveXObject(progId); + } catch (e) {} + + if (xhr) { + progIds = [progId]; // so faster next time + break; + } + } + } + + if (!xhr) { + throw new Error("getXhr(): XMLHttpRequest not available"); + } + + return xhr; + }; + + fetchText = function (url, callback) { + var xhr = getXhr(); + xhr.open('GET', url, true); + xhr.onreadystatechange = function (evt) { + //Do not explicitly handle errors, those should be + //visible via console output in the browser. + if (xhr.readyState === 4) { + callback(xhr.responseText); + } + }; + xhr.send(null); + }; + // end browser.js adapters + } else if (typeof Packages !== 'undefined') { + //Why Java, why is this so awkward? + fetchText = function (path, callback) { + var encoding = "utf-8", + file = new java.io.File(path), + lineSeparator = java.lang.System.getProperty("line.separator"), + input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), + stringBuffer, line, + content = ''; + try { + stringBuffer = new java.lang.StringBuffer(); + line = input.readLine(); + + // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 + // http://www.unicode.org/faq/utf_bom.html + + // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 + if (line && line.length() && line.charAt(0) === 0xfeff) { + // Eat the BOM, since we've already found the encoding on this file, + // and we plan to concatenating this buffer with others; the BOM should + // only appear at the top of a file. + line = line.substring(1); + } + + stringBuffer.append(line); + + while ((line = input.readLine()) !== null) { + stringBuffer.append(lineSeparator); + stringBuffer.append(line); + } + //Make sure we return a JavaScript string and not a Java string. + content = String(stringBuffer.toString()); //String + } finally { + input.close(); + } + callback(content); + }; + } + + return { + get: function () { + return CoffeeScript; + }, + + write: function (pluginName, name, write) { + if (buildMap.hasOwnProperty(name)) { + var text = buildMap[name]; + write.asModule(pluginName + "!" + name, text); + } + }, + + version: '0.4.2', + + load: function (name, parentRequire, load, config) { + var path = parentRequire.toUrl(name + '.coffee'); + fetchText(path, function (text) { + + //Do CoffeeScript transform. + try { + text = CoffeeScript.compile(text, config.CoffeeScript); + } + catch (err) { + err.message = "In " + path + ", " + err.message; + throw(err); + } + + //Hold on to the transformed text if a build. + if (config.isBuild) { + buildMap[name] = text; + } + + //IE with conditional comments on cannot handle the + //sourceURL trick, so skip it if enabled. + /*@if (@_jscript) @else @*/ + if (!config.isBuild) { + text += "\r\n//@ sourceURL=" + path; + } + /*@end@*/ + + load.fromText(name, text); + + //Give result to load. Need to wait until the module + //is fully parse, which will happen after this + //execution. + parentRequire([name], function (value) { + load(value); + }); + }); + } + }; +}); diff --git a/node_modules/jasmine-node/lib/jasmine-node/index.js b/node_modules/jasmine-node/lib/jasmine-node/index.js new file mode 100755 index 0000000..625e81c --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/index.js @@ -0,0 +1,204 @@ +var fs = require('fs'); +var mkdirp = require('mkdirp'); +var util; +try { + util = require('util') +} catch(e) { + util = require('sys') +} + +var path = require('path'); + +var filename = __dirname + '/jasmine-1.3.1.js'; +var isWindowUndefined = typeof global.window === 'undefined'; +if (isWindowUndefined) { + global.window = { + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval + }; +} + +var src = fs.readFileSync(filename); +// Put jasmine in the global context, this is somewhat like running in a +// browser where every file will have access to `jasmine` +var jasmine = require('vm').runInThisContext(src + "\njasmine;", filename); + + +if (isWindowUndefined) { + delete global.window; +} +require("./async-callback"); +require("jasmine-reporters"); +var nodeReporters = require('./reporter').jasmineNode; +jasmine.TerminalVerboseReporter = nodeReporters.TerminalVerboseReporter; +jasmine.TerminalReporter = nodeReporters.TerminalReporter; +jasmine.TeamcityReporter = nodeReporters.TeamcityReporter; +jasmine.GrowlReporter = require('jasmine-growl-reporter'); + + +jasmine.loadHelpersInFolder = function(folder, matcher) { + // Check to see if the folder is actually a file, if so, back up to the + // parent directory and find some helpers + folderStats = fs.statSync(folder); + if (folderStats.isFile()) { + folder = path.dirname(folder); + } + + var helpers = [], + helperCollection = require('./spec-collection'); + + helperCollection.load([folder], matcher); + helpers = helperCollection.getSpecs(); + + for (var i = 0, len = helpers.length; i < len; ++i) { + var file = helpers[i].path(); + + try { + var helper = require(file.replace(/\.*$/, "")); + } catch (e) { + console.log("Exception loading helper: " + file) + console.log(e); + throw e; // If any of the helpers fail to load, fail everything + } + + for (var key in helper) { + global[key]= helper[key]; + } + } +}; + +function removeJasmineFrames(text) { + if (!text) { + return text; + } + + var lines = []; + text.split(/\n/).forEach(function(line){ + if (line.indexOf(filename) == -1) { + lines.push(line); + } + }); + return lines.join('\n'); +} + +jasmine.executeSpecsInFolder = function(options){ + var folders = options['specFolders']; + var done = options['onComplete']; + var isVerbose = options['isVerbose']; + var showColors = options['showColors']; + var teamcity = options['teamcity']; + var useRequireJs = options['useRequireJs']; + var matcher = options['regExpSpec']; + var junitreport = options['junitreport']; + var includeStackTrace = options['includeStackTrace']; + var growl = options['growl']; + + // Overwriting it allows us to handle custom async specs + it = function(desc, func, timeout) { + return jasmine.getEnv().it(desc, func, timeout); + } + beforeEach = function(func, timeout) { + return jasmine.getEnv().beforeEach(func, timeout); + } + afterEach = function(func, timeout) { + return jasmine.getEnv().afterEach(func, timeout); + } + var fileMatcher = matcher || new RegExp(".(js)$", "i"), + colors = showColors || false, + specs = require('./spec-collection'), + jasmineEnv = jasmine.getEnv(); + + specs.load(folders, fileMatcher); + + if(junitreport && junitreport.report) { + var existsSync = fs.existsSync || path.existsSync; + if(!existsSync(junitreport.savePath)) { + util.puts('creating junit xml report save path: ' + junitreport.savePath); + mkdirp.sync(junitreport.savePath, "0755"); + } + jasmineEnv.addReporter(new jasmine.JUnitXmlReporter(junitreport.savePath, + junitreport.consolidate, + junitreport.useDotNotation)); + } + + if(teamcity){ + jasmineEnv.addReporter(new jasmine.TeamcityReporter({onComplete: done})); + } else if(isVerbose) { + jasmineEnv.addReporter(new jasmine.TerminalVerboseReporter({ print: print, + color: showColors, + onComplete: done, + stackFilter: removeJasmineFrames})); + } else { + jasmineEnv.addReporter(new jasmine.TerminalReporter({print: print, + color: showColors, + includeStackTrace: includeStackTrace, + onComplete: done, + stackFilter: removeJasmineFrames})); + } + + if (growl) { + jasmineEnv.addReporter(new jasmine.GrowlReporter()); + } + + if (useRequireJs) { + require('./requirejs-runner').executeJsRunner( + specs, + done, + jasmineEnv, + typeof useRequireJs === 'string' ? useRequireJs : null + ); + } else { + var specsList = specs.getSpecs(); + + for (var i = 0, len = specsList.length; i < len; ++i) { + var filename = specsList[i]; + delete require.cache[filename.path()]; + // Catch exceptions in loading the spec + try { + require(filename.path().replace(/\.\w+$/, "")); + } catch (e) { + console.log("Exception loading: " + filename.path()); + console.log(e); + throw e; + } + } + + jasmineEnv.execute(); + } +}; + +function now(){ + return new Date().getTime(); +} + +jasmine.asyncSpecWait = function(){ + var wait = jasmine.asyncSpecWait; + wait.start = now(); + wait.done = false; + (function innerWait(){ + waits(10); + runs(function() { + if (wait.start + wait.timeout < now()) { + expect('timeout waiting for spec').toBeNull(); + } else if (wait.done) { + wait.done = false; + } else { + innerWait(); + } + }); + })(); +}; +jasmine.asyncSpecWait.timeout = 4 * 1000; +jasmine.asyncSpecDone = function(){ + jasmine.asyncSpecWait.done = true; +}; + +function print(str) { + process.stdout.write(util.format(str)); +} + +for ( var key in jasmine) { + exports[key] = jasmine[key]; +} diff --git a/node_modules/jasmine-node/lib/jasmine-node/jasmine-1.3.1.js b/node_modules/jasmine-node/lib/jasmine-node/jasmine-1.3.1.js new file mode 100644 index 0000000..3cb32a8 --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/jasmine-1.3.1.js @@ -0,0 +1,2683 @@ +var isCommonJS = typeof window == "undefined" && typeof exports == "object"; + +/** + * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. + * + * @namespace + */ +var jasmine = {}; +if (isCommonJS) exports.jasmine = jasmine; +/** + * @private + */ +jasmine.unimplementedMethod_ = function() { + throw new Error("unimplemented method"); +}; + +/** + * Use jasmine.undefined instead of undefined, since undefined is just + * a plain old variable and may be redefined by somebody else. + * + * @private + */ +jasmine.undefined = jasmine.___undefined___; + +/** + * Show diagnostic messages in the console if set to true + * + */ +jasmine.VERBOSE = false; + +/** + * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. + * + */ +jasmine.DEFAULT_UPDATE_INTERVAL = 250; + +/** + * Maximum levels of nesting that will be included when an object is pretty-printed + */ +jasmine.MAX_PRETTY_PRINT_DEPTH = 40; + +/** + * Default timeout interval in milliseconds for waitsFor() blocks. + */ +jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + +/** + * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite. + * Set to false to let the exception bubble up in the browser. + * + */ +jasmine.CATCH_EXCEPTIONS = true; + +jasmine.getGlobal = function() { + function getGlobal() { + return this; + } + + return getGlobal(); +}; + +/** + * Allows for bound functions to be compared. Internal use only. + * + * @ignore + * @private + * @param base {Object} bound 'this' for the function + * @param name {Function} function to find + */ +jasmine.bindOriginal_ = function(base, name) { + var original = base[name]; + if (original.apply) { + return function() { + return original.apply(base, arguments); + }; + } else { + // IE support + return jasmine.getGlobal()[name]; + } +}; + +jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); +jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); +jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); +jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); + +jasmine.MessageResult = function(values) { + this.type = 'log'; + this.values = values; + this.trace = new Error(); // todo: test better +}; + +jasmine.MessageResult.prototype.toString = function() { + var text = ""; + for (var i = 0; i < this.values.length; i++) { + if (i > 0) text += " "; + if (jasmine.isString_(this.values[i])) { + text += this.values[i]; + } else { + text += jasmine.pp(this.values[i]); + } + } + return text; +}; + +jasmine.ExpectationResult = function(params) { + this.type = 'expect'; + this.matcherName = params.matcherName; + this.passed_ = params.passed; + this.expected = params.expected; + this.actual = params.actual; + this.message = this.passed_ ? 'Passed.' : params.message; + + var trace = (params.trace || new Error(this.message)); + this.trace = this.passed_ ? '' : trace; +}; + +jasmine.ExpectationResult.prototype.toString = function () { + return this.message; +}; + +jasmine.ExpectationResult.prototype.passed = function () { + return this.passed_; +}; + +/** + * Getter for the Jasmine environment. Ensures one gets created + */ +jasmine.getEnv = function() { + var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); + return env; +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isArray_ = function(value) { + return jasmine.isA_("Array", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isString_ = function(value) { + return jasmine.isA_("String", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isNumber_ = function(value) { + return jasmine.isA_("Number", value); +}; + +/** + * @ignore + * @private + * @param {String} typeName + * @param value + * @returns {Boolean} + */ +jasmine.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; +}; + +/** + * Pretty printer for expecations. Takes any object and turns it into a human-readable string. + * + * @param value {Object} an object to be outputted + * @returns {String} + */ +jasmine.pp = function(value) { + var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; +}; + +/** + * Returns true if the object is a DOM Node. + * + * @param {Object} obj object to check + * @returns {Boolean} + */ +jasmine.isDomNode = function(obj) { + return obj.nodeType > 0; +}; + +/** + * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. + * + * @example + * // don't care about which function is passed in, as long as it's a function + * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); + * + * @param {Class} clazz + * @returns matchable object of the type clazz + */ +jasmine.any = function(clazz) { + return new jasmine.Matchers.Any(clazz); +}; + +/** + * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the + * attributes on the object. + * + * @example + * // don't care about any other attributes than foo. + * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); + * + * @param sample {Object} sample + * @returns matchable object for the sample + */ +jasmine.objectContaining = function (sample) { + return new jasmine.Matchers.ObjectContaining(sample); +}; + +/** + * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. + * + * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine + * expectation syntax. Spies can be checked if they were called or not and what the calling params were. + * + * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). + * + * Spies are torn down at the end of every spec. + * + * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. + * + * @example + * // a stub + * var myStub = jasmine.createSpy('myStub'); // can be used anywhere + * + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // actual foo.not will not be called, execution stops + * spyOn(foo, 'not'); + + // foo.not spied upon, execution will continue to implementation + * spyOn(foo, 'not').andCallThrough(); + * + * // fake example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // foo.not(val) will return val + * spyOn(foo, 'not').andCallFake(function(value) {return value;}); + * + * // mock example + * foo.not(7 == 7); + * expect(foo.not).toHaveBeenCalled(); + * expect(foo.not).toHaveBeenCalledWith(true); + * + * @constructor + * @see spyOn, jasmine.createSpy, jasmine.createSpyObj + * @param {String} name + */ +jasmine.Spy = function(name) { + /** + * The name of the spy, if provided. + */ + this.identity = name || 'unknown'; + /** + * Is this Object a spy? + */ + this.isSpy = true; + /** + * The actual function this spy stubs. + */ + this.plan = function() { + }; + /** + * Tracking of the most recent call to the spy. + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy.mostRecentCall.args = [1, 2]; + */ + this.mostRecentCall = {}; + + /** + * Holds arguments for each call to the spy, indexed by call count + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy(7, 8); + * mySpy.mostRecentCall.args = [7, 8]; + * mySpy.argsForCall[0] = [1, 2]; + * mySpy.argsForCall[1] = [7, 8]; + */ + this.argsForCall = []; + this.calls = []; +}; + +/** + * Tells a spy to call through to the actual implementation. + * + * @example + * var foo = { + * bar: function() { // do some stuff } + * } + * + * // defining a spy on an existing property: foo.bar + * spyOn(foo, 'bar').andCallThrough(); + */ +jasmine.Spy.prototype.andCallThrough = function() { + this.plan = this.originalValue; + return this; +}; + +/** + * For setting the return value of a spy. + * + * @example + * // defining a spy from scratch: foo() returns 'baz' + * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); + * + * // defining a spy on an existing property: foo.bar() returns 'baz' + * spyOn(foo, 'bar').andReturn('baz'); + * + * @param {Object} value + */ +jasmine.Spy.prototype.andReturn = function(value) { + this.plan = function() { + return value; + }; + return this; +}; + +/** + * For throwing an exception when a spy is called. + * + * @example + * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' + * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); + * + * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' + * spyOn(foo, 'bar').andThrow('baz'); + * + * @param {String} exceptionMsg + */ +jasmine.Spy.prototype.andThrow = function(exceptionMsg) { + this.plan = function() { + throw exceptionMsg; + }; + return this; +}; + +/** + * Calls an alternate implementation when a spy is called. + * + * @example + * var baz = function() { + * // do some stuff, return something + * } + * // defining a spy from scratch: foo() calls the function baz + * var foo = jasmine.createSpy('spy on foo').andCall(baz); + * + * // defining a spy on an existing property: foo.bar() calls an anonymnous function + * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); + * + * @param {Function} fakeFunc + */ +jasmine.Spy.prototype.andCallFake = function(fakeFunc) { + this.plan = fakeFunc; + return this; +}; + +/** + * Resets all of a spy's the tracking variables so that it can be used again. + * + * @example + * spyOn(foo, 'bar'); + * + * foo.bar(); + * + * expect(foo.bar.callCount).toEqual(1); + * + * foo.bar.reset(); + * + * expect(foo.bar.callCount).toEqual(0); + */ +jasmine.Spy.prototype.reset = function() { + this.wasCalled = false; + this.callCount = 0; + this.argsForCall = []; + this.calls = []; + this.mostRecentCall = {}; +}; + +jasmine.createSpy = function(name) { + + var spyObj = function() { + spyObj.wasCalled = true; + spyObj.callCount++; + var args = jasmine.util.argsToArray(arguments); + spyObj.mostRecentCall.object = this; + spyObj.mostRecentCall.args = args; + spyObj.argsForCall.push(args); + spyObj.calls.push({object: this, args: args}); + return spyObj.plan.apply(this, arguments); + }; + + var spy = new jasmine.Spy(name); + + for (var prop in spy) { + spyObj[prop] = spy[prop]; + } + + spyObj.reset(); + + return spyObj; +}; + +/** + * Determines whether an object is a spy. + * + * @param {jasmine.Spy|Object} putativeSpy + * @returns {Boolean} + */ +jasmine.isSpy = function(putativeSpy) { + return putativeSpy && putativeSpy.isSpy; +}; + +/** + * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something + * large in one call. + * + * @param {String} baseName name of spy class + * @param {Array} methodNames array of names of methods to make spies + */ +jasmine.createSpyObj = function(baseName, methodNames) { + if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { + throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); + } + return obj; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the current spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.log = function() { + var spec = jasmine.getEnv().currentSpec; + spec.log.apply(spec, arguments); +}; + +/** + * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. + * + * @example + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops + * + * @see jasmine.createSpy + * @param obj + * @param methodName + * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods + */ +var spyOn = function(obj, methodName) { + return jasmine.getEnv().currentSpec.spyOn(obj, methodName); +}; +if (isCommonJS) exports.spyOn = spyOn; + +/** + * Creates a Jasmine spec that will be added to the current suite. + * + * // TODO: pending tests + * + * @example + * it('should be true', function() { + * expect(true).toEqual(true); + * }); + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var it = function(desc, func) { + return jasmine.getEnv().it(desc, func); +}; +if (isCommonJS) exports.it = it; + +/** + * Creates an exclusive Jasmine spec that will be added to the current suite. + * + * If at least one exclusive (iit) spec is registered, only these exclusive specs are run. + * Note, that this behavior works only with the default specFilter. + * Note, that iit has higher priority over ddescribe + * + * @example + * describe('suite', function() { + * iit('should be true', function() { + * // only this spec will be run + * }); + * + * it('should be false', function() { + * // this won't be run + * }); + * }); + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var iit = function(desc, func) { + return jasmine.getEnv().iit(desc, func); +}; +if (isCommonJS) exports.iit = iit; + +/** + * Creates a disabled Jasmine spec. + * + * A convenience method that allows existing specs to be disabled temporarily during development. + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var xit = function(desc, func) { + return jasmine.getEnv().xit(desc, func); +}; +if (isCommonJS) exports.xit = xit; + +/** + * Starts a chain for a Jasmine expectation. + * + * It is passed an Object that is the actual value and should chain to one of the many + * jasmine.Matchers functions. + * + * @param {Object} actual Actual value to test against and expected value + * @return {jasmine.Matchers} + */ +var expect = function(actual) { + return jasmine.getEnv().currentSpec.expect(actual); +}; +if (isCommonJS) exports.expect = expect; + +/** + * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. + * + * @param {Function} func Function that defines part of a jasmine spec. + */ +var runs = function(func) { + jasmine.getEnv().currentSpec.runs(func); +}; +if (isCommonJS) exports.runs = runs; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +var waits = function(timeout) { + jasmine.getEnv().currentSpec.waits(timeout); +}; +if (isCommonJS) exports.waits = waits; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); +}; +if (isCommonJS) exports.waitsFor = waitsFor; + +/** + * A function that is called before each spec in a suite. + * + * Used for spec setup, including validating assumptions. + * + * @param {Function} beforeEachFunction + */ +var beforeEach = function(beforeEachFunction) { + jasmine.getEnv().beforeEach(beforeEachFunction); +}; +if (isCommonJS) exports.beforeEach = beforeEach; + +/** + * A function that is called after each spec in a suite. + * + * Used for restoring any state that is hijacked during spec execution. + * + * @param {Function} afterEachFunction + */ +var afterEach = function(afterEachFunction) { + jasmine.getEnv().afterEach(afterEachFunction); +}; +if (isCommonJS) exports.afterEach = afterEach; + +/** + * Defines a suite of specifications. + * + * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared + * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization + * of setup in some tests. + * + * @example + * // TODO: a simple suite + * + * // TODO: a simple suite with a nested describe block + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var describe = function(description, specDefinitions) { + return jasmine.getEnv().describe(description, specDefinitions); +}; +if (isCommonJS) exports.describe = describe; + + +/** + * Defines an exclusive suite of specifications. + * + * If at least one exclusive (ddescribe) suite is registered, only these exclusive suites are run. + * Note, that this behavior works only with the default specFilter. + * + * @example + * ddescribe('exclusive suite', function() { + * it('should be true', function() { + * // this spec will be run + * }); + * + * it('should be false', function() { + * // this spec will be run as well + * }); + * }); + * + * describe('normal suite', function() { + * // no spec from this suite will be run + * }); + * + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var ddescribe = function(description, specDefinitions) { + return jasmine.getEnv().ddescribe(description, specDefinitions); +}; +if (isCommonJS) exports.ddescribe = ddescribe; + +/** + * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var xdescribe = function(description, specDefinitions) { + return jasmine.getEnv().xdescribe(description, specDefinitions); +}; +if (isCommonJS) exports.xdescribe = xdescribe; + + +// Provide the XMLHttpRequest class for IE 5.x-6.x: +jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { + function tryIt(f) { + try { + return f(); + } catch(e) { + } + return null; + } + + var xhr = tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP.6.0"); + }) || + tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP.3.0"); + }) || + tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP"); + }) || + tryIt(function() { + return new ActiveXObject("Microsoft.XMLHTTP"); + }); + + if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); + + return xhr; +} : XMLHttpRequest; +/** + * @namespace + */ +jasmine.util = {}; + +/** + * Declare that a child class inherit it's prototype from the parent class. + * + * @private + * @param {Function} childClass + * @param {Function} parentClass + */ +jasmine.util.inherit = function(childClass, parentClass) { + /** + * @private + */ + var subclass = function() { + }; + subclass.prototype = parentClass.prototype; + childClass.prototype = new subclass(); +}; + +jasmine.util.formatException = function(e) { + var lineNumber; + if (e.line) { + lineNumber = e.line; + } + else if (e.lineNumber) { + lineNumber = e.lineNumber; + } + + var file; + + if (e.sourceURL) { + file = e.sourceURL; + } + else if (e.fileName) { + file = e.fileName; + } + + var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); + + if (file && lineNumber) { + message += ' in ' + file + ' (line ' + lineNumber + ')'; + } + + return message; +}; + +jasmine.util.htmlEscape = function(str) { + if (!str) return str; + return str.replace(/&/g, '&') + .replace(//g, '>'); +}; + +jasmine.util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); + return arrayOfArgs; +}; + +jasmine.util.extend = function(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; +}; + +/** + * Environment for Jasmine + * + * @constructor + */ +jasmine.Env = function() { + this.currentSpec = null; + this.currentSuite = null; + this.currentRunner_ = new jasmine.Runner(this); + + this.reporter = new jasmine.MultiReporter(); + + this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; + this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; + this.lastUpdate = 0; + this.specFilter = function(spec) { + return this.exclusive_ <= spec.exclusive_; + }; + + this.nextSpecId_ = 0; + this.nextSuiteId_ = 0; + this.equalityTesters_ = []; + + // 0 - normal + // 1 - contains some ddescribe + // 2 - contains some iit + this.exclusive_ = 0; + + // wrap matchers + this.matchersClass = function() { + jasmine.Matchers.apply(this, arguments); + }; + jasmine.util.inherit(this.matchersClass, jasmine.Matchers); + + jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); +}; + + +jasmine.Env.prototype.setTimeout = jasmine.setTimeout; +jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; +jasmine.Env.prototype.setInterval = jasmine.setInterval; +jasmine.Env.prototype.clearInterval = jasmine.clearInterval; + +/** + * @returns an object containing jasmine version build info, if set. + */ +jasmine.Env.prototype.version = function () { + if (jasmine.version_) { + return jasmine.version_; + } else { + throw new Error('Version not set'); + } +}; + +/** + * @returns string containing jasmine version build info, if set. + */ +jasmine.Env.prototype.versionString = function() { + if (!jasmine.version_) { + return "version unknown"; + } + + var version = this.version(); + var versionString = version.major + "." + version.minor + "." + version.build; + if (version.release_candidate) { + versionString += ".rc" + version.release_candidate; + } + versionString += " revision " + version.revision; + return versionString; +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSpecId = function () { + return this.nextSpecId_++; +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSuiteId = function () { + return this.nextSuiteId_++; +}; + +/** + * Register a reporter to receive status updates from Jasmine. + * @param {jasmine.Reporter} reporter An object which will receive status updates. + */ +jasmine.Env.prototype.addReporter = function(reporter) { + this.reporter.addReporter(reporter); +}; + +jasmine.Env.prototype.execute = function() { + this.currentRunner_.execute(); +}; + +jasmine.Env.prototype.describe = function(description, specDefinitions) { + var suite = new jasmine.Suite(this, description, null, this.currentSuite); + return this.describe_(suite, specDefinitions); +}; + +jasmine.Env.prototype.describe_ = function(suite, specDefinitions) { + var parentSuite = this.currentSuite; + if (parentSuite) { + parentSuite.add(suite); + } else { + this.currentRunner_.add(suite); + } + + this.currentSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch(e) { + declarationError = e; + } + + if (declarationError) { + this.it("encountered a declaration exception", function() { + throw declarationError; + }); + } + + this.currentSuite = parentSuite; + + return suite; +}; + +jasmine.Env.prototype.ddescribe = function(description, specDefinitions) { + var suite = new jasmine.Suite(this, description, null, this.currentSuite); + suite.exclusive_ = 1; + this.exclusive_ = Math.max(this.exclusive_, 1); + + return this.describe_(suite, specDefinitions); +}; + +jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { + if (this.currentSuite) { + this.currentSuite.beforeEach(beforeEachFunction); + } else { + this.currentRunner_.beforeEach(beforeEachFunction); + } +}; + +jasmine.Env.prototype.currentRunner = function () { + return this.currentRunner_; +}; + +jasmine.Env.prototype.afterEach = function(afterEachFunction) { + if (this.currentSuite) { + this.currentSuite.afterEach(afterEachFunction); + } else { + this.currentRunner_.afterEach(afterEachFunction); + } + +}; + +jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { + return { + execute: function() { + } + }; +}; + +jasmine.Env.prototype.it = function(description, func) { + var spec = new jasmine.Spec(this, this.currentSuite, description); + this.currentSuite.add(spec); + this.currentSpec = spec; + + if (func) { + spec.runs(func); + } + + return spec; +}; + +jasmine.Env.prototype.iit = function(description, func) { + var spec = this.it(description, func); + spec.exclusive_ = 2; + this.exclusive_ = 2; + + return spec; +}; + +jasmine.Env.prototype.xit = function(desc, func) { + return { + id: this.nextSpecId(), + runs: function() { + } + }; +}; + +jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) { + if (a.source != b.source) + mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/"); + + if (a.ignoreCase != b.ignoreCase) + mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier"); + + if (a.global != b.global) + mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier"); + + if (a.multiline != b.multiline) + mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier"); + + if (a.sticky != b.sticky) + mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier"); + + return (mismatchValues.length === 0); +}; + +jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { + if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { + return true; + } + + a.__Jasmine_been_here_before__ = b; + b.__Jasmine_been_here_before__ = a; + + var hasKey = function(obj, keyName) { + return obj !== null && obj[keyName] !== jasmine.undefined; + }; + + for (var property in b) { + if (!hasKey(a, property) && hasKey(b, property)) { + mismatchKeys.push("expected has key '" + property + "', but missing from actual."); + } + } + for (property in a) { + if (!hasKey(b, property) && hasKey(a, property)) { + mismatchKeys.push("expected missing key '" + property + "', but present in actual."); + } + } + for (property in b) { + if (property == '__Jasmine_been_here_before__') continue; + if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { + mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); + } + } + + if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { + mismatchValues.push("arrays were not the same length"); + } + + delete a.__Jasmine_been_here_before__; + delete b.__Jasmine_been_here_before__; + return (mismatchKeys.length === 0 && mismatchValues.length === 0); +}; + +jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { + mismatchKeys = mismatchKeys || []; + mismatchValues = mismatchValues || []; + + for (var i = 0; i < this.equalityTesters_.length; i++) { + var equalityTester = this.equalityTesters_[i]; + var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); + if (result !== jasmine.undefined) return result; + } + + if (a === b) return true; + + if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { + return (a == jasmine.undefined && b == jasmine.undefined); + } + + if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { + return a === b; + } + + if (a instanceof Date && b instanceof Date) { + return a.getTime() == b.getTime(); + } + + if (a.jasmineMatches) { + return a.jasmineMatches(b); + } + + if (b.jasmineMatches) { + return b.jasmineMatches(a); + } + + if (a instanceof jasmine.Matchers.ObjectContaining) { + return a.matches(b); + } + + if (b instanceof jasmine.Matchers.ObjectContaining) { + return b.matches(a); + } + + if (jasmine.isString_(a) && jasmine.isString_(b)) { + return (a == b); + } + + if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { + return (a == b); + } + + if (a instanceof RegExp && b instanceof RegExp) { + return this.compareRegExps_(a, b, mismatchKeys, mismatchValues); + } + + if (typeof a === "object" && typeof b === "object") { + return this.compareObjects_(a, b, mismatchKeys, mismatchValues); + } + + //Straight check + return (a === b); +}; + +jasmine.Env.prototype.contains_ = function(haystack, needle) { + if (jasmine.isArray_(haystack)) { + for (var i = 0; i < haystack.length; i++) { + if (this.equals_(haystack[i], needle)) return true; + } + return false; + } + return haystack.indexOf(needle) >= 0; +}; + +jasmine.Env.prototype.addEqualityTester = function(equalityTester) { + this.equalityTesters_.push(equalityTester); +}; +/** No-op base class for Jasmine reporters. + * + * @constructor + */ +jasmine.Reporter = function() { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerResults = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecStarting = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecResults = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.log = function(str) { +}; + +/** + * Blocks are functions with executable code that make up a spec. + * + * @constructor + * @param {jasmine.Env} env + * @param {Function} func + * @param {jasmine.Spec} spec + */ +jasmine.Block = function(env, func, spec) { + this.env = env; + this.func = func; + this.spec = spec; +}; + +jasmine.Block.prototype.execute = function(onComplete) { + if (!jasmine.CATCH_EXCEPTIONS) { + this.func.apply(this.spec); + } + else { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } + } + onComplete(); +}; +/** JavaScript API reporter. + * + * @constructor + */ +jasmine.JsApiReporter = function() { + this.started = false; + this.finished = false; + this.suites_ = []; + this.results_ = {}; +}; + +jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { + this.started = true; + var suites = runner.topLevelSuites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + this.suites_.push(this.summarize_(suite)); + } +}; + +jasmine.JsApiReporter.prototype.suites = function() { + return this.suites_; +}; + +jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { + var isSuite = suiteOrSpec instanceof jasmine.Suite; + var summary = { + id: suiteOrSpec.id, + name: suiteOrSpec.description, + type: isSuite ? 'suite' : 'spec', + children: [] + }; + + if (isSuite) { + var children = suiteOrSpec.children(); + for (var i = 0; i < children.length; i++) { + summary.children.push(this.summarize_(children[i])); + } + } + return summary; +}; + +jasmine.JsApiReporter.prototype.results = function() { + return this.results_; +}; + +jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { + return this.results_[specId]; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { + this.finished = true; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { + this.results_[spec.id] = { + messages: spec.results().getItems(), + result: spec.results().failedCount > 0 ? "failed" : "passed" + }; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.log = function(str) { +}; + +jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ + var results = {}; + for (var i = 0; i < specIds.length; i++) { + var specId = specIds[i]; + results[specId] = this.summarizeResult_(this.results_[specId]); + } + return results; +}; + +jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ + var summaryMessages = []; + var messagesLength = result.messages.length; + for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { + var resultMessage = result.messages[messageIndex]; + summaryMessages.push({ + text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, + passed: resultMessage.passed ? resultMessage.passed() : true, + type: resultMessage.type, + message: resultMessage.message, + trace: { + stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined + } + }); + } + + return { + result : result.result, + messages : summaryMessages + }; +}; + +/** + * @constructor + * @param {jasmine.Env} env + * @param actual + * @param {jasmine.Spec} spec + */ +jasmine.Matchers = function(env, actual, spec, opt_isNot) { + this.env = env; + this.actual = actual; + this.spec = spec; + this.isNot = opt_isNot || false; + this.reportWasCalled_ = false; +}; + +// todo: @deprecated as of Jasmine 0.11, remove soon [xw] +jasmine.Matchers.pp = function(str) { + throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); +}; + +// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] +jasmine.Matchers.prototype.report = function(result, failing_message, details) { + throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); +}; + +jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { + for (var methodName in prototype) { + if (methodName == 'report') continue; + var orig = prototype[methodName]; + matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); + } +}; + +jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { + return function() { + var matcherArgs = jasmine.util.argsToArray(arguments); + var result = matcherFunction.apply(this, arguments); + + if (this.isNot) { + result = !result; + } + + if (this.reportWasCalled_) return result; + + var message; + if (!result) { + if (this.message) { + message = this.message.apply(this, arguments); + if (jasmine.isArray_(message)) { + message = message[this.isNot ? 1 : 0]; + } + } else { + var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; + if (matcherArgs.length > 0) { + for (var i = 0; i < matcherArgs.length; i++) { + if (i > 0) message += ","; + message += " " + jasmine.pp(matcherArgs[i]); + } + } + message += "."; + } + } + var expectationResult = new jasmine.ExpectationResult({ + matcherName: matcherName, + passed: result, + expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], + actual: this.actual, + message: message + }); + this.spec.addMatcherResult(expectationResult); + return jasmine.undefined; + }; +}; + + + + +/** + * toBe: compares the actual to the expected using === + * @param expected + */ +jasmine.Matchers.prototype.toBe = function(expected) { + return this.actual === expected; +}; + +/** + * toNotBe: compares the actual to the expected using !== + * @param expected + * @deprecated as of 1.0. Use not.toBe() instead. + */ +jasmine.Matchers.prototype.toNotBe = function(expected) { + return this.actual !== expected; +}; + +/** + * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. + * + * @param expected + */ +jasmine.Matchers.prototype.toEqual = function(expected) { + return this.env.equals_(this.actual, expected); +}; + +/** + * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual + * @param expected + * @deprecated as of 1.0. Use not.toEqual() instead. + */ +jasmine.Matchers.prototype.toNotEqual = function(expected) { + return !this.env.equals_(this.actual, expected); +}; + +/** + * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes + * a pattern or a String. + * + * @param expected + */ +jasmine.Matchers.prototype.toMatch = function(expected) { + return new RegExp(expected).test(this.actual); +}; + +/** + * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch + * @param expected + * @deprecated as of 1.0. Use not.toMatch() instead. + */ +jasmine.Matchers.prototype.toNotMatch = function(expected) { + return !(new RegExp(expected).test(this.actual)); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeDefined = function() { + return (this.actual !== jasmine.undefined); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeUndefined = function() { + return (this.actual === jasmine.undefined); +}; + +/** + * Matcher that compares the actual to null. + */ +jasmine.Matchers.prototype.toBeNull = function() { + return (this.actual === null); +}; + +/** + * Matcher that compares the actual to NaN. + */ +jasmine.Matchers.prototype.toBeNaN = function() { + this.message = function() { + return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ]; + }; + + return (this.actual !== this.actual); +}; + +/** + * Matcher that boolean not-nots the actual. + */ +jasmine.Matchers.prototype.toBeTruthy = function() { + return !!this.actual; +}; + + +/** + * Matcher that boolean nots the actual. + */ +jasmine.Matchers.prototype.toBeFalsy = function() { + return !this.actual; +}; + + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called. + */ +jasmine.Matchers.prototype.toHaveBeenCalled = function() { + if (arguments.length > 0) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to have been called.", + "Expected spy " + this.actual.identity + " not to have been called." + ]; + }; + + return this.actual.wasCalled; +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ +jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was not called. + * + * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead + */ +jasmine.Matchers.prototype.wasNotCalled = function() { + if (arguments.length > 0) { + throw new Error('wasNotCalled does not take arguments'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to not have been called.", + "Expected spy " + this.actual.identity + " to have been called." + ]; + }; + + return !this.actual.wasCalled; +}; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. + * + * @example + * + */ +jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + this.message = function() { + var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."; + var positiveMessage = ""; + if (this.actual.callCount === 0) { + positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called."; + } else { + positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '') + } + return [positiveMessage, invertedMessage]; + }; + + return this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; + +/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasNotCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" + ]; + }; + + return !this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** + * Matcher that checks that the expected item is an element in the actual Array. + * + * @param {Object} expected + */ +jasmine.Matchers.prototype.toContain = function(expected) { + return this.env.contains_(this.actual, expected); +}; + +/** + * Matcher that checks that the expected item is NOT an element in the actual Array. + * + * @param {Object} expected + * @deprecated as of 1.0. Use not.toContain() instead. + */ +jasmine.Matchers.prototype.toNotContain = function(expected) { + return !this.env.contains_(this.actual, expected); +}; + +jasmine.Matchers.prototype.toBeLessThan = function(expected) { + return this.actual < expected; +}; + +jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { + return this.actual > expected; +}; + +/** + * Matcher that checks that the expected item is equal to the actual item + * up to a given level of decimal precision (default 2). + * + * @param {Number} expected + * @param {Number} precision, as number of decimal places + */ +jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { + if (!(precision === 0)) { + precision = precision || 2; + } + return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2); +}; + +/** + * Matcher that checks that the expected exception was thrown by the actual. + * + * @param {String} [expected] + */ +jasmine.Matchers.prototype.toThrow = function(expected) { + var result = false; + var exception; + if (typeof this.actual != 'function') { + throw new Error('Actual is not a function'); + } + try { + this.actual(); + } catch (e) { + exception = e; + } + if (exception) { + result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); + } + + var not = this.isNot ? "not " : ""; + + this.message = function() { + if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { + return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); + } else { + return "Expected function to throw an exception."; + } + }; + + return result; +}; + +jasmine.Matchers.Any = function(expectedClass) { + this.expectedClass = expectedClass; +}; + +jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { + if (this.expectedClass == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedClass == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedClass == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedClass == Object) { + return typeof other == 'object'; + } + + return other instanceof this.expectedClass; +}; + +jasmine.Matchers.Any.prototype.jasmineToString = function() { + return ''; +}; + +jasmine.Matchers.ObjectContaining = function (sample) { + this.sample = sample; +}; + +jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { + mismatchKeys = mismatchKeys || []; + mismatchValues = mismatchValues || []; + + var env = jasmine.getEnv(); + + var hasKey = function(obj, keyName) { + return obj != null && obj[keyName] !== jasmine.undefined; + }; + + for (var property in this.sample) { + if (!hasKey(other, property) && hasKey(this.sample, property)) { + mismatchKeys.push("expected has key '" + property + "', but missing from actual."); + } + else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) { + mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual."); + } + } + + return (mismatchKeys.length === 0 && mismatchValues.length === 0); +}; + +jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { + return ""; +}; +// Mock setTimeout, clearTimeout +// Contributed by Pivotal Computer Systems, www.pivotalsf.com + +jasmine.FakeTimer = function() { + this.reset(); + + var self = this; + self.setTimeout = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); + return self.timeoutsMade; + }; + + self.setInterval = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); + return self.timeoutsMade; + }; + + self.clearTimeout = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + + self.clearInterval = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + +}; + +jasmine.FakeTimer.prototype.reset = function() { + this.timeoutsMade = 0; + this.scheduledFunctions = {}; + this.nowMillis = 0; +}; + +jasmine.FakeTimer.prototype.tick = function(millis) { + var oldMillis = this.nowMillis; + var newMillis = oldMillis + millis; + this.runFunctionsWithinRange(oldMillis, newMillis); + this.nowMillis = newMillis; +}; + +jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { + var scheduledFunc; + var funcsToRun = []; + for (var timeoutKey in this.scheduledFunctions) { + scheduledFunc = this.scheduledFunctions[timeoutKey]; + if (scheduledFunc != jasmine.undefined && + scheduledFunc.runAtMillis >= oldMillis && + scheduledFunc.runAtMillis <= nowMillis) { + funcsToRun.push(scheduledFunc); + this.scheduledFunctions[timeoutKey] = jasmine.undefined; + } + } + + if (funcsToRun.length > 0) { + funcsToRun.sort(function(a, b) { + return a.runAtMillis - b.runAtMillis; + }); + for (var i = 0; i < funcsToRun.length; ++i) { + try { + var funcToRun = funcsToRun[i]; + this.nowMillis = funcToRun.runAtMillis; + funcToRun.funcToCall(); + if (funcToRun.recurring) { + this.scheduleFunction(funcToRun.timeoutKey, + funcToRun.funcToCall, + funcToRun.millis, + true); + } + } catch(e) { + } + } + this.runFunctionsWithinRange(oldMillis, nowMillis); + } +}; + +jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { + this.scheduledFunctions[timeoutKey] = { + runAtMillis: this.nowMillis + millis, + funcToCall: funcToCall, + recurring: recurring, + timeoutKey: timeoutKey, + millis: millis + }; +}; + +/** + * @namespace + */ +jasmine.Clock = { + defaultFakeTimer: new jasmine.FakeTimer(), + + reset: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.reset(); + }, + + tick: function(millis) { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.tick(millis); + }, + + runFunctionsWithinRange: function(oldMillis, nowMillis) { + jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); + }, + + scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { + jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); + }, + + useMock: function() { + if (!jasmine.Clock.isInstalled()) { + var spec = jasmine.getEnv().currentSpec; + spec.after(jasmine.Clock.uninstallMock); + + jasmine.Clock.installMock(); + } + }, + + installMock: function() { + jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; + }, + + uninstallMock: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.installed = jasmine.Clock.real; + }, + + real: { + setTimeout: jasmine.getGlobal().setTimeout, + clearTimeout: jasmine.getGlobal().clearTimeout, + setInterval: jasmine.getGlobal().setInterval, + clearInterval: jasmine.getGlobal().clearInterval + }, + + assertInstalled: function() { + if (!jasmine.Clock.isInstalled()) { + throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); + } + }, + + isInstalled: function() { + return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; + }, + + installed: null +}; +jasmine.Clock.installed = jasmine.Clock.real; + +//else for IE support +jasmine.getGlobal().setTimeout = function(funcToCall, millis) { + if (jasmine.Clock.installed.setTimeout.apply) { + return jasmine.Clock.installed.setTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.setTimeout(funcToCall, millis); + } +}; + +jasmine.getGlobal().setInterval = function(funcToCall, millis) { + if (jasmine.Clock.installed.setInterval.apply) { + return jasmine.Clock.installed.setInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.setInterval(funcToCall, millis); + } +}; + +jasmine.getGlobal().clearTimeout = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearTimeout(timeoutKey); + } +}; + +jasmine.getGlobal().clearInterval = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearInterval(timeoutKey); + } +}; + +/** + * @constructor + */ +jasmine.MultiReporter = function() { + this.subReporters_ = []; +}; +jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); + +jasmine.MultiReporter.prototype.addReporter = function(reporter) { + this.subReporters_.push(reporter); +}; + +(function() { + var functionNames = [ + "reportRunnerStarting", + "reportRunnerResults", + "reportSuiteResults", + "reportSpecStarting", + "reportSpecResults", + "log" + ]; + for (var i = 0; i < functionNames.length; i++) { + var functionName = functionNames[i]; + jasmine.MultiReporter.prototype[functionName] = (function(functionName) { + return function() { + for (var j = 0; j < this.subReporters_.length; j++) { + var subReporter = this.subReporters_[j]; + if (subReporter[functionName]) { + subReporter[functionName].apply(subReporter, arguments); + } + } + }; + })(functionName); + } +})(); +/** + * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults + * + * @constructor + */ +jasmine.NestedResults = function() { + /** + * The total count of results + */ + this.totalCount = 0; + /** + * Number of passed results + */ + this.passedCount = 0; + /** + * Number of failed results + */ + this.failedCount = 0; + /** + * Was this suite/spec skipped? + */ + this.skipped = false; + /** + * @ignore + */ + this.items_ = []; +}; + +/** + * Roll up the result counts. + * + * @param result + */ +jasmine.NestedResults.prototype.rollupCounts = function(result) { + this.totalCount += result.totalCount; + this.passedCount += result.passedCount; + this.failedCount += result.failedCount; +}; + +/** + * Adds a log message. + * @param values Array of message parts which will be concatenated later. + */ +jasmine.NestedResults.prototype.log = function(values) { + this.items_.push(new jasmine.MessageResult(values)); +}; + +/** + * Getter for the results: message & results. + */ +jasmine.NestedResults.prototype.getItems = function() { + return this.items_; +}; + +/** + * Adds a result, tracking counts (total, passed, & failed) + * @param {jasmine.ExpectationResult|jasmine.NestedResults} result + */ +jasmine.NestedResults.prototype.addResult = function(result) { + if (result.type != 'log') { + if (result.items_) { + this.rollupCounts(result); + } else { + this.totalCount++; + if (result.passed()) { + this.passedCount++; + } else { + this.failedCount++; + } + } + } + this.items_.push(result); +}; + +/** + * @returns {Boolean} True if everything below passed + */ +jasmine.NestedResults.prototype.passed = function() { + return this.passedCount === this.totalCount; +}; +/** + * Base class for pretty printing for expectation results. + */ +jasmine.PrettyPrinter = function() { + this.ppNestLevel_ = 0; +}; + +/** + * Formats a value in a nice, human-readable string. + * + * @param value + */ +jasmine.PrettyPrinter.prototype.format = function(value) { + this.ppNestLevel_++; + try { + if (value === jasmine.undefined) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === jasmine.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (jasmine.isSpy(value)) { + this.emitScalar("spy on " + value.identity); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (value.__Jasmine_been_here_before__) { + this.emitScalar(''); + } else if (jasmine.isArray_(value) || typeof value == 'object') { + value.__Jasmine_been_here_before__ = true; + if (jasmine.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + delete value.__Jasmine_been_here_before__; + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } +}; + +jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (!obj.hasOwnProperty(property)) continue; + if (property == '__Jasmine_been_here_before__') continue; + fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && + obj.__lookupGetter__(property) !== null) : false); + } +}; + +jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; + +jasmine.StringPrettyPrinter = function() { + jasmine.PrettyPrinter.call(this); + + this.string = ''; +}; +jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); + +jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); +}; + +jasmine.StringPrettyPrinter.prototype.emitString = function(value) { + this.append("'" + value + "'"); +}; + +jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { + if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) { + this.append("Array"); + return; + } + + this.append('[ '); + for (var i = 0; i < array.length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + this.append(' ]'); +}; + +jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { + if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) { + this.append("Object"); + return; + } + + var self = this; + this.append('{ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(' : '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' }'); +}; + +jasmine.StringPrettyPrinter.prototype.append = function(value) { + this.string += value; +}; +jasmine.Queue = function(env) { + this.env = env; + + // parallel to blocks. each true value in this array means the block will + // get executed even if we abort + this.ensured = []; + this.blocks = []; + this.running = false; + this.index = 0; + this.offset = 0; + this.abort = false; +}; + +jasmine.Queue.prototype.addBefore = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + + this.blocks.unshift(block); + this.ensured.unshift(ensure); +}; + +jasmine.Queue.prototype.add = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + + this.blocks.push(block); + this.ensured.push(ensure); +}; + +jasmine.Queue.prototype.insertNext = function(block, ensure) { + if (ensure === jasmine.undefined) { + ensure = false; + } + + this.ensured.splice((this.index + this.offset + 1), 0, ensure); + this.blocks.splice((this.index + this.offset + 1), 0, block); + this.offset++; +}; + +jasmine.Queue.prototype.start = function(onComplete) { + this.running = true; + this.onComplete = onComplete; + this.next_(); +}; + +jasmine.Queue.prototype.isRunning = function() { + return this.running; +}; + +jasmine.Queue.LOOP_DONT_RECURSE = true; + +jasmine.Queue.prototype.next_ = function() { + var self = this; + var goAgain = true; + + while (goAgain) { + goAgain = false; + + if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) { + var calledSynchronously = true; + var completedSynchronously = false; + + var onComplete = function () { + if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { + completedSynchronously = true; + return; + } + + if (self.blocks[self.index].abort) { + self.abort = true; + } + + self.offset = 0; + self.index++; + + var now = new Date().getTime(); + if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { + self.env.lastUpdate = now; + self.env.setTimeout(function() { + self.next_(); + }, 0); + } else { + if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { + goAgain = true; + } else { + self.next_(); + } + } + }; + self.blocks[self.index].execute(onComplete); + + calledSynchronously = false; + if (completedSynchronously) { + onComplete(); + } + + } else { + self.running = false; + if (self.onComplete) { + self.onComplete(); + } + } + } +}; + +jasmine.Queue.prototype.results = function() { + var results = new jasmine.NestedResults(); + for (var i = 0; i < this.blocks.length; i++) { + if (this.blocks[i].results) { + results.addResult(this.blocks[i].results()); + } + } + return results; +}; + + +/** + * Runner + * + * @constructor + * @param {jasmine.Env} env + */ +jasmine.Runner = function(env) { + var self = this; + self.env = env; + self.queue = new jasmine.Queue(env); + self.before_ = []; + self.after_ = []; + self.suites_ = []; +}; + +jasmine.Runner.prototype.execute = function() { + var self = this; + if (self.env.reporter.reportRunnerStarting) { + self.env.reporter.reportRunnerStarting(this); + } + self.queue.start(function () { + self.finishCallback(); + }); +}; + +jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.splice(0,0,beforeEachFunction); +}; + +jasmine.Runner.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.splice(0,0,afterEachFunction); +}; + + +jasmine.Runner.prototype.finishCallback = function() { + this.env.reporter.reportRunnerResults(this); +}; + +jasmine.Runner.prototype.addSuite = function(suite) { + this.suites_.push(suite); +}; + +jasmine.Runner.prototype.add = function(block) { + if (block instanceof jasmine.Suite) { + this.addSuite(block); + } + this.queue.add(block); +}; + +jasmine.Runner.prototype.specs = function () { + var suites = this.suites(); + var specs = []; + for (var i = 0; i < suites.length; i++) { + specs = specs.concat(suites[i].specs()); + } + return specs; +}; + +jasmine.Runner.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Runner.prototype.topLevelSuites = function() { + var topLevelSuites = []; + for (var i = 0; i < this.suites_.length; i++) { + if (!this.suites_[i].parentSuite) { + topLevelSuites.push(this.suites_[i]); + } + } + return topLevelSuites; +}; + +jasmine.Runner.prototype.results = function() { + return this.queue.results(); +}; +/** + * Internal representation of a Jasmine specification, or test. + * + * @constructor + * @param {jasmine.Env} env + * @param {jasmine.Suite} suite + * @param {String} description + */ +jasmine.Spec = function(env, suite, description) { + if (!env) { + throw new Error('jasmine.Env() required'); + } + if (!suite) { + throw new Error('jasmine.Suite() required'); + } + var spec = this; + spec.id = env.nextSpecId ? env.nextSpecId() : null; + spec.env = env; + spec.suite = suite; + spec.description = description; + spec.queue = new jasmine.Queue(env); + + spec.afterCallbacks = []; + spec.spies_ = []; + + spec.results_ = new jasmine.NestedResults(); + spec.results_.description = description; + spec.matchersClass = null; + spec.exclusive_ = suite.exclusive_; +}; + +jasmine.Spec.prototype.getFullName = function() { + return this.suite.getFullName() + ' ' + this.description + '.'; +}; + + +jasmine.Spec.prototype.results = function() { + return this.results_; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); +}; + +jasmine.Spec.prototype.runs = function (func) { + var block = new jasmine.Block(this.env, func, this); + this.addToQueue(block); + return this; +}; + +jasmine.Spec.prototype.addToQueue = function (block) { + if (this.queue.isRunning()) { + this.queue.insertNext(block); + } else { + this.queue.add(block); + } +}; + +/** + * @param {jasmine.ExpectationResult} result + */ +jasmine.Spec.prototype.addMatcherResult = function(result) { + this.results_.addResult(result); +}; + +jasmine.Spec.prototype.expect = function(actual) { + var positive = new (this.getMatchersClass_())(this.env, actual, this); + positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); + return positive; +}; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +jasmine.Spec.prototype.waits = function(timeout) { + var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); + this.addToQueue(waitsFunc); + return this; +}; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + var latchFunction_ = null; + var optional_timeoutMessage_ = null; + var optional_timeout_ = null; + + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + switch (typeof arg) { + case 'function': + latchFunction_ = arg; + break; + case 'string': + optional_timeoutMessage_ = arg; + break; + case 'number': + optional_timeout_ = arg; + break; + } + } + + var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); + this.addToQueue(waitsForFunc); + return this; +}; + +jasmine.Spec.prototype.fail = function (e) { + var expectationResult = new jasmine.ExpectationResult({ + passed: false, + message: e ? jasmine.util.formatException(e) : 'Exception', + trace: { stack: e.stack } + }); + this.results_.addResult(expectationResult); +}; + +jasmine.Spec.prototype.getMatchersClass_ = function() { + return this.matchersClass || this.env.matchersClass; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); + this.matchersClass = newMatchersClass; +}; + +jasmine.Spec.prototype.finishCallback = function() { + this.env.reporter.reportSpecResults(this); +}; + +jasmine.Spec.prototype.finish = function(onComplete) { + this.removeAllSpies(); + this.finishCallback(); + if (onComplete) { + onComplete(); + } +}; + +jasmine.Spec.prototype.after = function(doAfter) { + if (this.queue.isRunning()) { + this.queue.add(new jasmine.Block(this.env, doAfter, this), true); + } else { + this.afterCallbacks.unshift(doAfter); + } +}; + +jasmine.Spec.prototype.execute = function(onComplete) { + var spec = this; + if (!spec.env.specFilter(spec)) { + spec.results_.skipped = true; + spec.finish(onComplete); + return; + } + + this.env.reporter.reportSpecStarting(this); + + spec.env.currentSpec = spec; + + spec.addBeforesAndAftersToQueue(); + + spec.queue.start(function () { + spec.finish(onComplete); + }); +}; + +jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { + var runner = this.env.currentRunner(); + var i; + + for (var suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); + } + } + for (i = 0; i < runner.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); + } + for (i = 0; i < this.afterCallbacks.length; i++) { + this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true); + } + for (suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true); + } + } + for (i = 0; i < runner.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true); + } +}; + +jasmine.Spec.prototype.explodes = function() { + throw 'explodes function should not have been called'; +}; + +jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { + if (obj == jasmine.undefined) { + throw "spyOn could not find an object to spy upon for " + methodName + "()"; + } + + if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { + throw methodName + '() method does not exist'; + } + + if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { + throw new Error(methodName + ' has already been spied upon'); + } + + var spyObj = jasmine.createSpy(methodName); + + this.spies_.push(spyObj); + spyObj.baseObj = obj; + spyObj.methodName = methodName; + spyObj.originalValue = obj[methodName]; + + obj[methodName] = spyObj; + + return spyObj; +}; + +jasmine.Spec.prototype.removeAllSpies = function() { + for (var i = 0; i < this.spies_.length; i++) { + var spy = this.spies_[i]; + spy.baseObj[spy.methodName] = spy.originalValue; + } + this.spies_ = []; +}; + +/** + * Internal representation of a Jasmine suite. + * + * @constructor + * @param {jasmine.Env} env + * @param {String} description + * @param {Function} specDefinitions + * @param {jasmine.Suite} parentSuite + */ +jasmine.Suite = function(env, description, specDefinitions, parentSuite) { + var self = this; + self.id = env.nextSuiteId ? env.nextSuiteId() : null; + self.description = description; + self.queue = new jasmine.Queue(env); + self.parentSuite = parentSuite; + self.env = env; + self.before_ = []; + self.after_ = []; + self.children_ = []; + self.suites_ = []; + self.specs_ = []; + self.exclusive_ = parentSuite && parentSuite.exclusive_ || 0; +}; + +jasmine.Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + return fullName; +}; + +jasmine.Suite.prototype.finish = function(onComplete) { + this.env.reporter.reportSuiteResults(this); + this.finished = true; + if (typeof(onComplete) == 'function') { + onComplete(); + } +}; + +jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.unshift(beforeEachFunction); +}; + +jasmine.Suite.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.unshift(afterEachFunction); +}; + +jasmine.Suite.prototype.results = function() { + return this.queue.results(); +}; + +jasmine.Suite.prototype.add = function(suiteOrSpec) { + this.children_.push(suiteOrSpec); + if (suiteOrSpec instanceof jasmine.Suite) { + this.suites_.push(suiteOrSpec); + this.env.currentRunner().addSuite(suiteOrSpec); + } else { + this.specs_.push(suiteOrSpec); + } + this.queue.add(suiteOrSpec); +}; + +jasmine.Suite.prototype.specs = function() { + return this.specs_; +}; + +jasmine.Suite.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Suite.prototype.children = function() { + return this.children_; +}; + +jasmine.Suite.prototype.execute = function(onComplete) { + var self = this; + this.queue.start(function () { + self.finish(onComplete); + }); +}; +jasmine.WaitsBlock = function(env, timeout, spec) { + this.timeout = timeout; + jasmine.Block.call(this, env, null, spec); +}; + +jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); + +jasmine.WaitsBlock.prototype.execute = function (onComplete) { + if (jasmine.VERBOSE) { + this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); + } + this.env.setTimeout(function () { + onComplete(); + }, this.timeout); +}; +/** + * A block which waits for some condition to become true, with timeout. + * + * @constructor + * @extends jasmine.Block + * @param {jasmine.Env} env The Jasmine environment. + * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. + * @param {Function} latchFunction A function which returns true when the desired condition has been met. + * @param {String} message The message to display if the desired condition hasn't been met within the given time period. + * @param {jasmine.Spec} spec The Jasmine spec. + */ +jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { + this.timeout = timeout || env.defaultTimeoutInterval; + this.latchFunction = latchFunction; + this.message = message; + this.totalTimeSpentWaitingForLatch = 0; + jasmine.Block.call(this, env, null, spec); +}; +jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); + +jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; + +jasmine.WaitsForBlock.prototype.execute = function(onComplete) { + if (jasmine.VERBOSE) { + this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); + } + var latchFunctionResult; + try { + latchFunctionResult = this.latchFunction.apply(this.spec); + } catch (e) { + this.spec.fail(e); + onComplete(); + return; + } + + if (latchFunctionResult) { + onComplete(); + } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { + var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); + this.spec.fail({ + name: 'timeout', + message: message + }); + + this.abort = true; + onComplete(); + } else { + this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; + var self = this; + this.env.setTimeout(function() { + self.execute(onComplete); + }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); + } +}; + +jasmine.version_= { + "major": 1, + "minor": 3, + "build": 1, + "revision": 1354556913 +}; diff --git a/node_modules/jasmine-node/lib/jasmine-node/reporter.js b/node_modules/jasmine-node/lib/jasmine-node/reporter.js new file mode 100755 index 0000000..55f3a1d --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/reporter.js @@ -0,0 +1,342 @@ +(function() { + // + // Imports + // + var util; + try { + util = require('util') + } catch(e) { + util = require('sys') + } + + var jasmineNode = {}; + // + // Helpers + // + function noop() {} + + + jasmineNode.TerminalReporter = function(config) { + this.print_ = config.print || function (str) { process.stdout.write(util.format(str)); }; + this.color_ = config.color ? this.ANSIColors : this.NoColors; + + this.started_ = false; + this.finished_ = false; + + this.callback_ = config.onComplete || false + + this.suites_ = []; + this.specResults_ = {}; + this.failures_ = []; + this.includeStackTrace_ = config.includeStackTrace === false ? false : true; + this.stackFilter_ = config.stackFilter || function(t) { return t; }; + } + + + jasmineNode.TerminalReporter.prototype = { + reportRunnerStarting: function(runner) { + this.started_ = true; + this.startedAt = new Date(); + var suites = runner.topLevelSuites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + this.suites_.push(this.summarize_(suite)); + } + }, + + ANSIColors: { + pass: function() { return '\033[32m'; }, // Green + fail: function() { return '\033[31m'; }, // Red + specTiming: function() { return '\033[34m'; }, // Blue + suiteTiming: function() { return '\033[33m'; }, // Yelow + ignore: function() { return '\033[37m'; }, // Light Gray + neutral: function() { return '\033[0m'; } // Normal + }, + + NoColors: { + pass: function() { return ''; }, + fail: function() { return ''; }, + specTiming: function() { return ''; }, + suiteTiming: function() { return ''; }, + ignore: function() { return ''; }, + neutral: function() { return ''; } + }, + + summarize_: function(suiteOrSpec) { + var isSuite = suiteOrSpec instanceof jasmine.Suite; + + // We could use a separate object for suite and spec + var summary = { + id: suiteOrSpec.id, + name: suiteOrSpec.description, + type: isSuite? 'suite' : 'spec', + suiteNestingLevel: 0, + children: [] + }; + + if (isSuite) { + var calculateNestingLevel = function(examinedSuite) { + var nestingLevel = 0; + while (examinedSuite.parentSuite !== null) { + nestingLevel += 1; + examinedSuite = examinedSuite.parentSuite; + } + return nestingLevel; + }; + + summary.suiteNestingLevel = calculateNestingLevel(suiteOrSpec); + + var children = suiteOrSpec.children(); + for (var i = 0; i < children.length; i++) { + summary.children.push(this.summarize_(children[i])); + } + } + + return summary; + }, + + // This is heavily influenced by Jasmine's Html/Trivial Reporter + reportRunnerResults: function(runner) { + this.reportFailures_(); + + var results = runner.results(); + var resultColor = (results.failedCount > 0) ? this.color_.fail() : this.color_.pass(); + + var specs = runner.specs(); + var specCount = specs.length; + + var message = "\n\nFinished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + " seconds"; + this.printLine_(message); + + // This is what jasmine-html.js has + //message = "" + specCount + " spec" + ( specCount === 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount === 1) ? "" : "s"); + + this.printLine_(this.stringWithColor_(this.printRunnerResults_(runner), resultColor)); + + this.finished_ = true; + if(this.callback_) { this.callback_(runner); } + }, + + reportFailures_: function() { + if (this.failures_.length === 0) { + return; + } + + var indent = ' ', failure; + this.printLine_('\n'); + + this.print_('Failures:'); + + for (var i = 0; i < this.failures_.length; i++) { + failure = this.failures_[i]; + this.printLine_('\n'); + this.printLine_(' ' + (i + 1) + ') ' + failure.spec); + this.printLine_(' Message:'); + this.printLine_(' ' + this.stringWithColor_(failure.message, this.color_.fail())); + if (this.includeStackTrace_) { + this.printLine_(' Stacktrace:'); + this.print_(' ' + this.stackFilter_(failure.stackTrace)); + } + } + }, + + reportSuiteResults: function(suite) { + // Not used in this context + }, + + reportSpecResults: function(spec) { + var result = spec.results(); + var msg = ''; + if (result.skipped) { + msg = this.stringWithColor_('-', this.color_.ignore()); + } else if (result.passed()) { + msg = this.stringWithColor_('.', this.color_.pass()); + } else { + msg = this.stringWithColor_('F', this.color_.fail()); + this.addFailureToFailures_(spec); + } + this.spec_results += msg; + this.print_(msg); + }, + + addFailureToFailures_: function(spec) { + var result = spec.results(); + var failureItem = null; + + var items_length = result.items_.length; + for (var i = 0; i < items_length; i++) { + if (result.items_[i].passed_ === false) { + failureItem = result.items_[i]; + + var failure = { + spec: spec.suite.getFullName() + " " + spec.description, + message: failureItem.message, + stackTrace: failureItem.trace.stack + } + + this.failures_.push(failure); + } + } + }, + + printRunnerResults_: function(runner){ + var results = runner.results(); + var specs = runner.specs(); + var msg = ''; + var skippedCount = 0; + specs.forEach(function(spec) { + if (spec.results().skipped) { + skippedCount++; + } + }); + var passedCount = specs.length - skippedCount; + msg += passedCount + ' test' + ((passedCount === 1) ? '' : 's') + ', '; + msg += results.totalCount + ' assertion' + ((results.totalCount === 1) ? '' : 's') + ', '; + msg += results.failedCount + ' failure' + ((results.failedCount === 1) ? '' : 's') + ', '; + msg += skippedCount + ' skipped' + '\n'; + return msg; + }, + + // Helper Methods // + stringWithColor_: function(stringValue, color) { + return (color || this.color_.neutral()) + stringValue + this.color_.neutral(); + }, + + printLine_: function(stringValue) { + this.print_(stringValue); + this.print_('\n'); + } + }; + + // *************************************************************** + // TerminalVerboseReporter uses the TerminalReporter's constructor + // *************************************************************** + jasmineNode.TerminalVerboseReporter = function(config) { + jasmineNode.TerminalReporter.call(this, config); + // The extra field in this object + this.indent_ = 0; + this.specTimes_ = {}; + this.suiteTimes_ = {}; + this.suiteResults_ = {}; + } + + + jasmineNode.TerminalVerboseReporter.prototype = { + + reportSpecStarting: function(spec) { + now = new Date().getTime(); + this.specTimes_[spec.id] = now; + var suite = spec.suite; + while (suite) { + if (!this.suiteTimes_[suite.id]) { + this.suiteTimes_[suite.id] = now; + } + suite = suite.parentSuite; + } + }, + + reportSpecResults: function(spec) { + var elapsed = new Date().getTime() - this.specTimes_[spec.id]; + + if (spec.results().failedCount > 0) { + this.addFailureToFailures_(spec); + } + + this.specResults_[spec.id] = { + messages: spec.results().getItems(), + result: spec.results().failedCount > 0 ? 'failed' : 'passed', + runtime: elapsed + }; + }, + + reportSuiteResults: function(suite) { + var startTime = this.suiteTimes_[suite.id]; + if (startTime) { + var elapsed = new Date().getTime() - startTime; + this.suiteResults_[suite.id] = { + runtime: elapsed + }; + } + }, + + reportRunnerResults: function(runner) { + var messages = new Array(); + this.buildMessagesFromResults_(messages, this.suites_); + + var messages_length = messages.length; + for (var i = 0; i < messages_length-1; i++) { + this.printLine_(messages[i]); + } + + this.print_(messages[messages_length-1]); + + // Call the parent object's method + jasmineNode.TerminalReporter.prototype.reportRunnerResults.call(this, runner); + }, + + buildMessagesFromResults_: function(messages, results, depth) { + var element, specResult, specIndentSpaces, msg = ''; + depth = (depth === undefined) ? 0 : depth; + + var results_length = results.length; + for (var i = 0; i < results_length; i++) { + element = results[i]; + + if (element.type === 'spec') { + specResult = this.specResults_[element.id.toString()]; + + if (specResult.result === 'passed') { + msg = this.stringWithColor_(this.indentMessage_(element.name, depth), this.color_.pass()); + } else { + msg = this.stringWithColor_(this.indentMessage_(element.name, depth), this.color_.fail()); + } + msg += this.stringWithColor_(" - " + specResult.runtime + " ms", + this.color_.specTiming()); + + messages.push(msg); + } else { + messages.push(''); + msg = this.indentMessage_(element.name, depth) + if (element.id != null) { + suiteResult = this.suiteResults_[element.id.toString()]; + if (suiteResult) { + msg += this.stringWithColor_(" - " + suiteResult.runtime + " ms", this.color_.suiteTiming()); + } + } + messages.push(msg); + } + + this.buildMessagesFromResults_(messages, element.children, depth + 2); + } + }, + + indentMessage_: function(message, indentCount) { + var _indent = ''; + for (var i = 0; i < indentCount; i++) { + _indent += ' '; + } + return (_indent + message); + } + }; + + // Inherit from TerminalReporter + jasmineNode.TerminalVerboseReporter.prototype.__proto__ = jasmineNode.TerminalReporter.prototype; + + // Extend Teamcity Reporter + jasmineNode.TeamcityReporter = function(config) { + var callback_ = config.onComplete || false; + + (function(superFn) { + jasmineNode.TeamcityReporter.prototype.reportRunnerResults = function(runner) { + superFn.call(this, runner); + if (callback_) {callback_(runner)} + } + }(jasmine.TeamcityReporter.prototype.reportRunnerResults)); + }; + jasmineNode.TeamcityReporter.prototype = new jasmine.TeamcityReporter; + + // + // Exports + // + exports.jasmineNode = jasmineNode; +})(); diff --git a/node_modules/jasmine-node/lib/jasmine-node/requirejs-runner.js b/node_modules/jasmine-node/lib/jasmine-node/requirejs-runner.js new file mode 100644 index 0000000..cf57b07 --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/requirejs-runner.js @@ -0,0 +1,86 @@ +exports.executeJsRunner = function(specCollection, done, jasmineEnv, setupFile) { + var specs, + specLoader = require('./requirejs-spec-loader'), + requirejs = require('requirejs'), + vm = require('vm'), + fs = require('fs'), + coffeescript = require('coffee-script'), + template = fs.readFileSync( + setupFile || (__dirname + '/requirejs-wrapper-template.js'), + 'utf8' + ), + ensureUnixPath = function(path){ + return path.replace(/^(.):/, '/$1').replace(/\\/g, '/'); + }, + buildNewContext = function(spec){ + var context = { + describe: describe, + it: it, + xdescribe: xdescribe, + xit: xit, + beforeEach: beforeEach, + afterEach: afterEach, + spyOn: spyOn, + waitsFor: waitsFor, + waits: waits, + runs: runs, + jasmine: jasmine, + expect: expect, + require: require, + console: console, + process: process, + module: module, + specLoader: specLoader, + __dirname: spec.directory(), + __filename: spec.path(), + baseUrl: buildRelativeDirName(spec.directory()), + csPath: __dirname + '/cs' + }; + + context.global = context; + + return context; + }, + buildRelativeDirName = function(dir){ + var retVal = "", + thisDir = ensureUnixPath(process.cwd()), + toDir = ensureUnixPath(dir).split('/'), + index = 0; + + thisDir = thisDir.split('/'); + + for(; index < thisDir.length || index < toDir.length; index++) { + if(thisDir[index] != toDir[index]){ + for(var i = index; i < thisDir.length-1; i++){ + retVal += '../'; + } + + for(var i = index; i < toDir.length; i++){ + retVal += toDir[i] + '/'; + } + + break; + } + } + + return retVal.trim('/'); + }; + + specCollection.getSpecs().forEach(function(s){ + var script = fs.readFileSync(s.path(), 'utf8'); + + if (s.filename().substr(-6).toLowerCase() == 'coffee') { + script = coffeescript.compile(script); + } + + var newContext = buildNewContext(s); + newContext.setTimeout = jasmine.getGlobal().setTimeout; + newContext.setInterval = jasmine.getGlobal().setInterval; + + var vmContext = vm.createContext(newContext); + vm.runInContext(template, vmContext); + vm.runInContext(script, vmContext, s.path()); + }); + + specLoader.executeWhenAllSpecsAreComplete(jasmineEnv); +}; diff --git a/node_modules/jasmine-node/lib/jasmine-node/requirejs-spec-loader.js b/node_modules/jasmine-node/lib/jasmine-node/requirejs-spec-loader.js new file mode 100644 index 0000000..284db7d --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/requirejs-spec-loader.js @@ -0,0 +1,48 @@ +var _ = require('underscore'), + registry = {}, + timeout = 120000, + now = function() { + return new Date().getTime(); + }, + loader = { + register: function(name) { + registry[name] = false; + }, + completed: function(name){ + registry[name] = true; + } + }, + specLoader = { + defineLoader: function(requirejs) { + requirejs.define('jasmine-spec-loader', function() { + return loader; + }); + }, + executeWhenAllSpecsAreComplete: function(jasmineEnv) { + var allComplete = false, + wait = now(), + timeoutCallback = function() { + allComplete = _.all(registry, function(value) { + return value; + }); + + if(!allComplete && wait + timeout > now()) { + setTimeout(timeoutCallback, 100); + } else if (!allComplete) { + console.log('Failed to load all specs within timeout window.'); + process.exit(-1); + } else { + jasmineEnv.execute(); + } + }; + + setTimeout(timeoutCallback, 100); + }, + setTimeoutInterval: function(value) { + timeout = value; + }, + }; + +for(var key in specLoader) { + exports[key] = specLoader[key]; +} diff --git a/node_modules/jasmine-node/lib/jasmine-node/requirejs-wrapper-template.js b/node_modules/jasmine-node/lib/jasmine-node/requirejs-wrapper-template.js new file mode 100644 index 0000000..344daeb --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/requirejs-wrapper-template.js @@ -0,0 +1,78 @@ +/* Setup file run before spec files to setup the context (and RequireJS + * specifically) to execute the spec file. + * + * Defined by caller: + * - Jasmine predefines + * - require (Node require) + * - __dirname, __filename + * - baseUrl (Relative path to the directory containing this file) + * - csPath (Path to require-cs module) + * + * See requirejs-runner source for full invocation details. + */ +var define, + requirejsOrig = require('requirejs'), + ostring = Object.prototype.toString, + path = require('path'), + isArray = function(it){ + return ostring.call(it) === '[object Array]'; + }, + isFunction = function(it){ + return ostring.call(it) === '[object Function]'; + }, + requirejs = function(deps, callback){ + var retVal; + + if(!isArray(deps) && typeof deps !== 'string'){ + if(isArray(callback)){ + retVal = requirejsOrig(deps, callback, arguments[2]); + } else { + retVal = requirejsOrig(deps, [], callback); + } + } else { + retVal = requirejsOrig(deps, callback); + } + + return retVal; + }; + +requirejsOrig.config({ + baseUrl: baseUrl, + nodeRequire: require, + paths: { + cs: csPath + } +}); + +for(var key in requirejsOrig) { + requirejs[key] = requirejsOrig[key]; +} + +requirejs.config = function(config){ + var alteredConfig = {}; + + for(var key in config) { + alteredConfig[key] = config[key]; + } + + if(alteredConfig.baseUrl){ + var base = baseUrl.replace(/\\/g, '/'), + splitUrl = alteredConfig.baseUrl.replace(/\\/g, '/').split('/'), + index = 0; + + for(; index < splitUrl.length; index++){ + if(splitUrl[index] === '..'){ + base = path.dirname(base); + } else { + base += '/' + splitUrl[index]; + } + } + + alteredConfig.baseUrl = base; + } + + return requirejsOrig.config(alteredConfig); +}; + +require = requirejs; +define = requirejs.define; diff --git a/node_modules/jasmine-node/lib/jasmine-node/spec-collection.js b/node_modules/jasmine-node/lib/jasmine-node/spec-collection.js new file mode 100644 index 0000000..4b2de89 --- /dev/null +++ b/node_modules/jasmine-node/lib/jasmine-node/spec-collection.js @@ -0,0 +1,44 @@ +var walkdir = require('walkdir'); +var path = require('path'); +var fs = require('fs'); +var specs; + +var createSpecObj = function(path, root) { + return { + path: function() { return path; }, + relativePath: function() { return path.replace(root, '').replace(/^[\/\\]/, '').replace(/\\/g, '/'); }, + directory: function() { return path.replace(/[\/\\][\s\w\.-]*$/, "").replace(/\\/g, '/'); }, + relativeDirectory: function() { return relativePath().replace(/[\/\\][\s\w\.-]*$/, "").replace(/\\/g, '/'); }, + filename: function() { return path.replace(/^.*[\\\/]/, ''); } + }; +}; + +exports.load = function(loadpaths, matcher) { + var wannaBeSpecs = [] + specs = []; + loadpaths.forEach(function(loadpath){ + wannaBeSpecs = walkdir.sync(loadpath, { follow_symlinks: true }); + for (var i = 0; i < wannaBeSpecs.length; i++) { + var file = wannaBeSpecs[i]; + try { + if (fs.statSync(file).isFile()) { + if (!/.*node_modules.*/.test(path.relative(loadpath, file)) & + matcher.test(path.basename(file))) { + specs.push(createSpecObj(file)); + } + } + } catch(e) { + // nothing to do here + } + } + }); +}; + +exports.getSpecs = function() { + // Sorts spec paths in ascending alphabetical order to be able to + // run tests in a deterministic order. + specs.sort(function(a, b) { + return a.path().localeCompare(b.path()); + }); + return specs; +}; diff --git a/node_modules/jasmine-node/package.json b/node_modules/jasmine-node/package.json new file mode 100644 index 0000000..164c2ed --- /dev/null +++ b/node_modules/jasmine-node/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + "jasmine-node", + "/home/sundar/CodeAstra/git_hub_repos/data_structures" + ] + ], + "_from": "jasmine-node@*", + "_id": "jasmine-node@1.14.5", + "_inCache": true, + "_installable": true, + "_location": "/jasmine-node", + "_npmUser": { + "email": "tebriel@gmail.com", + "name": "tebriel" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "name": "jasmine-node", + "raw": "jasmine-node", + "rawSpec": "", + "scope": null, + "spec": "*", + "type": "range" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/jasmine-node/-/jasmine-node-1.14.5.tgz", + "_shasum": "18e8397b856924ee77003666c3731b5aea50c39d", + "_shrinkwrap": null, + "_spec": "jasmine-node", + "_where": "/home/sundar/CodeAstra/git_hub_repos/data_structures", + "author": { + "email": "misko@hevery.com", + "name": "Misko Hevery" + }, + "bin": { + "jasmine-node": "bin/jasmine-node" + }, + "bugs": { + "url": "https://github.com/mhevery/jasmine-node/issues" + }, + "contributors": [ + { + "name": "Chris Moultrie", + "email": "chris@moultrie.org" + } + ], + "dependencies": { + "coffee-script": ">=1.0.1", + "gaze": "~0.3.2", + "jasmine-growl-reporter": "~0.0.2", + "jasmine-reporters": "~1.0.0", + "mkdirp": "~0.3.5", + "requirejs": ">=0.27.1", + "underscore": ">= 1.3.1", + "walkdir": ">= 0.0.1" + }, + "description": "DOM-less simple JavaScript BDD testing framework for Node", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "18e8397b856924ee77003666c3731b5aea50c39d", + "tarball": "https://registry.npmjs.org/jasmine-node/-/jasmine-node-1.14.5.tgz" + }, + "homepage": "https://github.com/mhevery/jasmine-node", + "keywords": [ + "bdd", + "testing" + ], + "licenses": [ + "MIT" + ], + "main": "lib/jasmine-node", + "maintainers": [ + { + "name": "mhevery", + "email": "misko@hevery.com" + }, + { + "name": "tebriel", + "email": "chris@moultrie.org" + } + ], + "name": "jasmine-node", + "optionalDependencies": {}, + "preferGlobal": true, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mhevery/jasmine-node.git" + }, + "scripts": { + "test": "node lib/jasmine-node/cli.js spec" + }, + "version": "1.14.5" +} diff --git a/node_modules/jasmine-node/scripts/specs b/node_modules/jasmine-node/scripts/specs new file mode 100755 index 0000000..28a45f0 --- /dev/null +++ b/node_modules/jasmine-node/scripts/specs @@ -0,0 +1,37 @@ +#!/bin/bash + +entry="node lib/jasmine-node/cli.js " + +if [ $# -ne 0 ]; then + command=$entry"$1 spec" + echo $command + $command +else + echo "Running all tests located in the spec directory" + command=$entry"spec" + echo $command + time $command #/nested/uber-nested + echo -e "\033[1;35m--- Should have 40 tests and 71 assertions and 1 Failure. ---\033[0m" + echo "" + + echo "Running all tests located in the spec directory with coffee option" + command=$entry"--coffee spec" + echo $command + time $command #/nested/uber-nested + echo -e "\033[1;35m--- Should have 40 tests and 71 assertions and 1 Failure. ---\033[0m" + echo "" + + echo "Running all tests located in the spec directory with requirejs option" + #command=$entry"--nohelpers --runWithRequireJs spec-requirejs" + command=$entry"--runWithRequireJs spec" + echo $command + time $command + echo -e "\033[1;35m--- Should have 40 tests and 71 assertions and 1 Failure. ---\033[0m" + + echo "Running all tests located in the spec-requirejs directory with requirejs" + #command=$entry"--nohelpers --runWithRequireJs spec-requirejs" + command=$entry"--runWithRequireJs spec-requirejs" + echo $command + time $command + echo -e "\033[1;35m--- Should have 1 test and 2 assertions and 0 Failures. ---\033[0m" +fi diff --git a/node_modules/jasmine-node/spec-requirejs-coffee/RequireCsSpec.coffee b/node_modules/jasmine-node/spec-requirejs-coffee/RequireCsSpec.coffee new file mode 100644 index 0000000..4a8f754 --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs-coffee/RequireCsSpec.coffee @@ -0,0 +1,5 @@ +require [ "cs!requirecs.sut" ], (sut) -> + describe "RequireJs basic tests with spec and sut in CoffeeScript", -> + it "should load coffeescript sut", -> + expect(sut.name).toBe "CoffeeScript To Test" + expect(sut.method(2)).toBe 4 diff --git a/node_modules/jasmine-node/spec-requirejs-coffee/RequireJsSpec.coffee b/node_modules/jasmine-node/spec-requirejs-coffee/RequireJsSpec.coffee new file mode 100644 index 0000000..05bad4a --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs-coffee/RequireJsSpec.coffee @@ -0,0 +1,5 @@ +require [ "requirecs.sut" ], (sut) -> + describe "RequireJs basic tests with spec in CoffeeScript", -> + it "should load javascript sut", -> + expect(sut.name).toBe "CoffeeScript To Test" + expect(sut.method(2)).toBe 4 diff --git a/node_modules/jasmine-node/spec-requirejs-coffee/requirecs.sut.coffee b/node_modules/jasmine-node/spec-requirejs-coffee/requirecs.sut.coffee new file mode 100644 index 0000000..b0a2250 --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs-coffee/requirecs.sut.coffee @@ -0,0 +1,3 @@ +define -> + name: 'CoffeeScript To Test' + method: (input) -> 2 * input diff --git a/node_modules/jasmine-node/spec-requirejs-coffee/requirejs-setup.js b/node_modules/jasmine-node/spec-requirejs-coffee/requirejs-setup.js new file mode 100644 index 0000000..0cd82b8 --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs-coffee/requirejs-setup.js @@ -0,0 +1,13 @@ +/** Custom RequireJS setup file to test user-specified setup files */ + +/* We want to minimize behavior changes between this test setup file and the + * default setup file to avoid breaking tests which rely on any (current or + * future) default behavior. So we: + * - Run the normal setup file + * - Avoid introducing additional global variables + * - Avoid maintaining two copies of the setup file + */ +eval(require('fs').readFileSync(baseUrl + '../lib/jasmine-node/requirejs-wrapper-template.js', 'utf8')); + +// This is our indicator that this custom setup script has run +var setupHasRun = true; diff --git a/node_modules/jasmine-node/spec-requirejs/requirejs-setup.js b/node_modules/jasmine-node/spec-requirejs/requirejs-setup.js new file mode 100644 index 0000000..0cd82b8 --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs/requirejs-setup.js @@ -0,0 +1,13 @@ +/** Custom RequireJS setup file to test user-specified setup files */ + +/* We want to minimize behavior changes between this test setup file and the + * default setup file to avoid breaking tests which rely on any (current or + * future) default behavior. So we: + * - Run the normal setup file + * - Avoid introducing additional global variables + * - Avoid maintaining two copies of the setup file + */ +eval(require('fs').readFileSync(baseUrl + '../lib/jasmine-node/requirejs-wrapper-template.js', 'utf8')); + +// This is our indicator that this custom setup script has run +var setupHasRun = true; diff --git a/node_modules/jasmine-node/spec-requirejs/requirejs-wrapper-template.js b/node_modules/jasmine-node/spec-requirejs/requirejs-wrapper-template.js new file mode 100644 index 0000000..344daeb --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs/requirejs-wrapper-template.js @@ -0,0 +1,78 @@ +/* Setup file run before spec files to setup the context (and RequireJS + * specifically) to execute the spec file. + * + * Defined by caller: + * - Jasmine predefines + * - require (Node require) + * - __dirname, __filename + * - baseUrl (Relative path to the directory containing this file) + * - csPath (Path to require-cs module) + * + * See requirejs-runner source for full invocation details. + */ +var define, + requirejsOrig = require('requirejs'), + ostring = Object.prototype.toString, + path = require('path'), + isArray = function(it){ + return ostring.call(it) === '[object Array]'; + }, + isFunction = function(it){ + return ostring.call(it) === '[object Function]'; + }, + requirejs = function(deps, callback){ + var retVal; + + if(!isArray(deps) && typeof deps !== 'string'){ + if(isArray(callback)){ + retVal = requirejsOrig(deps, callback, arguments[2]); + } else { + retVal = requirejsOrig(deps, [], callback); + } + } else { + retVal = requirejsOrig(deps, callback); + } + + return retVal; + }; + +requirejsOrig.config({ + baseUrl: baseUrl, + nodeRequire: require, + paths: { + cs: csPath + } +}); + +for(var key in requirejsOrig) { + requirejs[key] = requirejsOrig[key]; +} + +requirejs.config = function(config){ + var alteredConfig = {}; + + for(var key in config) { + alteredConfig[key] = config[key]; + } + + if(alteredConfig.baseUrl){ + var base = baseUrl.replace(/\\/g, '/'), + splitUrl = alteredConfig.baseUrl.replace(/\\/g, '/').split('/'), + index = 0; + + for(; index < splitUrl.length; index++){ + if(splitUrl[index] === '..'){ + base = path.dirname(base); + } else { + base += '/' + splitUrl[index]; + } + } + + alteredConfig.baseUrl = base; + } + + return requirejsOrig.config(alteredConfig); +}; + +require = requirejs; +define = requirejs.define; diff --git a/node_modules/jasmine-node/spec-requirejs/requirejs.spec.js b/node_modules/jasmine-node/spec-requirejs/requirejs.spec.js new file mode 100644 index 0000000..5e7bddb --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs/requirejs.spec.js @@ -0,0 +1,19 @@ +require(['requirejs.sut'], function(sut){ + describe('RequireJs basic tests', function(){ + beforeEach(function(){ + expect(true).toBeTruthy(); + }); + afterEach(function(){ + expect(true).toBeTruthy(); + }); + + it('should load sut', function(){ + expect(sut.name).toBe('Subject To Test'); + expect(sut.method(2)).toBe(3); + }); + + it('should run setup', function(){ + expect(typeof setupHasRun).toBe('boolean'); + }); + }); +}); diff --git a/node_modules/jasmine-node/spec-requirejs/requirejs.sut.js b/node_modules/jasmine-node/spec-requirejs/requirejs.sut.js new file mode 100644 index 0000000..1d5095f --- /dev/null +++ b/node_modules/jasmine-node/spec-requirejs/requirejs.sut.js @@ -0,0 +1,8 @@ +define(function(){ + return { + name: 'Subject To Test', + method: function(input){ + return 1+input; + } + }; +}); diff --git a/node_modules/jasmine-node/spec/AsyncSpec.coffee b/node_modules/jasmine-node/spec/AsyncSpec.coffee new file mode 100644 index 0000000..a6e160d --- /dev/null +++ b/node_modules/jasmine-node/spec/AsyncSpec.coffee @@ -0,0 +1,11 @@ +#============================================================================= +# Async spec, that will be time outed +#============================================================================= +describe 'async', -> + it 'should be timed out', -> + waitsFor (-> false), 'MIRACLE', 500 + + doneFunc = (done) -> + setTimeout(done, 10000) + + it "should timeout after 100 ms", doneFunc, 100 diff --git a/node_modules/jasmine-node/spec/CoffeeSpec.coffee b/node_modules/jasmine-node/spec/CoffeeSpec.coffee new file mode 100755 index 0000000..757da61 --- /dev/null +++ b/node_modules/jasmine-node/spec/CoffeeSpec.coffee @@ -0,0 +1,4 @@ +describe 'jasmine-node', -> + + it 'should pass', -> + expect(1+2).toEqual(3) diff --git a/node_modules/jasmine-node/spec/GrammarHelper.coffee b/node_modules/jasmine-node/spec/GrammarHelper.coffee new file mode 100644 index 0000000..507fd58 --- /dev/null +++ b/node_modules/jasmine-node/spec/GrammarHelper.coffee @@ -0,0 +1,22 @@ +global.testClass = (description, specDefinitions) -> + suite = jasmine.getEnv().describe('Class: ' + description, specDefinitions) + suite.tags = ['class'] + suite.isIntermediate = true; + suite + +global.feature = (description, specDefinitions) -> + suite = jasmine.getEnv().describe('Feature: ' + description, specDefinitions) + suite.tags = ['feature'] + suite.isIntermediate = true; + suite + +global.scenario = (desc, func) -> + suite = jasmine.getEnv().describe('Scenario: ' + desc, func) + suite.tags = ['scenario'] + suite.isIntermediate = true; + suite + +global.should = (description, specDefinitions) -> + suite = jasmine.getEnv().it('It should ' + description, specDefinitions) + suite.tags = ['should'] + suite diff --git a/node_modules/jasmine-node/spec/HelperSpec.coffee b/node_modules/jasmine-node/spec/HelperSpec.coffee new file mode 100644 index 0000000..16498c0 --- /dev/null +++ b/node_modules/jasmine-node/spec/HelperSpec.coffee @@ -0,0 +1,6 @@ + +testClass 'HelperLoader', -> + feature 'Loading order', -> + should 'load the helpers before the specs.', -> + expect(true).toBeTruthy() + # will fail to parse the spec if the helper was not loaded first diff --git a/node_modules/jasmine-node/spec/SampleSpecs.js b/node_modules/jasmine-node/spec/SampleSpecs.js new file mode 100755 index 0000000..f9c001b --- /dev/null +++ b/node_modules/jasmine-node/spec/SampleSpecs.js @@ -0,0 +1,25 @@ +describe('jasmine-node', function(){ + + it('should pass', function(){ + expect(1+2).toEqual(3); + }); + + it('shows asynchronous test', function(){ + setTimeout(function(){ + expect('second').toEqual('second'); + asyncSpecDone(); + }, 1); + expect('first').toEqual('first'); + asyncSpecWait(); + }); + + it('shows asynchronous test node-style', function(done){ + setTimeout(function(){ + expect('second').toEqual('second'); + // If you call done() with an argument, it will fail the spec + // so you can use it as a handler for many async node calls + done(); + }, 1); + expect('first').toEqual('first'); + }); +}); diff --git a/node_modules/jasmine-node/spec/TestSpec.js b/node_modules/jasmine-node/spec/TestSpec.js new file mode 100755 index 0000000..36441c0 --- /dev/null +++ b/node_modules/jasmine-node/spec/TestSpec.js @@ -0,0 +1,100 @@ + +describe('jasmine-node-flat', function(){ + it('should pass', function(){ + expect(1+2).toEqual(3); + }); +}); + +describe('beforeEach Timeout', function(){ + beforeEach(function(done) { + setTimeout(done, 1000); + }, 100); + it('should fail', function(){ + expect(1+2).toEqual(3); + }); +}); + +describe('afterEach Timeout', function(){ + afterEach(function(done) { + setTimeout(done, 1000); + }, 100); + it('should pass and then afterEach will fail', function(){ + expect(1+2).toEqual(3); + }); +}); + +describe('Testing some characters', function() { + var chars = ['&', '\'', '"', '<', '>']; + for(var i = 0; i < chars.length; i+=1) { + currentChar = chars[i]; + it('should reject ' + currentChar, (function(currentChar) { + expect(false).toEqual(false); + })(currentChar)); + } +}); + +describe('Testing waitsfor functionality', function() { + it("Runs and then waitsFor", function() { + runs(function() { + 1+1; + }); + waitsFor(function() { + return true === false; + }, "the impossible", 1000); + runs(function() { + expect(true).toBeTruthy(); + }); + }); +}); + +describe('root', function () { + + describe('nested', function () { + + xit('nested statement', function () { + expect(1).toBeTruthy(); + }); + + }); + + it('root statement', function () { + expect(1).toBeTruthy(); + }); + +}); + +describe("Top level describe block", function() { + it("first it block in top level describe", function() { + expect(true).toEqual(true); + }); + describe("Second level describe block", function() { + it("first it block in second level describe", function() { + expect(true).toBe(true); + }); + }); + it("second it block in top level describe", function() { + expect(true).toEqual(true); + }); +}); + +describe('async', function () { + + var request = function (str, func) { + func('1', '2', 'hello world'); + }; + + it("should respond with hello world", function(done) { + request("http://localhost:3000/hello", function(error, response, body){ + expect(body).toEqual("hello world"); + done(); + }); + }); + + it("should respond with hello world", function(done) { + request("http://localhost:3000/hello", function(error, response, body){ + expect(body).toEqual("hello world"); + done(); + }); + }, 250); // timeout after 250 ms + +}); diff --git a/node_modules/jasmine-node/spec/TimerSpec.js b/node_modules/jasmine-node/spec/TimerSpec.js new file mode 100644 index 0000000..00d584c --- /dev/null +++ b/node_modules/jasmine-node/spec/TimerSpec.js @@ -0,0 +1,34 @@ +describe("Manually ticking the Jasmine Mock Clock", function() { + var timerCallback; + + beforeEach(function() { + timerCallback = jasmine.createSpy('timerCallback'); + jasmine.Clock.useMock(); + }); + + it("causes a timeout to be called synchronously", function() { + setTimeout(timerCallback, 100); + + expect(timerCallback).not.toHaveBeenCalled(); + + jasmine.Clock.tick(101); + + expect(timerCallback).toHaveBeenCalled(); + }); + + it("causes an interval to be called synchronously", function() { + setInterval(timerCallback, 100); + + expect(timerCallback).not.toHaveBeenCalled(); + + jasmine.Clock.tick(102); + expect(timerCallback).toHaveBeenCalled(); + expect(timerCallback.callCount).toEqual(1); + + jasmine.Clock.tick(50); + expect(timerCallback.callCount).toEqual(1); + + jasmine.Clock.tick(50); + expect(timerCallback.callCount).toEqual(2); + }); +}); diff --git a/node_modules/jasmine-node/spec/async-callback_spec.js b/node_modules/jasmine-node/spec/async-callback_spec.js new file mode 100644 index 0000000..79bd754 --- /dev/null +++ b/node_modules/jasmine-node/spec/async-callback_spec.js @@ -0,0 +1,174 @@ +describe('async-callback', function() { + var env; + beforeEach(function() { + env = new jasmine.Env(); + }); + + describe('it', function() { + + it("should time out if callback is not called", function() { + env.describe("it", function() { + env.it("doesn't wait", function(done) { + expect(1+2).toEqual(3); + }); + }); + + env.currentRunner().execute(); + + waitsFor(function() { + return env.currentRunner().results().totalCount > 0; + }, 6000); + + runs(function() { + expect(env.currentRunner().results().failedCount).toEqual(1); + expect(firstResult(env.currentRunner()).message).toMatch(/timeout/);; + }); + }); + + it("should accept timeout for individual spec", function() { + env.describe("it", function() { + env.it("doesn't wait", function(done) { + expect(1+2).toEqual(3); + }, 250); + }); + + env.currentRunner().execute(); + + waitsFor(function() { + return env.currentRunner().results().totalCount > 0; + }, 500); + + runs(function() { + expect(env.currentRunner().results().failedCount).toEqual(1); + expect(firstResult(env.currentRunner()).message).toMatch(/timeout/);; + }); + }); + + it("should fail if callback is passed error", function() { + env.describe("it", function() { + env.it("doesn't wait", function(done) { + process.nextTick(function() { + done("Failed asynchronously"); + }); + }); + }); + + env.currentRunner().execute(); + + waitsFor(function() { + return env.currentRunner().results().totalCount > 0; + }); + + runs(function() { + expect(env.currentRunner().results().failedCount).toEqual(1); + expect(firstResult(env.currentRunner()).message).toEqual("Failed asynchronously"); + }); + }); + + + it("should finish after callback is called", function() { + env.describe("it", function() { + env.it("waits", function(done) { + process.nextTick(function() { + env.currentSpec.expect(1+2).toEqual(3); + done(); + }); + }); + }); + + env.currentRunner().execute(); + + waitsFor(function() { + return env.currentRunner().results().totalCount > 0; + }, 2000); + + runs(function() { + expect(env.currentRunner().results().passedCount).toEqual(1); + }); + }); + + it('should run in the context of the current spec', function(){ + var actualContext; + var jasmineSpecContext; + env.describe("it", function() { + env.it("register context", function(done) { + actualContext = this; + jasmineSpecContext = env.currentSpec; + env.expect(this).toBe(jasmineSpecContext); + done(); + }); + }); + + env.currentRunner().execute(); + + waitsFor(function() { + return env.currentRunner().results().totalCount > 0; + }, 'tested jasmine env runner to run the test', 100); + + runs(function() { + expect(actualContext).not.toBe(global); + expect(actualContext).toBe(jasmineSpecContext); + }); + }); + + }); + + describe("beforeEach", function() { + it("should wait for callback", function() { + env.describe("beforeEach", function() { + var waited = false; + env.beforeEach(function(done) { + process.nextTick(function() { + waited = true; + done(); + }); + }); + env.it("waited", function() { + env.currentSpec.expect(waited).toBeTruthy(); + }); + }); + + env.currentRunner().execute(); + + waitsFor(function() { + return env.currentRunner().results().totalCount > 0; + }); + + runs(function() { + expect(env.currentRunner().results().passedCount).toEqual(1); + }); + }); + }); + + describe("afterEach", function() { + it("should be passed async callback", function() { + var completed = false; + env.describe("afterEach", function() { + env.afterEach(function(done) { + process.nextTick(function() { + done('Failed in afterEach'); + completed = true; + }); + }); + env.it("should pass", function() { + this.expect(1+2).toEqual(3); + }); + }); + + env.currentRunner().execute(); + + waitsFor(function() { + return completed === true; + }); + + runs(function() { + expect(env.currentRunner().results().passedCount).toEqual(1); + expect(env.currentRunner().results().failedCount).toEqual(1); + }); + }); + }); +}); + +function firstResult(runner) { + return runner.results().getItems()[0].getItems()[0].getItems()[0]; +} diff --git a/node_modules/jasmine-node/spec/helper_spec.js b/node_modules/jasmine-node/spec/helper_spec.js new file mode 100644 index 0000000..d157fd2 --- /dev/null +++ b/node_modules/jasmine-node/spec/helper_spec.js @@ -0,0 +1,7 @@ +describe("helper", function() { + it("should load the helpers", function() { + var expectation= expect(true); + + expect(typeof(expectation.toHaveProperty)).toBe('function'); + }); +}); \ No newline at end of file diff --git a/node_modules/jasmine-node/spec/litcoffee/Litcoffee.spec.litcoffee b/node_modules/jasmine-node/spec/litcoffee/Litcoffee.spec.litcoffee new file mode 100644 index 0000000..77eb791 --- /dev/null +++ b/node_modules/jasmine-node/spec/litcoffee/Litcoffee.spec.litcoffee @@ -0,0 +1,9 @@ +Literate CoffeeScript +==================== + +This is a spec using written in Literate CoffeeScript + + describe 'Coffee.litcoffee', -> + + it 'should pass', -> + expect(1+2).toEqual(3) diff --git a/node_modules/jasmine-node/spec/nested.js/NestedSpec.js b/node_modules/jasmine-node/spec/nested.js/NestedSpec.js new file mode 100644 index 0000000..e63ee64 --- /dev/null +++ b/node_modules/jasmine-node/spec/nested.js/NestedSpec.js @@ -0,0 +1,5 @@ +describe('jasmine-node-nested.js', function(){ + it('should pass', function(){ + expect(1+2).toEqual(3); + }); +}); diff --git a/node_modules/jasmine-node/spec/nested/NestedSpec.js b/node_modules/jasmine-node/spec/nested/NestedSpec.js new file mode 100755 index 0000000..6d27d30 --- /dev/null +++ b/node_modules/jasmine-node/spec/nested/NestedSpec.js @@ -0,0 +1,5 @@ +describe('jasmine-node-nested', function(){ + it('should pass', function(){ + expect(1+2).toEqual(3); + }); +}); diff --git a/node_modules/jasmine-node/spec/nested/uber-nested/UberNestedSpec.js b/node_modules/jasmine-node/spec/nested/uber-nested/UberNestedSpec.js new file mode 100755 index 0000000..146203b --- /dev/null +++ b/node_modules/jasmine-node/spec/nested/uber-nested/UberNestedSpec.js @@ -0,0 +1,11 @@ +describe('jasmine-node-uber-nested', function(){ + it('should pass', function(){ + expect(1+2).toEqual(3); + }); + + describe('failure', function(){ + it('should report failure (THIS IS EXPECTED)', function(){ + expect(true).toBeFalsy(); + }); + }); +}); diff --git a/node_modules/jasmine-node/spec/reporter_spec.js b/node_modules/jasmine-node/spec/reporter_spec.js new file mode 100644 index 0000000..19cdddd --- /dev/null +++ b/node_modules/jasmine-node/spec/reporter_spec.js @@ -0,0 +1,495 @@ +var jasmineNode = require(__dirname + "/../lib/jasmine-node/reporter").jasmineNode; + +describe('TerminalReporter', function() { + beforeEach(function() { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + }); + + describe("initialize", function() { + it('initializes print_ from config', function() { + var config = { print: true }; + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.print_).toBeTruthy(); + }); + + it('initializes color_ from config', function() { + var config = { color: true } + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.color_).toEqual(jasmineNode.TerminalReporter.prototype.ANSIColors); + }); + + it('initializes includeStackTrace_ from config', function () { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.includeStackTrace_).toBeTruthy(); + }); + + it('sets the started_ flag to false', function() { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.started_).toBeFalsy(); + }); + + it('sets the finished_ flag to false', function() { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.finished_).toBeFalsy(); + }); + + it('initializes the suites_ array', function() { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.suites_.length).toEqual(0); + }); + + it('initializes the specResults_ to an Object', function() { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.specResults_).toBeDefined(); + }); + + it('initializes the failures_ array', function() { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.failures_.length).toEqual(0); + }); + + it('sets the callback_ property to false by default', function() { + var config = {} + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.callback_).toEqual(false) + }); + + it('sets the callback_ property to onComplete if supplied', function() { + var foo = function() { } + var config = { onComplete: foo } + this.reporter = new jasmineNode.TerminalReporter(config); + expect(this.reporter.callback_).toBe(foo) + }); + }); + + describe('when the report runner starts', function() { + beforeEach(function() { + this.spy = spyOn(this.reporter, 'printLine_'); + + var runner = { + topLevelSuites: function() { + var suites = []; + var suite = { id: 25 }; + suites.push(suite); + return suites; + } + }; + this.reporter.reportRunnerStarting(runner); + }); + + it('sets the started_ field to true', function() { + expect(this.reporter.started_).toBeTruthy(); + }); + + it('sets the startedAt field', function() { + // instanceof does not work cross-context (such as when run with requirejs) + var ts = Object.prototype.toString; + expect(ts.call(this.reporter.startedAt)).toBe(ts.call(new Date())); + }); + + it('buildes the suites_ collection', function() { + expect(this.reporter.suites_.length).toEqual(1); + expect(this.reporter.suites_[0].id).toEqual(25); + }); + }); + + describe('the summarize_ creates suite and spec tree', function() { + beforeEach(function() { + this.spec = { + id: 1, + description: 'the spec', + isSuite: false + } + }); + + it('creates a summary object from spec', function() { + var result = this.reporter.summarize_(this.spec); + + expect(result.id).toEqual(1); + expect(result.name).toEqual('the spec'); + expect(result.type).toEqual('spec'); + expect(result.children.length).toEqual(0); + }); + + it('creates a summary object from suite with 1 spec', function() { + var env = { nextSuiteId: false } + var suite = new jasmine.Suite(env, 'suite name', undefined, undefined); + suite.description = 'the suite'; + suite.parentSuite = null; + suite.children_.push(this.spec); + + var result = this.reporter.summarize_(suite); + expect(result.name).toEqual('the suite'); + expect(result.type).toEqual('suite'); + expect(result.children.length).toEqual(1); + + var suiteChildSpec = result.children[0]; + expect(suiteChildSpec.id).toEqual(1); + }); + }); + + describe('reportRunnerResults', function() { + beforeEach(function() { + this.printLineSpy = spyOn(this.reporter, 'printLine_'); + }); + + it('generates the report', function() { + var failuresSpy = spyOn(this.reporter, 'reportFailures_'); + var printRunnerResultsSpy = spyOn(this.reporter, 'printRunnerResults_'). + andReturn('this is the runner result'); + + var callbackSpy = spyOn(this.reporter, 'callback_'); + + var runner = { + results: function() { + var result = { failedCount: 0 }; + return result; + }, + specs: function() { return []; } + }; + this.reporter.startedAt = new Date(); + + this.reporter.reportRunnerResults(runner); + + expect(failuresSpy).toHaveBeenCalled(); + expect(this.printLineSpy).toHaveBeenCalled(); + expect(callbackSpy).toHaveBeenCalled(); + }); + }); + + describe('reportSpecResults', function() { + beforeEach(function() { + this.printSpy = spyOn(this.reporter, 'print_'); + this.spec = { + id: 1, + description: 'the spec', + isSuite: false, + results: function() { + var result = { + passed: function() { return true; } + } + return result; + } + } + }); + + it('prints a \'.\' for pass', function() { + this.reporter.reportSpecResults(this.spec); + expect(this.printSpy).toHaveBeenCalledWith('.'); + }); + + it('prints an \'F\' for failure', function() { + var addFailureToFailuresSpy = spyOn(this.reporter, 'addFailureToFailures_'); + var results = function() { + var result = { + passed: function() { return false; } + } + return result; + } + this.spec.results = results; + + this.reporter.reportSpecResults(this.spec); + + expect(this.printSpy).toHaveBeenCalledWith('F'); + expect(addFailureToFailuresSpy).toHaveBeenCalled(); + }); + }); + + describe('addFailureToFailures', function() { + it('adds message and stackTrace to failures_', function() { + var spec = { + suite: { + getFullName: function() { return 'Suite name' } + }, + description: 'the spec', + results: function() { + var result = { + items_: function() { + var theItems = new Array(); + var item = { + passed_: false, + message: 'the message', + trace: { + stack: 'the stack' + } + } + theItems.push(item); + return theItems; + }.call() + }; + return result; + } + }; + + this.reporter.addFailureToFailures_(spec); + + var failures = this.reporter.failures_; + expect(failures.length).toEqual(1); + var failure = failures[0]; + expect(failure.spec).toEqual('Suite name the spec'); + expect(failure.message).toEqual('the message'); + expect(failure.stackTrace).toEqual('the stack'); + }); + }); + + describe('prints the runner results', function() { + beforeEach(function() { + this.runner = { + results: function() { + var _results = { + totalCount: 23, + failedCount: 52 + }; + return _results; + }, + specs: function() { + var _specs = new Array(); + spec = { + results: function() { + var _results = { + skipped: false + } + return _results; + } + }; + _specs.push(spec); + return _specs; + } + }; + }); + + it('uses the specs\'s length, totalCount and failedCount', function() { + var message = this.reporter.printRunnerResults_(this.runner); + expect(message).toEqual('1 test, 23 assertions, 52 failures, 0 skipped\n'); + }); + }); + + describe('reports failures', function() { + beforeEach(function() { + this.printSpy = spyOn(this.reporter, 'print_'); + this.printLineSpy = spyOn(this.reporter, 'printLine_'); + }); + + it('does not report anything when there are no failures', function() { + this.reporter.failures_ = new Array(); + + this.reporter.reportFailures_(); + + expect(this.printLineSpy).not.toHaveBeenCalled(); + }); + + it('prints the failures', function() { + var failure = { + spec: 'the spec', + message: 'the message', + stackTrace: 'the stackTrace' + } + + this.reporter.failures_ = new Array(); + this.reporter.failures_.push(failure); + + this.reporter.reportFailures_(); + + var generatedOutput = + [ [ '\n' ], + [ '\n' ], + [ ' 1) the spec' ], + [ ' Message:' ], + [ ' the message' ], + [ ' Stacktrace:' ] ]; + + expect(this.printLineSpy).toHaveBeenCalled(); + expect(this.printLineSpy.argsForCall).toEqual(generatedOutput); + + expect(this.printSpy).toHaveBeenCalled(); + expect(this.printSpy.argsForCall[0]).toEqual(['Failures:']); + expect(this.printSpy.argsForCall[1]).toEqual([' the stackTrace']); + }); + + it('prints the failures without a Stacktrace', function () { + var config = { includeStackTrace: false }; + this.reporter = new jasmineNode.TerminalReporter(config); + this.printSpy = spyOn(this.reporter, 'print_'); + this.printLineSpy = spyOn(this.reporter, 'printLine_'); + + var failure = { + spec: 'the spec', + message: 'the message', + stackTrace: 'the stackTrace' + } + + this.reporter.failures_ = new Array(); + this.reporter.failures_.push(failure); + + this.reporter.reportFailures_(); + + var generatedOutput = + [ [ '\n' ], + [ '\n' ], + [ ' 1) the spec' ], + [ ' Message:' ], + [ ' the message' ] ]; + + expect(this.printLineSpy).toHaveBeenCalled(); + expect(this.printLineSpy.argsForCall).toEqual(generatedOutput); + + expect(this.printSpy).toHaveBeenCalled(); + expect(this.printSpy.argsForCall[0]).toEqual(['Failures:']); + expect(this.printSpy.argsForCall[1]).toBeUndefined(); + }); + }); +}); + +describe('TerminalVerboseReporter', function() { + beforeEach(function() { + var config = {} + this.verboseReporter = new jasmineNode.TerminalVerboseReporter(config); + this.addFailureToFailuresSpy = spyOn(this.verboseReporter, 'addFailureToFailures_'); + this.spec = { + id: 23, + results: function() { + return { + failedCount: 1, + getItems: function() { + return ["this is the message"]; + } + } + } + }; + }); + + describe('#reportSpecResults', function() { + it('adds the spec to the failures_', function() { + this.verboseReporter.reportSpecResults(this.spec); + + expect(this.addFailureToFailuresSpy).toHaveBeenCalledWith(this.spec); + }); + + it('adds a new object to the specResults_', function() { + this.verboseReporter.reportSpecResults(this.spec); + + expect(this.verboseReporter.specResults_[23].messages).toEqual(['this is the message']); + expect(this.verboseReporter.specResults_[23].result).toEqual('failed'); + }); + }); + + describe('#buildMessagesFromResults_', function() { + beforeEach(function() { + this.suite = { + id: 17, + type: 'suite', + name: 'a describe block', + suiteNestingLevel: 0, + children: [], + getFullName: function() { return "A spec"; }, + }; + + this.spec = { + id: 23, + type: 'spec', + name: 'a spec block', + children: [] + }; + + this.verboseReporter.specResults_['23'] = { + result: 'passed', + runtime: 200 + }; + + this.verboseReporter.suiteResults_['17'] = { + runtime: 500 + }; + + }); + + it('does not build anything when the results collection is empty', function() { + var results = [], + messages = []; + + this.verboseReporter.buildMessagesFromResults_(messages, results); + + expect(messages.length).toEqual(0); + }); + + it('adds a single suite to the messages', function() { + var results = [], + messages = []; + + results.push(this.suite); + + this.verboseReporter.buildMessagesFromResults_(messages, results); + + expect(messages.length).toEqual(2); + expect(messages[0]).toEqual(''); + expect(messages[1]).toEqual('a describe block - 500 ms'); + }); + + it('adds a single spec with success to the messages', function() { + var results = [], + messages = []; + + this.passSpy = spyOn(this.verboseReporter.color_, 'pass'); + + results.push(this.spec); + + this.verboseReporter.buildMessagesFromResults_(messages, results); + + expect(this.passSpy).toHaveBeenCalled(); + expect(messages.length).toEqual(1); + expect(messages[0]).toEqual('a spec block - 200 ms'); + }); + + it('adds a single spec with failure to the messages', function() { + var results = [], + messages = []; + + this.verboseReporter.specResults_['23'].result = 'failed'; + + this.passSpy = spyOn(this.verboseReporter.color_, 'pass'); + this.failSpy = spyOn(this.verboseReporter.color_, 'fail'); + + results.push(this.spec); + + this.verboseReporter.buildMessagesFromResults_(messages, results); + + expect(this.failSpy).toHaveBeenCalled(); + expect(this.passSpy).not.toHaveBeenCalled(); + }); + + it('adds a suite, a suite and a single spec with success to the messages', function() { + var results = [], + messages = []; + + var subSuite = new Object(); + subSuite.id = '29'; + subSuite.type = 'suite'; + subSuite.name = 'a sub describe block'; + subSuite.suiteNestingLevel = 1; + subSuite.children = []; + subSuite.children.push(this.spec); + + this.suite.children.push(subSuite); + results.push(this.suite); + + this.verboseReporter.suiteResults_['29'] = { + runtime: 350 + }; + + this.verboseReporter.buildMessagesFromResults_(messages, results); + + expect(messages.length).toEqual(5); + expect(messages[0]).toEqual(''); + expect(messages[1]).toEqual('a describe block - 500 ms'); + expect(messages[2]).toEqual(''); + expect(messages[3]).toEqual(' a sub describe block - 350 ms'); + expect(messages[4]).toEqual(' a spec block - 200 ms'); + }); + }); +}); diff --git a/node_modules/jasmine-node/spec/sample_helper.js b/node_modules/jasmine-node/spec/sample_helper.js new file mode 100644 index 0000000..9f8032f --- /dev/null +++ b/node_modules/jasmine-node/spec/sample_helper.js @@ -0,0 +1,15 @@ +(function(){ + + var objectToString = Object.prototype.toString; + var PRIMITIVE_TYPES = [String, Number, RegExp, Boolean, Date]; + + jasmine.Matchers.prototype.toHaveProperty = function(prop) { + try { + return prop in this.actual; + } + catch (e) { + return false; + } + } + +})(); diff --git a/node_modules/jasmine-node/specs.sh b/node_modules/jasmine-node/specs.sh new file mode 100755 index 0000000..8f8011d --- /dev/null +++ b/node_modules/jasmine-node/specs.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +entry="node lib/jasmine-node/cli.js --noStack " + +echo "Running all tests located in the spec directory" +command=$entry"spec" +echo $command +time $command #/nested/uber-nested +echo -e "\033[1;35m--- Should have 59 tests and 104 assertions and 4 Failure. ---\033[0m" +echo "" + +echo "Running all tests located in the spec directory with coffee option" +command=$entry"--coffee spec" +echo $command +time $command #/nested/uber-nested +echo -e "\033[1;35m--- Should have 64 tests and 109 assertions and 6 Failures. ---\033[0m" +echo "" + +echo "Running all tests located in the spec directory with requirejs option" +#command=$entry"--nohelpers --runWithRequireJs spec-requirejs" +command=$entry"--runWithRequireJs spec" +echo $command +time $command +echo -e "\033[1;35m--- Should have 59 tests and 104 assertions and 4 Failure. ---\033[0m" +echo "" + +echo "Running all tests located in the spec-requirejs directory with requirejs, requirejs setup, and coffee option" +command=$entry"--runWithRequireJs --requireJsSetup spec-requirejs-coffee/requirejs-setup.js --coffee spec-requirejs-coffee" +echo $command +time $command +echo -e "\033[1;35m--- Should have 2 tests and 4 assertions and 0 Failure. ---\033[0m" + +echo "Running three specs file in the spec directory with coffee option" +command=$entry"--coffee spec/AsyncSpec.coffee spec/CoffeeSpec.coffee spec/SampleSpecs.js" +echo $command +time $command +echo -e "\033[1;35m--- Should have 3 tests and 3 assertions and 2 Failure. ---\033[0m" diff --git a/node_modules/jasmine-reporters/.npmignore b/node_modules/jasmine-reporters/.npmignore new file mode 100644 index 0000000..e8a93ed --- /dev/null +++ b/node_modules/jasmine-reporters/.npmignore @@ -0,0 +1,3 @@ +node_modules +*.pyc +*.swp diff --git a/node_modules/jasmine-reporters/LICENSE b/node_modules/jasmine-reporters/LICENSE new file mode 100644 index 0000000..fcc702f --- /dev/null +++ b/node_modules/jasmine-reporters/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2010 Larry Myers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/jasmine-reporters/README.markdown b/node_modules/jasmine-reporters/README.markdown new file mode 100644 index 0000000..0367b10 --- /dev/null +++ b/node_modules/jasmine-reporters/README.markdown @@ -0,0 +1,59 @@ +This branch is for Jasmine 1.x. +[Switch to the 2.x branch.](https://github.com/larrymyers/jasmine-reporters) + +# Jasmine Reporters + +Jasmine Reporters is a collection of javascript jasmine.Reporter classes that can be used with +the [JasmineBDD testing framework](http://jasmine.github.io/). + +Included reporters: + +* ConsoleReporter - Report test results to the browser console. +* JUnitXmlReporter - Report test results to a file in JUnit XML Report format. +* NUnitXmlReporter - Report test results to a file in NUnit XML Report format. +* TapReporter - Test Anything Protocol, report tests results to console. +* TeamcityReporter - Basic reporter that outputs spec results to for the Teamcity build system. +* TerminalReporter - Logs to a terminal (including colors) with variable verbosity. + +## Usage + +Examples are included in the test directory that show how to use the reporters, +as well a basic runner scripts for Rhino + envjs, and a basic runner for +[PhantomJS](https://github.com/ariya/phantomjs). Either of these methods could +be used in a Continuous Integration project for running headless tests and +generating JUnit XML output. + +### Rhino + EnvJS + +Everything needed to run the tests in Rhino + EnvJS is included in this +repository inside the `ext` directory, specifically Rhino 1.7r2 and envjs 1.2 +for Rhino. + +### PhantomJS + +Should work in most versions of PhantomJS > 1.4.1 +I have used PhantomJS 1.4.1 through 1.9.6 on Mac OS X with no problems. + +### Node.js + +Most of these reporters also work in node.js by making use of the excellent +[jasmine-node project](https://github.com/mhevery/jasmine-node). + +# Protractor + +Protractor 1.6.0 or above allows you to use either Jasmine 1 or Jasmine 2. +If you are using Jasmine 1, make sure you install a 1.x-compatible version of jasmine-reporters: + + npm install --save-dev jasmine-reporters@^1.0.0 + +Then set everything up inside your protractor.conf: + + onPrepare: function() { + // The require statement must be down here, since jasmine-reporters@1.0 + // expects jasmine to be in the global and protractor does not guarantee + // this until inside the onPrepare function. + require('jasmine-reporters'); + jasmine.getEnv().addReporter( + new jasmine.JUnitXmlReporter('xmloutput', true, true) + ); + } diff --git a/node_modules/jasmine-reporters/ext/env.rhino.1.2.js b/node_modules/jasmine-reporters/ext/env.rhino.1.2.js new file mode 100644 index 0000000..8da1c07 --- /dev/null +++ b/node_modules/jasmine-reporters/ext/env.rhino.1.2.js @@ -0,0 +1,13989 @@ +/* + * Envjs core-env.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +var Envjs = function(){ + var i, + name, + override = function(){ + for(i=0;i and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +//CLOSURE_START +(function(){ + + + + + +/** + * @author john resig + */ +// Helper method for extending one object with another. +function __extend__(a,b) { + for ( var i in b ) { + var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); + if ( g || s ) { + if ( g ) { a.__defineGetter__(i, g); } + if ( s ) { a.__defineSetter__(i, s); } + } else { + a[i] = b[i]; + } + } return a; +} + +/** + * Writes message to system out + * @param {String} message + */ +Envjs.log = function(message){}; + +/** + * Constants providing enumerated levels for logging in modules + */ +Envjs.DEBUG = 1; +Envjs.INFO = 2; +Envjs.WARN = 3; +Envjs.ERROR = 3; +Envjs.NONE = 3; + +/** + * Writes error info out to console + * @param {Error} e + */ +Envjs.lineSource = function(e){}; + + +/** + * TODO: used in ./event/eventtarget.js + * @param {Object} event + */ +Envjs.defaultEventBehaviors = {}; + + +/** + * describes which script src values will trigger Envjs to load + * the script like a browser would + */ +Envjs.scriptTypes = { + "text/javascript" :false, + "text/envjs" :true +}; + +/** + * will be called when loading a script throws an error + * @param {Object} script + * @param {Object} e + */ +Envjs.onScriptLoadError = function(script, e){ + console.log('error loading script %s %s', script, e); +}; + + +/** + * load and execute script tag text content + * @param {Object} script + */ +Envjs.loadInlineScript = function(script){ + var tmpFile; + tmpFile = Envjs.writeToTempFile(script.text, 'js') ; + load(tmpFile); +}; + +/** + * Should evaluate script in some context + * @param {Object} context + * @param {Object} source + * @param {Object} name + */ +Envjs.eval = function(context, source, name){}; + + +/** + * Executes a script tag + * @param {Object} script + * @param {Object} parser + */ +Envjs.loadLocalScript = function(script){ + //console.log("loading script %s", script); + var types, + src, + i, + base, + filename, + xhr; + + if(script.type){ + types = script.type.split(";"); + for(i=0;i + * - Via an innerHTML parse of a + * - A modificiation of the 'src' attribute of an Image/HTMLImageElement + * + * NOTE: this is optional API. If this doesn't exist then the default + * 'loaded' event occurs. + * + * @param node {Object} the node + * @param node the src value + * @return 'true' to indicate the 'load' succeed, false otherwise + */ +Envjs.loadImage = function(node, src) { + return true; +}; + + +/** + * A 'link' was requested by the document. Typically this occurs when: + * - During inital parse of a + * - Via an innerHTML parse of a + * - A modificiation of the 'href' attribute on a node in the tree + * + * @param node {Object} is the link node in question + * @param href {String} is the href. + * + * Return 'true' to indicate that the 'load' was successful, or false + * otherwise. The appropriate event is then triggered. + * + * NOTE: this is optional API. If this doesn't exist then the default + * 'loaded' event occurs + */ +Envjs.loadLink = function(node, href) { + return true; +}; + +(function(){ + + +/* + * cookie handling + * Private internal helper class used to save/retreive cookies + */ + +/** + * Specifies the location of the cookie file + */ +Envjs.cookieFile = function(){ + return 'file://'+Envjs.homedir+'/.cookies'; +}; + +/** + * saves cookies to a local file + * @param {Object} htmldoc + */ +Envjs.saveCookies = function(){ + var cookiejson = JSON.stringify(Envjs.cookies.peristent,null,'\t'); + //console.log('persisting cookies %s', cookiejson); + Envjs.writeToFile(cookiejson, Envjs.cookieFile()); +}; + +/** + * loads cookies from a local file + * @param {Object} htmldoc + */ +Envjs.loadCookies = function(){ + var cookiejson, + js; + try{ + cookiejson = Envjs.readFromFile(Envjs.cookieFile()) + js = JSON.parse(cookiejson, null, '\t'); + }catch(e){ + //console.log('failed to load cookies %s', e); + js = {}; + } + return js; +}; + +Envjs.cookies = { + persistent:{ + //domain - key on domain name { + //path - key on path { + //name - key on name { + //value : cookie value + //other cookie properties + //} + //} + //} + //expire - provides a timestamp for expiring the cookie + //cookie - the cookie! + }, + temporary:{//transient is a reserved word :( + //like above + } +}; + +var __cookies__; + +//HTMLDocument cookie +Envjs.setCookie = function(url, cookie){ + var i, + index, + name, + value, + properties = {}, + attr, + attrs; + url = Envjs.urlsplit(url); + if(cookie) + attrs = cookie.split(";"); + else + return; + + //for now the strategy is to simply create a json object + //and post it to a file in the .cookies.js file. I hate parsing + //dates so I decided not to implement support for 'expires' + //(which is deprecated) and instead focus on the easier 'max-age' + //(which succeeds 'expires') + cookie = {};//keyword properties of the cookie + cookie['domain'] = url.hostname; + cookie['path'] = url.path||'/'; + for(i=0;i -1){ + name = __trim__(attrs[i].slice(0,index)); + value = __trim__(attrs[i].slice(index+1)); + if(name=='max-age'){ + //we'll have to when to check these + //and garbage collect expired cookies + cookie[name] = parseInt(value, 10); + } else if( name == 'domain' ){ + if(__domainValid__(url, value)){ + cookie['domain'] = value; + } + } else if( name == 'path' ){ + //not sure of any special logic for path + cookie['path'] = value; + } else { + //its not a cookie keyword so store it in our array of properties + //and we'll serialize individually in a moment + properties[name] = value; + } + }else{ + if( attrs[i] == 'secure' ){ + cookie[attrs[i]] = true; + } + } + } + if(!('max-age' in cookie)){ + //it's a transient cookie so it only lasts as long as + //the window.location remains the same (ie in-memory cookie) + __mergeCookie__(Envjs.cookies.temporary, cookie, properties); + }else{ + //the cookie is persistent + __mergeCookie__(Envjs.cookies.persistent, cookie, properties); + Envjs.saveCookies(); + } +}; + +function __domainValid__(url, value){ + var i, + domainParts = url.hostname.split('.').reverse(), + newDomainParts = value.split('.').reverse(); + if(newDomainParts.length > 1){ + for(i=0;i -1) { + for (name in cookies[domain][path]) { + // console.log('cookie domain path name %s', name); + cookieString += + ((i++ > 0)?'; ':'') + + name + "=" + + cookies[domain][path][name].value; + } + } + } + } + } + return cookieString; +}; + +function __mergeCookie__(target, cookie, properties){ + var name, now; + if(!target[cookie.domain]){ + target[cookie.domain] = {}; + } + if(!target[cookie.domain][cookie.path]){ + target[cookie.domain][cookie.path] = {}; + } + for(name in properties){ + now = new Date().getTime(); + target[cookie.domain][cookie.path][name] = { + "value":properties[name], + "secure":cookie.secure, + "max-age":cookie['max-age'], + "date-created":now, + "expiration":(cookie['max-age']===0) ? + 0 : + now + cookie['max-age'] + }; + //console.log('cookie is %o',target[cookie.domain][cookie.path][name]); + } +}; + +})();//end cookies +/* + http://www.JSON.org/json2.js + 2008-07-15 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. +*/ +try{ JSON; }catch(e){ +JSON = function () { + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + Date.prototype.toJSON = function (key) { + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + String.prototype.toJSON = function (key) { + return String(this); + }; + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + + escapeable.lastIndex = 0; + return escapeable.test(string) ? + '"' + string.replace(escapeable, function (a) { + var c = meta[a]; + if (typeof c === 'string') { + return c; + } + return '\\u' + ('0000' + + (+(a.charCodeAt(0))).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + + return String(value); + + case 'object': + + if (!value) { + return 'null'; + } + gap += indent; + partial = []; + + if (typeof value.length === 'number' && + !(value.propertyIsEnumerable('length'))) { + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + + return { + stringify: function (value, replacer, space) { + + var i; + gap = ''; + indent = ''; + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + + } else if (typeof space === 'string') { + indent = space; + } + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + + return str('', {'': value}); + }, + + + parse: function (text, reviver) { + var j; + function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + ('0000' + + (+(a.charCodeAt(0))).toString(16)).slice(-4); + }); + } + + + if (/^[\],:{}\s]*$/. +test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + + j = eval('(' + text + ')'); + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + + throw new SyntaxError('JSON.parse'); + } + }; +}(); + +} + +/** + * synchronizes thread modifications + * @param {Function} fn + */ +Envjs.sync = function(fn){}; + +/** + * sleep thread for specified duration + * @param {Object} millseconds + */ +Envjs.sleep = function(millseconds){}; + +/** + * Interval to wait on event loop when nothing is happening + */ +Envjs.WAIT_INTERVAL = 20;//milliseconds + +/* + * Copyright (c) 2010 Nick Galbreath + * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript + * + * 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. + */ + +/* + * url processing in the spirit of python's urlparse module + * see `pydoc urlparse` or + * http://docs.python.org/library/urlparse.html + * + * urlsplit: break apart a URL into components + * urlunsplit: reconsistute a URL from componets + * urljoin: join an absolute and another URL + * urldefrag: remove the fragment from a URL + * + * Take a look at the tests in urlparse-test.html + * + * On URL Normalization: + * + * urlsplit only does minor normalization the components Only scheme + * and hostname are lowercased urljoin does a bit more, normalizing + * paths with "." and "..". + + * urlnormalize adds additional normalization + * + * * removes default port numbers + * http://abc.com:80/ -> http://abc.com/, etc + * * normalizes path + * http://abc.com -> http://abc.com/ + * and other "." and ".." cleanups + * * if file, remove query and fragment + * + * It does not do: + * * normalizes escaped hex values + * http://abc.com/%7efoo -> http://abc.com/%7Efoo + * * normalize '+' <--> '%20' + * + * Differences with Python + * + * The javascript urlsplit returns a normal object with the following + * properties: scheme, netloc, hostname, port, path, query, fragment. + * All properties are read-write. + * + * In python, the resulting object is not a dict, but a specialized, + * read-only, and has alternative tuple interface (e.g. obj[0] == + * obj.scheme). It's not clear why such a simple function requires + * a unique datastructure. + * + * urlunsplit in javascript takes an duck-typed object, + * { scheme: 'http', netloc: 'abc.com', ...} + * while in * python it takes a list-like object. + * ['http', 'abc.com'... ] + * + * For all functions, the javascript version use + * hostname+port if netloc is missing. In python + * hostname+port were always ignored. + * + * Similar functionality in different languages: + * + * http://php.net/manual/en/function.parse-url.php + * returns assocative array but cannot handle relative URL + * + * TODO: test allowfragments more + * TODO: test netloc missing, but hostname present + */ + +var urlparse = {}; + +// Unlike to be useful standalone +// +// NORMALIZE PATH with "../" and "./" +// http://en.wikipedia.org/wiki/URL_normalization +// http://tools.ietf.org/html/rfc3986#section-5.2.3 +// +urlparse.normalizepath = function(path) +{ + if (!path || path === '/') { + return '/'; + } + + var parts = path.split('/'); + + var newparts = []; + // make sure path always starts with '/' + if (parts[0]) { + newparts.push(''); + } + + for (var i = 0; i < parts.length; ++i) { + if (parts[i] === '..') { + if (newparts.length > 1) { + newparts.pop(); + } else { + newparts.push(parts[i]); + } + } else if (parts[i] != '.') { + newparts.push(parts[i]); + } + } + + path = newparts.join('/'); + if (!path) { + path = '/'; + } + return path; +}; + +// +// Does many of the normalizations that the stock +// python urlsplit/urlunsplit/urljoin neglects +// +// Doesn't do hex-escape normalization on path or query +// %7e -> %7E +// Nor, '+' <--> %20 translation +// +urlparse.urlnormalize = function(url) +{ + var parts = urlparse.urlsplit(url); + switch (parts.scheme) { + case 'file': + // files can't have query strings + // and we don't bother with fragments + parts.query = ''; + parts.fragment = ''; + break; + case 'http': + case 'https': + // remove default port + if ((parts.scheme === 'http' && parts.port == 80) || + (parts.scheme === 'https' && parts.port == 443)) { + parts.port = null; + // hostname is already lower case + parts.netloc = parts.hostname; + } + break; + default: + // if we don't have specific normalizations for this + // scheme, return the original url unmolested + return url; + } + + // for [file|http|https]. Not sure about other schemes + parts.path = urlparse.normalizepath(parts.path); + + return urlparse.urlunsplit(parts); +}; + +urlparse.urldefrag = function(url) +{ + var idx = url.indexOf('#'); + if (idx == -1) { + return [ url, '' ]; + } else { + return [ url.substr(0,idx), url.substr(idx+1) ]; + } +}; + +urlparse.urlsplit = function(url, default_scheme, allow_fragments) +{ + var leftover; + + if (typeof allow_fragments === 'undefined') { + allow_fragments = true; + } + + // scheme (optional), host, port + var fullurl = /^([A-Za-z]+)?(:?\/\/)([0-9.\-A-Za-z]*)(?::(\d+))?(.*)$/; + // path, query, fragment + var parse_leftovers = /([^?#]*)?(?:\?([^#]*))?(?:#(.*))?$/; + + var o = {}; + + var parts = url.match(fullurl); + if (parts) { + o.scheme = parts[1] || default_scheme || ''; + o.hostname = parts[3].toLowerCase() || ''; + o.port = parseInt(parts[4],10) || ''; + // Probably should grab the netloc from regexp + // and then parse again for hostname/port + + o.netloc = parts[3]; + if (parts[4]) { + o.netloc += ':' + parts[4]; + } + + leftover = parts[5]; + } else { + o.scheme = default_scheme || ''; + o.netloc = ''; + o.hostname = ''; + leftover = url; + } + o.scheme = o.scheme.toLowerCase(); + + parts = leftover.match(parse_leftovers); + + o.path = parts[1] || ''; + o.query = parts[2] || ''; + + if (allow_fragments) { + o.fragment = parts[3] || ''; + } else { + o.fragment = ''; + } + + return o; +}; + +urlparse.urlunsplit = function(o) { + var s = ''; + if (o.scheme) { + s += o.scheme + '://'; + } + + if (o.netloc) { + if (s == '') { + s += '//'; + } + s += o.netloc; + } else if (o.hostname) { + // extension. Python only uses netloc + if (s == '') { + s += '//'; + } + s += o.hostname; + if (o.port) { + s += ':' + o.port; + } + } + + if (o.path) { + s += o.path; + } + + if (o.query) { + s += '?' + o.query; + } + if (o.fragment) { + s += '#' + o.fragment; + } + return s; +}; + +urlparse.urljoin = function(base, url, allow_fragments) +{ + if (typeof allow_fragments === 'undefined') { + allow_fragments = true; + } + + var url_parts = urlparse.urlsplit(url); + + // if url parts has a scheme (i.e. absolute) + // then nothing to do + if (url_parts.scheme) { + if (! allow_fragments) { + return url; + } else { + return urlparse.urldefrag(url)[0]; + } + } + var base_parts = urlparse.urlsplit(base); + + // copy base, only if not present + if (!base_parts.scheme) { + base_parts.scheme = url_parts.scheme; + } + + // copy netloc, only if not present + if (!base_parts.netloc || !base_parts.hostname) { + base_parts.netloc = url_parts.netloc; + base_parts.hostname = url_parts.hostname; + base_parts.port = url_parts.port; + } + + // paths + if (url_parts.path.length > 0) { + if (url_parts.path.charAt(0) == '/') { + base_parts.path = url_parts.path; + } else { + // relative path.. get rid of "current filename" and + // replace. Same as var parts = + // base_parts.path.split('/'); parts[parts.length-1] = + // url_parts.path; base_parts.path = parts.join('/'); + var idx = base_parts.path.lastIndexOf('/'); + if (idx == -1) { + base_parts.path = url_parts.path; + } else { + base_parts.path = base_parts.path.substr(0,idx) + '/' + + url_parts.path; + } + } + } + + // clean up path + base_parts.path = urlparse.normalizepath(base_parts.path); + + // copy query string + base_parts.query = url_parts.query; + + // copy fragments + if (allow_fragments) { + base_parts.fragment = url_parts.fragment; + } else { + base_parts.fragment = ''; + } + + return urlparse.urlunsplit(base_parts); +}; + +/** + * getcwd - named after posix call of same name (see 'man 2 getcwd') + * + */ +Envjs.getcwd = function() { + return '.'; +}; + +/** + * resolves location relative to doc location + * + * @param {Object} path Relative or absolute URL + * @param {Object} base (semi-optional) The base url used in resolving "path" above + */ +Envjs.uri = function(path, base) { + //console.log('constructing uri from path %s and base %s', path, base); + + // Semi-common trick is to make an iframe with src='javascript:false' + // (or some equivalent). By returning '', the load is skipped + if (path.indexOf('javascript') === 0) { + return ''; + } + + // if path is absolute, then just normalize and return + if (path.match('^[a-zA-Z]+://')) { + return urlparse.urlnormalize(path); + } + + // interesting special case, a few very large websites use + // '//foo/bar/' to mean 'http://foo/bar' + if (path.match('^//')) { + path = 'http:' + path; + } + + // if base not passed in, try to get it from document + // Ideally I would like the caller to pass in document.baseURI to + // make this more self-sufficient and testable + if (!base && document) { + base = document.baseURI; + } + + // about:blank doesn't count + if (base === 'about:blank'){ + base = ''; + } + + // if base is still empty, then we are in QA mode loading local + // files. Get current working directory + if (!base) { + base = 'file://' + Envjs.getcwd() + '/'; + } + // handles all cases if path is abosulte or relative to base + // 3rd arg is "false" --> remove fragments + var newurl = urlparse.urlnormalize(urlparse.urljoin(base, path, false)); + + return newurl; +}; + + + +/** + * Used in the XMLHttpRquest implementation to run a + * request in a seperate thread + * @param {Object} fn + */ +Envjs.runAsync = function(fn){}; + + +/** + * Used to write to a local file + * @param {Object} text + * @param {Object} url + */ +Envjs.writeToFile = function(text, url){}; + + +/** + * Used to write to a local file + * @param {Object} text + * @param {Object} suffix + */ +Envjs.writeToTempFile = function(text, suffix){}; + +/** + * Used to read the contents of a local file + * @param {Object} url + */ +Envjs.readFromFile = function(url){}; + +/** + * Used to delete a local file + * @param {Object} url + */ +Envjs.deleteFile = function(url){}; + +/** + * establishes connection and calls responsehandler + * @param {Object} xhr + * @param {Object} responseHandler + * @param {Object} data + */ +Envjs.connection = function(xhr, responseHandler, data){}; + + +__extend__(Envjs, urlparse); + +/** + * Makes an object window-like by proxying object accessors + * @param {Object} scope + * @param {Object} parent + */ +Envjs.proxy = function(scope, parent, aliasList){}; + +Envjs.javaEnabled = false; + +Envjs.homedir = ''; +Envjs.tmpdir = ''; +Envjs.os_name = ''; +Envjs.os_arch = ''; +Envjs.os_version = ''; +Envjs.lang = ''; +Envjs.platform = ''; + +/** + * + * @param {Object} frameElement + * @param {Object} url + */ +Envjs.loadFrame = function(frame, url){ + try { + if(frame.contentWindow){ + //mark for garbage collection + frame.contentWindow = null; + } + + //create a new scope for the window proxy + //platforms will need to override this function + //to make sure the scope is global-like + frame.contentWindow = (function(){return this;})(); + new Window(frame.contentWindow, window); + + //I dont think frames load asynchronously in firefox + //and I think the tests have verified this but for + //some reason I'm less than confident... Are there cases? + frame.contentDocument = frame.contentWindow.document; + frame.contentDocument.async = false; + if(url){ + //console.log('envjs.loadFrame async %s', frame.contentDocument.async); + frame.contentWindow.location = url; + } + } catch(e) { + console.log("failed to load frame content: from %s %s", url, e); + } +}; + + +// The following are in rhino/window.js +// TODO: Envjs.unloadFrame +// TODO: Envjs.proxy + +/** + * @author john resig & the envjs team + * @uri http://www.envjs.com/ + * @copyright 2008-2010 + * @license MIT + */ +//CLOSURE_END +}()); +/* + * Envjs rhino-env.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +var __context__ = Packages.org.mozilla.javascript.Context.getCurrentContext(); + +Envjs.platform = "Rhino"; +Envjs.revision = "1.7.0.rc2"; + +/* + * Envjs rhino-env.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +//CLOSURE_START +(function(){ + + + + + +/** + * @author john resig + */ +// Helper method for extending one object with another. +function __extend__(a,b) { + for ( var i in b ) { + var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); + if ( g || s ) { + if ( g ) { a.__defineGetter__(i, g); } + if ( s ) { a.__defineSetter__(i, s); } + } else { + a[i] = b[i]; + } + } return a; +} + +/** + * Writes message to system out. + * + * Some sites redefine 'print' as in 'window.print', so instead of + * printing to stdout, you are popping open a new window, which might + * call print, etc, etc,etc This can cause infinite loops and can + * exhausing all memory. + * + * By defining this upfront now, Envjs.log will always call the native 'print' + * function + * + * @param {Object} message + */ +Envjs.log = print; + +Envjs.lineSource = function(e){ + return e&&e.rhinoException?e.rhinoException.lineSource():"(line ?)"; +}; +/** + * load and execute script tag text content + * @param {Object} script + */ +Envjs.loadInlineScript = function(script){ + if(script.ownerDocument.ownerWindow){ + Envjs.eval( + script.ownerDocument.ownerWindow, + script.text, + 'eval('+script.text.substring(0,16)+'...):'+new Date().getTime() + ); + }else{ + Envjs.eval( + __this__, + script.text, + 'eval('+script.text.substring(0,16)+'...):'+new Date().getTime() + ); + } + //console.log('evaluated at scope %s \n%s', + // script.ownerDocument.ownerWindow.guid, script.text); +}; + + +Envjs.eval = function(context, source, name){ + __context__.evaluateString( + context, + source, + name, + 0, + null + ); +}; + +//Temporary patch for parser module +Packages.org.mozilla.javascript.Context. + getCurrentContext().setOptimizationLevel(-1); + +/** + * Rhino provides a very succinct 'sync' + * @param {Function} fn + */ +try{ + Envjs.sync = sync; + Envjs.spawn = spawn; +} catch(e){ + //sync unavailable on AppEngine + Envjs.sync = function(fn){ + //console.log('Threadless platform, sync is safe'); + return fn; + }; + + Envjs.spawn = function(fn){ + //console.log('Threadless platform, spawn shares main thread.'); + return fn(); + }; +} + +/** + * sleep thread for specified duration + * @param {Object} millseconds + */ +Envjs.sleep = function(millseconds){ + try{ + java.lang.Thread.currentThread().sleep(millseconds); + }catch(e){ + console.log('Threadless platform, cannot sleep.'); + } +}; + +/** + * provides callback hook for when the system exits + */ +Envjs.onExit = function(callback){ + var rhino = Packages.org.mozilla.javascript, + contextFactory = __context__.getFactory(), + listener = new rhino.ContextFactory.Listener({ + contextReleased: function(context){ + if(context === __context__) + console.log('context released', context); + contextFactory.removeListener(this); + if(callback) + callback(); + } + }); + contextFactory.addListener(listener); +}; + +/** + * Get 'Current Working Directory' + */ +Envjs.getcwd = function() { + return java.lang.System.getProperty('user.dir'); +} + +/** + * + * @param {Object} fn + * @param {Object} onInterupt + */ +Envjs.runAsync = function(fn, onInterupt){ + ////Envjs.debug("running async"); + var running = true, + run; + + try{ + run = Envjs.sync(function(){ + fn(); + Envjs.wait(); + }); + Envjs.spawn(run); + }catch(e){ + console.log("error while running async operation", e); + try{if(onInterrupt)onInterrupt(e)}catch(ee){}; + } +}; + +/** + * Used to write to a local file + * @param {Object} text + * @param {Object} url + */ +Envjs.writeToFile = function(text, url){ + //Envjs.debug("writing text to url : " + url); + var out = new java.io.FileWriter( + new java.io.File( + new java.net.URI(url.toString()))); + out.write( text, 0, text.length ); + out.flush(); + out.close(); +}; + +/** + * Used to write to a local file + * @param {Object} text + * @param {Object} suffix + */ +Envjs.writeToTempFile = function(text, suffix){ + //Envjs.debug("writing text to temp url : " + suffix); + // Create temp file. + var temp = java.io.File.createTempFile("envjs-tmp", suffix); + + // Delete temp file when program exits. + temp.deleteOnExit(); + + // Write to temp file + var out = new java.io.FileWriter(temp); + out.write(text, 0, text.length); + out.close(); + return temp.getAbsolutePath().toString()+''; +}; + + +/** + * Used to read the contents of a local file + * @param {Object} url + */ +Envjs.readFromFile = function( url ){ + var fileReader = new java.io.FileReader( + new java.io.File( + new java.net.URI( url ))); + + var stringwriter = new java.io.StringWriter(), + buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024), + length; + + while ((length = fileReader.read(buffer, 0, 1024)) != -1) { + stringwriter.write(buffer, 0, length); + } + + stringwriter.close(); + return stringwriter.toString()+""; +}; + + +/** + * Used to delete a local file + * @param {Object} url + */ +Envjs.deleteFile = function(url){ + var file = new java.io.File( new java.net.URI( url ) ); + file["delete"](); +}; + +/** + * establishes connection and calls responsehandler + * @param {Object} xhr + * @param {Object} responseHandler + * @param {Object} data + */ +Envjs.connection = function(xhr, responseHandler, data){ + var url = java.net.URL(xhr.url), + connection, + header, + outstream, + buffer, + length, + binary = false, + name, value, + contentEncoding, + instream, + responseXML, + i; + if ( /^file\:/.test(url) ) { + try{ + if ( "PUT" == xhr.method || "POST" == xhr.method ) { + data = data || "" ; + Envjs.writeToFile(data, url); + xhr.readyState = 4; + //could be improved, I just cant recall the correct http codes + xhr.status = 200; + xhr.statusText = ""; + } else if ( xhr.method == "DELETE" ) { + Envjs.deleteFile(url); + xhr.readyState = 4; + //could be improved, I just cant recall the correct http codes + xhr.status = 200; + xhr.statusText = ""; + } else { + connection = url.openConnection(); + connection.connect(); + //try to add some canned headers that make sense + + try{ + if(xhr.url.match(/html$/)){ + xhr.responseHeaders["Content-Type"] = 'text/html'; + }else if(xhr.url.match(/.xml$/)){ + xhr.responseHeaders["Content-Type"] = 'text/xml'; + }else if(xhr.url.match(/.js$/)){ + xhr.responseHeaders["Content-Type"] = 'text/javascript'; + }else if(xhr.url.match(/.json$/)){ + xhr.responseHeaders["Content-Type"] = 'application/json'; + }else{ + xhr.responseHeaders["Content-Type"] = 'text/plain'; + } + //xhr.responseHeaders['Last-Modified'] = connection.getLastModified(); + //xhr.responseHeaders['Content-Length'] = headerValue+''; + //xhr.responseHeaders['Date'] = new Date()+'';*/ + }catch(e){ + console.log('failed to load response headers',e); + } + } + }catch(e){ + console.log('failed to open file %s %s', url, e); + connection = null; + xhr.readyState = 4; + xhr.statusText = "Local File Protocol Error"; + xhr.responseText = "

"+ e+ "

"; + } + } else { + connection = url.openConnection(); + connection.setRequestMethod( xhr.method ); + + // Add headers to Java connection + for (header in xhr.headers){ + connection.addRequestProperty(header+'', xhr.headers[header]+''); + } + + //write data to output stream if required + if(data){ + if(data instanceof Document){ + if ( xhr.method == "PUT" || xhr.method == "POST" ) { + connection.setDoOutput(true); + outstream = connection.getOutputStream(), + xml = (new XMLSerializer()).serializeToString(data); + buffer = new java.lang.String(xml).getBytes('UTF-8'); + outstream.write(buffer, 0, buffer.length); + outstream.close(); + } + }else if(data.length&&data.length>0){ + if ( xhr.method == "PUT" || xhr.method == "POST" ) { + connection.setDoOutput(true); + outstream = connection.getOutputStream(); + buffer = new java.lang.String(data).getBytes('UTF-8'); + outstream.write(buffer, 0, buffer.length); + outstream.close(); + } + } + connection.connect(); + }else{ + connection.connect(); + } + } + + if(connection){ + try{ + length = connection.getHeaderFields().size(); + // Stick the response headers into responseHeaders + for (i = 0; i < length; i++) { + name = connection.getHeaderFieldKey(i); + value = connection.getHeaderField(i); + if (name) + xhr.responseHeaders[name+''] = value+''; + } + }catch(e){ + console.log('failed to load response headers \n%s',e); + } + + xhr.readyState = 4; + xhr.status = parseInt(connection.responseCode,10) || undefined; + xhr.statusText = connection.responseMessage || ""; + + contentEncoding = connection.getContentEncoding() || "utf-8"; + instream = null; + responseXML = null; + + try{ + //console.log('contentEncoding %s', contentEncoding); + if( contentEncoding.equalsIgnoreCase("gzip") || + contentEncoding.equalsIgnoreCase("decompress")){ + //zipped content + binary = true; + outstream = new java.io.ByteArrayOutputStream(); + buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024); + instream = new java.util.zip.GZIPInputStream(connection.getInputStream()) + }else{ + //this is a text file + outstream = new java.io.StringWriter(); + buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024); + instream = new java.io.InputStreamReader(connection.getInputStream()); + } + }catch(e){ + if (connection.getResponseCode() == 404){ + console.log('failed to open connection stream \n %s %s', + e.toString(), e); + }else{ + console.log('failed to open connection stream \n %s %s', + e.toString(), e); + } + instream = connection.getErrorStream(); + } + + while ((length = instream.read(buffer, 0, 1024)) != -1) { + outstream.write(buffer, 0, length); + } + + outstream.close(); + instream.close(); + + if(binary){ + xhr.responseText = new String(outstream.toByteArray(), 'UTF-8') + ''; + }else{ + xhr.responseText = outstream.toString() + ''; + } + + } + if(responseHandler){ + //Envjs.debug('calling ajax response handler'); + responseHandler(); + } +}; + +//Since we're running in rhino I guess we can safely assume +//java is 'enabled'. I'm sure this requires more thought +//than I've given it here +Envjs.javaEnabled = true; + +Envjs.homedir = java.lang.System.getProperty("user.home"); +Envjs.tmpdir = java.lang.System.getProperty("java.io.tmpdir"); +Envjs.os_name = java.lang.System.getProperty("os.name"); +Envjs.os_arch = java.lang.System.getProperty("os.arch"); +Envjs.os_version = java.lang.System.getProperty("os.version"); +Envjs.lang = java.lang.System.getProperty("user.lang"); + + +/** + * + * @param {Object} frameElement + * @param {Object} url + */ +Envjs.loadFrame = function(frame, url){ + try { + if(frame.contentWindow){ + //mark for garbage collection + frame.contentWindow = null; + } + + //create a new scope for the window proxy + frame.contentWindow = Envjs.proxy(); + new Window(frame.contentWindow, window); + + //I dont think frames load asynchronously in firefox + //and I think the tests have verified this but for + //some reason I'm less than confident... Are there cases? + frame.contentDocument = frame.contentWindow.document; + frame.contentDocument.async = false; + if(url){ + //console.log('envjs.loadFrame async %s', frame.contentDocument.async); + frame.contentWindow.location = url; + } + } catch(e) { + console.log("failed to load frame content: from %s %s", url, e); + } +}; + +/** + * unloadFrame + * @param {Object} frame + */ +Envjs.unloadFrame = function(frame){ + var all, length, i; + try{ + //TODO: probably self-referencing structures within a document tree + //preventing it from being entirely garbage collected once orphaned. + //Should have code to walk tree and break all links between contained + //objects. + frame.contentDocument = null; + if(frame.contentWindow){ + frame.contentWindow.close(); + } + gc(); + }catch(e){ + console.log(e); + } +}; + +/** + * Makes an object window-like by proxying object accessors + * @param {Object} scope + * @param {Object} parent + */ +Envjs.proxy = function(scope, parent) { + try{ + if(scope+'' == '[object global]'){ + return scope + }else{ + return __context__.initStandardObjects(); + } + }catch(e){ + console.log('failed to init standard objects %s %s \n%s', scope, parent, e); + } + +}; + +/** + * @author john resig & the envjs team + * @uri http://www.envjs.com/ + * @copyright 2008-2010 + * @license MIT + */ +//CLOSURE_END +}()); + +/** + * @author envjs team + */ +var Console, + console; + +/* + * Envjs console.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +//CLOSURE_START +(function(){ + + + + + +/** + * @author envjs team + * borrowed 99%-ish with love from firebug-lite + * + * http://wiki.commonjs.org/wiki/Console + */ +Console = function(module){ + var $level, + $logger, + $null = function(){}; + + + if(Envjs[module] && Envjs[module].loglevel){ + $level = Envjs.module.loglevel; + $logger = { + log: function(level){ + logFormatted(arguments, (module)+" "); + }, + debug: $level>1 ? $null: function() { + logFormatted(arguments, (module)+" debug"); + }, + info: $level>2 ? $null:function(){ + logFormatted(arguments, (module)+" info"); + }, + warn: $level>3 ? $null:function(){ + logFormatted(arguments, (module)+" warning"); + }, + error: $level>4 ? $null:function(){ + logFormatted(arguments, (module)+" error"); + } + }; + } else { + $logger = { + log: function(level){ + logFormatted(arguments, ""); + }, + debug: $null, + info: $null, + warn: $null, + error: $null + }; + } + + return $logger; +}; + +console = new Console("console",1); + +function logFormatted(objects, className) +{ + var html = []; + + var format = objects[0]; + var objIndex = 0; + + if (typeof(format) != "string") + { + format = ""; + objIndex = -1; + } + + var parts = parseFormat(format); + for (var i = 0; i < parts.length; ++i) + { + var part = parts[i]; + if (part && typeof(part) == "object") + { + var object = objects[++objIndex]; + part.appender(object, html); + } + else { + appendText(part, html); + } + } + + for (var i = objIndex+1; i < objects.length; ++i) + { + appendText(" ", html); + + var object = objects[i]; + if (typeof(object) == "string") { + appendText(object, html); + } else { + appendObject(object, html); + } + } + + Envjs.log(html.join(' ')); +} + +function parseFormat(format) +{ + var parts = []; + + var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/; + var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat}; + + for (var m = reg.exec(format); m; m = reg.exec(format)) + { + var type = m[8] ? m[8] : m[5]; + var appender = type in appenderMap ? appenderMap[type] : appendObject; + var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); + + parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); + parts.push({appender: appender, precision: precision}); + + format = format.substr(m.index+m[0].length); + } + + parts.push(format); + + return parts; +} + +function escapeHTML(value) +{ + return value; +} + +function objectToString(object) +{ + try + { + return object+""; + } + catch (exc) + { + return null; + } +} + +// ******************************************************************************************** + +function appendText(object, html) +{ + html.push(escapeHTML(objectToString(object))); +} + +function appendNull(object, html) +{ + html.push(escapeHTML(objectToString(object))); +} + +function appendString(object, html) +{ + html.push(escapeHTML(objectToString(object))); +} + +function appendInteger(object, html) +{ + html.push(escapeHTML(objectToString(object))); +} + +function appendFloat(object, html) +{ + html.push(escapeHTML(objectToString(object))); +} + +function appendFunction(object, html) +{ + var reName = /function ?(.*?)\(/; + var m = reName.exec(objectToString(object)); + var name = m ? m[1] : "function"; + html.push(escapeHTML(name)); +} + +function appendObject(object, html) +{ + try + { + if (object == undefined) { + appendNull("undefined", html); + } else if (object == null) { + appendNull("null", html); + } else if (typeof object == "string") { + appendString(object, html); + } else if (typeof object == "number") { + appendInteger(object, html); + } else if (typeof object == "function") { + appendFunction(object, html); + } else if (object.nodeType == 1) { + appendSelector(object, html); + } else if (typeof object == "object") { + appendObjectFormatted(object, html); + } else { + appendText(object, html); + } + } + catch (exc) + { + } +} + +function appendObjectFormatted(object, html) +{ + var text = objectToString(object); + var reObject = /\[object (.*?)\]/; + + var m = reObject.exec(text); + html.push( m ? m[1] : text); +} + +function appendSelector(object, html) +{ + + html.push(escapeHTML(object.nodeName.toLowerCase())); + if (object.id) { + html.push(escapeHTML(object.id)); + } + if (object.className) { + html.push(escapeHTML(object.className)); + } +} + +function appendNode(node, html) +{ + if (node.nodeType == 1) + { + html.push( node.nodeName.toLowerCase()); + + for (var i = 0; i < node.attributes.length; ++i) + { + var attr = node.attributes[i]; + if (!attr.specified) { + continue; + } + + html.push( attr.nodeName.toLowerCase(),escapeHTML(attr.nodeValue)); + } + + if (node.firstChild) + { + for (var child = node.firstChild; child; child = child.nextSibling) { + appendNode(child, html); + } + + html.push( node.nodeName.toLowerCase()); + } + } + else if (node.nodeType === 3) + { + html.push(escapeHTML(node.nodeValue)); + } +}; + +/** + * @author john resig & the envjs team + * @uri http://www.envjs.com/ + * @copyright 2008-2010 + * @license MIT + */ +//CLOSURE_END +}()); +/* + * Envjs dom.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + * + * Parts of the implementation were originally written by:\ + * and Jon van Noort (jon@webarcana.com.au) \ + * and David Joham (djoham@yahoo.com)",\ + * and Scott Severtson + * + * This file simply provides the global definitions we need to \ + * be able to correctly implement to core browser DOM interfaces." + */ + +var Attr, + CDATASection, + CharacterData, + Comment, + Document, + DocumentFragment, + DocumentType, + DOMException, + DOMImplementation, + Element, + Entity, + EntityReference, + NamedNodeMap, + Namespace, + Node, + NodeList, + Notation, + ProcessingInstruction, + Text, + Range, + XMLSerializer, + DOMParser; + + + +/* + * Envjs dom.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +//CLOSURE_START +(function(){ + + + + + +/** + * @author john resig + */ +// Helper method for extending one object with another. +function __extend__(a,b) { + for ( var i in b ) { + var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); + if ( g || s ) { + if ( g ) { a.__defineGetter__(i, g); } + if ( s ) { a.__defineSetter__(i, s); } + } else { + a[i] = b[i]; + } + } return a; +} + +/** + * @author john resig + */ +//from jQuery +function __setArray__( target, array ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties + target.length = 0; + Array.prototype.push.apply( target, array ); +} + +/** + * @class NodeList - + * provides the abstraction of an ordered collection of nodes + * + * @param ownerDocument : Document - the ownerDocument + * @param parentNode : Node - the node that the NodeList is attached to (or null) + */ +NodeList = function(ownerDocument, parentNode) { + this.length = 0; + this.parentNode = parentNode; + this.ownerDocument = ownerDocument; + this._readonly = false; + __setArray__(this, []); +}; + +__extend__(NodeList.prototype, { + item : function(index) { + var ret = null; + if ((index >= 0) && (index < this.length)) { + // bounds check + ret = this[index]; + } + // if the index is out of bounds, default value null is returned + return ret; + }, + get xml() { + var ret = "", + i; + + // create string containing the concatenation of the string values of each child + for (i=0; i < this.length; i++) { + if(this[i]){ + if(this[i].nodeType == Node.TEXT_NODE && i>0 && + this[i-1].nodeType == Node.TEXT_NODE){ + //add a single space between adjacent text nodes + ret += " "+this[i].xml; + }else{ + ret += this[i].xml; + } + } + } + return ret; + }, + toArray: function () { + var children = [], + i; + for ( i=0; i < this.length; i++) { + children.push (this[i]); + } + return children; + }, + toString: function(){ + return "[object NodeList]"; + } +}); + + +/** + * @method __findItemIndex__ + * find the item index of the node + * @author Jon van Noort (jon@webarcana.com.au) + * @param node : Node + * @return : int + */ +var __findItemIndex__ = function (nodelist, node) { + var ret = -1, i; + for (i=0; i= 0) && (refChildIndex <= nodelist.length)) { + // bounds check + if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + // node is a DocumentFragment + // append the children of DocumentFragment + Array.prototype.splice.apply(nodelist, + [refChildIndex, 0].concat(newChild.childNodes.toArray())); + } + else { + // append the newChild + Array.prototype.splice.apply(nodelist,[refChildIndex, 0, newChild]); + } + } +}; + +/** + * @method __replaceChild__ + * replace the specified Node in the NodeList at the specified index + * Used by Node.replaceChild(). Note: Node.replaceChild() is responsible + * for Node Pointer surgery __replaceChild__ simply modifies the internal + * data structure (Array). + * + * @param newChild : Node - the Node to be inserted + * @param refChildIndex : int - the array index to hold the Node + */ +var __replaceChild__ = function(nodelist, newChild, refChildIndex) { + var ret = null; + + // bounds check + if ((refChildIndex >= 0) && (refChildIndex < nodelist.length)) { + // preserve old child for return + ret = nodelist[refChildIndex]; + + if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + // node is a DocumentFragment + // get array containing children prior to refChild + Array.prototype.splice.apply(nodelist, + [refChildIndex, 1].concat(newChild.childNodes.toArray())); + } + else { + // simply replace node in array (links between Nodes are + // made at higher level) + nodelist[refChildIndex] = newChild; + } + } + // return replaced node + return ret; +}; + +/** + * @method __removeChild__ + * remove the specified Node in the NodeList at the specified index + * Used by Node.removeChild(). Note: Node.removeChild() is responsible + * for Node Pointer surgery __removeChild__ simply modifies the internal + * data structure (Array). + * @param refChildIndex : int - the array index holding the Node to be removed + */ +var __removeChild__ = function(nodelist, refChildIndex) { + var ret = null; + + if (refChildIndex > -1) { + // found it! + // return removed node + ret = nodelist[refChildIndex]; + + // rebuild array without removed child + Array.prototype.splice.apply(nodelist,[refChildIndex, 1]); + } + // return removed node + return ret; +}; + +/** + * @method __appendChild__ + * append the specified Node to the NodeList. Used by Node.appendChild(). + * Note: Node.appendChild() is responsible for Node Pointer surgery + * __appendChild__ simply modifies the internal data structure (Array). + * @param newChild : Node - the Node to be inserted + */ +var __appendChild__ = function(nodelist, newChild) { + if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + // node is a DocumentFragment + // append the children of DocumentFragment + Array.prototype.push.apply(nodelist, newChild.childNodes.toArray() ); + } else { + // simply add node to array (links between Nodes are made at higher level) + Array.prototype.push.apply(nodelist, [newChild]); + } + +}; + +/** + * @method __cloneNodes__ - + * Returns a NodeList containing clones of the Nodes in this NodeList + * @param deep : boolean - + * If true, recursively clone the subtree under each of the nodes; + * if false, clone only the nodes themselves (and their attributes, + * if it is an Element). + * @param parentNode : Node - the new parent of the cloned NodeList + * @return : NodeList - NodeList containing clones of the Nodes in this NodeList + */ +var __cloneNodes__ = function(nodelist, deep, parentNode) { + var cloneNodeList = new NodeList(nodelist.ownerDocument, parentNode); + + // create list containing clones of each child + for (var i=0; i < nodelist.length; i++) { + __appendChild__(cloneNodeList, nodelist[i].cloneNode(deep)); + } + + return cloneNodeList; +}; + + +var __ownerDocument__ = function(node){ + return (node.nodeType == Node.DOCUMENT_NODE)?node:node.ownerDocument; +}; + +/** + * @class Node - + * The Node interface is the primary datatype for the entire + * Document Object Model. It represents a single node in the + * document tree. + * @param ownerDocument : Document - The Document object associated with this node. + */ + +Node = function(ownerDocument) { + this.baseURI = 'about:blank'; + this.namespaceURI = null; + this.nodeName = ""; + this.nodeValue = null; + + // A NodeList that contains all children of this node. If there are no + // children, this is a NodeList containing no nodes. The content of the + // returned NodeList is "live" in the sense that, for instance, changes to + // the children of the node object that it was created from are immediately + // reflected in the nodes returned by the NodeList accessors; it is not a + // static snapshot of the content of the node. This is true for every + // NodeList, including the ones returned by the getElementsByTagName method. + this.childNodes = new NodeList(ownerDocument, this); + + // The first child of this node. If there is no such node, this is null + this.firstChild = null; + // The last child of this node. If there is no such node, this is null. + this.lastChild = null; + // The node immediately preceding this node. If there is no such node, + // this is null. + this.previousSibling = null; + // The node immediately following this node. If there is no such node, + // this is null. + this.nextSibling = null; + + this.attributes = null; + // The namespaces in scope for this node + this._namespaces = new NamespaceNodeMap(ownerDocument, this); + this._readonly = false; + + //IMPORTANT: These must come last so rhino will not iterate parent + // properties before child properties. (qunit.equiv issue) + + // The parent of this node. All nodes, except Document, DocumentFragment, + // and Attr may have a parent. However, if a node has just been created + // and not yet added to the tree, or if it has been removed from the tree, + // this is null + this.parentNode = null; + // The Document object associated with this node + this.ownerDocument = ownerDocument; + +}; + +// nodeType constants +Node.ELEMENT_NODE = 1; +Node.ATTRIBUTE_NODE = 2; +Node.TEXT_NODE = 3; +Node.CDATA_SECTION_NODE = 4; +Node.ENTITY_REFERENCE_NODE = 5; +Node.ENTITY_NODE = 6; +Node.PROCESSING_INSTRUCTION_NODE = 7; +Node.COMMENT_NODE = 8; +Node.DOCUMENT_NODE = 9; +Node.DOCUMENT_TYPE_NODE = 10; +Node.DOCUMENT_FRAGMENT_NODE = 11; +Node.NOTATION_NODE = 12; +Node.NAMESPACE_NODE = 13; + +Node.DOCUMENT_POSITION_EQUAL = 0x00; +Node.DOCUMENT_POSITION_DISCONNECTED = 0x01; +Node.DOCUMENT_POSITION_PRECEDING = 0x02; +Node.DOCUMENT_POSITION_FOLLOWING = 0x04; +Node.DOCUMENT_POSITION_CONTAINS = 0x08; +Node.DOCUMENT_POSITION_CONTAINED_BY = 0x10; +Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; + + +__extend__(Node.prototype, { + get localName(){ + return this.prefix? + this.nodeName.substring(this.prefix.length+1, this.nodeName.length): + this.nodeName; + }, + get prefix(){ + return this.nodeName.split(':').length>1? + this.nodeName.split(':')[0]: + null; + }, + set prefix(value){ + if(value === null){ + this.nodeName = this.localName; + }else{ + this.nodeName = value+':'+this.localName; + } + }, + hasAttributes : function() { + if (this.attributes.length == 0) { + return false; + }else{ + return true; + } + }, + get textContent(){ + return __recursivelyGatherText__(this); + }, + set textContent(newText){ + while(this.firstChild != null){ + this.removeChild( this.firstChild ); + } + var text = this.ownerDocument.createTextNode(newText); + this.appendChild(text); + }, + insertBefore : function(newChild, refChild) { + var prevNode; + + if(newChild==null){ + return newChild; + } + if(refChild==null){ + this.appendChild(newChild); + return this.newChild; + } + + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if Node is readonly + if (this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // throw Exception if newChild was not created by this Document + if (__ownerDocument__(this) != __ownerDocument__(newChild)) { + throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR)); + } + + // throw Exception if the node is an ancestor + if (__isAncestor__(this, newChild)) { + throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR)); + } + } + + // if refChild is specified, insert before it + if (refChild) { + // find index of refChild + var itemIndex = __findItemIndex__(this.childNodes, refChild); + // throw Exception if there is no child node with this id + if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) { + throw(new DOMException(DOMException.NOT_FOUND_ERR)); + } + + // if the newChild is already in the tree, + var newChildParent = newChild.parentNode; + if (newChildParent) { + // remove it + newChildParent.removeChild(newChild); + } + + // insert newChild into childNodes + __insertBefore__(this.childNodes, newChild, itemIndex); + + // do node pointer surgery + prevNode = refChild.previousSibling; + + // handle DocumentFragment + if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + if (newChild.childNodes.length > 0) { + // set the parentNode of DocumentFragment's children + for (var ind = 0; ind < newChild.childNodes.length; ind++) { + newChild.childNodes[ind].parentNode = this; + } + + // link refChild to last child of DocumentFragment + refChild.previousSibling = newChild.childNodes[newChild.childNodes.length-1]; + } + }else { + // set the parentNode of the newChild + newChild.parentNode = this; + // link refChild to newChild + refChild.previousSibling = newChild; + } + + }else { + // otherwise, append to end + prevNode = this.lastChild; + this.appendChild(newChild); + } + + if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + // do node pointer surgery for DocumentFragment + if (newChild.childNodes.length > 0) { + if (prevNode) { + prevNode.nextSibling = newChild.childNodes[0]; + }else { + // this is the first child in the list + this.firstChild = newChild.childNodes[0]; + } + newChild.childNodes[0].previousSibling = prevNode; + newChild.childNodes[newChild.childNodes.length-1].nextSibling = refChild; + } + }else { + // do node pointer surgery for newChild + if (prevNode) { + prevNode.nextSibling = newChild; + }else { + // this is the first child in the list + this.firstChild = newChild; + } + newChild.previousSibling = prevNode; + newChild.nextSibling = refChild; + } + + return newChild; + }, + replaceChild : function(newChild, oldChild) { + var ret = null; + + if(newChild==null || oldChild==null){ + return oldChild; + } + + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if Node is readonly + if (this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // throw Exception if newChild was not created by this Document + if (__ownerDocument__(this) != __ownerDocument__(newChild)) { + throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR)); + } + + // throw Exception if the node is an ancestor + if (__isAncestor__(this, newChild)) { + throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR)); + } + } + + // get index of oldChild + var index = __findItemIndex__(this.childNodes, oldChild); + + // throw Exception if there is no child node with this id + if (__ownerDocument__(this).implementation.errorChecking && (index < 0)) { + throw(new DOMException(DOMException.NOT_FOUND_ERR)); + } + + // if the newChild is already in the tree, + var newChildParent = newChild.parentNode; + if (newChildParent) { + // remove it + newChildParent.removeChild(newChild); + } + + // add newChild to childNodes + ret = __replaceChild__(this.childNodes,newChild, index); + + + if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + // do node pointer surgery for Document Fragment + if (newChild.childNodes.length > 0) { + for (var ind = 0; ind < newChild.childNodes.length; ind++) { + newChild.childNodes[ind].parentNode = this; + } + + if (oldChild.previousSibling) { + oldChild.previousSibling.nextSibling = newChild.childNodes[0]; + } else { + this.firstChild = newChild.childNodes[0]; + } + + if (oldChild.nextSibling) { + oldChild.nextSibling.previousSibling = newChild; + } else { + this.lastChild = newChild.childNodes[newChild.childNodes.length-1]; + } + + newChild.childNodes[0].previousSibling = oldChild.previousSibling; + newChild.childNodes[newChild.childNodes.length-1].nextSibling = oldChild.nextSibling; + } + } else { + // do node pointer surgery for newChild + newChild.parentNode = this; + + if (oldChild.previousSibling) { + oldChild.previousSibling.nextSibling = newChild; + }else{ + this.firstChild = newChild; + } + if (oldChild.nextSibling) { + oldChild.nextSibling.previousSibling = newChild; + }else{ + this.lastChild = newChild; + } + newChild.previousSibling = oldChild.previousSibling; + newChild.nextSibling = oldChild.nextSibling; + } + + return ret; + }, + removeChild : function(oldChild) { + if(!oldChild){ + return null; + } + // throw Exception if NamedNodeMap is readonly + if (__ownerDocument__(this).implementation.errorChecking && + (this._readonly || oldChild._readonly)) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // get index of oldChild + var itemIndex = __findItemIndex__(this.childNodes, oldChild); + + // throw Exception if there is no child node with this id + if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) { + throw(new DOMException(DOMException.NOT_FOUND_ERR)); + } + + // remove oldChild from childNodes + __removeChild__(this.childNodes, itemIndex); + + // do node pointer surgery + oldChild.parentNode = null; + + if (oldChild.previousSibling) { + oldChild.previousSibling.nextSibling = oldChild.nextSibling; + }else { + this.firstChild = oldChild.nextSibling; + } + if (oldChild.nextSibling) { + oldChild.nextSibling.previousSibling = oldChild.previousSibling; + }else { + this.lastChild = oldChild.previousSibling; + } + + oldChild.previousSibling = null; + oldChild.nextSibling = null; + + return oldChild; + }, + appendChild : function(newChild) { + if(!newChild){ + return null; + } + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if Node is readonly + if (this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // throw Exception if arg was not created by this Document + if (__ownerDocument__(this) != __ownerDocument__(this)) { + throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR)); + } + + // throw Exception if the node is an ancestor + if (__isAncestor__(this, newChild)) { + throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR)); + } + } + + // if the newChild is already in the tree, + var newChildParent = newChild.parentNode; + if (newChildParent) { + // remove it + //console.debug('removing node %s', newChild); + newChildParent.removeChild(newChild); + } + + // add newChild to childNodes + __appendChild__(this.childNodes, newChild); + + if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + // do node pointer surgery for DocumentFragment + if (newChild.childNodes.length > 0) { + for (var ind = 0; ind < newChild.childNodes.length; ind++) { + newChild.childNodes[ind].parentNode = this; + } + + if (this.lastChild) { + this.lastChild.nextSibling = newChild.childNodes[0]; + newChild.childNodes[0].previousSibling = this.lastChild; + this.lastChild = newChild.childNodes[newChild.childNodes.length-1]; + } else { + this.lastChild = newChild.childNodes[newChild.childNodes.length-1]; + this.firstChild = newChild.childNodes[0]; + } + } + } else { + // do node pointer surgery for newChild + newChild.parentNode = this; + if (this.lastChild) { + this.lastChild.nextSibling = newChild; + newChild.previousSibling = this.lastChild; + this.lastChild = newChild; + } else { + this.lastChild = newChild; + this.firstChild = newChild; + } + } + return newChild; + }, + hasChildNodes : function() { + return (this.childNodes.length > 0); + }, + cloneNode: function(deep) { + // use importNode to clone this Node + //do not throw any exceptions + try { + return __ownerDocument__(this).importNode(this, deep); + } catch (e) { + //there shouldn't be any exceptions, but if there are, return null + // may want to warn: $debug("could not clone node: "+e.code); + return null; + } + }, + normalize : function() { + var i; + var inode; + var nodesToRemove = new NodeList(); + + if (this.nodeType == Node.ELEMENT_NODE || this.nodeType == Node.DOCUMENT_NODE) { + var adjacentTextNode = null; + + // loop through all childNodes + for(i = 0; i < this.childNodes.length; i++) { + inode = this.childNodes.item(i); + + if (inode.nodeType == Node.TEXT_NODE) { + // this node is a text node + if (inode.length < 1) { + // this text node is empty + // add this node to the list of nodes to be remove + __appendChild__(nodesToRemove, inode); + }else { + if (adjacentTextNode) { + // previous node was also text + adjacentTextNode.appendData(inode.data); + // merge the data in adjacent text nodes + // add this node to the list of nodes to be removed + __appendChild__(nodesToRemove, inode); + } else { + // remember this node for next cycle + adjacentTextNode = inode; + } + } + } else { + // (soon to be) previous node is not a text node + adjacentTextNode = null; + // normalize non Text childNodes + inode.normalize(); + } + } + + // remove redundant Text Nodes + for(i = 0; i < nodesToRemove.length; i++) { + inode = nodesToRemove.item(i); + inode.parentNode.removeChild(inode); + } + } + }, + isSupported : function(feature, version) { + // use Implementation.hasFeature to determine if this feature is supported + return __ownerDocument__(this).implementation.hasFeature(feature, version); + }, + getElementsByTagName : function(tagname) { + // delegate to _getElementsByTagNameRecursive + // recurse childNodes + var nodelist = new NodeList(__ownerDocument__(this)); + for (var i = 0; i < this.childNodes.length; i++) { + __getElementsByTagNameRecursive__(this.childNodes.item(i), + tagname, + nodelist); + } + return nodelist; + }, + getElementsByTagNameNS : function(namespaceURI, localName) { + // delegate to _getElementsByTagNameNSRecursive + return __getElementsByTagNameNSRecursive__(this, namespaceURI, localName, + new NodeList(__ownerDocument__(this))); + }, + importNode : function(importedNode, deep) { + var i; + var importNode; + + //there is no need to perform namespace checks since everything has already gone through them + //in order to have gotten into the DOM in the first place. The following line + //turns namespace checking off in ._isValidNamespace + __ownerDocument__(this).importing = true; + + if (importedNode.nodeType == Node.ELEMENT_NODE) { + if (!__ownerDocument__(this).implementation.namespaceAware) { + // create a local Element (with the name of the importedNode) + importNode = __ownerDocument__(this).createElement(importedNode.tagName); + + // create attributes matching those of the importedNode + for(i = 0; i < importedNode.attributes.length; i++) { + importNode.setAttribute(importedNode.attributes.item(i).name, importedNode.attributes.item(i).value); + } + } else { + // create a local Element (with the name & namespaceURI of the importedNode) + importNode = __ownerDocument__(this).createElementNS(importedNode.namespaceURI, importedNode.nodeName); + + // create attributes matching those of the importedNode + for(i = 0; i < importedNode.attributes.length; i++) { + importNode.setAttributeNS(importedNode.attributes.item(i).namespaceURI, + importedNode.attributes.item(i).name, importedNode.attributes.item(i).value); + } + + // create namespace definitions matching those of the importedNode + for(i = 0; i < importedNode._namespaces.length; i++) { + importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName); + importNode._namespaces[i].value = importedNode._namespaces.item(i).value; + } + } + } else if (importedNode.nodeType == Node.ATTRIBUTE_NODE) { + if (!__ownerDocument__(this).implementation.namespaceAware) { + // create a local Attribute (with the name of the importedAttribute) + importNode = __ownerDocument__(this).createAttribute(importedNode.name); + } else { + // create a local Attribute (with the name & namespaceURI of the importedAttribute) + importNode = __ownerDocument__(this).createAttributeNS(importedNode.namespaceURI, importedNode.nodeName); + + // create namespace definitions matching those of the importedAttribute + for(i = 0; i < importedNode._namespaces.length; i++) { + importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName); + importNode._namespaces[i].value = importedNode._namespaces.item(i).value; + } + } + + // set the value of the local Attribute to match that of the importedAttribute + importNode.value = importedNode.value; + + } else if (importedNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + // create a local DocumentFragment + importNode = __ownerDocument__(this).createDocumentFragment(); + } else if (importedNode.nodeType == Node.NAMESPACE_NODE) { + // create a local NamespaceNode (with the same name & value as the importedNode) + importNode = __ownerDocument__(this).createNamespace(importedNode.nodeName); + importNode.value = importedNode.value; + } else if (importedNode.nodeType == Node.TEXT_NODE) { + // create a local TextNode (with the same data as the importedNode) + importNode = __ownerDocument__(this).createTextNode(importedNode.data); + } else if (importedNode.nodeType == Node.CDATA_SECTION_NODE) { + // create a local CDATANode (with the same data as the importedNode) + importNode = __ownerDocument__(this).createCDATASection(importedNode.data); + } else if (importedNode.nodeType == Node.PROCESSING_INSTRUCTION_NODE) { + // create a local ProcessingInstruction (with the same target & data as the importedNode) + importNode = __ownerDocument__(this).createProcessingInstruction(importedNode.target, importedNode.data); + } else if (importedNode.nodeType == Node.COMMENT_NODE) { + // create a local Comment (with the same data as the importedNode) + importNode = __ownerDocument__(this).createComment(importedNode.data); + } else { // throw Exception if nodeType is not supported + throw(new DOMException(DOMException.NOT_SUPPORTED_ERR)); + } + + if (deep) { + // recurse childNodes + for(i = 0; i < importedNode.childNodes.length; i++) { + importNode.appendChild(__ownerDocument__(this).importNode(importedNode.childNodes.item(i), true)); + } + } + + //reset importing + __ownerDocument__(this).importing = false; + return importNode; + + }, + contains : function(node){ + while(node && node != this ){ + node = node.parentNode; + } + return !!node; + }, + compareDocumentPosition : function(b){ + //console.log("comparing document position %s %s", this, b); + var i, + length, + a = this, + parent, + aparents, + bparents; + //handle a couple simpler case first + if(a === b) { + return Node.DOCUMENT_POSITION_EQUAL; + } + if(a.ownerDocument !== b.ownerDocument) { + return Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC| + Node.DOCUMENT_POSITION_FOLLOWING| + Node.DOCUMENT_POSITION_DISCONNECTED; + } + if(a.parentNode === b.parentNode){ + length = a.parentNode.childNodes.length; + for(i=0;i aparents.length){ + return Node.DOCUMENT_POSITION_FOLLOWING; + }else if(bparents.length < aparents.length){ + return Node.DOCUMENT_POSITION_PRECEDING; + }else{ + //common ancestor diverge point + if (i === 0) { + return Node.DOCUMENT_POSITION_FOLLOWING; + } else { + parent = aparents[i-1]; + } + return parent.compareDocumentPosition(bparents.pop()); + } + } + } + + return Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC| + Node.DOCUMENT_POSITION_DISCONNECTED; + + }, + toString : function() { + return '[object Node]'; + } + +}); + + + +/** + * @method __getElementsByTagNameRecursive__ - implements getElementsByTagName() + * @param elem : Element - The element which are checking and then recursing into + * @param tagname : string - The name of the tag to match on. The special value "*" matches all tags + * @param nodeList : NodeList - The accumulating list of matching nodes + * + * @return : NodeList + */ +var __getElementsByTagNameRecursive__ = function (elem, tagname, nodeList) { + + if (elem.nodeType == Node.ELEMENT_NODE || elem.nodeType == Node.DOCUMENT_NODE) { + + if(elem.nodeType !== Node.DOCUMENT_NODE && + ((elem.nodeName.toUpperCase() == tagname.toUpperCase()) || + (tagname == "*")) ){ + // add matching node to nodeList + __appendChild__(nodeList, elem); + } + + // recurse childNodes + for(var i = 0; i < elem.childNodes.length; i++) { + nodeList = __getElementsByTagNameRecursive__(elem.childNodes.item(i), tagname, nodeList); + } + } + + return nodeList; +}; + +/** + * @method __getElementsByTagNameNSRecursive__ + * implements getElementsByTagName() + * + * @param elem : Element - The element which are checking and then recursing into + * @param namespaceURI : string - the namespace URI of the required node + * @param localName : string - the local name of the required node + * @param nodeList : NodeList - The accumulating list of matching nodes + * + * @return : NodeList + */ +var __getElementsByTagNameNSRecursive__ = function(elem, namespaceURI, localName, nodeList) { + if (elem.nodeType == Node.ELEMENT_NODE || elem.nodeType == Node.DOCUMENT_NODE) { + + if (((elem.namespaceURI == namespaceURI) || (namespaceURI == "*")) && + ((elem.localName == localName) || (localName == "*"))) { + // add matching node to nodeList + __appendChild__(nodeList, elem); + } + + // recurse childNodes + for(var i = 0; i < elem.childNodes.length; i++) { + nodeList = __getElementsByTagNameNSRecursive__( + elem.childNodes.item(i), namespaceURI, localName, nodeList); + } + } + + return nodeList; +}; + +/** + * @method __isAncestor__ - returns true if node is ancestor of target + * @param target : Node - The node we are using as context + * @param node : Node - The candidate ancestor node + * @return : boolean + */ +var __isAncestor__ = function(target, node) { + // if this node matches, return true, + // otherwise recurse up (if there is a parentNode) + return ((target == node) || ((target.parentNode) && (__isAncestor__(target.parentNode, node)))); +}; + + + +var __recursivelyGatherText__ = function(aNode) { + var accumulateText = "", + idx, + node; + for (idx=0;idx < aNode.childNodes.length;idx++){ + node = aNode.childNodes.item(idx); + if(node.nodeType == Node.TEXT_NODE) + accumulateText += node.data; + else + accumulateText += __recursivelyGatherText__(node); + } + return accumulateText; +}; + +/** + * function __escapeXML__ + * @param str : string - The string to be escaped + * @return : string - The escaped string + */ +var escAmpRegEx = /&(?!(amp;|lt;|gt;|quot|apos;))/g; +var escLtRegEx = //g; +var quotRegEx = /"/g; +var aposRegEx = /'/g; + +function __escapeXML__(str) { + str = str.replace(escAmpRegEx, "&"). + replace(escLtRegEx, "<"). + replace(escGtRegEx, ">"). + replace(quotRegEx, """). + replace(aposRegEx, "'"); + + return str; +}; + +/* +function __escapeHTML5__(str) { + str = str.replace(escAmpRegEx, "&"). + replace(escLtRegEx, "<"). + replace(escGtRegEx, ">"); + + return str; +}; +function __escapeHTML5Atribute__(str) { + str = str.replace(escAmpRegEx, "&"). + replace(escLtRegEx, "<"). + replace(escGtRegEx, ">"). + replace(quotRegEx, """). + replace(aposRegEx, "'"); + + return str; +}; +*/ + +/** + * function __unescapeXML__ + * @param str : string - The string to be unescaped + * @return : string - The unescaped string + */ +var unescAmpRegEx = /&/g; +var unescLtRegEx = /</g; +var unescGtRegEx = />/g; +var unquotRegEx = /"/g; +var unaposRegEx = /'/g; +function __unescapeXML__(str) { + str = str.replace(unescAmpRegEx, "&"). + replace(unescLtRegEx, "<"). + replace(unescGtRegEx, ">"). + replace(unquotRegEx, "\""). + replace(unaposRegEx, "'"); + + return str; +}; + +/** + * @class NamedNodeMap - + * used to represent collections of nodes that can be accessed by name + * typically a set of Element attributes + * + * @extends NodeList - + * note W3C spec says that this is not the case, but we need an item() + * method identical to NodeList's, so why not? + * @param ownerDocument : Document - the ownerDocument + * @param parentNode : Node - the node that the NamedNodeMap is attached to (or null) + */ +NamedNodeMap = function(ownerDocument, parentNode) { + NodeList.apply(this, arguments); + __setArray__(this, []); +}; +NamedNodeMap.prototype = new NodeList(); +__extend__(NamedNodeMap.prototype, { + add: function(name){ + this[this.length] = name; + }, + getNamedItem : function(name) { + var ret = null; + //console.log('NamedNodeMap getNamedItem %s', name); + // test that Named Node exists + var itemIndex = __findNamedItemIndex__(this, name); + + if (itemIndex > -1) { + // found it! + ret = this[itemIndex]; + } + // if node is not found, default value null is returned + return ret; + }, + setNamedItem : function(arg) { + //console.log('setNamedItem %s', arg); + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if arg was not created by this Document + if (this.ownerDocument != arg.ownerDocument) { + throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR)); + } + + // throw Exception if DOMNamedNodeMap is readonly + if (this._readonly || (this.parentNode && this.parentNode._readonly)) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // throw Exception if arg is already an attribute of another Element object + if (arg.ownerElement && (arg.ownerElement != this.parentNode)) { + throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR)); + } + } + + //console.log('setNamedItem __findNamedItemIndex__ '); + // get item index + var itemIndex = __findNamedItemIndex__(this, arg.name); + var ret = null; + + //console.log('setNamedItem __findNamedItemIndex__ %s', itemIndex); + if (itemIndex > -1) { // found it! + ret = this[itemIndex]; // use existing Attribute + + // throw Exception if DOMAttr is readonly + if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } else { + this[itemIndex] = arg; // over-write existing NamedNode + this[arg.name.toLowerCase()] = arg; + } + } else { + // add new NamedNode + //console.log('setNamedItem add new named node map (by index)'); + Array.prototype.push.apply(this, [arg]); + //console.log('setNamedItem add new named node map (by name) %s %s', arg, arg.name); + this[arg.name] = arg; + //console.log('finsished setNamedItem add new named node map (by name) %s', arg.name); + + } + + //console.log('setNamedItem parentNode'); + arg.ownerElement = this.parentNode; // update ownerElement + // return old node or new node + //console.log('setNamedItem exit'); + return ret; + }, + removeNamedItem : function(name) { + var ret = null; + // test for exceptions + // throw Exception if NamedNodeMap is readonly + if (__ownerDocument__(this).implementation.errorChecking && + (this._readonly || (this.parentNode && this.parentNode._readonly))) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // get item index + var itemIndex = __findNamedItemIndex__(this, name); + + // throw Exception if there is no node named name in this map + if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) { + throw(new DOMException(DOMException.NOT_FOUND_ERR)); + } + + // get Node + var oldNode = this[itemIndex]; + //this[oldNode.name] = undefined; + + // throw Exception if Node is readonly + if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // return removed node + return __removeChild__(this, itemIndex); + }, + getNamedItemNS : function(namespaceURI, localName) { + var ret = null; + + // test that Named Node exists + var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName); + + if (itemIndex > -1) { + // found it! return NamedNode + ret = this[itemIndex]; + } + // if node is not found, default value null is returned + return ret; + }, + setNamedItemNS : function(arg) { + //console.log('setNamedItemNS %s', arg); + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if NamedNodeMap is readonly + if (this._readonly || (this.parentNode && this.parentNode._readonly)) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // throw Exception if arg was not created by this Document + if (__ownerDocument__(this) != __ownerDocument__(arg)) { + throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR)); + } + + // throw Exception if arg is already an attribute of another Element object + if (arg.ownerElement && (arg.ownerElement != this.parentNode)) { + throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR)); + } + } + + // get item index + var itemIndex = __findNamedItemNSIndex__(this, arg.namespaceURI, arg.localName); + var ret = null; + + if (itemIndex > -1) { + // found it! + // use existing Attribute + ret = this[itemIndex]; + // throw Exception if Attr is readonly + if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } else { + // over-write existing NamedNode + this[itemIndex] = arg; + } + }else { + // add new NamedNode + Array.prototype.push.apply(this, [arg]); + } + arg.ownerElement = this.parentNode; + + // return old node or null + return ret; + //console.log('finished setNamedItemNS %s', arg); + }, + removeNamedItemNS : function(namespaceURI, localName) { + var ret = null; + + // test for exceptions + // throw Exception if NamedNodeMap is readonly + if (__ownerDocument__(this).implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // get item index + var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName); + + // throw Exception if there is no matching node in this map + if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) { + throw(new DOMException(DOMException.NOT_FOUND_ERR)); + } + + // get Node + var oldNode = this[itemIndex]; + + // throw Exception if Node is readonly + if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + return __removeChild__(this, itemIndex); // return removed node + }, + get xml() { + var ret = ""; + + // create string containing concatenation of all (but last) Attribute string values (separated by spaces) + for (var i=0; i < this.length -1; i++) { + ret += this[i].xml +" "; + } + + // add last Attribute to string (without trailing space) + if (this.length > 0) { + ret += this[this.length -1].xml; + } + + return ret; + }, + toString : function(){ + return "[object NamedNodeMap]"; + } + +}); + +/** + * @method __findNamedItemIndex__ + * find the item index of the node with the specified name + * + * @param name : string - the name of the required node + * @param isnsmap : if its a NamespaceNodeMap + * @return : int + */ +var __findNamedItemIndex__ = function(namednodemap, name, isnsmap) { + var ret = -1; + // loop through all nodes + for (var i=0; i -1) { + // found it! + ret = true; + } + // if node is not found, default value false is returned + return ret; +} + +/** + * @method __hasAttributeNS__ + * Returns true if specified node exists + * + * @param namespaceURI : string - the namespace URI of the required node + * @param localName : string - the local name of the required node + * @return : boolean + */ +var __hasAttributeNS__ = function(namednodemap, namespaceURI, localName) { + var ret = false; + // test that Named Node exists + var itemIndex = __findNamedItemNSIndex__(namednodemap, namespaceURI, localName); + if (itemIndex > -1) { + // found it! + ret = true; + } + // if node is not found, default value false is returned + return ret; +} + +/** + * @method __cloneNamedNodes__ + * Returns a NamedNodeMap containing clones of the Nodes in this NamedNodeMap + * + * @param parentNode : Node - the new parent of the cloned NodeList + * @param isnsmap : bool - is this a NamespaceNodeMap + * @return NamedNodeMap containing clones of the Nodes in this NamedNodeMap + */ +var __cloneNamedNodes__ = function(namednodemap, parentNode, isnsmap) { + var cloneNamedNodeMap = isnsmap? + new NamespaceNodeMap(namednodemap.ownerDocument, parentNode): + new NamedNodeMap(namednodemap.ownerDocument, parentNode); + + // create list containing clones of all children + for (var i=0; i < namednodemap.length; i++) { + __appendChild__(cloneNamedNodeMap, namednodemap[i].cloneNode(false)); + } + + return cloneNamedNodeMap; +}; + + +/** + * @class NamespaceNodeMap - + * used to represent collections of namespace nodes that can be + * accessed by name typically a set of Element attributes + * + * @extends NamedNodeMap + * + * @param ownerDocument : Document - the ownerDocument + * @param parentNode : Node - the node that the NamespaceNodeMap is attached to (or null) + */ +var NamespaceNodeMap = function(ownerDocument, parentNode) { + this.NamedNodeMap = NamedNodeMap; + this.NamedNodeMap(ownerDocument, parentNode); + __setArray__(this, []); +}; +NamespaceNodeMap.prototype = new NamedNodeMap(); +__extend__(NamespaceNodeMap.prototype, { + get xml() { + var ret = "", + ns, + ind; + // identify namespaces declared local to this Element (ie, not inherited) + for (ind = 0; ind < this.length; ind++) { + // if namespace declaration does not exist in the containing node's, parentNode's namespaces + ns = null; + try { + var ns = this.parentNode.parentNode._namespaces. + getNamedItem(this[ind].localName); + }catch (e) { + //breaking to prevent default namespace being inserted into return value + break; + } + if (!(ns && (""+ ns.nodeValue == ""+ this[ind].nodeValue))) { + // display the namespace declaration + ret += this[ind].xml +" "; + } + } + return ret; + } +}); + +/** + * @class Namespace - + * The Namespace interface represents an namespace in an Element object + * + * @param ownerDocument : The Document object associated with this node. + */ +Namespace = function(ownerDocument) { + Node.apply(this, arguments); + // the name of this attribute + this.name = ""; + + // If this attribute was explicitly given a value in the original document, + // this is true; otherwise, it is false. + // Note that the implementation is in charge of this attribute, not the user. + // If the user changes the value of the attribute (even if it ends up having + // the same value as the default value) then the specified flag is + // automatically flipped to true + this.specified = false; +}; +Namespace.prototype = new Node(); +__extend__(Namespace.prototype, { + get value(){ + // the value of the attribute is returned as a string + return this.nodeValue; + }, + set value(value){ + this.nodeValue = value+''; + }, + get nodeType(){ + return Node.NAMESPACE_NODE; + }, + get xml(){ + var ret = ""; + + // serialize Namespace Declaration + if (this.nodeName != "") { + ret += this.nodeName +"=\""+ __escapeXML__(this.nodeValue) +"\""; + } + else { // handle default namespace + ret += "xmlns=\""+ __escapeXML__(this.nodeValue) +"\""; + } + + return ret; + }, + toString: function(){ + return '[object Namespace]'; + } +}); + + +/** + * @class CharacterData - parent abstract class for Text and Comment + * @extends Node + * @param ownerDocument : The Document object associated with this node. + */ +CharacterData = function(ownerDocument) { + Node.apply(this, arguments); +}; +CharacterData.prototype = new Node(); +__extend__(CharacterData.prototype,{ + get data(){ + return this.nodeValue; + }, + set data(data){ + this.nodeValue = data; + }, + get textContent(){ + return this.nodeValue; + }, + set textContent(newText){ + this.nodeValue = newText; + }, + get length(){return this.nodeValue.length;}, + appendData: function(arg){ + // throw Exception if CharacterData is readonly + if (__ownerDocument__(this).implementation.errorChecking && this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + // append data + this.data = "" + this.data + arg; + }, + deleteData: function(offset, count){ + // throw Exception if CharacterData is readonly + if (__ownerDocument__(this).implementation.errorChecking && this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + if (this.data) { + // throw Exception if offset is negative or greater than the data length, + if (__ownerDocument__(this).implementation.errorChecking && + ((offset < 0) || (offset > this.data.length) || (count < 0))) { + throw(new DOMException(DOMException.INDEX_SIZE_ERR)); + } + + // delete data + if(!count || (offset + count) > this.data.length) { + this.data = this.data.substring(0, offset); + }else { + this.data = this.data.substring(0, offset). + concat(this.data.substring(offset + count)); + } + } + }, + insertData: function(offset, arg){ + // throw Exception if CharacterData is readonly + if(__ownerDocument__(this).implementation.errorChecking && this._readonly){ + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + if(this.data){ + // throw Exception if offset is negative or greater than the data length, + if (__ownerDocument__(this).implementation.errorChecking && + ((offset < 0) || (offset > this.data.length))) { + throw(new DOMException(DOMException.INDEX_SIZE_ERR)); + } + + // insert data + this.data = this.data.substring(0, offset).concat(arg, this.data.substring(offset)); + }else { + // throw Exception if offset is negative or greater than the data length, + if (__ownerDocument__(this).implementation.errorChecking && (offset !== 0)) { + throw(new DOMException(DOMException.INDEX_SIZE_ERR)); + } + + // set data + this.data = arg; + } + }, + replaceData: function(offset, count, arg){ + // throw Exception if CharacterData is readonly + if (__ownerDocument__(this).implementation.errorChecking && this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + if (this.data) { + // throw Exception if offset is negative or greater than the data length, + if (__ownerDocument__(this).implementation.errorChecking && + ((offset < 0) || (offset > this.data.length) || (count < 0))) { + throw(new DOMException(DOMException.INDEX_SIZE_ERR)); + } + + // replace data + this.data = this.data.substring(0, offset). + concat(arg, this.data.substring(offset + count)); + }else { + // set data + this.data = arg; + } + }, + substringData: function(offset, count){ + var ret = null; + if (this.data) { + // throw Exception if offset is negative or greater than the data length, + // or the count is negative + if (__ownerDocument__(this).implementation.errorChecking && + ((offset < 0) || (offset > this.data.length) || (count < 0))) { + throw(new DOMException(DOMException.INDEX_SIZE_ERR)); + } + // if count is not specified + if (!count) { + ret = this.data.substring(offset); // default to 'end of string' + }else{ + ret = this.data.substring(offset, offset + count); + } + } + return ret; + }, + toString : function(){ + return "[object CharacterData]"; + } +}); + +/** + * @class Text + * The Text interface represents the textual content (termed + * character data in XML) of an Element or Attr. + * If there is no markup inside an element's content, the text is + * contained in a single object implementing the Text interface that + * is the only child of the element. If there is markup, it is + * parsed into a list of elements and Text nodes that form the + * list of children of the element. + * @extends CharacterData + * @param ownerDocument The Document object associated with this node. + */ +Text = function(ownerDocument) { + CharacterData.apply(this, arguments); + this.nodeName = "#text"; +}; +Text.prototype = new CharacterData(); +__extend__(Text.prototype,{ + get localName(){ + return null; + }, + // Breaks this Text node into two Text nodes at the specified offset, + // keeping both in the tree as siblings. This node then only contains + // all the content up to the offset point. And a new Text node, which + // is inserted as the next sibling of this node, contains all the + // content at and after the offset point. + splitText : function(offset) { + var data, + inode; + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if Node is readonly + if (this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + // throw Exception if offset is negative or greater than the data length, + if ((offset < 0) || (offset > this.data.length)) { + throw(new DOMException(DOMException.INDEX_SIZE_ERR)); + } + } + if (this.parentNode) { + // get remaining string (after offset) + data = this.substringData(offset); + // create new TextNode with remaining string + inode = __ownerDocument__(this).createTextNode(data); + // attach new TextNode + if (this.nextSibling) { + this.parentNode.insertBefore(inode, this.nextSibling); + } else { + this.parentNode.appendChild(inode); + } + // remove remaining string from original TextNode + this.deleteData(offset); + } + return inode; + }, + get nodeType(){ + return Node.TEXT_NODE; + }, + get xml(){ + return __escapeXML__(""+ this.nodeValue); + }, + toString: function(){ + return "[object Text]"; + } +}); + +/** + * @class CDATASection + * CDATA sections are used to escape blocks of text containing + * characters that would otherwise be regarded as markup. + * The only delimiter that is recognized in a CDATA section is + * the "\]\]\>" string that ends the CDATA section + * @extends Text + * @param ownerDocument : The Document object associated with this node. + */ +CDATASection = function(ownerDocument) { + Text.apply(this, arguments); + this.nodeName = '#cdata-section'; +}; +CDATASection.prototype = new Text(); +__extend__(CDATASection.prototype,{ + get nodeType(){ + return Node.CDATA_SECTION_NODE; + }, + get xml(){ + return ""; + }, + toString : function(){ + return "[object CDATASection]"; + } +}); +/** + * @class Comment + * This represents the content of a comment, i.e., all the + * characters between the starting '' + * @extends CharacterData + * @param ownerDocument : The Document object associated with this node. + */ +Comment = function(ownerDocument) { + CharacterData.apply(this, arguments); + this.nodeName = "#comment"; +}; +Comment.prototype = new CharacterData(); +__extend__(Comment.prototype, { + get localName(){ + return null; + }, + get nodeType(){ + return Node.COMMENT_NODE; + }, + get xml(){ + return ""; + }, + toString : function(){ + return "[object Comment]"; + } +}); + + +/** + * @author envjs team + * @param {Document} onwnerDocument + */ +DocumentType = function(ownerDocument) { + Node.apply(this, arguments); + this.systemId = null; + this.publicId = null; +}; +DocumentType.prototype = new Node(); +__extend__({ + get name(){ + return this.nodeName; + }, + get entities(){ + return null; + }, + get internalSubsets(){ + return null; + }, + get notations(){ + return null; + }, + toString : function(){ + return "[object DocumentType]"; + } +}); + +/** + * @class Attr + * The Attr interface represents an attribute in an Element object + * @extends Node + * @param ownerDocument : The Document object associated with this node. + */ +Attr = function(ownerDocument) { + Node.apply(this, arguments); + // set when Attr is added to NamedNodeMap + this.ownerElement = null; + //TODO: our implementation of Attr is incorrect because we don't + // treat the value of the attribute as a child text node. +}; +Attr.prototype = new Node(); +__extend__(Attr.prototype, { + // the name of this attribute + get name(){ + return this.nodeName; + }, + // the value of the attribute is returned as a string + get value(){ + return this.nodeValue||''; + }, + set value(value){ + // throw Exception if Attribute is readonly + if (__ownerDocument__(this).implementation.errorChecking && this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + // delegate to node + this.nodeValue = value; + }, + get textContent(){ + return this.nodeValue; + }, + set textContent(newText){ + this.nodeValue = newText; + }, + get specified(){ + return (this !== null && this !== undefined); + }, + get nodeType(){ + return Node.ATTRIBUTE_NODE; + }, + get xml() { + if (this.nodeValue) { + return __escapeXML__(this.nodeValue+""); + } else { + return ''; + } + }, + toString : function() { + return '[object Attr]'; + } +}); + + +/** + * @class Element - + * By far the vast majority of objects (apart from text) + * that authors encounter when traversing a document are + * Element nodes. + * @extends Node + * @param ownerDocument : The Document object associated with this node. + */ +Element = function(ownerDocument) { + Node.apply(this, arguments); + this.attributes = new NamedNodeMap(this.ownerDocument, this); +}; +Element.prototype = new Node(); +__extend__(Element.prototype, { + // The name of the element. + get tagName(){ + return this.nodeName; + }, + + getAttribute: function(name) { + var ret = null; + // if attribute exists, use it + var attr = this.attributes.getNamedItem(name); + if (attr) { + ret = attr.value; + } + // if Attribute exists, return its value, otherwise, return null + return ret; + }, + setAttribute : function (name, value) { + // if attribute exists, use it + var attr = this.attributes.getNamedItem(name); + //console.log('attr %s', attr); + //I had to add this check because as the script initializes + //the id may be set in the constructor, and the html element + //overrides the id property with a getter/setter. + if(__ownerDocument__(this)){ + if (attr===null||attr===undefined) { + // otherwise create it + attr = __ownerDocument__(this).createAttribute(name); + //console.log('attr %s', attr); + } + + + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if Attribute is readonly + if (attr._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // throw Exception if the value string contains an illegal character + if (!__isValidString__(value+'')) { + throw(new DOMException(DOMException.INVALID_CHARACTER_ERR)); + } + } + + // assign values to properties (and aliases) + attr.value = value + ''; + + // add/replace Attribute in NamedNodeMap + this.attributes.setNamedItem(attr); + //console.log('element setNamedItem %s', attr); + }else{ + console.warn('Element has no owner document '+this.tagName+ + '\n\t cant set attribute ' + name + ' = '+value ); + } + }, + removeAttribute : function removeAttribute(name) { + // delegate to NamedNodeMap.removeNamedItem + return this.attributes.removeNamedItem(name); + }, + getAttributeNode : function getAttributeNode(name) { + // delegate to NamedNodeMap.getNamedItem + return this.attributes.getNamedItem(name); + }, + setAttributeNode: function(newAttr) { + // if this Attribute is an ID + if (__isIdDeclaration__(newAttr.name)) { + this.id = newAttr.value; // cache ID for getElementById() + } + // delegate to NamedNodeMap.setNamedItem + return this.attributes.setNamedItem(newAttr); + }, + removeAttributeNode: function(oldAttr) { + // throw Exception if Attribute is readonly + if (__ownerDocument__(this).implementation.errorChecking && oldAttr._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // get item index + var itemIndex = this.attributes._findItemIndex(oldAttr._id); + + // throw Exception if node does not exist in this map + if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) { + throw(new DOMException(DOMException.NOT_FOUND_ERR)); + } + + return this.attributes._removeChild(itemIndex); + }, + getAttributeNS : function(namespaceURI, localName) { + var ret = ""; + // delegate to NAmedNodeMap.getNamedItemNS + var attr = this.attributes.getNamedItemNS(namespaceURI, localName); + if (attr) { + ret = attr.value; + } + return ret; // if Attribute exists, return its value, otherwise return "" + }, + setAttributeNS : function(namespaceURI, qualifiedName, value) { + // call NamedNodeMap.getNamedItem + //console.log('setAttributeNS %s %s %s', namespaceURI, qualifiedName, value); + var attr = this.attributes.getNamedItem(namespaceURI, qualifiedName); + + if (!attr) { // if Attribute exists, use it + // otherwise create it + attr = __ownerDocument__(this).createAttributeNS(namespaceURI, qualifiedName); + } + + value = '' + value; + + // test for exceptions + if (__ownerDocument__(this).implementation.errorChecking) { + // throw Exception if Attribute is readonly + if (attr._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + + // throw Exception if the Namespace is invalid + if (!__isValidNamespace__(this.ownerDocument, namespaceURI, qualifiedName, true)) { + throw(new DOMException(DOMException.NAMESPACE_ERR)); + } + + // throw Exception if the value string contains an illegal character + if (!__isValidString__(value)) { + throw(new DOMException(DOMException.INVALID_CHARACTER_ERR)); + } + } + + // if this Attribute is an ID + //if (__isIdDeclaration__(name)) { + // this.id = value; + //} + + // assign values to properties (and aliases) + attr.value = value; + attr.nodeValue = value; + + // delegate to NamedNodeMap.setNamedItem + this.attributes.setNamedItemNS(attr); + }, + removeAttributeNS : function(namespaceURI, localName) { + // delegate to NamedNodeMap.removeNamedItemNS + return this.attributes.removeNamedItemNS(namespaceURI, localName); + }, + getAttributeNodeNS : function(namespaceURI, localName) { + // delegate to NamedNodeMap.getNamedItemNS + return this.attributes.getNamedItemNS(namespaceURI, localName); + }, + setAttributeNodeNS : function(newAttr) { + // if this Attribute is an ID + if ((newAttr.prefix == "") && __isIdDeclaration__(newAttr.name)) { + this.id = newAttr.value+''; // cache ID for getElementById() + } + + // delegate to NamedNodeMap.setNamedItemNS + return this.attributes.setNamedItemNS(newAttr); + }, + hasAttribute : function(name) { + // delegate to NamedNodeMap._hasAttribute + return __hasAttribute__(this.attributes,name); + }, + hasAttributeNS : function(namespaceURI, localName) { + // delegate to NamedNodeMap._hasAttributeNS + return __hasAttributeNS__(this.attributes, namespaceURI, localName); + }, + get nodeType(){ + return Node.ELEMENT_NODE; + }, + get xml() { + var ret = "", + ns = "", + attrs, + attrstring, + i; + + // serialize namespace declarations + if (this.namespaceURI ){ + if((this === this.ownerDocument.documentElement) || + (!this.parentNode)|| + (this.parentNode && (this.parentNode.namespaceURI !== this.namespaceURI))) { + ns = ' xmlns' + (this.prefix?(':'+this.prefix):'') + + '="' + this.namespaceURI + '"'; + } + } + + // serialize Attribute declarations + attrs = this.attributes; + attrstring = ""; + for(i=0;i< attrs.length;i++){ + if(attrs[i].name.match('xmlns:')) { + attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"'; + } + } + for(i=0;i< attrs.length;i++){ + if(!attrs[i].name.match('xmlns:')) { + attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"'; + } + } + + if(this.hasChildNodes()){ + // serialize this Element + ret += "<" + this.tagName + ns + attrstring +">"; + ret += this.childNodes.xml; + ret += ""; + }else{ + ret += "<" + this.tagName + ns + attrstring +"/>"; + } + + return ret; + }, + toString : function(){ + return '[object Element]'; + } +}); +/** + * @class DOMException - raised when an operation is impossible to perform + * @author Jon van Noort (jon@webarcana.com.au) + * @param code : int - the exception code (one of the DOMException constants) + */ +DOMException = function(code) { + this.code = code; +}; + +// DOMException constants +// Introduced in DOM Level 1: +DOMException.INDEX_SIZE_ERR = 1; +DOMException.DOMSTRING_SIZE_ERR = 2; +DOMException.HIERARCHY_REQUEST_ERR = 3; +DOMException.WRONG_DOCUMENT_ERR = 4; +DOMException.INVALID_CHARACTER_ERR = 5; +DOMException.NO_DATA_ALLOWED_ERR = 6; +DOMException.NO_MODIFICATION_ALLOWED_ERR = 7; +DOMException.NOT_FOUND_ERR = 8; +DOMException.NOT_SUPPORTED_ERR = 9; +DOMException.INUSE_ATTRIBUTE_ERR = 10; + +// Introduced in DOM Level 2: +DOMException.INVALID_STATE_ERR = 11; +DOMException.SYNTAX_ERR = 12; +DOMException.INVALID_MODIFICATION_ERR = 13; +DOMException.NAMESPACE_ERR = 14; +DOMException.INVALID_ACCESS_ERR = 15; + +/** + * @class DocumentFragment - + * DocumentFragment is a "lightweight" or "minimal" Document object. + * @extends Node + * @param ownerDocument : The Document object associated with this node. + */ +DocumentFragment = function(ownerDocument) { + Node.apply(this, arguments); + this.nodeName = "#document-fragment"; +}; +DocumentFragment.prototype = new Node(); +__extend__(DocumentFragment.prototype,{ + get nodeType(){ + return Node.DOCUMENT_FRAGMENT_NODE; + }, + get xml(){ + var xml = "", + count = this.childNodes.length; + + // create string concatenating the serialized ChildNodes + for (var i = 0; i < count; i++) { + xml += this.childNodes.item(i).xml; + } + + return xml; + }, + toString : function(){ + return "[object DocumentFragment]"; + }, + get localName(){ + return null; + } +}); + + +/** + * @class ProcessingInstruction - + * The ProcessingInstruction interface represents a + * "processing instruction", used in XML as a way to + * keep processor-specific information in the text of + * the document + * @extends Node + * @author Jon van Noort (jon@webarcana.com.au) + * @param ownerDocument : The Document object associated with this node. + */ +ProcessingInstruction = function(ownerDocument) { + Node.apply(this, arguments); +}; +ProcessingInstruction.prototype = new Node(); +__extend__(ProcessingInstruction.prototype, { + get data(){ + return this.nodeValue; + }, + set data(data){ + // throw Exception if Node is readonly + if (__ownerDocument__(this).errorChecking && this._readonly) { + throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR)); + } + this.nodeValue = data; + }, + get textContent(){ + return this.data; + }, + get localName(){ + return null; + }, + get target(){ + // The target of this processing instruction. + // XML defines this as being the first token following the markup that begins the processing instruction. + // The content of this processing instruction. + return this.nodeName; + }, + set target(value){ + // The target of this processing instruction. + // XML defines this as being the first token following the markup that begins the processing instruction. + // The content of this processing instruction. + this.nodeName = value; + }, + get nodeType(){ + return Node.PROCESSING_INSTRUCTION_NODE; + }, + get xml(){ + return ""; + }, + toString : function(){ + return "[object ProcessingInstruction]"; + } +}); + + +/** + * @author envjs team + */ + +Entity = function() { + throw new Error("Entity Not Implemented" ); +}; + +Entity.constants = { + // content taken from W3C "HTML 4.01 Specification" + // "W3C Recommendation 24 December 1999" + + nbsp: "\u00A0", + iexcl: "\u00A1", + cent: "\u00A2", + pound: "\u00A3", + curren: "\u00A4", + yen: "\u00A5", + brvbar: "\u00A6", + sect: "\u00A7", + uml: "\u00A8", + copy: "\u00A9", + ordf: "\u00AA", + laquo: "\u00AB", + not: "\u00AC", + shy: "\u00AD", + reg: "\u00AE", + macr: "\u00AF", + deg: "\u00B0", + plusmn: "\u00B1", + sup2: "\u00B2", + sup3: "\u00B3", + acute: "\u00B4", + micro: "\u00B5", + para: "\u00B6", + middot: "\u00B7", + cedil: "\u00B8", + sup1: "\u00B9", + ordm: "\u00BA", + raquo: "\u00BB", + frac14: "\u00BC", + frac12: "\u00BD", + frac34: "\u00BE", + iquest: "\u00BF", + Agrave: "\u00C0", + Aacute: "\u00C1", + Acirc: "\u00C2", + Atilde: "\u00C3", + Auml: "\u00C4", + Aring: "\u00C5", + AElig: "\u00C6", + Ccedil: "\u00C7", + Egrave: "\u00C8", + Eacute: "\u00C9", + Ecirc: "\u00CA", + Euml: "\u00CB", + Igrave: "\u00CC", + Iacute: "\u00CD", + Icirc: "\u00CE", + Iuml: "\u00CF", + ETH: "\u00D0", + Ntilde: "\u00D1", + Ograve: "\u00D2", + Oacute: "\u00D3", + Ocirc: "\u00D4", + Otilde: "\u00D5", + Ouml: "\u00D6", + times: "\u00D7", + Oslash: "\u00D8", + Ugrave: "\u00D9", + Uacute: "\u00DA", + Ucirc: "\u00DB", + Uuml: "\u00DC", + Yacute: "\u00DD", + THORN: "\u00DE", + szlig: "\u00DF", + agrave: "\u00E0", + aacute: "\u00E1", + acirc: "\u00E2", + atilde: "\u00E3", + auml: "\u00E4", + aring: "\u00E5", + aelig: "\u00E6", + ccedil: "\u00E7", + egrave: "\u00E8", + eacute: "\u00E9", + ecirc: "\u00EA", + euml: "\u00EB", + igrave: "\u00EC", + iacute: "\u00ED", + icirc: "\u00EE", + iuml: "\u00EF", + eth: "\u00F0", + ntilde: "\u00F1", + ograve: "\u00F2", + oacute: "\u00F3", + ocirc: "\u00F4", + otilde: "\u00F5", + ouml: "\u00F6", + divide: "\u00F7", + oslash: "\u00F8", + ugrave: "\u00F9", + uacute: "\u00FA", + ucirc: "\u00FB", + uuml: "\u00FC", + yacute: "\u00FD", + thorn: "\u00FE", + yuml: "\u00FF", + fnof: "\u0192", + Alpha: "\u0391", + Beta: "\u0392", + Gamma: "\u0393", + Delta: "\u0394", + Epsilon: "\u0395", + Zeta: "\u0396", + Eta: "\u0397", + Theta: "\u0398", + Iota: "\u0399", + Kappa: "\u039A", + Lambda: "\u039B", + Mu: "\u039C", + Nu: "\u039D", + Xi: "\u039E", + Omicron: "\u039F", + Pi: "\u03A0", + Rho: "\u03A1", + Sigma: "\u03A3", + Tau: "\u03A4", + Upsilon: "\u03A5", + Phi: "\u03A6", + Chi: "\u03A7", + Psi: "\u03A8", + Omega: "\u03A9", + alpha: "\u03B1", + beta: "\u03B2", + gamma: "\u03B3", + delta: "\u03B4", + epsilon: "\u03B5", + zeta: "\u03B6", + eta: "\u03B7", + theta: "\u03B8", + iota: "\u03B9", + kappa: "\u03BA", + lambda: "\u03BB", + mu: "\u03BC", + nu: "\u03BD", + xi: "\u03BE", + omicron: "\u03BF", + pi: "\u03C0", + rho: "\u03C1", + sigmaf: "\u03C2", + sigma: "\u03C3", + tau: "\u03C4", + upsilon: "\u03C5", + phi: "\u03C6", + chi: "\u03C7", + psi: "\u03C8", + omega: "\u03C9", + thetasym: "\u03D1", + upsih: "\u03D2", + piv: "\u03D6", + bull: "\u2022", + hellip: "\u2026", + prime: "\u2032", + Prime: "\u2033", + oline: "\u203E", + frasl: "\u2044", + weierp: "\u2118", + image: "\u2111", + real: "\u211C", + trade: "\u2122", + alefsym: "\u2135", + larr: "\u2190", + uarr: "\u2191", + rarr: "\u2192", + darr: "\u2193", + harr: "\u2194", + crarr: "\u21B5", + lArr: "\u21D0", + uArr: "\u21D1", + rArr: "\u21D2", + dArr: "\u21D3", + hArr: "\u21D4", + forall: "\u2200", + part: "\u2202", + exist: "\u2203", + empty: "\u2205", + nabla: "\u2207", + isin: "\u2208", + notin: "\u2209", + ni: "\u220B", + prod: "\u220F", + sum: "\u2211", + minus: "\u2212", + lowast: "\u2217", + radic: "\u221A", + prop: "\u221D", + infin: "\u221E", + ang: "\u2220", + and: "\u2227", + or: "\u2228", + cap: "\u2229", + cup: "\u222A", + intXX: "\u222B", + there4: "\u2234", + sim: "\u223C", + cong: "\u2245", + asymp: "\u2248", + ne: "\u2260", + equiv: "\u2261", + le: "\u2264", + ge: "\u2265", + sub: "\u2282", + sup: "\u2283", + nsub: "\u2284", + sube: "\u2286", + supe: "\u2287", + oplus: "\u2295", + otimes: "\u2297", + perp: "\u22A5", + sdot: "\u22C5", + lceil: "\u2308", + rceil: "\u2309", + lfloor: "\u230A", + rfloor: "\u230B", + lang: "\u2329", + rang: "\u232A", + loz: "\u25CA", + spades: "\u2660", + clubs: "\u2663", + hearts: "\u2665", + diams: "\u2666", + quot: "\u0022", + amp: "\u0026", + lt: "\u003C", + gt: "\u003E", + OElig: "\u0152", + oelig: "\u0153", + Scaron: "\u0160", + scaron: "\u0161", + Yuml: "\u0178", + circ: "\u02C6", + tilde: "\u02DC", + ensp: "\u2002", + emsp: "\u2003", + thinsp: "\u2009", + zwnj: "\u200C", + zwj: "\u200D", + lrm: "\u200E", + rlm: "\u200F", + ndash: "\u2013", + mdash: "\u2014", + lsquo: "\u2018", + rsquo: "\u2019", + sbquo: "\u201A", + ldquo: "\u201C", + rdquo: "\u201D", + bdquo: "\u201E", + dagger: "\u2020", + Dagger: "\u2021", + permil: "\u2030", + lsaquo: "\u2039", + rsaquo: "\u203A", + euro: "\u20AC", + + // non-standard entities + apos: "'" +}; + +/** + * @author envjs team + */ + +EntityReference = function() { + throw new Error("EntityReference Not Implemented" ); +}; + +/** + * @class DOMImplementation - + * provides a number of methods for performing operations + * that are independent of any particular instance of the + * document object model. + * + * @author Jon van Noort (jon@webarcana.com.au) + */ +DOMImplementation = function() { + this.preserveWhiteSpace = false; // by default, ignore whitespace + this.namespaceAware = true; // by default, handle namespaces + this.errorChecking = true; // by default, test for exceptions +}; + +__extend__(DOMImplementation.prototype,{ + // @param feature : string - The package name of the feature to test. + // the legal only values are "XML" and "CORE" (case-insensitive). + // @param version : string - This is the version number of the package + // name to test. In Level 1, this is the string "1.0".* + // @return : boolean + hasFeature : function(feature, version) { + var ret = false; + if (feature.toLowerCase() == "xml") { + ret = (!version || (version == "1.0") || (version == "2.0")); + } + else if (feature.toLowerCase() == "core") { + ret = (!version || (version == "2.0")); + } + else if (feature == "http://www.w3.org/TR/SVG11/feature#BasicStructure") { + ret = (version == "1.1"); + } + return ret; + }, + createDocumentType : function(qname, publicId, systemId){ + var doctype = new DocumentType(); + doctype.nodeName = qname?qname.toUpperCase():null; + doctype.publicId = publicId?publicId:null; + doctype.systemId = systemId?systemId:null; + return doctype; + }, + createDocument : function(nsuri, qname, doctype){ + + var doc = null, documentElement; + + doc = new Document(this, null); + if(doctype){ + doc.doctype = doctype; + } + + if(nsuri && qname){ + documentElement = doc.createElementNS(nsuri, qname); + }else if(qname){ + documentElement = doc.createElement(qname); + } + if(documentElement){ + doc.appendChild(documentElement); + } + return doc; + }, + createHTMLDocument : function(title){ + var doc = new HTMLDocument($implementation, null, ""); + var html = doc.createElement("html"); doc.appendChild(html); + var head = doc.createElement("head"); html.appendChild(head); + var body = doc.createElement("body"); html.appendChild(body); + var t = doc.createElement("title"); head.appendChild(t); + if( title) { + t.appendChild(doc.createTextNode(title)); + } + return doc; + }, + translateErrCode : function(code) { + //convert DOMException Code to human readable error message; + var msg = ""; + + switch (code) { + case DOMException.INDEX_SIZE_ERR : // 1 + msg = "INDEX_SIZE_ERR: Index out of bounds"; + break; + + case DOMException.DOMSTRING_SIZE_ERR : // 2 + msg = "DOMSTRING_SIZE_ERR: The resulting string is too long to fit in a DOMString"; + break; + + case DOMException.HIERARCHY_REQUEST_ERR : // 3 + msg = "HIERARCHY_REQUEST_ERR: The Node can not be inserted at this location"; + break; + + case DOMException.WRONG_DOCUMENT_ERR : // 4 + msg = "WRONG_DOCUMENT_ERR: The source and the destination Documents are not the same"; + break; + + case DOMException.INVALID_CHARACTER_ERR : // 5 + msg = "INVALID_CHARACTER_ERR: The string contains an invalid character"; + break; + + case DOMException.NO_DATA_ALLOWED_ERR : // 6 + msg = "NO_DATA_ALLOWED_ERR: This Node / NodeList does not support data"; + break; + + case DOMException.NO_MODIFICATION_ALLOWED_ERR : // 7 + msg = "NO_MODIFICATION_ALLOWED_ERR: This object cannot be modified"; + break; + + case DOMException.NOT_FOUND_ERR : // 8 + msg = "NOT_FOUND_ERR: The item cannot be found"; + break; + + case DOMException.NOT_SUPPORTED_ERR : // 9 + msg = "NOT_SUPPORTED_ERR: This implementation does not support function"; + break; + + case DOMException.INUSE_ATTRIBUTE_ERR : // 10 + msg = "INUSE_ATTRIBUTE_ERR: The Attribute has already been assigned to another Element"; + break; + + // Introduced in DOM Level 2: + case DOMException.INVALID_STATE_ERR : // 11 + msg = "INVALID_STATE_ERR: The object is no longer usable"; + break; + + case DOMException.SYNTAX_ERR : // 12 + msg = "SYNTAX_ERR: Syntax error"; + break; + + case DOMException.INVALID_MODIFICATION_ERR : // 13 + msg = "INVALID_MODIFICATION_ERR: Cannot change the type of the object"; + break; + + case DOMException.NAMESPACE_ERR : // 14 + msg = "NAMESPACE_ERR: The namespace declaration is incorrect"; + break; + + case DOMException.INVALID_ACCESS_ERR : // 15 + msg = "INVALID_ACCESS_ERR: The object does not support this function"; + break; + + default : + msg = "UNKNOWN: Unknown Exception Code ("+ code +")"; + } + + return msg; + }, + toString : function(){ + return "[object DOMImplementation]"; + } +}); + + + +/** + * @method DOMImplementation._isNamespaceDeclaration - Return true, if attributeName is a namespace declaration + * @author Jon van Noort (jon@webarcana.com.au) + * @param attributeName : string - the attribute name + * @return : boolean + */ +function __isNamespaceDeclaration__(attributeName) { + // test if attributeName is 'xmlns' + return (attributeName.indexOf('xmlns') > -1); +} + +/** + * @method DOMImplementation._isIdDeclaration - Return true, if attributeName is an id declaration + * @author Jon van Noort (jon@webarcana.com.au) + * @param attributeName : string - the attribute name + * @return : boolean + */ +function __isIdDeclaration__(attributeName) { + // test if attributeName is 'id' (case insensitive) + return attributeName?(attributeName.toLowerCase() == 'id'):false; +} + +/** + * @method DOMImplementation._isValidName - Return true, + * if name contains no invalid characters + * @author Jon van Noort (jon@webarcana.com.au) + * @param name : string - the candidate name + * @return : boolean + */ +function __isValidName__(name) { + // test if name contains only valid characters + return name.match(re_validName); +} +var re_validName = /^[a-zA-Z_:][a-zA-Z0-9\.\-_:]*$/; + +/** + * @method DOMImplementation._isValidString - Return true, if string does not contain any illegal chars + * All of the characters 0 through 31 and character 127 are nonprinting control characters. + * With the exception of characters 09, 10, and 13, (Ox09, Ox0A, and Ox0D) + * Note: different from _isValidName in that ValidStrings may contain spaces + * @author Jon van Noort (jon@webarcana.com.au) + * @param name : string - the candidate string + * @return : boolean + */ +function __isValidString__(name) { + // test that string does not contains invalid characters + return (name.search(re_invalidStringChars) < 0); +} +var re_invalidStringChars = /\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F/; + +/** + * @method DOMImplementation._parseNSName - parse the namespace name. + * if there is no colon, the + * @author Jon van Noort (jon@webarcana.com.au) + * @param qualifiedName : string - The qualified name + * @return : NSName - [ + .prefix : string - The prefix part of the qname + .namespaceName : string - The namespaceURI part of the qname + ] + */ +function __parseNSName__(qualifiedName) { + var resultNSName = {}; + // unless the qname has a namespaceName, the prefix is the entire String + resultNSName.prefix = qualifiedName; + resultNSName.namespaceName = ""; + // split on ':' + var delimPos = qualifiedName.indexOf(':'); + if (delimPos > -1) { + // get prefix + resultNSName.prefix = qualifiedName.substring(0, delimPos); + // get namespaceName + resultNSName.namespaceName = qualifiedName.substring(delimPos +1, qualifiedName.length); + } + return resultNSName; +} + +/** + * @method DOMImplementation._parseQName - parse the qualified name + * @author Jon van Noort (jon@webarcana.com.au) + * @param qualifiedName : string - The qualified name + * @return : QName + */ +function __parseQName__(qualifiedName) { + var resultQName = {}; + // unless the qname has a prefix, the local name is the entire String + resultQName.localName = qualifiedName; + resultQName.prefix = ""; + // split on ':' + var delimPos = qualifiedName.indexOf(':'); + if (delimPos > -1) { + // get prefix + resultQName.prefix = qualifiedName.substring(0, delimPos); + // get localName + resultQName.localName = qualifiedName.substring(delimPos +1, qualifiedName.length); + } + return resultQName; +} +/** + * @author envjs team + */ +Notation = function() { + throw new Error("Notation Not Implemented" ); +};/** + * @author thatcher + */ +Range = function(){ + +}; + +__extend__(Range.prototype, { + get startContainer(){ + + }, + get endContainer(){ + + }, + get startOffset(){ + + }, + get endOffset(){ + + }, + get collapsed(){ + + }, + get commonAncestorContainer(){ + + }, + setStart: function(refNode, offset){//throws RangeException + + }, + setEnd: function(refNode, offset){//throws RangeException + + }, + setStartBefore: function(refNode){//throws RangeException + + }, + setStartAfter: function(refNode){//throws RangeException + + }, + setEndBefore: function(refNode){//throws RangeException + + }, + setEndAfter: function(refNode){//throws RangeException + + }, + collapse: function(toStart){//throws RangeException + + }, + selectNode: function(refNode){//throws RangeException + + }, + selectNodeContents: function(refNode){//throws RangeException + + }, + compareBoundaryPoints: function(how, sourceRange){ + + }, + deleteContents: function(){ + + }, + extractContents: function(){ + + }, + cloneContents: function(){ + + }, + insertNode: function(newNode){ + + }, + surroundContents: function(newParent){ + + }, + cloneRange: function(){ + + }, + toString: function(){ + return '[object Range]'; + }, + detach: function(){ + + } +}); + + + // CompareHow +Range.START_TO_START = 0; +Range.START_TO_END = 1; +Range.END_TO_END = 2; +Range.END_TO_START = 3; + +/* + * Forward declarations + */ +var __isValidNamespace__; + +/** + * @class Document - The Document interface represents the entire HTML + * or XML document. Conceptually, it is the root of the document tree, + * and provides the primary access to the document's data. + * + * @extends Node + * @param implementation : DOMImplementation - the creator Implementation + */ +Document = function(implementation, docParentWindow) { + Node.apply(this, arguments); + + //TODO: Temporary!!! Cnage back to true!!! + this.async = true; + // The Document Type Declaration (see DocumentType) associated with this document + this.doctype = null; + // The DOMImplementation object that handles this document. + this.implementation = implementation; + + this.nodeName = "#document"; + // initially false, set to true by parser + this.parsing = false; + this.baseURI = 'about:blank'; + + this.ownerDocument = null; + + this.importing = false; +}; + +Document.prototype = new Node(); +__extend__(Document.prototype,{ + get localName(){ + return null; + }, + get textContent(){ + return null; + }, + get all(){ + return this.getElementsByTagName("*"); + }, + get documentElement(){ + var i, length = this.childNodes?this.childNodes.length:0; + for(i=0;i -1 ){ + valid = false; + } + + if ((valid) && (!isAttribute)) { + // if the namespaceURI is not null + if (!namespaceURI) { + valid = false; + } + } + + // if the qualifiedName has a prefix + if ((valid) && (qName.prefix === "")) { + valid = false; + } + } + + // if the qualifiedName has a prefix that is "xml" and the namespaceURI is + // different from "http://www.w3.org/XML/1998/namespace" [Namespaces]. + if ((valid) && (qName.prefix === "xml") && (namespaceURI !== "http://www.w3.org/XML/1998/namespace")) { + valid = false; + } + + return valid; +}; +/** + * + * This file only handles XML parser. + * It is extended by parser/domparser.js (and parser/htmlparser.js) + * + * This depends on e4x, which some engines may not have. + * + * @author thatcher + */ +DOMParser = function(principle, documentURI, baseURI) { + // TODO: why/what should these 3 args do? +}; +__extend__(DOMParser.prototype,{ + parseFromString: function(xmlstring, mimetype){ + var doc = new Document(new DOMImplementation()), + e4; + + // The following are e4x directives. + // Full spec is here: + // http://www.ecma-international.org/publications/standards/Ecma-357.htm + // + // that is pretty gross, so checkout this summary + // http://rephrase.net/days/07/06/e4x + // + // also see the Mozilla Developer Center: + // https://developer.mozilla.org/en/E4X + // + XML.ignoreComments = false; + XML.ignoreProcessingInstructions = false; + XML.ignoreWhitespace = false; + + // for some reason e4x can't handle initial xml declarations + // https://bugzilla.mozilla.org/show_bug.cgi?id=336551 + // The official workaround is the big regexp below + // but simpler one seems to be ok + // xmlstring = xmlstring.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, ""); + // + xmlstring = xmlstring.replace(/<\?xml.*\?>/); + + e4 = new XMLList(xmlstring); + + __toDomNode__(e4, doc, doc); + + //console.log('xml \n %s', doc.documentElement.xml); + return doc; + } +}); + +var __toDomNode__ = function(e4, parent, doc){ + var xnode, + domnode, + children, + target, + value, + length, + element, + kind, + item; + //console.log('converting e4x node list \n %s', e4) + + // not using the for each(item in e4) since some engines can't + // handle the syntax (i.e. says syntax error) + // + // for each(xnode in e4) { + for (item in e4) { + // NO do not do this if (e4.hasOwnProperty(item)) { + // breaks spidermonkey + xnode = e4[item]; + + kind = xnode.nodeKind(); + //console.log('treating node kind %s', kind); + switch(kind){ + case 'element': + // add node + //console.log('creating element %s %s', xnode.localName(), xnode.namespace()); + if(xnode.namespace() && (xnode.namespace()+'') !== ''){ + //console.log('createElementNS %s %s',xnode.namespace()+'', xnode.localName() ); + domnode = doc.createElementNS(xnode.namespace()+'', xnode.localName()); + }else{ + domnode = doc.createElement(xnode.name()+''); + } + parent.appendChild(domnode); + + // add attributes + __toDomNode__(xnode.attributes(), domnode, doc); + + // add children + children = xnode.children(); + length = children.length(); + //console.log('recursing? %s', length ? 'yes' : 'no'); + if (length > 0) { + __toDomNode__(children, domnode, doc); + } + break; + case 'attribute': + // console.log('setting attribute %s %s %s', + // xnode.localName(), xnode.namespace(), xnode.valueOf()); + + // + // cross-platform alert. The original code used + // xnode.text() to get the attribute value + // This worked in Rhino, but did not in Spidermonkey + // valueOf seemed to work in both + // + if(xnode.namespace() && xnode.namespace().prefix){ + //console.log("%s", xnode.namespace().prefix); + parent.setAttributeNS(xnode.namespace()+'', + xnode.namespace().prefix+':'+xnode.localName(), + xnode.valueOf()); + }else if((xnode.name()+'').match('http://www.w3.org/2000/xmlns/::')){ + if(xnode.localName()!=='xmlns'){ + parent.setAttributeNS('http://www.w3.org/2000/xmlns/', + 'xmlns:'+xnode.localName(), + xnode.valueOf()); + } + }else{ + parent.setAttribute(xnode.localName()+'', xnode.valueOf()); + } + break; + case 'text': + //console.log('creating text node : %s', xnode); + domnode = doc.createTextNode(xnode+''); + parent.appendChild(domnode); + break; + case 'comment': + //console.log('creating comment node : %s', xnode); + value = xnode+''; + domnode = doc.createComment(value.substring(4,value.length-3)); + parent.appendChild(domnode); + break; + case 'processing-instruction': + //console.log('creating processing-instruction node : %s', xnode); + value = xnode+''; + target = value.split(' ')[0].substring(2); + value = value.split(' ').splice(1).join(' ').replace('?>',''); + //console.log('creating processing-instruction data : %s', value); + domnode = doc.createProcessingInstruction(target, value); + parent.appendChild(domnode); + break; + default: + console.log('e4x DOM ERROR'); + throw new Error("Assertion failed in xml parser"); + } + } +}; +/** + * @author envjs team + * @class XMLSerializer + */ + +XMLSerializer = function() {}; + +__extend__(XMLSerializer.prototype, { + serializeToString: function(node){ + return node.xml; + }, + toString : function(){ + return "[object XMLSerializer]"; + } +}); + +/** + * @author john resig & the envjs team + * @uri http://www.envjs.com/ + * @copyright 2008-2010 + * @license MIT + */ +//CLOSURE_END +}()); +/* + * Envjs event.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + * + * This file simply provides the global definitions we need to + * be able to correctly implement to core browser DOM Event interfaces. + */ +var Event, + MouseEvent, + UIEvent, + KeyboardEvent, + MutationEvent, + DocumentEvent, + EventTarget, + EventException, + //nonstandard but very useful for implementing mutation events + //among other things like general profiling + Aspect; +/* + * Envjs event.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +//CLOSURE_START +(function(){ + + + + + +/** + * @author john resig + */ +// Helper method for extending one object with another. +function __extend__(a,b) { + for ( var i in b ) { + var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); + if ( g || s ) { + if ( g ) { a.__defineGetter__(i, g); } + if ( s ) { a.__defineSetter__(i, s); } + } else { + a[i] = b[i]; + } + } return a; +} + +/** + * @author john resig + */ +//from jQuery +function __setArray__( target, array ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties + target.length = 0; + Array.prototype.push.apply( target, array ); +} +/** + * Borrowed with love from: + * + * jQuery AOP - jQuery plugin to add features of aspect-oriented programming (AOP) to jQuery. + * http://jquery-aop.googlecode.com/ + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Version: 1.1 + */ +(function() { + + var _after = 1; + var _before = 2; + var _around = 3; + var _intro = 4; + var _regexEnabled = true; + + /** + * Private weaving function. + */ + var weaveOne = function(source, method, advice) { + + var old = source[method]; + + var aspect; + if (advice.type == _after) + aspect = function() { + var returnValue = old.apply(this, arguments); + return advice.value.apply(this, [returnValue, method]); + }; + else if (advice.type == _before) + aspect = function() { + advice.value.apply(this, [arguments, method]); + return old.apply(this, arguments); + }; + else if (advice.type == _intro) + aspect = function() { + return advice.value.apply(this, arguments); + }; + else if (advice.type == _around) { + aspect = function() { + var invocation = { object: this, args: arguments }; + return advice.value.apply(invocation.object, [{ arguments: invocation.args, method: method, proceed : + function() { + return old.apply(invocation.object, invocation.args); + } + }] ); + }; + } + + aspect.unweave = function() { + source[method] = old; + pointcut = source = aspect = old = null; + }; + + source[method] = aspect; + + return aspect; + + }; + + + /** + * Private weaver and pointcut parser. + */ + var weave = function(pointcut, advice) + { + + var source = (typeof(pointcut.target.prototype) != 'undefined') ? pointcut.target.prototype : pointcut.target; + var advices = []; + + // If it's not an introduction and no method was found, try with regex... + if (advice.type != _intro && typeof(source[pointcut.method]) == 'undefined') + { + + for (var method in source) + { + if (source[method] != null && source[method] instanceof Function && method.match(pointcut.method)) + { + advices[advices.length] = weaveOne(source, method, advice); + } + } + + if (advices.length == 0) + throw 'No method: ' + pointcut.method; + + } + else + { + // Return as an array of one element + advices[0] = weaveOne(source, pointcut.method, advice); + } + + return _regexEnabled ? advices : advices[0]; + + }; + + Aspect = + { + /** + * Creates an advice after the defined point-cut. The advice will be executed after the point-cut method + * has completed execution successfully, and will receive one parameter with the result of the execution. + * This function returns an array of weaved aspects (Function). + * + * @example jQuery.aop.after( {target: window, method: 'MyGlobalMethod'}, function(result) { alert('Returned: ' + result); } ); + * @result Array + * + * @example jQuery.aop.after( {target: String, method: 'indexOf'}, function(index) { alert('Result found at: ' + index + ' on:' + this); } ); + * @result Array + * + * @name after + * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved. + * @option Object target Target object to be weaved. + * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects. + * @param Function advice Function containing the code that will get called after the execution of the point-cut. It receives one parameter + * with the result of the point-cut's execution. + * + * @type Array + * @cat Plugins/General + */ + after : function(pointcut, advice) + { + return weave( pointcut, { type: _after, value: advice } ); + }, + + /** + * Creates an advice before the defined point-cut. The advice will be executed before the point-cut method + * but cannot modify the behavior of the method, or prevent its execution. + * This function returns an array of weaved aspects (Function). + * + * @example jQuery.aop.before( {target: window, method: 'MyGlobalMethod'}, function() { alert('About to execute MyGlobalMethod'); } ); + * @result Array + * + * @example jQuery.aop.before( {target: String, method: 'indexOf'}, function(index) { alert('About to execute String.indexOf on: ' + this); } ); + * @result Array + * + * @name before + * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved. + * @option Object target Target object to be weaved. + * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects. + * @param Function advice Function containing the code that will get called before the execution of the point-cut. + * + * @type Array + * @cat Plugins/General + */ + before : function(pointcut, advice) + { + return weave( pointcut, { type: _before, value: advice } ); + }, + + + /** + * Creates an advice 'around' the defined point-cut. This type of advice can control the point-cut method execution by calling + * the functions '.proceed()' on the 'invocation' object, and also, can modify the arguments collection before sending them to the function call. + * This function returns an array of weaved aspects (Function). + * + * @example jQuery.aop.around( {target: window, method: 'MyGlobalMethod'}, function(invocation) { + * alert('# of Arguments: ' + invocation.arguments.length); + * return invocation.proceed(); + * } ); + * @result Array + * + * @example jQuery.aop.around( {target: String, method: 'indexOf'}, function(invocation) { + * alert('Searching: ' + invocation.arguments[0] + ' on: ' + this); + * return invocation.proceed(); + * } ); + * @result Array + * + * @example jQuery.aop.around( {target: window, method: /Get(\d+)/}, function(invocation) { + * alert('Executing ' + invocation.method); + * return invocation.proceed(); + * } ); + * @desc Matches all global methods starting with 'Get' and followed by a number. + * @result Array + * + * + * @name around + * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved. + * @option Object target Target object to be weaved. + * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects. + * @param Function advice Function containing the code that will get called around the execution of the point-cut. This advice will be called with one + * argument containing one function '.proceed()', the collection of arguments '.arguments', and the matched method name '.method'. + * + * @type Array + * @cat Plugins/General + */ + around : function(pointcut, advice) + { + return weave( pointcut, { type: _around, value: advice } ); + }, + + /** + * Creates an introduction on the defined point-cut. This type of advice replaces any existing methods with the same + * name. To restore them, just unweave it. + * This function returns an array with only one weaved aspect (Function). + * + * @example jQuery.aop.introduction( {target: window, method: 'MyGlobalMethod'}, function(result) { alert('Returned: ' + result); } ); + * @result Array + * + * @example jQuery.aop.introduction( {target: String, method: 'log'}, function() { alert('Console: ' + this); } ); + * @result Array + * + * @name introduction + * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved. + * @option Object target Target object to be weaved. + * @option String method Name of the function to be weaved. + * @param Function advice Function containing the code that will be executed on the point-cut. + * + * @type Array + * @cat Plugins/General + */ + introduction : function(pointcut, advice) + { + return weave( pointcut, { type: _intro, value: advice } ); + }, + + /** + * Configures global options. + * + * @name setup + * @param Map settings Configuration options. + * @option Boolean regexMatch Enables/disables regex matching of method names. + * + * @example jQuery.aop.setup( { regexMatch: false } ); + * @desc Disable regex matching. + * + * @type Void + * @cat Plugins/General + */ + setup: function(settings) + { + _regexEnabled = settings.regexMatch; + } + }; + +})(); + + + + +/** + * @name EventTarget + * @w3c:domlevel 2 + * @uri -//TODO: paste dom event level 2 w3c spc uri here + */ +EventTarget = function(){}; +EventTarget.prototype.addEventListener = function(type, fn, phase){ + __addEventListener__(this, type, fn, phase); +}; +EventTarget.prototype.removeEventListener = function(type, fn){ + __removeEventListener__(this, type, fn); +}; +EventTarget.prototype.dispatchEvent = function(event, bubbles){ + __dispatchEvent__(this, event, bubbles); +}; + +__extend__(Node.prototype, EventTarget.prototype); + + +var $events = [{}]; + +function __addEventListener__(target, type, fn, phase){ + phase = !!phase?"CAPTURING":"BUBBLING"; + if ( !target.uuid ) { + //console.log('event uuid %s %s', target, target.uuid); + target.uuid = $events.length+''; + } + if ( !$events[target.uuid] ) { + //console.log('creating listener for target: %s %s', target, target.uuid); + $events[target.uuid] = {}; + } + if ( !$events[target.uuid][type] ){ + //console.log('creating listener for type: %s %s %s', target, target.uuid, type); + $events[target.uuid][type] = { + CAPTURING:[], + BUBBLING:[] + }; + } + if ( $events[target.uuid][type][phase].indexOf( fn ) < 0 ){ + //console.log('adding event listener %s %s %s %s %s %s', target, target.uuid, type, phase, + // $events[target.uuid][type][phase].length, $events[target.uuid][type][phase].indexOf( fn )); + //console.log('creating listener for function: %s %s %s', target, target.uuid, phase); + $events[target.uuid][type][phase].push( fn ); + //console.log('adding event listener %s %s %s %s %s %s', target, target.uuid, type, phase, + // $events[target.uuid][type][phase].length, $events[target.uuid][type][phase].indexOf( fn )); + } + //console.log('registered event listeners %s', $events.length); +} + +function __removeEventListener__(target, type, fn, phase){ + + phase = !!phase?"CAPTURING":"BUBBLING"; + if ( !target.uuid ) { + return; + } + if ( !$events[target.uuid] ) { + return; + } + if(type == '*'){ + //used to clean all event listeners for a given node + //console.log('cleaning all event listeners for node %s %s',target, target.uuid); + delete $events[target.uuid]; + return; + }else if ( !$events[target.uuid][type] ){ + return; + } + $events[target.uuid][type][phase] = + $events[target.uuid][type][phase].filter(function(f){ + //console.log('removing event listener %s %s %s %s', target, type, phase, fn); + return f != fn; + }); +} + +var __eventuuid__ = 0; +function __dispatchEvent__(target, event, bubbles){ + + if (!event.uuid) { + event.uuid = __eventuuid__++; + } + //the window scope defines the $event object, for IE(^^^) compatibility; + //$event = event; + //console.log('dispatching event %s', event.uuid); + if (bubbles === undefined || bubbles === null) { + bubbles = true; + } + + if (!event.target) { + event.target = target; + } + + //console.log('dispatching? %s %s %s', target, event.type, bubbles); + if ( event.type && (target.nodeType || target === window )) { + + //console.log('dispatching event %s %s %s', target, event.type, bubbles); + __captureEvent__(target, event); + + event.eventPhase = Event.AT_TARGET; + if ( target.uuid && $events[target.uuid] && $events[target.uuid][event.type] ) { + event.currentTarget = target; + //console.log('dispatching %s %s %s %s', target, event.type, + // $events[target.uuid][event.type]['CAPTURING'].length); + $events[target.uuid][event.type].CAPTURING.forEach(function(fn){ + //console.log('AT_TARGET (CAPTURING) event %s', fn); + var returnValue = fn( event ); + //console.log('AT_TARGET (CAPTURING) return value %s', returnValue); + if(returnValue === false){ + event.stopPropagation(); + } + }); + //console.log('dispatching %s %s %s %s', target, event.type, + // $events[target.uuid][event.type]['BUBBLING'].length); + $events[target.uuid][event.type].BUBBLING.forEach(function(fn){ + //console.log('AT_TARGET (BUBBLING) event %s', fn); + var returnValue = fn( event ); + //console.log('AT_TARGET (BUBBLING) return value %s', returnValue); + if(returnValue === false){ + event.stopPropagation(); + } + }); + } + if (target["on" + event.type]) { + target["on" + event.type](event); + } + if (bubbles && !event.cancelled){ + __bubbleEvent__(target, event); + } + if(!event._preventDefault){ + //At this point I'm guessing that just HTMLEvents are concerned + //with default behavior being executed in a browser but I could be + //wrong as usual. The goal is much more to filter at this point + //what events have no need to be handled + //console.log('triggering default behavior for %s', event.type); + if(event.type in Envjs.defaultEventBehaviors){ + Envjs.defaultEventBehaviors[event.type](event); + } + } + //console.log('deleting event %s', event.uuid); + event.target = null; + event = null; + }else{ + throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR); + } +} + +function __captureEvent__(target, event){ + var ancestorStack = [], + parent = target.parentNode; + + event.eventPhase = Event.CAPTURING_PHASE; + while(parent){ + if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type]){ + ancestorStack.push(parent); + } + parent = parent.parentNode; + } + while(ancestorStack.length && !event.cancelled){ + event.currentTarget = ancestorStack.pop(); + if($events[event.currentTarget.uuid] && $events[event.currentTarget.uuid][event.type]){ + $events[event.currentTarget.uuid][event.type].CAPTURING.forEach(function(fn){ + var returnValue = fn( event ); + if(returnValue === false){ + event.stopPropagation(); + } + }); + } + } +} + +function __bubbleEvent__(target, event){ + var parent = target.parentNode; + event.eventPhase = Event.BUBBLING_PHASE; + while(parent){ + if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type] ){ + event.currentTarget = parent; + $events[event.currentTarget.uuid][event.type].BUBBLING.forEach(function(fn){ + var returnValue = fn( event ); + if(returnValue === false){ + event.stopPropagation(); + } + }); + } + parent = parent.parentNode; + } +} + +/** + * @class Event + */ +Event = function(options){ + // event state is kept read-only by forcing + // a new object for each event. This may not + // be appropriate in the long run and we'll + // have to decide if we simply dont adhere to + // the read-only restriction of the specification + this._bubbles = true; + this._cancelable = true; + this._cancelled = false; + this._currentTarget = null; + this._target = null; + this._eventPhase = Event.AT_TARGET; + this._timeStamp = new Date().getTime(); + this._preventDefault = false; + this._stopPropogation = false; +}; + +__extend__(Event.prototype,{ + get bubbles(){return this._bubbles;}, + get cancelable(){return this._cancelable;}, + get currentTarget(){return this._currentTarget;}, + set currentTarget(currentTarget){ this._currentTarget = currentTarget; }, + get eventPhase(){return this._eventPhase;}, + set eventPhase(eventPhase){this._eventPhase = eventPhase;}, + get target(){return this._target;}, + set target(target){ this._target = target;}, + get timeStamp(){return this._timeStamp;}, + get type(){return this._type;}, + initEvent: function(type, bubbles, cancelable){ + this._type=type?type:''; + this._bubbles=!!bubbles; + this._cancelable=!!cancelable; + }, + preventDefault: function(){ + this._preventDefault = true; + }, + stopPropagation: function(){ + if(this._cancelable){ + this._cancelled = true; + this._bubbles = false; + } + }, + get cancelled(){ + return this._cancelled; + }, + toString: function(){ + return '[object Event]'; + } +}); + +__extend__(Event,{ + CAPTURING_PHASE : 1, + AT_TARGET : 2, + BUBBLING_PHASE : 3 +}); + + + +/** + * @name UIEvent + * @param {Object} options + */ +UIEvent = function(options) { + this._view = null; + this._detail = 0; +}; + +UIEvent.prototype = new Event(); +__extend__(UIEvent.prototype,{ + get view(){ + return this._view; + }, + get detail(){ + return this._detail; + }, + initUIEvent: function(type, bubbles, cancelable, windowObject, detail){ + this.initEvent(type, bubbles, cancelable); + this._detail = 0; + this._view = windowObject; + } +}); + +var $onblur, + $onfocus, + $onresize; + + +/** + * @name MouseEvent + * @w3c:domlevel 2 + * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html + */ +MouseEvent = function(options) { + this._screenX= 0; + this._screenY= 0; + this._clientX= 0; + this._clientY= 0; + this._ctrlKey= false; + this._metaKey= false; + this._altKey= false; + this._button= null; + this._relatedTarget= null; +}; +MouseEvent.prototype = new UIEvent(); +__extend__(MouseEvent.prototype,{ + get screenX(){ + return this._screenX; + }, + get screenY(){ + return this._screenY; + }, + get clientX(){ + return this._clientX; + }, + get clientY(){ + return this._clientY; + }, + get ctrlKey(){ + return this._ctrlKey; + }, + get altKey(){ + return this._altKey; + }, + get shiftKey(){ + return this._shiftKey; + }, + get metaKey(){ + return this._metaKey; + }, + get button(){ + return this._button; + }, + get relatedTarget(){ + return this._relatedTarget; + }, + initMouseEvent: function(type, bubbles, cancelable, windowObject, detail, + screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, + metaKey, button, relatedTarget){ + this.initUIEvent(type, bubbles, cancelable, windowObject, detail); + this._screenX = screenX; + this._screenY = screenY; + this._clientX = clientX; + this._clientY = clientY; + this._ctrlKey = ctrlKey; + this._altKey = altKey; + this._shiftKey = shiftKey; + this._metaKey = metaKey; + this._button = button; + this._relatedTarget = relatedTarget; + } +}); + +/** + * Interface KeyboardEvent (introduced in DOM Level 3) + */ +KeyboardEvent = function(options) { + this._keyIdentifier = 0; + this._keyLocation = 0; + this._ctrlKey = false; + this._metaKey = false; + this._altKey = false; + this._metaKey = false; +}; +KeyboardEvent.prototype = new UIEvent(); + +__extend__(KeyboardEvent.prototype,{ + + get ctrlKey(){ + return this._ctrlKey; + }, + get altKey(){ + return this._altKey; + }, + get shiftKey(){ + return this._shiftKey; + }, + get metaKey(){ + return this._metaKey; + }, + get button(){ + return this._button; + }, + get relatedTarget(){ + return this._relatedTarget; + }, + getModifiersState: function(keyIdentifier){ + + }, + initMouseEvent: function(type, bubbles, cancelable, windowObject, + keyIdentifier, keyLocation, modifiersList, repeat){ + this.initUIEvent(type, bubbles, cancelable, windowObject, 0); + this._keyIdentifier = keyIdentifier; + this._keyLocation = keyLocation; + this._modifiersList = modifiersList; + this._repeat = repeat; + } +}); + +KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0; +KeyboardEvent.DOM_KEY_LOCATION_LEFT = 1; +KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 2; +KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 3; +KeyboardEvent.DOM_KEY_LOCATION_MOBILE = 4; +KeyboardEvent.DOM_KEY_LOCATION_JOYSTICK = 5; + + + +//We dont fire mutation events until someone has registered for them +var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved|DOMAttrModified|DOMCharacterDataModified/; + +var __fireMutationEvents__ = Aspect.before({ + target: EventTarget, + method: 'addEventListener' +}, function(target, type){ + if(type && type.match(__supportedMutations__)){ + //unweaving removes the __addEventListener__ aspect + __fireMutationEvents__.unweave(); + // These two methods are enough to cover all dom 2 manipulations + Aspect.around({ + target: Node, + method:"removeChild" + }, function(invocation){ + var event, + node = invocation.arguments[0]; + event = node.ownerDocument.createEvent('MutationEvents'); + event.initEvent('DOMNodeRemoved', true, false, node.parentNode, null, null, null, null); + node.dispatchEvent(event, false); + return invocation.proceed(); + + }); + Aspect.around({ + target: Node, + method:"appendChild" + }, function(invocation) { + var event, + node = invocation.proceed(); + event = node.ownerDocument.createEvent('MutationEvents'); + event.initEvent('DOMNodeInserted', true, false, node.parentNode, null, null, null, null); + node.dispatchEvent(event, false); + return node; + }); + } +}); + +/** + * @name MutationEvent + * @param {Object} options + */ +MutationEvent = function(options) { + this._cancelable = false; + this._timeStamp = 0; +}; + +MutationEvent.prototype = new Event(); +__extend__(MutationEvent.prototype,{ + get relatedNode(){ + return this._relatedNode; + }, + get prevValue(){ + return this._prevValue; + }, + get newValue(){ + return this._newValue; + }, + get attrName(){ + return this._attrName; + }, + get attrChange(){ + return this._attrChange; + }, + initMutationEvent: function( type, bubbles, cancelable, + relatedNode, prevValue, newValue, attrName, attrChange ){ + this._relatedNode = relatedNode; + this._prevValue = prevValue; + this._newValue = newValue; + this._attrName = attrName; + this._attrChange = attrChange; + switch(type){ + case "DOMSubtreeModified": + this.initEvent(type, true, false); + break; + case "DOMNodeInserted": + this.initEvent(type, true, false); + break; + case "DOMNodeRemoved": + this.initEvent(type, true, false); + break; + case "DOMNodeRemovedFromDocument": + this.initEvent(type, false, false); + break; + case "DOMNodeInsertedIntoDocument": + this.initEvent(type, false, false); + break; + case "DOMAttrModified": + this.initEvent(type, true, false); + break; + case "DOMCharacterDataModified": + this.initEvent(type, true, false); + break; + default: + this.initEvent(type, bubbles, cancelable); + } + } +}); + +// constants +MutationEvent.ADDITION = 0; +MutationEvent.MODIFICATION = 1; +MutationEvent.REMOVAL = 2; + + +/** + * @name EventException + */ +EventException = function(code) { + this.code = code; +}; +EventException.UNSPECIFIED_EVENT_TYPE_ERR = 0; +/** + * + * DOM Level 2: http://www.w3.org/TR/DOM-Level-2-Events/events.html + * DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Events/ + * + * interface DocumentEvent { + * Event createEvent (in DOMString eventType) + * raises (DOMException); + * }; + * + * Firefox (3.6) exposes DocumentEvent + * Safari (4) does NOT. + */ + +/** + * TODO: Not sure we need a full prototype. We not just an regular object? + */ +DocumentEvent = function(){}; +DocumentEvent.prototype.__EventMap__ = { + // Safari4: singular and plural forms accepted + // Firefox3.6: singular and plural forms accepted + 'Event' : Event, + 'Events' : Event, + 'UIEvent' : UIEvent, + 'UIEvents' : UIEvent, + 'MouseEvent' : MouseEvent, + 'MouseEvents' : MouseEvent, + 'MutationEvent' : MutationEvent, + 'MutationEvents' : MutationEvent, + + // Safari4: accepts HTMLEvents, but not HTMLEvent + // Firefox3.6: accepts HTMLEvents, but not HTMLEvent + 'HTMLEvent' : Event, + 'HTMLEvents' : Event, + + // Safari4: both not accepted + // Firefox3.6, only KeyEvents is accepted + 'KeyEvent' : KeyboardEvent, + 'KeyEvents' : KeyboardEvent, + + // Safari4: both accepted + // Firefox3.6: none accepted + 'KeyboardEvent' : KeyboardEvent, + 'KeyboardEvents' : KeyboardEvent +}; + +DocumentEvent.prototype.createEvent = function(eventType) { + var Clazz = this.__EventMap__[eventType]; + if (Clazz) { + return new Clazz(); + } + throw(new DOMException(DOMException.NOT_SUPPORTED_ERR)); +}; + +__extend__(Document.prototype, DocumentEvent.prototype); + +/** + * @author john resig & the envjs team + * @uri http://www.envjs.com/ + * @copyright 2008-2010 + * @license MIT + */ +//CLOSURE_END +}()); + +/* + * Envjs timer.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + * + * Parts of the implementation were originally written by:\ + * Steven Parkes + * + * requires Envjs.wait, Envjs.sleep, Envjs.WAIT_INTERVAL + */ +var setTimeout, + clearTimeout, + setInterval, + clearInterval; + +/* + * Envjs timer.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +//CLOSURE_START +(function(){ + + + + +/* +* timer.js +* implementation provided by Steven Parkes +*/ + +//private +var $timers = [], + EVENT_LOOP_RUNNING = false; + +$timers.lock = function(fn){ + Envjs.sync(fn)(); +}; + +//private internal class +var Timer = function(fn, interval){ + this.fn = fn; + this.interval = interval; + this.at = Date.now() + interval; + // allows for calling wait() from callbacks + this.running = false; +}; + +Timer.prototype.start = function(){}; +Timer.prototype.stop = function(){}; + +//static +Timer.normalize = function(time) { + time = time*1; + if ( isNaN(time) || time < 0 ) { + time = 0; + } + + if ( EVENT_LOOP_RUNNING && time < Timer.MIN_TIME ) { + time = Timer.MIN_TIME; + } + return time; +}; +// html5 says this should be at least 4, but the parser is using +// a setTimeout for the SAX stuff which messes up the world +Timer.MIN_TIME = /* 4 */ 0; + +/** + * @function setTimeout + * @param {Object} fn + * @param {Object} time + */ +setTimeout = function(fn, time){ + var num; + time = Timer.normalize(time); + $timers.lock(function(){ + num = $timers.length+1; + var tfn; + if (typeof fn == 'string') { + tfn = function() { + try { + // eval in global scope + eval(fn, null); + } catch (e) { + console.log('timer error %s %s', fn, e); + } finally { + clearInterval(num); + } + }; + } else { + tfn = function() { + try { + fn(); + } catch (e) { + console.log('timer error %s %s', fn, e); + } finally { + clearInterval(num); + } + }; + } + //console.log("Creating timer number %s", num); + $timers[num] = new Timer(tfn, time); + $timers[num].start(); + }); + return num; +}; + +/** + * @function setInterval + * @param {Object} fn + * @param {Object} time + */ +setInterval = function(fn, time){ + //console.log('setting interval %s %s', time, fn.toString().substring(0,64)); + time = Timer.normalize(time); + if ( time < 10 ) { + time = 10; + } + if (typeof fn == 'string') { + var fnstr = fn; + fn = function() { + eval(fnstr); + }; + } + var num; + $timers.lock(function(){ + num = $timers.length+1; + //Envjs.debug("Creating timer number "+num); + $timers[num] = new Timer(fn, time); + $timers[num].start(); + }); + return num; +}; + +/** + * clearInterval + * @param {Object} num + */ +clearInterval = clearTimeout = function(num){ + //console.log("clearing interval "+num); + $timers.lock(function(){ + if ( $timers[num] ) { + $timers[num].stop(); + delete $timers[num]; + } + }); +}; + +// wait === null/undefined: execute any timers as they fire, +// waiting until there are none left +// wait(n) (n > 0): execute any timers as they fire until there +// are none left waiting at least n ms but no more, even if there +// are future events/current threads +// wait(0): execute any immediately runnable timers and return +// wait(-n): keep sleeping until the next event is more than n ms +// in the future +// +// TODO: make a priority queue ... + +Envjs.wait = function(wait) { + //console.log('wait %s', wait); + var delta_wait, + start = Date.now(), + was_running = EVENT_LOOP_RUNNING; + + if (wait < 0) { + delta_wait = -wait; + wait = 0; + } + EVENT_LOOP_RUNNING = true; + if (wait !== 0 && wait !== null && wait !== undefined){ + wait += Date.now(); + } + + var earliest, + timer, + sleep, + index, + goal, + now, + nextfn; + + for (;;) { + //console.log('timer loop'); + earliest = sleep = goal = now = nextfn = null; + $timers.lock(function(){ + for(index in $timers){ + if( isNaN(index*0) ) { + continue; + } + timer = $timers[index]; + // determine timer with smallest run-at time that is + // not already running + if( !timer.running && ( !earliest || timer.at < earliest.at) ) { + earliest = timer; + } + } + }); + //next sleep time + sleep = earliest && earliest.at - Date.now(); + if ( earliest && sleep <= 0 ) { + nextfn = earliest.fn; + try { + //console.log('running stack %s', nextfn.toString().substring(0,64)); + earliest.running = true; + nextfn(); + } catch (e) { + console.log('timer error %s %s', nextfn, e); + } finally { + earliest.running = false; + } + goal = earliest.at + earliest.interval; + now = Date.now(); + if ( goal < now ) { + earliest.at = now; + } else { + earliest.at = goal; + } + continue; + } + + // bunch of subtle cases here ... + if ( !earliest ) { + // no events in the queue (but maybe XHR will bring in events, so ... + if ( !wait || wait < Date.now() ) { + // Loop ends if there are no events and a wait hasn't been + // requested or has expired + break; + } + // no events, but a wait requested: fall through to sleep + } else { + // there are events in the queue, but they aren't firable now + /*if ( delta_wait && sleep <= delta_wait ) { + //TODO: why waste a check on a tight + // loop if it just falls through? + // if they will happen within the next delta, fall through to sleep + } else */if ( wait === 0 || ( wait > 0 && wait < Date.now () ) ) { + // loop ends even if there are events but the user + // specifcally asked not to wait too long + break; + } + // there are events and the user wants to wait: fall through to sleep + } + + // Related to ajax threads ... hopefully can go away .. + var interval = Envjs.WAIT_INTERVAL || 100; + if ( !sleep || sleep > interval ) { + sleep = interval; + } + //console.log('sleeping %s', sleep); + Envjs.sleep(sleep); + + } + EVENT_LOOP_RUNNING = was_running; +}; + + +/** + * @author john resig & the envjs team + * @uri http://www.envjs.com/ + * @copyright 2008-2010 + * @license MIT + */ +//CLOSURE_END +}()); +/* + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + * + * This file simply provides the global definitions we need to + * be able to correctly implement to core browser DOM HTML interfaces. + */ +var HTMLDocument, + HTMLElement, + HTMLCollection, + HTMLAnchorElement, + HTMLAreaElement, + HTMLBaseElement, + HTMLQuoteElement, + HTMLBodyElement, + HTMLBRElement, + HTMLButtonElement, + HTMLCanvasElement, + HTMLTableColElement, + HTMLModElement, + HTMLDivElement, + HTMLDListElement, + HTMLFieldSetElement, + HTMLFormElement, + HTMLFrameElement, + HTMLFrameSetElement, + HTMLHeadElement, + HTMLHeadingElement, + HTMLHRElement, + HTMLHtmlElement, + HTMLIFrameElement, + HTMLImageElement, + HTMLInputElement, + HTMLLabelElement, + HTMLLegendElement, + HTMLLIElement, + HTMLLinkElement, + HTMLMapElement, + HTMLMetaElement, + HTMLObjectElement, + HTMLOListElement, + HTMLOptGroupElement, + HTMLOptionElement, + HTMLParagraphElement, + HTMLParamElement, + HTMLPreElement, + HTMLScriptElement, + HTMLSelectElement, + HTMLSpanElement, + HTMLStyleElement, + HTMLTableElement, + HTMLTableSectionElement, + HTMLTableCellElement, + HTMLTableDataCellElement, + HTMLTableHeaderCellElement, + HTMLTableRowElement, + HTMLTextAreaElement, + HTMLTitleElement, + HTMLUListElement, + HTMLUnknownElement, + Image, + Option, + __loadImage__, + __loadLink__; + +/* + * Envjs html.1.2.13 + * Pure JavaScript Browser Environment + * By John Resig and the Envjs Team + * Copyright 2008-2010 John Resig, under the MIT License + */ + +//CLOSURE_START +(function(){ + + + + + +/** + * @author ariel flesler + * http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html + * @param {Object} str + */ +function __trim__( str ){ + return (str || "").replace( /^\s+|\s+$/g, "" ); +} + + +/** + * @author john resig + */ +// Helper method for extending one object with another. +function __extend__(a,b) { + for ( var i in b ) { + var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); + if ( g || s ) { + if ( g ) { a.__defineGetter__(i, g); } + if ( s ) { a.__defineSetter__(i, s); } + } else { + a[i] = b[i]; + } + } return a; +} + +/** + * @author john resig + */ +//from jQuery +function __setArray__( target, array ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties + target.length = 0; + Array.prototype.push.apply( target, array ); +} + +/** + * @class HTMLDocument + * The Document interface represents the entire HTML or XML document. + * Conceptually, it is the root of the document tree, and provides + * the primary access to the document's data. + * + * @extends Document + */ +HTMLDocument = function(implementation, ownerWindow, referrer) { + Document.apply(this, arguments); + this.referrer = referrer || ''; + this.baseURI = "about:blank"; + this.ownerWindow = ownerWindow; +}; + +HTMLDocument.prototype = new Document(); + +__extend__(HTMLDocument.prototype, { + createElement: function(tagName){ + var node; + tagName = tagName.toUpperCase(); + // create Element specifying 'this' as ownerDocument + // This is an html document so we need to use explicit interfaces per the + //TODO: would be much faster as a big switch + switch(tagName){ + case "A": + node = new HTMLAnchorElement(this);break; + case "AREA": + node = new HTMLAreaElement(this);break; + case "BASE": + node = new HTMLBaseElement(this);break; + case "BLOCKQUOTE": + node = new HTMLQuoteElement(this);break; + case "CANVAS": + node = new HTMLCanvasElement(this);break; + case "Q": + node = new HTMLQuoteElement(this);break; + case "BODY": + node = new HTMLBodyElement(this);break; + case "BR": + node = new HTMLBRElement(this);break; + case "BUTTON": + node = new HTMLButtonElement(this);break; + case "CAPTION": + node = new HTMLElement(this);break; + case "COL": + node = new HTMLTableColElement(this);break; + case "COLGROUP": + node = new HTMLTableColElement(this);break; + case "DEL": + node = new HTMLModElement(this);break; + case "INS": + node = new HTMLModElement(this);break; + case "DIV": + node = new HTMLDivElement(this);break; + case "DL": + node = new HTMLDListElement(this);break; + case "DT": + node = new HTMLElement(this); break; + case "FIELDSET": + node = new HTMLFieldSetElement(this);break; + case "FORM": + node = new HTMLFormElement(this);break; + case "FRAME": + node = new HTMLFrameElement(this);break; + case "H1": + node = new HTMLHeadingElement(this);break; + case "H2": + node = new HTMLHeadingElement(this);break; + case "H3": + node = new HTMLHeadingElement(this);break; + case "H4": + node = new HTMLHeadingElement(this);break; + case "H5": + node = new HTMLHeadingElement(this);break; + case "H6": + node = new HTMLHeadingElement(this);break; + case "HEAD": + node = new HTMLHeadElement(this);break; + case "HR": + node = new HTMLHRElement(this);break; + case "HTML": + node = new HTMLHtmlElement(this);break; + case "IFRAME": + node = new HTMLIFrameElement(this);break; + case "IMG": + node = new HTMLImageElement(this);break; + case "INPUT": + node = new HTMLInputElement(this);break; + case "LABEL": + node = new HTMLLabelElement(this);break; + case "LEGEND": + node = new HTMLLegendElement(this);break; + case "LI": + node = new HTMLLIElement(this);break; + case "LINK": + node = new HTMLLinkElement(this);break; + case "MAP": + node = new HTMLMapElement(this);break; + case "META": + node = new HTMLMetaElement(this);break; + case "NOSCRIPT": + node = new HTMLElement(this);break; + case "OBJECT": + node = new HTMLObjectElement(this);break; + case "OPTGROUP": + node = new HTMLOptGroupElement(this);break; + case "OL": + node = new HTMLOListElement(this); break; + case "OPTION": + node = new HTMLOptionElement(this);break; + case "P": + node = new HTMLParagraphElement(this);break; + case "PARAM": + node = new HTMLParamElement(this);break; + case "PRE": + node = new HTMLPreElement(this);break; + case "SCRIPT": + node = new HTMLScriptElement(this);break; + case "SELECT": + node = new HTMLSelectElement(this);break; + case "SMALL": + node = new HTMLElement(this);break; + case "SPAN": + node = new HTMLSpanElement(this);break; + case "STRONG": + node = new HTMLElement(this);break; + case "STYLE": + node = new HTMLStyleElement(this);break; + case "TABLE": + node = new HTMLTableElement(this);break; + case "TBODY": + node = new HTMLTableSectionElement(this);break; + case "TFOOT": + node = new HTMLTableSectionElement(this);break; + case "THEAD": + node = new HTMLTableSectionElement(this);break; + case "TD": + node = new HTMLTableDataCellElement(this);break; + case "TH": + node = new HTMLTableHeaderCellElement(this);break; + case "TEXTAREA": + node = new HTMLTextAreaElement(this);break; + case "TITLE": + node = new HTMLTitleElement(this);break; + case "TR": + node = new HTMLTableRowElement(this);break; + case "UL": + node = new HTMLUListElement(this);break; + default: + node = new HTMLUnknownElement(this); + } + // assign values to properties (and aliases) + node.nodeName = tagName; + return node; + }, + createElementNS : function (uri, local) { + //print('createElementNS :'+uri+" "+local); + if(!uri){ + return this.createElement(local); + }else if ("http://www.w3.org/1999/xhtml" == uri) { + return this.createElement(local); + } else if ("http://www.w3.org/1998/Math/MathML" == uri) { + return this.createElement(local); + } else { + return Document.prototype.createElementNS.apply(this,[uri, local]); + } + }, + get anchors(){ + return new HTMLCollection(this.getElementsByTagName('a')); + }, + get applets(){ + return new HTMLCollection(this.getElementsByTagName('applet')); + }, + get documentElement(){ + var html = Document.prototype.__lookupGetter__('documentElement').apply(this,[]); + if( html === null){ + html = this.createElement('html'); + this.appendChild(html); + html.appendChild(this.createElement('head')); + html.appendChild(this.createElement('body')); + } + return html; + }, + //document.head is non-standard + get head(){ + //console.log('get head'); + if (!this.documentElement) { + this.appendChild(this.createElement('html')); + } + var element = this.documentElement, + length = element.childNodes.length, + i; + //check for the presence of the head element in this html doc + for(i=0;i1?matches[1]:""; + }, + set domain(value){ + var i, + domainParts = this.domain.split('.').reverse(), + newDomainParts = value.split('.').reverse(); + if(newDomainParts.length > 1){ + for(i=0;i 0){ + event = doc.createEvent('HTMLEvents'); + event.initEvent( okay ? "load" : "error", false, false ); + node.dispatchEvent( event, false ); + } + }catch(e){ + console.log('error loading html element %s %e', node, e.toString()); + } + } + break; + case 'frame': + case 'iframe': + node.contentWindow = { }; + node.contentDocument = new HTMLDocument(new DOMImplementation(), node.contentWindow); + node.contentWindow.document = node.contentDocument; + try{ + Window; + }catch(e){ + node.contentDocument.addEventListener('DOMContentLoaded', function(){ + event = node.contentDocument.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + }); + } + try{ + if (node.src && node.src.length > 0){ + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); + event = node.contentDocument.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + }else{ + //I dont like this being here: + //TODO: better mix-in strategy so the try/catch isnt required + try{ + if(Window){ + Envjs.loadFrame(node); + //console.log('src/html/document.js: triggering frame load'); + event = node.contentDocument.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + } + }catch(e){} + } + }catch(e){ + console.log('error loading html element %s %e', node, e.toString()); + } + break; + + case 'link': + if (node.href && node.href.length > 0) { + __loadLink__(node, node.href); + } + break; + /* + case 'img': + if (node.src && node.src.length > 0){ + // don't actually load anything, so we're "done" immediately: + event = doc.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + } + break; + */ + case 'option': + node._updateoptions(); + break; + default: + if(node.getAttribute('onload')){ + console.log('calling attribute onload %s | %s', node.onload, node.tagName); + node.onload(); + } + break; + }//switch on name + default: + break; + }//switch on ns + break; + default: + // console.log('element appended: %s %s', node+'', node.namespaceURI); + }//switch on doc.parsing + return node; + +}); + +Aspect.around({ + target: Node, + method:"removeChild" +}, function(invocation) { + var event, + okay, + node = invocation.proceed(), + doc = node.ownerDocument; + if((node.nodeType !== Node.ELEMENT_NODE)){ + //for now we are only handling element insertions. probably we will need + //to handle text node changes to script tags and changes to src + //attributes + if(node.nodeType !== Node.DOCUMENT_NODE && node.uuid){ + //console.log('removing event listeners, %s', node, node.uuid); + node.removeEventListener('*', null, null); + } + return node; + } + //console.log('appended html element %s %s %s', node.namespaceURI, node.nodeName, node); + + switch(doc.parsing){ + case true: + //handled by parser if included + break; + case false: + switch(node.namespaceURI){ + case null: + //fall through + case "": + //fall through + case "http://www.w3.org/1999/xhtml": + //this is interesting dillema since our event engine is + //storing the registered events in an array accessed + //by the uuid property of the node. unforunately this + //means listeners hang out way after(forever ;)) the node + //has been removed and gone out of scope. + //console.log('removing event listeners, %s', node, node.uuid); + node.removeEventListener('*', null, null); + switch(node.tagName.toLowerCase()){ + case 'frame': + case 'iframe': + try{ + //console.log('removing iframe document'); + try{ + Envjs.unloadFrame(node); + }catch(e){ + console.log('error freeing resources from frame %s', e); + } + node.contentWindow = null; + node.contentDocument = null; + }catch(e){ + console.log('error unloading html element %s %e', node, e.toString()); + } + break; + default: + break; + }//switch on name + default: + break; + }//switch on ns + break; + default: + console.log('element appended: %s %s', node+'', node.namespaceURI); + }//switch on doc.parsing + return node; + +}); + + + +/** + * Named Element Support + * + * + */ + +/* + * + * @returns 'name' if the node has a appropriate name + * null if node does not have a name + */ + +var __isNamedElement__ = function(node) { + if (node.nodeType !== Node.ELEMENT_NODE) { + return null; + } + var tagName = node.tagName.toLowerCase(); + var nodename = null; + + switch (tagName) { + case 'embed': + case 'form': + case 'iframe': + nodename = node.getAttribute('name'); + break; + case 'applet': + nodename = node.id; + break; + case 'object': + // TODO: object needs to be 'fallback free' + nodename = node.id; + break; + case 'img': + nodename = node.id; + if (!nodename || ! node.getAttribute('name')) { + nodename = null; + } + break; + } + return (nodename) ? nodename : null; +}; + + +var __addNamedMap__ = function(target, node) { + var nodename = __isNamedElement__(node); + if (nodename) { + target.__defineGetter__(nodename, function() { + return node; + }); + } +}; + +var __removeNamedMap__ = function(target, node) { + if (!node) { + return; + } + var nodename = __isNamedElement__(node); + if (nodename) { + delete target[nodename]; + } +}; + +/** + * @name HTMLEvents + * @w3c:domlevel 2 + * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html + */ + +var __eval__ = function(script, node){ + if (!script == ""){ + // don't assemble environment if no script... + try{ + eval(script); + }catch(e){ + console.log('error evaluating %s', e); + } + } +}; + +var HTMLEvents= function(){}; +HTMLEvents.prototype = { + onload: function(event){ + __eval__(this.getAttribute('onload')||'', this); + }, + onunload: function(event){ + __eval__(this.getAttribute('onunload')||'', this); + }, + onabort: function(event){ + __eval__(this.getAttribute('onabort')||'', this); + }, + onerror: function(event){ + __eval__(this.getAttribute('onerror')||'', this); + }, + onselect: function(event){ + __eval__(this.getAttribute('onselect')||'', this); + }, + onchange: function(event){ + __eval__(this.getAttribute('onchange')||'', this); + }, + onsubmit: function(event){ + if (__eval__(this.getAttribute('onsubmit')||'', this)) { + this.submit(); + } + }, + onreset: function(event){ + __eval__(this.getAttribute('onreset')||'', this); + }, + onfocus: function(event){ + __eval__(this.getAttribute('onfocus')||'', this); + }, + onblur: function(event){ + __eval__(this.getAttribute('onblur')||'', this); + }, + onresize: function(event){ + __eval__(this.getAttribute('onresize')||'', this); + }, + onscroll: function(event){ + __eval__(this.getAttribute('onscroll')||'', this); + } +}; + +//HTMLDocument, HTMLFramesetElement, HTMLObjectElement +var __load__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("load", false, false); + element.dispatchEvent(event); + return event; +}; + +//HTMLFramesetElement, HTMLBodyElement +var __unload__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("unload", false, false); + element.dispatchEvent(event); + return event; +}; + +//HTMLObjectElement +var __abort__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("abort", true, false); + element.dispatchEvent(event); + return event; +}; + +//HTMLFramesetElement, HTMLObjectElement, HTMLBodyElement +var __error__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("error", true, false); + element.dispatchEvent(event); + return event; +}; + +//HTMLInputElement, HTMLTextAreaElement +var __select__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("select", true, false); + element.dispatchEvent(event); + return event; +}; + +//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement +var __change__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("change", true, false); + element.dispatchEvent(event); + return event; +}; + +//HtmlFormElement +var __submit__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("submit", true, true); + element.dispatchEvent(event); + return event; +}; + +//HtmlFormElement +var __reset__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("reset", false, false); + element.dispatchEvent(event); + return event; +}; + +//LABEL, INPUT, SELECT, TEXTAREA, and BUTTON +var __focus__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("focus", false, false); + element.dispatchEvent(event); + return event; +}; + +//LABEL, INPUT, SELECT, TEXTAREA, and BUTTON +var __blur__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("blur", false, false); + element.dispatchEvent(event); + return event; +}; + +//Window +var __resize__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("resize", true, false); + element.dispatchEvent(event); + return event; +}; + +//Window +var __scroll__ = function(element){ + var event = new Event('HTMLEvents'); + event.initEvent("scroll", true, false); + element.dispatchEvent(event); + return event; +}; + +/** + * @name KeyboardEvents + * @w3c:domlevel 2 + * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html + */ +var KeyboardEvents= function(){}; +KeyboardEvents.prototype = { + onkeydown: function(event){ + __eval__(this.getAttribute('onkeydown')||'', this); + }, + onkeypress: function(event){ + __eval__(this.getAttribute('onkeypress')||'', this); + }, + onkeyup: function(event){ + __eval__(this.getAttribute('onkeyup')||'', this); + } +}; + + +var __registerKeyboardEventAttrs__ = function(elm){ + if(elm.hasAttribute('onkeydown')){ + elm.addEventListener('keydown', elm.onkeydown, false); + } + if(elm.hasAttribute('onkeypress')){ + elm.addEventListener('keypress', elm.onkeypress, false); + } + if(elm.hasAttribute('onkeyup')){ + elm.addEventListener('keyup', elm.onkeyup, false); + } + return elm; +}; + +//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement +var __keydown__ = function(element){ + var event = new Event('KeyboardEvents'); + event.initEvent("keydown", false, false); + element.dispatchEvent(event); +}; + +//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement +var __keypress__ = function(element){ + var event = new Event('KeyboardEvents'); + event.initEvent("keypress", false, false); + element.dispatchEvent(event); +}; + +//HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement +var __keyup__ = function(element){ + var event = new Event('KeyboardEvents'); + event.initEvent("keyup", false, false); + element.dispatchEvent(event); +}; + +/** + * @name MaouseEvents + * @w3c:domlevel 2 + * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html + */ +var MouseEvents= function(){}; +MouseEvents.prototype = { + onclick: function(event){ + __eval__(this.getAttribute('onclick')||'', this); + }, + ondblclick: function(event){ + __eval__(this.getAttribute('ondblclick')||'', this); + }, + onmousedown: function(event){ + __eval__(this.getAttribute('onmousedown')||'', this); + }, + onmousemove: function(event){ + __eval__(this.getAttribute('onmousemove')||'', this); + }, + onmouseout: function(event){ + __eval__(this.getAttribute('onmouseout')||'', this); + }, + onmouseover: function(event){ + __eval__(this.getAttribute('onmouseover')||'', this); + }, + onmouseup: function(event){ + __eval__(this.getAttribute('onmouseup')||'', this); + } +}; + +var __registerMouseEventAttrs__ = function(elm){ + if(elm.hasAttribute('onclick')){ + elm.addEventListener('click', elm.onclick, false); + } + if(elm.hasAttribute('ondblclick')){ + elm.addEventListener('dblclick', elm.ondblclick, false); + } + if(elm.hasAttribute('onmousedown')){ + elm.addEventListener('mousedown', elm.onmousedown, false); + } + if(elm.hasAttribute('onmousemove')){ + elm.addEventListener('mousemove', elm.onmousemove, false); + } + if(elm.hasAttribute('onmouseout')){ + elm.addEventListener('mouseout', elm.onmouseout, false); + } + if(elm.hasAttribute('onmouseover')){ + elm.addEventListener('mouseover', elm.onmouseover, false); + } + if(elm.hasAttribute('onmouseup')){ + elm.addEventListener('mouseup', elm.onmouseup, false); + } + return elm; +}; + + +var __click__ = function(element){ + var event = new Event('MouseEvents'); + event.initEvent("click", true, true, null, 0, + 0, 0, 0, 0, false, false, false, + false, null, null); + element.dispatchEvent(event); +}; +var __mousedown__ = function(element){ + var event = new Event('MouseEvents'); + event.initEvent("mousedown", true, true, null, 0, + 0, 0, 0, 0, false, false, false, + false, null, null); + element.dispatchEvent(event); +}; +var __mouseup__ = function(element){ + var event = new Event('MouseEvents'); + event.initEvent("mouseup", true, true, null, 0, + 0, 0, 0, 0, false, false, false, + false, null, null); + element.dispatchEvent(event); +}; +var __mouseover__ = function(element){ + var event = new Event('MouseEvents'); + event.initEvent("mouseover", true, true, null, 0, + 0, 0, 0, 0, false, false, false, + false, null, null); + element.dispatchEvent(event); +}; +var __mousemove__ = function(element){ + var event = new Event('MouseEvents'); + event.initEvent("mousemove", true, true, null, 0, + 0, 0, 0, 0, false, false, false, + false, null, null); + element.dispatchEvent(event); +}; +var __mouseout__ = function(element){ + var event = new Event('MouseEvents'); + event.initEvent("mouseout", true, true, null, 0, + 0, 0, 0, 0, false, false, false, + false, null, null); + element.dispatchEvent(event); +}; + +/** + * HTMLElement - DOM Level 2 + */ + + +/* Hack for http://www.prototypejs.org/ + * + * Prototype 1.6 (the library) creates a new global Element, which causes + * envjs to use the wrong Element. + * + * http://envjs.lighthouseapp.com/projects/21590/tickets/108-prototypejs-wont-load-due-it-clobbering-element + * + * Options: + * (1) Rename the dom/element to something else + * rejected: been done before. people want Element. + * (2) merge dom+html and not export Element to global namespace + * (meaning we would use a local var Element in a closure, so prototype + * can do what ever it wants) + * rejected: want dom and html separate + * (3) use global namespace (put everything under Envjs = {}) + * rejected: massive change + * (4) use commonjs modules (similar to (3) in spirit) + * rejected: massive change + * + * or + * + * (5) take a reference to Element during initial loading ("compile + * time"), and use the reference instead of "Element". That's + * what the next line does. We use __DOMElement__ if we need to + * reference the parent class. Only this file explcity uses + * Element so this should work, and is the most minimal change I + * could think of with no external API changes. + * + */ +var __DOMElement__ = Element; + +HTMLElement = function(ownerDocument) { + __DOMElement__.apply(this, arguments); +}; + +HTMLElement.prototype = new Element(); +__extend__(HTMLElement.prototype, HTMLEvents.prototype); +__extend__(HTMLElement.prototype, { + get className() { + return this.getAttribute("class")||''; + }, + set className(value) { + return this.setAttribute("class",__trim__(value)); + }, + get dir() { + return this.getAttribute("dir")||"ltr"; + }, + set dir(val) { + return this.setAttribute("dir",val); + }, + get id(){ + return this.getAttribute('id'); + }, + set id(id){ + this.setAttribute('id', id); + }, + get innerHTML(){ + var ret = "", + i; + + // create string containing the concatenation of the string + // values of each child + for (i=0; i < this.childNodes.length; i++) { + if(this.childNodes[i]){ + if(this.childNodes[i].nodeType === Node.ELEMENT_NODE){ + ret += this.childNodes[i].xhtml; + } else if (this.childNodes[i].nodeType === Node.TEXT_NODE && i>0 && + this.childNodes[i-1].nodeType === Node.TEXT_NODE){ + //add a single space between adjacent text nodes + ret += " "+this.childNodes[i].xml; + }else{ + ret += this.childNodes[i].xml; + } + } + } + return ret; + }, + get lang() { + return this.getAttribute("lang"); + }, + set lang(val) { + return this.setAttribute("lang",val); + }, + get offsetHeight(){ + return Number((this.style.height || '').replace("px","")); + }, + get offsetWidth(){ + return Number((this.style.width || '').replace("px","")); + }, + offsetLeft: 0, + offsetRight: 0, + get offsetParent(){ + /* TODO */ + return; + }, + set offsetParent(element){ + /* TODO */ + return; + }, + scrollHeight: 0, + scrollWidth: 0, + scrollLeft: 0, + scrollRight: 0, + get style(){ + return this.getAttribute('style')||''; + }, + get title() { + return this.getAttribute("title"); + }, + set title(value) { + return this.setAttribute("title", value); + }, + get tabIndex(){ + var tabindex = this.getAttribute('tabindex'); + if(tabindex!==null){ + return Number(tabindex); + } else { + return 0; + } + }, + set tabIndex(value){ + if (value === undefined || value === null) { + value = 0; + } + this.setAttribute('tabindex',Number(value)); + }, + get outerHTML(){ + //Not in the specs but I'll leave it here for now. + return this.xhtml; + }, + scrollIntoView: function(){ + /*TODO*/ + return; + }, + toString: function(){ + return '[object HTMLElement]'; + }, + get xhtml() { + // HTMLDocument.xhtml is non-standard + // This is exactly like Document.xml except the tagName has to be + // lower cased. I dont like to duplicate this but its really not + // a simple work around between xml and html serialization via + // XMLSerializer (which uppercases html tags) and innerHTML (which + // lowercases tags) + + var ret = "", + ns = "", + name = (this.tagName+"").toLowerCase(), + attrs, + attrstring = "", + i; + + // serialize namespace declarations + if (this.namespaceURI){ + if((this === this.ownerDocument.documentElement) || + (!this.parentNode) || + (this.parentNode && + (this.parentNode.namespaceURI !== this.namespaceURI))) { + ns = ' xmlns' + (this.prefix ? (':' + this.prefix) : '') + + '="' + this.namespaceURI + '"'; + } + } + + // serialize Attribute declarations + attrs = this.attributes; + for(i=0;i< attrs.length;i++){ + attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"'; + } + + if(this.hasChildNodes()){ + // serialize this Element + ret += "<" + name + ns + attrstring +">"; + for(i=0;i< this.childNodes.length;i++){ + ret += this.childNodes[i].xhtml ? + this.childNodes[i].xhtml : + this.childNodes[i].xml; + } + ret += ""; + }else{ + switch(name){ + case 'script': + ret += "<" + name + ns + attrstring +">"; + break; + default: + ret += "<" + name + ns + attrstring +"/>"; + } + } + + return ret; + }, + + /** + * setAttribute use a dispatch table that other tags can set to + * "listen" to various values being set. The dispatch table + * and registration functions are at the end of the file. + * + */ + + setAttribute: function(name, value) { + var result = __DOMElement__.prototype.setAttribute.apply(this, arguments); + __addNamedMap__(this.ownerDocument, this); + var tagname = this.tagName; + var callback = HTMLElement.getAttributeCallback('set', tagname, name); + if (callback) { + callback(this, value); + } + }, + setAttributeNS: function(namespaceURI, name, value) { + var result = __DOMElement__.prototype.setAttributeNS.apply(this, arguments); + __addNamedMap__(this.ownerDocument, this); + var tagname = this.tagName; + var callback = HTMLElement.getAttributeCallback('set', tagname, name); + if (callback) { + callback(this, value); + } + + return result; + }, + setAttributeNode: function(newnode) { + var result = __DOMElement__.prototype.setAttributeNode.apply(this, arguments); + __addNamedMap__(this.ownerDocument, this); + var tagname = this.tagName; + var callback = HTMLElement.getAttributeCallback('set', tagname, newnode.name); + if (callback) { + callback(this, node.value); + } + return result; + }, + setAttributeNodeNS: function(newnode) { + var result = __DOMElement__.prototype.setAttributeNodeNS.apply(this, arguments); + __addNamedMap__(this.ownerDocument, this); + var tagname = this.tagName; + var callback = HTMLElement.getAttributeCallback('set', tagname, newnode.name); + if (callback) { + callback(this, node.value); + } + return result; + }, + removeAttribute: function(name) { + __removeNamedMap__(this.ownerDocument, this); + return __DOMElement__.prototype.removeAttribute.apply(this, arguments); + }, + removeAttributeNS: function(namespace, localname) { + __removeNamedMap__(this.ownerDocument, this); + return __DOMElement__.prototype.removeAttributeNS.apply(this, arguments); + }, + removeAttributeNode: function(name) { + __removeNamedMap__(this.ownerDocument, this); + return __DOMElement__.prototype.removeAttribute.apply(this, arguments); + }, + removeChild: function(oldChild) { + __removeNamedMap__(this.ownerDocument, oldChild); + return __DOMElement__.prototype.removeChild.apply(this, arguments); + }, + importNode: function(othernode, deep) { + var newnode = __DOMElement__.prototype.importNode.apply(this, arguments); + __addNamedMap__(this.ownerDocument, newnode); + return newnode; + }, + + // not actually sure if this is needed or not + replaceNode: function(newchild, oldchild) { + var newnode = __DOMElement__.prototype.replaceNode.apply(this, arguments); + __removeNamedMap__(this.ownerDocument, oldchild); + __addNamedMap__(this.ownerDocument, newnode); + return newnode; + } +}); + + +HTMLElement.attributeCallbacks = {}; +HTMLElement.registerSetAttribute = function(tag, attrib, callbackfn) { + HTMLElement.attributeCallbacks[tag + ':set:' + attrib] = callbackfn; +}; +HTMLElement.registerRemoveAttribute = function(tag, attrib, callbackfn) { + HTMLElement.attributeCallbacks[tag + ':remove:' + attrib] = callbackfn; +}; + +/** + * This is really only useful internally + * + */ +HTMLElement.getAttributeCallback = function(type, tag, attrib) { + return HTMLElement.attributeCallbacks[tag + ':' + type + ':' + attrib] || null; +}; +/* + * HTMLCollection + * + * HTML5 -- 2.7.2.1 HTMLCollection + * http://dev.w3.org/html5/spec/Overview.html#htmlcollection + * http://dev.w3.org/html5/spec/Overview.html#collections + */ +HTMLCollection = function(nodelist, type) { + + __setArray__(this, []); + var n; + for (var i=0; i= 0) && (idx < this.length)) ? this[idx] : null; + }, + + namedItem: function (name) { + return this[name] || null; + }, + + toString: function() { + return '[object HTMLCollection]'; + } +}; +/* + * a set of convenience classes to centralize implementation of + * properties and methods across multiple in-form elements + * + * the hierarchy of related HTML elements and their members is as follows: + * + * Condensed Version + * + * HTMLInputCommon + * * legent (no value attr) + * * fieldset (no value attr) + * * label (no value attr) + * * option (custom value) + * HTMLTypeValueInputs (extends InputCommon) + * * select (custom value) + * * button (just sets value) + * HTMLInputAreaCommon (extends TypeValueIput) + * * input (custom) + * * textarea (just sets value) + * + * ----------------------- + * HTMLInputCommon: common to all elements + * .form + * + * + * [common plus:] + * .align + * + *
+ * [identical to "legend" plus:] + * .margin + * + * + * **** + * + *