@react-email/tailwind
Version:
A React component to wrap emails with Tailwind CSS
1,631 lines (1,614 loc) • 712 kB
JavaScript
import * as React$1 from "react";
import React from "react";
import { Body } from "@react-email/body";
import { Button } from "@react-email/button";
import { CodeBlock } from "@react-email/code-block";
import { CodeInline } from "@react-email/code-inline";
import { Container } from "@react-email/container";
import { Heading } from "@react-email/heading";
import { Hr } from "@react-email/hr";
import { Img } from "@react-email/img";
import { Link } from "@react-email/link";
import { Preview } from "@react-email/preview";
import { Text } from "@react-email/text";
import { compile } from "tailwindcss";
import { jsx } from "react/jsx-runtime";
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (all) => {
let target = {};
for (var name$49 in all) __defProp(target, name$49, {
get: all[name$49],
enumerable: true
});
return target;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/types.js
const EOF = 0;
const Ident = 1;
const Function = 2;
const AtKeyword = 3;
const Hash = 4;
const String$1 = 5;
const BadString = 6;
const Url = 7;
const BadUrl = 8;
const Delim = 9;
const Number$1 = 10;
const Percentage = 11;
const Dimension = 12;
const WhiteSpace = 13;
const CDO = 14;
const CDC = 15;
const Colon = 16;
const Semicolon = 17;
const Comma = 18;
const LeftSquareBracket = 19;
const RightSquareBracket = 20;
const LeftParenthesis = 21;
const RightParenthesis = 22;
const LeftCurlyBracket = 23;
const RightCurlyBracket = 24;
const Comment = 25;
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/char-code-definitions.js
const EOF$1 = 0;
function isDigit(code$1) {
return code$1 >= 48 && code$1 <= 57;
}
function isHexDigit(code$1) {
return isDigit(code$1) || code$1 >= 65 && code$1 <= 70 || code$1 >= 97 && code$1 <= 102;
}
function isUppercaseLetter(code$1) {
return code$1 >= 65 && code$1 <= 90;
}
function isLowercaseLetter(code$1) {
return code$1 >= 97 && code$1 <= 122;
}
function isLetter(code$1) {
return isUppercaseLetter(code$1) || isLowercaseLetter(code$1);
}
function isNonAscii(code$1) {
return code$1 >= 128;
}
function isNameStart(code$1) {
return isLetter(code$1) || isNonAscii(code$1) || code$1 === 95;
}
function isName(code$1) {
return isNameStart(code$1) || isDigit(code$1) || code$1 === 45;
}
function isNonPrintable(code$1) {
return code$1 >= 0 && code$1 <= 8 || code$1 === 11 || code$1 >= 14 && code$1 <= 31 || code$1 === 127;
}
function isNewline(code$1) {
return code$1 === 10 || code$1 === 13 || code$1 === 12;
}
function isWhiteSpace(code$1) {
return isNewline(code$1) || code$1 === 32 || code$1 === 9;
}
function isValidEscape(first, second) {
if (first !== 92) return false;
if (isNewline(second) || second === EOF$1) return false;
return true;
}
function isIdentifierStart(first, second, third) {
if (first === 45) return isNameStart(second) || second === 45 || isValidEscape(second, third);
if (isNameStart(first)) return true;
if (first === 92) return isValidEscape(first, second);
return false;
}
function isNumberStart(first, second, third) {
if (first === 43 || first === 45) {
if (isDigit(second)) return 2;
return second === 46 && isDigit(third) ? 3 : 0;
}
if (first === 46) return isDigit(second) ? 2 : 0;
if (isDigit(first)) return 1;
return 0;
}
function isBOM(code$1) {
if (code$1 === 65279) return 1;
if (code$1 === 65534) return 1;
return 0;
}
const CATEGORY = new Array(128);
const EofCategory = 128;
const WhiteSpaceCategory = 130;
const DigitCategory = 131;
const NameStartCategory = 132;
const NonPrintableCategory = 133;
for (let i = 0; i < CATEGORY.length; i++) CATEGORY[i] = isWhiteSpace(i) && WhiteSpaceCategory || isDigit(i) && DigitCategory || isNameStart(i) && NameStartCategory || isNonPrintable(i) && NonPrintableCategory || i || EofCategory;
function charCodeCategory(code$1) {
return code$1 < 128 ? CATEGORY[code$1] : NameStartCategory;
}
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/utils.js
function getCharCode(source, offset) {
return offset < source.length ? source.charCodeAt(offset) : 0;
}
function getNewlineLength(source, offset, code$1) {
if (code$1 === 13 && getCharCode(source, offset + 1) === 10) return 2;
return 1;
}
function cmpChar(testStr, offset, referenceCode) {
let code$1 = testStr.charCodeAt(offset);
if (isUppercaseLetter(code$1)) code$1 = code$1 | 32;
return code$1 === referenceCode;
}
function cmpStr(testStr, start, end, referenceStr) {
if (end - start !== referenceStr.length) return false;
if (start < 0 || end > testStr.length) return false;
for (let i = start; i < end; i++) {
const referenceCode = referenceStr.charCodeAt(i - start);
let testCode = testStr.charCodeAt(i);
if (isUppercaseLetter(testCode)) testCode = testCode | 32;
if (testCode !== referenceCode) return false;
}
return true;
}
function findWhiteSpaceStart(source, offset) {
for (; offset >= 0; offset--) if (!isWhiteSpace(source.charCodeAt(offset))) break;
return offset + 1;
}
function findWhiteSpaceEnd(source, offset) {
for (; offset < source.length; offset++) if (!isWhiteSpace(source.charCodeAt(offset))) break;
return offset;
}
function findDecimalNumberEnd(source, offset) {
for (; offset < source.length; offset++) if (!isDigit(source.charCodeAt(offset))) break;
return offset;
}
function consumeEscaped(source, offset) {
offset += 2;
if (isHexDigit(getCharCode(source, offset - 1))) {
for (const maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) if (!isHexDigit(getCharCode(source, offset))) break;
const code$1 = getCharCode(source, offset);
if (isWhiteSpace(code$1)) offset += getNewlineLength(source, offset, code$1);
}
return offset;
}
function consumeName(source, offset) {
for (; offset < source.length; offset++) {
const code$1 = source.charCodeAt(offset);
if (isName(code$1)) continue;
if (isValidEscape(code$1, getCharCode(source, offset + 1))) {
offset = consumeEscaped(source, offset) - 1;
continue;
}
break;
}
return offset;
}
function consumeNumber(source, offset) {
let code$1 = source.charCodeAt(offset);
if (code$1 === 43 || code$1 === 45) code$1 = source.charCodeAt(offset += 1);
if (isDigit(code$1)) {
offset = findDecimalNumberEnd(source, offset + 1);
code$1 = source.charCodeAt(offset);
}
if (code$1 === 46 && isDigit(source.charCodeAt(offset + 1))) {
offset += 2;
offset = findDecimalNumberEnd(source, offset);
}
if (cmpChar(source, offset, 101)) {
let sign = 0;
code$1 = source.charCodeAt(offset + 1);
if (code$1 === 45 || code$1 === 43) {
sign = 1;
code$1 = source.charCodeAt(offset + 2);
}
if (isDigit(code$1)) offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
}
return offset;
}
function consumeBadUrlRemnants(source, offset) {
for (; offset < source.length; offset++) {
const code$1 = source.charCodeAt(offset);
if (code$1 === 41) {
offset++;
break;
}
if (isValidEscape(code$1, getCharCode(source, offset + 1))) offset = consumeEscaped(source, offset);
}
return offset;
}
function decodeEscaped(escaped) {
if (escaped.length === 1 && !isHexDigit(escaped.charCodeAt(0))) return escaped[0];
let code$1 = parseInt(escaped, 16);
if (code$1 === 0 || code$1 >= 55296 && code$1 <= 57343 || code$1 > 1114111) code$1 = 65533;
return String.fromCodePoint(code$1);
}
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/names.js
var names_default = [
"EOF-token",
"ident-token",
"function-token",
"at-keyword-token",
"hash-token",
"string-token",
"bad-string-token",
"url-token",
"bad-url-token",
"delim-token",
"number-token",
"percentage-token",
"dimension-token",
"whitespace-token",
"CDO-token",
"CDC-token",
"colon-token",
"semicolon-token",
"comma-token",
"[-token",
"]-token",
"(-token",
")-token",
"{-token",
"}-token",
"comment-token"
];
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/adopt-buffer.js
const MIN_SIZE = 16 * 1024;
function adoptBuffer(buffer = null, size) {
if (buffer === null || buffer.length < size) return new Uint32Array(Math.max(size + 1024, MIN_SIZE));
return buffer;
}
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/OffsetToLocation.js
const N$4 = 10;
const F$2 = 12;
const R$2 = 13;
function computeLinesAndColumns(host) {
const source = host.source;
const sourceLength = source.length;
const startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0;
const lines = adoptBuffer(host.lines, sourceLength);
const columns = adoptBuffer(host.columns, sourceLength);
let line = host.startLine;
let column = host.startColumn;
for (let i = startOffset; i < sourceLength; i++) {
const code$1 = source.charCodeAt(i);
lines[i] = line;
columns[i] = column++;
if (code$1 === N$4 || code$1 === R$2 || code$1 === F$2) {
if (code$1 === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$4) {
i++;
lines[i] = line;
columns[i] = column;
}
line++;
column = 1;
}
}
lines[sourceLength] = line;
columns[sourceLength] = column;
host.lines = lines;
host.columns = columns;
host.computed = true;
}
var OffsetToLocation = class {
constructor(source, startOffset, startLine, startColumn) {
this.setSource(source, startOffset, startLine, startColumn);
this.lines = null;
this.columns = null;
}
setSource(source = "", startOffset = 0, startLine = 1, startColumn = 1) {
this.source = source;
this.startOffset = startOffset;
this.startLine = startLine;
this.startColumn = startColumn;
this.computed = false;
}
getLocation(offset, filename) {
if (!this.computed) computeLinesAndColumns(this);
return {
source: filename,
offset: this.startOffset + offset,
line: this.lines[offset],
column: this.columns[offset]
};
}
getLocationRange(start, end, filename) {
if (!this.computed) computeLinesAndColumns(this);
return {
source: filename,
start: {
offset: this.startOffset + start,
line: this.lines[start],
column: this.columns[start]
},
end: {
offset: this.startOffset + end,
line: this.lines[end],
column: this.columns[end]
}
};
}
};
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/TokenStream.js
const OFFSET_MASK = 16777215;
const TYPE_SHIFT = 24;
const balancePair$1 = new Uint8Array(32);
balancePair$1[Function] = RightParenthesis;
balancePair$1[LeftParenthesis] = RightParenthesis;
balancePair$1[LeftSquareBracket] = RightSquareBracket;
balancePair$1[LeftCurlyBracket] = RightCurlyBracket;
function isBlockOpenerToken(tokenType$1) {
return balancePair$1[tokenType$1] !== 0;
}
var TokenStream = class {
constructor(source, tokenize$2) {
this.setSource(source, tokenize$2);
}
reset() {
this.eof = false;
this.tokenIndex = -1;
this.tokenType = 0;
this.tokenStart = this.firstCharOffset;
this.tokenEnd = this.firstCharOffset;
}
setSource(source = "", tokenize$2 = () => {}) {
source = String(source || "");
const sourceLength = source.length;
const offsetAndType = adoptBuffer(this.offsetAndType, source.length + 1);
const balance = adoptBuffer(this.balance, source.length + 1);
let tokenCount = 0;
let firstCharOffset = -1;
let balanceCloseType = 0;
let balanceStart = source.length;
this.offsetAndType = null;
this.balance = null;
balance.fill(0);
tokenize$2(source, (type, start, end) => {
const index = tokenCount++;
offsetAndType[index] = type << TYPE_SHIFT | end;
if (firstCharOffset === -1) firstCharOffset = start;
balance[index] = balanceStart;
if (type === balanceCloseType) {
const prevBalanceStart = balance[balanceStart];
balance[balanceStart] = index;
balanceStart = prevBalanceStart;
balanceCloseType = balancePair$1[offsetAndType[prevBalanceStart] >> TYPE_SHIFT];
} else if (isBlockOpenerToken(type)) {
balanceStart = index;
balanceCloseType = balancePair$1[type];
}
});
offsetAndType[tokenCount] = EOF << TYPE_SHIFT | sourceLength;
balance[tokenCount] = tokenCount;
for (let i = 0; i < tokenCount; i++) {
const balanceStart$1 = balance[i];
if (balanceStart$1 <= i) {
const balanceEnd = balance[balanceStart$1];
if (balanceEnd !== i) balance[i] = balanceEnd;
} else if (balanceStart$1 > tokenCount) balance[i] = tokenCount;
}
this.source = source;
this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset;
this.tokenCount = tokenCount;
this.offsetAndType = offsetAndType;
this.balance = balance;
this.reset();
this.next();
}
lookupType(offset) {
offset += this.tokenIndex;
if (offset < this.tokenCount) return this.offsetAndType[offset] >> TYPE_SHIFT;
return EOF;
}
lookupTypeNonSC(idx) {
for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) {
const tokenType$1 = this.offsetAndType[offset] >> TYPE_SHIFT;
if (tokenType$1 !== WhiteSpace && tokenType$1 !== Comment) {
if (idx-- === 0) return tokenType$1;
}
}
return EOF;
}
lookupOffset(offset) {
offset += this.tokenIndex;
if (offset < this.tokenCount) return this.offsetAndType[offset - 1] & OFFSET_MASK;
return this.source.length;
}
lookupOffsetNonSC(idx) {
for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) {
const tokenType$1 = this.offsetAndType[offset] >> TYPE_SHIFT;
if (tokenType$1 !== WhiteSpace && tokenType$1 !== Comment) {
if (idx-- === 0) return offset - this.tokenIndex;
}
}
return EOF;
}
lookupValue(offset, referenceStr) {
offset += this.tokenIndex;
if (offset < this.tokenCount) return cmpStr(this.source, this.offsetAndType[offset - 1] & OFFSET_MASK, this.offsetAndType[offset] & OFFSET_MASK, referenceStr);
return false;
}
getTokenStart(tokenIndex) {
if (tokenIndex === this.tokenIndex) return this.tokenStart;
if (tokenIndex > 0) return tokenIndex < this.tokenCount ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK : this.offsetAndType[this.tokenCount] & OFFSET_MASK;
return this.firstCharOffset;
}
substrToCursor(start) {
return this.source.substring(start, this.tokenStart);
}
isBalanceEdge(pos) {
return this.balance[this.tokenIndex] < pos;
}
isDelim(code$1, offset) {
if (offset) return this.lookupType(offset) === Delim && this.source.charCodeAt(this.lookupOffset(offset)) === code$1;
return this.tokenType === Delim && this.source.charCodeAt(this.tokenStart) === code$1;
}
skip(tokenCount) {
let next = this.tokenIndex + tokenCount;
if (next < this.tokenCount) {
this.tokenIndex = next;
this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
next = this.offsetAndType[next];
this.tokenType = next >> TYPE_SHIFT;
this.tokenEnd = next & OFFSET_MASK;
} else {
this.tokenIndex = this.tokenCount;
this.next();
}
}
next() {
let next = this.tokenIndex + 1;
if (next < this.tokenCount) {
this.tokenIndex = next;
this.tokenStart = this.tokenEnd;
next = this.offsetAndType[next];
this.tokenType = next >> TYPE_SHIFT;
this.tokenEnd = next & OFFSET_MASK;
} else {
this.eof = true;
this.tokenIndex = this.tokenCount;
this.tokenType = EOF;
this.tokenStart = this.tokenEnd = this.source.length;
}
}
skipSC() {
while (this.tokenType === WhiteSpace || this.tokenType === Comment) this.next();
}
skipUntilBalanced(startToken, stopConsume) {
let cursor = startToken;
let balanceEnd = 0;
let offset = 0;
loop: for (; cursor < this.tokenCount; cursor++) {
balanceEnd = this.balance[cursor];
if (balanceEnd < startToken) break loop;
offset = cursor > 0 ? this.offsetAndType[cursor - 1] & OFFSET_MASK : this.firstCharOffset;
switch (stopConsume(this.source.charCodeAt(offset))) {
case 1: break loop;
case 2:
cursor++;
break loop;
default: if (isBlockOpenerToken(this.offsetAndType[cursor] >> TYPE_SHIFT)) cursor = balanceEnd;
}
}
this.skip(cursor - this.tokenIndex);
}
forEachToken(fn) {
for (let i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) {
const start = offset;
const item = this.offsetAndType[i];
const end = item & OFFSET_MASK;
const type = item >> TYPE_SHIFT;
offset = end;
fn(type, start, end, i);
}
}
dump() {
const tokens = new Array(this.tokenCount);
this.forEachToken((type, start, end, index) => {
tokens[index] = {
idx: index,
type: names_default[type],
chunk: this.source.substring(start, end),
balance: this.balance[index]
};
});
return tokens;
}
};
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/tokenizer/index.js
function tokenize$1(source, onToken) {
function getCharCode$1(offset$1) {
return offset$1 < sourceLength ? source.charCodeAt(offset$1) : 0;
}
function consumeNumericToken() {
offset = consumeNumber(source, offset);
if (isIdentifierStart(getCharCode$1(offset), getCharCode$1(offset + 1), getCharCode$1(offset + 2))) {
type = Dimension;
offset = consumeName(source, offset);
return;
}
if (getCharCode$1(offset) === 37) {
type = Percentage;
offset++;
return;
}
type = Number$1;
}
function consumeIdentLikeToken() {
const nameStartOffset = offset;
offset = consumeName(source, offset);
if (cmpStr(source, nameStartOffset, offset, "url") && getCharCode$1(offset) === 40) {
offset = findWhiteSpaceEnd(source, offset + 1);
if (getCharCode$1(offset) === 34 || getCharCode$1(offset) === 39) {
type = Function;
offset = nameStartOffset + 4;
return;
}
consumeUrlToken();
return;
}
if (getCharCode$1(offset) === 40) {
type = Function;
offset++;
return;
}
type = Ident;
}
function consumeStringToken(endingCodePoint) {
if (!endingCodePoint) endingCodePoint = getCharCode$1(offset++);
type = String$1;
for (; offset < source.length; offset++) {
const code$1 = source.charCodeAt(offset);
switch (charCodeCategory(code$1)) {
case endingCodePoint:
offset++;
return;
case WhiteSpaceCategory:
if (isNewline(code$1)) {
offset += getNewlineLength(source, offset, code$1);
type = BadString;
return;
}
break;
case 92:
if (offset === source.length - 1) break;
const nextCode = getCharCode$1(offset + 1);
if (isNewline(nextCode)) offset += getNewlineLength(source, offset + 1, nextCode);
else if (isValidEscape(code$1, nextCode)) offset = consumeEscaped(source, offset) - 1;
break;
}
}
}
function consumeUrlToken() {
type = Url;
offset = findWhiteSpaceEnd(source, offset);
for (; offset < source.length; offset++) {
const code$1 = source.charCodeAt(offset);
switch (charCodeCategory(code$1)) {
case 41:
offset++;
return;
case WhiteSpaceCategory:
offset = findWhiteSpaceEnd(source, offset);
if (getCharCode$1(offset) === 41 || offset >= source.length) {
if (offset < source.length) offset++;
return;
}
offset = consumeBadUrlRemnants(source, offset);
type = BadUrl;
return;
case 34:
case 39:
case 40:
case NonPrintableCategory:
offset = consumeBadUrlRemnants(source, offset);
type = BadUrl;
return;
case 92:
if (isValidEscape(code$1, getCharCode$1(offset + 1))) {
offset = consumeEscaped(source, offset) - 1;
break;
}
offset = consumeBadUrlRemnants(source, offset);
type = BadUrl;
return;
}
}
}
source = String(source || "");
const sourceLength = source.length;
let start = isBOM(getCharCode$1(0));
let offset = start;
let type;
while (offset < sourceLength) {
const code$1 = source.charCodeAt(offset);
switch (charCodeCategory(code$1)) {
case WhiteSpaceCategory:
type = WhiteSpace;
offset = findWhiteSpaceEnd(source, offset + 1);
break;
case 34:
consumeStringToken();
break;
case 35:
if (isName(getCharCode$1(offset + 1)) || isValidEscape(getCharCode$1(offset + 1), getCharCode$1(offset + 2))) {
type = Hash;
offset = consumeName(source, offset + 1);
} else {
type = Delim;
offset++;
}
break;
case 39:
consumeStringToken();
break;
case 40:
type = LeftParenthesis;
offset++;
break;
case 41:
type = RightParenthesis;
offset++;
break;
case 43:
if (isNumberStart(code$1, getCharCode$1(offset + 1), getCharCode$1(offset + 2))) consumeNumericToken();
else {
type = Delim;
offset++;
}
break;
case 44:
type = Comma;
offset++;
break;
case 45:
if (isNumberStart(code$1, getCharCode$1(offset + 1), getCharCode$1(offset + 2))) consumeNumericToken();
else if (getCharCode$1(offset + 1) === 45 && getCharCode$1(offset + 2) === 62) {
type = CDC;
offset = offset + 3;
} else if (isIdentifierStart(code$1, getCharCode$1(offset + 1), getCharCode$1(offset + 2))) consumeIdentLikeToken();
else {
type = Delim;
offset++;
}
break;
case 46:
if (isNumberStart(code$1, getCharCode$1(offset + 1), getCharCode$1(offset + 2))) consumeNumericToken();
else {
type = Delim;
offset++;
}
break;
case 47:
if (getCharCode$1(offset + 1) === 42) {
type = Comment;
offset = source.indexOf("*/", offset + 2);
offset = offset === -1 ? source.length : offset + 2;
} else {
type = Delim;
offset++;
}
break;
case 58:
type = Colon;
offset++;
break;
case 59:
type = Semicolon;
offset++;
break;
case 60:
if (getCharCode$1(offset + 1) === 33 && getCharCode$1(offset + 2) === 45 && getCharCode$1(offset + 3) === 45) {
type = CDO;
offset = offset + 4;
} else {
type = Delim;
offset++;
}
break;
case 64:
if (isIdentifierStart(getCharCode$1(offset + 1), getCharCode$1(offset + 2), getCharCode$1(offset + 3))) {
type = AtKeyword;
offset = consumeName(source, offset + 1);
} else {
type = Delim;
offset++;
}
break;
case 91:
type = LeftSquareBracket;
offset++;
break;
case 92:
if (isValidEscape(code$1, getCharCode$1(offset + 1))) consumeIdentLikeToken();
else {
type = Delim;
offset++;
}
break;
case 93:
type = RightSquareBracket;
offset++;
break;
case 123:
type = LeftCurlyBracket;
offset++;
break;
case 125:
type = RightCurlyBracket;
offset++;
break;
case DigitCategory:
consumeNumericToken();
break;
case NameStartCategory:
consumeIdentLikeToken();
break;
default:
type = Delim;
offset++;
}
onToken(type, start, start = offset);
}
}
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/utils/List.js
let releasedCursors = null;
var List = class List {
static createItem(data) {
return {
prev: null,
next: null,
data
};
}
constructor() {
this.head = null;
this.tail = null;
this.cursor = null;
}
createItem(data) {
return List.createItem(data);
}
allocateCursor(prev, next) {
let cursor;
if (releasedCursors !== null) {
cursor = releasedCursors;
releasedCursors = releasedCursors.cursor;
cursor.prev = prev;
cursor.next = next;
cursor.cursor = this.cursor;
} else cursor = {
prev,
next,
cursor: this.cursor
};
this.cursor = cursor;
return cursor;
}
releaseCursor() {
const { cursor } = this;
this.cursor = cursor.cursor;
cursor.prev = null;
cursor.next = null;
cursor.cursor = releasedCursors;
releasedCursors = cursor;
}
updateCursors(prevOld, prevNew, nextOld, nextNew) {
let { cursor } = this;
while (cursor !== null) {
if (cursor.prev === prevOld) cursor.prev = prevNew;
if (cursor.next === nextOld) cursor.next = nextNew;
cursor = cursor.cursor;
}
}
*[Symbol.iterator]() {
for (let cursor = this.head; cursor !== null; cursor = cursor.next) yield cursor.data;
}
get size() {
let size = 0;
for (let cursor = this.head; cursor !== null; cursor = cursor.next) size++;
return size;
}
get isEmpty() {
return this.head === null;
}
get first() {
return this.head && this.head.data;
}
get last() {
return this.tail && this.tail.data;
}
fromArray(array) {
let cursor = null;
this.head = null;
for (let data of array) {
const item = List.createItem(data);
if (cursor !== null) cursor.next = item;
else this.head = item;
item.prev = cursor;
cursor = item;
}
this.tail = cursor;
return this;
}
toArray() {
return [...this];
}
toJSON() {
return [...this];
}
forEach(fn, thisArg = this) {
const cursor = this.allocateCursor(null, this.head);
while (cursor.next !== null) {
const item = cursor.next;
cursor.next = item.next;
fn.call(thisArg, item.data, item, this);
}
this.releaseCursor();
}
forEachRight(fn, thisArg = this) {
const cursor = this.allocateCursor(this.tail, null);
while (cursor.prev !== null) {
const item = cursor.prev;
cursor.prev = item.prev;
fn.call(thisArg, item.data, item, this);
}
this.releaseCursor();
}
reduce(fn, initialValue, thisArg = this) {
let cursor = this.allocateCursor(null, this.head);
let acc = initialValue;
let item;
while (cursor.next !== null) {
item = cursor.next;
cursor.next = item.next;
acc = fn.call(thisArg, acc, item.data, item, this);
}
this.releaseCursor();
return acc;
}
reduceRight(fn, initialValue, thisArg = this) {
let cursor = this.allocateCursor(this.tail, null);
let acc = initialValue;
let item;
while (cursor.prev !== null) {
item = cursor.prev;
cursor.prev = item.prev;
acc = fn.call(thisArg, acc, item.data, item, this);
}
this.releaseCursor();
return acc;
}
some(fn, thisArg = this) {
for (let cursor = this.head; cursor !== null; cursor = cursor.next) if (fn.call(thisArg, cursor.data, cursor, this)) return true;
return false;
}
map(fn, thisArg = this) {
const result = new List();
for (let cursor = this.head; cursor !== null; cursor = cursor.next) result.appendData(fn.call(thisArg, cursor.data, cursor, this));
return result;
}
filter(fn, thisArg = this) {
const result = new List();
for (let cursor = this.head; cursor !== null; cursor = cursor.next) if (fn.call(thisArg, cursor.data, cursor, this)) result.appendData(cursor.data);
return result;
}
nextUntil(start, fn, thisArg = this) {
if (start === null) return;
const cursor = this.allocateCursor(null, start);
while (cursor.next !== null) {
const item = cursor.next;
cursor.next = item.next;
if (fn.call(thisArg, item.data, item, this)) break;
}
this.releaseCursor();
}
prevUntil(start, fn, thisArg = this) {
if (start === null) return;
const cursor = this.allocateCursor(start, null);
while (cursor.prev !== null) {
const item = cursor.prev;
cursor.prev = item.prev;
if (fn.call(thisArg, item.data, item, this)) break;
}
this.releaseCursor();
}
clear() {
this.head = null;
this.tail = null;
}
copy() {
const result = new List();
for (let data of this) result.appendData(data);
return result;
}
prepend(item) {
this.updateCursors(null, item, this.head, item);
if (this.head !== null) {
this.head.prev = item;
item.next = this.head;
} else this.tail = item;
this.head = item;
return this;
}
prependData(data) {
return this.prepend(List.createItem(data));
}
append(item) {
return this.insert(item);
}
appendData(data) {
return this.insert(List.createItem(data));
}
insert(item, before = null) {
if (before !== null) {
this.updateCursors(before.prev, item, before, item);
if (before.prev === null) {
if (this.head !== before) throw new Error("before doesn't belong to list");
this.head = item;
before.prev = item;
item.next = before;
this.updateCursors(null, item);
} else {
before.prev.next = item;
item.prev = before.prev;
before.prev = item;
item.next = before;
}
} else {
this.updateCursors(this.tail, item, null, item);
if (this.tail !== null) {
this.tail.next = item;
item.prev = this.tail;
} else this.head = item;
this.tail = item;
}
return this;
}
insertData(data, before) {
return this.insert(List.createItem(data), before);
}
remove(item) {
this.updateCursors(item, item.prev, item, item.next);
if (item.prev !== null) item.prev.next = item.next;
else {
if (this.head !== item) throw new Error("item doesn't belong to list");
this.head = item.next;
}
if (item.next !== null) item.next.prev = item.prev;
else {
if (this.tail !== item) throw new Error("item doesn't belong to list");
this.tail = item.prev;
}
item.prev = null;
item.next = null;
return item;
}
push(data) {
this.insert(List.createItem(data));
}
pop() {
return this.tail !== null ? this.remove(this.tail) : null;
}
unshift(data) {
this.prepend(List.createItem(data));
}
shift() {
return this.head !== null ? this.remove(this.head) : null;
}
prependList(list) {
return this.insertList(list, this.head);
}
appendList(list) {
return this.insertList(list);
}
insertList(list, before) {
if (list.head === null) return this;
if (before !== void 0 && before !== null) {
this.updateCursors(before.prev, list.tail, before, list.head);
if (before.prev !== null) {
before.prev.next = list.head;
list.head.prev = before.prev;
} else this.head = list.head;
before.prev = list.tail;
list.tail.next = before;
} else {
this.updateCursors(this.tail, list.tail, null, list.head);
if (this.tail !== null) {
this.tail.next = list.head;
list.head.prev = this.tail;
} else this.head = list.head;
this.tail = list.tail;
}
list.head = null;
list.tail = null;
return this;
}
replace(oldItem, newItemOrList) {
if ("head" in newItemOrList) this.insertList(newItemOrList, oldItem);
else this.insert(newItemOrList, oldItem);
this.remove(oldItem);
}
};
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/utils/create-custom-error.js
function createCustomError(name$49, message) {
const error = Object.create(SyntaxError.prototype);
const errorStack = /* @__PURE__ */ new Error();
return Object.assign(error, {
name: name$49,
message,
get stack() {
return (errorStack.stack || "").replace(/^(.+\n){1,3}/, `${name$49}: ${message}\n`);
}
});
}
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/parser/SyntaxError.js
const MAX_LINE_LENGTH = 100;
const OFFSET_CORRECTION = 60;
const TAB_REPLACEMENT = " ";
function sourceFragment({ source, line, column, baseLine, baseColumn }, extraLines) {
function processLines(start, end) {
return lines.slice(start, end).map((line$1, idx) => String(start + idx + 1).padStart(maxNumLength) + " |" + line$1).join("\n");
}
const lines = ("\n".repeat(Math.max(baseLine - 1, 0)) + " ".repeat(Math.max(baseColumn - 1, 0)) + source).split(/\r\n?|\n|\f/);
const startLine = Math.max(1, line - extraLines) - 1;
const endLine = Math.min(line + extraLines, lines.length + 1);
const maxNumLength = Math.max(4, String(endLine).length) + 1;
let cutLeft = 0;
column += 3 * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
if (column > MAX_LINE_LENGTH) {
cutLeft = column - OFFSET_CORRECTION + 3;
column = OFFSET_CORRECTION - 2;
}
for (let i = startLine; i <= endLine; i++) if (i >= 0 && i < lines.length) {
lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
lines[i] = (cutLeft > 0 && lines[i].length > cutLeft ? "…" : "") + lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) + (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? "…" : "");
}
return [
processLines(startLine, line),
new Array(column + maxNumLength + 2).join("-") + "^",
processLines(line, endLine)
].filter(Boolean).join("\n").replace(/^(\s+\d+\s+\|\n)+/, "").replace(/\n(\s+\d+\s+\|)+$/, "");
}
function SyntaxError$2(message, source, offset, line, column, baseLine = 1, baseColumn = 1) {
return Object.assign(createCustomError("SyntaxError", message), {
source,
offset,
line,
column,
sourceFragment(extraLines) {
return sourceFragment({
source,
line,
column,
baseLine,
baseColumn
}, isNaN(extraLines) ? 0 : extraLines);
},
get formattedMessage() {
return `Parse error: ${message}\n` + sourceFragment({
source,
line,
column,
baseLine,
baseColumn
}, 2);
}
});
}
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/parser/sequence.js
function readSequence(recognizer) {
const children = this.createList();
let space = false;
const context = { recognizer };
while (!this.eof) {
switch (this.tokenType) {
case Comment:
this.next();
continue;
case WhiteSpace:
space = true;
this.next();
continue;
}
let child = recognizer.getNode.call(this, context);
if (child === void 0) break;
if (space) {
if (recognizer.onWhiteSpace) recognizer.onWhiteSpace.call(this, child, children, context);
space = false;
}
children.push(child);
}
if (space && recognizer.onWhiteSpace) recognizer.onWhiteSpace.call(this, null, children, context);
return children;
}
//#endregion
//#region ../../node_modules/.pnpm/css-tree@3.1.0/node_modules/css-tree/lib/parser/create.js
const NOOP = () => {};
const EXCLAMATIONMARK$3 = 33;
const NUMBERSIGN$4 = 35;
const SEMICOLON = 59;
const LEFTCURLYBRACKET$1 = 123;
const NULL = 0;
function createParseContext(name$49) {
return function() {
return this[name$49]();
};
}
function fetchParseValues(dict) {
const result = Object.create(null);
for (const name$49 of Object.keys(dict)) {
const item = dict[name$49];
const fn = item.parse || item;
if (fn) result[name$49] = fn;
}
return result;
}
function processConfig(config) {
const parseConfig = {
context: Object.create(null),
features: Object.assign(Object.create(null), config.features),
scope: Object.assign(Object.create(null), config.scope),
atrule: fetchParseValues(config.atrule),
pseudo: fetchParseValues(config.pseudo),
node: fetchParseValues(config.node)
};
for (const [name$49, context] of Object.entries(config.parseContext)) switch (typeof context) {
case "function":
parseConfig.context[name$49] = context;
break;
case "string":
parseConfig.context[name$49] = createParseContext(context);
break;
}
return {
config: parseConfig,
...parseConfig,
...parseConfig.node
};
}
function createParser(config) {
let source = "";
let filename = "<unknown>";
let needPositions = false;
let onParseError = NOOP;
let onParseErrorThrow = false;
const locationMap = new OffsetToLocation();
const parser = Object.assign(new TokenStream(), processConfig(config || {}), {
parseAtrulePrelude: true,
parseRulePrelude: true,
parseValue: true,
parseCustomProperty: false,
readSequence,
consumeUntilBalanceEnd: () => 0,
consumeUntilLeftCurlyBracket(code$1) {
return code$1 === LEFTCURLYBRACKET$1 ? 1 : 0;
},
consumeUntilLeftCurlyBracketOrSemicolon(code$1) {
return code$1 === LEFTCURLYBRACKET$1 || code$1 === SEMICOLON ? 1 : 0;
},
consumeUntilExclamationMarkOrSemicolon(code$1) {
return code$1 === EXCLAMATIONMARK$3 || code$1 === SEMICOLON ? 1 : 0;
},
consumeUntilSemicolonIncluded(code$1) {
return code$1 === SEMICOLON ? 2 : 0;
},
createList() {
return new List();
},
createSingleNodeList(node) {
return new List().appendData(node);
},
getFirstListNode(list) {
return list && list.first;
},
getLastListNode(list) {
return list && list.last;
},
parseWithFallback(consumer, fallback) {
const startIndex = this.tokenIndex;
try {
return consumer.call(this);
} catch (e) {
if (onParseErrorThrow) throw e;
this.skip(startIndex - this.tokenIndex);
const fallbackNode = fallback.call(this);
onParseErrorThrow = true;
onParseError(e, fallbackNode);
onParseErrorThrow = false;
return fallbackNode;
}
},
lookupNonWSType(offset) {
let type;
do {
type = this.lookupType(offset++);
if (type !== WhiteSpace && type !== Comment) return type;
} while (type !== NULL);
return NULL;
},
charCodeAt(offset) {
return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0;
},
substring(offsetStart, offsetEnd) {
return source.substring(offsetStart, offsetEnd);
},
substrToCursor(start) {
return this.source.substring(start, this.tokenStart);
},
cmpChar(offset, charCode) {
return cmpChar(source, offset, charCode);
},
cmpStr(offsetStart, offsetEnd, str) {
return cmpStr(source, offsetStart, offsetEnd, str);
},
consume(tokenType$1) {
const start = this.tokenStart;
this.eat(tokenType$1);
return this.substrToCursor(start);
},
consumeFunctionName() {
const name$49 = source.substring(this.tokenStart, this.tokenEnd - 1);
this.eat(Function);
return name$49;
},
consumeNumber(type) {
const number$1 = source.substring(this.tokenStart, consumeNumber(source, this.tokenStart));
this.eat(type);
return number$1;
},
eat(tokenType$1) {
if (this.tokenType !== tokenType$1) {
const tokenName = names_default[tokenType$1].slice(0, -6).replace(/-/g, " ").replace(/^./, (m) => m.toUpperCase());
let message = `${/[[\](){}]/.test(tokenName) ? `"${tokenName}"` : tokenName} is expected`;
let offset = this.tokenStart;
switch (tokenType$1) {
case Ident:
if (this.tokenType === Function || this.tokenType === Url) {
offset = this.tokenEnd - 1;
message = "Identifier is expected but function found";
} else message = "Identifier is expected";
break;
case Hash:
if (this.isDelim(NUMBERSIGN$4)) {
this.next();
offset++;
message = "Name is expected";
}
break;
case Percentage:
if (this.tokenType === Number$1) {
offset = this.tokenEnd;
message = "Percent sign is expected";
}
break;
}
this.error(message, offset);
}
this.next();
},
eatIdent(name$49) {
if (this.tokenType !== Ident || this.lookupValue(0, name$49) === false) this.error(`Identifier "${name$49}" is expected`);
this.next();
},
eatDelim(code$1) {
if (!this.isDelim(code$1)) this.error(`Delim "${String.fromCharCode(code$1)}" is expected`);
this.next();
},
getLocation(start, end) {
if (needPositions) return locationMap.getLocationRange(start, end, filename);
return null;
},
getLocationFromList(list) {
if (needPositions) {
const head = this.getFirstListNode(list);
const tail = this.getLastListNode(list);
return locationMap.getLocationRange(head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart, tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart, filename);
}
return null;
},
error(message, offset) {
const location = typeof offset !== "undefined" && offset < source.length ? locationMap.getLocation(offset) : this.eof ? locationMap.getLocation(findWhiteSpaceStart(source, source.length - 1)) : locationMap.getLocation(this.tokenStart);
throw new SyntaxError$2(message || "Unexpected input", source, location.offset, location.line, location.column, locationMap.startLine, locationMap.startColumn);
}
});
const parse$51 = function(source_, options) {
source = source_;
options = options || {};
parser.setSource(source, tokenize$1);
locationMap.setSource(source, options.offset, options.line, options.column);
filename = options.filename || "<unknown>";
needPositions = Boolean(options.positions);
onParseError = typeof options.onParseError === "function" ? options.onParseError : NOOP;
onParseErrorThrow = false;
parser.parseAtrulePrelude = "parseAtrulePrelude" in options ? Boolean(options.parseAtrulePrelude) : true;
parser.parseRulePrelude = "parseRulePrelude" in options ? Boolean(options.parseRulePrelude) : true;
parser.parseValue = "parseValue" in options ? Boolean(options.parseValue) : true;
parser.parseCustomProperty = "parseCustomProperty" in options ? Boolean(options.parseCustomProperty) : false;
const { context = "default", onComment } = options;
if (context in parser.context === false) throw new Error("Unknown context `" + context + "`");
if (typeof onComment === "function") parser.forEachToken((type, start, end) => {
if (type === Comment) {
const loc = parser.getLocation(start, end);
onComment(cmpStr(source, end - 2, end, "*/") ? source.slice(start + 2, end - 2) : source.slice(start + 2, end), loc);
}
});
const ast = parser.context[context].call(parser, options);
if (!parser.eof) parser.error();
return ast;
};
return Object.assign(parse$51, {
SyntaxError: SyntaxError$2,
config: parser.config
});
}
//#endregion
//#region ../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/lib/base64.js
var require_base64 = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/lib/base64.js": ((exports) => {
var intToCharMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
/**
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
exports.encode = function(number$1) {
if (0 <= number$1 && number$1 < intToCharMap.length) return intToCharMap[number$1];
throw new TypeError("Must be between 0 and 63: " + number$1);
};
/**
* Decode a single base 64 character code digit to an integer. Returns -1 on
* failure.
*/
exports.decode = function(charCode) {
var bigA = 65;
var bigZ = 90;
var littleA = 97;
var littleZ = 122;
var zero$1 = 48;
var nine = 57;
var plus = 43;
var slash = 47;
var littleOffset = 26;
var numberOffset = 52;
if (bigA <= charCode && charCode <= bigZ) return charCode - bigA;
if (littleA <= charCode && charCode <= littleZ) return charCode - littleA + littleOffset;
if (zero$1 <= charCode && charCode <= nine) return charCode - zero$1 + numberOffset;
if (charCode == plus) return 62;
if (charCode == slash) return 63;
return -1;
};
}) });
//#endregion
//#region ../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/lib/base64-vlq.js
var require_base64_vlq = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/lib/base64-vlq.js": ((exports) => {
var base64 = require_base64();
var VLQ_BASE_SHIFT = 5;
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
var VLQ_BASE_MASK = VLQ_BASE - 1;
var VLQ_CONTINUATION_BIT = VLQ_BASE;
/**
* Converts from a two-complement value to a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
*/
function toVLQSigned(aValue) {
return aValue < 0 ? (-aValue << 1) + 1 : (aValue << 1) + 0;
}
/**
* Converts to a two-complement value from a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
*/
function fromVLQSigned(aValue) {
var isNegative = (aValue & 1) === 1;
var shifted = aValue >> 1;
return isNegative ? -shifted : shifted;
}
/**
* Returns the base 64 VLQ encoded value.
*/
exports.encode = function base64VLQ_encode(aValue) {
var encoded = "";
var digit;
var vlq = toVLQSigned(aValue);
do {
digit = vlq & VLQ_BASE_MASK;
vlq >>>= VLQ_BASE_SHIFT;
if (vlq > 0) digit |= VLQ_CONTINUATION_BIT;
encoded += base64.encode(digit);
} while (vlq > 0);
return encoded;
};
/**
* Decodes the next base 64 VLQ value from the given string and returns the
* value and the rest of the string via the out parameter.
*/
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
var strLen = aStr.length;
var result = 0;
var shift = 0;
var continuation, digit;
do {
if (aIndex >= strLen) throw new Error("Expected more digits in base 64 VLQ value.");
digit = base64.decode(aStr.charCodeAt(aIndex++));
if (digit === -1) throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
continuation = !!(digit & VLQ_CONTINUATION_BIT);
digit &= VLQ_BASE_MASK;
result = result + (digit << shift);
shift += VLQ_BASE_SHIFT;
} while (continuation);
aOutParam.value = fromVLQSigned(result);
aOutParam.rest = aIndex;
};
}) });
//#endregion
//#region ../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/lib/util.js
var require_util = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/source-map-js@1.2.1/node_modules/source-map-js/lib/util.js": ((exports) => {
/**
* This is a helper function for getting values from parameter/options
* objects.
*
* @param args The object we are extracting values from
* @param name The name of the property we are getting.
* @param defaultValue An optional value to return if the property is missing
* from the object. If this is not specified and the property is missing, an
* error will be thrown.
*/
function getArg(aArgs, aName, aDefaultValue) {
if (aName in aArgs) return aArgs[aName];
else if (arguments.length === 3) return aDefaultValue;
else throw new Error("\"" + aName + "\" is a required argument.");
}
exports.getArg = getArg;
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
var match = aUrl.match(urlRegexp);
if (!match) return null;
return {
scheme: match[1],
auth: match[2],
host: match[3],
port: match[4],
path: match[5]
};
}
exports.urlParse = urlParse;
function urlGenerate(aParsedUrl) {
var url = "";
if (aParsedUrl.scheme) url += aParsedUrl.scheme + ":";
url += "//";
if (aParsedUrl.auth) url += aParsedUrl.auth + "@";
if (aParsedUrl.host) url += aParsedUrl.host;
if (aParsedUrl.port) url += ":" + aParsedUrl.port;
if (aParsedUrl.path) url += aParsedUrl.path;
return url;
}
exports.urlGenerate = urlGenerate;
var MAX_CACHED_INPUTS = 32;
/**
* Takes some function `f(input) -> result` and returns a memoized version of
* `f`.
*
* We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The
* memoization is a dumb-simple, linear least-recently-used cache.
*/
function lruMemoize(f) {
var cache = [];
return function(input) {
for (var i = 0; i < cache.length; i++) if (cache[i].input === input) {
var temp = cache[0];
cache[0] = cache[i];
cache[i] = temp;
return cache[0].result;
}
var result = f(input);
cache.unshift({
input,
result
});
if (cache.length > MAX_CACHED_INPUTS) cache.pop();
return result;
};
}
/**
* Normalizes a path, or the path portion of a URL:
*
* - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
* Based on code in the Node.js 'path' core module.
*
* @param aPath The path or url to normalize.
*/
var normalize = lruMemoize(function normalize$1(aPath) {
var path = aPath;
var url = urlParse(aPath);
if (url) {
if (!url.path) return aPath;
path = url.path;
}
var isAbsolute = exports.isAbsolute(path);
var parts = [];
var start = 0;
var i = 0;
while (true) {
start = i;
i = path.indexOf("/", start);
if (i === -1) {
parts.push(path.slice(start));
break;
} else {
parts.push(path.slice(start, i));
while (i < path.length && path[i] === "/") i++;
}
}
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
part = parts[i];
if (part === ".") parts.splice(i, 1);
else if (part === "..") up++;
else if (up > 0) if (part === "") {
parts.splice(i + 1, up);
up = 0;
} else {
parts.splice(i, 2);
up--;
}
}
path = parts.join("/");
if (path === "") path = isAbsolute ? "/" : ".";
if (url) {
url.path = path;
return urlGenerate(url);
}
return path;
});
exports.normalize = normalize;
/**
* Joins two paths/URLs.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be joined with the root.
*
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
* first.
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
* is updated with the result and aRoot is returned. Otherwise the result
* is returned.
* - If aPath is absolute, the result is aPath.
* - Otherwise the two paths are joined with a slash.
* - Joining for example 'http://' and 'www.example.com' is also supported.
*/
function join(aRoot, aPath) {
if (aRoot === "") aRoot = ".";
if (aPath === "") aPath = ".";
var aPathUrl = urlParse(aPath)