diff --git a/.gitignore b/.gitignore index 1109132..5fd4491 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /uglifier-2.3.0.gem /uglifier-2.4.0.gem /uglifier-3.0.0.gem +/uglifier-3.0.2.gem diff --git a/rubygem-uglifier-3.0.0-fix-test-for-uglifyjs-2.7.0.patch b/rubygem-uglifier-3.0.0-fix-test-for-uglifyjs-2.7.0.patch deleted file mode 100644 index 710af92..0000000 --- a/rubygem-uglifier-3.0.0-fix-test-for-uglifyjs-2.7.0.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f676b66f1d35653f81b9645508c30053b680a64b Mon Sep 17 00:00:00 2001 -From: Ville Lautanala -Date: Sun, 24 Jul 2016 20:29:43 +0300 -Subject: [PATCH] Update UglifyJS to 2.7.0 - ---- - CHANGELOG.md | 4 ++++ - lib/uglify.js | 21 +++++++++++---------- - spec/uglifier_spec.rb | 2 +- - vendor/uglifyjs | 2 +- - 4 files changed, 17 insertions(+), 12 deletions(-) - -diff --git a/spec/uglifier_spec.rb b/spec/uglifier_spec.rb -index 7f0fdc1..8f2420e 100644 ---- a/spec/uglifier_spec.rb -+++ b/spec/uglifier_spec.rb -@@ -19,7 +19,7 @@ - end - - it "doesn't omit null character in strings" do -- expect(Uglifier.new.compile('var foo="\0bar"')).to include("\\x00bar") -+ expect(Uglifier.new.compile('var foo="\0bar"')).to include("\\0bar") - end - - it "adds trailing semicolon to minified source" do diff --git a/rubygem-uglifier-3.0.0-separate-source-map.patch b/rubygem-uglifier-3.0.0-separate-source-map.patch deleted file mode 100644 index 5296b9c..0000000 --- a/rubygem-uglifier-3.0.0-separate-source-map.patch +++ /dev/null @@ -1,6103 +0,0 @@ -From 8866392cef092ee4ad3a5a5276e03bc67eb7a51d Mon Sep 17 00:00:00 2001 -From: Jun Aruga -Date: Fri, 22 Jul 2016 19:19:51 +0200 -Subject: [PATCH] Separate Source Map and UglifyJS library file. - ---- - Rakefile | 8 +- - lib/source-map.js | 3005 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - lib/uglifier.js | 3 + - lib/uglifier.rb | 5 +- - lib/uglify.js | 3006 +---------------------------------------------------- - 5 files changed, 3016 insertions(+), 3011 deletions(-) - create mode 100644 lib/source-map.js - -diff --git a/Rakefile b/Rakefile -index a70363e..f42d63f 100644 ---- a/Rakefile -+++ b/Rakefile -@@ -1,5 +1,6 @@ - # encoding: utf-8 - -+require 'fileutils' - require 'bundler/gem_tasks' - require 'rspec/core/rake_task' - RSpec::Core::RakeTask.new(:spec) do |spec| -@@ -17,12 +18,9 @@ task :js do - `npm install` - end - -- source = "" -- source << "window = this;" -- source << File.read("vendor/source-map/dist/source-map.js") -- source << "MOZ_SourceMap = sourceMap;" -- source << `./vendor/uglifyjs/bin/uglifyjs --self --comments /Copyright/` -+ FileUtils.cp("vendor/source-map/dist/source-map.js", "lib/source-map.js") - -+ source = `./vendor/uglifyjs/bin/uglifyjs --self --comments /Copyright/` - File.write("lib/uglify.js", source) - end - -diff --git a/lib/source-map.js b/lib/source-map.js -new file mode 100644 -index 0000000..25199a6 ---- /dev/null -+++ b/lib/source-map.js -@@ -0,0 +1,3005 @@ -+(function webpackUniversalModuleDefinition(root, factory) { -+ if(typeof exports === 'object' && typeof module === 'object') -+ module.exports = factory(); -+ else if(typeof define === 'function' && define.amd) -+ define([], factory); -+ else if(typeof exports === 'object') -+ exports["sourceMap"] = factory(); -+ else -+ root["sourceMap"] = factory(); -+})(this, function() { -+return /******/ (function(modules) { // webpackBootstrap -+/******/ // The module cache -+/******/ var installedModules = {}; -+ -+/******/ // The require function -+/******/ function __webpack_require__(moduleId) { -+ -+/******/ // Check if module is in cache -+/******/ if(installedModules[moduleId]) -+/******/ return installedModules[moduleId].exports; -+ -+/******/ // Create a new module (and put it into the cache) -+/******/ var module = installedModules[moduleId] = { -+/******/ exports: {}, -+/******/ id: moduleId, -+/******/ loaded: false -+/******/ }; -+ -+/******/ // Execute the module function -+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -+ -+/******/ // Flag the module as loaded -+/******/ module.loaded = true; -+ -+/******/ // Return the exports of the module -+/******/ return module.exports; -+/******/ } -+ -+ -+/******/ // expose the modules object (__webpack_modules__) -+/******/ __webpack_require__.m = modules; -+ -+/******/ // expose the module cache -+/******/ __webpack_require__.c = installedModules; -+ -+/******/ // __webpack_public_path__ -+/******/ __webpack_require__.p = ""; -+ -+/******/ // Load entry module and return exports -+/******/ return __webpack_require__(0); -+/******/ }) -+/************************************************************************/ -+/******/ ([ -+/* 0 */ -+/***/ function(module, exports, __webpack_require__) { -+ -+ /* -+ * Copyright 2009-2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE.txt or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; -+ exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; -+ exports.SourceNode = __webpack_require__(10).SourceNode; -+ -+ -+/***/ }, -+/* 1 */ -+/***/ function(module, exports, __webpack_require__) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ var base64VLQ = __webpack_require__(2); -+ var util = __webpack_require__(4); -+ var ArraySet = __webpack_require__(5).ArraySet; -+ var MappingList = __webpack_require__(6).MappingList; -+ -+ /** -+ * An instance of the SourceMapGenerator represents a source map which is -+ * being built incrementally. You may pass an object with the following -+ * properties: -+ * -+ * - file: The filename of the generated source. -+ * - sourceRoot: A root for all relative URLs in this source map. -+ */ -+ function SourceMapGenerator(aArgs) { -+ if (!aArgs) { -+ aArgs = {}; -+ } -+ this._file = util.getArg(aArgs, 'file', null); -+ this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); -+ this._skipValidation = util.getArg(aArgs, 'skipValidation', false); -+ this._sources = new ArraySet(); -+ this._names = new ArraySet(); -+ this._mappings = new MappingList(); -+ this._sourcesContents = null; -+ } -+ -+ SourceMapGenerator.prototype._version = 3; -+ -+ /** -+ * Creates a new SourceMapGenerator based on a SourceMapConsumer -+ * -+ * @param aSourceMapConsumer The SourceMap. -+ */ -+ SourceMapGenerator.fromSourceMap = -+ function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { -+ var sourceRoot = aSourceMapConsumer.sourceRoot; -+ var generator = new SourceMapGenerator({ -+ file: aSourceMapConsumer.file, -+ sourceRoot: sourceRoot -+ }); -+ aSourceMapConsumer.eachMapping(function (mapping) { -+ var newMapping = { -+ generated: { -+ line: mapping.generatedLine, -+ column: mapping.generatedColumn -+ } -+ }; -+ -+ if (mapping.source != null) { -+ newMapping.source = mapping.source; -+ if (sourceRoot != null) { -+ newMapping.source = util.relative(sourceRoot, newMapping.source); -+ } -+ -+ newMapping.original = { -+ line: mapping.originalLine, -+ column: mapping.originalColumn -+ }; -+ -+ if (mapping.name != null) { -+ newMapping.name = mapping.name; -+ } -+ } -+ -+ generator.addMapping(newMapping); -+ }); -+ aSourceMapConsumer.sources.forEach(function (sourceFile) { -+ var content = aSourceMapConsumer.sourceContentFor(sourceFile); -+ if (content != null) { -+ generator.setSourceContent(sourceFile, content); -+ } -+ }); -+ return generator; -+ }; -+ -+ /** -+ * Add a single mapping from original source line and column to the generated -+ * source's line and column for this source map being created. The mapping -+ * object should have the following properties: -+ * -+ * - generated: An object with the generated line and column positions. -+ * - original: An object with the original line and column positions. -+ * - source: The original source file (relative to the sourceRoot). -+ * - name: An optional original token name for this mapping. -+ */ -+ SourceMapGenerator.prototype.addMapping = -+ function SourceMapGenerator_addMapping(aArgs) { -+ var generated = util.getArg(aArgs, 'generated'); -+ var original = util.getArg(aArgs, 'original', null); -+ var source = util.getArg(aArgs, 'source', null); -+ var name = util.getArg(aArgs, 'name', null); -+ -+ if (!this._skipValidation) { -+ this._validateMapping(generated, original, source, name); -+ } -+ -+ if (source != null && !this._sources.has(source)) { -+ this._sources.add(source); -+ } -+ -+ if (name != null && !this._names.has(name)) { -+ this._names.add(name); -+ } -+ -+ this._mappings.add({ -+ generatedLine: generated.line, -+ generatedColumn: generated.column, -+ originalLine: original != null && original.line, -+ originalColumn: original != null && original.column, -+ source: source, -+ name: name -+ }); -+ }; -+ -+ /** -+ * Set the source content for a source file. -+ */ -+ SourceMapGenerator.prototype.setSourceContent = -+ function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { -+ var source = aSourceFile; -+ if (this._sourceRoot != null) { -+ source = util.relative(this._sourceRoot, source); -+ } -+ -+ if (aSourceContent != null) { -+ // Add the source content to the _sourcesContents map. -+ // Create a new _sourcesContents map if the property is null. -+ if (!this._sourcesContents) { -+ this._sourcesContents = {}; -+ } -+ this._sourcesContents[util.toSetString(source)] = aSourceContent; -+ } else if (this._sourcesContents) { -+ // Remove the source file from the _sourcesContents map. -+ // If the _sourcesContents map is empty, set the property to null. -+ delete this._sourcesContents[util.toSetString(source)]; -+ if (Object.keys(this._sourcesContents).length === 0) { -+ this._sourcesContents = null; -+ } -+ } -+ }; -+ -+ /** -+ * Applies the mappings of a sub-source-map for a specific source file to the -+ * source map being generated. Each mapping to the supplied source file is -+ * rewritten using the supplied source map. Note: The resolution for the -+ * resulting mappings is the minimium of this map and the supplied map. -+ * -+ * @param aSourceMapConsumer The source map to be applied. -+ * @param aSourceFile Optional. The filename of the source file. -+ * If omitted, SourceMapConsumer's file property will be used. -+ * @param aSourceMapPath Optional. The dirname of the path to the source map -+ * to be applied. If relative, it is relative to the SourceMapConsumer. -+ * This parameter is needed when the two source maps aren't in the same -+ * directory, and the source map to be applied contains relative source -+ * paths. If so, those relative source paths need to be rewritten -+ * relative to the SourceMapGenerator. -+ */ -+ SourceMapGenerator.prototype.applySourceMap = -+ function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { -+ var sourceFile = aSourceFile; -+ // If aSourceFile is omitted, we will use the file property of the SourceMap -+ if (aSourceFile == null) { -+ if (aSourceMapConsumer.file == null) { -+ throw new Error( -+ 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + -+ 'or the source map\'s "file" property. Both were omitted.' -+ ); -+ } -+ sourceFile = aSourceMapConsumer.file; -+ } -+ var sourceRoot = this._sourceRoot; -+ // Make "sourceFile" relative if an absolute Url is passed. -+ if (sourceRoot != null) { -+ sourceFile = util.relative(sourceRoot, sourceFile); -+ } -+ // Applying the SourceMap can add and remove items from the sources and -+ // the names array. -+ var newSources = new ArraySet(); -+ var newNames = new ArraySet(); -+ -+ // Find mappings for the "sourceFile" -+ this._mappings.unsortedForEach(function (mapping) { -+ if (mapping.source === sourceFile && mapping.originalLine != null) { -+ // Check if it can be mapped by the source map, then update the mapping. -+ var original = aSourceMapConsumer.originalPositionFor({ -+ line: mapping.originalLine, -+ column: mapping.originalColumn -+ }); -+ if (original.source != null) { -+ // Copy mapping -+ mapping.source = original.source; -+ if (aSourceMapPath != null) { -+ mapping.source = util.join(aSourceMapPath, mapping.source) -+ } -+ if (sourceRoot != null) { -+ mapping.source = util.relative(sourceRoot, mapping.source); -+ } -+ mapping.originalLine = original.line; -+ mapping.originalColumn = original.column; -+ if (original.name != null) { -+ mapping.name = original.name; -+ } -+ } -+ } -+ -+ var source = mapping.source; -+ if (source != null && !newSources.has(source)) { -+ newSources.add(source); -+ } -+ -+ var name = mapping.name; -+ if (name != null && !newNames.has(name)) { -+ newNames.add(name); -+ } -+ -+ }, this); -+ this._sources = newSources; -+ this._names = newNames; -+ -+ // Copy sourcesContents of applied map. -+ aSourceMapConsumer.sources.forEach(function (sourceFile) { -+ var content = aSourceMapConsumer.sourceContentFor(sourceFile); -+ if (content != null) { -+ if (aSourceMapPath != null) { -+ sourceFile = util.join(aSourceMapPath, sourceFile); -+ } -+ if (sourceRoot != null) { -+ sourceFile = util.relative(sourceRoot, sourceFile); -+ } -+ this.setSourceContent(sourceFile, content); -+ } -+ }, this); -+ }; -+ -+ /** -+ * A mapping can have one of the three levels of data: -+ * -+ * 1. Just the generated position. -+ * 2. The Generated position, original position, and original source. -+ * 3. Generated and original position, original source, as well as a name -+ * token. -+ * -+ * To maintain consistency, we validate that any new mapping being added falls -+ * in to one of these categories. -+ */ -+ SourceMapGenerator.prototype._validateMapping = -+ function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, -+ aName) { -+ if (aGenerated && 'line' in aGenerated && 'column' in aGenerated -+ && aGenerated.line > 0 && aGenerated.column >= 0 -+ && !aOriginal && !aSource && !aName) { -+ // Case 1. -+ return; -+ } -+ else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated -+ && aOriginal && 'line' in aOriginal && 'column' in aOriginal -+ && aGenerated.line > 0 && aGenerated.column >= 0 -+ && aOriginal.line > 0 && aOriginal.column >= 0 -+ && aSource) { -+ // Cases 2 and 3. -+ return; -+ } -+ else { -+ throw new Error('Invalid mapping: ' + JSON.stringify({ -+ generated: aGenerated, -+ source: aSource, -+ original: aOriginal, -+ name: aName -+ })); -+ } -+ }; -+ -+ /** -+ * Serialize the accumulated mappings in to the stream of base 64 VLQs -+ * specified by the source map format. -+ */ -+ SourceMapGenerator.prototype._serializeMappings = -+ function SourceMapGenerator_serializeMappings() { -+ var previousGeneratedColumn = 0; -+ var previousGeneratedLine = 1; -+ var previousOriginalColumn = 0; -+ var previousOriginalLine = 0; -+ var previousName = 0; -+ var previousSource = 0; -+ var result = ''; -+ var mapping; -+ var nameIdx; -+ var sourceIdx; -+ -+ var mappings = this._mappings.toArray(); -+ for (var i = 0, len = mappings.length; i < len; i++) { -+ mapping = mappings[i]; -+ -+ if (mapping.generatedLine !== previousGeneratedLine) { -+ previousGeneratedColumn = 0; -+ while (mapping.generatedLine !== previousGeneratedLine) { -+ result += ';'; -+ previousGeneratedLine++; -+ } -+ } -+ else { -+ if (i > 0) { -+ if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { -+ continue; -+ } -+ result += ','; -+ } -+ } -+ -+ result += base64VLQ.encode(mapping.generatedColumn -+ - previousGeneratedColumn); -+ previousGeneratedColumn = mapping.generatedColumn; -+ -+ if (mapping.source != null) { -+ sourceIdx = this._sources.indexOf(mapping.source); -+ result += base64VLQ.encode(sourceIdx - previousSource); -+ previousSource = sourceIdx; -+ -+ // lines are stored 0-based in SourceMap spec version 3 -+ result += base64VLQ.encode(mapping.originalLine - 1 -+ - previousOriginalLine); -+ previousOriginalLine = mapping.originalLine - 1; -+ -+ result += base64VLQ.encode(mapping.originalColumn -+ - previousOriginalColumn); -+ previousOriginalColumn = mapping.originalColumn; -+ -+ if (mapping.name != null) { -+ nameIdx = this._names.indexOf(mapping.name); -+ result += base64VLQ.encode(nameIdx - previousName); -+ previousName = nameIdx; -+ } -+ } -+ } -+ -+ return result; -+ }; -+ -+ SourceMapGenerator.prototype._generateSourcesContent = -+ function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { -+ return aSources.map(function (source) { -+ if (!this._sourcesContents) { -+ return null; -+ } -+ if (aSourceRoot != null) { -+ source = util.relative(aSourceRoot, source); -+ } -+ var key = util.toSetString(source); -+ return Object.prototype.hasOwnProperty.call(this._sourcesContents, -+ key) -+ ? this._sourcesContents[key] -+ : null; -+ }, this); -+ }; -+ -+ /** -+ * Externalize the source map. -+ */ -+ SourceMapGenerator.prototype.toJSON = -+ function SourceMapGenerator_toJSON() { -+ var map = { -+ version: this._version, -+ sources: this._sources.toArray(), -+ names: this._names.toArray(), -+ mappings: this._serializeMappings() -+ }; -+ if (this._file != null) { -+ map.file = this._file; -+ } -+ if (this._sourceRoot != null) { -+ map.sourceRoot = this._sourceRoot; -+ } -+ if (this._sourcesContents) { -+ map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); -+ } -+ -+ return map; -+ }; -+ -+ /** -+ * Render the source map being generated to a string. -+ */ -+ SourceMapGenerator.prototype.toString = -+ function SourceMapGenerator_toString() { -+ return JSON.stringify(this.toJSON()); -+ }; -+ -+ exports.SourceMapGenerator = SourceMapGenerator; -+ } -+ -+ -+/***/ }, -+/* 2 */ -+/***/ function(module, exports, __webpack_require__) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ * -+ * Based on the Base 64 VLQ implementation in Closure Compiler: -+ * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java -+ * -+ * Copyright 2011 The Closure Compiler Authors. All rights reserved. -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are -+ * met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following -+ * disclaimer in the documentation and/or other materials provided -+ * with the distribution. -+ * * Neither the name of Google Inc. nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ { -+ var base64 = __webpack_require__(3); -+ -+ // A single base 64 digit can contain 6 bits of data. For the base 64 variable -+ // length quantities we use in the source map spec, the first bit is the sign, -+ // the next four bits are the actual value, and the 6th bit is the -+ // continuation bit. The continuation bit tells us whether there are more -+ // digits in this value following this digit. -+ // -+ // Continuation -+ // | Sign -+ // | | -+ // V V -+ // 101011 -+ -+ var VLQ_BASE_SHIFT = 5; -+ -+ // binary: 100000 -+ var VLQ_BASE = 1 << VLQ_BASE_SHIFT; -+ -+ // binary: 011111 -+ var VLQ_BASE_MASK = VLQ_BASE - 1; -+ -+ // binary: 100000 -+ var VLQ_CONTINUATION_BIT = VLQ_BASE; -+ -+ /** -+ * Converts from a two-complement value to a value where the sign bit is -+ * placed in the least significant bit. For example, as decimals: -+ * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) -+ * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) -+ */ -+ function toVLQSigned(aValue) { -+ return aValue < 0 -+ ? ((-aValue) << 1) + 1 -+ : (aValue << 1) + 0; -+ } -+ -+ /** -+ * Converts to a two-complement value from a value where the sign bit is -+ * placed in the least significant bit. For example, as decimals: -+ * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 -+ * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 -+ */ -+ function fromVLQSigned(aValue) { -+ var isNegative = (aValue & 1) === 1; -+ var shifted = aValue >> 1; -+ return isNegative -+ ? -shifted -+ : shifted; -+ } -+ -+ /** -+ * Returns the base 64 VLQ encoded value. -+ */ -+ exports.encode = function base64VLQ_encode(aValue) { -+ var encoded = ""; -+ var digit; -+ -+ var vlq = toVLQSigned(aValue); -+ -+ do { -+ digit = vlq & VLQ_BASE_MASK; -+ vlq >>>= VLQ_BASE_SHIFT; -+ if (vlq > 0) { -+ // There are still more digits in this value, so we must make sure the -+ // continuation bit is marked. -+ digit |= VLQ_CONTINUATION_BIT; -+ } -+ encoded += base64.encode(digit); -+ } while (vlq > 0); -+ -+ return encoded; -+ }; -+ -+ /** -+ * Decodes the next base 64 VLQ value from the given string and returns the -+ * value and the rest of the string via the out parameter. -+ */ -+ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { -+ var strLen = aStr.length; -+ var result = 0; -+ var shift = 0; -+ var continuation, digit; -+ -+ do { -+ if (aIndex >= strLen) { -+ throw new Error("Expected more digits in base 64 VLQ value."); -+ } -+ -+ digit = base64.decode(aStr.charCodeAt(aIndex++)); -+ if (digit === -1) { -+ throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); -+ } -+ -+ continuation = !!(digit & VLQ_CONTINUATION_BIT); -+ digit &= VLQ_BASE_MASK; -+ result = result + (digit << shift); -+ shift += VLQ_BASE_SHIFT; -+ } while (continuation); -+ -+ aOutParam.value = fromVLQSigned(result); -+ aOutParam.rest = aIndex; -+ }; -+ } -+ -+ -+/***/ }, -+/* 3 */ -+/***/ function(module, exports) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); -+ -+ /** -+ * Encode an integer in the range of 0 to 63 to a single base 64 digit. -+ */ -+ exports.encode = function (number) { -+ if (0 <= number && number < intToCharMap.length) { -+ return intToCharMap[number]; -+ } -+ throw new TypeError("Must be between 0 and 63: " + number); -+ }; -+ -+ /** -+ * Decode a single base 64 character code digit to an integer. Returns -1 on -+ * failure. -+ */ -+ exports.decode = function (charCode) { -+ var bigA = 65; // 'A' -+ var bigZ = 90; // 'Z' -+ -+ var littleA = 97; // 'a' -+ var littleZ = 122; // 'z' -+ -+ var zero = 48; // '0' -+ var nine = 57; // '9' -+ -+ var plus = 43; // '+' -+ var slash = 47; // '/' -+ -+ var littleOffset = 26; -+ var numberOffset = 52; -+ -+ // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ -+ if (bigA <= charCode && charCode <= bigZ) { -+ return (charCode - bigA); -+ } -+ -+ // 26 - 51: abcdefghijklmnopqrstuvwxyz -+ if (littleA <= charCode && charCode <= littleZ) { -+ return (charCode - littleA + littleOffset); -+ } -+ -+ // 52 - 61: 0123456789 -+ if (zero <= charCode && charCode <= nine) { -+ return (charCode - zero + numberOffset); -+ } -+ -+ // 62: + -+ if (charCode == plus) { -+ return 62; -+ } -+ -+ // 63: / -+ if (charCode == slash) { -+ return 63; -+ } -+ -+ // Invalid base64 digit. -+ return -1; -+ }; -+ } -+ -+ -+/***/ }, -+/* 4 */ -+/***/ function(module, exports) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ /** -+ * This is a helper function for getting values from parameter/options -+ * objects. -+ * -+ * @param args The object we are extracting values from -+ * @param name The name of the property we are getting. -+ * @param defaultValue An optional value to return if the property is missing -+ * from the object. If this is not specified and the property is missing, an -+ * error will be thrown. -+ */ -+ function getArg(aArgs, aName, aDefaultValue) { -+ if (aName in aArgs) { -+ return aArgs[aName]; -+ } else if (arguments.length === 3) { -+ return aDefaultValue; -+ } else { -+ throw new Error('"' + aName + '" is a required argument.'); -+ } -+ } -+ exports.getArg = getArg; -+ -+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; -+ var dataUrlRegexp = /^data:.+\,.+$/; -+ -+ function urlParse(aUrl) { -+ var match = aUrl.match(urlRegexp); -+ if (!match) { -+ return null; -+ } -+ return { -+ scheme: match[1], -+ auth: match[2], -+ host: match[3], -+ port: match[4], -+ path: match[5] -+ }; -+ } -+ exports.urlParse = urlParse; -+ -+ function urlGenerate(aParsedUrl) { -+ var url = ''; -+ if (aParsedUrl.scheme) { -+ url += aParsedUrl.scheme + ':'; -+ } -+ url += '//'; -+ if (aParsedUrl.auth) { -+ url += aParsedUrl.auth + '@'; -+ } -+ if (aParsedUrl.host) { -+ url += aParsedUrl.host; -+ } -+ if (aParsedUrl.port) { -+ url += ":" + aParsedUrl.port -+ } -+ if (aParsedUrl.path) { -+ url += aParsedUrl.path; -+ } -+ return url; -+ } -+ exports.urlGenerate = urlGenerate; -+ -+ /** -+ * Normalizes a path, or the path portion of a URL: -+ * -+ * - Replaces consequtive slashes with one slash. -+ * - Removes unnecessary '.' parts. -+ * - Removes unnecessary '/..' parts. -+ * -+ * Based on code in the Node.js 'path' core module. -+ * -+ * @param aPath The path or url to normalize. -+ */ -+ function normalize(aPath) { -+ var path = aPath; -+ var url = urlParse(aPath); -+ if (url) { -+ if (!url.path) { -+ return aPath; -+ } -+ path = url.path; -+ } -+ var isAbsolute = exports.isAbsolute(path); -+ -+ var parts = path.split(/\/+/); -+ for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { -+ part = parts[i]; -+ if (part === '.') { -+ parts.splice(i, 1); -+ } else if (part === '..') { -+ up++; -+ } else if (up > 0) { -+ if (part === '') { -+ // The first part is blank if the path is absolute. Trying to go -+ // above the root is a no-op. Therefore we can remove all '..' parts -+ // directly after the root. -+ parts.splice(i + 1, up); -+ up = 0; -+ } else { -+ parts.splice(i, 2); -+ up--; -+ } -+ } -+ } -+ path = parts.join('/'); -+ -+ if (path === '') { -+ path = isAbsolute ? '/' : '.'; -+ } -+ -+ if (url) { -+ url.path = path; -+ return urlGenerate(url); -+ } -+ return path; -+ } -+ exports.normalize = normalize; -+ -+ /** -+ * Joins two paths/URLs. -+ * -+ * @param aRoot The root path or URL. -+ * @param aPath The path or URL to be joined with the root. -+ * -+ * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a -+ * scheme-relative URL: Then the scheme of aRoot, if any, is prepended -+ * first. -+ * - Otherwise aPath is a path. If aRoot is a URL, then its path portion -+ * is updated with the result and aRoot is returned. Otherwise the result -+ * is returned. -+ * - If aPath is absolute, the result is aPath. -+ * - Otherwise the two paths are joined with a slash. -+ * - Joining for example 'http://' and 'www.example.com' is also supported. -+ */ -+ function join(aRoot, aPath) { -+ if (aRoot === "") { -+ aRoot = "."; -+ } -+ if (aPath === "") { -+ aPath = "."; -+ } -+ var aPathUrl = urlParse(aPath); -+ var aRootUrl = urlParse(aRoot); -+ if (aRootUrl) { -+ aRoot = aRootUrl.path || '/'; -+ } -+ -+ // `join(foo, '//www.example.org')` -+ if (aPathUrl && !aPathUrl.scheme) { -+ if (aRootUrl) { -+ aPathUrl.scheme = aRootUrl.scheme; -+ } -+ return urlGenerate(aPathUrl); -+ } -+ -+ if (aPathUrl || aPath.match(dataUrlRegexp)) { -+ return aPath; -+ } -+ -+ // `join('http://', 'www.example.com')` -+ if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { -+ aRootUrl.host = aPath; -+ return urlGenerate(aRootUrl); -+ } -+ -+ var joined = aPath.charAt(0) === '/' -+ ? aPath -+ : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); -+ -+ if (aRootUrl) { -+ aRootUrl.path = joined; -+ return urlGenerate(aRootUrl); -+ } -+ return joined; -+ } -+ exports.join = join; -+ -+ exports.isAbsolute = function (aPath) { -+ return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); -+ }; -+ -+ /** -+ * Make a path relative to a URL or another path. -+ * -+ * @param aRoot The root path or URL. -+ * @param aPath The path or URL to be made relative to aRoot. -+ */ -+ function relative(aRoot, aPath) { -+ if (aRoot === "") { -+ aRoot = "."; -+ } -+ -+ aRoot = aRoot.replace(/\/$/, ''); -+ -+ // It is possible for the path to be above the root. In this case, simply -+ // checking whether the root is a prefix of the path won't work. Instead, we -+ // need to remove components from the root one by one, until either we find -+ // a prefix that fits, or we run out of components to remove. -+ var level = 0; -+ while (aPath.indexOf(aRoot + '/') !== 0) { -+ var index = aRoot.lastIndexOf("/"); -+ if (index < 0) { -+ return aPath; -+ } -+ -+ // If the only part of the root that is left is the scheme (i.e. http://, -+ // file:///, etc.), one or more slashes (/), or simply nothing at all, we -+ // have exhausted all components, so the path is not relative to the root. -+ aRoot = aRoot.slice(0, index); -+ if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { -+ return aPath; -+ } -+ -+ ++level; -+ } -+ -+ // Make sure we add a "../" for each component we removed from the root. -+ return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); -+ } -+ exports.relative = relative; -+ -+ /** -+ * Because behavior goes wacky when you set `__proto__` on objects, we -+ * have to prefix all the strings in our set with an arbitrary character. -+ * -+ * See https://github.com/mozilla/source-map/pull/31 and -+ * https://github.com/mozilla/source-map/issues/30 -+ * -+ * @param String aStr -+ */ -+ function toSetString(aStr) { -+ return '$' + aStr; -+ } -+ exports.toSetString = toSetString; -+ -+ function fromSetString(aStr) { -+ return aStr.substr(1); -+ } -+ exports.fromSetString = fromSetString; -+ -+ /** -+ * Comparator between two mappings where the original positions are compared. -+ * -+ * Optionally pass in `true` as `onlyCompareGenerated` to consider two -+ * mappings with the same original source/line/column, but different generated -+ * line and column the same. Useful when searching for a mapping with a -+ * stubbed out mapping. -+ */ -+ function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { -+ var cmp = mappingA.source - mappingB.source; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.originalLine - mappingB.originalLine; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.originalColumn - mappingB.originalColumn; -+ if (cmp !== 0 || onlyCompareOriginal) { -+ return cmp; -+ } -+ -+ cmp = mappingA.generatedColumn - mappingB.generatedColumn; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.generatedLine - mappingB.generatedLine; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ return mappingA.name - mappingB.name; -+ } -+ exports.compareByOriginalPositions = compareByOriginalPositions; -+ -+ /** -+ * Comparator between two mappings with deflated source and name indices where -+ * the generated positions are compared. -+ * -+ * Optionally pass in `true` as `onlyCompareGenerated` to consider two -+ * mappings with the same generated line and column, but different -+ * source/name/original line and column the same. Useful when searching for a -+ * mapping with a stubbed out mapping. -+ */ -+ function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { -+ var cmp = mappingA.generatedLine - mappingB.generatedLine; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.generatedColumn - mappingB.generatedColumn; -+ if (cmp !== 0 || onlyCompareGenerated) { -+ return cmp; -+ } -+ -+ cmp = mappingA.source - mappingB.source; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.originalLine - mappingB.originalLine; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.originalColumn - mappingB.originalColumn; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ return mappingA.name - mappingB.name; -+ } -+ exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; -+ -+ function strcmp(aStr1, aStr2) { -+ if (aStr1 === aStr2) { -+ return 0; -+ } -+ -+ if (aStr1 > aStr2) { -+ return 1; -+ } -+ -+ return -1; -+ } -+ -+ /** -+ * Comparator between two mappings with inflated source and name strings where -+ * the generated positions are compared. -+ */ -+ function compareByGeneratedPositionsInflated(mappingA, mappingB) { -+ var cmp = mappingA.generatedLine - mappingB.generatedLine; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.generatedColumn - mappingB.generatedColumn; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = strcmp(mappingA.source, mappingB.source); -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.originalLine - mappingB.originalLine; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ cmp = mappingA.originalColumn - mappingB.originalColumn; -+ if (cmp !== 0) { -+ return cmp; -+ } -+ -+ return strcmp(mappingA.name, mappingB.name); -+ } -+ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; -+ } -+ -+ -+/***/ }, -+/* 5 */ -+/***/ function(module, exports, __webpack_require__) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ var util = __webpack_require__(4); -+ -+ /** -+ * A data structure which is a combination of an array and a set. Adding a new -+ * member is O(1), testing for membership is O(1), and finding the index of an -+ * element is O(1). Removing elements from the set is not supported. Only -+ * strings are supported for membership. -+ */ -+ function ArraySet() { -+ this._array = []; -+ this._set = {}; -+ } -+ -+ /** -+ * Static method for creating ArraySet instances from an existing array. -+ */ -+ ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { -+ var set = new ArraySet(); -+ for (var i = 0, len = aArray.length; i < len; i++) { -+ set.add(aArray[i], aAllowDuplicates); -+ } -+ return set; -+ }; -+ -+ /** -+ * Return how many unique items are in this ArraySet. If duplicates have been -+ * added, than those do not count towards the size. -+ * -+ * @returns Number -+ */ -+ ArraySet.prototype.size = function ArraySet_size() { -+ return Object.getOwnPropertyNames(this._set).length; -+ }; -+ -+ /** -+ * Add the given string to this set. -+ * -+ * @param String aStr -+ */ -+ ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { -+ var sStr = util.toSetString(aStr); -+ var isDuplicate = this._set.hasOwnProperty(sStr); -+ var idx = this._array.length; -+ if (!isDuplicate || aAllowDuplicates) { -+ this._array.push(aStr); -+ } -+ if (!isDuplicate) { -+ this._set[sStr] = idx; -+ } -+ }; -+ -+ /** -+ * Is the given string a member of this set? -+ * -+ * @param String aStr -+ */ -+ ArraySet.prototype.has = function ArraySet_has(aStr) { -+ var sStr = util.toSetString(aStr); -+ return this._set.hasOwnProperty(sStr); -+ }; -+ -+ /** -+ * What is the index of the given string in the array? -+ * -+ * @param String aStr -+ */ -+ ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { -+ var sStr = util.toSetString(aStr); -+ if (this._set.hasOwnProperty(sStr)) { -+ return this._set[sStr]; -+ } -+ throw new Error('"' + aStr + '" is not in the set.'); -+ }; -+ -+ /** -+ * What is the element at the given index? -+ * -+ * @param Number aIdx -+ */ -+ ArraySet.prototype.at = function ArraySet_at(aIdx) { -+ if (aIdx >= 0 && aIdx < this._array.length) { -+ return this._array[aIdx]; -+ } -+ throw new Error('No element indexed by ' + aIdx); -+ }; -+ -+ /** -+ * Returns the array representation of this set (which has the proper indices -+ * indicated by indexOf). Note that this is a copy of the internal array used -+ * for storing the members so that no one can mess with internal state. -+ */ -+ ArraySet.prototype.toArray = function ArraySet_toArray() { -+ return this._array.slice(); -+ }; -+ -+ exports.ArraySet = ArraySet; -+ } -+ -+ -+/***/ }, -+/* 6 */ -+/***/ function(module, exports, __webpack_require__) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2014 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ var util = __webpack_require__(4); -+ -+ /** -+ * Determine whether mappingB is after mappingA with respect to generated -+ * position. -+ */ -+ function generatedPositionAfter(mappingA, mappingB) { -+ // Optimized for most common case -+ var lineA = mappingA.generatedLine; -+ var lineB = mappingB.generatedLine; -+ var columnA = mappingA.generatedColumn; -+ var columnB = mappingB.generatedColumn; -+ return lineB > lineA || lineB == lineA && columnB >= columnA || -+ util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; -+ } -+ -+ /** -+ * A data structure to provide a sorted view of accumulated mappings in a -+ * performance conscious manner. It trades a neglibable overhead in general -+ * case for a large speedup in case of mappings being added in order. -+ */ -+ function MappingList() { -+ this._array = []; -+ this._sorted = true; -+ // Serves as infimum -+ this._last = {generatedLine: -1, generatedColumn: 0}; -+ } -+ -+ /** -+ * Iterate through internal items. This method takes the same arguments that -+ * `Array.prototype.forEach` takes. -+ * -+ * NOTE: The order of the mappings is NOT guaranteed. -+ */ -+ MappingList.prototype.unsortedForEach = -+ function MappingList_forEach(aCallback, aThisArg) { -+ this._array.forEach(aCallback, aThisArg); -+ }; -+ -+ /** -+ * Add the given source mapping. -+ * -+ * @param Object aMapping -+ */ -+ MappingList.prototype.add = function MappingList_add(aMapping) { -+ if (generatedPositionAfter(this._last, aMapping)) { -+ this._last = aMapping; -+ this._array.push(aMapping); -+ } else { -+ this._sorted = false; -+ this._array.push(aMapping); -+ } -+ }; -+ -+ /** -+ * Returns the flat, sorted array of mappings. The mappings are sorted by -+ * generated position. -+ * -+ * WARNING: This method returns internal data without copying, for -+ * performance. The return value must NOT be mutated, and should be treated as -+ * an immutable borrow. If you want to take ownership, you must make your own -+ * copy. -+ */ -+ MappingList.prototype.toArray = function MappingList_toArray() { -+ if (!this._sorted) { -+ this._array.sort(util.compareByGeneratedPositionsInflated); -+ this._sorted = true; -+ } -+ return this._array; -+ }; -+ -+ exports.MappingList = MappingList; -+ } -+ -+ -+/***/ }, -+/* 7 */ -+/***/ function(module, exports, __webpack_require__) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ var util = __webpack_require__(4); -+ var binarySearch = __webpack_require__(8); -+ var ArraySet = __webpack_require__(5).ArraySet; -+ var base64VLQ = __webpack_require__(2); -+ var quickSort = __webpack_require__(9).quickSort; -+ -+ function SourceMapConsumer(aSourceMap) { -+ var sourceMap = aSourceMap; -+ if (typeof aSourceMap === 'string') { -+ sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); -+ } -+ -+ return sourceMap.sections != null -+ ? new IndexedSourceMapConsumer(sourceMap) -+ : new BasicSourceMapConsumer(sourceMap); -+ } -+ -+ SourceMapConsumer.fromSourceMap = function(aSourceMap) { -+ return BasicSourceMapConsumer.fromSourceMap(aSourceMap); -+ } -+ -+ /** -+ * The version of the source mapping spec that we are consuming. -+ */ -+ SourceMapConsumer.prototype._version = 3; -+ -+ // `__generatedMappings` and `__originalMappings` are arrays that hold the -+ // parsed mapping coordinates from the source map's "mappings" attribute. They -+ // are lazily instantiated, accessed via the `_generatedMappings` and -+ // `_originalMappings` getters respectively, and we only parse the mappings -+ // and create these arrays once queried for a source location. We jump through -+ // these hoops because there can be many thousands of mappings, and parsing -+ // them is expensive, so we only want to do it if we must. -+ // -+ // Each object in the arrays is of the form: -+ // -+ // { -+ // generatedLine: The line number in the generated code, -+ // generatedColumn: The column number in the generated code, -+ // source: The path to the original source file that generated this -+ // chunk of code, -+ // originalLine: The line number in the original source that -+ // corresponds to this chunk of generated code, -+ // originalColumn: The column number in the original source that -+ // corresponds to this chunk of generated code, -+ // name: The name of the original symbol which generated this chunk of -+ // code. -+ // } -+ // -+ // All properties except for `generatedLine` and `generatedColumn` can be -+ // `null`. -+ // -+ // `_generatedMappings` is ordered by the generated positions. -+ // -+ // `_originalMappings` is ordered by the original positions. -+ -+ SourceMapConsumer.prototype.__generatedMappings = null; -+ Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { -+ get: function () { -+ if (!this.__generatedMappings) { -+ this._parseMappings(this._mappings, this.sourceRoot); -+ } -+ -+ return this.__generatedMappings; -+ } -+ }); -+ -+ SourceMapConsumer.prototype.__originalMappings = null; -+ Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { -+ get: function () { -+ if (!this.__originalMappings) { -+ this._parseMappings(this._mappings, this.sourceRoot); -+ } -+ -+ return this.__originalMappings; -+ } -+ }); -+ -+ SourceMapConsumer.prototype._charIsMappingSeparator = -+ function SourceMapConsumer_charIsMappingSeparator(aStr, index) { -+ var c = aStr.charAt(index); -+ return c === ";" || c === ","; -+ }; -+ -+ /** -+ * Parse the mappings in a string in to a data structure which we can easily -+ * query (the ordered arrays in the `this.__generatedMappings` and -+ * `this.__originalMappings` properties). -+ */ -+ SourceMapConsumer.prototype._parseMappings = -+ function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { -+ throw new Error("Subclasses must implement _parseMappings"); -+ }; -+ -+ SourceMapConsumer.GENERATED_ORDER = 1; -+ SourceMapConsumer.ORIGINAL_ORDER = 2; -+ -+ SourceMapConsumer.GREATEST_LOWER_BOUND = 1; -+ SourceMapConsumer.LEAST_UPPER_BOUND = 2; -+ -+ /** -+ * Iterate over each mapping between an original source/line/column and a -+ * generated line/column in this source map. -+ * -+ * @param Function aCallback -+ * The function that is called with each mapping. -+ * @param Object aContext -+ * Optional. If specified, this object will be the value of `this` every -+ * time that `aCallback` is called. -+ * @param aOrder -+ * Either `SourceMapConsumer.GENERATED_ORDER` or -+ * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to -+ * iterate over the mappings sorted by the generated file's line/column -+ * order or the original's source/line/column order, respectively. Defaults to -+ * `SourceMapConsumer.GENERATED_ORDER`. -+ */ -+ SourceMapConsumer.prototype.eachMapping = -+ function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { -+ var context = aContext || null; -+ var order = aOrder || SourceMapConsumer.GENERATED_ORDER; -+ -+ var mappings; -+ switch (order) { -+ case SourceMapConsumer.GENERATED_ORDER: -+ mappings = this._generatedMappings; -+ break; -+ case SourceMapConsumer.ORIGINAL_ORDER: -+ mappings = this._originalMappings; -+ break; -+ default: -+ throw new Error("Unknown order of iteration."); -+ } -+ -+ var sourceRoot = this.sourceRoot; -+ mappings.map(function (mapping) { -+ var source = mapping.source === null ? null : this._sources.at(mapping.source); -+ if (source != null && sourceRoot != null) { -+ source = util.join(sourceRoot, source); -+ } -+ return { -+ source: source, -+ generatedLine: mapping.generatedLine, -+ generatedColumn: mapping.generatedColumn, -+ originalLine: mapping.originalLine, -+ originalColumn: mapping.originalColumn, -+ name: mapping.name === null ? null : this._names.at(mapping.name) -+ }; -+ }, this).forEach(aCallback, context); -+ }; -+ -+ /** -+ * Returns all generated line and column information for the original source, -+ * line, and column provided. If no column is provided, returns all mappings -+ * corresponding to a either the line we are searching for or the next -+ * closest line that has any mappings. Otherwise, returns all mappings -+ * corresponding to the given line and either the column we are searching for -+ * or the next closest column that has any offsets. -+ * -+ * The only argument is an object with the following properties: -+ * -+ * - source: The filename of the original source. -+ * - line: The line number in the original source. -+ * - column: Optional. the column number in the original source. -+ * -+ * and an array of objects is returned, each with the following properties: -+ * -+ * - line: The line number in the generated source, or null. -+ * - column: The column number in the generated source, or null. -+ */ -+ SourceMapConsumer.prototype.allGeneratedPositionsFor = -+ function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { -+ var line = util.getArg(aArgs, 'line'); -+ -+ // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping -+ // returns the index of the closest mapping less than the needle. By -+ // setting needle.originalColumn to 0, we thus find the last mapping for -+ // the given line, provided such a mapping exists. -+ var needle = { -+ source: util.getArg(aArgs, 'source'), -+ originalLine: line, -+ originalColumn: util.getArg(aArgs, 'column', 0) -+ }; -+ -+ if (this.sourceRoot != null) { -+ needle.source = util.relative(this.sourceRoot, needle.source); -+ } -+ if (!this._sources.has(needle.source)) { -+ return []; -+ } -+ needle.source = this._sources.indexOf(needle.source); -+ -+ var mappings = []; -+ -+ var index = this._findMapping(needle, -+ this._originalMappings, -+ "originalLine", -+ "originalColumn", -+ util.compareByOriginalPositions, -+ binarySearch.LEAST_UPPER_BOUND); -+ if (index >= 0) { -+ var mapping = this._originalMappings[index]; -+ -+ if (aArgs.column === undefined) { -+ var originalLine = mapping.originalLine; -+ -+ // Iterate until either we run out of mappings, or we run into -+ // a mapping for a different line than the one we found. Since -+ // mappings are sorted, this is guaranteed to find all mappings for -+ // the line we found. -+ while (mapping && mapping.originalLine === originalLine) { -+ mappings.push({ -+ line: util.getArg(mapping, 'generatedLine', null), -+ column: util.getArg(mapping, 'generatedColumn', null), -+ lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) -+ }); -+ -+ mapping = this._originalMappings[++index]; -+ } -+ } else { -+ var originalColumn = mapping.originalColumn; -+ -+ // Iterate until either we run out of mappings, or we run into -+ // a mapping for a different line than the one we were searching for. -+ // Since mappings are sorted, this is guaranteed to find all mappings for -+ // the line we are searching for. -+ while (mapping && -+ mapping.originalLine === line && -+ mapping.originalColumn == originalColumn) { -+ mappings.push({ -+ line: util.getArg(mapping, 'generatedLine', null), -+ column: util.getArg(mapping, 'generatedColumn', null), -+ lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) -+ }); -+ -+ mapping = this._originalMappings[++index]; -+ } -+ } -+ } -+ -+ return mappings; -+ }; -+ -+ exports.SourceMapConsumer = SourceMapConsumer; -+ -+ /** -+ * A BasicSourceMapConsumer instance represents a parsed source map which we can -+ * query for information about the original file positions by giving it a file -+ * position in the generated source. -+ * -+ * The only parameter is the raw source map (either as a JSON string, or -+ * already parsed to an object). According to the spec, source maps have the -+ * following attributes: -+ * -+ * - version: Which version of the source map spec this map is following. -+ * - sources: An array of URLs to the original source files. -+ * - names: An array of identifiers which can be referrenced by individual mappings. -+ * - sourceRoot: Optional. The URL root from which all sources are relative. -+ * - sourcesContent: Optional. An array of contents of the original source files. -+ * - mappings: A string of base64 VLQs which contain the actual mappings. -+ * - file: Optional. The generated file this source map is associated with. -+ * -+ * Here is an example source map, taken from the source map spec[0]: -+ * -+ * { -+ * version : 3, -+ * file: "out.js", -+ * sourceRoot : "", -+ * sources: ["foo.js", "bar.js"], -+ * names: ["src", "maps", "are", "fun"], -+ * mappings: "AA,AB;;ABCDE;" -+ * } -+ * -+ * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# -+ */ -+ function BasicSourceMapConsumer(aSourceMap) { -+ var sourceMap = aSourceMap; -+ if (typeof aSourceMap === 'string') { -+ sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); -+ } -+ -+ var version = util.getArg(sourceMap, 'version'); -+ var sources = util.getArg(sourceMap, 'sources'); -+ // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which -+ // requires the array) to play nice here. -+ var names = util.getArg(sourceMap, 'names', []); -+ var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); -+ var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); -+ var mappings = util.getArg(sourceMap, 'mappings'); -+ var file = util.getArg(sourceMap, 'file', null); -+ -+ // Once again, Sass deviates from the spec and supplies the version as a -+ // string rather than a number, so we use loose equality checking here. -+ if (version != this._version) { -+ throw new Error('Unsupported version: ' + version); -+ } -+ -+ sources = sources -+ // Some source maps produce relative source paths like "./foo.js" instead of -+ // "foo.js". Normalize these first so that future comparisons will succeed. -+ // See bugzil.la/1090768. -+ .map(util.normalize) -+ // Always ensure that absolute sources are internally stored relative to -+ // the source root, if the source root is absolute. Not doing this would -+ // be particularly problematic when the source root is a prefix of the -+ // source (valid, but why??). See github issue #199 and bugzil.la/1188982. -+ .map(function (source) { -+ return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) -+ ? util.relative(sourceRoot, source) -+ : source; -+ }); -+ -+ // Pass `true` below to allow duplicate names and sources. While source maps -+ // are intended to be compressed and deduplicated, the TypeScript compiler -+ // sometimes generates source maps with duplicates in them. See Github issue -+ // #72 and bugzil.la/889492. -+ this._names = ArraySet.fromArray(names, true); -+ this._sources = ArraySet.fromArray(sources, true); -+ -+ this.sourceRoot = sourceRoot; -+ this.sourcesContent = sourcesContent; -+ this._mappings = mappings; -+ this.file = file; -+ } -+ -+ BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -+ BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; -+ -+ /** -+ * Create a BasicSourceMapConsumer from a SourceMapGenerator. -+ * -+ * @param SourceMapGenerator aSourceMap -+ * The source map that will be consumed. -+ * @returns BasicSourceMapConsumer -+ */ -+ BasicSourceMapConsumer.fromSourceMap = -+ function SourceMapConsumer_fromSourceMap(aSourceMap) { -+ var smc = Object.create(BasicSourceMapConsumer.prototype); -+ -+ var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); -+ var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); -+ smc.sourceRoot = aSourceMap._sourceRoot; -+ smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), -+ smc.sourceRoot); -+ smc.file = aSourceMap._file; -+ -+ // Because we are modifying the entries (by converting string sources and -+ // names to indices into the sources and names ArraySets), we have to make -+ // a copy of the entry or else bad things happen. Shared mutable state -+ // strikes again! See github issue #191. -+ -+ var generatedMappings = aSourceMap._mappings.toArray().slice(); -+ var destGeneratedMappings = smc.__generatedMappings = []; -+ var destOriginalMappings = smc.__originalMappings = []; -+ -+ for (var i = 0, length = generatedMappings.length; i < length; i++) { -+ var srcMapping = generatedMappings[i]; -+ var destMapping = new Mapping; -+ destMapping.generatedLine = srcMapping.generatedLine; -+ destMapping.generatedColumn = srcMapping.generatedColumn; -+ -+ if (srcMapping.source) { -+ destMapping.source = sources.indexOf(srcMapping.source); -+ destMapping.originalLine = srcMapping.originalLine; -+ destMapping.originalColumn = srcMapping.originalColumn; -+ -+ if (srcMapping.name) { -+ destMapping.name = names.indexOf(srcMapping.name); -+ } -+ -+ destOriginalMappings.push(destMapping); -+ } -+ -+ destGeneratedMappings.push(destMapping); -+ } -+ -+ quickSort(smc.__originalMappings, util.compareByOriginalPositions); -+ -+ return smc; -+ }; -+ -+ /** -+ * The version of the source mapping spec that we are consuming. -+ */ -+ BasicSourceMapConsumer.prototype._version = 3; -+ -+ /** -+ * The list of original sources. -+ */ -+ Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { -+ get: function () { -+ return this._sources.toArray().map(function (s) { -+ return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; -+ }, this); -+ } -+ }); -+ -+ /** -+ * Provide the JIT with a nice shape / hidden class. -+ */ -+ function Mapping() { -+ this.generatedLine = 0; -+ this.generatedColumn = 0; -+ this.source = null; -+ this.originalLine = null; -+ this.originalColumn = null; -+ this.name = null; -+ } -+ -+ /** -+ * Parse the mappings in a string in to a data structure which we can easily -+ * query (the ordered arrays in the `this.__generatedMappings` and -+ * `this.__originalMappings` properties). -+ */ -+ BasicSourceMapConsumer.prototype._parseMappings = -+ function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { -+ var generatedLine = 1; -+ var previousGeneratedColumn = 0; -+ var previousOriginalLine = 0; -+ var previousOriginalColumn = 0; -+ var previousSource = 0; -+ var previousName = 0; -+ var length = aStr.length; -+ var index = 0; -+ var cachedSegments = {}; -+ var temp = {}; -+ var originalMappings = []; -+ var generatedMappings = []; -+ var mapping, str, segment, end, value; -+ -+ while (index < length) { -+ if (aStr.charAt(index) === ';') { -+ generatedLine++; -+ index++; -+ previousGeneratedColumn = 0; -+ } -+ else if (aStr.charAt(index) === ',') { -+ index++; -+ } -+ else { -+ mapping = new Mapping(); -+ mapping.generatedLine = generatedLine; -+ -+ // Because each offset is encoded relative to the previous one, -+ // many segments often have the same encoding. We can exploit this -+ // fact by caching the parsed variable length fields of each segment, -+ // allowing us to avoid a second parse if we encounter the same -+ // segment again. -+ for (end = index; end < length; end++) { -+ if (this._charIsMappingSeparator(aStr, end)) { -+ break; -+ } -+ } -+ str = aStr.slice(index, end); -+ -+ segment = cachedSegments[str]; -+ if (segment) { -+ index += str.length; -+ } else { -+ segment = []; -+ while (index < end) { -+ base64VLQ.decode(aStr, index, temp); -+ value = temp.value; -+ index = temp.rest; -+ segment.push(value); -+ } -+ -+ if (segment.length === 2) { -+ throw new Error('Found a source, but no line and column'); -+ } -+ -+ if (segment.length === 3) { -+ throw new Error('Found a source and line, but no column'); -+ } -+ -+ cachedSegments[str] = segment; -+ } -+ -+ // Generated column. -+ mapping.generatedColumn = previousGeneratedColumn + segment[0]; -+ previousGeneratedColumn = mapping.generatedColumn; -+ -+ if (segment.length > 1) { -+ // Original source. -+ mapping.source = previousSource + segment[1]; -+ previousSource += segment[1]; -+ -+ // Original line. -+ mapping.originalLine = previousOriginalLine + segment[2]; -+ previousOriginalLine = mapping.originalLine; -+ // Lines are stored 0-based -+ mapping.originalLine += 1; -+ -+ // Original column. -+ mapping.originalColumn = previousOriginalColumn + segment[3]; -+ previousOriginalColumn = mapping.originalColumn; -+ -+ if (segment.length > 4) { -+ // Original name. -+ mapping.name = previousName + segment[4]; -+ previousName += segment[4]; -+ } -+ } -+ -+ generatedMappings.push(mapping); -+ if (typeof mapping.originalLine === 'number') { -+ originalMappings.push(mapping); -+ } -+ } -+ } -+ -+ quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); -+ this.__generatedMappings = generatedMappings; -+ -+ quickSort(originalMappings, util.compareByOriginalPositions); -+ this.__originalMappings = originalMappings; -+ }; -+ -+ /** -+ * Find the mapping that best matches the hypothetical "needle" mapping that -+ * we are searching for in the given "haystack" of mappings. -+ */ -+ BasicSourceMapConsumer.prototype._findMapping = -+ function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, -+ aColumnName, aComparator, aBias) { -+ // To return the position we are searching for, we must first find the -+ // mapping for the given position and then return the opposite position it -+ // points to. Because the mappings are sorted, we can use binary search to -+ // find the best mapping. -+ -+ if (aNeedle[aLineName] <= 0) { -+ throw new TypeError('Line must be greater than or equal to 1, got ' -+ + aNeedle[aLineName]); -+ } -+ if (aNeedle[aColumnName] < 0) { -+ throw new TypeError('Column must be greater than or equal to 0, got ' -+ + aNeedle[aColumnName]); -+ } -+ -+ return binarySearch.search(aNeedle, aMappings, aComparator, aBias); -+ }; -+ -+ /** -+ * Compute the last column for each generated mapping. The last column is -+ * inclusive. -+ */ -+ BasicSourceMapConsumer.prototype.computeColumnSpans = -+ function SourceMapConsumer_computeColumnSpans() { -+ for (var index = 0; index < this._generatedMappings.length; ++index) { -+ var mapping = this._generatedMappings[index]; -+ -+ // Mappings do not contain a field for the last generated columnt. We -+ // can come up with an optimistic estimate, however, by assuming that -+ // mappings are contiguous (i.e. given two consecutive mappings, the -+ // first mapping ends where the second one starts). -+ if (index + 1 < this._generatedMappings.length) { -+ var nextMapping = this._generatedMappings[index + 1]; -+ -+ if (mapping.generatedLine === nextMapping.generatedLine) { -+ mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; -+ continue; -+ } -+ } -+ -+ // The last mapping for each line spans the entire line. -+ mapping.lastGeneratedColumn = Infinity; -+ } -+ }; -+ -+ /** -+ * Returns the original source, line, and column information for the generated -+ * source's line and column positions provided. The only argument is an object -+ * with the following properties: -+ * -+ * - line: The line number in the generated source. -+ * - column: The column number in the generated source. -+ * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or -+ * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the -+ * closest element that is smaller than or greater than the one we are -+ * searching for, respectively, if the exact element cannot be found. -+ * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. -+ * -+ * and an object is returned with the following properties: -+ * -+ * - source: The original source file, or null. -+ * - line: The line number in the original source, or null. -+ * - column: The column number in the original source, or null. -+ * - name: The original identifier, or null. -+ */ -+ BasicSourceMapConsumer.prototype.originalPositionFor = -+ function SourceMapConsumer_originalPositionFor(aArgs) { -+ var needle = { -+ generatedLine: util.getArg(aArgs, 'line'), -+ generatedColumn: util.getArg(aArgs, 'column') -+ }; -+ -+ var index = this._findMapping( -+ needle, -+ this._generatedMappings, -+ "generatedLine", -+ "generatedColumn", -+ util.compareByGeneratedPositionsDeflated, -+ util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) -+ ); -+ -+ if (index >= 0) { -+ var mapping = this._generatedMappings[index]; -+ -+ if (mapping.generatedLine === needle.generatedLine) { -+ var source = util.getArg(mapping, 'source', null); -+ if (source !== null) { -+ source = this._sources.at(source); -+ if (this.sourceRoot != null) { -+ source = util.join(this.sourceRoot, source); -+ } -+ } -+ var name = util.getArg(mapping, 'name', null); -+ if (name !== null) { -+ name = this._names.at(name); -+ } -+ return { -+ source: source, -+ line: util.getArg(mapping, 'originalLine', null), -+ column: util.getArg(mapping, 'originalColumn', null), -+ name: name -+ }; -+ } -+ } -+ -+ return { -+ source: null, -+ line: null, -+ column: null, -+ name: null -+ }; -+ }; -+ -+ /** -+ * Return true if we have the source content for every source in the source -+ * map, false otherwise. -+ */ -+ BasicSourceMapConsumer.prototype.hasContentsOfAllSources = -+ function BasicSourceMapConsumer_hasContentsOfAllSources() { -+ if (!this.sourcesContent) { -+ return false; -+ } -+ return this.sourcesContent.length >= this._sources.size() && -+ !this.sourcesContent.some(function (sc) { return sc == null; }); -+ }; -+ -+ /** -+ * Returns the original source content. The only argument is the url of the -+ * original source file. Returns null if no original source content is -+ * available. -+ */ -+ BasicSourceMapConsumer.prototype.sourceContentFor = -+ function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { -+ if (!this.sourcesContent) { -+ return null; -+ } -+ -+ if (this.sourceRoot != null) { -+ aSource = util.relative(this.sourceRoot, aSource); -+ } -+ -+ if (this._sources.has(aSource)) { -+ return this.sourcesContent[this._sources.indexOf(aSource)]; -+ } -+ -+ var url; -+ if (this.sourceRoot != null -+ && (url = util.urlParse(this.sourceRoot))) { -+ // XXX: file:// URIs and absolute paths lead to unexpected behavior for -+ // many users. We can help them out when they expect file:// URIs to -+ // behave like it would if they were running a local HTTP server. See -+ // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. -+ var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); -+ if (url.scheme == "file" -+ && this._sources.has(fileUriAbsPath)) { -+ return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] -+ } -+ -+ if ((!url.path || url.path == "/") -+ && this._sources.has("/" + aSource)) { -+ return this.sourcesContent[this._sources.indexOf("/" + aSource)]; -+ } -+ } -+ -+ // This function is used recursively from -+ // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we -+ // don't want to throw if we can't find the source - we just want to -+ // return null, so we provide a flag to exit gracefully. -+ if (nullOnMissing) { -+ return null; -+ } -+ else { -+ throw new Error('"' + aSource + '" is not in the SourceMap.'); -+ } -+ }; -+ -+ /** -+ * Returns the generated line and column information for the original source, -+ * line, and column positions provided. The only argument is an object with -+ * the following properties: -+ * -+ * - source: The filename of the original source. -+ * - line: The line number in the original source. -+ * - column: The column number in the original source. -+ * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or -+ * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the -+ * closest element that is smaller than or greater than the one we are -+ * searching for, respectively, if the exact element cannot be found. -+ * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. -+ * -+ * and an object is returned with the following properties: -+ * -+ * - line: The line number in the generated source, or null. -+ * - column: The column number in the generated source, or null. -+ */ -+ BasicSourceMapConsumer.prototype.generatedPositionFor = -+ function SourceMapConsumer_generatedPositionFor(aArgs) { -+ var source = util.getArg(aArgs, 'source'); -+ if (this.sourceRoot != null) { -+ source = util.relative(this.sourceRoot, source); -+ } -+ if (!this._sources.has(source)) { -+ return { -+ line: null, -+ column: null, -+ lastColumn: null -+ }; -+ } -+ source = this._sources.indexOf(source); -+ -+ var needle = { -+ source: source, -+ originalLine: util.getArg(aArgs, 'line'), -+ originalColumn: util.getArg(aArgs, 'column') -+ }; -+ -+ var index = this._findMapping( -+ needle, -+ this._originalMappings, -+ "originalLine", -+ "originalColumn", -+ util.compareByOriginalPositions, -+ util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) -+ ); -+ -+ if (index >= 0) { -+ var mapping = this._originalMappings[index]; -+ -+ if (mapping.source === needle.source) { -+ return { -+ line: util.getArg(mapping, 'generatedLine', null), -+ column: util.getArg(mapping, 'generatedColumn', null), -+ lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) -+ }; -+ } -+ } -+ -+ return { -+ line: null, -+ column: null, -+ lastColumn: null -+ }; -+ }; -+ -+ exports.BasicSourceMapConsumer = BasicSourceMapConsumer; -+ -+ /** -+ * An IndexedSourceMapConsumer instance represents a parsed source map which -+ * we can query for information. It differs from BasicSourceMapConsumer in -+ * that it takes "indexed" source maps (i.e. ones with a "sections" field) as -+ * input. -+ * -+ * The only parameter is a raw source map (either as a JSON string, or already -+ * parsed to an object). According to the spec for indexed source maps, they -+ * have the following attributes: -+ * -+ * - version: Which version of the source map spec this map is following. -+ * - file: Optional. The generated file this source map is associated with. -+ * - sections: A list of section definitions. -+ * -+ * Each value under the "sections" field has two fields: -+ * - offset: The offset into the original specified at which this section -+ * begins to apply, defined as an object with a "line" and "column" -+ * field. -+ * - map: A source map definition. This source map could also be indexed, -+ * but doesn't have to be. -+ * -+ * Instead of the "map" field, it's also possible to have a "url" field -+ * specifying a URL to retrieve a source map from, but that's currently -+ * unsupported. -+ * -+ * Here's an example source map, taken from the source map spec[0], but -+ * modified to omit a section which uses the "url" field. -+ * -+ * { -+ * version : 3, -+ * file: "app.js", -+ * sections: [{ -+ * offset: {line:100, column:10}, -+ * map: { -+ * version : 3, -+ * file: "section.js", -+ * sources: ["foo.js", "bar.js"], -+ * names: ["src", "maps", "are", "fun"], -+ * mappings: "AAAA,E;;ABCDE;" -+ * } -+ * }], -+ * } -+ * -+ * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt -+ */ -+ function IndexedSourceMapConsumer(aSourceMap) { -+ var sourceMap = aSourceMap; -+ if (typeof aSourceMap === 'string') { -+ sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); -+ } -+ -+ var version = util.getArg(sourceMap, 'version'); -+ var sections = util.getArg(sourceMap, 'sections'); -+ -+ if (version != this._version) { -+ throw new Error('Unsupported version: ' + version); -+ } -+ -+ this._sources = new ArraySet(); -+ this._names = new ArraySet(); -+ -+ var lastOffset = { -+ line: -1, -+ column: 0 -+ }; -+ this._sections = sections.map(function (s) { -+ if (s.url) { -+ // The url field will require support for asynchronicity. -+ // See https://github.com/mozilla/source-map/issues/16 -+ throw new Error('Support for url field in sections not implemented.'); -+ } -+ var offset = util.getArg(s, 'offset'); -+ var offsetLine = util.getArg(offset, 'line'); -+ var offsetColumn = util.getArg(offset, 'column'); -+ -+ if (offsetLine < lastOffset.line || -+ (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { -+ throw new Error('Section offsets must be ordered and non-overlapping.'); -+ } -+ lastOffset = offset; -+ -+ return { -+ generatedOffset: { -+ // The offset fields are 0-based, but we use 1-based indices when -+ // encoding/decoding from VLQ. -+ generatedLine: offsetLine + 1, -+ generatedColumn: offsetColumn + 1 -+ }, -+ consumer: new SourceMapConsumer(util.getArg(s, 'map')) -+ } -+ }); -+ } -+ -+ IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -+ IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; -+ -+ /** -+ * The version of the source mapping spec that we are consuming. -+ */ -+ IndexedSourceMapConsumer.prototype._version = 3; -+ -+ /** -+ * The list of original sources. -+ */ -+ Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { -+ get: function () { -+ var sources = []; -+ for (var i = 0; i < this._sections.length; i++) { -+ for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { -+ sources.push(this._sections[i].consumer.sources[j]); -+ } -+ } -+ return sources; -+ } -+ }); -+ -+ /** -+ * Returns the original source, line, and column information for the generated -+ * source's line and column positions provided. The only argument is an object -+ * with the following properties: -+ * -+ * - line: The line number in the generated source. -+ * - column: The column number in the generated source. -+ * -+ * and an object is returned with the following properties: -+ * -+ * - source: The original source file, or null. -+ * - line: The line number in the original source, or null. -+ * - column: The column number in the original source, or null. -+ * - name: The original identifier, or null. -+ */ -+ IndexedSourceMapConsumer.prototype.originalPositionFor = -+ function IndexedSourceMapConsumer_originalPositionFor(aArgs) { -+ var needle = { -+ generatedLine: util.getArg(aArgs, 'line'), -+ generatedColumn: util.getArg(aArgs, 'column') -+ }; -+ -+ // Find the section containing the generated position we're trying to map -+ // to an original position. -+ var sectionIndex = binarySearch.search(needle, this._sections, -+ function(needle, section) { -+ var cmp = needle.generatedLine - section.generatedOffset.generatedLine; -+ if (cmp) { -+ return cmp; -+ } -+ -+ return (needle.generatedColumn - -+ section.generatedOffset.generatedColumn); -+ }); -+ var section = this._sections[sectionIndex]; -+ -+ if (!section) { -+ return { -+ source: null, -+ line: null, -+ column: null, -+ name: null -+ }; -+ } -+ -+ return section.consumer.originalPositionFor({ -+ line: needle.generatedLine - -+ (section.generatedOffset.generatedLine - 1), -+ column: needle.generatedColumn - -+ (section.generatedOffset.generatedLine === needle.generatedLine -+ ? section.generatedOffset.generatedColumn - 1 -+ : 0), -+ bias: aArgs.bias -+ }); -+ }; -+ -+ /** -+ * Return true if we have the source content for every source in the source -+ * map, false otherwise. -+ */ -+ IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = -+ function IndexedSourceMapConsumer_hasContentsOfAllSources() { -+ return this._sections.every(function (s) { -+ return s.consumer.hasContentsOfAllSources(); -+ }); -+ }; -+ -+ /** -+ * Returns the original source content. The only argument is the url of the -+ * original source file. Returns null if no original source content is -+ * available. -+ */ -+ IndexedSourceMapConsumer.prototype.sourceContentFor = -+ function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { -+ for (var i = 0; i < this._sections.length; i++) { -+ var section = this._sections[i]; -+ -+ var content = section.consumer.sourceContentFor(aSource, true); -+ if (content) { -+ return content; -+ } -+ } -+ if (nullOnMissing) { -+ return null; -+ } -+ else { -+ throw new Error('"' + aSource + '" is not in the SourceMap.'); -+ } -+ }; -+ -+ /** -+ * Returns the generated line and column information for the original source, -+ * line, and column positions provided. The only argument is an object with -+ * the following properties: -+ * -+ * - source: The filename of the original source. -+ * - line: The line number in the original source. -+ * - column: The column number in the original source. -+ * -+ * and an object is returned with the following properties: -+ * -+ * - line: The line number in the generated source, or null. -+ * - column: The column number in the generated source, or null. -+ */ -+ IndexedSourceMapConsumer.prototype.generatedPositionFor = -+ function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { -+ for (var i = 0; i < this._sections.length; i++) { -+ var section = this._sections[i]; -+ -+ // Only consider this section if the requested source is in the list of -+ // sources of the consumer. -+ if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { -+ continue; -+ } -+ var generatedPosition = section.consumer.generatedPositionFor(aArgs); -+ if (generatedPosition) { -+ var ret = { -+ line: generatedPosition.line + -+ (section.generatedOffset.generatedLine - 1), -+ column: generatedPosition.column + -+ (section.generatedOffset.generatedLine === generatedPosition.line -+ ? section.generatedOffset.generatedColumn - 1 -+ : 0) -+ }; -+ return ret; -+ } -+ } -+ -+ return { -+ line: null, -+ column: null -+ }; -+ }; -+ -+ /** -+ * Parse the mappings in a string in to a data structure which we can easily -+ * query (the ordered arrays in the `this.__generatedMappings` and -+ * `this.__originalMappings` properties). -+ */ -+ IndexedSourceMapConsumer.prototype._parseMappings = -+ function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { -+ this.__generatedMappings = []; -+ this.__originalMappings = []; -+ for (var i = 0; i < this._sections.length; i++) { -+ var section = this._sections[i]; -+ var sectionMappings = section.consumer._generatedMappings; -+ for (var j = 0; j < sectionMappings.length; j++) { -+ var mapping = sectionMappings[j]; -+ -+ var source = section.consumer._sources.at(mapping.source); -+ if (section.consumer.sourceRoot !== null) { -+ source = util.join(section.consumer.sourceRoot, source); -+ } -+ this._sources.add(source); -+ source = this._sources.indexOf(source); -+ -+ var name = section.consumer._names.at(mapping.name); -+ this._names.add(name); -+ name = this._names.indexOf(name); -+ -+ // The mappings coming from the consumer for the section have -+ // generated positions relative to the start of the section, so we -+ // need to offset them to be relative to the start of the concatenated -+ // generated file. -+ var adjustedMapping = { -+ source: source, -+ generatedLine: mapping.generatedLine + -+ (section.generatedOffset.generatedLine - 1), -+ generatedColumn: mapping.generatedColumn + -+ (section.generatedOffset.generatedLine === mapping.generatedLine -+ ? section.generatedOffset.generatedColumn - 1 -+ : 0), -+ originalLine: mapping.originalLine, -+ originalColumn: mapping.originalColumn, -+ name: name -+ }; -+ -+ this.__generatedMappings.push(adjustedMapping); -+ if (typeof adjustedMapping.originalLine === 'number') { -+ this.__originalMappings.push(adjustedMapping); -+ } -+ } -+ } -+ -+ quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); -+ quickSort(this.__originalMappings, util.compareByOriginalPositions); -+ }; -+ -+ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; -+ } -+ -+ -+/***/ }, -+/* 8 */ -+/***/ function(module, exports) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ exports.GREATEST_LOWER_BOUND = 1; -+ exports.LEAST_UPPER_BOUND = 2; -+ -+ /** -+ * Recursive implementation of binary search. -+ * -+ * @param aLow Indices here and lower do not contain the needle. -+ * @param aHigh Indices here and higher do not contain the needle. -+ * @param aNeedle The element being searched for. -+ * @param aHaystack The non-empty array being searched. -+ * @param aCompare Function which takes two elements and returns -1, 0, or 1. -+ * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or -+ * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the -+ * closest element that is smaller than or greater than the one we are -+ * searching for, respectively, if the exact element cannot be found. -+ */ -+ function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { -+ // This function terminates when one of the following is true: -+ // -+ // 1. We find the exact element we are looking for. -+ // -+ // 2. We did not find the exact element, but we can return the index of -+ // the next-closest element. -+ // -+ // 3. We did not find the exact element, and there is no next-closest -+ // element than the one we are searching for, so we return -1. -+ var mid = Math.floor((aHigh - aLow) / 2) + aLow; -+ var cmp = aCompare(aNeedle, aHaystack[mid], true); -+ if (cmp === 0) { -+ // Found the element we are looking for. -+ return mid; -+ } -+ else if (cmp > 0) { -+ // Our needle is greater than aHaystack[mid]. -+ if (aHigh - mid > 1) { -+ // The element is in the upper half. -+ return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); -+ } -+ -+ // The exact needle element was not found in this haystack. Determine if -+ // we are in termination case (3) or (2) and return the appropriate thing. -+ if (aBias == exports.LEAST_UPPER_BOUND) { -+ return aHigh < aHaystack.length ? aHigh : -1; -+ } else { -+ return mid; -+ } -+ } -+ else { -+ // Our needle is less than aHaystack[mid]. -+ if (mid - aLow > 1) { -+ // The element is in the lower half. -+ return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); -+ } -+ -+ // we are in termination case (3) or (2) and return the appropriate thing. -+ if (aBias == exports.LEAST_UPPER_BOUND) { -+ return mid; -+ } else { -+ return aLow < 0 ? -1 : aLow; -+ } -+ } -+ } -+ -+ /** -+ * This is an implementation of binary search which will always try and return -+ * the index of the closest element if there is no exact hit. This is because -+ * mappings between original and generated line/col pairs are single points, -+ * and there is an implicit region between each of them, so a miss just means -+ * that you aren't on the very start of a region. -+ * -+ * @param aNeedle The element you are looking for. -+ * @param aHaystack The array that is being searched. -+ * @param aCompare A function which takes the needle and an element in the -+ * array and returns -1, 0, or 1 depending on whether the needle is less -+ * than, equal to, or greater than the element, respectively. -+ * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or -+ * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the -+ * closest element that is smaller than or greater than the one we are -+ * searching for, respectively, if the exact element cannot be found. -+ * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. -+ */ -+ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { -+ if (aHaystack.length === 0) { -+ return -1; -+ } -+ -+ var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, -+ aCompare, aBias || exports.GREATEST_LOWER_BOUND); -+ if (index < 0) { -+ return -1; -+ } -+ -+ // We have found either the exact element, or the next-closest element than -+ // the one we are searching for. However, there may be more than one such -+ // element. Make sure we always return the smallest of these. -+ while (index - 1 >= 0) { -+ if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { -+ break; -+ } -+ --index; -+ } -+ -+ return index; -+ }; -+ } -+ -+ -+/***/ }, -+/* 9 */ -+/***/ function(module, exports) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ // It turns out that some (most?) JavaScript engines don't self-host -+ // `Array.prototype.sort`. This makes sense because C++ will likely remain -+ // faster than JS when doing raw CPU-intensive sorting. However, when using a -+ // custom comparator function, calling back and forth between the VM's C++ and -+ // JIT'd JS is rather slow *and* loses JIT type information, resulting in -+ // worse generated code for the comparator function than would be optimal. In -+ // fact, when sorting with a comparator, these costs outweigh the benefits of -+ // sorting in C++. By using our own JS-implemented Quick Sort (below), we get -+ // a ~3500ms mean speed-up in `bench/bench.html`. -+ -+ /** -+ * Swap the elements indexed by `x` and `y` in the array `ary`. -+ * -+ * @param {Array} ary -+ * The array. -+ * @param {Number} x -+ * The index of the first item. -+ * @param {Number} y -+ * The index of the second item. -+ */ -+ function swap(ary, x, y) { -+ var temp = ary[x]; -+ ary[x] = ary[y]; -+ ary[y] = temp; -+ } -+ -+ /** -+ * Returns a random integer within the range `low .. high` inclusive. -+ * -+ * @param {Number} low -+ * The lower bound on the range. -+ * @param {Number} high -+ * The upper bound on the range. -+ */ -+ function randomIntInRange(low, high) { -+ return Math.round(low + (Math.random() * (high - low))); -+ } -+ -+ /** -+ * The Quick Sort algorithm. -+ * -+ * @param {Array} ary -+ * An array to sort. -+ * @param {function} comparator -+ * Function to use to compare two items. -+ * @param {Number} p -+ * Start index of the array -+ * @param {Number} r -+ * End index of the array -+ */ -+ function doQuickSort(ary, comparator, p, r) { -+ // If our lower bound is less than our upper bound, we (1) partition the -+ // array into two pieces and (2) recurse on each half. If it is not, this is -+ // the empty array and our base case. -+ -+ if (p < r) { -+ // (1) Partitioning. -+ // -+ // The partitioning chooses a pivot between `p` and `r` and moves all -+ // elements that are less than or equal to the pivot to the before it, and -+ // all the elements that are greater than it after it. The effect is that -+ // once partition is done, the pivot is in the exact place it will be when -+ // the array is put in sorted order, and it will not need to be moved -+ // again. This runs in O(n) time. -+ -+ // Always choose a random pivot so that an input array which is reverse -+ // sorted does not cause O(n^2) running time. -+ var pivotIndex = randomIntInRange(p, r); -+ var i = p - 1; -+ -+ swap(ary, pivotIndex, r); -+ var pivot = ary[r]; -+ -+ // Immediately after `j` is incremented in this loop, the following hold -+ // true: -+ // -+ // * Every element in `ary[p .. i]` is less than or equal to the pivot. -+ // -+ // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. -+ for (var j = p; j < r; j++) { -+ if (comparator(ary[j], pivot) <= 0) { -+ i += 1; -+ swap(ary, i, j); -+ } -+ } -+ -+ swap(ary, i + 1, j); -+ var q = i + 1; -+ -+ // (2) Recurse on each half. -+ -+ doQuickSort(ary, comparator, p, q - 1); -+ doQuickSort(ary, comparator, q + 1, r); -+ } -+ } -+ -+ /** -+ * Sort the given array in-place with the given comparator function. -+ * -+ * @param {Array} ary -+ * An array to sort. -+ * @param {function} comparator -+ * Function to use to compare two items. -+ */ -+ exports.quickSort = function (ary, comparator) { -+ doQuickSort(ary, comparator, 0, ary.length - 1); -+ }; -+ } -+ -+ -+/***/ }, -+/* 10 */ -+/***/ function(module, exports, __webpack_require__) { -+ -+ /* -*- Mode: js; js-indent-level: 2; -*- */ -+ /* -+ * Copyright 2011 Mozilla Foundation and contributors -+ * Licensed under the New BSD license. See LICENSE or: -+ * http://opensource.org/licenses/BSD-3-Clause -+ */ -+ { -+ var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; -+ var util = __webpack_require__(4); -+ -+ // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other -+ // operating systems these days (capturing the result). -+ var REGEX_NEWLINE = /(\r?\n)/; -+ -+ // Newline character code for charCodeAt() comparisons -+ var NEWLINE_CODE = 10; -+ -+ // Private symbol for identifying `SourceNode`s when multiple versions of -+ // the source-map library are loaded. This MUST NOT CHANGE across -+ // versions! -+ var isSourceNode = "$$$isSourceNode$$$"; -+ -+ /** -+ * SourceNodes provide a way to abstract over interpolating/concatenating -+ * snippets of generated JavaScript source code while maintaining the line and -+ * column information associated with the original source code. -+ * -+ * @param aLine The original line number. -+ * @param aColumn The original column number. -+ * @param aSource The original source's filename. -+ * @param aChunks Optional. An array of strings which are snippets of -+ * generated JS, or other SourceNodes. -+ * @param aName The original identifier. -+ */ -+ function SourceNode(aLine, aColumn, aSource, aChunks, aName) { -+ this.children = []; -+ this.sourceContents = {}; -+ this.line = aLine == null ? null : aLine; -+ this.column = aColumn == null ? null : aColumn; -+ this.source = aSource == null ? null : aSource; -+ this.name = aName == null ? null : aName; -+ this[isSourceNode] = true; -+ if (aChunks != null) this.add(aChunks); -+ } -+ -+ /** -+ * Creates a SourceNode from generated code and a SourceMapConsumer. -+ * -+ * @param aGeneratedCode The generated code -+ * @param aSourceMapConsumer The SourceMap for the generated code -+ * @param aRelativePath Optional. The path that relative sources in the -+ * SourceMapConsumer should be relative to. -+ */ -+ SourceNode.fromStringWithSourceMap = -+ function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { -+ // The SourceNode we want to fill with the generated code -+ // and the SourceMap -+ var node = new SourceNode(); -+ -+ // All even indices of this array are one line of the generated code, -+ // while all odd indices are the newlines between two adjacent lines -+ // (since `REGEX_NEWLINE` captures its match). -+ // Processed fragments are removed from this array, by calling `shiftNextLine`. -+ var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); -+ var shiftNextLine = function() { -+ var lineContents = remainingLines.shift(); -+ // The last line of a file might not have a newline. -+ var newLine = remainingLines.shift() || ""; -+ return lineContents + newLine; -+ }; -+ -+ // We need to remember the position of "remainingLines" -+ var lastGeneratedLine = 1, lastGeneratedColumn = 0; -+ -+ // The generate SourceNodes we need a code range. -+ // To extract it current and last mapping is used. -+ // Here we store the last mapping. -+ var lastMapping = null; -+ -+ aSourceMapConsumer.eachMapping(function (mapping) { -+ if (lastMapping !== null) { -+ // We add the code from "lastMapping" to "mapping": -+ // First check if there is a new line in between. -+ if (lastGeneratedLine < mapping.generatedLine) { -+ // Associate first line with "lastMapping" -+ addMappingWithCode(lastMapping, shiftNextLine()); -+ lastGeneratedLine++; -+ lastGeneratedColumn = 0; -+ // The remaining code is added without mapping -+ } else { -+ // There is no new line in between. -+ // Associate the code between "lastGeneratedColumn" and -+ // "mapping.generatedColumn" with "lastMapping" -+ var nextLine = remainingLines[0]; -+ var code = nextLine.substr(0, mapping.generatedColumn - -+ lastGeneratedColumn); -+ remainingLines[0] = nextLine.substr(mapping.generatedColumn - -+ lastGeneratedColumn); -+ lastGeneratedColumn = mapping.generatedColumn; -+ addMappingWithCode(lastMapping, code); -+ // No more remaining code, continue -+ lastMapping = mapping; -+ return; -+ } -+ } -+ // We add the generated code until the first mapping -+ // to the SourceNode without any mapping. -+ // Each line is added as separate string. -+ while (lastGeneratedLine < mapping.generatedLine) { -+ node.add(shiftNextLine()); -+ lastGeneratedLine++; -+ } -+ if (lastGeneratedColumn < mapping.generatedColumn) { -+ var nextLine = remainingLines[0]; -+ node.add(nextLine.substr(0, mapping.generatedColumn)); -+ remainingLines[0] = nextLine.substr(mapping.generatedColumn); -+ lastGeneratedColumn = mapping.generatedColumn; -+ } -+ lastMapping = mapping; -+ }, this); -+ // We have processed all mappings. -+ if (remainingLines.length > 0) { -+ if (lastMapping) { -+ // Associate the remaining code in the current line with "lastMapping" -+ addMappingWithCode(lastMapping, shiftNextLine()); -+ } -+ // and add the remaining lines without any mapping -+ node.add(remainingLines.join("")); -+ } -+ -+ // Copy sourcesContent into SourceNode -+ aSourceMapConsumer.sources.forEach(function (sourceFile) { -+ var content = aSourceMapConsumer.sourceContentFor(sourceFile); -+ if (content != null) { -+ if (aRelativePath != null) { -+ sourceFile = util.join(aRelativePath, sourceFile); -+ } -+ node.setSourceContent(sourceFile, content); -+ } -+ }); -+ -+ return node; -+ -+ function addMappingWithCode(mapping, code) { -+ if (mapping === null || mapping.source === undefined) { -+ node.add(code); -+ } else { -+ var source = aRelativePath -+ ? util.join(aRelativePath, mapping.source) -+ : mapping.source; -+ node.add(new SourceNode(mapping.originalLine, -+ mapping.originalColumn, -+ source, -+ code, -+ mapping.name)); -+ } -+ } -+ }; -+ -+ /** -+ * Add a chunk of generated JS to this source node. -+ * -+ * @param aChunk A string snippet of generated JS code, another instance of -+ * SourceNode, or an array where each member is one of those things. -+ */ -+ SourceNode.prototype.add = function SourceNode_add(aChunk) { -+ if (Array.isArray(aChunk)) { -+ aChunk.forEach(function (chunk) { -+ this.add(chunk); -+ }, this); -+ } -+ else if (aChunk[isSourceNode] || typeof aChunk === "string") { -+ if (aChunk) { -+ this.children.push(aChunk); -+ } -+ } -+ else { -+ throw new TypeError( -+ "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk -+ ); -+ } -+ return this; -+ }; -+ -+ /** -+ * Add a chunk of generated JS to the beginning of this source node. -+ * -+ * @param aChunk A string snippet of generated JS code, another instance of -+ * SourceNode, or an array where each member is one of those things. -+ */ -+ SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { -+ if (Array.isArray(aChunk)) { -+ for (var i = aChunk.length-1; i >= 0; i--) { -+ this.prepend(aChunk[i]); -+ } -+ } -+ else if (aChunk[isSourceNode] || typeof aChunk === "string") { -+ this.children.unshift(aChunk); -+ } -+ else { -+ throw new TypeError( -+ "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk -+ ); -+ } -+ return this; -+ }; -+ -+ /** -+ * Walk over the tree of JS snippets in this node and its children. The -+ * walking function is called once for each snippet of JS and is passed that -+ * snippet and the its original associated source's line/column location. -+ * -+ * @param aFn The traversal function. -+ */ -+ SourceNode.prototype.walk = function SourceNode_walk(aFn) { -+ var chunk; -+ for (var i = 0, len = this.children.length; i < len; i++) { -+ chunk = this.children[i]; -+ if (chunk[isSourceNode]) { -+ chunk.walk(aFn); -+ } -+ else { -+ if (chunk !== '') { -+ aFn(chunk, { source: this.source, -+ line: this.line, -+ column: this.column, -+ name: this.name }); -+ } -+ } -+ } -+ }; -+ -+ /** -+ * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between -+ * each of `this.children`. -+ * -+ * @param aSep The separator. -+ */ -+ SourceNode.prototype.join = function SourceNode_join(aSep) { -+ var newChildren; -+ var i; -+ var len = this.children.length; -+ if (len > 0) { -+ newChildren = []; -+ for (i = 0; i < len-1; i++) { -+ newChildren.push(this.children[i]); -+ newChildren.push(aSep); -+ } -+ newChildren.push(this.children[i]); -+ this.children = newChildren; -+ } -+ return this; -+ }; -+ -+ /** -+ * Call String.prototype.replace on the very right-most source snippet. Useful -+ * for trimming whitespace from the end of a source node, etc. -+ * -+ * @param aPattern The pattern to replace. -+ * @param aReplacement The thing to replace the pattern with. -+ */ -+ SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { -+ var lastChild = this.children[this.children.length - 1]; -+ if (lastChild[isSourceNode]) { -+ lastChild.replaceRight(aPattern, aReplacement); -+ } -+ else if (typeof lastChild === 'string') { -+ this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); -+ } -+ else { -+ this.children.push(''.replace(aPattern, aReplacement)); -+ } -+ return this; -+ }; -+ -+ /** -+ * Set the source content for a source file. This will be added to the SourceMapGenerator -+ * in the sourcesContent field. -+ * -+ * @param aSourceFile The filename of the source file -+ * @param aSourceContent The content of the source file -+ */ -+ SourceNode.prototype.setSourceContent = -+ function SourceNode_setSourceContent(aSourceFile, aSourceContent) { -+ this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; -+ }; -+ -+ /** -+ * Walk over the tree of SourceNodes. The walking function is called for each -+ * source file content and is passed the filename and source content. -+ * -+ * @param aFn The traversal function. -+ */ -+ SourceNode.prototype.walkSourceContents = -+ function SourceNode_walkSourceContents(aFn) { -+ for (var i = 0, len = this.children.length; i < len; i++) { -+ if (this.children[i][isSourceNode]) { -+ this.children[i].walkSourceContents(aFn); -+ } -+ } -+ -+ var sources = Object.keys(this.sourceContents); -+ for (var i = 0, len = sources.length; i < len; i++) { -+ aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); -+ } -+ }; -+ -+ /** -+ * Return the string representation of this source node. Walks over the tree -+ * and concatenates all the various snippets together to one string. -+ */ -+ SourceNode.prototype.toString = function SourceNode_toString() { -+ var str = ""; -+ this.walk(function (chunk) { -+ str += chunk; -+ }); -+ return str; -+ }; -+ -+ /** -+ * Returns the string representation of this source node along with a source -+ * map. -+ */ -+ SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { -+ var generated = { -+ code: "", -+ line: 1, -+ column: 0 -+ }; -+ var map = new SourceMapGenerator(aArgs); -+ var sourceMappingActive = false; -+ var lastOriginalSource = null; -+ var lastOriginalLine = null; -+ var lastOriginalColumn = null; -+ var lastOriginalName = null; -+ this.walk(function (chunk, original) { -+ generated.code += chunk; -+ if (original.source !== null -+ && original.line !== null -+ && original.column !== null) { -+ if(lastOriginalSource !== original.source -+ || lastOriginalLine !== original.line -+ || lastOriginalColumn !== original.column -+ || lastOriginalName !== original.name) { -+ map.addMapping({ -+ source: original.source, -+ original: { -+ line: original.line, -+ column: original.column -+ }, -+ generated: { -+ line: generated.line, -+ column: generated.column -+ }, -+ name: original.name -+ }); -+ } -+ lastOriginalSource = original.source; -+ lastOriginalLine = original.line; -+ lastOriginalColumn = original.column; -+ lastOriginalName = original.name; -+ sourceMappingActive = true; -+ } else if (sourceMappingActive) { -+ map.addMapping({ -+ generated: { -+ line: generated.line, -+ column: generated.column -+ } -+ }); -+ lastOriginalSource = null; -+ sourceMappingActive = false; -+ } -+ for (var idx = 0, length = chunk.length; idx < length; idx++) { -+ if (chunk.charCodeAt(idx) === NEWLINE_CODE) { -+ generated.line++; -+ generated.column = 0; -+ // Mappings end at eol -+ if (idx + 1 === length) { -+ lastOriginalSource = null; -+ sourceMappingActive = false; -+ } else if (sourceMappingActive) { -+ map.addMapping({ -+ source: original.source, -+ original: { -+ line: original.line, -+ column: original.column -+ }, -+ generated: { -+ line: generated.line, -+ column: generated.column -+ }, -+ name: original.name -+ }); -+ } -+ } else { -+ generated.column++; -+ } -+ } -+ }); -+ this.walkSourceContents(function (sourceFile, sourceContent) { -+ map.setSourceContent(sourceFile, sourceContent); -+ }); -+ -+ return { code: generated.code, map: map }; -+ }; -+ -+ exports.SourceNode = SourceNode; -+ } -+ -+ -+/***/ } -+/******/ ]) -+}); -+; -\ No newline at end of file -diff --git a/lib/uglifier.js b/lib/uglifier.js -index c7532f2..169b716 100644 ---- a/lib/uglifier.js -+++ b/lib/uglifier.js -@@ -1,3 +1,6 @@ -+// Set source-map.js sourceMap to uglify.js MOZ_SourceMap -+MOZ_SourceMap = sourceMap; -+ - function comments(option) { - if (Object.prototype.toString.call(option) === '[object Array]') { - return new RegExp(option[0], option[1]); -diff --git a/lib/uglifier.rb b/lib/uglifier.rb -index 2b4ce05..de24e26 100644 ---- a/lib/uglifier.rb -+++ b/lib/uglifier.rb -@@ -12,6 +12,8 @@ class Uglifier - - # UglifyJS source path - SourcePath = File.expand_path("../uglify.js", __FILE__) -+ # Source Map path -+ SourceMapPath = File.expand_path("../source-map.js", __FILE__) - # ES5 shims source path - ES5FallbackPath = File.expand_path("../es5.js", __FILE__) - # String.split shim source path -@@ -152,7 +154,8 @@ class Uglifier - private - - def uglifyjs_source -- [ES5FallbackPath, SplitFallbackPath, SourcePath, UglifyJSWrapperPath].map do |file| -+ [ES5FallbackPath, SplitFallbackPath, SourceMapPath, SourcePath, -+ UglifyJSWrapperPath].map do |file| - File.open(file, "r:UTF-8", &:read) - end.join("\n") - end -diff --git a/lib/uglify.js b/lib/uglify.js -index c2ed075..12d025d 100644 ---- a/lib/uglify.js -+++ b/lib/uglify.js -@@ -1,3008 +1,4 @@ --window = this;(function webpackUniversalModuleDefinition(root, factory) { -- if(typeof exports === 'object' && typeof module === 'object') -- module.exports = factory(); -- else if(typeof define === 'function' && define.amd) -- define([], factory); -- else if(typeof exports === 'object') -- exports["sourceMap"] = factory(); -- else -- root["sourceMap"] = factory(); --})(this, function() { --return /******/ (function(modules) { // webpackBootstrap --/******/ // The module cache --/******/ var installedModules = {}; -- --/******/ // The require function --/******/ function __webpack_require__(moduleId) { -- --/******/ // Check if module is in cache --/******/ if(installedModules[moduleId]) --/******/ return installedModules[moduleId].exports; -- --/******/ // Create a new module (and put it into the cache) --/******/ var module = installedModules[moduleId] = { --/******/ exports: {}, --/******/ id: moduleId, --/******/ loaded: false --/******/ }; -- --/******/ // Execute the module function --/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -- --/******/ // Flag the module as loaded --/******/ module.loaded = true; -- --/******/ // Return the exports of the module --/******/ return module.exports; --/******/ } -- -- --/******/ // expose the modules object (__webpack_modules__) --/******/ __webpack_require__.m = modules; -- --/******/ // expose the module cache --/******/ __webpack_require__.c = installedModules; -- --/******/ // __webpack_public_path__ --/******/ __webpack_require__.p = ""; -- --/******/ // Load entry module and return exports --/******/ return __webpack_require__(0); --/******/ }) --/************************************************************************/ --/******/ ([ --/* 0 */ --/***/ function(module, exports, __webpack_require__) { -- -- /* -- * Copyright 2009-2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE.txt or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; -- exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; -- exports.SourceNode = __webpack_require__(10).SourceNode; -- -- --/***/ }, --/* 1 */ --/***/ function(module, exports, __webpack_require__) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- var base64VLQ = __webpack_require__(2); -- var util = __webpack_require__(4); -- var ArraySet = __webpack_require__(5).ArraySet; -- var MappingList = __webpack_require__(6).MappingList; -- -- /** -- * An instance of the SourceMapGenerator represents a source map which is -- * being built incrementally. You may pass an object with the following -- * properties: -- * -- * - file: The filename of the generated source. -- * - sourceRoot: A root for all relative URLs in this source map. -- */ -- function SourceMapGenerator(aArgs) { -- if (!aArgs) { -- aArgs = {}; -- } -- this._file = util.getArg(aArgs, 'file', null); -- this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); -- this._skipValidation = util.getArg(aArgs, 'skipValidation', false); -- this._sources = new ArraySet(); -- this._names = new ArraySet(); -- this._mappings = new MappingList(); -- this._sourcesContents = null; -- } -- -- SourceMapGenerator.prototype._version = 3; -- -- /** -- * Creates a new SourceMapGenerator based on a SourceMapConsumer -- * -- * @param aSourceMapConsumer The SourceMap. -- */ -- SourceMapGenerator.fromSourceMap = -- function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { -- var sourceRoot = aSourceMapConsumer.sourceRoot; -- var generator = new SourceMapGenerator({ -- file: aSourceMapConsumer.file, -- sourceRoot: sourceRoot -- }); -- aSourceMapConsumer.eachMapping(function (mapping) { -- var newMapping = { -- generated: { -- line: mapping.generatedLine, -- column: mapping.generatedColumn -- } -- }; -- -- if (mapping.source != null) { -- newMapping.source = mapping.source; -- if (sourceRoot != null) { -- newMapping.source = util.relative(sourceRoot, newMapping.source); -- } -- -- newMapping.original = { -- line: mapping.originalLine, -- column: mapping.originalColumn -- }; -- -- if (mapping.name != null) { -- newMapping.name = mapping.name; -- } -- } -- -- generator.addMapping(newMapping); -- }); -- aSourceMapConsumer.sources.forEach(function (sourceFile) { -- var content = aSourceMapConsumer.sourceContentFor(sourceFile); -- if (content != null) { -- generator.setSourceContent(sourceFile, content); -- } -- }); -- return generator; -- }; -- -- /** -- * Add a single mapping from original source line and column to the generated -- * source's line and column for this source map being created. The mapping -- * object should have the following properties: -- * -- * - generated: An object with the generated line and column positions. -- * - original: An object with the original line and column positions. -- * - source: The original source file (relative to the sourceRoot). -- * - name: An optional original token name for this mapping. -- */ -- SourceMapGenerator.prototype.addMapping = -- function SourceMapGenerator_addMapping(aArgs) { -- var generated = util.getArg(aArgs, 'generated'); -- var original = util.getArg(aArgs, 'original', null); -- var source = util.getArg(aArgs, 'source', null); -- var name = util.getArg(aArgs, 'name', null); -- -- if (!this._skipValidation) { -- this._validateMapping(generated, original, source, name); -- } -- -- if (source != null && !this._sources.has(source)) { -- this._sources.add(source); -- } -- -- if (name != null && !this._names.has(name)) { -- this._names.add(name); -- } -- -- this._mappings.add({ -- generatedLine: generated.line, -- generatedColumn: generated.column, -- originalLine: original != null && original.line, -- originalColumn: original != null && original.column, -- source: source, -- name: name -- }); -- }; -- -- /** -- * Set the source content for a source file. -- */ -- SourceMapGenerator.prototype.setSourceContent = -- function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { -- var source = aSourceFile; -- if (this._sourceRoot != null) { -- source = util.relative(this._sourceRoot, source); -- } -- -- if (aSourceContent != null) { -- // Add the source content to the _sourcesContents map. -- // Create a new _sourcesContents map if the property is null. -- if (!this._sourcesContents) { -- this._sourcesContents = {}; -- } -- this._sourcesContents[util.toSetString(source)] = aSourceContent; -- } else if (this._sourcesContents) { -- // Remove the source file from the _sourcesContents map. -- // If the _sourcesContents map is empty, set the property to null. -- delete this._sourcesContents[util.toSetString(source)]; -- if (Object.keys(this._sourcesContents).length === 0) { -- this._sourcesContents = null; -- } -- } -- }; -- -- /** -- * Applies the mappings of a sub-source-map for a specific source file to the -- * source map being generated. Each mapping to the supplied source file is -- * rewritten using the supplied source map. Note: The resolution for the -- * resulting mappings is the minimium of this map and the supplied map. -- * -- * @param aSourceMapConsumer The source map to be applied. -- * @param aSourceFile Optional. The filename of the source file. -- * If omitted, SourceMapConsumer's file property will be used. -- * @param aSourceMapPath Optional. The dirname of the path to the source map -- * to be applied. If relative, it is relative to the SourceMapConsumer. -- * This parameter is needed when the two source maps aren't in the same -- * directory, and the source map to be applied contains relative source -- * paths. If so, those relative source paths need to be rewritten -- * relative to the SourceMapGenerator. -- */ -- SourceMapGenerator.prototype.applySourceMap = -- function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { -- var sourceFile = aSourceFile; -- // If aSourceFile is omitted, we will use the file property of the SourceMap -- if (aSourceFile == null) { -- if (aSourceMapConsumer.file == null) { -- throw new Error( -- 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + -- 'or the source map\'s "file" property. Both were omitted.' -- ); -- } -- sourceFile = aSourceMapConsumer.file; -- } -- var sourceRoot = this._sourceRoot; -- // Make "sourceFile" relative if an absolute Url is passed. -- if (sourceRoot != null) { -- sourceFile = util.relative(sourceRoot, sourceFile); -- } -- // Applying the SourceMap can add and remove items from the sources and -- // the names array. -- var newSources = new ArraySet(); -- var newNames = new ArraySet(); -- -- // Find mappings for the "sourceFile" -- this._mappings.unsortedForEach(function (mapping) { -- if (mapping.source === sourceFile && mapping.originalLine != null) { -- // Check if it can be mapped by the source map, then update the mapping. -- var original = aSourceMapConsumer.originalPositionFor({ -- line: mapping.originalLine, -- column: mapping.originalColumn -- }); -- if (original.source != null) { -- // Copy mapping -- mapping.source = original.source; -- if (aSourceMapPath != null) { -- mapping.source = util.join(aSourceMapPath, mapping.source) -- } -- if (sourceRoot != null) { -- mapping.source = util.relative(sourceRoot, mapping.source); -- } -- mapping.originalLine = original.line; -- mapping.originalColumn = original.column; -- if (original.name != null) { -- mapping.name = original.name; -- } -- } -- } -- -- var source = mapping.source; -- if (source != null && !newSources.has(source)) { -- newSources.add(source); -- } -- -- var name = mapping.name; -- if (name != null && !newNames.has(name)) { -- newNames.add(name); -- } -- -- }, this); -- this._sources = newSources; -- this._names = newNames; -- -- // Copy sourcesContents of applied map. -- aSourceMapConsumer.sources.forEach(function (sourceFile) { -- var content = aSourceMapConsumer.sourceContentFor(sourceFile); -- if (content != null) { -- if (aSourceMapPath != null) { -- sourceFile = util.join(aSourceMapPath, sourceFile); -- } -- if (sourceRoot != null) { -- sourceFile = util.relative(sourceRoot, sourceFile); -- } -- this.setSourceContent(sourceFile, content); -- } -- }, this); -- }; -- -- /** -- * A mapping can have one of the three levels of data: -- * -- * 1. Just the generated position. -- * 2. The Generated position, original position, and original source. -- * 3. Generated and original position, original source, as well as a name -- * token. -- * -- * To maintain consistency, we validate that any new mapping being added falls -- * in to one of these categories. -- */ -- SourceMapGenerator.prototype._validateMapping = -- function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, -- aName) { -- if (aGenerated && 'line' in aGenerated && 'column' in aGenerated -- && aGenerated.line > 0 && aGenerated.column >= 0 -- && !aOriginal && !aSource && !aName) { -- // Case 1. -- return; -- } -- else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated -- && aOriginal && 'line' in aOriginal && 'column' in aOriginal -- && aGenerated.line > 0 && aGenerated.column >= 0 -- && aOriginal.line > 0 && aOriginal.column >= 0 -- && aSource) { -- // Cases 2 and 3. -- return; -- } -- else { -- throw new Error('Invalid mapping: ' + JSON.stringify({ -- generated: aGenerated, -- source: aSource, -- original: aOriginal, -- name: aName -- })); -- } -- }; -- -- /** -- * Serialize the accumulated mappings in to the stream of base 64 VLQs -- * specified by the source map format. -- */ -- SourceMapGenerator.prototype._serializeMappings = -- function SourceMapGenerator_serializeMappings() { -- var previousGeneratedColumn = 0; -- var previousGeneratedLine = 1; -- var previousOriginalColumn = 0; -- var previousOriginalLine = 0; -- var previousName = 0; -- var previousSource = 0; -- var result = ''; -- var mapping; -- var nameIdx; -- var sourceIdx; -- -- var mappings = this._mappings.toArray(); -- for (var i = 0, len = mappings.length; i < len; i++) { -- mapping = mappings[i]; -- -- if (mapping.generatedLine !== previousGeneratedLine) { -- previousGeneratedColumn = 0; -- while (mapping.generatedLine !== previousGeneratedLine) { -- result += ';'; -- previousGeneratedLine++; -- } -- } -- else { -- if (i > 0) { -- if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { -- continue; -- } -- result += ','; -- } -- } -- -- result += base64VLQ.encode(mapping.generatedColumn -- - previousGeneratedColumn); -- previousGeneratedColumn = mapping.generatedColumn; -- -- if (mapping.source != null) { -- sourceIdx = this._sources.indexOf(mapping.source); -- result += base64VLQ.encode(sourceIdx - previousSource); -- previousSource = sourceIdx; -- -- // lines are stored 0-based in SourceMap spec version 3 -- result += base64VLQ.encode(mapping.originalLine - 1 -- - previousOriginalLine); -- previousOriginalLine = mapping.originalLine - 1; -- -- result += base64VLQ.encode(mapping.originalColumn -- - previousOriginalColumn); -- previousOriginalColumn = mapping.originalColumn; -- -- if (mapping.name != null) { -- nameIdx = this._names.indexOf(mapping.name); -- result += base64VLQ.encode(nameIdx - previousName); -- previousName = nameIdx; -- } -- } -- } -- -- return result; -- }; -- -- SourceMapGenerator.prototype._generateSourcesContent = -- function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { -- return aSources.map(function (source) { -- if (!this._sourcesContents) { -- return null; -- } -- if (aSourceRoot != null) { -- source = util.relative(aSourceRoot, source); -- } -- var key = util.toSetString(source); -- return Object.prototype.hasOwnProperty.call(this._sourcesContents, -- key) -- ? this._sourcesContents[key] -- : null; -- }, this); -- }; -- -- /** -- * Externalize the source map. -- */ -- SourceMapGenerator.prototype.toJSON = -- function SourceMapGenerator_toJSON() { -- var map = { -- version: this._version, -- sources: this._sources.toArray(), -- names: this._names.toArray(), -- mappings: this._serializeMappings() -- }; -- if (this._file != null) { -- map.file = this._file; -- } -- if (this._sourceRoot != null) { -- map.sourceRoot = this._sourceRoot; -- } -- if (this._sourcesContents) { -- map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); -- } -- -- return map; -- }; -- -- /** -- * Render the source map being generated to a string. -- */ -- SourceMapGenerator.prototype.toString = -- function SourceMapGenerator_toString() { -- return JSON.stringify(this.toJSON()); -- }; -- -- exports.SourceMapGenerator = SourceMapGenerator; -- } -- -- --/***/ }, --/* 2 */ --/***/ function(module, exports, __webpack_require__) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- * -- * Based on the Base 64 VLQ implementation in Closure Compiler: -- * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java -- * -- * Copyright 2011 The Closure Compiler Authors. All rights reserved. -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are -- * met: -- * -- * * Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * * Redistributions in binary form must reproduce the above -- * copyright notice, this list of conditions and the following -- * disclaimer in the documentation and/or other materials provided -- * with the distribution. -- * * Neither the name of Google Inc. nor the names of its -- * contributors may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- { -- var base64 = __webpack_require__(3); -- -- // A single base 64 digit can contain 6 bits of data. For the base 64 variable -- // length quantities we use in the source map spec, the first bit is the sign, -- // the next four bits are the actual value, and the 6th bit is the -- // continuation bit. The continuation bit tells us whether there are more -- // digits in this value following this digit. -- // -- // Continuation -- // | Sign -- // | | -- // V V -- // 101011 -- -- var VLQ_BASE_SHIFT = 5; -- -- // binary: 100000 -- var VLQ_BASE = 1 << VLQ_BASE_SHIFT; -- -- // binary: 011111 -- var VLQ_BASE_MASK = VLQ_BASE - 1; -- -- // binary: 100000 -- var VLQ_CONTINUATION_BIT = VLQ_BASE; -- -- /** -- * Converts from a two-complement value to a value where the sign bit is -- * placed in the least significant bit. For example, as decimals: -- * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) -- * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) -- */ -- function toVLQSigned(aValue) { -- return aValue < 0 -- ? ((-aValue) << 1) + 1 -- : (aValue << 1) + 0; -- } -- -- /** -- * Converts to a two-complement value from a value where the sign bit is -- * placed in the least significant bit. For example, as decimals: -- * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 -- * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 -- */ -- function fromVLQSigned(aValue) { -- var isNegative = (aValue & 1) === 1; -- var shifted = aValue >> 1; -- return isNegative -- ? -shifted -- : shifted; -- } -- -- /** -- * Returns the base 64 VLQ encoded value. -- */ -- exports.encode = function base64VLQ_encode(aValue) { -- var encoded = ""; -- var digit; -- -- var vlq = toVLQSigned(aValue); -- -- do { -- digit = vlq & VLQ_BASE_MASK; -- vlq >>>= VLQ_BASE_SHIFT; -- if (vlq > 0) { -- // There are still more digits in this value, so we must make sure the -- // continuation bit is marked. -- digit |= VLQ_CONTINUATION_BIT; -- } -- encoded += base64.encode(digit); -- } while (vlq > 0); -- -- return encoded; -- }; -- -- /** -- * Decodes the next base 64 VLQ value from the given string and returns the -- * value and the rest of the string via the out parameter. -- */ -- exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { -- var strLen = aStr.length; -- var result = 0; -- var shift = 0; -- var continuation, digit; -- -- do { -- if (aIndex >= strLen) { -- throw new Error("Expected more digits in base 64 VLQ value."); -- } -- -- digit = base64.decode(aStr.charCodeAt(aIndex++)); -- if (digit === -1) { -- throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); -- } -- -- continuation = !!(digit & VLQ_CONTINUATION_BIT); -- digit &= VLQ_BASE_MASK; -- result = result + (digit << shift); -- shift += VLQ_BASE_SHIFT; -- } while (continuation); -- -- aOutParam.value = fromVLQSigned(result); -- aOutParam.rest = aIndex; -- }; -- } -- -- --/***/ }, --/* 3 */ --/***/ function(module, exports) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); -- -- /** -- * Encode an integer in the range of 0 to 63 to a single base 64 digit. -- */ -- exports.encode = function (number) { -- if (0 <= number && number < intToCharMap.length) { -- return intToCharMap[number]; -- } -- throw new TypeError("Must be between 0 and 63: " + number); -- }; -- -- /** -- * Decode a single base 64 character code digit to an integer. Returns -1 on -- * failure. -- */ -- exports.decode = function (charCode) { -- var bigA = 65; // 'A' -- var bigZ = 90; // 'Z' -- -- var littleA = 97; // 'a' -- var littleZ = 122; // 'z' -- -- var zero = 48; // '0' -- var nine = 57; // '9' -- -- var plus = 43; // '+' -- var slash = 47; // '/' -- -- var littleOffset = 26; -- var numberOffset = 52; -- -- // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ -- if (bigA <= charCode && charCode <= bigZ) { -- return (charCode - bigA); -- } -- -- // 26 - 51: abcdefghijklmnopqrstuvwxyz -- if (littleA <= charCode && charCode <= littleZ) { -- return (charCode - littleA + littleOffset); -- } -- -- // 52 - 61: 0123456789 -- if (zero <= charCode && charCode <= nine) { -- return (charCode - zero + numberOffset); -- } -- -- // 62: + -- if (charCode == plus) { -- return 62; -- } -- -- // 63: / -- if (charCode == slash) { -- return 63; -- } -- -- // Invalid base64 digit. -- return -1; -- }; -- } -- -- --/***/ }, --/* 4 */ --/***/ function(module, exports) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- /** -- * This is a helper function for getting values from parameter/options -- * objects. -- * -- * @param args The object we are extracting values from -- * @param name The name of the property we are getting. -- * @param defaultValue An optional value to return if the property is missing -- * from the object. If this is not specified and the property is missing, an -- * error will be thrown. -- */ -- function getArg(aArgs, aName, aDefaultValue) { -- if (aName in aArgs) { -- return aArgs[aName]; -- } else if (arguments.length === 3) { -- return aDefaultValue; -- } else { -- throw new Error('"' + aName + '" is a required argument.'); -- } -- } -- exports.getArg = getArg; -- -- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; -- var dataUrlRegexp = /^data:.+\,.+$/; -- -- function urlParse(aUrl) { -- var match = aUrl.match(urlRegexp); -- if (!match) { -- return null; -- } -- return { -- scheme: match[1], -- auth: match[2], -- host: match[3], -- port: match[4], -- path: match[5] -- }; -- } -- exports.urlParse = urlParse; -- -- function urlGenerate(aParsedUrl) { -- var url = ''; -- if (aParsedUrl.scheme) { -- url += aParsedUrl.scheme + ':'; -- } -- url += '//'; -- if (aParsedUrl.auth) { -- url += aParsedUrl.auth + '@'; -- } -- if (aParsedUrl.host) { -- url += aParsedUrl.host; -- } -- if (aParsedUrl.port) { -- url += ":" + aParsedUrl.port -- } -- if (aParsedUrl.path) { -- url += aParsedUrl.path; -- } -- return url; -- } -- exports.urlGenerate = urlGenerate; -- -- /** -- * Normalizes a path, or the path portion of a URL: -- * -- * - Replaces consequtive slashes with one slash. -- * - Removes unnecessary '.' parts. -- * - Removes unnecessary '/..' parts. -- * -- * Based on code in the Node.js 'path' core module. -- * -- * @param aPath The path or url to normalize. -- */ -- function normalize(aPath) { -- var path = aPath; -- var url = urlParse(aPath); -- if (url) { -- if (!url.path) { -- return aPath; -- } -- path = url.path; -- } -- var isAbsolute = exports.isAbsolute(path); -- -- var parts = path.split(/\/+/); -- for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { -- part = parts[i]; -- if (part === '.') { -- parts.splice(i, 1); -- } else if (part === '..') { -- up++; -- } else if (up > 0) { -- if (part === '') { -- // The first part is blank if the path is absolute. Trying to go -- // above the root is a no-op. Therefore we can remove all '..' parts -- // directly after the root. -- parts.splice(i + 1, up); -- up = 0; -- } else { -- parts.splice(i, 2); -- up--; -- } -- } -- } -- path = parts.join('/'); -- -- if (path === '') { -- path = isAbsolute ? '/' : '.'; -- } -- -- if (url) { -- url.path = path; -- return urlGenerate(url); -- } -- return path; -- } -- exports.normalize = normalize; -- -- /** -- * Joins two paths/URLs. -- * -- * @param aRoot The root path or URL. -- * @param aPath The path or URL to be joined with the root. -- * -- * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a -- * scheme-relative URL: Then the scheme of aRoot, if any, is prepended -- * first. -- * - Otherwise aPath is a path. If aRoot is a URL, then its path portion -- * is updated with the result and aRoot is returned. Otherwise the result -- * is returned. -- * - If aPath is absolute, the result is aPath. -- * - Otherwise the two paths are joined with a slash. -- * - Joining for example 'http://' and 'www.example.com' is also supported. -- */ -- function join(aRoot, aPath) { -- if (aRoot === "") { -- aRoot = "."; -- } -- if (aPath === "") { -- aPath = "."; -- } -- var aPathUrl = urlParse(aPath); -- var aRootUrl = urlParse(aRoot); -- if (aRootUrl) { -- aRoot = aRootUrl.path || '/'; -- } -- -- // `join(foo, '//www.example.org')` -- if (aPathUrl && !aPathUrl.scheme) { -- if (aRootUrl) { -- aPathUrl.scheme = aRootUrl.scheme; -- } -- return urlGenerate(aPathUrl); -- } -- -- if (aPathUrl || aPath.match(dataUrlRegexp)) { -- return aPath; -- } -- -- // `join('http://', 'www.example.com')` -- if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { -- aRootUrl.host = aPath; -- return urlGenerate(aRootUrl); -- } -- -- var joined = aPath.charAt(0) === '/' -- ? aPath -- : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); -- -- if (aRootUrl) { -- aRootUrl.path = joined; -- return urlGenerate(aRootUrl); -- } -- return joined; -- } -- exports.join = join; -- -- exports.isAbsolute = function (aPath) { -- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); -- }; -- -- /** -- * Make a path relative to a URL or another path. -- * -- * @param aRoot The root path or URL. -- * @param aPath The path or URL to be made relative to aRoot. -- */ -- function relative(aRoot, aPath) { -- if (aRoot === "") { -- aRoot = "."; -- } -- -- aRoot = aRoot.replace(/\/$/, ''); -- -- // It is possible for the path to be above the root. In this case, simply -- // checking whether the root is a prefix of the path won't work. Instead, we -- // need to remove components from the root one by one, until either we find -- // a prefix that fits, or we run out of components to remove. -- var level = 0; -- while (aPath.indexOf(aRoot + '/') !== 0) { -- var index = aRoot.lastIndexOf("/"); -- if (index < 0) { -- return aPath; -- } -- -- // If the only part of the root that is left is the scheme (i.e. http://, -- // file:///, etc.), one or more slashes (/), or simply nothing at all, we -- // have exhausted all components, so the path is not relative to the root. -- aRoot = aRoot.slice(0, index); -- if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { -- return aPath; -- } -- -- ++level; -- } -- -- // Make sure we add a "../" for each component we removed from the root. -- return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); -- } -- exports.relative = relative; -- -- /** -- * Because behavior goes wacky when you set `__proto__` on objects, we -- * have to prefix all the strings in our set with an arbitrary character. -- * -- * See https://github.com/mozilla/source-map/pull/31 and -- * https://github.com/mozilla/source-map/issues/30 -- * -- * @param String aStr -- */ -- function toSetString(aStr) { -- return '$' + aStr; -- } -- exports.toSetString = toSetString; -- -- function fromSetString(aStr) { -- return aStr.substr(1); -- } -- exports.fromSetString = fromSetString; -- -- /** -- * Comparator between two mappings where the original positions are compared. -- * -- * Optionally pass in `true` as `onlyCompareGenerated` to consider two -- * mappings with the same original source/line/column, but different generated -- * line and column the same. Useful when searching for a mapping with a -- * stubbed out mapping. -- */ -- function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { -- var cmp = mappingA.source - mappingB.source; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.originalLine - mappingB.originalLine; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.originalColumn - mappingB.originalColumn; -- if (cmp !== 0 || onlyCompareOriginal) { -- return cmp; -- } -- -- cmp = mappingA.generatedColumn - mappingB.generatedColumn; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.generatedLine - mappingB.generatedLine; -- if (cmp !== 0) { -- return cmp; -- } -- -- return mappingA.name - mappingB.name; -- } -- exports.compareByOriginalPositions = compareByOriginalPositions; -- -- /** -- * Comparator between two mappings with deflated source and name indices where -- * the generated positions are compared. -- * -- * Optionally pass in `true` as `onlyCompareGenerated` to consider two -- * mappings with the same generated line and column, but different -- * source/name/original line and column the same. Useful when searching for a -- * mapping with a stubbed out mapping. -- */ -- function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { -- var cmp = mappingA.generatedLine - mappingB.generatedLine; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.generatedColumn - mappingB.generatedColumn; -- if (cmp !== 0 || onlyCompareGenerated) { -- return cmp; -- } -- -- cmp = mappingA.source - mappingB.source; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.originalLine - mappingB.originalLine; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.originalColumn - mappingB.originalColumn; -- if (cmp !== 0) { -- return cmp; -- } -- -- return mappingA.name - mappingB.name; -- } -- exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; -- -- function strcmp(aStr1, aStr2) { -- if (aStr1 === aStr2) { -- return 0; -- } -- -- if (aStr1 > aStr2) { -- return 1; -- } -- -- return -1; -- } -- -- /** -- * Comparator between two mappings with inflated source and name strings where -- * the generated positions are compared. -- */ -- function compareByGeneratedPositionsInflated(mappingA, mappingB) { -- var cmp = mappingA.generatedLine - mappingB.generatedLine; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.generatedColumn - mappingB.generatedColumn; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = strcmp(mappingA.source, mappingB.source); -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.originalLine - mappingB.originalLine; -- if (cmp !== 0) { -- return cmp; -- } -- -- cmp = mappingA.originalColumn - mappingB.originalColumn; -- if (cmp !== 0) { -- return cmp; -- } -- -- return strcmp(mappingA.name, mappingB.name); -- } -- exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; -- } -- -- --/***/ }, --/* 5 */ --/***/ function(module, exports, __webpack_require__) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- var util = __webpack_require__(4); -- -- /** -- * A data structure which is a combination of an array and a set. Adding a new -- * member is O(1), testing for membership is O(1), and finding the index of an -- * element is O(1). Removing elements from the set is not supported. Only -- * strings are supported for membership. -- */ -- function ArraySet() { -- this._array = []; -- this._set = {}; -- } -- -- /** -- * Static method for creating ArraySet instances from an existing array. -- */ -- ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { -- var set = new ArraySet(); -- for (var i = 0, len = aArray.length; i < len; i++) { -- set.add(aArray[i], aAllowDuplicates); -- } -- return set; -- }; -- -- /** -- * Return how many unique items are in this ArraySet. If duplicates have been -- * added, than those do not count towards the size. -- * -- * @returns Number -- */ -- ArraySet.prototype.size = function ArraySet_size() { -- return Object.getOwnPropertyNames(this._set).length; -- }; -- -- /** -- * Add the given string to this set. -- * -- * @param String aStr -- */ -- ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { -- var sStr = util.toSetString(aStr); -- var isDuplicate = this._set.hasOwnProperty(sStr); -- var idx = this._array.length; -- if (!isDuplicate || aAllowDuplicates) { -- this._array.push(aStr); -- } -- if (!isDuplicate) { -- this._set[sStr] = idx; -- } -- }; -- -- /** -- * Is the given string a member of this set? -- * -- * @param String aStr -- */ -- ArraySet.prototype.has = function ArraySet_has(aStr) { -- var sStr = util.toSetString(aStr); -- return this._set.hasOwnProperty(sStr); -- }; -- -- /** -- * What is the index of the given string in the array? -- * -- * @param String aStr -- */ -- ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { -- var sStr = util.toSetString(aStr); -- if (this._set.hasOwnProperty(sStr)) { -- return this._set[sStr]; -- } -- throw new Error('"' + aStr + '" is not in the set.'); -- }; -- -- /** -- * What is the element at the given index? -- * -- * @param Number aIdx -- */ -- ArraySet.prototype.at = function ArraySet_at(aIdx) { -- if (aIdx >= 0 && aIdx < this._array.length) { -- return this._array[aIdx]; -- } -- throw new Error('No element indexed by ' + aIdx); -- }; -- -- /** -- * Returns the array representation of this set (which has the proper indices -- * indicated by indexOf). Note that this is a copy of the internal array used -- * for storing the members so that no one can mess with internal state. -- */ -- ArraySet.prototype.toArray = function ArraySet_toArray() { -- return this._array.slice(); -- }; -- -- exports.ArraySet = ArraySet; -- } -- -- --/***/ }, --/* 6 */ --/***/ function(module, exports, __webpack_require__) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2014 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- var util = __webpack_require__(4); -- -- /** -- * Determine whether mappingB is after mappingA with respect to generated -- * position. -- */ -- function generatedPositionAfter(mappingA, mappingB) { -- // Optimized for most common case -- var lineA = mappingA.generatedLine; -- var lineB = mappingB.generatedLine; -- var columnA = mappingA.generatedColumn; -- var columnB = mappingB.generatedColumn; -- return lineB > lineA || lineB == lineA && columnB >= columnA || -- util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; -- } -- -- /** -- * A data structure to provide a sorted view of accumulated mappings in a -- * performance conscious manner. It trades a neglibable overhead in general -- * case for a large speedup in case of mappings being added in order. -- */ -- function MappingList() { -- this._array = []; -- this._sorted = true; -- // Serves as infimum -- this._last = {generatedLine: -1, generatedColumn: 0}; -- } -- -- /** -- * Iterate through internal items. This method takes the same arguments that -- * `Array.prototype.forEach` takes. -- * -- * NOTE: The order of the mappings is NOT guaranteed. -- */ -- MappingList.prototype.unsortedForEach = -- function MappingList_forEach(aCallback, aThisArg) { -- this._array.forEach(aCallback, aThisArg); -- }; -- -- /** -- * Add the given source mapping. -- * -- * @param Object aMapping -- */ -- MappingList.prototype.add = function MappingList_add(aMapping) { -- if (generatedPositionAfter(this._last, aMapping)) { -- this._last = aMapping; -- this._array.push(aMapping); -- } else { -- this._sorted = false; -- this._array.push(aMapping); -- } -- }; -- -- /** -- * Returns the flat, sorted array of mappings. The mappings are sorted by -- * generated position. -- * -- * WARNING: This method returns internal data without copying, for -- * performance. The return value must NOT be mutated, and should be treated as -- * an immutable borrow. If you want to take ownership, you must make your own -- * copy. -- */ -- MappingList.prototype.toArray = function MappingList_toArray() { -- if (!this._sorted) { -- this._array.sort(util.compareByGeneratedPositionsInflated); -- this._sorted = true; -- } -- return this._array; -- }; -- -- exports.MappingList = MappingList; -- } -- -- --/***/ }, --/* 7 */ --/***/ function(module, exports, __webpack_require__) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- var util = __webpack_require__(4); -- var binarySearch = __webpack_require__(8); -- var ArraySet = __webpack_require__(5).ArraySet; -- var base64VLQ = __webpack_require__(2); -- var quickSort = __webpack_require__(9).quickSort; -- -- function SourceMapConsumer(aSourceMap) { -- var sourceMap = aSourceMap; -- if (typeof aSourceMap === 'string') { -- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); -- } -- -- return sourceMap.sections != null -- ? new IndexedSourceMapConsumer(sourceMap) -- : new BasicSourceMapConsumer(sourceMap); -- } -- -- SourceMapConsumer.fromSourceMap = function(aSourceMap) { -- return BasicSourceMapConsumer.fromSourceMap(aSourceMap); -- } -- -- /** -- * The version of the source mapping spec that we are consuming. -- */ -- SourceMapConsumer.prototype._version = 3; -- -- // `__generatedMappings` and `__originalMappings` are arrays that hold the -- // parsed mapping coordinates from the source map's "mappings" attribute. They -- // are lazily instantiated, accessed via the `_generatedMappings` and -- // `_originalMappings` getters respectively, and we only parse the mappings -- // and create these arrays once queried for a source location. We jump through -- // these hoops because there can be many thousands of mappings, and parsing -- // them is expensive, so we only want to do it if we must. -- // -- // Each object in the arrays is of the form: -- // -- // { -- // generatedLine: The line number in the generated code, -- // generatedColumn: The column number in the generated code, -- // source: The path to the original source file that generated this -- // chunk of code, -- // originalLine: The line number in the original source that -- // corresponds to this chunk of generated code, -- // originalColumn: The column number in the original source that -- // corresponds to this chunk of generated code, -- // name: The name of the original symbol which generated this chunk of -- // code. -- // } -- // -- // All properties except for `generatedLine` and `generatedColumn` can be -- // `null`. -- // -- // `_generatedMappings` is ordered by the generated positions. -- // -- // `_originalMappings` is ordered by the original positions. -- -- SourceMapConsumer.prototype.__generatedMappings = null; -- Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { -- get: function () { -- if (!this.__generatedMappings) { -- this._parseMappings(this._mappings, this.sourceRoot); -- } -- -- return this.__generatedMappings; -- } -- }); -- -- SourceMapConsumer.prototype.__originalMappings = null; -- Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { -- get: function () { -- if (!this.__originalMappings) { -- this._parseMappings(this._mappings, this.sourceRoot); -- } -- -- return this.__originalMappings; -- } -- }); -- -- SourceMapConsumer.prototype._charIsMappingSeparator = -- function SourceMapConsumer_charIsMappingSeparator(aStr, index) { -- var c = aStr.charAt(index); -- return c === ";" || c === ","; -- }; -- -- /** -- * Parse the mappings in a string in to a data structure which we can easily -- * query (the ordered arrays in the `this.__generatedMappings` and -- * `this.__originalMappings` properties). -- */ -- SourceMapConsumer.prototype._parseMappings = -- function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { -- throw new Error("Subclasses must implement _parseMappings"); -- }; -- -- SourceMapConsumer.GENERATED_ORDER = 1; -- SourceMapConsumer.ORIGINAL_ORDER = 2; -- -- SourceMapConsumer.GREATEST_LOWER_BOUND = 1; -- SourceMapConsumer.LEAST_UPPER_BOUND = 2; -- -- /** -- * Iterate over each mapping between an original source/line/column and a -- * generated line/column in this source map. -- * -- * @param Function aCallback -- * The function that is called with each mapping. -- * @param Object aContext -- * Optional. If specified, this object will be the value of `this` every -- * time that `aCallback` is called. -- * @param aOrder -- * Either `SourceMapConsumer.GENERATED_ORDER` or -- * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to -- * iterate over the mappings sorted by the generated file's line/column -- * order or the original's source/line/column order, respectively. Defaults to -- * `SourceMapConsumer.GENERATED_ORDER`. -- */ -- SourceMapConsumer.prototype.eachMapping = -- function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { -- var context = aContext || null; -- var order = aOrder || SourceMapConsumer.GENERATED_ORDER; -- -- var mappings; -- switch (order) { -- case SourceMapConsumer.GENERATED_ORDER: -- mappings = this._generatedMappings; -- break; -- case SourceMapConsumer.ORIGINAL_ORDER: -- mappings = this._originalMappings; -- break; -- default: -- throw new Error("Unknown order of iteration."); -- } -- -- var sourceRoot = this.sourceRoot; -- mappings.map(function (mapping) { -- var source = mapping.source === null ? null : this._sources.at(mapping.source); -- if (source != null && sourceRoot != null) { -- source = util.join(sourceRoot, source); -- } -- return { -- source: source, -- generatedLine: mapping.generatedLine, -- generatedColumn: mapping.generatedColumn, -- originalLine: mapping.originalLine, -- originalColumn: mapping.originalColumn, -- name: mapping.name === null ? null : this._names.at(mapping.name) -- }; -- }, this).forEach(aCallback, context); -- }; -- -- /** -- * Returns all generated line and column information for the original source, -- * line, and column provided. If no column is provided, returns all mappings -- * corresponding to a either the line we are searching for or the next -- * closest line that has any mappings. Otherwise, returns all mappings -- * corresponding to the given line and either the column we are searching for -- * or the next closest column that has any offsets. -- * -- * The only argument is an object with the following properties: -- * -- * - source: The filename of the original source. -- * - line: The line number in the original source. -- * - column: Optional. the column number in the original source. -- * -- * and an array of objects is returned, each with the following properties: -- * -- * - line: The line number in the generated source, or null. -- * - column: The column number in the generated source, or null. -- */ -- SourceMapConsumer.prototype.allGeneratedPositionsFor = -- function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { -- var line = util.getArg(aArgs, 'line'); -- -- // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping -- // returns the index of the closest mapping less than the needle. By -- // setting needle.originalColumn to 0, we thus find the last mapping for -- // the given line, provided such a mapping exists. -- var needle = { -- source: util.getArg(aArgs, 'source'), -- originalLine: line, -- originalColumn: util.getArg(aArgs, 'column', 0) -- }; -- -- if (this.sourceRoot != null) { -- needle.source = util.relative(this.sourceRoot, needle.source); -- } -- if (!this._sources.has(needle.source)) { -- return []; -- } -- needle.source = this._sources.indexOf(needle.source); -- -- var mappings = []; -- -- var index = this._findMapping(needle, -- this._originalMappings, -- "originalLine", -- "originalColumn", -- util.compareByOriginalPositions, -- binarySearch.LEAST_UPPER_BOUND); -- if (index >= 0) { -- var mapping = this._originalMappings[index]; -- -- if (aArgs.column === undefined) { -- var originalLine = mapping.originalLine; -- -- // Iterate until either we run out of mappings, or we run into -- // a mapping for a different line than the one we found. Since -- // mappings are sorted, this is guaranteed to find all mappings for -- // the line we found. -- while (mapping && mapping.originalLine === originalLine) { -- mappings.push({ -- line: util.getArg(mapping, 'generatedLine', null), -- column: util.getArg(mapping, 'generatedColumn', null), -- lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) -- }); -- -- mapping = this._originalMappings[++index]; -- } -- } else { -- var originalColumn = mapping.originalColumn; -- -- // Iterate until either we run out of mappings, or we run into -- // a mapping for a different line than the one we were searching for. -- // Since mappings are sorted, this is guaranteed to find all mappings for -- // the line we are searching for. -- while (mapping && -- mapping.originalLine === line && -- mapping.originalColumn == originalColumn) { -- mappings.push({ -- line: util.getArg(mapping, 'generatedLine', null), -- column: util.getArg(mapping, 'generatedColumn', null), -- lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) -- }); -- -- mapping = this._originalMappings[++index]; -- } -- } -- } -- -- return mappings; -- }; -- -- exports.SourceMapConsumer = SourceMapConsumer; -- -- /** -- * A BasicSourceMapConsumer instance represents a parsed source map which we can -- * query for information about the original file positions by giving it a file -- * position in the generated source. -- * -- * The only parameter is the raw source map (either as a JSON string, or -- * already parsed to an object). According to the spec, source maps have the -- * following attributes: -- * -- * - version: Which version of the source map spec this map is following. -- * - sources: An array of URLs to the original source files. -- * - names: An array of identifiers which can be referrenced by individual mappings. -- * - sourceRoot: Optional. The URL root from which all sources are relative. -- * - sourcesContent: Optional. An array of contents of the original source files. -- * - mappings: A string of base64 VLQs which contain the actual mappings. -- * - file: Optional. The generated file this source map is associated with. -- * -- * Here is an example source map, taken from the source map spec[0]: -- * -- * { -- * version : 3, -- * file: "out.js", -- * sourceRoot : "", -- * sources: ["foo.js", "bar.js"], -- * names: ["src", "maps", "are", "fun"], -- * mappings: "AA,AB;;ABCDE;" -- * } -- * -- * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# -- */ -- function BasicSourceMapConsumer(aSourceMap) { -- var sourceMap = aSourceMap; -- if (typeof aSourceMap === 'string') { -- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); -- } -- -- var version = util.getArg(sourceMap, 'version'); -- var sources = util.getArg(sourceMap, 'sources'); -- // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which -- // requires the array) to play nice here. -- var names = util.getArg(sourceMap, 'names', []); -- var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); -- var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); -- var mappings = util.getArg(sourceMap, 'mappings'); -- var file = util.getArg(sourceMap, 'file', null); -- -- // Once again, Sass deviates from the spec and supplies the version as a -- // string rather than a number, so we use loose equality checking here. -- if (version != this._version) { -- throw new Error('Unsupported version: ' + version); -- } -- -- sources = sources -- // Some source maps produce relative source paths like "./foo.js" instead of -- // "foo.js". Normalize these first so that future comparisons will succeed. -- // See bugzil.la/1090768. -- .map(util.normalize) -- // Always ensure that absolute sources are internally stored relative to -- // the source root, if the source root is absolute. Not doing this would -- // be particularly problematic when the source root is a prefix of the -- // source (valid, but why??). See github issue #199 and bugzil.la/1188982. -- .map(function (source) { -- return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) -- ? util.relative(sourceRoot, source) -- : source; -- }); -- -- // Pass `true` below to allow duplicate names and sources. While source maps -- // are intended to be compressed and deduplicated, the TypeScript compiler -- // sometimes generates source maps with duplicates in them. See Github issue -- // #72 and bugzil.la/889492. -- this._names = ArraySet.fromArray(names, true); -- this._sources = ArraySet.fromArray(sources, true); -- -- this.sourceRoot = sourceRoot; -- this.sourcesContent = sourcesContent; -- this._mappings = mappings; -- this.file = file; -- } -- -- BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -- BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; -- -- /** -- * Create a BasicSourceMapConsumer from a SourceMapGenerator. -- * -- * @param SourceMapGenerator aSourceMap -- * The source map that will be consumed. -- * @returns BasicSourceMapConsumer -- */ -- BasicSourceMapConsumer.fromSourceMap = -- function SourceMapConsumer_fromSourceMap(aSourceMap) { -- var smc = Object.create(BasicSourceMapConsumer.prototype); -- -- var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); -- var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); -- smc.sourceRoot = aSourceMap._sourceRoot; -- smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), -- smc.sourceRoot); -- smc.file = aSourceMap._file; -- -- // Because we are modifying the entries (by converting string sources and -- // names to indices into the sources and names ArraySets), we have to make -- // a copy of the entry or else bad things happen. Shared mutable state -- // strikes again! See github issue #191. -- -- var generatedMappings = aSourceMap._mappings.toArray().slice(); -- var destGeneratedMappings = smc.__generatedMappings = []; -- var destOriginalMappings = smc.__originalMappings = []; -- -- for (var i = 0, length = generatedMappings.length; i < length; i++) { -- var srcMapping = generatedMappings[i]; -- var destMapping = new Mapping; -- destMapping.generatedLine = srcMapping.generatedLine; -- destMapping.generatedColumn = srcMapping.generatedColumn; -- -- if (srcMapping.source) { -- destMapping.source = sources.indexOf(srcMapping.source); -- destMapping.originalLine = srcMapping.originalLine; -- destMapping.originalColumn = srcMapping.originalColumn; -- -- if (srcMapping.name) { -- destMapping.name = names.indexOf(srcMapping.name); -- } -- -- destOriginalMappings.push(destMapping); -- } -- -- destGeneratedMappings.push(destMapping); -- } -- -- quickSort(smc.__originalMappings, util.compareByOriginalPositions); -- -- return smc; -- }; -- -- /** -- * The version of the source mapping spec that we are consuming. -- */ -- BasicSourceMapConsumer.prototype._version = 3; -- -- /** -- * The list of original sources. -- */ -- Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { -- get: function () { -- return this._sources.toArray().map(function (s) { -- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; -- }, this); -- } -- }); -- -- /** -- * Provide the JIT with a nice shape / hidden class. -- */ -- function Mapping() { -- this.generatedLine = 0; -- this.generatedColumn = 0; -- this.source = null; -- this.originalLine = null; -- this.originalColumn = null; -- this.name = null; -- } -- -- /** -- * Parse the mappings in a string in to a data structure which we can easily -- * query (the ordered arrays in the `this.__generatedMappings` and -- * `this.__originalMappings` properties). -- */ -- BasicSourceMapConsumer.prototype._parseMappings = -- function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { -- var generatedLine = 1; -- var previousGeneratedColumn = 0; -- var previousOriginalLine = 0; -- var previousOriginalColumn = 0; -- var previousSource = 0; -- var previousName = 0; -- var length = aStr.length; -- var index = 0; -- var cachedSegments = {}; -- var temp = {}; -- var originalMappings = []; -- var generatedMappings = []; -- var mapping, str, segment, end, value; -- -- while (index < length) { -- if (aStr.charAt(index) === ';') { -- generatedLine++; -- index++; -- previousGeneratedColumn = 0; -- } -- else if (aStr.charAt(index) === ',') { -- index++; -- } -- else { -- mapping = new Mapping(); -- mapping.generatedLine = generatedLine; -- -- // Because each offset is encoded relative to the previous one, -- // many segments often have the same encoding. We can exploit this -- // fact by caching the parsed variable length fields of each segment, -- // allowing us to avoid a second parse if we encounter the same -- // segment again. -- for (end = index; end < length; end++) { -- if (this._charIsMappingSeparator(aStr, end)) { -- break; -- } -- } -- str = aStr.slice(index, end); -- -- segment = cachedSegments[str]; -- if (segment) { -- index += str.length; -- } else { -- segment = []; -- while (index < end) { -- base64VLQ.decode(aStr, index, temp); -- value = temp.value; -- index = temp.rest; -- segment.push(value); -- } -- -- if (segment.length === 2) { -- throw new Error('Found a source, but no line and column'); -- } -- -- if (segment.length === 3) { -- throw new Error('Found a source and line, but no column'); -- } -- -- cachedSegments[str] = segment; -- } -- -- // Generated column. -- mapping.generatedColumn = previousGeneratedColumn + segment[0]; -- previousGeneratedColumn = mapping.generatedColumn; -- -- if (segment.length > 1) { -- // Original source. -- mapping.source = previousSource + segment[1]; -- previousSource += segment[1]; -- -- // Original line. -- mapping.originalLine = previousOriginalLine + segment[2]; -- previousOriginalLine = mapping.originalLine; -- // Lines are stored 0-based -- mapping.originalLine += 1; -- -- // Original column. -- mapping.originalColumn = previousOriginalColumn + segment[3]; -- previousOriginalColumn = mapping.originalColumn; -- -- if (segment.length > 4) { -- // Original name. -- mapping.name = previousName + segment[4]; -- previousName += segment[4]; -- } -- } -- -- generatedMappings.push(mapping); -- if (typeof mapping.originalLine === 'number') { -- originalMappings.push(mapping); -- } -- } -- } -- -- quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); -- this.__generatedMappings = generatedMappings; -- -- quickSort(originalMappings, util.compareByOriginalPositions); -- this.__originalMappings = originalMappings; -- }; -- -- /** -- * Find the mapping that best matches the hypothetical "needle" mapping that -- * we are searching for in the given "haystack" of mappings. -- */ -- BasicSourceMapConsumer.prototype._findMapping = -- function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, -- aColumnName, aComparator, aBias) { -- // To return the position we are searching for, we must first find the -- // mapping for the given position and then return the opposite position it -- // points to. Because the mappings are sorted, we can use binary search to -- // find the best mapping. -- -- if (aNeedle[aLineName] <= 0) { -- throw new TypeError('Line must be greater than or equal to 1, got ' -- + aNeedle[aLineName]); -- } -- if (aNeedle[aColumnName] < 0) { -- throw new TypeError('Column must be greater than or equal to 0, got ' -- + aNeedle[aColumnName]); -- } -- -- return binarySearch.search(aNeedle, aMappings, aComparator, aBias); -- }; -- -- /** -- * Compute the last column for each generated mapping. The last column is -- * inclusive. -- */ -- BasicSourceMapConsumer.prototype.computeColumnSpans = -- function SourceMapConsumer_computeColumnSpans() { -- for (var index = 0; index < this._generatedMappings.length; ++index) { -- var mapping = this._generatedMappings[index]; -- -- // Mappings do not contain a field for the last generated columnt. We -- // can come up with an optimistic estimate, however, by assuming that -- // mappings are contiguous (i.e. given two consecutive mappings, the -- // first mapping ends where the second one starts). -- if (index + 1 < this._generatedMappings.length) { -- var nextMapping = this._generatedMappings[index + 1]; -- -- if (mapping.generatedLine === nextMapping.generatedLine) { -- mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; -- continue; -- } -- } -- -- // The last mapping for each line spans the entire line. -- mapping.lastGeneratedColumn = Infinity; -- } -- }; -- -- /** -- * Returns the original source, line, and column information for the generated -- * source's line and column positions provided. The only argument is an object -- * with the following properties: -- * -- * - line: The line number in the generated source. -- * - column: The column number in the generated source. -- * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or -- * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the -- * closest element that is smaller than or greater than the one we are -- * searching for, respectively, if the exact element cannot be found. -- * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. -- * -- * and an object is returned with the following properties: -- * -- * - source: The original source file, or null. -- * - line: The line number in the original source, or null. -- * - column: The column number in the original source, or null. -- * - name: The original identifier, or null. -- */ -- BasicSourceMapConsumer.prototype.originalPositionFor = -- function SourceMapConsumer_originalPositionFor(aArgs) { -- var needle = { -- generatedLine: util.getArg(aArgs, 'line'), -- generatedColumn: util.getArg(aArgs, 'column') -- }; -- -- var index = this._findMapping( -- needle, -- this._generatedMappings, -- "generatedLine", -- "generatedColumn", -- util.compareByGeneratedPositionsDeflated, -- util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) -- ); -- -- if (index >= 0) { -- var mapping = this._generatedMappings[index]; -- -- if (mapping.generatedLine === needle.generatedLine) { -- var source = util.getArg(mapping, 'source', null); -- if (source !== null) { -- source = this._sources.at(source); -- if (this.sourceRoot != null) { -- source = util.join(this.sourceRoot, source); -- } -- } -- var name = util.getArg(mapping, 'name', null); -- if (name !== null) { -- name = this._names.at(name); -- } -- return { -- source: source, -- line: util.getArg(mapping, 'originalLine', null), -- column: util.getArg(mapping, 'originalColumn', null), -- name: name -- }; -- } -- } -- -- return { -- source: null, -- line: null, -- column: null, -- name: null -- }; -- }; -- -- /** -- * Return true if we have the source content for every source in the source -- * map, false otherwise. -- */ -- BasicSourceMapConsumer.prototype.hasContentsOfAllSources = -- function BasicSourceMapConsumer_hasContentsOfAllSources() { -- if (!this.sourcesContent) { -- return false; -- } -- return this.sourcesContent.length >= this._sources.size() && -- !this.sourcesContent.some(function (sc) { return sc == null; }); -- }; -- -- /** -- * Returns the original source content. The only argument is the url of the -- * original source file. Returns null if no original source content is -- * available. -- */ -- BasicSourceMapConsumer.prototype.sourceContentFor = -- function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { -- if (!this.sourcesContent) { -- return null; -- } -- -- if (this.sourceRoot != null) { -- aSource = util.relative(this.sourceRoot, aSource); -- } -- -- if (this._sources.has(aSource)) { -- return this.sourcesContent[this._sources.indexOf(aSource)]; -- } -- -- var url; -- if (this.sourceRoot != null -- && (url = util.urlParse(this.sourceRoot))) { -- // XXX: file:// URIs and absolute paths lead to unexpected behavior for -- // many users. We can help them out when they expect file:// URIs to -- // behave like it would if they were running a local HTTP server. See -- // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. -- var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); -- if (url.scheme == "file" -- && this._sources.has(fileUriAbsPath)) { -- return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] -- } -- -- if ((!url.path || url.path == "/") -- && this._sources.has("/" + aSource)) { -- return this.sourcesContent[this._sources.indexOf("/" + aSource)]; -- } -- } -- -- // This function is used recursively from -- // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we -- // don't want to throw if we can't find the source - we just want to -- // return null, so we provide a flag to exit gracefully. -- if (nullOnMissing) { -- return null; -- } -- else { -- throw new Error('"' + aSource + '" is not in the SourceMap.'); -- } -- }; -- -- /** -- * Returns the generated line and column information for the original source, -- * line, and column positions provided. The only argument is an object with -- * the following properties: -- * -- * - source: The filename of the original source. -- * - line: The line number in the original source. -- * - column: The column number in the original source. -- * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or -- * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the -- * closest element that is smaller than or greater than the one we are -- * searching for, respectively, if the exact element cannot be found. -- * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. -- * -- * and an object is returned with the following properties: -- * -- * - line: The line number in the generated source, or null. -- * - column: The column number in the generated source, or null. -- */ -- BasicSourceMapConsumer.prototype.generatedPositionFor = -- function SourceMapConsumer_generatedPositionFor(aArgs) { -- var source = util.getArg(aArgs, 'source'); -- if (this.sourceRoot != null) { -- source = util.relative(this.sourceRoot, source); -- } -- if (!this._sources.has(source)) { -- return { -- line: null, -- column: null, -- lastColumn: null -- }; -- } -- source = this._sources.indexOf(source); -- -- var needle = { -- source: source, -- originalLine: util.getArg(aArgs, 'line'), -- originalColumn: util.getArg(aArgs, 'column') -- }; -- -- var index = this._findMapping( -- needle, -- this._originalMappings, -- "originalLine", -- "originalColumn", -- util.compareByOriginalPositions, -- util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) -- ); -- -- if (index >= 0) { -- var mapping = this._originalMappings[index]; -- -- if (mapping.source === needle.source) { -- return { -- line: util.getArg(mapping, 'generatedLine', null), -- column: util.getArg(mapping, 'generatedColumn', null), -- lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) -- }; -- } -- } -- -- return { -- line: null, -- column: null, -- lastColumn: null -- }; -- }; -- -- exports.BasicSourceMapConsumer = BasicSourceMapConsumer; -- -- /** -- * An IndexedSourceMapConsumer instance represents a parsed source map which -- * we can query for information. It differs from BasicSourceMapConsumer in -- * that it takes "indexed" source maps (i.e. ones with a "sections" field) as -- * input. -- * -- * The only parameter is a raw source map (either as a JSON string, or already -- * parsed to an object). According to the spec for indexed source maps, they -- * have the following attributes: -- * -- * - version: Which version of the source map spec this map is following. -- * - file: Optional. The generated file this source map is associated with. -- * - sections: A list of section definitions. -- * -- * Each value under the "sections" field has two fields: -- * - offset: The offset into the original specified at which this section -- * begins to apply, defined as an object with a "line" and "column" -- * field. -- * - map: A source map definition. This source map could also be indexed, -- * but doesn't have to be. -- * -- * Instead of the "map" field, it's also possible to have a "url" field -- * specifying a URL to retrieve a source map from, but that's currently -- * unsupported. -- * -- * Here's an example source map, taken from the source map spec[0], but -- * modified to omit a section which uses the "url" field. -- * -- * { -- * version : 3, -- * file: "app.js", -- * sections: [{ -- * offset: {line:100, column:10}, -- * map: { -- * version : 3, -- * file: "section.js", -- * sources: ["foo.js", "bar.js"], -- * names: ["src", "maps", "are", "fun"], -- * mappings: "AAAA,E;;ABCDE;" -- * } -- * }], -- * } -- * -- * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt -- */ -- function IndexedSourceMapConsumer(aSourceMap) { -- var sourceMap = aSourceMap; -- if (typeof aSourceMap === 'string') { -- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); -- } -- -- var version = util.getArg(sourceMap, 'version'); -- var sections = util.getArg(sourceMap, 'sections'); -- -- if (version != this._version) { -- throw new Error('Unsupported version: ' + version); -- } -- -- this._sources = new ArraySet(); -- this._names = new ArraySet(); -- -- var lastOffset = { -- line: -1, -- column: 0 -- }; -- this._sections = sections.map(function (s) { -- if (s.url) { -- // The url field will require support for asynchronicity. -- // See https://github.com/mozilla/source-map/issues/16 -- throw new Error('Support for url field in sections not implemented.'); -- } -- var offset = util.getArg(s, 'offset'); -- var offsetLine = util.getArg(offset, 'line'); -- var offsetColumn = util.getArg(offset, 'column'); -- -- if (offsetLine < lastOffset.line || -- (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { -- throw new Error('Section offsets must be ordered and non-overlapping.'); -- } -- lastOffset = offset; -- -- return { -- generatedOffset: { -- // The offset fields are 0-based, but we use 1-based indices when -- // encoding/decoding from VLQ. -- generatedLine: offsetLine + 1, -- generatedColumn: offsetColumn + 1 -- }, -- consumer: new SourceMapConsumer(util.getArg(s, 'map')) -- } -- }); -- } -- -- IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -- IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; -- -- /** -- * The version of the source mapping spec that we are consuming. -- */ -- IndexedSourceMapConsumer.prototype._version = 3; -- -- /** -- * The list of original sources. -- */ -- Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { -- get: function () { -- var sources = []; -- for (var i = 0; i < this._sections.length; i++) { -- for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { -- sources.push(this._sections[i].consumer.sources[j]); -- } -- } -- return sources; -- } -- }); -- -- /** -- * Returns the original source, line, and column information for the generated -- * source's line and column positions provided. The only argument is an object -- * with the following properties: -- * -- * - line: The line number in the generated source. -- * - column: The column number in the generated source. -- * -- * and an object is returned with the following properties: -- * -- * - source: The original source file, or null. -- * - line: The line number in the original source, or null. -- * - column: The column number in the original source, or null. -- * - name: The original identifier, or null. -- */ -- IndexedSourceMapConsumer.prototype.originalPositionFor = -- function IndexedSourceMapConsumer_originalPositionFor(aArgs) { -- var needle = { -- generatedLine: util.getArg(aArgs, 'line'), -- generatedColumn: util.getArg(aArgs, 'column') -- }; -- -- // Find the section containing the generated position we're trying to map -- // to an original position. -- var sectionIndex = binarySearch.search(needle, this._sections, -- function(needle, section) { -- var cmp = needle.generatedLine - section.generatedOffset.generatedLine; -- if (cmp) { -- return cmp; -- } -- -- return (needle.generatedColumn - -- section.generatedOffset.generatedColumn); -- }); -- var section = this._sections[sectionIndex]; -- -- if (!section) { -- return { -- source: null, -- line: null, -- column: null, -- name: null -- }; -- } -- -- return section.consumer.originalPositionFor({ -- line: needle.generatedLine - -- (section.generatedOffset.generatedLine - 1), -- column: needle.generatedColumn - -- (section.generatedOffset.generatedLine === needle.generatedLine -- ? section.generatedOffset.generatedColumn - 1 -- : 0), -- bias: aArgs.bias -- }); -- }; -- -- /** -- * Return true if we have the source content for every source in the source -- * map, false otherwise. -- */ -- IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = -- function IndexedSourceMapConsumer_hasContentsOfAllSources() { -- return this._sections.every(function (s) { -- return s.consumer.hasContentsOfAllSources(); -- }); -- }; -- -- /** -- * Returns the original source content. The only argument is the url of the -- * original source file. Returns null if no original source content is -- * available. -- */ -- IndexedSourceMapConsumer.prototype.sourceContentFor = -- function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { -- for (var i = 0; i < this._sections.length; i++) { -- var section = this._sections[i]; -- -- var content = section.consumer.sourceContentFor(aSource, true); -- if (content) { -- return content; -- } -- } -- if (nullOnMissing) { -- return null; -- } -- else { -- throw new Error('"' + aSource + '" is not in the SourceMap.'); -- } -- }; -- -- /** -- * Returns the generated line and column information for the original source, -- * line, and column positions provided. The only argument is an object with -- * the following properties: -- * -- * - source: The filename of the original source. -- * - line: The line number in the original source. -- * - column: The column number in the original source. -- * -- * and an object is returned with the following properties: -- * -- * - line: The line number in the generated source, or null. -- * - column: The column number in the generated source, or null. -- */ -- IndexedSourceMapConsumer.prototype.generatedPositionFor = -- function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { -- for (var i = 0; i < this._sections.length; i++) { -- var section = this._sections[i]; -- -- // Only consider this section if the requested source is in the list of -- // sources of the consumer. -- if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { -- continue; -- } -- var generatedPosition = section.consumer.generatedPositionFor(aArgs); -- if (generatedPosition) { -- var ret = { -- line: generatedPosition.line + -- (section.generatedOffset.generatedLine - 1), -- column: generatedPosition.column + -- (section.generatedOffset.generatedLine === generatedPosition.line -- ? section.generatedOffset.generatedColumn - 1 -- : 0) -- }; -- return ret; -- } -- } -- -- return { -- line: null, -- column: null -- }; -- }; -- -- /** -- * Parse the mappings in a string in to a data structure which we can easily -- * query (the ordered arrays in the `this.__generatedMappings` and -- * `this.__originalMappings` properties). -- */ -- IndexedSourceMapConsumer.prototype._parseMappings = -- function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { -- this.__generatedMappings = []; -- this.__originalMappings = []; -- for (var i = 0; i < this._sections.length; i++) { -- var section = this._sections[i]; -- var sectionMappings = section.consumer._generatedMappings; -- for (var j = 0; j < sectionMappings.length; j++) { -- var mapping = sectionMappings[j]; -- -- var source = section.consumer._sources.at(mapping.source); -- if (section.consumer.sourceRoot !== null) { -- source = util.join(section.consumer.sourceRoot, source); -- } -- this._sources.add(source); -- source = this._sources.indexOf(source); -- -- var name = section.consumer._names.at(mapping.name); -- this._names.add(name); -- name = this._names.indexOf(name); -- -- // The mappings coming from the consumer for the section have -- // generated positions relative to the start of the section, so we -- // need to offset them to be relative to the start of the concatenated -- // generated file. -- var adjustedMapping = { -- source: source, -- generatedLine: mapping.generatedLine + -- (section.generatedOffset.generatedLine - 1), -- generatedColumn: mapping.generatedColumn + -- (section.generatedOffset.generatedLine === mapping.generatedLine -- ? section.generatedOffset.generatedColumn - 1 -- : 0), -- originalLine: mapping.originalLine, -- originalColumn: mapping.originalColumn, -- name: name -- }; -- -- this.__generatedMappings.push(adjustedMapping); -- if (typeof adjustedMapping.originalLine === 'number') { -- this.__originalMappings.push(adjustedMapping); -- } -- } -- } -- -- quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); -- quickSort(this.__originalMappings, util.compareByOriginalPositions); -- }; -- -- exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; -- } -- -- --/***/ }, --/* 8 */ --/***/ function(module, exports) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- exports.GREATEST_LOWER_BOUND = 1; -- exports.LEAST_UPPER_BOUND = 2; -- -- /** -- * Recursive implementation of binary search. -- * -- * @param aLow Indices here and lower do not contain the needle. -- * @param aHigh Indices here and higher do not contain the needle. -- * @param aNeedle The element being searched for. -- * @param aHaystack The non-empty array being searched. -- * @param aCompare Function which takes two elements and returns -1, 0, or 1. -- * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or -- * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the -- * closest element that is smaller than or greater than the one we are -- * searching for, respectively, if the exact element cannot be found. -- */ -- function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { -- // This function terminates when one of the following is true: -- // -- // 1. We find the exact element we are looking for. -- // -- // 2. We did not find the exact element, but we can return the index of -- // the next-closest element. -- // -- // 3. We did not find the exact element, and there is no next-closest -- // element than the one we are searching for, so we return -1. -- var mid = Math.floor((aHigh - aLow) / 2) + aLow; -- var cmp = aCompare(aNeedle, aHaystack[mid], true); -- if (cmp === 0) { -- // Found the element we are looking for. -- return mid; -- } -- else if (cmp > 0) { -- // Our needle is greater than aHaystack[mid]. -- if (aHigh - mid > 1) { -- // The element is in the upper half. -- return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); -- } -- -- // The exact needle element was not found in this haystack. Determine if -- // we are in termination case (3) or (2) and return the appropriate thing. -- if (aBias == exports.LEAST_UPPER_BOUND) { -- return aHigh < aHaystack.length ? aHigh : -1; -- } else { -- return mid; -- } -- } -- else { -- // Our needle is less than aHaystack[mid]. -- if (mid - aLow > 1) { -- // The element is in the lower half. -- return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); -- } -- -- // we are in termination case (3) or (2) and return the appropriate thing. -- if (aBias == exports.LEAST_UPPER_BOUND) { -- return mid; -- } else { -- return aLow < 0 ? -1 : aLow; -- } -- } -- } -- -- /** -- * This is an implementation of binary search which will always try and return -- * the index of the closest element if there is no exact hit. This is because -- * mappings between original and generated line/col pairs are single points, -- * and there is an implicit region between each of them, so a miss just means -- * that you aren't on the very start of a region. -- * -- * @param aNeedle The element you are looking for. -- * @param aHaystack The array that is being searched. -- * @param aCompare A function which takes the needle and an element in the -- * array and returns -1, 0, or 1 depending on whether the needle is less -- * than, equal to, or greater than the element, respectively. -- * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or -- * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the -- * closest element that is smaller than or greater than the one we are -- * searching for, respectively, if the exact element cannot be found. -- * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. -- */ -- exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { -- if (aHaystack.length === 0) { -- return -1; -- } -- -- var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, -- aCompare, aBias || exports.GREATEST_LOWER_BOUND); -- if (index < 0) { -- return -1; -- } -- -- // We have found either the exact element, or the next-closest element than -- // the one we are searching for. However, there may be more than one such -- // element. Make sure we always return the smallest of these. -- while (index - 1 >= 0) { -- if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { -- break; -- } -- --index; -- } -- -- return index; -- }; -- } -- -- --/***/ }, --/* 9 */ --/***/ function(module, exports) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- // It turns out that some (most?) JavaScript engines don't self-host -- // `Array.prototype.sort`. This makes sense because C++ will likely remain -- // faster than JS when doing raw CPU-intensive sorting. However, when using a -- // custom comparator function, calling back and forth between the VM's C++ and -- // JIT'd JS is rather slow *and* loses JIT type information, resulting in -- // worse generated code for the comparator function than would be optimal. In -- // fact, when sorting with a comparator, these costs outweigh the benefits of -- // sorting in C++. By using our own JS-implemented Quick Sort (below), we get -- // a ~3500ms mean speed-up in `bench/bench.html`. -- -- /** -- * Swap the elements indexed by `x` and `y` in the array `ary`. -- * -- * @param {Array} ary -- * The array. -- * @param {Number} x -- * The index of the first item. -- * @param {Number} y -- * The index of the second item. -- */ -- function swap(ary, x, y) { -- var temp = ary[x]; -- ary[x] = ary[y]; -- ary[y] = temp; -- } -- -- /** -- * Returns a random integer within the range `low .. high` inclusive. -- * -- * @param {Number} low -- * The lower bound on the range. -- * @param {Number} high -- * The upper bound on the range. -- */ -- function randomIntInRange(low, high) { -- return Math.round(low + (Math.random() * (high - low))); -- } -- -- /** -- * The Quick Sort algorithm. -- * -- * @param {Array} ary -- * An array to sort. -- * @param {function} comparator -- * Function to use to compare two items. -- * @param {Number} p -- * Start index of the array -- * @param {Number} r -- * End index of the array -- */ -- function doQuickSort(ary, comparator, p, r) { -- // If our lower bound is less than our upper bound, we (1) partition the -- // array into two pieces and (2) recurse on each half. If it is not, this is -- // the empty array and our base case. -- -- if (p < r) { -- // (1) Partitioning. -- // -- // The partitioning chooses a pivot between `p` and `r` and moves all -- // elements that are less than or equal to the pivot to the before it, and -- // all the elements that are greater than it after it. The effect is that -- // once partition is done, the pivot is in the exact place it will be when -- // the array is put in sorted order, and it will not need to be moved -- // again. This runs in O(n) time. -- -- // Always choose a random pivot so that an input array which is reverse -- // sorted does not cause O(n^2) running time. -- var pivotIndex = randomIntInRange(p, r); -- var i = p - 1; -- -- swap(ary, pivotIndex, r); -- var pivot = ary[r]; -- -- // Immediately after `j` is incremented in this loop, the following hold -- // true: -- // -- // * Every element in `ary[p .. i]` is less than or equal to the pivot. -- // -- // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. -- for (var j = p; j < r; j++) { -- if (comparator(ary[j], pivot) <= 0) { -- i += 1; -- swap(ary, i, j); -- } -- } -- -- swap(ary, i + 1, j); -- var q = i + 1; -- -- // (2) Recurse on each half. -- -- doQuickSort(ary, comparator, p, q - 1); -- doQuickSort(ary, comparator, q + 1, r); -- } -- } -- -- /** -- * Sort the given array in-place with the given comparator function. -- * -- * @param {Array} ary -- * An array to sort. -- * @param {function} comparator -- * Function to use to compare two items. -- */ -- exports.quickSort = function (ary, comparator) { -- doQuickSort(ary, comparator, 0, ary.length - 1); -- }; -- } -- -- --/***/ }, --/* 10 */ --/***/ function(module, exports, __webpack_require__) { -- -- /* -*- Mode: js; js-indent-level: 2; -*- */ -- /* -- * Copyright 2011 Mozilla Foundation and contributors -- * Licensed under the New BSD license. See LICENSE or: -- * http://opensource.org/licenses/BSD-3-Clause -- */ -- { -- var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; -- var util = __webpack_require__(4); -- -- // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other -- // operating systems these days (capturing the result). -- var REGEX_NEWLINE = /(\r?\n)/; -- -- // Newline character code for charCodeAt() comparisons -- var NEWLINE_CODE = 10; -- -- // Private symbol for identifying `SourceNode`s when multiple versions of -- // the source-map library are loaded. This MUST NOT CHANGE across -- // versions! -- var isSourceNode = "$$$isSourceNode$$$"; -- -- /** -- * SourceNodes provide a way to abstract over interpolating/concatenating -- * snippets of generated JavaScript source code while maintaining the line and -- * column information associated with the original source code. -- * -- * @param aLine The original line number. -- * @param aColumn The original column number. -- * @param aSource The original source's filename. -- * @param aChunks Optional. An array of strings which are snippets of -- * generated JS, or other SourceNodes. -- * @param aName The original identifier. -- */ -- function SourceNode(aLine, aColumn, aSource, aChunks, aName) { -- this.children = []; -- this.sourceContents = {}; -- this.line = aLine == null ? null : aLine; -- this.column = aColumn == null ? null : aColumn; -- this.source = aSource == null ? null : aSource; -- this.name = aName == null ? null : aName; -- this[isSourceNode] = true; -- if (aChunks != null) this.add(aChunks); -- } -- -- /** -- * Creates a SourceNode from generated code and a SourceMapConsumer. -- * -- * @param aGeneratedCode The generated code -- * @param aSourceMapConsumer The SourceMap for the generated code -- * @param aRelativePath Optional. The path that relative sources in the -- * SourceMapConsumer should be relative to. -- */ -- SourceNode.fromStringWithSourceMap = -- function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { -- // The SourceNode we want to fill with the generated code -- // and the SourceMap -- var node = new SourceNode(); -- -- // All even indices of this array are one line of the generated code, -- // while all odd indices are the newlines between two adjacent lines -- // (since `REGEX_NEWLINE` captures its match). -- // Processed fragments are removed from this array, by calling `shiftNextLine`. -- var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); -- var shiftNextLine = function() { -- var lineContents = remainingLines.shift(); -- // The last line of a file might not have a newline. -- var newLine = remainingLines.shift() || ""; -- return lineContents + newLine; -- }; -- -- // We need to remember the position of "remainingLines" -- var lastGeneratedLine = 1, lastGeneratedColumn = 0; -- -- // The generate SourceNodes we need a code range. -- // To extract it current and last mapping is used. -- // Here we store the last mapping. -- var lastMapping = null; -- -- aSourceMapConsumer.eachMapping(function (mapping) { -- if (lastMapping !== null) { -- // We add the code from "lastMapping" to "mapping": -- // First check if there is a new line in between. -- if (lastGeneratedLine < mapping.generatedLine) { -- // Associate first line with "lastMapping" -- addMappingWithCode(lastMapping, shiftNextLine()); -- lastGeneratedLine++; -- lastGeneratedColumn = 0; -- // The remaining code is added without mapping -- } else { -- // There is no new line in between. -- // Associate the code between "lastGeneratedColumn" and -- // "mapping.generatedColumn" with "lastMapping" -- var nextLine = remainingLines[0]; -- var code = nextLine.substr(0, mapping.generatedColumn - -- lastGeneratedColumn); -- remainingLines[0] = nextLine.substr(mapping.generatedColumn - -- lastGeneratedColumn); -- lastGeneratedColumn = mapping.generatedColumn; -- addMappingWithCode(lastMapping, code); -- // No more remaining code, continue -- lastMapping = mapping; -- return; -- } -- } -- // We add the generated code until the first mapping -- // to the SourceNode without any mapping. -- // Each line is added as separate string. -- while (lastGeneratedLine < mapping.generatedLine) { -- node.add(shiftNextLine()); -- lastGeneratedLine++; -- } -- if (lastGeneratedColumn < mapping.generatedColumn) { -- var nextLine = remainingLines[0]; -- node.add(nextLine.substr(0, mapping.generatedColumn)); -- remainingLines[0] = nextLine.substr(mapping.generatedColumn); -- lastGeneratedColumn = mapping.generatedColumn; -- } -- lastMapping = mapping; -- }, this); -- // We have processed all mappings. -- if (remainingLines.length > 0) { -- if (lastMapping) { -- // Associate the remaining code in the current line with "lastMapping" -- addMappingWithCode(lastMapping, shiftNextLine()); -- } -- // and add the remaining lines without any mapping -- node.add(remainingLines.join("")); -- } -- -- // Copy sourcesContent into SourceNode -- aSourceMapConsumer.sources.forEach(function (sourceFile) { -- var content = aSourceMapConsumer.sourceContentFor(sourceFile); -- if (content != null) { -- if (aRelativePath != null) { -- sourceFile = util.join(aRelativePath, sourceFile); -- } -- node.setSourceContent(sourceFile, content); -- } -- }); -- -- return node; -- -- function addMappingWithCode(mapping, code) { -- if (mapping === null || mapping.source === undefined) { -- node.add(code); -- } else { -- var source = aRelativePath -- ? util.join(aRelativePath, mapping.source) -- : mapping.source; -- node.add(new SourceNode(mapping.originalLine, -- mapping.originalColumn, -- source, -- code, -- mapping.name)); -- } -- } -- }; -- -- /** -- * Add a chunk of generated JS to this source node. -- * -- * @param aChunk A string snippet of generated JS code, another instance of -- * SourceNode, or an array where each member is one of those things. -- */ -- SourceNode.prototype.add = function SourceNode_add(aChunk) { -- if (Array.isArray(aChunk)) { -- aChunk.forEach(function (chunk) { -- this.add(chunk); -- }, this); -- } -- else if (aChunk[isSourceNode] || typeof aChunk === "string") { -- if (aChunk) { -- this.children.push(aChunk); -- } -- } -- else { -- throw new TypeError( -- "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk -- ); -- } -- return this; -- }; -- -- /** -- * Add a chunk of generated JS to the beginning of this source node. -- * -- * @param aChunk A string snippet of generated JS code, another instance of -- * SourceNode, or an array where each member is one of those things. -- */ -- SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { -- if (Array.isArray(aChunk)) { -- for (var i = aChunk.length-1; i >= 0; i--) { -- this.prepend(aChunk[i]); -- } -- } -- else if (aChunk[isSourceNode] || typeof aChunk === "string") { -- this.children.unshift(aChunk); -- } -- else { -- throw new TypeError( -- "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk -- ); -- } -- return this; -- }; -- -- /** -- * Walk over the tree of JS snippets in this node and its children. The -- * walking function is called once for each snippet of JS and is passed that -- * snippet and the its original associated source's line/column location. -- * -- * @param aFn The traversal function. -- */ -- SourceNode.prototype.walk = function SourceNode_walk(aFn) { -- var chunk; -- for (var i = 0, len = this.children.length; i < len; i++) { -- chunk = this.children[i]; -- if (chunk[isSourceNode]) { -- chunk.walk(aFn); -- } -- else { -- if (chunk !== '') { -- aFn(chunk, { source: this.source, -- line: this.line, -- column: this.column, -- name: this.name }); -- } -- } -- } -- }; -- -- /** -- * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between -- * each of `this.children`. -- * -- * @param aSep The separator. -- */ -- SourceNode.prototype.join = function SourceNode_join(aSep) { -- var newChildren; -- var i; -- var len = this.children.length; -- if (len > 0) { -- newChildren = []; -- for (i = 0; i < len-1; i++) { -- newChildren.push(this.children[i]); -- newChildren.push(aSep); -- } -- newChildren.push(this.children[i]); -- this.children = newChildren; -- } -- return this; -- }; -- -- /** -- * Call String.prototype.replace on the very right-most source snippet. Useful -- * for trimming whitespace from the end of a source node, etc. -- * -- * @param aPattern The pattern to replace. -- * @param aReplacement The thing to replace the pattern with. -- */ -- SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { -- var lastChild = this.children[this.children.length - 1]; -- if (lastChild[isSourceNode]) { -- lastChild.replaceRight(aPattern, aReplacement); -- } -- else if (typeof lastChild === 'string') { -- this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); -- } -- else { -- this.children.push(''.replace(aPattern, aReplacement)); -- } -- return this; -- }; -- -- /** -- * Set the source content for a source file. This will be added to the SourceMapGenerator -- * in the sourcesContent field. -- * -- * @param aSourceFile The filename of the source file -- * @param aSourceContent The content of the source file -- */ -- SourceNode.prototype.setSourceContent = -- function SourceNode_setSourceContent(aSourceFile, aSourceContent) { -- this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; -- }; -- -- /** -- * Walk over the tree of SourceNodes. The walking function is called for each -- * source file content and is passed the filename and source content. -- * -- * @param aFn The traversal function. -- */ -- SourceNode.prototype.walkSourceContents = -- function SourceNode_walkSourceContents(aFn) { -- for (var i = 0, len = this.children.length; i < len; i++) { -- if (this.children[i][isSourceNode]) { -- this.children[i].walkSourceContents(aFn); -- } -- } -- -- var sources = Object.keys(this.sourceContents); -- for (var i = 0, len = sources.length; i < len; i++) { -- aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); -- } -- }; -- -- /** -- * Return the string representation of this source node. Walks over the tree -- * and concatenates all the various snippets together to one string. -- */ -- SourceNode.prototype.toString = function SourceNode_toString() { -- var str = ""; -- this.walk(function (chunk) { -- str += chunk; -- }); -- return str; -- }; -- -- /** -- * Returns the string representation of this source node along with a source -- * map. -- */ -- SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { -- var generated = { -- code: "", -- line: 1, -- column: 0 -- }; -- var map = new SourceMapGenerator(aArgs); -- var sourceMappingActive = false; -- var lastOriginalSource = null; -- var lastOriginalLine = null; -- var lastOriginalColumn = null; -- var lastOriginalName = null; -- this.walk(function (chunk, original) { -- generated.code += chunk; -- if (original.source !== null -- && original.line !== null -- && original.column !== null) { -- if(lastOriginalSource !== original.source -- || lastOriginalLine !== original.line -- || lastOriginalColumn !== original.column -- || lastOriginalName !== original.name) { -- map.addMapping({ -- source: original.source, -- original: { -- line: original.line, -- column: original.column -- }, -- generated: { -- line: generated.line, -- column: generated.column -- }, -- name: original.name -- }); -- } -- lastOriginalSource = original.source; -- lastOriginalLine = original.line; -- lastOriginalColumn = original.column; -- lastOriginalName = original.name; -- sourceMappingActive = true; -- } else if (sourceMappingActive) { -- map.addMapping({ -- generated: { -- line: generated.line, -- column: generated.column -- } -- }); -- lastOriginalSource = null; -- sourceMappingActive = false; -- } -- for (var idx = 0, length = chunk.length; idx < length; idx++) { -- if (chunk.charCodeAt(idx) === NEWLINE_CODE) { -- generated.line++; -- generated.column = 0; -- // Mappings end at eol -- if (idx + 1 === length) { -- lastOriginalSource = null; -- sourceMappingActive = false; -- } else if (sourceMappingActive) { -- map.addMapping({ -- source: original.source, -- original: { -- line: original.line, -- column: original.column -- }, -- generated: { -- line: generated.line, -- column: generated.column -- }, -- name: original.name -- }); -- } -- } else { -- generated.column++; -- } -- } -- }); -- this.walkSourceContents(function (sourceFile, sourceContent) { -- map.setSourceContent(sourceFile, sourceContent); -- }); -- -- return { code: generated.code, map: map }; -- }; -- -- exports.SourceNode = SourceNode; -- } -- -- --/***/ } --/******/ ]) --}); --;MOZ_SourceMap = sourceMap;(function(exports,global){/*********************************************************************** -+(function(exports,global){/*********************************************************************** - - A JavaScript tokenizer / parser / beautifier / compressor. - https://github.com/mishoo/UglifyJS2 --- -2.5.5 - diff --git a/rubygem-uglifier-3.0.0-unbundle-js-files-for-jscript.patch b/rubygem-uglifier-3.0.0-unbundle-js-files-for-jscript.patch index 2ba8a7c..d9d411c 100644 --- a/rubygem-uglifier-3.0.0-unbundle-js-files-for-jscript.patch +++ b/rubygem-uglifier-3.0.0-unbundle-js-files-for-jscript.patch @@ -476,7 +476,7 @@ index de24e26..431c4b3 100644 # UglifyJS wrapper path UglifyJSWrapperPath = File.expand_path("../uglifier.js", __FILE__) -@@ -154,7 +150,7 @@ class Uglifier +@@ -156,7 +152,7 @@ class Uglifier private def uglifyjs_source diff --git a/rubygem-uglifier.spec b/rubygem-uglifier.spec index 45d1d72..721f2bd 100644 --- a/rubygem-uglifier.spec +++ b/rubygem-uglifier.spec @@ -1,25 +1,20 @@ # Generated from uglifier-1.2.6.gem by gem2rpm -*- rpm-spec -*- %global gem_name uglifier -Summary: Ruby wrapper for UglifyJS JavaScript compressor Name: rubygem-%{gem_name} -Version: 3.0.0 +Version: 3.0.2 Release: 1%{?dist} +Summary: Ruby wrapper for UglifyJS JavaScript compressor Group: Development/Languages # lib/source-map.js is BSD. +# lib/uglify.js is BSD. License: MIT and BSD URL: http://github.com/lautis/uglifier Source0: https://rubygems.org/gems/%{gem_name}-%{version}.gem -# Separate lib/uglify.js and lib/source-map.js -# https://github.com/lautis/uglifier/pull/98 -Patch0: rubygem-uglifier-3.0.0-separate-source-map.patch # Unbundling es5.js and split.js files, # since they are needed only by JScript engine, which is not supported on Fedora # https://github.com/lautis/uglifier/issues/99 Patch1: rubygem-uglifier-3.0.0-unbundle-js-files-for-jscript.patch -# Fix test to use UglifyJs 2.7.0 -# https://github.com/lautis/uglifier/commit/f676b66 -Patch2: rubygem-uglifier-3.0.0-fix-test-for-uglifyjs-2.7.0.patch BuildRequires: ruby(release) BuildRequires: rubygems-devel @@ -28,7 +23,8 @@ BuildRequires: rubygem(execjs) >= 0.3.0 BuildRequires: rubygem(rspec) BuildRequires: %{_bindir}/node BuildRequires: uglify-js = 2.7.0 -# There is not included uglify-js.js yet. +# uglify-js does not provide single file uglify-js.js yet => let's +# generate and bundle it here. Provides: bundled(uglify-js) = 2.7.0 # There is not included dist/source-map.js yet. # https://bugzilla.redhat.com/show_bug.cgi?id=1358915 @@ -47,7 +43,7 @@ Requires: %{name} = %{version}-%{release} BuildArch: noarch %description doc -Documentation for %{name} +Documentation for %{name}. %prep gem unpack %{SOURCE0} @@ -55,8 +51,7 @@ gem unpack %{SOURCE0} %setup -q -D -T -n %{gem_name}-%{version} gem spec %{SOURCE0} -l --ruby > %{gem_name}.gemspec -%patch0 -p1 -sed -i '/files/ s|"\]|", "lib/source-map.js"\]|' %{gem_name}.gemspec + %patch1 -p1 sed -i '/files/ s|"lib/es5.js", ||' %{gem_name}.gemspec sed -i '/files/ s|"lib/split.js", ||' %{gem_name}.gemspec @@ -83,10 +78,8 @@ cp -a .%{gem_dir}/* \ %check pushd .%{gem_instdir} -patch -p1 < %{PATCH2} - # Disable rubygem-sourcemap because it is not part of fedora yet. -sed -i "s/require 'sourcemap'//" spec/spec_helper.rb +sed -i "/require 'sourcemap'/ s/^/#/" spec/spec_helper.rb sed -i '/SourceMap::Map/ i \ pending' spec/source_map_spec.rb rspec spec @@ -95,9 +88,9 @@ popd %files %dir %{gem_instdir} +%exclude %{gem_instdir}/.* %license %{gem_instdir}/LICENSE.txt %{gem_libdir} -%exclude %{gem_instdir}/.* %exclude %{gem_cache} %{gem_spec} @@ -113,6 +106,9 @@ popd %{gem_instdir}/%{gem_name}.gemspec %changelog +* Thu Oct 13 2016 Vít Ondruch - 3.0.2-1 +- Update to Uglifier 3.0.2. + * Wed Jul 27 2016 Jun Aruga - 3.0.0-1 - Fix for FTBFS. (rhbz#1357879) - Update to uglifier 3.0.0 diff --git a/sources b/sources index c4dbd4e..daa1797 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -82d04a344bc9870b743943e32de1eb87 uglifier-3.0.0.gem +de2dafb9245236e12630e7ba18970d79 uglifier-3.0.2.gem