1(function webpackUniversalModuleDefinition(root, factory) { 2 if(typeof exports === 'object' && typeof module === 'object') 3 module.exports = factory(); 4 else if(typeof define === 'function' && define.amd) 5 define([], factory); 6 else if(typeof exports === 'object') 7 exports["sourceMap"] = factory(); 8 else 9 root["sourceMap"] = factory(); 10})(this, function() { 11return /******/ (function(modules) { // webpackBootstrap 12/******/ // The module cache 13/******/ var installedModules = {}; 14 15/******/ // The require function 16/******/ function __webpack_require__(moduleId) { 17 18/******/ // Check if module is in cache 19/******/ if(installedModules[moduleId]) 20/******/ return installedModules[moduleId].exports; 21 22/******/ // Create a new module (and put it into the cache) 23/******/ var module = installedModules[moduleId] = { 24/******/ exports: {}, 25/******/ id: moduleId, 26/******/ loaded: false 27/******/ }; 28 29/******/ // Execute the module function 30/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 32/******/ // Flag the module as loaded 33/******/ module.loaded = true; 34 35/******/ // Return the exports of the module 36/******/ return module.exports; 37/******/ } 38 39 40/******/ // expose the modules object (__webpack_modules__) 41/******/ __webpack_require__.m = modules; 42 43/******/ // expose the module cache 44/******/ __webpack_require__.c = installedModules; 45 46/******/ // __webpack_public_path__ 47/******/ __webpack_require__.p = ""; 48 49/******/ // Load entry module and return exports 50/******/ return __webpack_require__(0); 51/******/ }) 52/************************************************************************/ 53/******/ ([ 54/* 0 */ 55/***/ (function(module, exports, __webpack_require__) { 56 57 /* 58 * Copyright 2009-2011 Mozilla Foundation and contributors 59 * Licensed under the New BSD license. See LICENSE.txt or: 60 * http://opensource.org/licenses/BSD-3-Clause 61 */ 62 exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; 63 exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; 64 exports.SourceNode = __webpack_require__(10).SourceNode; 65 66 67/***/ }), 68/* 1 */ 69/***/ (function(module, exports, __webpack_require__) { 70 71 /* -*- Mode: js; js-indent-level: 2; -*- */ 72 /* 73 * Copyright 2011 Mozilla Foundation and contributors 74 * Licensed under the New BSD license. See LICENSE or: 75 * http://opensource.org/licenses/BSD-3-Clause 76 */ 77 78 var base64VLQ = __webpack_require__(2); 79 var util = __webpack_require__(4); 80 var ArraySet = __webpack_require__(5).ArraySet; 81 var MappingList = __webpack_require__(6).MappingList; 82 83 /** 84 * An instance of the SourceMapGenerator represents a source map which is 85 * being built incrementally. You may pass an object with the following 86 * properties: 87 * 88 * - file: The filename of the generated source. 89 * - sourceRoot: A root for all relative URLs in this source map. 90 */ 91 function SourceMapGenerator(aArgs) { 92 if (!aArgs) { 93 aArgs = {}; 94 } 95 this._file = util.getArg(aArgs, 'file', null); 96 this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); 97 this._skipValidation = util.getArg(aArgs, 'skipValidation', false); 98 this._sources = new ArraySet(); 99 this._names = new ArraySet(); 100 this._mappings = new MappingList(); 101 this._sourcesContents = null; 102 } 103 104 SourceMapGenerator.prototype._version = 3; 105 106 /** 107 * Creates a new SourceMapGenerator based on a SourceMapConsumer 108 * 109 * @param aSourceMapConsumer The SourceMap. 110 */ 111 SourceMapGenerator.fromSourceMap = 112 function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { 113 var sourceRoot = aSourceMapConsumer.sourceRoot; 114 var generator = new SourceMapGenerator({ 115 file: aSourceMapConsumer.file, 116 sourceRoot: sourceRoot 117 }); 118 aSourceMapConsumer.eachMapping(function (mapping) { 119 var newMapping = { 120 generated: { 121 line: mapping.generatedLine, 122 column: mapping.generatedColumn 123 } 124 }; 125 126 if (mapping.source != null) { 127 newMapping.source = mapping.source; 128 if (sourceRoot != null) { 129 newMapping.source = util.relative(sourceRoot, newMapping.source); 130 } 131 132 newMapping.original = { 133 line: mapping.originalLine, 134 column: mapping.originalColumn 135 }; 136 137 if (mapping.name != null) { 138 newMapping.name = mapping.name; 139 } 140 } 141 142 generator.addMapping(newMapping); 143 }); 144 aSourceMapConsumer.sources.forEach(function (sourceFile) { 145 var content = aSourceMapConsumer.sourceContentFor(sourceFile); 146 if (content != null) { 147 generator.setSourceContent(sourceFile, content); 148 } 149 }); 150 return generator; 151 }; 152 153 /** 154 * Add a single mapping from original source line and column to the generated 155 * source's line and column for this source map being created. The mapping 156 * object should have the following properties: 157 * 158 * - generated: An object with the generated line and column positions. 159 * - original: An object with the original line and column positions. 160 * - source: The original source file (relative to the sourceRoot). 161 * - name: An optional original token name for this mapping. 162 */ 163 SourceMapGenerator.prototype.addMapping = 164 function SourceMapGenerator_addMapping(aArgs) { 165 var generated = util.getArg(aArgs, 'generated'); 166 var original = util.getArg(aArgs, 'original', null); 167 var source = util.getArg(aArgs, 'source', null); 168 var name = util.getArg(aArgs, 'name', null); 169 170 if (!this._skipValidation) { 171 this._validateMapping(generated, original, source, name); 172 } 173 174 if (source != null) { 175 source = String(source); 176 if (!this._sources.has(source)) { 177 this._sources.add(source); 178 } 179 } 180 181 if (name != null) { 182 name = String(name); 183 if (!this._names.has(name)) { 184 this._names.add(name); 185 } 186 } 187 188 this._mappings.add({ 189 generatedLine: generated.line, 190 generatedColumn: generated.column, 191 originalLine: original != null && original.line, 192 originalColumn: original != null && original.column, 193 source: source, 194 name: name 195 }); 196 }; 197 198 /** 199 * Set the source content for a source file. 200 */ 201 SourceMapGenerator.prototype.setSourceContent = 202 function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { 203 var source = aSourceFile; 204 if (this._sourceRoot != null) { 205 source = util.relative(this._sourceRoot, source); 206 } 207 208 if (aSourceContent != null) { 209 // Add the source content to the _sourcesContents map. 210 // Create a new _sourcesContents map if the property is null. 211 if (!this._sourcesContents) { 212 this._sourcesContents = Object.create(null); 213 } 214 this._sourcesContents[util.toSetString(source)] = aSourceContent; 215 } else if (this._sourcesContents) { 216 // Remove the source file from the _sourcesContents map. 217 // If the _sourcesContents map is empty, set the property to null. 218 delete this._sourcesContents[util.toSetString(source)]; 219 if (Object.keys(this._sourcesContents).length === 0) { 220 this._sourcesContents = null; 221 } 222 } 223 }; 224 225 /** 226 * Applies the mappings of a sub-source-map for a specific source file to the 227 * source map being generated. Each mapping to the supplied source file is 228 * rewritten using the supplied source map. Note: The resolution for the 229 * resulting mappings is the minimium of this map and the supplied map. 230 * 231 * @param aSourceMapConsumer The source map to be applied. 232 * @param aSourceFile Optional. The filename of the source file. 233 * If omitted, SourceMapConsumer's file property will be used. 234 * @param aSourceMapPath Optional. The dirname of the path to the source map 235 * to be applied. If relative, it is relative to the SourceMapConsumer. 236 * This parameter is needed when the two source maps aren't in the same 237 * directory, and the source map to be applied contains relative source 238 * paths. If so, those relative source paths need to be rewritten 239 * relative to the SourceMapGenerator. 240 */ 241 SourceMapGenerator.prototype.applySourceMap = 242 function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { 243 var sourceFile = aSourceFile; 244 // If aSourceFile is omitted, we will use the file property of the SourceMap 245 if (aSourceFile == null) { 246 if (aSourceMapConsumer.file == null) { 247 throw new Error( 248 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + 249 'or the source map\'s "file" property. Both were omitted.' 250 ); 251 } 252 sourceFile = aSourceMapConsumer.file; 253 } 254 var sourceRoot = this._sourceRoot; 255 // Make "sourceFile" relative if an absolute Url is passed. 256 if (sourceRoot != null) { 257 sourceFile = util.relative(sourceRoot, sourceFile); 258 } 259 // Applying the SourceMap can add and remove items from the sources and 260 // the names array. 261 var newSources = new ArraySet(); 262 var newNames = new ArraySet(); 263 264 // Find mappings for the "sourceFile" 265 this._mappings.unsortedForEach(function (mapping) { 266 if (mapping.source === sourceFile && mapping.originalLine != null) { 267 // Check if it can be mapped by the source map, then update the mapping. 268 var original = aSourceMapConsumer.originalPositionFor({ 269 line: mapping.originalLine, 270 column: mapping.originalColumn 271 }); 272 if (original.source != null) { 273 // Copy mapping 274 mapping.source = original.source; 275 if (aSourceMapPath != null) { 276 mapping.source = util.join(aSourceMapPath, mapping.source) 277 } 278 if (sourceRoot != null) { 279 mapping.source = util.relative(sourceRoot, mapping.source); 280 } 281 mapping.originalLine = original.line; 282 mapping.originalColumn = original.column; 283 if (original.name != null) { 284 mapping.name = original.name; 285 } 286 } 287 } 288 289 var source = mapping.source; 290 if (source != null && !newSources.has(source)) { 291 newSources.add(source); 292 } 293 294 var name = mapping.name; 295 if (name != null && !newNames.has(name)) { 296 newNames.add(name); 297 } 298 299 }, this); 300 this._sources = newSources; 301 this._names = newNames; 302 303 // Copy sourcesContents of applied map. 304 aSourceMapConsumer.sources.forEach(function (sourceFile) { 305 var content = aSourceMapConsumer.sourceContentFor(sourceFile); 306 if (content != null) { 307 if (aSourceMapPath != null) { 308 sourceFile = util.join(aSourceMapPath, sourceFile); 309 } 310 if (sourceRoot != null) { 311 sourceFile = util.relative(sourceRoot, sourceFile); 312 } 313 this.setSourceContent(sourceFile, content); 314 } 315 }, this); 316 }; 317 318 /** 319 * A mapping can have one of the three levels of data: 320 * 321 * 1. Just the generated position. 322 * 2. The Generated position, original position, and original source. 323 * 3. Generated and original position, original source, as well as a name 324 * token. 325 * 326 * To maintain consistency, we validate that any new mapping being added falls 327 * in to one of these categories. 328 */ 329 SourceMapGenerator.prototype._validateMapping = 330 function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, 331 aName) { 332 // When aOriginal is truthy but has empty values for .line and .column, 333 // it is most likely a programmer error. In this case we throw a very 334 // specific error message to try to guide them the right way. 335 // For example: https://github.com/Polymer/polymer-bundler/pull/519 336 if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { 337 throw new Error( 338 'original.line and original.column are not numbers -- you probably meant to omit ' + 339 'the original mapping entirely and only map the generated position. If so, pass ' + 340 'null for the original mapping instead of an object with empty or null values.' 341 ); 342 } 343 344 if (aGenerated && 'line' in aGenerated && 'column' in aGenerated 345 && aGenerated.line > 0 && aGenerated.column >= 0 346 && !aOriginal && !aSource && !aName) { 347 // Case 1. 348 return; 349 } 350 else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated 351 && aOriginal && 'line' in aOriginal && 'column' in aOriginal 352 && aGenerated.line > 0 && aGenerated.column >= 0 353 && aOriginal.line > 0 && aOriginal.column >= 0 354 && aSource) { 355 // Cases 2 and 3. 356 return; 357 } 358 else { 359 throw new Error('Invalid mapping: ' + JSON.stringify({ 360 generated: aGenerated, 361 source: aSource, 362 original: aOriginal, 363 name: aName 364 })); 365 } 366 }; 367 368 /** 369 * Serialize the accumulated mappings in to the stream of base 64 VLQs 370 * specified by the source map format. 371 */ 372 SourceMapGenerator.prototype._serializeMappings = 373 function SourceMapGenerator_serializeMappings() { 374 var previousGeneratedColumn = 0; 375 var previousGeneratedLine = 1; 376 var previousOriginalColumn = 0; 377 var previousOriginalLine = 0; 378 var previousName = 0; 379 var previousSource = 0; 380 var result = ''; 381 var next; 382 var mapping; 383 var nameIdx; 384 var sourceIdx; 385 386 var mappings = this._mappings.toArray(); 387 for (var i = 0, len = mappings.length; i < len; i++) { 388 mapping = mappings[i]; 389 next = '' 390 391 if (mapping.generatedLine !== previousGeneratedLine) { 392 previousGeneratedColumn = 0; 393 while (mapping.generatedLine !== previousGeneratedLine) { 394 next += ';'; 395 previousGeneratedLine++; 396 } 397 } 398 else { 399 if (i > 0) { 400 if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { 401 continue; 402 } 403 next += ','; 404 } 405 } 406 407 next += base64VLQ.encode(mapping.generatedColumn 408 - previousGeneratedColumn); 409 previousGeneratedColumn = mapping.generatedColumn; 410 411 if (mapping.source != null) { 412 sourceIdx = this._sources.indexOf(mapping.source); 413 next += base64VLQ.encode(sourceIdx - previousSource); 414 previousSource = sourceIdx; 415 416 // lines are stored 0-based in SourceMap spec version 3 417 next += base64VLQ.encode(mapping.originalLine - 1 418 - previousOriginalLine); 419 previousOriginalLine = mapping.originalLine - 1; 420 421 next += base64VLQ.encode(mapping.originalColumn 422 - previousOriginalColumn); 423 previousOriginalColumn = mapping.originalColumn; 424 425 if (mapping.name != null) { 426 nameIdx = this._names.indexOf(mapping.name); 427 next += base64VLQ.encode(nameIdx - previousName); 428 previousName = nameIdx; 429 } 430 } 431 432 result += next; 433 } 434 435 return result; 436 }; 437 438 SourceMapGenerator.prototype._generateSourcesContent = 439 function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { 440 return aSources.map(function (source) { 441 if (!this._sourcesContents) { 442 return null; 443 } 444 if (aSourceRoot != null) { 445 source = util.relative(aSourceRoot, source); 446 } 447 var key = util.toSetString(source); 448 return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) 449 ? this._sourcesContents[key] 450 : null; 451 }, this); 452 }; 453 454 /** 455 * Externalize the source map. 456 */ 457 SourceMapGenerator.prototype.toJSON = 458 function SourceMapGenerator_toJSON() { 459 var map = { 460 version: this._version, 461 sources: this._sources.toArray(), 462 names: this._names.toArray(), 463 mappings: this._serializeMappings() 464 }; 465 if (this._file != null) { 466 map.file = this._file; 467 } 468 if (this._sourceRoot != null) { 469 map.sourceRoot = this._sourceRoot; 470 } 471 if (this._sourcesContents) { 472 map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); 473 } 474 475 return map; 476 }; 477 478 /** 479 * Render the source map being generated to a string. 480 */ 481 SourceMapGenerator.prototype.toString = 482 function SourceMapGenerator_toString() { 483 return JSON.stringify(this.toJSON()); 484 }; 485 486 exports.SourceMapGenerator = SourceMapGenerator; 487 488 489/***/ }), 490/* 2 */ 491/***/ (function(module, exports, __webpack_require__) { 492 493 /* -*- Mode: js; js-indent-level: 2; -*- */ 494 /* 495 * Copyright 2011 Mozilla Foundation and contributors 496 * Licensed under the New BSD license. See LICENSE or: 497 * http://opensource.org/licenses/BSD-3-Clause 498 * 499 * Based on the Base 64 VLQ implementation in Closure Compiler: 500 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java 501 * 502 * Copyright 2011 The Closure Compiler Authors. All rights reserved. 503 * Redistribution and use in source and binary forms, with or without 504 * modification, are permitted provided that the following conditions are 505 * met: 506 * 507 * * Redistributions of source code must retain the above copyright 508 * notice, this list of conditions and the following disclaimer. 509 * * Redistributions in binary form must reproduce the above 510 * copyright notice, this list of conditions and the following 511 * disclaimer in the documentation and/or other materials provided 512 * with the distribution. 513 * * Neither the name of Google Inc. nor the names of its 514 * contributors may be used to endorse or promote products derived 515 * from this software without specific prior written permission. 516 * 517 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 518 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 519 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 520 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 521 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 522 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 523 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 524 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 525 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 526 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 527 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 528 */ 529 530 var base64 = __webpack_require__(3); 531 532 // A single base 64 digit can contain 6 bits of data. For the base 64 variable 533 // length quantities we use in the source map spec, the first bit is the sign, 534 // the next four bits are the actual value, and the 6th bit is the 535 // continuation bit. The continuation bit tells us whether there are more 536 // digits in this value following this digit. 537 // 538 // Continuation 539 // | Sign 540 // | | 541 // V V 542 // 101011 543 544 var VLQ_BASE_SHIFT = 5; 545 546 // binary: 100000 547 var VLQ_BASE = 1 << VLQ_BASE_SHIFT; 548 549 // binary: 011111 550 var VLQ_BASE_MASK = VLQ_BASE - 1; 551 552 // binary: 100000 553 var VLQ_CONTINUATION_BIT = VLQ_BASE; 554 555 /** 556 * Converts from a two-complement value to a value where the sign bit is 557 * placed in the least significant bit. For example, as decimals: 558 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) 559 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) 560 */ 561 function toVLQSigned(aValue) { 562 return aValue < 0 563 ? ((-aValue) << 1) + 1 564 : (aValue << 1) + 0; 565 } 566 567 /** 568 * Converts to a two-complement value from a value where the sign bit is 569 * placed in the least significant bit. For example, as decimals: 570 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 571 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 572 */ 573 function fromVLQSigned(aValue) { 574 var isNegative = (aValue & 1) === 1; 575 var shifted = aValue >> 1; 576 return isNegative 577 ? -shifted 578 : shifted; 579 } 580 581 /** 582 * Returns the base 64 VLQ encoded value. 583 */ 584 exports.encode = function base64VLQ_encode(aValue) { 585 var encoded = ""; 586 var digit; 587 588 var vlq = toVLQSigned(aValue); 589 590 do { 591 digit = vlq & VLQ_BASE_MASK; 592 vlq >>>= VLQ_BASE_SHIFT; 593 if (vlq > 0) { 594 // There are still more digits in this value, so we must make sure the 595 // continuation bit is marked. 596 digit |= VLQ_CONTINUATION_BIT; 597 } 598 encoded += base64.encode(digit); 599 } while (vlq > 0); 600 601 return encoded; 602 }; 603 604 /** 605 * Decodes the next base 64 VLQ value from the given string and returns the 606 * value and the rest of the string via the out parameter. 607 */ 608 exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { 609 var strLen = aStr.length; 610 var result = 0; 611 var shift = 0; 612 var continuation, digit; 613 614 do { 615 if (aIndex >= strLen) { 616 throw new Error("Expected more digits in base 64 VLQ value."); 617 } 618 619 digit = base64.decode(aStr.charCodeAt(aIndex++)); 620 if (digit === -1) { 621 throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); 622 } 623 624 continuation = !!(digit & VLQ_CONTINUATION_BIT); 625 digit &= VLQ_BASE_MASK; 626 result = result + (digit << shift); 627 shift += VLQ_BASE_SHIFT; 628 } while (continuation); 629 630 aOutParam.value = fromVLQSigned(result); 631 aOutParam.rest = aIndex; 632 }; 633 634 635/***/ }), 636/* 3 */ 637/***/ (function(module, exports) { 638 639 /* -*- Mode: js; js-indent-level: 2; -*- */ 640 /* 641 * Copyright 2011 Mozilla Foundation and contributors 642 * Licensed under the New BSD license. See LICENSE or: 643 * http://opensource.org/licenses/BSD-3-Clause 644 */ 645 646 var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); 647 648 /** 649 * Encode an integer in the range of 0 to 63 to a single base 64 digit. 650 */ 651 exports.encode = function (number) { 652 if (0 <= number && number < intToCharMap.length) { 653 return intToCharMap[number]; 654 } 655 throw new TypeError("Must be between 0 and 63: " + number); 656 }; 657 658 /** 659 * Decode a single base 64 character code digit to an integer. Returns -1 on 660 * failure. 661 */ 662 exports.decode = function (charCode) { 663 var bigA = 65; // 'A' 664 var bigZ = 90; // 'Z' 665 666 var littleA = 97; // 'a' 667 var littleZ = 122; // 'z' 668 669 var zero = 48; // '0' 670 var nine = 57; // '9' 671 672 var plus = 43; // '+' 673 var slash = 47; // '/' 674 675 var littleOffset = 26; 676 var numberOffset = 52; 677 678 // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ 679 if (bigA <= charCode && charCode <= bigZ) { 680 return (charCode - bigA); 681 } 682 683 // 26 - 51: abcdefghijklmnopqrstuvwxyz 684 if (littleA <= charCode && charCode <= littleZ) { 685 return (charCode - littleA + littleOffset); 686 } 687 688 // 52 - 61: 0123456789 689 if (zero <= charCode && charCode <= nine) { 690 return (charCode - zero + numberOffset); 691 } 692 693 // 62: + 694 if (charCode == plus) { 695 return 62; 696 } 697 698 // 63: / 699 if (charCode == slash) { 700 return 63; 701 } 702 703 // Invalid base64 digit. 704 return -1; 705 }; 706 707 708/***/ }), 709/* 4 */ 710/***/ (function(module, exports) { 711 712 /* -*- Mode: js; js-indent-level: 2; -*- */ 713 /* 714 * Copyright 2011 Mozilla Foundation and contributors 715 * Licensed under the New BSD license. See LICENSE or: 716 * http://opensource.org/licenses/BSD-3-Clause 717 */ 718 719 /** 720 * This is a helper function for getting values from parameter/options 721 * objects. 722 * 723 * @param args The object we are extracting values from 724 * @param name The name of the property we are getting. 725 * @param defaultValue An optional value to return if the property is missing 726 * from the object. If this is not specified and the property is missing, an 727 * error will be thrown. 728 */ 729 function getArg(aArgs, aName, aDefaultValue) { 730 if (aName in aArgs) { 731 return aArgs[aName]; 732 } else if (arguments.length === 3) { 733 return aDefaultValue; 734 } else { 735 throw new Error('"' + aName + '" is a required argument.'); 736 } 737 } 738 exports.getArg = getArg; 739 740 var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; 741 var dataUrlRegexp = /^data:.+\,.+$/; 742 743 function urlParse(aUrl) { 744 var match = aUrl.match(urlRegexp); 745 if (!match) { 746 return null; 747 } 748 return { 749 scheme: match[1], 750 auth: match[2], 751 host: match[3], 752 port: match[4], 753 path: match[5] 754 }; 755 } 756 exports.urlParse = urlParse; 757 758 function urlGenerate(aParsedUrl) { 759 var url = ''; 760 if (aParsedUrl.scheme) { 761 url += aParsedUrl.scheme + ':'; 762 } 763 url += '//'; 764 if (aParsedUrl.auth) { 765 url += aParsedUrl.auth + '@'; 766 } 767 if (aParsedUrl.host) { 768 url += aParsedUrl.host; 769 } 770 if (aParsedUrl.port) { 771 url += ":" + aParsedUrl.port 772 } 773 if (aParsedUrl.path) { 774 url += aParsedUrl.path; 775 } 776 return url; 777 } 778 exports.urlGenerate = urlGenerate; 779 780 /** 781 * Normalizes a path, or the path portion of a URL: 782 * 783 * - Replaces consecutive slashes with one slash. 784 * - Removes unnecessary '.' parts. 785 * - Removes unnecessary '<dir>/..' parts. 786 * 787 * Based on code in the Node.js 'path' core module. 788 * 789 * @param aPath The path or url to normalize. 790 */ 791 function normalize(aPath) { 792 var path = aPath; 793 var url = urlParse(aPath); 794 if (url) { 795 if (!url.path) { 796 return aPath; 797 } 798 path = url.path; 799 } 800 var isAbsolute = exports.isAbsolute(path); 801 802 var parts = path.split(/\/+/); 803 for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { 804 part = parts[i]; 805 if (part === '.') { 806 parts.splice(i, 1); 807 } else if (part === '..') { 808 up++; 809 } else if (up > 0) { 810 if (part === '') { 811 // The first part is blank if the path is absolute. Trying to go 812 // above the root is a no-op. Therefore we can remove all '..' parts 813 // directly after the root. 814 parts.splice(i + 1, up); 815 up = 0; 816 } else { 817 parts.splice(i, 2); 818 up--; 819 } 820 } 821 } 822 path = parts.join('/'); 823 824 if (path === '') { 825 path = isAbsolute ? '/' : '.'; 826 } 827 828 if (url) { 829 url.path = path; 830 return urlGenerate(url); 831 } 832 return path; 833 } 834 exports.normalize = normalize; 835 836 /** 837 * Joins two paths/URLs. 838 * 839 * @param aRoot The root path or URL. 840 * @param aPath The path or URL to be joined with the root. 841 * 842 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a 843 * scheme-relative URL: Then the scheme of aRoot, if any, is prepended 844 * first. 845 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion 846 * is updated with the result and aRoot is returned. Otherwise the result 847 * is returned. 848 * - If aPath is absolute, the result is aPath. 849 * - Otherwise the two paths are joined with a slash. 850 * - Joining for example 'http://' and 'www.example.com' is also supported. 851 */ 852 function join(aRoot, aPath) { 853 if (aRoot === "") { 854 aRoot = "."; 855 } 856 if (aPath === "") { 857 aPath = "."; 858 } 859 var aPathUrl = urlParse(aPath); 860 var aRootUrl = urlParse(aRoot); 861 if (aRootUrl) { 862 aRoot = aRootUrl.path || '/'; 863 } 864 865 // `join(foo, '//www.example.org')` 866 if (aPathUrl && !aPathUrl.scheme) { 867 if (aRootUrl) { 868 aPathUrl.scheme = aRootUrl.scheme; 869 } 870 return urlGenerate(aPathUrl); 871 } 872 873 if (aPathUrl || aPath.match(dataUrlRegexp)) { 874 return aPath; 875 } 876 877 // `join('http://', 'www.example.com')` 878 if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { 879 aRootUrl.host = aPath; 880 return urlGenerate(aRootUrl); 881 } 882 883 var joined = aPath.charAt(0) === '/' 884 ? aPath 885 : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); 886 887 if (aRootUrl) { 888 aRootUrl.path = joined; 889 return urlGenerate(aRootUrl); 890 } 891 return joined; 892 } 893 exports.join = join; 894 895 exports.isAbsolute = function (aPath) { 896 return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); 897 }; 898 899 /** 900 * Make a path relative to a URL or another path. 901 * 902 * @param aRoot The root path or URL. 903 * @param aPath The path or URL to be made relative to aRoot. 904 */ 905 function relative(aRoot, aPath) { 906 if (aRoot === "") { 907 aRoot = "."; 908 } 909 910 aRoot = aRoot.replace(/\/$/, ''); 911 912 // It is possible for the path to be above the root. In this case, simply 913 // checking whether the root is a prefix of the path won't work. Instead, we 914 // need to remove components from the root one by one, until either we find 915 // a prefix that fits, or we run out of components to remove. 916 var level = 0; 917 while (aPath.indexOf(aRoot + '/') !== 0) { 918 var index = aRoot.lastIndexOf("/"); 919 if (index < 0) { 920 return aPath; 921 } 922 923 // If the only part of the root that is left is the scheme (i.e. http://, 924 // file:///, etc.), one or more slashes (/), or simply nothing at all, we 925 // have exhausted all components, so the path is not relative to the root. 926 aRoot = aRoot.slice(0, index); 927 if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { 928 return aPath; 929 } 930 931 ++level; 932 } 933 934 // Make sure we add a "../" for each component we removed from the root. 935 return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); 936 } 937 exports.relative = relative; 938 939 var supportsNullProto = (function () { 940 var obj = Object.create(null); 941 return !('__proto__' in obj); 942 }()); 943 944 function identity (s) { 945 return s; 946 } 947 948 /** 949 * Because behavior goes wacky when you set `__proto__` on objects, we 950 * have to prefix all the strings in our set with an arbitrary character. 951 * 952 * See https://github.com/mozilla/source-map/pull/31 and 953 * https://github.com/mozilla/source-map/issues/30 954 * 955 * @param String aStr 956 */ 957 function toSetString(aStr) { 958 if (isProtoString(aStr)) { 959 return '$' + aStr; 960 } 961 962 return aStr; 963 } 964 exports.toSetString = supportsNullProto ? identity : toSetString; 965 966 function fromSetString(aStr) { 967 if (isProtoString(aStr)) { 968 return aStr.slice(1); 969 } 970 971 return aStr; 972 } 973 exports.fromSetString = supportsNullProto ? identity : fromSetString; 974 975 function isProtoString(s) { 976 if (!s) { 977 return false; 978 } 979 980 var length = s.length; 981 982 if (length < 9 /* "__proto__".length */) { 983 return false; 984 } 985 986 if (s.charCodeAt(length - 1) !== 95 /* '_' */ || 987 s.charCodeAt(length - 2) !== 95 /* '_' */ || 988 s.charCodeAt(length - 3) !== 111 /* 'o' */ || 989 s.charCodeAt(length - 4) !== 116 /* 't' */ || 990 s.charCodeAt(length - 5) !== 111 /* 'o' */ || 991 s.charCodeAt(length - 6) !== 114 /* 'r' */ || 992 s.charCodeAt(length - 7) !== 112 /* 'p' */ || 993 s.charCodeAt(length - 8) !== 95 /* '_' */ || 994 s.charCodeAt(length - 9) !== 95 /* '_' */) { 995 return false; 996 } 997 998 for (var i = length - 10; i >= 0; i--) { 999 if (s.charCodeAt(i) !== 36 /* '$' */) { 1000 return false; 1001 } 1002 } 1003 1004 return true; 1005 } 1006 1007 /** 1008 * Comparator between two mappings where the original positions are compared. 1009 * 1010 * Optionally pass in `true` as `onlyCompareGenerated` to consider two 1011 * mappings with the same original source/line/column, but different generated 1012 * line and column the same. Useful when searching for a mapping with a 1013 * stubbed out mapping. 1014 */ 1015 function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { 1016 var cmp = mappingA.source - mappingB.source; 1017 if (cmp !== 0) { 1018 return cmp; 1019 } 1020 1021 cmp = mappingA.originalLine - mappingB.originalLine; 1022 if (cmp !== 0) { 1023 return cmp; 1024 } 1025 1026 cmp = mappingA.originalColumn - mappingB.originalColumn; 1027 if (cmp !== 0 || onlyCompareOriginal) { 1028 return cmp; 1029 } 1030 1031 cmp = mappingA.generatedColumn - mappingB.generatedColumn; 1032 if (cmp !== 0) { 1033 return cmp; 1034 } 1035 1036 cmp = mappingA.generatedLine - mappingB.generatedLine; 1037 if (cmp !== 0) { 1038 return cmp; 1039 } 1040 1041 return mappingA.name - mappingB.name; 1042 } 1043 exports.compareByOriginalPositions = compareByOriginalPositions; 1044 1045 /** 1046 * Comparator between two mappings with deflated source and name indices where 1047 * the generated positions are compared. 1048 * 1049 * Optionally pass in `true` as `onlyCompareGenerated` to consider two 1050 * mappings with the same generated line and column, but different 1051 * source/name/original line and column the same. Useful when searching for a 1052 * mapping with a stubbed out mapping. 1053 */ 1054 function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { 1055 var cmp = mappingA.generatedLine - mappingB.generatedLine; 1056 if (cmp !== 0) { 1057 return cmp; 1058 } 1059 1060 cmp = mappingA.generatedColumn - mappingB.generatedColumn; 1061 if (cmp !== 0 || onlyCompareGenerated) { 1062 return cmp; 1063 } 1064 1065 cmp = mappingA.source - mappingB.source; 1066 if (cmp !== 0) { 1067 return cmp; 1068 } 1069 1070 cmp = mappingA.originalLine - mappingB.originalLine; 1071 if (cmp !== 0) { 1072 return cmp; 1073 } 1074 1075 cmp = mappingA.originalColumn - mappingB.originalColumn; 1076 if (cmp !== 0) { 1077 return cmp; 1078 } 1079 1080 return mappingA.name - mappingB.name; 1081 } 1082 exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; 1083 1084 function strcmp(aStr1, aStr2) { 1085 if (aStr1 === aStr2) { 1086 return 0; 1087 } 1088 1089 if (aStr1 > aStr2) { 1090 return 1; 1091 } 1092 1093 return -1; 1094 } 1095 1096 /** 1097 * Comparator between two mappings with inflated source and name strings where 1098 * the generated positions are compared. 1099 */ 1100 function compareByGeneratedPositionsInflated(mappingA, mappingB) { 1101 var cmp = mappingA.generatedLine - mappingB.generatedLine; 1102 if (cmp !== 0) { 1103 return cmp; 1104 } 1105 1106 cmp = mappingA.generatedColumn - mappingB.generatedColumn; 1107 if (cmp !== 0) { 1108 return cmp; 1109 } 1110 1111 cmp = strcmp(mappingA.source, mappingB.source); 1112 if (cmp !== 0) { 1113 return cmp; 1114 } 1115 1116 cmp = mappingA.originalLine - mappingB.originalLine; 1117 if (cmp !== 0) { 1118 return cmp; 1119 } 1120 1121 cmp = mappingA.originalColumn - mappingB.originalColumn; 1122 if (cmp !== 0) { 1123 return cmp; 1124 } 1125 1126 return strcmp(mappingA.name, mappingB.name); 1127 } 1128 exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; 1129 1130 1131/***/ }), 1132/* 5 */ 1133/***/ (function(module, exports, __webpack_require__) { 1134 1135 /* -*- Mode: js; js-indent-level: 2; -*- */ 1136 /* 1137 * Copyright 2011 Mozilla Foundation and contributors 1138 * Licensed under the New BSD license. See LICENSE or: 1139 * http://opensource.org/licenses/BSD-3-Clause 1140 */ 1141 1142 var util = __webpack_require__(4); 1143 var has = Object.prototype.hasOwnProperty; 1144 var hasNativeMap = typeof Map !== "undefined"; 1145 1146 /** 1147 * A data structure which is a combination of an array and a set. Adding a new 1148 * member is O(1), testing for membership is O(1), and finding the index of an 1149 * element is O(1). Removing elements from the set is not supported. Only 1150 * strings are supported for membership. 1151 */ 1152 function ArraySet() { 1153 this._array = []; 1154 this._set = hasNativeMap ? new Map() : Object.create(null); 1155 } 1156 1157 /** 1158 * Static method for creating ArraySet instances from an existing array. 1159 */ 1160 ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { 1161 var set = new ArraySet(); 1162 for (var i = 0, len = aArray.length; i < len; i++) { 1163 set.add(aArray[i], aAllowDuplicates); 1164 } 1165 return set; 1166 }; 1167 1168 /** 1169 * Return how many unique items are in this ArraySet. If duplicates have been 1170 * added, than those do not count towards the size. 1171 * 1172 * @returns Number 1173 */ 1174 ArraySet.prototype.size = function ArraySet_size() { 1175 return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; 1176 }; 1177 1178 /** 1179 * Add the given string to this set. 1180 * 1181 * @param String aStr 1182 */ 1183 ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { 1184 var sStr = hasNativeMap ? aStr : util.toSetString(aStr); 1185 var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); 1186 var idx = this._array.length; 1187 if (!isDuplicate || aAllowDuplicates) { 1188 this._array.push(aStr); 1189 } 1190 if (!isDuplicate) { 1191 if (hasNativeMap) { 1192 this._set.set(aStr, idx); 1193 } else { 1194 this._set[sStr] = idx; 1195 } 1196 } 1197 }; 1198 1199 /** 1200 * Is the given string a member of this set? 1201 * 1202 * @param String aStr 1203 */ 1204 ArraySet.prototype.has = function ArraySet_has(aStr) { 1205 if (hasNativeMap) { 1206 return this._set.has(aStr); 1207 } else { 1208 var sStr = util.toSetString(aStr); 1209 return has.call(this._set, sStr); 1210 } 1211 }; 1212 1213 /** 1214 * What is the index of the given string in the array? 1215 * 1216 * @param String aStr 1217 */ 1218 ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { 1219 if (hasNativeMap) { 1220 var idx = this._set.get(aStr); 1221 if (idx >= 0) { 1222 return idx; 1223 } 1224 } else { 1225 var sStr = util.toSetString(aStr); 1226 if (has.call(this._set, sStr)) { 1227 return this._set[sStr]; 1228 } 1229 } 1230 1231 throw new Error('"' + aStr + '" is not in the set.'); 1232 }; 1233 1234 /** 1235 * What is the element at the given index? 1236 * 1237 * @param Number aIdx 1238 */ 1239 ArraySet.prototype.at = function ArraySet_at(aIdx) { 1240 if (aIdx >= 0 && aIdx < this._array.length) { 1241 return this._array[aIdx]; 1242 } 1243 throw new Error('No element indexed by ' + aIdx); 1244 }; 1245 1246 /** 1247 * Returns the array representation of this set (which has the proper indices 1248 * indicated by indexOf). Note that this is a copy of the internal array used 1249 * for storing the members so that no one can mess with internal state. 1250 */ 1251 ArraySet.prototype.toArray = function ArraySet_toArray() { 1252 return this._array.slice(); 1253 }; 1254 1255 exports.ArraySet = ArraySet; 1256 1257 1258/***/ }), 1259/* 6 */ 1260/***/ (function(module, exports, __webpack_require__) { 1261 1262 /* -*- Mode: js; js-indent-level: 2; -*- */ 1263 /* 1264 * Copyright 2014 Mozilla Foundation and contributors 1265 * Licensed under the New BSD license. See LICENSE or: 1266 * http://opensource.org/licenses/BSD-3-Clause 1267 */ 1268 1269 var util = __webpack_require__(4); 1270 1271 /** 1272 * Determine whether mappingB is after mappingA with respect to generated 1273 * position. 1274 */ 1275 function generatedPositionAfter(mappingA, mappingB) { 1276 // Optimized for most common case 1277 var lineA = mappingA.generatedLine; 1278 var lineB = mappingB.generatedLine; 1279 var columnA = mappingA.generatedColumn; 1280 var columnB = mappingB.generatedColumn; 1281 return lineB > lineA || lineB == lineA && columnB >= columnA || 1282 util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; 1283 } 1284 1285 /** 1286 * A data structure to provide a sorted view of accumulated mappings in a 1287 * performance conscious manner. It trades a neglibable overhead in general 1288 * case for a large speedup in case of mappings being added in order. 1289 */ 1290 function MappingList() { 1291 this._array = []; 1292 this._sorted = true; 1293 // Serves as infimum 1294 this._last = {generatedLine: -1, generatedColumn: 0}; 1295 } 1296 1297 /** 1298 * Iterate through internal items. This method takes the same arguments that 1299 * `Array.prototype.forEach` takes. 1300 * 1301 * NOTE: The order of the mappings is NOT guaranteed. 1302 */ 1303 MappingList.prototype.unsortedForEach = 1304 function MappingList_forEach(aCallback, aThisArg) { 1305 this._array.forEach(aCallback, aThisArg); 1306 }; 1307 1308 /** 1309 * Add the given source mapping. 1310 * 1311 * @param Object aMapping 1312 */ 1313 MappingList.prototype.add = function MappingList_add(aMapping) { 1314 if (generatedPositionAfter(this._last, aMapping)) { 1315 this._last = aMapping; 1316 this._array.push(aMapping); 1317 } else { 1318 this._sorted = false; 1319 this._array.push(aMapping); 1320 } 1321 }; 1322 1323 /** 1324 * Returns the flat, sorted array of mappings. The mappings are sorted by 1325 * generated position. 1326 * 1327 * WARNING: This method returns internal data without copying, for 1328 * performance. The return value must NOT be mutated, and should be treated as 1329 * an immutable borrow. If you want to take ownership, you must make your own 1330 * copy. 1331 */ 1332 MappingList.prototype.toArray = function MappingList_toArray() { 1333 if (!this._sorted) { 1334 this._array.sort(util.compareByGeneratedPositionsInflated); 1335 this._sorted = true; 1336 } 1337 return this._array; 1338 }; 1339 1340 exports.MappingList = MappingList; 1341 1342 1343/***/ }), 1344/* 7 */ 1345/***/ (function(module, exports, __webpack_require__) { 1346 1347 /* -*- Mode: js; js-indent-level: 2; -*- */ 1348 /* 1349 * Copyright 2011 Mozilla Foundation and contributors 1350 * Licensed under the New BSD license. See LICENSE or: 1351 * http://opensource.org/licenses/BSD-3-Clause 1352 */ 1353 1354 var util = __webpack_require__(4); 1355 var binarySearch = __webpack_require__(8); 1356 var ArraySet = __webpack_require__(5).ArraySet; 1357 var base64VLQ = __webpack_require__(2); 1358 var quickSort = __webpack_require__(9).quickSort; 1359 1360 function SourceMapConsumer(aSourceMap) { 1361 var sourceMap = aSourceMap; 1362 if (typeof aSourceMap === 'string') { 1363 sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); 1364 } 1365 1366 return sourceMap.sections != null 1367 ? new IndexedSourceMapConsumer(sourceMap) 1368 : new BasicSourceMapConsumer(sourceMap); 1369 } 1370 1371 SourceMapConsumer.fromSourceMap = function(aSourceMap) { 1372 return BasicSourceMapConsumer.fromSourceMap(aSourceMap); 1373 } 1374 1375 /** 1376 * The version of the source mapping spec that we are consuming. 1377 */ 1378 SourceMapConsumer.prototype._version = 3; 1379 1380 // `__generatedMappings` and `__originalMappings` are arrays that hold the 1381 // parsed mapping coordinates from the source map's "mappings" attribute. They 1382 // are lazily instantiated, accessed via the `_generatedMappings` and 1383 // `_originalMappings` getters respectively, and we only parse the mappings 1384 // and create these arrays once queried for a source location. We jump through 1385 // these hoops because there can be many thousands of mappings, and parsing 1386 // them is expensive, so we only want to do it if we must. 1387 // 1388 // Each object in the arrays is of the form: 1389 // 1390 // { 1391 // generatedLine: The line number in the generated code, 1392 // generatedColumn: The column number in the generated code, 1393 // source: The path to the original source file that generated this 1394 // chunk of code, 1395 // originalLine: The line number in the original source that 1396 // corresponds to this chunk of generated code, 1397 // originalColumn: The column number in the original source that 1398 // corresponds to this chunk of generated code, 1399 // name: The name of the original symbol which generated this chunk of 1400 // code. 1401 // } 1402 // 1403 // All properties except for `generatedLine` and `generatedColumn` can be 1404 // `null`. 1405 // 1406 // `_generatedMappings` is ordered by the generated positions. 1407 // 1408 // `_originalMappings` is ordered by the original positions. 1409 1410 SourceMapConsumer.prototype.__generatedMappings = null; 1411 Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { 1412 get: function () { 1413 if (!this.__generatedMappings) { 1414 this._parseMappings(this._mappings, this.sourceRoot); 1415 } 1416 1417 return this.__generatedMappings; 1418 } 1419 }); 1420 1421 SourceMapConsumer.prototype.__originalMappings = null; 1422 Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { 1423 get: function () { 1424 if (!this.__originalMappings) { 1425 this._parseMappings(this._mappings, this.sourceRoot); 1426 } 1427 1428 return this.__originalMappings; 1429 } 1430 }); 1431 1432 SourceMapConsumer.prototype._charIsMappingSeparator = 1433 function SourceMapConsumer_charIsMappingSeparator(aStr, index) { 1434 var c = aStr.charAt(index); 1435 return c === ";" || c === ","; 1436 }; 1437 1438 /** 1439 * Parse the mappings in a string in to a data structure which we can easily 1440 * query (the ordered arrays in the `this.__generatedMappings` and 1441 * `this.__originalMappings` properties). 1442 */ 1443 SourceMapConsumer.prototype._parseMappings = 1444 function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { 1445 throw new Error("Subclasses must implement _parseMappings"); 1446 }; 1447 1448 SourceMapConsumer.GENERATED_ORDER = 1; 1449 SourceMapConsumer.ORIGINAL_ORDER = 2; 1450 1451 SourceMapConsumer.GREATEST_LOWER_BOUND = 1; 1452 SourceMapConsumer.LEAST_UPPER_BOUND = 2; 1453 1454 /** 1455 * Iterate over each mapping between an original source/line/column and a 1456 * generated line/column in this source map. 1457 * 1458 * @param Function aCallback 1459 * The function that is called with each mapping. 1460 * @param Object aContext 1461 * Optional. If specified, this object will be the value of `this` every 1462 * time that `aCallback` is called. 1463 * @param aOrder 1464 * Either `SourceMapConsumer.GENERATED_ORDER` or 1465 * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to 1466 * iterate over the mappings sorted by the generated file's line/column 1467 * order or the original's source/line/column order, respectively. Defaults to 1468 * `SourceMapConsumer.GENERATED_ORDER`. 1469 */ 1470 SourceMapConsumer.prototype.eachMapping = 1471 function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { 1472 var context = aContext || null; 1473 var order = aOrder || SourceMapConsumer.GENERATED_ORDER; 1474 1475 var mappings; 1476 switch (order) { 1477 case SourceMapConsumer.GENERATED_ORDER: 1478 mappings = this._generatedMappings; 1479 break; 1480 case SourceMapConsumer.ORIGINAL_ORDER: 1481 mappings = this._originalMappings; 1482 break; 1483 default: 1484 throw new Error("Unknown order of iteration."); 1485 } 1486 1487 var sourceRoot = this.sourceRoot; 1488 mappings.map(function (mapping) { 1489 var source = mapping.source === null ? null : this._sources.at(mapping.source); 1490 if (source != null && sourceRoot != null) { 1491 source = util.join(sourceRoot, source); 1492 } 1493 return { 1494 source: source, 1495 generatedLine: mapping.generatedLine, 1496 generatedColumn: mapping.generatedColumn, 1497 originalLine: mapping.originalLine, 1498 originalColumn: mapping.originalColumn, 1499 name: mapping.name === null ? null : this._names.at(mapping.name) 1500 }; 1501 }, this).forEach(aCallback, context); 1502 }; 1503 1504 /** 1505 * Returns all generated line and column information for the original source, 1506 * line, and column provided. If no column is provided, returns all mappings 1507 * corresponding to a either the line we are searching for or the next 1508 * closest line that has any mappings. Otherwise, returns all mappings 1509 * corresponding to the given line and either the column we are searching for 1510 * or the next closest column that has any offsets. 1511 * 1512 * The only argument is an object with the following properties: 1513 * 1514 * - source: The filename of the original source. 1515 * - line: The line number in the original source. 1516 * - column: Optional. the column number in the original source. 1517 * 1518 * and an array of objects is returned, each with the following properties: 1519 * 1520 * - line: The line number in the generated source, or null. 1521 * - column: The column number in the generated source, or null. 1522 */ 1523 SourceMapConsumer.prototype.allGeneratedPositionsFor = 1524 function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { 1525 var line = util.getArg(aArgs, 'line'); 1526 1527 // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping 1528 // returns the index of the closest mapping less than the needle. By 1529 // setting needle.originalColumn to 0, we thus find the last mapping for 1530 // the given line, provided such a mapping exists. 1531 var needle = { 1532 source: util.getArg(aArgs, 'source'), 1533 originalLine: line, 1534 originalColumn: util.getArg(aArgs, 'column', 0) 1535 }; 1536 1537 if (this.sourceRoot != null) { 1538 needle.source = util.relative(this.sourceRoot, needle.source); 1539 } 1540 if (!this._sources.has(needle.source)) { 1541 return []; 1542 } 1543 needle.source = this._sources.indexOf(needle.source); 1544 1545 var mappings = []; 1546 1547 var index = this._findMapping(needle, 1548 this._originalMappings, 1549 "originalLine", 1550 "originalColumn", 1551 util.compareByOriginalPositions, 1552 binarySearch.LEAST_UPPER_BOUND); 1553 if (index >= 0) { 1554 var mapping = this._originalMappings[index]; 1555 1556 if (aArgs.column === undefined) { 1557 var originalLine = mapping.originalLine; 1558 1559 // Iterate until either we run out of mappings, or we run into 1560 // a mapping for a different line than the one we found. Since 1561 // mappings are sorted, this is guaranteed to find all mappings for 1562 // the line we found. 1563 while (mapping && mapping.originalLine === originalLine) { 1564 mappings.push({ 1565 line: util.getArg(mapping, 'generatedLine', null), 1566 column: util.getArg(mapping, 'generatedColumn', null), 1567 lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) 1568 }); 1569 1570 mapping = this._originalMappings[++index]; 1571 } 1572 } else { 1573 var originalColumn = mapping.originalColumn; 1574 1575 // Iterate until either we run out of mappings, or we run into 1576 // a mapping for a different line than the one we were searching for. 1577 // Since mappings are sorted, this is guaranteed to find all mappings for 1578 // the line we are searching for. 1579 while (mapping && 1580 mapping.originalLine === line && 1581 mapping.originalColumn == originalColumn) { 1582 mappings.push({ 1583 line: util.getArg(mapping, 'generatedLine', null), 1584 column: util.getArg(mapping, 'generatedColumn', null), 1585 lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) 1586 }); 1587 1588 mapping = this._originalMappings[++index]; 1589 } 1590 } 1591 } 1592 1593 return mappings; 1594 }; 1595 1596 exports.SourceMapConsumer = SourceMapConsumer; 1597 1598 /** 1599 * A BasicSourceMapConsumer instance represents a parsed source map which we can 1600 * query for information about the original file positions by giving it a file 1601 * position in the generated source. 1602 * 1603 * The only parameter is the raw source map (either as a JSON string, or 1604 * already parsed to an object). According to the spec, source maps have the 1605 * following attributes: 1606 * 1607 * - version: Which version of the source map spec this map is following. 1608 * - sources: An array of URLs to the original source files. 1609 * - names: An array of identifiers which can be referrenced by individual mappings. 1610 * - sourceRoot: Optional. The URL root from which all sources are relative. 1611 * - sourcesContent: Optional. An array of contents of the original source files. 1612 * - mappings: A string of base64 VLQs which contain the actual mappings. 1613 * - file: Optional. The generated file this source map is associated with. 1614 * 1615 * Here is an example source map, taken from the source map spec[0]: 1616 * 1617 * { 1618 * version : 3, 1619 * file: "out.js", 1620 * sourceRoot : "", 1621 * sources: ["foo.js", "bar.js"], 1622 * names: ["src", "maps", "are", "fun"], 1623 * mappings: "AA,AB;;ABCDE;" 1624 * } 1625 * 1626 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# 1627 */ 1628 function BasicSourceMapConsumer(aSourceMap) { 1629 var sourceMap = aSourceMap; 1630 if (typeof aSourceMap === 'string') { 1631 sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); 1632 } 1633 1634 var version = util.getArg(sourceMap, 'version'); 1635 var sources = util.getArg(sourceMap, 'sources'); 1636 // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which 1637 // requires the array) to play nice here. 1638 var names = util.getArg(sourceMap, 'names', []); 1639 var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); 1640 var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); 1641 var mappings = util.getArg(sourceMap, 'mappings'); 1642 var file = util.getArg(sourceMap, 'file', null); 1643 1644 // Once again, Sass deviates from the spec and supplies the version as a 1645 // string rather than a number, so we use loose equality checking here. 1646 if (version != this._version) { 1647 throw new Error('Unsupported version: ' + version); 1648 } 1649 1650 sources = sources 1651 .map(String) 1652 // Some source maps produce relative source paths like "./foo.js" instead of 1653 // "foo.js". Normalize these first so that future comparisons will succeed. 1654 // See bugzil.la/1090768. 1655 .map(util.normalize) 1656 // Always ensure that absolute sources are internally stored relative to 1657 // the source root, if the source root is absolute. Not doing this would 1658 // be particularly problematic when the source root is a prefix of the 1659 // source (valid, but why??). See github issue #199 and bugzil.la/1188982. 1660 .map(function (source) { 1661 return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) 1662 ? util.relative(sourceRoot, source) 1663 : source; 1664 }); 1665 1666 // Pass `true` below to allow duplicate names and sources. While source maps 1667 // are intended to be compressed and deduplicated, the TypeScript compiler 1668 // sometimes generates source maps with duplicates in them. See Github issue 1669 // #72 and bugzil.la/889492. 1670 this._names = ArraySet.fromArray(names.map(String), true); 1671 this._sources = ArraySet.fromArray(sources, true); 1672 1673 this.sourceRoot = sourceRoot; 1674 this.sourcesContent = sourcesContent; 1675 this._mappings = mappings; 1676 this.file = file; 1677 } 1678 1679 BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); 1680 BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; 1681 1682 /** 1683 * Create a BasicSourceMapConsumer from a SourceMapGenerator. 1684 * 1685 * @param SourceMapGenerator aSourceMap 1686 * The source map that will be consumed. 1687 * @returns BasicSourceMapConsumer 1688 */ 1689 BasicSourceMapConsumer.fromSourceMap = 1690 function SourceMapConsumer_fromSourceMap(aSourceMap) { 1691 var smc = Object.create(BasicSourceMapConsumer.prototype); 1692 1693 var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); 1694 var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); 1695 smc.sourceRoot = aSourceMap._sourceRoot; 1696 smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), 1697 smc.sourceRoot); 1698 smc.file = aSourceMap._file; 1699 1700 // Because we are modifying the entries (by converting string sources and 1701 // names to indices into the sources and names ArraySets), we have to make 1702 // a copy of the entry or else bad things happen. Shared mutable state 1703 // strikes again! See github issue #191. 1704 1705 var generatedMappings = aSourceMap._mappings.toArray().slice(); 1706 var destGeneratedMappings = smc.__generatedMappings = []; 1707 var destOriginalMappings = smc.__originalMappings = []; 1708 1709 for (var i = 0, length = generatedMappings.length; i < length; i++) { 1710 var srcMapping = generatedMappings[i]; 1711 var destMapping = new Mapping; 1712 destMapping.generatedLine = srcMapping.generatedLine; 1713 destMapping.generatedColumn = srcMapping.generatedColumn; 1714 1715 if (srcMapping.source) { 1716 destMapping.source = sources.indexOf(srcMapping.source); 1717 destMapping.originalLine = srcMapping.originalLine; 1718 destMapping.originalColumn = srcMapping.originalColumn; 1719 1720 if (srcMapping.name) { 1721 destMapping.name = names.indexOf(srcMapping.name); 1722 } 1723 1724 destOriginalMappings.push(destMapping); 1725 } 1726 1727 destGeneratedMappings.push(destMapping); 1728 } 1729 1730 quickSort(smc.__originalMappings, util.compareByOriginalPositions); 1731 1732 return smc; 1733 }; 1734 1735 /** 1736 * The version of the source mapping spec that we are consuming. 1737 */ 1738 BasicSourceMapConsumer.prototype._version = 3; 1739 1740 /** 1741 * The list of original sources. 1742 */ 1743 Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { 1744 get: function () { 1745 return this._sources.toArray().map(function (s) { 1746 return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; 1747 }, this); 1748 } 1749 }); 1750 1751 /** 1752 * Provide the JIT with a nice shape / hidden class. 1753 */ 1754 function Mapping() { 1755 this.generatedLine = 0; 1756 this.generatedColumn = 0; 1757 this.source = null; 1758 this.originalLine = null; 1759 this.originalColumn = null; 1760 this.name = null; 1761 } 1762 1763 /** 1764 * Parse the mappings in a string in to a data structure which we can easily 1765 * query (the ordered arrays in the `this.__generatedMappings` and 1766 * `this.__originalMappings` properties). 1767 */ 1768 BasicSourceMapConsumer.prototype._parseMappings = 1769 function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { 1770 var generatedLine = 1; 1771 var previousGeneratedColumn = 0; 1772 var previousOriginalLine = 0; 1773 var previousOriginalColumn = 0; 1774 var previousSource = 0; 1775 var previousName = 0; 1776 var length = aStr.length; 1777 var index = 0; 1778 var cachedSegments = {}; 1779 var temp = {}; 1780 var originalMappings = []; 1781 var generatedMappings = []; 1782 var mapping, str, segment, end, value; 1783 1784 while (index < length) { 1785 if (aStr.charAt(index) === ';') { 1786 generatedLine++; 1787 index++; 1788 previousGeneratedColumn = 0; 1789 } 1790 else if (aStr.charAt(index) === ',') { 1791 index++; 1792 } 1793 else { 1794 mapping = new Mapping(); 1795 mapping.generatedLine = generatedLine; 1796 1797 // Because each offset is encoded relative to the previous one, 1798 // many segments often have the same encoding. We can exploit this 1799 // fact by caching the parsed variable length fields of each segment, 1800 // allowing us to avoid a second parse if we encounter the same 1801 // segment again. 1802 for (end = index; end < length; end++) { 1803 if (this._charIsMappingSeparator(aStr, end)) { 1804 break; 1805 } 1806 } 1807 str = aStr.slice(index, end); 1808 1809 segment = cachedSegments[str]; 1810 if (segment) { 1811 index += str.length; 1812 } else { 1813 segment = []; 1814 while (index < end) { 1815 base64VLQ.decode(aStr, index, temp); 1816 value = temp.value; 1817 index = temp.rest; 1818 segment.push(value); 1819 } 1820 1821 if (segment.length === 2) { 1822 throw new Error('Found a source, but no line and column'); 1823 } 1824 1825 if (segment.length === 3) { 1826 throw new Error('Found a source and line, but no column'); 1827 } 1828 1829 cachedSegments[str] = segment; 1830 } 1831 1832 // Generated column. 1833 mapping.generatedColumn = previousGeneratedColumn + segment[0]; 1834 previousGeneratedColumn = mapping.generatedColumn; 1835 1836 if (segment.length > 1) { 1837 // Original source. 1838 mapping.source = previousSource + segment[1]; 1839 previousSource += segment[1]; 1840 1841 // Original line. 1842 mapping.originalLine = previousOriginalLine + segment[2]; 1843 previousOriginalLine = mapping.originalLine; 1844 // Lines are stored 0-based 1845 mapping.originalLine += 1; 1846 1847 // Original column. 1848 mapping.originalColumn = previousOriginalColumn + segment[3]; 1849 previousOriginalColumn = mapping.originalColumn; 1850 1851 if (segment.length > 4) { 1852 // Original name. 1853 mapping.name = previousName + segment[4]; 1854 previousName += segment[4]; 1855 } 1856 } 1857 1858 generatedMappings.push(mapping); 1859 if (typeof mapping.originalLine === 'number') { 1860 originalMappings.push(mapping); 1861 } 1862 } 1863 } 1864 1865 quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); 1866 this.__generatedMappings = generatedMappings; 1867 1868 quickSort(originalMappings, util.compareByOriginalPositions); 1869 this.__originalMappings = originalMappings; 1870 }; 1871 1872 /** 1873 * Find the mapping that best matches the hypothetical "needle" mapping that 1874 * we are searching for in the given "haystack" of mappings. 1875 */ 1876 BasicSourceMapConsumer.prototype._findMapping = 1877 function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, 1878 aColumnName, aComparator, aBias) { 1879 // To return the position we are searching for, we must first find the 1880 // mapping for the given position and then return the opposite position it 1881 // points to. Because the mappings are sorted, we can use binary search to 1882 // find the best mapping. 1883 1884 if (aNeedle[aLineName] <= 0) { 1885 throw new TypeError('Line must be greater than or equal to 1, got ' 1886 + aNeedle[aLineName]); 1887 } 1888 if (aNeedle[aColumnName] < 0) { 1889 throw new TypeError('Column must be greater than or equal to 0, got ' 1890 + aNeedle[aColumnName]); 1891 } 1892 1893 return binarySearch.search(aNeedle, aMappings, aComparator, aBias); 1894 }; 1895 1896 /** 1897 * Compute the last column for each generated mapping. The last column is 1898 * inclusive. 1899 */ 1900 BasicSourceMapConsumer.prototype.computeColumnSpans = 1901 function SourceMapConsumer_computeColumnSpans() { 1902 for (var index = 0; index < this._generatedMappings.length; ++index) { 1903 var mapping = this._generatedMappings[index]; 1904 1905 // Mappings do not contain a field for the last generated columnt. We 1906 // can come up with an optimistic estimate, however, by assuming that 1907 // mappings are contiguous (i.e. given two consecutive mappings, the 1908 // first mapping ends where the second one starts). 1909 if (index + 1 < this._generatedMappings.length) { 1910 var nextMapping = this._generatedMappings[index + 1]; 1911 1912 if (mapping.generatedLine === nextMapping.generatedLine) { 1913 mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; 1914 continue; 1915 } 1916 } 1917 1918 // The last mapping for each line spans the entire line. 1919 mapping.lastGeneratedColumn = Infinity; 1920 } 1921 }; 1922 1923 /** 1924 * Returns the original source, line, and column information for the generated 1925 * source's line and column positions provided. The only argument is an object 1926 * with the following properties: 1927 * 1928 * - line: The line number in the generated source. 1929 * - column: The column number in the generated source. 1930 * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or 1931 * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the 1932 * closest element that is smaller than or greater than the one we are 1933 * searching for, respectively, if the exact element cannot be found. 1934 * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. 1935 * 1936 * and an object is returned with the following properties: 1937 * 1938 * - source: The original source file, or null. 1939 * - line: The line number in the original source, or null. 1940 * - column: The column number in the original source, or null. 1941 * - name: The original identifier, or null. 1942 */ 1943 BasicSourceMapConsumer.prototype.originalPositionFor = 1944 function SourceMapConsumer_originalPositionFor(aArgs) { 1945 var needle = { 1946 generatedLine: util.getArg(aArgs, 'line'), 1947 generatedColumn: util.getArg(aArgs, 'column') 1948 }; 1949 1950 var index = this._findMapping( 1951 needle, 1952 this._generatedMappings, 1953 "generatedLine", 1954 "generatedColumn", 1955 util.compareByGeneratedPositionsDeflated, 1956 util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) 1957 ); 1958 1959 if (index >= 0) { 1960 var mapping = this._generatedMappings[index]; 1961 1962 if (mapping.generatedLine === needle.generatedLine) { 1963 var source = util.getArg(mapping, 'source', null); 1964 if (source !== null) { 1965 source = this._sources.at(source); 1966 if (this.sourceRoot != null) { 1967 source = util.join(this.sourceRoot, source); 1968 } 1969 } 1970 var name = util.getArg(mapping, 'name', null); 1971 if (name !== null) { 1972 name = this._names.at(name); 1973 } 1974 return { 1975 source: source, 1976 line: util.getArg(mapping, 'originalLine', null), 1977 column: util.getArg(mapping, 'originalColumn', null), 1978 name: name 1979 }; 1980 } 1981 } 1982 1983 return { 1984 source: null, 1985 line: null, 1986 column: null, 1987 name: null 1988 }; 1989 }; 1990 1991 /** 1992 * Return true if we have the source content for every source in the source 1993 * map, false otherwise. 1994 */ 1995 BasicSourceMapConsumer.prototype.hasContentsOfAllSources = 1996 function BasicSourceMapConsumer_hasContentsOfAllSources() { 1997 if (!this.sourcesContent) { 1998 return false; 1999 } 2000 return this.sourcesContent.length >= this._sources.size() && 2001 !this.sourcesContent.some(function (sc) { return sc == null; }); 2002 }; 2003 2004 /** 2005 * Returns the original source content. The only argument is the url of the 2006 * original source file. Returns null if no original source content is 2007 * available. 2008 */ 2009 BasicSourceMapConsumer.prototype.sourceContentFor = 2010 function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { 2011 if (!this.sourcesContent) { 2012 return null; 2013 } 2014 2015 if (this.sourceRoot != null) { 2016 aSource = util.relative(this.sourceRoot, aSource); 2017 } 2018 2019 if (this._sources.has(aSource)) { 2020 return this.sourcesContent[this._sources.indexOf(aSource)]; 2021 } 2022 2023 var url; 2024 if (this.sourceRoot != null 2025 && (url = util.urlParse(this.sourceRoot))) { 2026 // XXX: file:// URIs and absolute paths lead to unexpected behavior for 2027 // many users. We can help them out when they expect file:// URIs to 2028 // behave like it would if they were running a local HTTP server. See 2029 // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. 2030 var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); 2031 if (url.scheme == "file" 2032 && this._sources.has(fileUriAbsPath)) { 2033 return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] 2034 } 2035 2036 if ((!url.path || url.path == "/") 2037 && this._sources.has("/" + aSource)) { 2038 return this.sourcesContent[this._sources.indexOf("/" + aSource)]; 2039 } 2040 } 2041 2042 // This function is used recursively from 2043 // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we 2044 // don't want to throw if we can't find the source - we just want to 2045 // return null, so we provide a flag to exit gracefully. 2046 if (nullOnMissing) { 2047 return null; 2048 } 2049 else { 2050 throw new Error('"' + aSource + '" is not in the SourceMap.'); 2051 } 2052 }; 2053 2054 /** 2055 * Returns the generated line and column information for the original source, 2056 * line, and column positions provided. The only argument is an object with 2057 * the following properties: 2058 * 2059 * - source: The filename of the original source. 2060 * - line: The line number in the original source. 2061 * - column: The column number in the original source. 2062 * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or 2063 * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the 2064 * closest element that is smaller than or greater than the one we are 2065 * searching for, respectively, if the exact element cannot be found. 2066 * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. 2067 * 2068 * and an object is returned with the following properties: 2069 * 2070 * - line: The line number in the generated source, or null. 2071 * - column: The column number in the generated source, or null. 2072 */ 2073 BasicSourceMapConsumer.prototype.generatedPositionFor = 2074 function SourceMapConsumer_generatedPositionFor(aArgs) { 2075 var source = util.getArg(aArgs, 'source'); 2076 if (this.sourceRoot != null) { 2077 source = util.relative(this.sourceRoot, source); 2078 } 2079 if (!this._sources.has(source)) { 2080 return { 2081 line: null, 2082 column: null, 2083 lastColumn: null 2084 }; 2085 } 2086 source = this._sources.indexOf(source); 2087 2088 var needle = { 2089 source: source, 2090 originalLine: util.getArg(aArgs, 'line'), 2091 originalColumn: util.getArg(aArgs, 'column') 2092 }; 2093 2094 var index = this._findMapping( 2095 needle, 2096 this._originalMappings, 2097 "originalLine", 2098 "originalColumn", 2099 util.compareByOriginalPositions, 2100 util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) 2101 ); 2102 2103 if (index >= 0) { 2104 var mapping = this._originalMappings[index]; 2105 2106 if (mapping.source === needle.source) { 2107 return { 2108 line: util.getArg(mapping, 'generatedLine', null), 2109 column: util.getArg(mapping, 'generatedColumn', null), 2110 lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) 2111 }; 2112 } 2113 } 2114 2115 return { 2116 line: null, 2117 column: null, 2118 lastColumn: null 2119 }; 2120 }; 2121 2122 exports.BasicSourceMapConsumer = BasicSourceMapConsumer; 2123 2124 /** 2125 * An IndexedSourceMapConsumer instance represents a parsed source map which 2126 * we can query for information. It differs from BasicSourceMapConsumer in 2127 * that it takes "indexed" source maps (i.e. ones with a "sections" field) as 2128 * input. 2129 * 2130 * The only parameter is a raw source map (either as a JSON string, or already 2131 * parsed to an object). According to the spec for indexed source maps, they 2132 * have the following attributes: 2133 * 2134 * - version: Which version of the source map spec this map is following. 2135 * - file: Optional. The generated file this source map is associated with. 2136 * - sections: A list of section definitions. 2137 * 2138 * Each value under the "sections" field has two fields: 2139 * - offset: The offset into the original specified at which this section 2140 * begins to apply, defined as an object with a "line" and "column" 2141 * field. 2142 * - map: A source map definition. This source map could also be indexed, 2143 * but doesn't have to be. 2144 * 2145 * Instead of the "map" field, it's also possible to have a "url" field 2146 * specifying a URL to retrieve a source map from, but that's currently 2147 * unsupported. 2148 * 2149 * Here's an example source map, taken from the source map spec[0], but 2150 * modified to omit a section which uses the "url" field. 2151 * 2152 * { 2153 * version : 3, 2154 * file: "app.js", 2155 * sections: [{ 2156 * offset: {line:100, column:10}, 2157 * map: { 2158 * version : 3, 2159 * file: "section.js", 2160 * sources: ["foo.js", "bar.js"], 2161 * names: ["src", "maps", "are", "fun"], 2162 * mappings: "AAAA,E;;ABCDE;" 2163 * } 2164 * }], 2165 * } 2166 * 2167 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt 2168 */ 2169 function IndexedSourceMapConsumer(aSourceMap) { 2170 var sourceMap = aSourceMap; 2171 if (typeof aSourceMap === 'string') { 2172 sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); 2173 } 2174 2175 var version = util.getArg(sourceMap, 'version'); 2176 var sections = util.getArg(sourceMap, 'sections'); 2177 2178 if (version != this._version) { 2179 throw new Error('Unsupported version: ' + version); 2180 } 2181 2182 this._sources = new ArraySet(); 2183 this._names = new ArraySet(); 2184 2185 var lastOffset = { 2186 line: -1, 2187 column: 0 2188 }; 2189 this._sections = sections.map(function (s) { 2190 if (s.url) { 2191 // The url field will require support for asynchronicity. 2192 // See https://github.com/mozilla/source-map/issues/16 2193 throw new Error('Support for url field in sections not implemented.'); 2194 } 2195 var offset = util.getArg(s, 'offset'); 2196 var offsetLine = util.getArg(offset, 'line'); 2197 var offsetColumn = util.getArg(offset, 'column'); 2198 2199 if (offsetLine < lastOffset.line || 2200 (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { 2201 throw new Error('Section offsets must be ordered and non-overlapping.'); 2202 } 2203 lastOffset = offset; 2204 2205 return { 2206 generatedOffset: { 2207 // The offset fields are 0-based, but we use 1-based indices when 2208 // encoding/decoding from VLQ. 2209 generatedLine: offsetLine + 1, 2210 generatedColumn: offsetColumn + 1 2211 }, 2212 consumer: new SourceMapConsumer(util.getArg(s, 'map')) 2213 } 2214 }); 2215 } 2216 2217 IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); 2218 IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; 2219 2220 /** 2221 * The version of the source mapping spec that we are consuming. 2222 */ 2223 IndexedSourceMapConsumer.prototype._version = 3; 2224 2225 /** 2226 * The list of original sources. 2227 */ 2228 Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { 2229 get: function () { 2230 var sources = []; 2231 for (var i = 0; i < this._sections.length; i++) { 2232 for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { 2233 sources.push(this._sections[i].consumer.sources[j]); 2234 } 2235 } 2236 return sources; 2237 } 2238 }); 2239 2240 /** 2241 * Returns the original source, line, and column information for the generated 2242 * source's line and column positions provided. The only argument is an object 2243 * with the following properties: 2244 * 2245 * - line: The line number in the generated source. 2246 * - column: The column number in the generated source. 2247 * 2248 * and an object is returned with the following properties: 2249 * 2250 * - source: The original source file, or null. 2251 * - line: The line number in the original source, or null. 2252 * - column: The column number in the original source, or null. 2253 * - name: The original identifier, or null. 2254 */ 2255 IndexedSourceMapConsumer.prototype.originalPositionFor = 2256 function IndexedSourceMapConsumer_originalPositionFor(aArgs) { 2257 var needle = { 2258 generatedLine: util.getArg(aArgs, 'line'), 2259 generatedColumn: util.getArg(aArgs, 'column') 2260 }; 2261 2262 // Find the section containing the generated position we're trying to map 2263 // to an original position. 2264 var sectionIndex = binarySearch.search(needle, this._sections, 2265 function(needle, section) { 2266 var cmp = needle.generatedLine - section.generatedOffset.generatedLine; 2267 if (cmp) { 2268 return cmp; 2269 } 2270 2271 return (needle.generatedColumn - 2272 section.generatedOffset.generatedColumn); 2273 }); 2274 var section = this._sections[sectionIndex]; 2275 2276 if (!section) { 2277 return { 2278 source: null, 2279 line: null, 2280 column: null, 2281 name: null 2282 }; 2283 } 2284 2285 return section.consumer.originalPositionFor({ 2286 line: needle.generatedLine - 2287 (section.generatedOffset.generatedLine - 1), 2288 column: needle.generatedColumn - 2289 (section.generatedOffset.generatedLine === needle.generatedLine 2290 ? section.generatedOffset.generatedColumn - 1 2291 : 0), 2292 bias: aArgs.bias 2293 }); 2294 }; 2295 2296 /** 2297 * Return true if we have the source content for every source in the source 2298 * map, false otherwise. 2299 */ 2300 IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = 2301 function IndexedSourceMapConsumer_hasContentsOfAllSources() { 2302 return this._sections.every(function (s) { 2303 return s.consumer.hasContentsOfAllSources(); 2304 }); 2305 }; 2306 2307 /** 2308 * Returns the original source content. The only argument is the url of the 2309 * original source file. Returns null if no original source content is 2310 * available. 2311 */ 2312 IndexedSourceMapConsumer.prototype.sourceContentFor = 2313 function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { 2314 for (var i = 0; i < this._sections.length; i++) { 2315 var section = this._sections[i]; 2316 2317 var content = section.consumer.sourceContentFor(aSource, true); 2318 if (content) { 2319 return content; 2320 } 2321 } 2322 if (nullOnMissing) { 2323 return null; 2324 } 2325 else { 2326 throw new Error('"' + aSource + '" is not in the SourceMap.'); 2327 } 2328 }; 2329 2330 /** 2331 * Returns the generated line and column information for the original source, 2332 * line, and column positions provided. The only argument is an object with 2333 * the following properties: 2334 * 2335 * - source: The filename of the original source. 2336 * - line: The line number in the original source. 2337 * - column: The column number in the original source. 2338 * 2339 * and an object is returned with the following properties: 2340 * 2341 * - line: The line number in the generated source, or null. 2342 * - column: The column number in the generated source, or null. 2343 */ 2344 IndexedSourceMapConsumer.prototype.generatedPositionFor = 2345 function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { 2346 for (var i = 0; i < this._sections.length; i++) { 2347 var section = this._sections[i]; 2348 2349 // Only consider this section if the requested source is in the list of 2350 // sources of the consumer. 2351 if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { 2352 continue; 2353 } 2354 var generatedPosition = section.consumer.generatedPositionFor(aArgs); 2355 if (generatedPosition) { 2356 var ret = { 2357 line: generatedPosition.line + 2358 (section.generatedOffset.generatedLine - 1), 2359 column: generatedPosition.column + 2360 (section.generatedOffset.generatedLine === generatedPosition.line 2361 ? section.generatedOffset.generatedColumn - 1 2362 : 0) 2363 }; 2364 return ret; 2365 } 2366 } 2367 2368 return { 2369 line: null, 2370 column: null 2371 }; 2372 }; 2373 2374 /** 2375 * Parse the mappings in a string in to a data structure which we can easily 2376 * query (the ordered arrays in the `this.__generatedMappings` and 2377 * `this.__originalMappings` properties). 2378 */ 2379 IndexedSourceMapConsumer.prototype._parseMappings = 2380 function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { 2381 this.__generatedMappings = []; 2382 this.__originalMappings = []; 2383 for (var i = 0; i < this._sections.length; i++) { 2384 var section = this._sections[i]; 2385 var sectionMappings = section.consumer._generatedMappings; 2386 for (var j = 0; j < sectionMappings.length; j++) { 2387 var mapping = sectionMappings[j]; 2388 2389 var source = section.consumer._sources.at(mapping.source); 2390 if (section.consumer.sourceRoot !== null) { 2391 source = util.join(section.consumer.sourceRoot, source); 2392 } 2393 this._sources.add(source); 2394 source = this._sources.indexOf(source); 2395 2396 var name = section.consumer._names.at(mapping.name); 2397 this._names.add(name); 2398 name = this._names.indexOf(name); 2399 2400 // The mappings coming from the consumer for the section have 2401 // generated positions relative to the start of the section, so we 2402 // need to offset them to be relative to the start of the concatenated 2403 // generated file. 2404 var adjustedMapping = { 2405 source: source, 2406 generatedLine: mapping.generatedLine + 2407 (section.generatedOffset.generatedLine - 1), 2408 generatedColumn: mapping.generatedColumn + 2409 (section.generatedOffset.generatedLine === mapping.generatedLine 2410 ? section.generatedOffset.generatedColumn - 1 2411 : 0), 2412 originalLine: mapping.originalLine, 2413 originalColumn: mapping.originalColumn, 2414 name: name 2415 }; 2416 2417 this.__generatedMappings.push(adjustedMapping); 2418 if (typeof adjustedMapping.originalLine === 'number') { 2419 this.__originalMappings.push(adjustedMapping); 2420 } 2421 } 2422 } 2423 2424 quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); 2425 quickSort(this.__originalMappings, util.compareByOriginalPositions); 2426 }; 2427 2428 exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; 2429 2430 2431/***/ }), 2432/* 8 */ 2433/***/ (function(module, exports) { 2434 2435 /* -*- Mode: js; js-indent-level: 2; -*- */ 2436 /* 2437 * Copyright 2011 Mozilla Foundation and contributors 2438 * Licensed under the New BSD license. See LICENSE or: 2439 * http://opensource.org/licenses/BSD-3-Clause 2440 */ 2441 2442 exports.GREATEST_LOWER_BOUND = 1; 2443 exports.LEAST_UPPER_BOUND = 2; 2444 2445 /** 2446 * Recursive implementation of binary search. 2447 * 2448 * @param aLow Indices here and lower do not contain the needle. 2449 * @param aHigh Indices here and higher do not contain the needle. 2450 * @param aNeedle The element being searched for. 2451 * @param aHaystack The non-empty array being searched. 2452 * @param aCompare Function which takes two elements and returns -1, 0, or 1. 2453 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or 2454 * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the 2455 * closest element that is smaller than or greater than the one we are 2456 * searching for, respectively, if the exact element cannot be found. 2457 */ 2458 function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { 2459 // This function terminates when one of the following is true: 2460 // 2461 // 1. We find the exact element we are looking for. 2462 // 2463 // 2. We did not find the exact element, but we can return the index of 2464 // the next-closest element. 2465 // 2466 // 3. We did not find the exact element, and there is no next-closest 2467 // element than the one we are searching for, so we return -1. 2468 var mid = Math.floor((aHigh - aLow) / 2) + aLow; 2469 var cmp = aCompare(aNeedle, aHaystack[mid], true); 2470 if (cmp === 0) { 2471 // Found the element we are looking for. 2472 return mid; 2473 } 2474 else if (cmp > 0) { 2475 // Our needle is greater than aHaystack[mid]. 2476 if (aHigh - mid > 1) { 2477 // The element is in the upper half. 2478 return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); 2479 } 2480 2481 // The exact needle element was not found in this haystack. Determine if 2482 // we are in termination case (3) or (2) and return the appropriate thing. 2483 if (aBias == exports.LEAST_UPPER_BOUND) { 2484 return aHigh < aHaystack.length ? aHigh : -1; 2485 } else { 2486 return mid; 2487 } 2488 } 2489 else { 2490 // Our needle is less than aHaystack[mid]. 2491 if (mid - aLow > 1) { 2492 // The element is in the lower half. 2493 return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); 2494 } 2495 2496 // we are in termination case (3) or (2) and return the appropriate thing. 2497 if (aBias == exports.LEAST_UPPER_BOUND) { 2498 return mid; 2499 } else { 2500 return aLow < 0 ? -1 : aLow; 2501 } 2502 } 2503 } 2504 2505 /** 2506 * This is an implementation of binary search which will always try and return 2507 * the index of the closest element if there is no exact hit. This is because 2508 * mappings between original and generated line/col pairs are single points, 2509 * and there is an implicit region between each of them, so a miss just means 2510 * that you aren't on the very start of a region. 2511 * 2512 * @param aNeedle The element you are looking for. 2513 * @param aHaystack The array that is being searched. 2514 * @param aCompare A function which takes the needle and an element in the 2515 * array and returns -1, 0, or 1 depending on whether the needle is less 2516 * than, equal to, or greater than the element, respectively. 2517 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or 2518 * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the 2519 * closest element that is smaller than or greater than the one we are 2520 * searching for, respectively, if the exact element cannot be found. 2521 * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. 2522 */ 2523 exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { 2524 if (aHaystack.length === 0) { 2525 return -1; 2526 } 2527 2528 var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, 2529 aCompare, aBias || exports.GREATEST_LOWER_BOUND); 2530 if (index < 0) { 2531 return -1; 2532 } 2533 2534 // We have found either the exact element, or the next-closest element than 2535 // the one we are searching for. However, there may be more than one such 2536 // element. Make sure we always return the smallest of these. 2537 while (index - 1 >= 0) { 2538 if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { 2539 break; 2540 } 2541 --index; 2542 } 2543 2544 return index; 2545 }; 2546 2547 2548/***/ }), 2549/* 9 */ 2550/***/ (function(module, exports) { 2551 2552 /* -*- Mode: js; js-indent-level: 2; -*- */ 2553 /* 2554 * Copyright 2011 Mozilla Foundation and contributors 2555 * Licensed under the New BSD license. See LICENSE or: 2556 * http://opensource.org/licenses/BSD-3-Clause 2557 */ 2558 2559 // It turns out that some (most?) JavaScript engines don't self-host 2560 // `Array.prototype.sort`. This makes sense because C++ will likely remain 2561 // faster than JS when doing raw CPU-intensive sorting. However, when using a 2562 // custom comparator function, calling back and forth between the VM's C++ and 2563 // JIT'd JS is rather slow *and* loses JIT type information, resulting in 2564 // worse generated code for the comparator function than would be optimal. In 2565 // fact, when sorting with a comparator, these costs outweigh the benefits of 2566 // sorting in C++. By using our own JS-implemented Quick Sort (below), we get 2567 // a ~3500ms mean speed-up in `bench/bench.html`. 2568 2569 /** 2570 * Swap the elements indexed by `x` and `y` in the array `ary`. 2571 * 2572 * @param {Array} ary 2573 * The array. 2574 * @param {Number} x 2575 * The index of the first item. 2576 * @param {Number} y 2577 * The index of the second item. 2578 */ 2579 function swap(ary, x, y) { 2580 var temp = ary[x]; 2581 ary[x] = ary[y]; 2582 ary[y] = temp; 2583 } 2584 2585 /** 2586 * Returns a random integer within the range `low .. high` inclusive. 2587 * 2588 * @param {Number} low 2589 * The lower bound on the range. 2590 * @param {Number} high 2591 * The upper bound on the range. 2592 */ 2593 function randomIntInRange(low, high) { 2594 return Math.round(low + (Math.random() * (high - low))); 2595 } 2596 2597 /** 2598 * The Quick Sort algorithm. 2599 * 2600 * @param {Array} ary 2601 * An array to sort. 2602 * @param {function} comparator 2603 * Function to use to compare two items. 2604 * @param {Number} p 2605 * Start index of the array 2606 * @param {Number} r 2607 * End index of the array 2608 */ 2609 function doQuickSort(ary, comparator, p, r) { 2610 // If our lower bound is less than our upper bound, we (1) partition the 2611 // array into two pieces and (2) recurse on each half. If it is not, this is 2612 // the empty array and our base case. 2613 2614 if (p < r) { 2615 // (1) Partitioning. 2616 // 2617 // The partitioning chooses a pivot between `p` and `r` and moves all 2618 // elements that are less than or equal to the pivot to the before it, and 2619 // all the elements that are greater than it after it. The effect is that 2620 // once partition is done, the pivot is in the exact place it will be when 2621 // the array is put in sorted order, and it will not need to be moved 2622 // again. This runs in O(n) time. 2623 2624 // Always choose a random pivot so that an input array which is reverse 2625 // sorted does not cause O(n^2) running time. 2626 var pivotIndex = randomIntInRange(p, r); 2627 var i = p - 1; 2628 2629 swap(ary, pivotIndex, r); 2630 var pivot = ary[r]; 2631 2632 // Immediately after `j` is incremented in this loop, the following hold 2633 // true: 2634 // 2635 // * Every element in `ary[p .. i]` is less than or equal to the pivot. 2636 // 2637 // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. 2638 for (var j = p; j < r; j++) { 2639 if (comparator(ary[j], pivot) <= 0) { 2640 i += 1; 2641 swap(ary, i, j); 2642 } 2643 } 2644 2645 swap(ary, i + 1, j); 2646 var q = i + 1; 2647 2648 // (2) Recurse on each half. 2649 2650 doQuickSort(ary, comparator, p, q - 1); 2651 doQuickSort(ary, comparator, q + 1, r); 2652 } 2653 } 2654 2655 /** 2656 * Sort the given array in-place with the given comparator function. 2657 * 2658 * @param {Array} ary 2659 * An array to sort. 2660 * @param {function} comparator 2661 * Function to use to compare two items. 2662 */ 2663 exports.quickSort = function (ary, comparator) { 2664 doQuickSort(ary, comparator, 0, ary.length - 1); 2665 }; 2666 2667 2668/***/ }), 2669/* 10 */ 2670/***/ (function(module, exports, __webpack_require__) { 2671 2672 /* -*- Mode: js; js-indent-level: 2; -*- */ 2673 /* 2674 * Copyright 2011 Mozilla Foundation and contributors 2675 * Licensed under the New BSD license. See LICENSE or: 2676 * http://opensource.org/licenses/BSD-3-Clause 2677 */ 2678 2679 var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; 2680 var util = __webpack_require__(4); 2681 2682 // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other 2683 // operating systems these days (capturing the result). 2684 var REGEX_NEWLINE = /(\r?\n)/; 2685 2686 // Newline character code for charCodeAt() comparisons 2687 var NEWLINE_CODE = 10; 2688 2689 // Private symbol for identifying `SourceNode`s when multiple versions of 2690 // the source-map library are loaded. This MUST NOT CHANGE across 2691 // versions! 2692 var isSourceNode = "$$$isSourceNode$$$"; 2693 2694 /** 2695 * SourceNodes provide a way to abstract over interpolating/concatenating 2696 * snippets of generated JavaScript source code while maintaining the line and 2697 * column information associated with the original source code. 2698 * 2699 * @param aLine The original line number. 2700 * @param aColumn The original column number. 2701 * @param aSource The original source's filename. 2702 * @param aChunks Optional. An array of strings which are snippets of 2703 * generated JS, or other SourceNodes. 2704 * @param aName The original identifier. 2705 */ 2706 function SourceNode(aLine, aColumn, aSource, aChunks, aName) { 2707 this.children = []; 2708 this.sourceContents = {}; 2709 this.line = aLine == null ? null : aLine; 2710 this.column = aColumn == null ? null : aColumn; 2711 this.source = aSource == null ? null : aSource; 2712 this.name = aName == null ? null : aName; 2713 this[isSourceNode] = true; 2714 if (aChunks != null) this.add(aChunks); 2715 } 2716 2717 /** 2718 * Creates a SourceNode from generated code and a SourceMapConsumer. 2719 * 2720 * @param aGeneratedCode The generated code 2721 * @param aSourceMapConsumer The SourceMap for the generated code 2722 * @param aRelativePath Optional. The path that relative sources in the 2723 * SourceMapConsumer should be relative to. 2724 */ 2725 SourceNode.fromStringWithSourceMap = 2726 function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { 2727 // The SourceNode we want to fill with the generated code 2728 // and the SourceMap 2729 var node = new SourceNode(); 2730 2731 // All even indices of this array are one line of the generated code, 2732 // while all odd indices are the newlines between two adjacent lines 2733 // (since `REGEX_NEWLINE` captures its match). 2734 // Processed fragments are accessed by calling `shiftNextLine`. 2735 var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); 2736 var remainingLinesIndex = 0; 2737 var shiftNextLine = function() { 2738 var lineContents = getNextLine(); 2739 // The last line of a file might not have a newline. 2740 var newLine = getNextLine() || ""; 2741 return lineContents + newLine; 2742 2743 function getNextLine() { 2744 return remainingLinesIndex < remainingLines.length ? 2745 remainingLines[remainingLinesIndex++] : undefined; 2746 } 2747 }; 2748 2749 // We need to remember the position of "remainingLines" 2750 var lastGeneratedLine = 1, lastGeneratedColumn = 0; 2751 2752 // The generate SourceNodes we need a code range. 2753 // To extract it current and last mapping is used. 2754 // Here we store the last mapping. 2755 var lastMapping = null; 2756 2757 aSourceMapConsumer.eachMapping(function (mapping) { 2758 if (lastMapping !== null) { 2759 // We add the code from "lastMapping" to "mapping": 2760 // First check if there is a new line in between. 2761 if (lastGeneratedLine < mapping.generatedLine) { 2762 // Associate first line with "lastMapping" 2763 addMappingWithCode(lastMapping, shiftNextLine()); 2764 lastGeneratedLine++; 2765 lastGeneratedColumn = 0; 2766 // The remaining code is added without mapping 2767 } else { 2768 // There is no new line in between. 2769 // Associate the code between "lastGeneratedColumn" and 2770 // "mapping.generatedColumn" with "lastMapping" 2771 var nextLine = remainingLines[remainingLinesIndex]; 2772 var code = nextLine.substr(0, mapping.generatedColumn - 2773 lastGeneratedColumn); 2774 remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - 2775 lastGeneratedColumn); 2776 lastGeneratedColumn = mapping.generatedColumn; 2777 addMappingWithCode(lastMapping, code); 2778 // No more remaining code, continue 2779 lastMapping = mapping; 2780 return; 2781 } 2782 } 2783 // We add the generated code until the first mapping 2784 // to the SourceNode without any mapping. 2785 // Each line is added as separate string. 2786 while (lastGeneratedLine < mapping.generatedLine) { 2787 node.add(shiftNextLine()); 2788 lastGeneratedLine++; 2789 } 2790 if (lastGeneratedColumn < mapping.generatedColumn) { 2791 var nextLine = remainingLines[remainingLinesIndex]; 2792 node.add(nextLine.substr(0, mapping.generatedColumn)); 2793 remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); 2794 lastGeneratedColumn = mapping.generatedColumn; 2795 } 2796 lastMapping = mapping; 2797 }, this); 2798 // We have processed all mappings. 2799 if (remainingLinesIndex < remainingLines.length) { 2800 if (lastMapping) { 2801 // Associate the remaining code in the current line with "lastMapping" 2802 addMappingWithCode(lastMapping, shiftNextLine()); 2803 } 2804 // and add the remaining lines without any mapping 2805 node.add(remainingLines.splice(remainingLinesIndex).join("")); 2806 } 2807 2808 // Copy sourcesContent into SourceNode 2809 aSourceMapConsumer.sources.forEach(function (sourceFile) { 2810 var content = aSourceMapConsumer.sourceContentFor(sourceFile); 2811 if (content != null) { 2812 if (aRelativePath != null) { 2813 sourceFile = util.join(aRelativePath, sourceFile); 2814 } 2815 node.setSourceContent(sourceFile, content); 2816 } 2817 }); 2818 2819 return node; 2820 2821 function addMappingWithCode(mapping, code) { 2822 if (mapping === null || mapping.source === undefined) { 2823 node.add(code); 2824 } else { 2825 var source = aRelativePath 2826 ? util.join(aRelativePath, mapping.source) 2827 : mapping.source; 2828 node.add(new SourceNode(mapping.originalLine, 2829 mapping.originalColumn, 2830 source, 2831 code, 2832 mapping.name)); 2833 } 2834 } 2835 }; 2836 2837 /** 2838 * Add a chunk of generated JS to this source node. 2839 * 2840 * @param aChunk A string snippet of generated JS code, another instance of 2841 * SourceNode, or an array where each member is one of those things. 2842 */ 2843 SourceNode.prototype.add = function SourceNode_add(aChunk) { 2844 if (Array.isArray(aChunk)) { 2845 aChunk.forEach(function (chunk) { 2846 this.add(chunk); 2847 }, this); 2848 } 2849 else if (aChunk[isSourceNode] || typeof aChunk === "string") { 2850 if (aChunk) { 2851 this.children.push(aChunk); 2852 } 2853 } 2854 else { 2855 throw new TypeError( 2856 "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk 2857 ); 2858 } 2859 return this; 2860 }; 2861 2862 /** 2863 * Add a chunk of generated JS to the beginning of this source node. 2864 * 2865 * @param aChunk A string snippet of generated JS code, another instance of 2866 * SourceNode, or an array where each member is one of those things. 2867 */ 2868 SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { 2869 if (Array.isArray(aChunk)) { 2870 for (var i = aChunk.length-1; i >= 0; i--) { 2871 this.prepend(aChunk[i]); 2872 } 2873 } 2874 else if (aChunk[isSourceNode] || typeof aChunk === "string") { 2875 this.children.unshift(aChunk); 2876 } 2877 else { 2878 throw new TypeError( 2879 "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk 2880 ); 2881 } 2882 return this; 2883 }; 2884 2885 /** 2886 * Walk over the tree of JS snippets in this node and its children. The 2887 * walking function is called once for each snippet of JS and is passed that 2888 * snippet and the its original associated source's line/column location. 2889 * 2890 * @param aFn The traversal function. 2891 */ 2892 SourceNode.prototype.walk = function SourceNode_walk(aFn) { 2893 var chunk; 2894 for (var i = 0, len = this.children.length; i < len; i++) { 2895 chunk = this.children[i]; 2896 if (chunk[isSourceNode]) { 2897 chunk.walk(aFn); 2898 } 2899 else { 2900 if (chunk !== '') { 2901 aFn(chunk, { source: this.source, 2902 line: this.line, 2903 column: this.column, 2904 name: this.name }); 2905 } 2906 } 2907 } 2908 }; 2909 2910 /** 2911 * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between 2912 * each of `this.children`. 2913 * 2914 * @param aSep The separator. 2915 */ 2916 SourceNode.prototype.join = function SourceNode_join(aSep) { 2917 var newChildren; 2918 var i; 2919 var len = this.children.length; 2920 if (len > 0) { 2921 newChildren = []; 2922 for (i = 0; i < len-1; i++) { 2923 newChildren.push(this.children[i]); 2924 newChildren.push(aSep); 2925 } 2926 newChildren.push(this.children[i]); 2927 this.children = newChildren; 2928 } 2929 return this; 2930 }; 2931 2932 /** 2933 * Call String.prototype.replace on the very right-most source snippet. Useful 2934 * for trimming whitespace from the end of a source node, etc. 2935 * 2936 * @param aPattern The pattern to replace. 2937 * @param aReplacement The thing to replace the pattern with. 2938 */ 2939 SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { 2940 var lastChild = this.children[this.children.length - 1]; 2941 if (lastChild[isSourceNode]) { 2942 lastChild.replaceRight(aPattern, aReplacement); 2943 } 2944 else if (typeof lastChild === 'string') { 2945 this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); 2946 } 2947 else { 2948 this.children.push(''.replace(aPattern, aReplacement)); 2949 } 2950 return this; 2951 }; 2952 2953 /** 2954 * Set the source content for a source file. This will be added to the SourceMapGenerator 2955 * in the sourcesContent field. 2956 * 2957 * @param aSourceFile The filename of the source file 2958 * @param aSourceContent The content of the source file 2959 */ 2960 SourceNode.prototype.setSourceContent = 2961 function SourceNode_setSourceContent(aSourceFile, aSourceContent) { 2962 this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; 2963 }; 2964 2965 /** 2966 * Walk over the tree of SourceNodes. The walking function is called for each 2967 * source file content and is passed the filename and source content. 2968 * 2969 * @param aFn The traversal function. 2970 */ 2971 SourceNode.prototype.walkSourceContents = 2972 function SourceNode_walkSourceContents(aFn) { 2973 for (var i = 0, len = this.children.length; i < len; i++) { 2974 if (this.children[i][isSourceNode]) { 2975 this.children[i].walkSourceContents(aFn); 2976 } 2977 } 2978 2979 var sources = Object.keys(this.sourceContents); 2980 for (var i = 0, len = sources.length; i < len; i++) { 2981 aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); 2982 } 2983 }; 2984 2985 /** 2986 * Return the string representation of this source node. Walks over the tree 2987 * and concatenates all the various snippets together to one string. 2988 */ 2989 SourceNode.prototype.toString = function SourceNode_toString() { 2990 var str = ""; 2991 this.walk(function (chunk) { 2992 str += chunk; 2993 }); 2994 return str; 2995 }; 2996 2997 /** 2998 * Returns the string representation of this source node along with a source 2999 * map. 3000 */ 3001 SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { 3002 var generated = { 3003 code: "", 3004 line: 1, 3005 column: 0 3006 }; 3007 var map = new SourceMapGenerator(aArgs); 3008 var sourceMappingActive = false; 3009 var lastOriginalSource = null; 3010 var lastOriginalLine = null; 3011 var lastOriginalColumn = null; 3012 var lastOriginalName = null; 3013 this.walk(function (chunk, original) { 3014 generated.code += chunk; 3015 if (original.source !== null 3016 && original.line !== null 3017 && original.column !== null) { 3018 if(lastOriginalSource !== original.source 3019 || lastOriginalLine !== original.line 3020 || lastOriginalColumn !== original.column 3021 || lastOriginalName !== original.name) { 3022 map.addMapping({ 3023 source: original.source, 3024 original: { 3025 line: original.line, 3026 column: original.column 3027 }, 3028 generated: { 3029 line: generated.line, 3030 column: generated.column 3031 }, 3032 name: original.name 3033 }); 3034 } 3035 lastOriginalSource = original.source; 3036 lastOriginalLine = original.line; 3037 lastOriginalColumn = original.column; 3038 lastOriginalName = original.name; 3039 sourceMappingActive = true; 3040 } else if (sourceMappingActive) { 3041 map.addMapping({ 3042 generated: { 3043 line: generated.line, 3044 column: generated.column 3045 } 3046 }); 3047 lastOriginalSource = null; 3048 sourceMappingActive = false; 3049 } 3050 for (var idx = 0, length = chunk.length; idx < length; idx++) { 3051 if (chunk.charCodeAt(idx) === NEWLINE_CODE) { 3052 generated.line++; 3053 generated.column = 0; 3054 // Mappings end at eol 3055 if (idx + 1 === length) { 3056 lastOriginalSource = null; 3057 sourceMappingActive = false; 3058 } else if (sourceMappingActive) { 3059 map.addMapping({ 3060 source: original.source, 3061 original: { 3062 line: original.line, 3063 column: original.column 3064 }, 3065 generated: { 3066 line: generated.line, 3067 column: generated.column 3068 }, 3069 name: original.name 3070 }); 3071 } 3072 } else { 3073 generated.column++; 3074 } 3075 } 3076 }); 3077 this.walkSourceContents(function (sourceFile, sourceContent) { 3078 map.setSourceContent(sourceFile, sourceContent); 3079 }); 3080 3081 return { code: generated.code, map: map }; 3082 }; 3083 3084 exports.SourceNode = SourceNode; 3085 3086 3087/***/ }) 3088/******/ ]) 3089}); 3090;