From 1b290f59aaecdbf59f8441c271e3dd61e865380e Mon Sep 17 00:00:00 2001 From: Jun Aruga Date: Jul 28 2016 12:48:07 +0000 Subject: - Fix for FTBFS. (rhbz#1357879) - Update to uglifier 3.0.0 --- diff --git a/.gitignore b/.gitignore index af13e8c..1109132 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /uglifier-2.2.1.gem /uglifier-2.3.0.gem /uglifier-2.4.0.gem +/uglifier-3.0.0.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 new file mode 100644 index 0000000..710af92 --- /dev/null +++ b/rubygem-uglifier-3.0.0-fix-test-for-uglifyjs-2.7.0.patch @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..5296b9c --- /dev/null +++ b/rubygem-uglifier-3.0.0-separate-source-map.patch @@ -0,0 +1,6103 @@ +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 new file mode 100644 index 0000000..2ba8a7c --- /dev/null +++ b/rubygem-uglifier-3.0.0-unbundle-js-files-for-jscript.patch @@ -0,0 +1,490 @@ +From b023cc8166705f8a2c8b8d348ef5d9a663afbb5f Mon Sep 17 00:00:00 2001 +From: Jun Aruga +Date: Wed, 27 Jul 2016 14:30:02 +0200 +Subject: [PATCH] Remove JS files for JS Engine not supporting ECMAScript 5. + +--- + lib/es5.js | 321 -------------------------------------------------------- + lib/split.js | 117 --------------------- + lib/uglifier.rb | 6 +- + 3 files changed, 1 insertion(+), 443 deletions(-) + delete mode 100644 lib/es5.js + delete mode 100644 lib/split.js + +diff --git a/lib/es5.js b/lib/es5.js +deleted file mode 100644 +index b5712b8..0000000 +--- a/lib/es5.js ++++ /dev/null +@@ -1,321 +0,0 @@ +-// https://developer.mozilla.org/en/JavaScript/Reference/global_objects/array/foreach +- +-if (!Array.prototype.forEach) +-{ +- Array.prototype.forEach = function(fun /*, thisp */) +- { +- "use strict"; +- +- if (this === void 0 || this === null) +- throw new TypeError(); +- +- var t = Object(this); +- var len = t.length >>> 0; +- if (typeof fun !== "function") +- throw new TypeError(); +- +- var thisp = arguments[1]; +- for (var i = 0; i < len; i++) +- { +- if (i in t) +- fun.call(thisp, t[i], i, t); +- } +- }; +-} +- +-// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map +-// Production steps of ECMA-262, Edition 5, 15.4.4.19 +-// Reference: http://es5.github.com/#x15.4.4.19 +-if (!Array.prototype.map) { +- Array.prototype.map = function(callback, thisArg) { +- +- var T, A, k; +- +- if (this == null) { +- throw new TypeError(" this is null or not defined"); +- } +- +- // 1. Let O be the result of calling ToObject passing the |this| value as the argument. +- var O = Object(this); +- +- // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length". +- // 3. Let len be ToUint32(lenValue). +- var len = O.length >>> 0; +- +- // 4. If IsCallable(callback) is false, throw a TypeError exception. +- // See: http://es5.github.com/#x9.11 +- if ({}.toString.call(callback) != "[object Function]") { +- throw new TypeError(callback + " is not a function"); +- } +- +- // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. +- if (thisArg) { +- T = thisArg; +- } +- +- // 6. Let A be a new array created as if by the expression new Array(len) where Array is +- // the standard built-in constructor with that name and len is the value of len. +- A = new Array(len); +- +- // 7. Let k be 0 +- k = 0; +- +- // 8. Repeat, while k < len +- while(k < len) { +- +- var kValue, mappedValue; +- +- // a. Let Pk be ToString(k). +- // This is implicit for LHS operands of the in operator +- // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. +- // This step can be combined with c +- // c. If kPresent is true, then +- if (k in O) { +- +- // i. Let kValue be the result of calling the Get internal method of O with argument Pk. +- kValue = O[ k ]; +- +- // ii. Let mappedValue be the result of calling the Call internal method of callback +- // with T as the this value and argument list containing kValue, k, and O. +- mappedValue = callback.call(T, kValue, k, O); +- +- // iii. Call the DefineOwnProperty internal method of A with arguments +- // Pk, Property Descriptor {Value: mappedValue, Writable: true, Enumerable: true, Configurable: true}, +- // and false. +- +- // In browsers that support Object.defineProperty, use the following: +- // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); +- +- // For best browser support, use the following: +- A[ k ] = mappedValue; +- } +- // d. Increase k by 1. +- k++; +- } +- +- // 9. return A +- return A; +- }; +-} +- +-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce +- +-if (!Array.prototype.reduce) +-{ +- Array.prototype.reduce = function(fun /*, initialValue */) +- { +- "use strict"; +- +- if (this === void 0 || this === null) +- throw new TypeError(); +- +- var t = Object(this); +- var len = t.length >>> 0; +- if (typeof fun !== "function") +- throw new TypeError(); +- +- // no value to return if no initial value and an empty array +- if (len == 0 && arguments.length == 1) +- throw new TypeError(); +- +- var k = 0; +- var accumulator; +- if (arguments.length >= 2) +- { +- accumulator = arguments[1]; +- } +- else +- { +- do +- { +- if (k in t) +- { +- accumulator = t[k++]; +- break; +- } +- +- // if array contains no values, no initial value to return +- if (++k >= len) +- throw new TypeError(); +- } +- while (true); +- } +- +- while (k < len) +- { +- if (k in t) +- accumulator = fun.call(undefined, accumulator, t[k], k, t); +- k++; +- } +- +- return accumulator; +- }; +-} +- +-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf +-if (!Array.prototype.indexOf) { +- Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { +- "use strict"; +- if (this === void 0 || this === null) { +- throw new TypeError(); +- } +- var t = Object(this); +- var len = t.length >>> 0; +- if (len === 0) { +- return -1; +- } +- var n = 0; +- if (arguments.length > 0) { +- n = Number(arguments[1]); +- if (n !== n) { // shortcut for verifying if it's NaN +- n = 0; +- } else if (n !== 0 && n !== Infinity && n !== -Infinity) { +- n = (n > 0 || -1) * Math.floor(Math.abs(n)); +- } +- } +- if (n >= len) { +- return -1; +- } +- var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); +- for (; k < len; k++) { +- if (k in t && t[k] === searchElement) { +- return k; +- } +- } +- return -1; +- } +-} +- +-// https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Object/keys +-if (!Object.keys) { +- Object.keys = (function () { +- var hasOwnProperty = Object.prototype.hasOwnProperty, +- hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), +- dontEnums = [ +- 'toString', +- 'toLocaleString', +- 'valueOf', +- 'hasOwnProperty', +- 'isPrototypeOf', +- 'propertyIsEnumerable', +- 'constructor' +- ], +- dontEnumsLength = dontEnums.length; +- +- return function (obj) { +- if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object'); +- +- var result = []; +- +- for (var prop in obj) { +- if (hasOwnProperty.call(obj, prop)) result.push(prop); +- } +- +- if (hasDontEnumBug) { +- for (var i=0; i < dontEnumsLength; i++) { +- if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]); +- } +- } +- return result; +- } +- })() +-}; +- +-// https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Object/create +-if (!Object.create) { +- Object.create = function (o) { +- if (arguments.length > 1) { +- throw new Error('Object.create implementation only accepts the first parameter.'); +- } +- function F() {} +- F.prototype = o; +- return new F(); +- }; +-} +- +-// https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Array/filter +-if (!Array.prototype.filter) +-{ +- Array.prototype.filter = function(fun /*, thisp*/) +- { +- "use strict"; +- +- if (this == null) +- throw new TypeError(); +- +- var t = Object(this); +- var len = t.length >>> 0; +- if (typeof fun != "function") +- throw new TypeError(); +- +- var res = []; +- var thisp = arguments[1]; +- for (var i = 0; i < len; i++) +- { +- if (i in t) +- { +- var val = t[i]; // in case fun mutates this +- if (fun.call(thisp, val, i, t)) +- res.push(val); +- } +- } +- +- return res; +- }; +-} +- +-// https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/bind +-if (!Function.prototype.bind) { +- Function.prototype.bind = function (oThis) { +- if (typeof this !== "function") { +- // closest thing possible to the ECMAScript 5 internal IsCallable function +- throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); +- } +- +- var aArgs = Array.prototype.slice.call(arguments, 1), +- fToBind = this, +- fNOP = function () {}, +- fBound = function () { +- return fToBind.apply(this instanceof fNOP && oThis +- ? this +- : oThis, +- aArgs.concat(Array.prototype.slice.call(arguments))); +- }; +- +- fNOP.prototype = this.prototype; +- fBound.prototype = new fNOP(); +- +- return fBound; +- }; +-} +- +-// https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Array/isArray +-if(!Array.isArray) { +- Array.isArray = function (vArg) { +- return Object.prototype.toString.call(vArg) === "[object Array]"; +- }; +-} +- +-// https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/trim +-if(!String.prototype.trim) { +- String.prototype.trim = function () { +- return this.replace(/^\s+|\s+$/g,''); +- }; +-} +- +- +-function definePropertyWorks() { +- try { +- Object.defineProperty({}, "property", {}); +- return true; +- } catch (exception) { +- return false; +- } +-} +- +-if (!definePropertyWorks()) { +- Object.defineProperty = function defineProperty(object) { +- // fail silently +- return object; +- } +-} +diff --git a/lib/split.js b/lib/split.js +deleted file mode 100644 +index 8cc2924..0000000 +--- a/lib/split.js ++++ /dev/null +@@ -1,117 +0,0 @@ +-/*! +- * Cross-Browser Split 1.1.1 +- * Copyright 2007-2012 Steven Levithan +- * Available under the MIT License +- * ECMAScript compliant, uniform cross-browser split method +- */ +- +-/** +- * Splits a string into an array of strings using a regex or string separator. Matches of the +- * separator are not included in the result array. However, if `separator` is a regex that contains +- * capturing groups, backreferences are spliced into the result each time `separator` is matched. +- * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably +- * cross-browser. +- * @param {String} str String to split. +- * @param {RegExp|String} separator Regex or string to use for separating the string. +- * @param {Number} [limit] Maximum number of items to include in the result array. +- * @returns {Array} Array of substrings. +- * @example +- * +- * // Basic use +- * split('a b c d', ' '); +- * // -> ['a', 'b', 'c', 'd'] +- * +- * // With limit +- * split('a b c d', ' ', 2); +- * // -> ['a', 'b'] +- * +- * // Backreferences in result array +- * split('..word1 word2..', /([a-z]+)(\d+)/i); +- * // -> ['..', 'word', '1', ' ', 'word', '2', '..'] +- */ +-var split; +- +-// Avoid running twice; that would break the `nativeSplit` reference +-split = split || function (undef) { +- +- var nativeSplit = String.prototype.split, +- compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group +- self; +- +- self = function (str, separator, limit) { +- // If `separator` is not a regex, use `nativeSplit` +- if (Object.prototype.toString.call(separator) !== "[object RegExp]") { +- return nativeSplit.call(str, separator, limit); +- } +- var output = [], +- flags = (separator.ignoreCase ? "i" : "") + +- (separator.multiline ? "m" : "") + +- (separator.extended ? "x" : "") + // Proposed for ES6 +- (separator.sticky ? "y" : ""), // Firefox 3+ +- lastLastIndex = 0, +- // Make `global` and avoid `lastIndex` issues by working with a copy +- separator = new RegExp(separator.source, flags + "g"), +- separator2, match, lastIndex, lastLength; +- str += ""; // Type-convert +- if (!compliantExecNpcg) { +- // Doesn't need flags gy, but they don't hurt +- separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags); +- } +- /* Values for `limit`, per the spec: +- * If undefined: 4294967295 // Math.pow(2, 32) - 1 +- * If 0, Infinity, or NaN: 0 +- * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; +- * If negative number: 4294967296 - Math.floor(Math.abs(limit)) +- * If other: Type-convert, then use the above rules +- */ +- limit = limit === undef ? +- -1 >>> 0 : // Math.pow(2, 32) - 1 +- limit >>> 0; // ToUint32(limit) +- while (match = separator.exec(str)) { +- // `separator.lastIndex` is not reliable cross-browser +- lastIndex = match.index + match[0].length; +- if (lastIndex > lastLastIndex) { +- output.push(str.slice(lastLastIndex, match.index)); +- // Fix browsers whose `exec` methods don't consistently return `undefined` for +- // nonparticipating capturing groups +- if (!compliantExecNpcg && match.length > 1) { +- match[0].replace(separator2, function () { +- for (var i = 1; i < arguments.length - 2; i++) { +- if (arguments[i] === undef) { +- match[i] = undef; +- } +- } +- }); +- } +- if (match.length > 1 && match.index < str.length) { +- Array.prototype.push.apply(output, match.slice(1)); +- } +- lastLength = match[0].length; +- lastLastIndex = lastIndex; +- if (output.length >= limit) { +- break; +- } +- } +- if (separator.lastIndex === match.index) { +- separator.lastIndex++; // Avoid an infinite loop +- } +- } +- if (lastLastIndex === str.length) { +- if (lastLength || !separator.test("")) { +- output.push(""); +- } +- } else { +- output.push(str.slice(lastLastIndex)); +- } +- return output.length > limit ? output.slice(0, limit) : output; +- }; +- +- if ("\n".split(/\n/).length == 0) { +- String.prototype.split = function (separator, limit) { +- return self(this, separator, limit); +- }; +- } +- +- return self; +- +-}(); +diff --git a/lib/uglifier.rb b/lib/uglifier.rb +index de24e26..431c4b3 100644 +--- a/lib/uglifier.rb ++++ b/lib/uglifier.rb +@@ -14,10 +14,6 @@ class Uglifier + 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 +- SplitFallbackPath = File.expand_path("../split.js", __FILE__) + # UglifyJS wrapper path + UglifyJSWrapperPath = File.expand_path("../uglifier.js", __FILE__) + +@@ -154,7 +150,7 @@ class Uglifier + private + + def uglifyjs_source +- [ES5FallbackPath, SplitFallbackPath, SourceMapPath, SourcePath, ++ [SourceMapPath, SourcePath, + UglifyJSWrapperPath].map do |file| + File.open(file, "r:UTF-8", &:read) + end.join("\n") +-- +2.5.5 + diff --git a/rubygem-uglifier.spec b/rubygem-uglifier.spec index 3e76df5..45d1d72 100644 --- a/rubygem-uglifier.spec +++ b/rubygem-uglifier.spec @@ -3,32 +3,41 @@ Summary: Ruby wrapper for UglifyJS JavaScript compressor Name: rubygem-%{gem_name} -Version: 2.4.0 -Release: 4%{?dist} +Version: 3.0.0 +Release: 1%{?dist} Group: Development/Languages -# Uglifier itself is MIT -# the bundled JavaScript from UglifyJS is BSD +# lib/source-map.js is BSD. License: MIT and BSD URL: http://github.com/lautis/uglifier -Source0: http://rubygems.org/gems/%{gem_name}-%{version}.gem -Requires: ruby(release) -Requires: ruby(rubygems) -Requires: rubygem(execjs) >= 0.3.0 -Requires: rubygem(multi_json) => 1.3 -Requires: rubygem(multi_json) < 2 +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 BuildRequires: ruby BuildRequires: rubygem(execjs) >= 0.3.0 -BuildRequires: rubygem(multi_json) => 1.3 -BuildRequires: rubygem(multi_json) < 2 BuildRequires: rubygem(rspec) -BuildRequires: rubygem(therubyracer) +BuildRequires: %{_bindir}/node +BuildRequires: uglify-js = 2.7.0 +# There is not included uglify-js.js yet. +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 +Provides: bundled(nodejs-source-map) = 0.5.3 BuildArch: noarch -Provides: rubygem(%{gem_name}) = %{version} %description -Ruby wrapper for UglifyJS JavaScript compressor. +Uglifier minifies JavaScript files by wrapping UglifyJS to be accessible in +Ruby. %package doc @@ -41,10 +50,31 @@ BuildArch: noarch Documentation for %{name} %prep -%setup -q -c -T -%gem_install -n %{SOURCE0} +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 + +# Explicitly removing the file. +rm lib/uglify.js %build +# It's nice to regenerate from system uglify.js +# See "Use of pregenerated code" Guidelines. +uglifyjs --self --comments /Copyright/ > lib/uglify.js + +# Create the gem as gem install only works on a gem file +gem build %{gem_name}.gemspec + +# %%gem_install compiles any C extensions and installs the gem into ./%%gem_dir +# by default, so that we can move it into the buildroot in %%install +%gem_install %install mkdir -p %{buildroot}%{gem_dir} @@ -53,10 +83,11 @@ cp -a .%{gem_dir}/* \ %check pushd .%{gem_instdir} +patch -p1 < %{PATCH2} -# source_map is not part of fedora yet, ged rid of source_map in specs -sed -i "s/require 'source_map'//" spec/spec_helper.rb -rm spec/source_map_spec.rb +# Disable rubygem-sourcemap because it is not part of fedora yet. +sed -i "s/require 'sourcemap'//" spec/spec_helper.rb +sed -i '/SourceMap::Map/ i \ pending' spec/source_map_spec.rb rspec spec popd @@ -64,24 +95,28 @@ popd %files %dir %{gem_instdir} -%doc %{gem_instdir}/LICENSE.txt +%license %{gem_instdir}/LICENSE.txt %{gem_libdir} %exclude %{gem_instdir}/.* %exclude %{gem_cache} -%exclude %{gem_instdir}/gemfiles %{gem_spec} %files doc %doc %{gem_docdir} +%doc %{gem_instdir}/CHANGELOG.md +%doc %{gem_instdir}/CONTRIBUTING.md %{gem_instdir}/Gemfile %{gem_instdir}/Rakefile %doc %{gem_instdir}/README.md +%{gem_instdir}/gemfiles %{gem_instdir}/spec %{gem_instdir}/%{gem_name}.gemspec -%doc %{gem_instdir}/CHANGELOG.md -%doc %{gem_instdir}/CONTRIBUTING.md %changelog +* Wed Jul 27 2016 Jun Aruga - 3.0.0-1 +- Fix for FTBFS. (rhbz#1357879) +- Update to uglifier 3.0.0 + * Thu Feb 04 2016 Fedora Release Engineering - 2.4.0-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild diff --git a/sources b/sources index f6b4717..c4dbd4e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -9bbbda0347b2b213739bee01df2605bc uglifier-2.4.0.gem +82d04a344bc9870b743943e32de1eb87 uglifier-3.0.0.gem