import { encode, encodeRangeMappings } from "@jridgewell/sourcemap-codec"; //#region src/BitSet.ts var BitSet = class BitSet { constructor(arg) { this.bits = arg instanceof BitSet ? arg.bits.slice() : []; } add(n) { this.bits[n >> 5] |= 1 << (n & 31); } has(n) { return !!(this.bits[n >> 5] & 1 << (n & 31)); } }; //#endregion //#region src/Chunk.ts var Chunk = class Chunk { constructor(start, end, content) { this.start = start; this.end = end; this.original = content; this.intro = ""; this.outro = ""; this.content = content; this.storeName = false; this.edited = false; this.previous = null; this.next = null; } appendLeft(content) { this.outro += content; } appendRight(content) { this.intro = this.intro + content; } clone() { const chunk = new Chunk(this.start, this.end, this.original); chunk.intro = this.intro; chunk.outro = this.outro; chunk.content = this.content; chunk.storeName = this.storeName; chunk.edited = this.edited; return chunk; } contains(index) { return this.start < index && index < this.end; } eachNext(fn) { fn(this); let chunk = this.next; while (chunk) { fn(chunk); chunk = chunk.next; } } eachPrevious(fn) { fn(this); let chunk = this.previous; while (chunk) { fn(chunk); chunk = chunk.previous; } } edit(content, storeName, contentOnly) { this.content = content; if (!contentOnly) { this.intro = ""; this.outro = ""; } this.storeName = storeName; this.edited = true; return this; } prependLeft(content) { this.outro = content + this.outro; } prependRight(content) { this.intro = content + this.intro; } reset() { this.intro = ""; this.outro = ""; if (this.edited) { this.content = this.original; this.storeName = false; this.edited = false; } } split(index) { const sliceIndex = index - this.start; const originalBefore = this.original.slice(0, sliceIndex); const originalAfter = this.original.slice(sliceIndex); this.original = originalBefore; const newChunk = new Chunk(index, this.end, originalAfter); newChunk.outro = this.outro; this.outro = ""; this.end = index; if (this.edited) { newChunk.edit("", false, true); this.content = ""; } else this.content = originalBefore; newChunk.next = this.next; if (newChunk.next) newChunk.next.previous = newChunk; newChunk.previous = this; this.next = newChunk; return newChunk; } toString() { return this.intro + this.content + this.outro; } trimEnd(rx) { this.outro = this.outro.replace(rx, ""); if (this.outro.length) return true; const trimmed = this.content.replace(rx, ""); if (trimmed.length) { if (trimmed !== this.content) { if (this.edited) this.edit(trimmed, this.storeName, true); else this.split(this.start + trimmed.length).edit("", void 0, true); } return true; } else { this.edit("", void 0, true); this.intro = this.intro.replace(rx, ""); if (this.intro.length) return true; } } trimStart(rx) { this.intro = this.intro.replace(rx, ""); if (this.intro.length) return true; const trimmed = this.content.replace(rx, ""); if (trimmed.length) { if (trimmed !== this.content) { if (this.edited) this.edit(trimmed, this.storeName, true); else { this.split(this.end - trimmed.length); this.edit("", void 0, true); } } return true; } else { this.edit("", void 0, true); this.outro = this.outro.replace(rx, ""); if (this.outro.length) return true; } } }; //#endregion //#region src/MagicStringError.ts /** * The single error type thrown by MagicString. * * Every message is prefixed with `[MagicString]` so its source is obvious at a * glance, and is kept short and consistent in tone. */ var MagicStringError = class extends Error { name = "MagicStringError"; constructor(message, options) { super(`[MagicString] ${message}`, options); } }; //#endregion //#region src/SourceMap.ts function getBtoa() { /* v8 ignore next -- environment fallback, unreachable when `btoa` is present */ if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") return (str) => globalThis.btoa(unescape(encodeURIComponent(str))); const buffer = globalThis["Buffer"]; if (buffer) return (str) => buffer.from(str, "utf-8").toString("base64"); return () => { throw new MagicStringError("unsupported environment: `btoa` or `Buffer` is required"); }; /* v8 ignore stop */ } const btoa = /* #__PURE__ */ getBtoa(); var SourceMap = class { constructor(properties) { this.version = 3; this.file = properties.file; this.sources = properties.sources; this.sourcesContent = properties.sourcesContent; this.names = properties.names; this.mappings = typeof properties.mappings === "string" ? properties.mappings : encode(properties.mappings); if (typeof properties.x_google_ignoreList !== "undefined") this.x_google_ignoreList = properties.x_google_ignoreList; if (typeof properties.debugId !== "undefined") this.debugId = properties.debugId; if (typeof properties.rangeMappings !== "undefined") { let shouldOutputRangeMapping = false; for (const line of properties.rangeMappings) if (line.length !== 0) { shouldOutputRangeMapping = true; break; } if (shouldOutputRangeMapping) this.rangeMappings = encodeRangeMappings(properties.rangeMappings); } } /** * Returns the equivalent of `JSON.stringify(map)` */ toString() { return JSON.stringify(this); } /** * Returns a DataURI containing the sourcemap. Useful for doing this sort of thing: * `generateMap(options?: SourceMapOptions): SourceMap;` */ toUrl() { return `data:application/json;charset=utf-8;base64,${btoa(this.toString())}`; } }; //#endregion //#region src/utils/getLocator.ts function getLocator(source) { const lineOffsets = [0]; for (let i = source.indexOf("\n"); i !== -1; i = source.indexOf("\n", i + 1)) lineOffsets.push(i + 1); return function locate(index) { let i = 0; let j = lineOffsets.length; while (i < j) { const m = i + j >> 1; if (index < lineOffsets[m]) j = m; else i = m + 1; } const line = i - 1; return { line, column: index - lineOffsets[line] }; }; } //#endregion //#region src/utils/getRelativePath.ts function getRelativePath(from, to) { const fromParts = from.split(/[/\\]/); const toParts = to.split(/[/\\]/); fromParts.pop(); while (fromParts[0] === toParts[0]) { fromParts.shift(); toParts.shift(); } if (fromParts.length) { let i = fromParts.length; while (i--) fromParts[i] = ".."; } return fromParts.concat(toParts).join("/"); } //#endregion //#region src/utils/guessIndent.ts function guessIndent(code) { const lines = code.split("\n"); const tabbed = lines.filter((line) => /^\t+/.test(line)); const spaced = lines.filter((line) => /^ {2,}/.test(line)); if (tabbed.length === 0 && spaced.length === 0) return null; if (tabbed.length >= spaced.length) return " "; const min = spaced.reduce((previous, current) => { const numSpaces = /^ +/.exec(current)[0].length; return Math.min(numSpaces, previous); }, Infinity); return " ".repeat(min); } //#endregion //#region src/utils/isObject.ts const toString = Object.prototype.toString; function isObject(thing) { return toString.call(thing) === "[object Object]"; } const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const intToChar = /* #__PURE__ */ (() => { const chars = /* @__PURE__ */ new Uint8Array(64); for (let i = 0; i < 64; i++) chars[i] = BASE64_CHARS.charCodeAt(i); return chars; })(); const COMMA = 44; const SEMICOLON = 59; const BUFFER_SIZE = 16384; const FLUSH_THRESHOLD = 16348; const scratch = /* #__PURE__ */ new Uint8Array(BUFFER_SIZE); function writeVlq(pos, num) { num = num < 0 ? -num << 1 | 1 : num << 1; do { let clamped = num & 31; num >>>= 5; if (num > 0) clamped |= 32; scratch[pos++] = intToChar[clamped]; } while (num > 0); return pos; } const decoder = /* #__PURE__ */ new TextDecoder(); var MappingsEncoder = class { constructor() { this.out = ""; this.pos = 0; this.lines = []; this.buffered = 0; this.needsComma = false; this.prevGenColumn = 0; this.prevSourceIndex = 0; this.prevSourceLine = 0; this.prevSourceColumn = 0; this.prevNameIndex = 0; } endLine(segments) { this.lines.push(segments); this.buffered += segments.length + 1; if (this.buffered >= 4096) this.drain(null); } segments(segments) { this.drain(segments); } finish(segments) { this.drain(segments); this.flush(); return this.out; } drain(trailing) { const lines = this.lines; const lineCount = lines.length; for (let l = 0; l <= lineCount; l++) { const line = l < lineCount ? lines[l] : trailing; if (line === null) break; for (let i = 0; i < line.length; i++) { if (this.pos > FLUSH_THRESHOLD) this.flush(); const segment = line[i]; if (this.needsComma) scratch[this.pos++] = COMMA; this.needsComma = true; this.pos = writeVlq(this.pos, segment[0] - this.prevGenColumn); this.prevGenColumn = segment[0]; this.pos = writeVlq(this.pos, segment[1] - this.prevSourceIndex); this.prevSourceIndex = segment[1]; this.pos = writeVlq(this.pos, segment[2] - this.prevSourceLine); this.prevSourceLine = segment[2]; this.pos = writeVlq(this.pos, segment[3] - this.prevSourceColumn); this.prevSourceColumn = segment[3]; if (segment.length === 5) { this.pos = writeVlq(this.pos, segment[4] - this.prevNameIndex); this.prevNameIndex = segment[4]; } } if (l < lineCount) { if (this.pos > FLUSH_THRESHOLD) this.flush(); scratch[this.pos++] = SEMICOLON; this.needsComma = false; this.prevGenColumn = 0; } } lines.length = 0; this.buffered = 0; this.flush(); } flush() { this.out += decoder.decode(scratch.subarray(0, this.pos)); this.pos = 0; } }; //#endregion //#region src/utils/Mappings.ts const NEWLINE_CHAR$1 = 10; function isWordCode(code) { return code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 || code === 95; } var Mappings = class { constructor(hires, encoder = null) { this.hires = hires; this.generatedCodeLine = 0; this.generatedCodeColumn = 0; this.raw = []; this.rawSegments = this.raw[this.generatedCodeLine] = []; this.rawRangeMappings = []; this.rawRangeMappingsIndices = this.rawRangeMappings[this.generatedCodeLine] = []; this.encoder = encoder; } nextLine() { if (this.encoder === null) { this.generatedCodeLine += 1; this.raw[this.generatedCodeLine] = this.rawSegments = []; } else { this.encoder.endLine(this.rawSegments); this.rawSegments = []; this.generatedCodeLine += 1; } this.generatedCodeColumn = 0; this.rawRangeMappings[this.generatedCodeLine] = this.rawRangeMappingsIndices = []; } addEdit(sourceIndex, content, loc, nameIndex) { if (content.length) { const contentLengthMinusOne = content.length - 1; let contentLineEnd = content.indexOf("\n", 0); let previousContentLineEnd = -1; while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) { const segment = [ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]; if (nameIndex >= 0) segment.push(nameIndex); this.rawSegments.push(segment); this.nextLine(); previousContentLineEnd = contentLineEnd; contentLineEnd = content.indexOf("\n", contentLineEnd + 1); } const segment = [ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]; if (nameIndex >= 0) segment.push(nameIndex); this.rawSegments.push(segment); this.advance(content.slice(previousContentLineEnd + 1)); } } addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) { const end = chunk.end; let i = chunk.start; if (this.hires) { const boundary = this.hires === "boundary"; const experimentalRange = this.hires === "experimental-range"; const encoder = experimentalRange ? null : this.encoder; let charInHiresBoundary = false; while (i < end) { if (encoder !== null && this.rawSegments.length >= 4096) { encoder.segments(this.rawSegments); this.rawSegments.length = 0; } if (experimentalRange && i + 1 >= end) this.rawSegments.push([ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]); const code = original.charCodeAt(i); if (code === NEWLINE_CHAR$1) { loc.line += 1; loc.column = 0; this.nextLine(); charInHiresBoundary = false; } else { if (boundary) { if (isWordCode(code)) { if (!charInHiresBoundary) { this.rawSegments.push([ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]); charInHiresBoundary = true; } } else { this.rawSegments.push([ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]); charInHiresBoundary = false; } } else if (experimentalRange) { if (i === chunk.start) { this.rawRangeMappingsIndices.push(this.rawSegments.length); this.rawSegments.push([ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]); } } else this.rawSegments.push([ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]); loc.column += 1; this.generatedCodeColumn += 1; } i += 1; } } else { const bits = sourcemapLocations.bits; while (i < end) { let newline = original.indexOf("\n", i); if (newline === -1 || newline > end) newline = end; if (newline > i) { this.rawSegments.push([ this.generatedCodeColumn, sourceIndex, loc.line, loc.column ]); for (let w = i + 1 >> 5, last = newline - 1 >> 5; w <= last; w++) { let word = bits[w]; if (!word) continue; const base = w << 5; while (word) { const lowest = word & -word; const index = base + 31 - Math.clz32(lowest); if (index > i && index < newline) { const offset = index - i; this.rawSegments.push([ this.generatedCodeColumn + offset, sourceIndex, loc.line, loc.column + offset ]); } word ^= lowest; } } loc.column += newline - i; this.generatedCodeColumn += newline - i; } if (newline === end) break; loc.line += 1; loc.column = 0; this.nextLine(); i = newline + 1; } } } advance(str) { if (!str) return; const lastNewline = str.lastIndexOf("\n"); for (let i = str.indexOf("\n"); i !== -1; i = str.indexOf("\n", i + 1)) this.nextLine(); this.generatedCodeColumn += str.length - lastNewline - 1; } }; //#endregion //#region src/MagicString.ts const n = "\n"; const NEWLINE_CHAR = "\n".charCodeAt(0); const CR_CHAR = "\r".charCodeAt(0); const warned = { insertLeft: false, insertRight: false, storeName: false }; /** * Expands the `$` substitution patterns that `String.prototype.replace` accepts * in a string replacement. * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter * * `captures` holds the capture groups in order, so `captures[0]` is `$1`. * `namedCaptures` is `undefined` when the pattern has no named groups, and * `$` is then literal text - which is also the case for a string search * value, where there are no groups of either kind. */ function expandReplacement(replacement, matched, position, str, captures, namedCaptures) { if (!replacement.includes("$")) return replacement; let result = ""; let index = 0; while (index < replacement.length) { const dollar = replacement.indexOf("$", index); if (dollar === -1) { result += replacement.slice(index); break; } result += replacement.slice(index, dollar); const char = replacement[dollar + 1]; let expansion = "$"; let consumed = 1; if (char === "$") consumed = 2; else if (char === "&") { expansion = matched; consumed = 2; } else if (char === "`") { expansion = str.slice(0, position); consumed = 2; } else if (char === "'") { expansion = str.slice(position + matched.length); consumed = 2; } else if (char === "<" && namedCaptures !== void 0) { const close = replacement.indexOf(">", dollar + 2); if (close !== -1) { expansion = namedCaptures[replacement.slice(dollar + 2, close)] ?? ""; consumed = close + 1 - dollar; } } else if (char >= "0" && char <= "9") { const second = replacement[dollar + 2]; const double = second >= "0" && second <= "9" ? Number(char + second) : NaN; const single = Number(char); if (double >= 1 && double <= captures.length) { expansion = captures[double - 1] ?? ""; consumed = 3; } else if (single >= 1 && single <= captures.length) { expansion = captures[single - 1] ?? ""; consumed = 2; } } result += expansion; index = dollar + consumed; } return result; } var MagicString = class MagicString { constructor(string, options = {}) { const chunk = new Chunk(0, string.length, string); Object.defineProperties(this, { original: { writable: true, value: string }, outro: { writable: true, value: "" }, intro: { writable: true, value: "" }, firstChunk: { writable: true, value: chunk }, lastChunk: { writable: true, value: chunk }, lastSearchedChunk: { writable: true, value: chunk }, byStart: { writable: true, value: /* @__PURE__ */ new Map([[0, chunk]]) }, byEnd: { writable: true, value: /* @__PURE__ */ new Map([[string.length, chunk]]) }, filename: { writable: true, value: options.filename }, indentExclusionRanges: { writable: true, value: options.indentExclusionRanges }, sourcemapLocations: { writable: true, value: new BitSet() }, storedNames: { writable: true, value: {} }, indentStr: { writable: true, value: void 0 }, ignoreList: { writable: true, value: options.ignoreList }, offset: { writable: true, value: options.offset || 0 }, hasMovedChunks: { writable: true, value: false } }); } /** * Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false. */ addSourcemapLocation(char) { this.sourcemapLocations.add(char); } /** * Appends the specified content to the end of the string. */ append(content) { if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`); this.outro += content; return this; } /** * Appends the specified content at the index in the original string. * If a range *ending* with index is subsequently moved, the insert will be moved with it. * See also `s.prependLeft(...)`. */ appendLeft(index, content) { index = index + this.offset; if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`); this._split(index); const chunk = this.byEnd.get(index); if (chunk) chunk.appendLeft(content); else this.intro += content; return this; } /** * Appends the specified content at the index in the original string. * If a range *starting* with index is subsequently moved, the insert will be moved with it. * See also `s.prependRight(...)`. */ appendRight(index, content) { index = index + this.offset; if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`); this._split(index); const chunk = this.byStart.get(index); if (chunk) chunk.appendRight(content); else this.outro += content; return this; } /** * Does what you'd expect. */ clone() { const cloned = new MagicString(this.original, { filename: this.filename, ignoreList: this.ignoreList, offset: this.offset }); let originalChunk = this.firstChunk; let clonedChunk = cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone(); while (originalChunk) { cloned.byStart.set(clonedChunk.start, clonedChunk); cloned.byEnd.set(clonedChunk.end, clonedChunk); const nextOriginalChunk = originalChunk.next; const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone(); if (nextClonedChunk) { clonedChunk.next = nextClonedChunk; nextClonedChunk.previous = clonedChunk; clonedChunk = nextClonedChunk; } originalChunk = nextOriginalChunk; } cloned.lastChunk = clonedChunk; if (this.indentExclusionRanges) cloned.indentExclusionRanges = this.indentExclusionRanges.slice(); cloned.sourcemapLocations = new BitSet(this.sourcemapLocations); cloned.storedNames = { ...this.storedNames }; cloned.intro = this.intro; cloned.outro = this.outro; cloned.hasMovedChunks = this.hasMovedChunks; return cloned; } /** * Generates a sourcemap object with raw mappings in array form, rather than encoded as a string. * Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead. */ generateDecodedMap(options) { options = options || {}; const mappings = new Mappings(options.hires); const names = this._generateMappings(mappings); return { ...this._mapProperties(options, names), mappings: mappings.raw, rangeMappings: mappings.rawRangeMappings }; } /** * Generates a version 3 sourcemap. */ generateMap(options) { options = options || {}; const encoder = new MappingsEncoder(); const mappings = new Mappings(options.hires, encoder); const names = this._generateMappings(mappings); return new SourceMap({ ...this._mapProperties(options, names), mappings: encoder.finish(mappings.rawSegments), rangeMappings: mappings.rawRangeMappings }); } /** @internal */ _generateMappings(mappings) { const sourceIndex = 0; const names = Object.keys(this.storedNames); const locate = getLocator(this.original); if (this.intro) mappings.advance(this.intro); this.firstChunk.eachNext((chunk) => { const loc = locate(chunk.start); if (chunk.intro.length) mappings.advance(chunk.intro); if (chunk.edited) mappings.addEdit(sourceIndex, chunk.content, loc, chunk.storeName ? names.indexOf(chunk.original) : -1); else mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations); if (chunk.outro.length) mappings.advance(chunk.outro); }); if (this.outro) mappings.advance(this.outro); return names; } /** @internal */ _mapProperties(options, names) { return { file: options.file ? options.file.split(/[/\\]/).pop() : void 0, sources: [options.source ? getRelativePath(options.file || "", options.source) : options.file || ""], sourcesContent: options.includeContent ? [this.original] : void 0, names, x_google_ignoreList: this.ignoreList ? [0] : void 0 }; } /** @internal */ _ensureindentStr() { if (this.indentStr === void 0) this.indentStr = guessIndent(this.original); } /** @internal */ _getRawIndentString() { this._ensureindentStr(); return this.indentStr; } getIndentString() { this._ensureindentStr(); return this.indentStr === null ? " " : this.indentStr; } indent(indentStr, options) { const pattern = /^[^\r\n]/gm; if (isObject(indentStr)) { options = indentStr; indentStr = void 0; } if (indentStr === void 0) { this._ensureindentStr(); indentStr = this.indentStr || " "; } if (indentStr === "") return this; const resolvedIndentStr = indentStr; options = options || {}; const isExcluded = {}; if (options.exclude) (typeof options.exclude[0] === "number" ? [options.exclude] : options.exclude).forEach((exclusion) => { for (let i = exclusion[0]; i < exclusion[1]; i += 1) isExcluded[i] = true; }); let shouldIndentNextCharacter = options.indentStart !== false; const indentPiece = (str) => { if (str === "") return str; const indented = str.replace(pattern, (match, offset) => offset > 0 || shouldIndentNextCharacter ? `${resolvedIndentStr}${match}` : match); shouldIndentNextCharacter = str[str.length - 1] === "\n"; return indented; }; this.intro = indentPiece(this.intro); let charIndex = 0; let chunk = this.firstChunk; const indentAt = (index) => { shouldIndentNextCharacter = false; if (index === chunk.start) chunk.appendRight(resolvedIndentStr); else { this._splitChunk(chunk, index); chunk = chunk.next; chunk.prependRight(resolvedIndentStr); } }; while (chunk) { const end = chunk.end; if (!isExcluded[chunk.start]) chunk.intro = indentPiece(chunk.intro); if (chunk.edited) { if (!isExcluded[charIndex]) chunk.content = indentPiece(chunk.content); } else if (options.exclude) { charIndex = chunk.start; while (charIndex < end) { if (!isExcluded[charIndex]) { const char = this.original.charCodeAt(charIndex); if (char === NEWLINE_CHAR) shouldIndentNextCharacter = true; else if (char !== CR_CHAR && shouldIndentNextCharacter) indentAt(charIndex); } charIndex += 1; } } else { charIndex = chunk.start; while (charIndex < end) { if (!shouldIndentNextCharacter) { const nextLine = this.original.indexOf(n, charIndex); if (nextLine === -1 || nextLine >= end) break; shouldIndentNextCharacter = true; charIndex = nextLine + 1; continue; } const char = this.original.charCodeAt(charIndex); if (char === NEWLINE_CHAR || char === CR_CHAR) { charIndex += 1; continue; } indentAt(charIndex); charIndex += 1; } } if (!isExcluded[chunk.end - 1]) chunk.outro = indentPiece(chunk.outro); charIndex = chunk.end; chunk = chunk.next; } this.outro = indentPiece(this.outro); return this; } /** @internal */ insert() { throw new MagicStringError("insert() is deprecated, use appendLeft() or prependRight()"); } /** @internal */ insertLeft(index, content) { if (!warned.insertLeft) { console.warn("magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead"); warned.insertLeft = true; } return this.appendLeft(index, content); } /** @internal */ insertRight(index, content) { if (!warned.insertRight) { console.warn("magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead"); warned.insertRight = true; } return this.prependRight(index, content); } /** * Moves the characters from `start` and `end` to `index`. * * `affinity` controls where the range is anchored at `index`. With the * default `'right'`, it is inserted before the content that starts at `index`; * with `'left'`, it is inserted after the content that ends at `index`. The * two differ only when other content has already been moved to that boundary, * mirroring the `appendLeft`/`appendRight` distinction. */ move(start, end, index, affinity = "right") { start = start + this.offset; end = end + this.offset; index = index + this.offset; if (start === end) return this; if (index >= start && index <= end) throw new MagicStringError("cannot move a selection inside itself"); this._split(start); this._split(end); this._split(index); const first = this.byStart.get(start); const last = this.byEnd.get(end); if (this.hasMovedChunks) { let cursor = first; while (cursor !== last) { cursor = cursor.next; if (!cursor || cursor.start < start || cursor.end > end) throw new MagicStringError(`cannot move ${start} to ${end} because an earlier move split that range`); } } const oldLeft = first.previous; const oldRight = last.next; let newLeft; let newRight; if (affinity === "left") { newLeft = this.byEnd.get(index) ?? null; if (!newLeft) { if (first === this.firstChunk) return this; newRight = this.firstChunk; } else { if (newLeft.next === first) return this; newRight = newLeft.next; } } else { newRight = this.byStart.get(index) ?? null; if (!newRight) { if (last === this.lastChunk) return this; newLeft = this.lastChunk; } else { if (newRight.previous === last) return this; newLeft = newRight.previous; } } if (oldLeft) oldLeft.next = oldRight; if (oldRight) oldRight.previous = oldLeft; if (newLeft) newLeft.next = first; if (newRight) newRight.previous = last; if (!first.previous) this.firstChunk = last.next; if (!last.next) { this.lastChunk = first.previous; this.lastChunk.next = null; } first.previous = newLeft; last.next = newRight || null; if (!newLeft) this.firstChunk = first; if (!newRight) this.lastChunk = last; this.hasMovedChunks = true; return this; } /** * Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in * that range. The same restrictions as `s.remove()` apply. * * The fourth argument is optional. It can have a storeName property - if true, the original name will be stored * for later inclusion in a sourcemap's names array - and a contentOnly property which determines whether only * the content is overwritten, or anything that was appended/prepended to the range as well. * * It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content. */ overwrite(start, end, content, options) { const optionObject = typeof options === "object" && options ? options : {}; return this.update(start, end, content, { ...optionObject, overwrite: !optionObject.contentOnly }); } /** * Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply. * * The fourth argument is optional. It can have a storeName property - if true, the original name will be stored * for later inclusion in a sourcemap's names array - and an overwrite property which determines whether only * the content is overwritten, or anything that was appended/prepended to the range as well. */ update(start, end, content, options) { start = start + this.offset; end = end + this.offset; if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`); if (this.original.length !== 0) { if (start < 0) start = Math.max(0, start + this.original.length); if (end < 0) end = Math.max(0, end + this.original.length); } if (start < 0) throw new MagicStringError(`start ${start} is out of bounds`); if (end > this.original.length) throw new MagicStringError(`end ${end} is out of bounds`); if (start === end) throw new MagicStringError(`cannot overwrite a zero-length range at ${start}, use appendLeft() or prependRight()`); if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`); this._split(start); this._split(end); if (options === true) { if (!warned.storeName) { console.warn("The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string"); warned.storeName = true; } options = { storeName: true }; } const optionObject = typeof options === "object" && options ? options : {}; const storeName = optionObject.storeName || false; const overwrite = optionObject.overwrite || false; if (storeName) { const original = this.original.slice(start, end); Object.defineProperty(this.storedNames, original, { writable: true, value: true, enumerable: true }); } const first = this.byStart.get(start); const last = this.byEnd.get(end); /* v8 ignore else -- unreachable: a valid start/end always yields a `first` chunk */ if (first) { let chunk = first; while (chunk !== last) { if (chunk.next !== this.byStart.get(chunk.end)) throw new MagicStringError("cannot overwrite across a split point"); chunk = chunk.next; chunk.edit("", false, !overwrite); } first.edit(content, storeName, !overwrite); } else { const newChunk = new Chunk(start, end, "").edit(content, storeName); last.next = newChunk; newChunk.previous = last; } return this; } /** * Prepends the string with the specified content. */ prepend(content) { if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`); this.intro = content + this.intro; return this; } /** * Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index */ prependLeft(index, content) { index = index + this.offset; if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`); this._split(index); const chunk = this.byEnd.get(index); if (chunk) chunk.prependLeft(content); else this.intro = content + this.intro; return this; } /** * Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index` */ prependRight(index, content) { index = index + this.offset; if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`); this._split(index); const chunk = this.byStart.get(index); if (chunk) chunk.prependRight(content); else this.outro = content + this.outro; return this; } /** * Removes the characters from `start` to `end` (of the original string, **not** the generated string). * Content appended or prepended at positions strictly inside the range is removed with it, while * content attached at `start` or `end` is preserved — use `s.overwrite(start, end, '')` to remove * the range including its edge inserts. * Repeated removals and removals with partially overlapping ranges are allowed. */ remove(start, end) { start = start + this.offset; end = end + this.offset; if (this.original.length !== 0) { if (start < 0) start = Math.max(0, start + this.original.length); if (end < 0) end = Math.max(0, end + this.original.length); } if (start === end) return this; if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`); if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`); this._split(start); this._split(end); let chunk = this.byStart.get(start); while (chunk) { if (chunk.start > start) chunk.intro = ""; if (chunk.end < end) chunk.outro = ""; chunk.edit("", false, true); chunk = end > chunk.end ? this.byStart.get(chunk.end) : null; } return this; } /** * Reset the modified characters from `start` to `end` (of the original string, **not** the generated string). */ reset(start, end) { start = start + this.offset; end = end + this.offset; if (this.original.length !== 0) { if (start < 0) start = Math.max(0, start + this.original.length); if (end < 0) end = Math.max(0, end + this.original.length); } if (start === end) return this; if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`); if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`); this._split(start); this._split(end); let chunk = this.byStart.get(start); while (chunk) { chunk.reset(); chunk = end > chunk.end ? this.byStart.get(chunk.end) : null; } return this; } lastChar() { if (this.outro.length) return this.outro[this.outro.length - 1]; let chunk = this.lastChunk; while (chunk) { if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1]; if (chunk.content.length) return chunk.content[chunk.content.length - 1]; if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1]; chunk = chunk.previous; } if (this.intro.length) return this.intro[this.intro.length - 1]; return ""; } lastLine() { let lineIndex = this.outro.lastIndexOf(n); if (lineIndex !== -1) return this.outro.substr(lineIndex + 1); let lineStr = this.outro; let chunk = this.lastChunk; while (chunk) { if (chunk.outro.length > 0) { lineIndex = chunk.outro.lastIndexOf(n); if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr; lineStr = chunk.outro + lineStr; } if (chunk.content.length > 0) { lineIndex = chunk.content.lastIndexOf(n); if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr; lineStr = chunk.content + lineStr; } if (chunk.intro.length > 0) { lineIndex = chunk.intro.lastIndexOf(n); if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr; lineStr = chunk.intro + lineStr; } chunk = chunk.previous; } lineIndex = this.intro.lastIndexOf(n); if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr; return this.intro + lineStr; } /** * Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string. * Throws error if the indices are for characters that were already removed. */ slice(start = 0, end = this.original.length - this.offset) { start = start + this.offset; end = end + this.offset; if (this.original.length !== 0) { if (start < 0) start = Math.max(0, start + this.original.length); if (end < 0) end = Math.max(0, end + this.original.length); } let result = ""; let chunk = this.firstChunk; while (chunk && (chunk.start > start || chunk.end <= start)) { if (chunk.start < end && chunk.end >= end || end === 0 && chunk.start === 0) return result; chunk = chunk.next; } if (chunk && chunk.edited && chunk.start !== start) throw new MagicStringError(`cannot use edited character ${start} as slice start anchor`); const startChunk = chunk; while (chunk) { if (end === 0 && chunk.start === 0) break; if (chunk.intro && (startChunk !== chunk || chunk.start === start)) result += chunk.intro; const containsEnd = chunk.start < end && chunk.end >= end; if (containsEnd && chunk.edited && chunk.end !== end) throw new MagicStringError(`cannot use edited character ${end} as slice end anchor`); const sliceStart = startChunk === chunk ? start - chunk.start : 0; const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length; result += chunk.content.slice(sliceStart, sliceEnd); if (chunk.outro && (!containsEnd || chunk.end === end)) result += chunk.outro; if (containsEnd) break; chunk = chunk.next; } return result; } /** * Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed. */ snip(start, end) { const clone = this.clone(); clone.remove(0, start); clone.remove(end, clone.original.length); return clone; } /** @internal */ _split(index) { if (this.byStart.get(index) || this.byEnd.get(index)) return; let chunk = this.lastSearchedChunk; let previousChunk = chunk; const searchForward = index > chunk.end; while (chunk) { if (chunk.contains(index)) return this._splitChunk(chunk, index); chunk = searchForward ? this.byStart.get(chunk.end) : this.byEnd.get(chunk.start); if (chunk === previousChunk) return; previousChunk = chunk; } } /** @internal */ _splitChunk(chunk, index) { if (chunk.edited && chunk.content.length) { const loc = getLocator(this.original)(index); throw new MagicStringError(`cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`); } const newChunk = chunk.split(index); this.byEnd.set(index, chunk); this.byStart.set(index, newChunk); this.byEnd.set(newChunk.end, newChunk); if (chunk === this.lastChunk) this.lastChunk = newChunk; this.lastSearchedChunk = chunk; return true; } /** * Returns the generated string. */ toString() { let str = this.intro; let chunk = this.firstChunk; while (chunk) { str += chunk.toString(); chunk = chunk.next; } return str + this.outro; } /** * Returns true if the resulting source is empty (disregarding white space). */ isEmpty() { if (this.intro.length && this.intro.trim()) return false; let chunk = this.firstChunk; while (chunk) { if (chunk.intro.length && chunk.intro.trim() || chunk.content.length && chunk.content.trim() || chunk.outro.length && chunk.outro.trim()) return false; chunk = chunk.next; } if (this.outro.length && this.outro.trim()) return false; return true; } length() { let chunk = this.firstChunk; let length = 0; while (chunk) { length += chunk.intro.length + chunk.content.length + chunk.outro.length; chunk = chunk.next; } return length; } /** * Removes empty lines from the start and end. */ trimLines() { return this.trim("[\\r\\n]"); } /** * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end. */ trim(charType) { return this.trimStart(charType).trimEnd(charType); } /** @internal */ trimEndAborted(charType) { const rx = new RegExp(`${charType || "\\s"}+$`); this.outro = this.outro.replace(rx, ""); if (this.outro.length) return true; let chunk = this.lastChunk; do { const end = chunk.end; const aborted = chunk.trimEnd(rx); if (chunk.end !== end) { if (this.lastChunk === chunk) this.lastChunk = chunk.next; this.byEnd.set(chunk.end, chunk); this.byStart.set(chunk.next.start, chunk.next); this.byEnd.set(chunk.next.end, chunk.next); } if (aborted) return true; chunk = chunk.previous; } while (chunk); this.intro = this.intro.replace(rx, ""); return this.intro.length > 0; } /** * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end. */ trimEnd(charType) { this.trimEndAborted(charType); return this; } /** @internal */ trimStartAborted(charType) { const rx = new RegExp(`^${charType || "\\s"}+`); this.intro = this.intro.replace(rx, ""); if (this.intro.length) return true; let chunk = this.firstChunk; do { const end = chunk.end; const aborted = chunk.trimStart(rx); if (chunk.end !== end) { if (chunk === this.lastChunk) this.lastChunk = chunk.next; this.byEnd.set(chunk.end, chunk); this.byStart.set(chunk.next.start, chunk.next); this.byEnd.set(chunk.next.end, chunk.next); } if (aborted) return true; chunk = chunk.next; } while (chunk); this.outro = this.outro.replace(rx, ""); return this.outro.length > 0; } /** * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start. */ trimStart(charType) { this.trimStartAborted(charType); return this; } /** * Indicates if the string has been changed. */ hasChanged() { if (this.intro || this.outro) return true; let outputIndex = 0; let chunk = this.firstChunk; while (chunk) { if (chunk.intro || chunk.outro) return true; if (!chunk.edited && chunk.start === outputIndex) outputIndex = chunk.end; else { if (!this.original.startsWith(chunk.content, outputIndex)) return true; outputIndex += chunk.content.length; } chunk = chunk.next; } return outputIndex !== this.original.length; } /** * Whether the original range [start, end) has had any of its characters * removed. `replace`/`replaceAll` search `original`, so a match can land on * text that is no longer in the output - overwriting it would resurrect the * removed characters, so such matches are skipped instead. * * @internal */ _hasRemovedContent(start, end) { let chunk = this.byStart.get(start); if (!chunk) { chunk = this.lastSearchedChunk; const searchForward = start >= chunk.end; while (chunk && !chunk.contains(start)) chunk = searchForward ? this.byStart.get(chunk.end) : this.byEnd.get(chunk.start); if (chunk) this.lastSearchedChunk = chunk; } while (chunk && chunk.start < end) { if (chunk.content === "") return true; chunk = this.byStart.get(chunk.end); } return false; } /** @internal */ _replaceRegexp(searchValue, replacement) { function getReplacement(match, str) { if (typeof replacement === "string") return expandReplacement(replacement, match[0], match.index, str, match.slice(1), match.groups); else return match.groups === void 0 ? replacement(match[0], ...match.slice(1), match.index, str) : replacement(match[0], ...match.slice(1), match.index, str, match.groups); } const replaceMatch = (match) => { /* v8 ignore next 2 -- `match.index` is always defined for matches from `matchAll` */ if (match.index == null) return false; if (this._hasRemovedContent(match.index, match.index + match[0].length)) return false; const replacement = getReplacement(match, this.original); if (replacement === match[0]) return true; if (match[0].length === 0) this.appendRight(match.index - this.offset, replacement); else this.overwrite(match.index - this.offset, match.index + match[0].length - this.offset, replacement); return true; }; if (searchValue.global) { searchValue.lastIndex = 0; for (const match of this.original.matchAll(searchValue)) replaceMatch(match); } else { const match = this.original.match(searchValue); if (match && !replaceMatch(match)) { const global = new RegExp(searchValue.source, `${searchValue.flags}g`); for (const next of this.original.matchAll(global)) if (replaceMatch(next)) break; } } return this; } /** @internal */ _replaceString(string, replacement) { const { original } = this; let index = original.indexOf(string); while (index !== -1) { if (this._hasRemovedContent(index, index + string.length)) { index = original.indexOf(string, index + string.length); continue; } if (typeof replacement === "function") replacement = replacement(string, index, original); else replacement = expandReplacement(replacement, string, index, original, [], void 0); if (string !== replacement) { if (string.length === 0) this.appendRight(index - this.offset, replacement); else this.overwrite(index - this.offset, index + string.length - this.offset, replacement); } break; } return this; } /** * String replacement with RegExp or string. */ replace(searchValue, replacement) { if (typeof searchValue === "string") return this._replaceString(searchValue, replacement); return this._replaceRegexp(searchValue, replacement); } /** @internal */ _replaceAllString(string, replacement) { const { original } = this; const stringLength = string.length; if (stringLength === 0) { for (let index = 0; index <= original.length; index += 1) { if (this._hasRemovedContent(index, index)) continue; const _replacement = typeof replacement === "function" ? replacement("", index, original) : expandReplacement(replacement, "", index, original, [], void 0); if (_replacement !== "") this.appendRight(index - this.offset, _replacement); } return this; } for (let index = original.indexOf(string); index !== -1; index = original.indexOf(string, index + stringLength)) { if (this._hasRemovedContent(index, index + stringLength)) continue; const previous = original.slice(index, index + stringLength); const _replacement = typeof replacement === "function" ? replacement(previous, index, original) : expandReplacement(replacement, previous, index, original, [], void 0); if (previous !== _replacement) this.overwrite(index - this.offset, index + stringLength - this.offset, _replacement); } return this; } /** * Same as `s.replace`, but replace all matched strings instead of just one. */ replaceAll(searchValue, replacement) { if (typeof searchValue === "string") return this._replaceAllString(searchValue, replacement); if (!searchValue.global) throw new MagicStringError("replaceAll() requires a global RegExp"); return this._replaceRegexp(searchValue, replacement); } }; //#endregion //#region src/Bundle.ts const hasOwnProp = Object.prototype.hasOwnProperty; var Bundle = class Bundle { constructor(options = {}) { this.intro = options.intro || ""; this.separator = options.separator !== void 0 ? options.separator : "\n"; this.sources = []; this.uniqueSources = []; this.uniqueSourceIndexByFilename = {}; } /** * Adds the specified source to the bundle, which can either be a `MagicString` object directly, * or an options object that holds a magic string `content` property and optionally provides * a `filename` for the source within the bundle, as well as an optional `ignoreList` hint * (which defaults to `false`). The `filename` is used when constructing the source map for the * bundle, to identify this `source` in the source map's `sources` field. The `ignoreList` hint * is used to populate the `x_google_ignoreList` extension field in the source map, which is a * mechanism for tools to signal to debuggers that certain sources should be ignored by default * (depending on user preferences). */ addSource(source) { if (source instanceof MagicString) return this.addSource({ content: source, filename: source.filename, separator: this.separator }); if (!isObject(source) || !source.content) throw new MagicStringError("addSource() requires a `content` property that is a MagicString"); [ "filename", "ignoreList", "indentExclusionRanges", "separator" ].forEach((option) => { if (!hasOwnProp.call(source, option)) source[option] = source.content[option]; }); if (source.separator === void 0) source.separator = this.separator; if (source.filename) { if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) { this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length; this.uniqueSources.push({ filename: source.filename, content: source.content.original }); } else { const uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]]; if (source.content.original !== uniqueSource.content) throw new MagicStringError(`duplicate filename "${source.filename}" with different content, use unique filenames`); } } this.sources.push(source); return this; } append(str, options) { this.addSource({ content: new MagicString(str), separator: options && options.separator || "" }); return this; } clone() { const bundle = new Bundle({ intro: this.intro, separator: this.separator }); this.sources.forEach((source) => { bundle.addSource({ filename: source.filename, content: source.content.clone(), ignoreList: source.ignoreList, indentExclusionRanges: source.indentExclusionRanges, separator: source.separator }); }); return bundle; } /** * Flattens the bundle into a single `MagicString`, so the concatenated result can be * processed further with the full `MagicString` API. The returned string's `original` * is the concatenation of every source's `original`, and all existing edits, inserts, * intros, outros and separators are preserved as inserted content, so its `toString()` * equals the bundle's `toString()` and its sourcemap maps back to that combined original. * * Because a `MagicString` maps to a single source, per-source `filename`s are not carried * over; generate the bundle's map before flattening if you need the multi-source mapping. */ toMagicString() { const combined = new MagicString(this.sources.map((source) => source.content.original).join("")); let offset = 0; let pending = this.intro; let first = null; let last = null; const byStart = /* @__PURE__ */ new Map(); const byEnd = /* @__PURE__ */ new Map(); let hasMovedChunks = false; this.sources.forEach((source, i) => { const magicString = source.content; const separator = i > 0 ? source.separator !== void 0 ? source.separator : this.separator : ""; if (magicString.original.length === 0) { pending += separator + magicString.toString(); return; } pending += separator + magicString.intro; let sourceFirst = null; let previous = null; let originalChunk = magicString.firstChunk; while (originalChunk) { const chunk = originalChunk.clone(); chunk.start += offset; chunk.end += offset; chunk.previous = previous; chunk.next = null; if (previous) previous.next = chunk; byStart.set(chunk.start, chunk); byEnd.set(chunk.end, chunk); sourceFirst ??= chunk; previous = chunk; originalChunk = originalChunk.next; } const sourceLast = previous; sourceFirst.intro = pending + sourceFirst.intro; pending = ""; sourceLast.outro += magicString.outro; if (last) { last.next = sourceFirst; sourceFirst.previous = last; } else first = sourceFirst; last = sourceLast; for (let index = 0; index < magicString.original.length; index += 1) if (magicString.sourcemapLocations.has(index)) combined.sourcemapLocations.add(index + offset); Object.keys(magicString.storedNames).forEach((name) => { Object.defineProperty(combined.storedNames, name, { writable: true, value: true, enumerable: true }); }); if (magicString.hasMovedChunks) hasMovedChunks = true; offset += magicString.original.length; }); if (!first) { combined.intro = pending; return combined; } if (pending) last.outro += pending; combined.firstChunk = first; combined.lastChunk = last; combined.lastSearchedChunk = first; combined.byStart = byStart; combined.byEnd = byEnd; combined.hasMovedChunks = hasMovedChunks; return combined; } generateDecodedMap(options = {}) { const mappings = new Mappings(options.hires); const { names, x_google_ignoreList } = this._generateMappings(mappings); return { ...this._mapProperties(options, names, x_google_ignoreList), mappings: mappings.raw, rangeMappings: mappings.rawRangeMappings }; } generateMap(options = {}) { const encoder = new MappingsEncoder(); const mappings = new Mappings(options.hires, encoder); const { names, x_google_ignoreList } = this._generateMappings(mappings); return new SourceMap({ ...this._mapProperties(options, names, x_google_ignoreList), mappings: encoder.finish(mappings.rawSegments), rangeMappings: mappings.rawRangeMappings }); } /** @internal */ _generateMappings(mappings) { const names = []; let x_google_ignoreList; this.sources.forEach((source) => { Object.keys(source.content.storedNames).forEach((name) => { if (!names.includes(name)) names.push(name); }); }); if (this.intro) mappings.advance(this.intro); this.sources.forEach((source, i) => { if (i > 0) /* v8 ignore next -- addSource always normalizes source.separator */ mappings.advance(source.separator !== void 0 ? source.separator : this.separator); const sourceIndex = source.filename ? this.uniqueSourceIndexByFilename[source.filename] : -1; const magicString = source.content; const locate = getLocator(magicString.original); if (magicString.intro) mappings.advance(magicString.intro); magicString.firstChunk.eachNext((chunk) => { const loc = locate(chunk.start); if (chunk.intro.length) mappings.advance(chunk.intro); if (source.filename) { if (chunk.edited) mappings.addEdit(sourceIndex, chunk.content, loc, chunk.storeName ? names.indexOf(chunk.original) : -1); else mappings.addUneditedChunk(sourceIndex, chunk, magicString.original, loc, magicString.sourcemapLocations); } else mappings.advance(chunk.content); if (chunk.outro.length) mappings.advance(chunk.outro); }); if (magicString.outro) mappings.advance(magicString.outro); if (source.ignoreList && sourceIndex !== -1) { if (x_google_ignoreList === void 0) x_google_ignoreList = []; x_google_ignoreList.push(sourceIndex); } }); return { names, x_google_ignoreList }; } /** @internal */ _mapProperties(options, names, x_google_ignoreList) { return { file: options.file ? options.file.split(/[/\\]/).pop() : void 0, sources: this.uniqueSources.map((source) => { return options.file ? getRelativePath(options.file, source.filename) : source.filename; }), sourcesContent: this.uniqueSources.map((source) => { return (typeof options.includeContent === "function" ? options.includeContent(source) : options.includeContent) ? source.content : null; }), names, x_google_ignoreList }; } getIndentString() { const indentStringCounts = {}; this.sources.forEach((source) => { const indentStr = source.content._getRawIndentString(); if (indentStr === null) return; if (!indentStringCounts[indentStr]) indentStringCounts[indentStr] = 0; indentStringCounts[indentStr] += 1; }); return Object.keys(indentStringCounts).sort((a, b) => { return indentStringCounts[b] - indentStringCounts[a]; })[0] || " "; } indent(indentStr) { if (!arguments.length) indentStr = this.getIndentString(); if (indentStr === "") return this; let trailingNewline = !this.intro || this.intro.slice(-1) === "\n"; this.sources.forEach((source, i) => { /* v8 ignore next -- addSource always normalizes source.separator */ const separator = source.separator !== void 0 ? source.separator : this.separator; const indentStart = trailingNewline || i > 0 && /\r?\n$/.test(separator); source.content.indent(indentStr, { exclude: source.indentExclusionRanges, indentStart }); trailingNewline = source.content.lastChar() === "\n"; }); if (this.intro) this.intro = indentStr + this.intro.replace(/^[^\n]/gm, (match, index) => { return index > 0 ? indentStr + match : match; }); return this; } prepend(str) { this.intro = str + this.intro; return this; } toString() { const body = this.sources.map((source, i) => { /* v8 ignore next -- addSource always normalizes source.separator */ const separator = source.separator !== void 0 ? source.separator : this.separator; return (i > 0 ? separator : "") + source.content.toString(); }).join(""); return this.intro + body; } isEmpty() { if (this.intro.length && this.intro.trim()) return false; if (this.sources.some((source, i) => { /* v8 ignore next -- addSource always normalizes source.separator */ const separator = source.separator !== void 0 ? source.separator : this.separator; return i > 0 && separator.trim() !== "" || !source.content.isEmpty(); })) return false; return true; } length() { return this.sources.reduce((length, source, i) => { /* v8 ignore next -- addSource always normalizes source.separator */ const separator = source.separator !== void 0 ? source.separator : this.separator; return length + (i > 0 ? separator.length : 0) + source.content.toString().length; }, this.intro.length); } trimLines() { return this.trim("[\\r\\n]"); } trim(charType) { return this.trimStart(charType).trimEnd(charType); } trimStart(charType) { const rx = new RegExp(`^${charType || "\\s"}+`); this.intro = this.intro.replace(rx, ""); if (!this.intro) for (let i = 0; i < this.sources.length; i += 1) { const source = this.sources[i]; if (i > 0) { source.separator = (source.separator !== void 0 ? source.separator : this.separator).replace(rx, ""); if (source.separator) break; } if (source.content.trimStartAborted(charType)) break; } return this; } trimEnd(charType) { const rx = new RegExp(`${charType || "\\s"}+$`); for (let i = this.sources.length - 1; i >= 0; i -= 1) { const source = this.sources[i]; if (source.content.trimEndAborted(charType)) return this; if (i > 0) { source.separator = (source.separator !== void 0 ? source.separator : this.separator).replace(rx, ""); if (source.separator) return this; } } this.intro = this.intro.replace(rx, ""); return this; } }; //#endregion export { Bundle, MagicString, MagicString as default, MagicStringError, SourceMap };