// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // This is a specialised implementation of a System module loader. "use strict"; // @ts-nocheck /* eslint-disable */ let System, __instantiateAsync, __instantiate; (() => { const r = new Map(); System = { register(id, d, f) { r.set(id, { d, f, exp: {} }); }, }; async function dI(mid, src) { let id = mid.replace(/\.\w+$/i, ""); if (id.includes("./")) { const [o, ...ia] = id.split("/").reverse(), [, ...sa] = src.split("/").reverse(), oa = [o]; let s = 0, i; while ((i = ia.shift())) { if (i === "..") s++; else if (i === ".") break; else oa.push(i); } if (s < sa.length) oa.push(...sa.slice(s)); id = oa.reverse().join("/"); } return r.has(id) ? gExpA(id) : import(mid); } function gC(id, main) { return { id, import: (m) => dI(m, id), meta: { url: id, main }, }; } function gE(exp) { return (id, v) => { v = typeof id === "string" ? { [id]: v } : id; for (const [id, value] of Object.entries(v)) { Object.defineProperty(exp, id, { value, writable: true, enumerable: true, }); } }; } function rF(main) { for (const [id, m] of r.entries()) { const { f, exp } = m; const { execute: e, setters: s } = f(gE(exp), gC(id, id === main)); delete m.f; m.e = e; m.s = s; } } async function gExpA(id) { if (!r.has(id)) return; const m = r.get(id); if (m.s) { const { d, e, s } = m; delete m.s; delete m.e; for (let i = 0; i < s.length; i++) s[i](await gExpA(d[i])); const r = e(); if (r) await r; } return m.exp; } function gExp(id) { if (!r.has(id)) return; const m = r.get(id); if (m.s) { const { d, e, s } = m; delete m.s; delete m.e; for (let i = 0; i < s.length; i++) s[i](gExp(d[i])); e(); } return m.exp; } __instantiateAsync = async (m) => { System = __instantiateAsync = __instantiate = undefined; rF(m); return gExpA(m); }; __instantiate = (m) => { System = __instantiateAsync = __instantiate = undefined; rF(m); return gExp(m); }; })(); System.register( "https://deno.land/std@0.56.0/encoding/utf8", [], function (exports_1, context_1) { "use strict"; var encoder, decoder; var __moduleName = context_1 && context_1.id; /** Shorthand for new TextEncoder().encode() */ function encode(input) { return encoder.encode(input); } exports_1("encode", encode); /** Shorthand for new TextDecoder().decode() */ function decode(input) { return decoder.decode(input); } exports_1("decode", decode); return { setters: [], execute: function () { /** A default TextEncoder instance */ exports_1("encoder", encoder = new TextEncoder()); /** A default TextDecoder instance */ exports_1("decoder", decoder = new TextDecoder()); }, }; }, ); // Copyright the Browserify authors. MIT License. // Ported from https://github.com/browserify/path-browserify/ /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/_constants", [], function (exports_2, context_2) { "use strict"; var CHAR_UPPERCASE_A, CHAR_LOWERCASE_A, CHAR_UPPERCASE_Z, CHAR_LOWERCASE_Z, CHAR_DOT, CHAR_FORWARD_SLASH, CHAR_BACKWARD_SLASH, CHAR_VERTICAL_LINE, CHAR_COLON, CHAR_QUESTION_MARK, CHAR_UNDERSCORE, CHAR_LINE_FEED, CHAR_CARRIAGE_RETURN, CHAR_TAB, CHAR_FORM_FEED, CHAR_EXCLAMATION_MARK, CHAR_HASH, CHAR_SPACE, CHAR_NO_BREAK_SPACE, CHAR_ZERO_WIDTH_NOBREAK_SPACE, CHAR_LEFT_SQUARE_BRACKET, CHAR_RIGHT_SQUARE_BRACKET, CHAR_LEFT_ANGLE_BRACKET, CHAR_RIGHT_ANGLE_BRACKET, CHAR_LEFT_CURLY_BRACKET, CHAR_RIGHT_CURLY_BRACKET, CHAR_HYPHEN_MINUS, CHAR_PLUS, CHAR_DOUBLE_QUOTE, CHAR_SINGLE_QUOTE, CHAR_PERCENT, CHAR_SEMICOLON, CHAR_CIRCUMFLEX_ACCENT, CHAR_GRAVE_ACCENT, CHAR_AT, CHAR_AMPERSAND, CHAR_EQUAL, CHAR_0, CHAR_9, navigator, isWindows; var __moduleName = context_2 && context_2.id; return { setters: [], execute: function () { // Alphabet chars. exports_2("CHAR_UPPERCASE_A", CHAR_UPPERCASE_A = 65); /* A */ exports_2("CHAR_LOWERCASE_A", CHAR_LOWERCASE_A = 97); /* a */ exports_2("CHAR_UPPERCASE_Z", CHAR_UPPERCASE_Z = 90); /* Z */ exports_2("CHAR_LOWERCASE_Z", CHAR_LOWERCASE_Z = 122); /* z */ // Non-alphabetic chars. exports_2("CHAR_DOT", CHAR_DOT = 46); /* . */ exports_2("CHAR_FORWARD_SLASH", CHAR_FORWARD_SLASH = 47); /* / */ exports_2("CHAR_BACKWARD_SLASH", CHAR_BACKWARD_SLASH = 92); /* \ */ exports_2("CHAR_VERTICAL_LINE", CHAR_VERTICAL_LINE = 124); /* | */ exports_2("CHAR_COLON", CHAR_COLON = 58); /* : */ exports_2("CHAR_QUESTION_MARK", CHAR_QUESTION_MARK = 63); /* ? */ exports_2("CHAR_UNDERSCORE", CHAR_UNDERSCORE = 95); /* _ */ exports_2("CHAR_LINE_FEED", CHAR_LINE_FEED = 10); /* \n */ exports_2("CHAR_CARRIAGE_RETURN", CHAR_CARRIAGE_RETURN = 13); /* \r */ exports_2("CHAR_TAB", CHAR_TAB = 9); /* \t */ exports_2("CHAR_FORM_FEED", CHAR_FORM_FEED = 12); /* \f */ exports_2("CHAR_EXCLAMATION_MARK", CHAR_EXCLAMATION_MARK = 33); /* ! */ exports_2("CHAR_HASH", CHAR_HASH = 35); /* # */ exports_2("CHAR_SPACE", CHAR_SPACE = 32); /* */ exports_2( "CHAR_NO_BREAK_SPACE", CHAR_NO_BREAK_SPACE = 160, ); /* \u00A0 */ exports_2( "CHAR_ZERO_WIDTH_NOBREAK_SPACE", CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279, ); /* \uFEFF */ exports_2( "CHAR_LEFT_SQUARE_BRACKET", CHAR_LEFT_SQUARE_BRACKET = 91, ); /* [ */ exports_2( "CHAR_RIGHT_SQUARE_BRACKET", CHAR_RIGHT_SQUARE_BRACKET = 93, ); /* ] */ exports_2( "CHAR_LEFT_ANGLE_BRACKET", CHAR_LEFT_ANGLE_BRACKET = 60, ); /* < */ exports_2( "CHAR_RIGHT_ANGLE_BRACKET", CHAR_RIGHT_ANGLE_BRACKET = 62, ); /* > */ exports_2( "CHAR_LEFT_CURLY_BRACKET", CHAR_LEFT_CURLY_BRACKET = 123, ); /* { */ exports_2( "CHAR_RIGHT_CURLY_BRACKET", CHAR_RIGHT_CURLY_BRACKET = 125, ); /* } */ exports_2("CHAR_HYPHEN_MINUS", CHAR_HYPHEN_MINUS = 45); /* - */ exports_2("CHAR_PLUS", CHAR_PLUS = 43); /* + */ exports_2("CHAR_DOUBLE_QUOTE", CHAR_DOUBLE_QUOTE = 34); /* " */ exports_2("CHAR_SINGLE_QUOTE", CHAR_SINGLE_QUOTE = 39); /* ' */ exports_2("CHAR_PERCENT", CHAR_PERCENT = 37); /* % */ exports_2("CHAR_SEMICOLON", CHAR_SEMICOLON = 59); /* ; */ exports_2( "CHAR_CIRCUMFLEX_ACCENT", CHAR_CIRCUMFLEX_ACCENT = 94, ); /* ^ */ exports_2("CHAR_GRAVE_ACCENT", CHAR_GRAVE_ACCENT = 96); /* ` */ exports_2("CHAR_AT", CHAR_AT = 64); /* @ */ exports_2("CHAR_AMPERSAND", CHAR_AMPERSAND = 38); /* & */ exports_2("CHAR_EQUAL", CHAR_EQUAL = 61); /* = */ // Digits exports_2("CHAR_0", CHAR_0 = 48); /* 0 */ exports_2("CHAR_9", CHAR_9 = 57); /* 9 */ // eslint-disable-next-line @typescript-eslint/no-explicit-any navigator = globalThis.navigator; isWindows = false; exports_2("isWindows", isWindows); if (globalThis.Deno != null) { exports_2("isWindows", isWindows = Deno.build.os == "windows"); } else if (navigator?.appVersion != null) { exports_2( "isWindows", isWindows = navigator.appVersion.includes("Win"), ); } }, }; }, ); /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/_interface", [], function (exports_3, context_3) { "use strict"; var __moduleName = context_3 && context_3.id; return { setters: [], execute: function () { }, }; }, ); // Copyright the Browserify authors. MIT License. // Ported from https://github.com/browserify/path-browserify/ /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/_util", ["https://deno.land/std@0.56.0/path/_constants"], function (exports_4, context_4) { "use strict"; var _constants_ts_1; var __moduleName = context_4 && context_4.id; function assertPath(path) { if (typeof path !== "string") { throw new TypeError( `Path must be a string. Received ${JSON.stringify(path)}`, ); } } exports_4("assertPath", assertPath); function isPosixPathSeparator(code) { return code === _constants_ts_1.CHAR_FORWARD_SLASH; } exports_4("isPosixPathSeparator", isPosixPathSeparator); function isPathSeparator(code) { return isPosixPathSeparator(code) || code === _constants_ts_1.CHAR_BACKWARD_SLASH; } exports_4("isPathSeparator", isPathSeparator); function isWindowsDeviceRoot(code) { return ((code >= _constants_ts_1.CHAR_LOWERCASE_A && code <= _constants_ts_1.CHAR_LOWERCASE_Z) || (code >= _constants_ts_1.CHAR_UPPERCASE_A && code <= _constants_ts_1.CHAR_UPPERCASE_Z)); } exports_4("isWindowsDeviceRoot", isWindowsDeviceRoot); // Resolves . and .. elements in a path with directory names function normalizeString(path, allowAboveRoot, separator, isPathSeparator) { let res = ""; let lastSegmentLength = 0; let lastSlash = -1; let dots = 0; let code; for (let i = 0, len = path.length; i <= len; ++i) { if (i < len) { code = path.charCodeAt(i); } else if (isPathSeparator(code)) { break; } else { code = _constants_ts_1.CHAR_FORWARD_SLASH; } if (isPathSeparator(code)) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { if ( res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== _constants_ts_1.CHAR_DOT || res.charCodeAt(res.length - 2) !== _constants_ts_1.CHAR_DOT ) { if (res.length > 2) { const lastSlashIndex = res.lastIndexOf(separator); if (lastSlashIndex === -1) { res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); } lastSlash = i; dots = 0; continue; } else if (res.length === 2 || res.length === 1) { res = ""; lastSegmentLength = 0; lastSlash = i; dots = 0; continue; } } if (allowAboveRoot) { if (res.length > 0) { res += `${separator}..`; } else { res = ".."; } lastSegmentLength = 2; } } else { if (res.length > 0) { res += separator + path.slice(lastSlash + 1, i); } else { res = path.slice(lastSlash + 1, i); } lastSegmentLength = i - lastSlash - 1; } lastSlash = i; dots = 0; } else if (code === _constants_ts_1.CHAR_DOT && dots !== -1) { ++dots; } else { dots = -1; } } return res; } exports_4("normalizeString", normalizeString); function _format(sep, pathObject) { const dir = pathObject.dir || pathObject.root; const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); if (!dir) { return base; } if (dir === pathObject.root) { return dir + base; } return dir + sep + base; } exports_4("_format", _format); return { setters: [ function (_constants_ts_1_1) { _constants_ts_1 = _constants_ts_1_1; }, ], execute: function () { }, }; }, ); // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /** A module to print ANSI terminal colors. Inspired by chalk, kleur, and colors * on npm. * * ``` * import { bgBlue, red, bold } from "https://deno.land/std/fmt/colors.ts"; * console.log(bgBlue(red(bold("Hello world!")))); * ``` * * This module supports `NO_COLOR` environmental variable disabling any coloring * if `NO_COLOR` is set. * * This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/fmt/colors", [], function (exports_5, context_5) { "use strict"; var noColor, enabled, ANSI_PATTERN; var __moduleName = context_5 && context_5.id; function setColorEnabled(value) { if (noColor) { return; } enabled = value; } exports_5("setColorEnabled", setColorEnabled); function getColorEnabled() { return enabled; } exports_5("getColorEnabled", getColorEnabled); function code(open, close) { return { open: `\x1b[${open.join(";")}m`, close: `\x1b[${close}m`, regexp: new RegExp(`\\x1b\\[${close}m`, "g"), }; } function run(str, code) { return enabled ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str; } function reset(str) { return run(str, code([0], 0)); } exports_5("reset", reset); function bold(str) { return run(str, code([1], 22)); } exports_5("bold", bold); function dim(str) { return run(str, code([2], 22)); } exports_5("dim", dim); function italic(str) { return run(str, code([3], 23)); } exports_5("italic", italic); function underline(str) { return run(str, code([4], 24)); } exports_5("underline", underline); function inverse(str) { return run(str, code([7], 27)); } exports_5("inverse", inverse); function hidden(str) { return run(str, code([8], 28)); } exports_5("hidden", hidden); function strikethrough(str) { return run(str, code([9], 29)); } exports_5("strikethrough", strikethrough); function black(str) { return run(str, code([30], 39)); } exports_5("black", black); function red(str) { return run(str, code([31], 39)); } exports_5("red", red); function green(str) { return run(str, code([32], 39)); } exports_5("green", green); function yellow(str) { return run(str, code([33], 39)); } exports_5("yellow", yellow); function blue(str) { return run(str, code([34], 39)); } exports_5("blue", blue); function magenta(str) { return run(str, code([35], 39)); } exports_5("magenta", magenta); function cyan(str) { return run(str, code([36], 39)); } exports_5("cyan", cyan); function white(str) { return run(str, code([37], 39)); } exports_5("white", white); function gray(str) { return run(str, code([90], 39)); } exports_5("gray", gray); function bgBlack(str) { return run(str, code([40], 49)); } exports_5("bgBlack", bgBlack); function bgRed(str) { return run(str, code([41], 49)); } exports_5("bgRed", bgRed); function bgGreen(str) { return run(str, code([42], 49)); } exports_5("bgGreen", bgGreen); function bgYellow(str) { return run(str, code([43], 49)); } exports_5("bgYellow", bgYellow); function bgBlue(str) { return run(str, code([44], 49)); } exports_5("bgBlue", bgBlue); function bgMagenta(str) { return run(str, code([45], 49)); } exports_5("bgMagenta", bgMagenta); function bgCyan(str) { return run(str, code([46], 49)); } exports_5("bgCyan", bgCyan); function bgWhite(str) { return run(str, code([47], 49)); } exports_5("bgWhite", bgWhite); /* Special Color Sequences */ function clampAndTruncate(n, max = 255, min = 0) { return Math.trunc(Math.max(Math.min(n, max), min)); } /** Set text color using paletted 8bit colors. * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit */ function rgb8(str, color) { return run(str, code([38, 5, clampAndTruncate(color)], 39)); } exports_5("rgb8", rgb8); /** Set background color using paletted 8bit colors. * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit */ function bgRgb8(str, color) { return run(str, code([48, 5, clampAndTruncate(color)], 49)); } exports_5("bgRgb8", bgRgb8); /** Set text color using 24bit rgb. * `color` can be a number in range `0x000000` to `0xffffff` or * an `Rgb`. * * To produce the color magenta: * * rgba24("foo", 0xff00ff); * rgba24("foo", {r: 255, g: 0, b: 255}); */ function rgb24(str, color) { if (typeof color === "number") { return run( str, code( [38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 39, ), ); } return run( str, code([ 38, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b), ], 39), ); } exports_5("rgb24", rgb24); /** Set background color using 24bit rgb. * `color` can be a number in range `0x000000` to `0xffffff` or * an `Rgb`. * * To produce the color magenta: * * bgRgba24("foo", 0xff00ff); * bgRgba24("foo", {r: 255, g: 0, b: 255}); */ function bgRgb24(str, color) { if (typeof color === "number") { return run( str, code( [48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 49, ), ); } return run( str, code([ 48, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b), ], 49), ); } exports_5("bgRgb24", bgRgb24); function stripColor(string) { return string.replace(ANSI_PATTERN, ""); } exports_5("stripColor", stripColor); return { setters: [], execute: function () { noColor = globalThis.Deno?.noColor ?? true; enabled = !noColor; // https://github.com/chalk/ansi-regex/blob/2b56fb0c7a07108e5b54241e8faec160d393aedb/index.js ANSI_PATTERN = new RegExp( [ "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))", ].join("|"), "g", ); }, }; }, ); // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/testing/diff", [], function (exports_6, context_6) { "use strict"; var DiffType, REMOVED, COMMON, ADDED; var __moduleName = context_6 && context_6.id; function createCommon(A, B, reverse) { const common = []; if (A.length === 0 || B.length === 0) { return []; } for (let i = 0; i < Math.min(A.length, B.length); i += 1) { if ( A[reverse ? A.length - i - 1 : i] === B[reverse ? B.length - i - 1 : i] ) { common.push(A[reverse ? A.length - i - 1 : i]); } else { return common; } } return common; } function diff(A, B) { const prefixCommon = createCommon(A, B); const suffixCommon = createCommon( A.slice(prefixCommon.length), B.slice(prefixCommon.length), true, ).reverse(); A = suffixCommon.length ? A.slice(prefixCommon.length, -suffixCommon.length) : A.slice(prefixCommon.length); B = suffixCommon.length ? B.slice(prefixCommon.length, -suffixCommon.length) : B.slice(prefixCommon.length); const swapped = B.length > A.length; [A, B] = swapped ? [B, A] : [A, B]; const M = A.length; const N = B.length; if (!M && !N && !suffixCommon.length && !prefixCommon.length) { return []; } if (!N) { return [ ...prefixCommon.map((c) => ({ type: DiffType.common, value: c })), ...A.map((a) => ({ type: swapped ? DiffType.added : DiffType.removed, value: a, })), ...suffixCommon.map((c) => ({ type: DiffType.common, value: c })), ]; } const offset = N; const delta = M - N; const size = M + N + 1; const fp = new Array(size).fill({ y: -1 }); /** * INFO: * This buffer is used to save memory and improve performance. * The first half is used to save route and last half is used to save diff * type. * This is because, when I kept new uint8array area to save type,performance * worsened. */ const routes = new Uint32Array((M * N + size + 1) * 2); const diffTypesPtrOffset = routes.length / 2; let ptr = 0; let p = -1; function backTrace(A, B, current, swapped) { const M = A.length; const N = B.length; const result = []; let a = M - 1; let b = N - 1; let j = routes[current.id]; let type = routes[current.id + diffTypesPtrOffset]; while (true) { if (!j && !type) { break; } const prev = j; if (type === REMOVED) { result.unshift({ type: swapped ? DiffType.removed : DiffType.added, value: B[b], }); b -= 1; } else if (type === ADDED) { result.unshift({ type: swapped ? DiffType.added : DiffType.removed, value: A[a], }); a -= 1; } else { result.unshift({ type: DiffType.common, value: A[a] }); a -= 1; b -= 1; } j = routes[prev]; type = routes[prev + diffTypesPtrOffset]; } return result; } function createFP(slide, down, k, M) { if (slide && slide.y === -1 && down && down.y === -1) { return { y: 0, id: 0 }; } if ( (down && down.y === -1) || k === M || (slide && slide.y) > (down && down.y) + 1 ) { const prev = slide.id; ptr++; routes[ptr] = prev; routes[ptr + diffTypesPtrOffset] = ADDED; return { y: slide.y, id: ptr }; } else { const prev = down.id; ptr++; routes[ptr] = prev; routes[ptr + diffTypesPtrOffset] = REMOVED; return { y: down.y + 1, id: ptr }; } } function snake(k, slide, down, _offset, A, B) { const M = A.length; const N = B.length; if (k < -N || M < k) { return { y: -1, id: -1 }; } const fp = createFP(slide, down, k, M); while (fp.y + k < M && fp.y < N && A[fp.y + k] === B[fp.y]) { const prev = fp.id; ptr++; fp.id = ptr; fp.y += 1; routes[ptr] = prev; routes[ptr + diffTypesPtrOffset] = COMMON; } return fp; } while (fp[delta + offset].y < N) { p = p + 1; for (let k = -p; k < delta; ++k) { fp[k + offset] = snake( k, fp[k - 1 + offset], fp[k + 1 + offset], offset, A, B, ); } for (let k = delta + p; k > delta; --k) { fp[k + offset] = snake( k, fp[k - 1 + offset], fp[k + 1 + offset], offset, A, B, ); } fp[delta + offset] = snake( delta, fp[delta - 1 + offset], fp[delta + 1 + offset], offset, A, B, ); } return [ ...prefixCommon.map((c) => ({ type: DiffType.common, value: c })), ...backTrace(A, B, fp[delta + offset], swapped), ...suffixCommon.map((c) => ({ type: DiffType.common, value: c })), ]; } exports_6("default", diff); return { setters: [], execute: function () { (function (DiffType) { DiffType["removed"] = "removed"; DiffType["common"] = "common"; DiffType["added"] = "added"; })(DiffType || (DiffType = {})); exports_6("DiffType", DiffType); REMOVED = 1; COMMON = 2; ADDED = 3; }, }; }, ); // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /** This module is browser compatible. Do not rely on good formatting of values * for AssertionError messages in browsers. */ System.register( "https://deno.land/std@0.56.0/testing/asserts", [ "https://deno.land/std@0.56.0/fmt/colors", "https://deno.land/std@0.56.0/testing/diff", ], function (exports_7, context_7) { "use strict"; var colors_ts_1, diff_ts_1, CAN_NOT_DISPLAY, AssertionError; var __moduleName = context_7 && context_7.id; function format(v) { let string = globalThis.Deno ? Deno.inspect(v) : String(v); if (typeof v == "string") { string = `"${string.replace(/(?=["\\])/g, "\\")}"`; } return string; } function createColor(diffType) { switch (diffType) { case diff_ts_1.DiffType.added: return (s) => colors_ts_1.green(colors_ts_1.bold(s)); case diff_ts_1.DiffType.removed: return (s) => colors_ts_1.red(colors_ts_1.bold(s)); default: return colors_ts_1.white; } } function createSign(diffType) { switch (diffType) { case diff_ts_1.DiffType.added: return "+ "; case diff_ts_1.DiffType.removed: return "- "; default: return " "; } } function buildMessage(diffResult) { const messages = []; messages.push(""); messages.push(""); messages.push( ` ${colors_ts_1.gray(colors_ts_1.bold("[Diff]"))} ${ colors_ts_1.red(colors_ts_1.bold("Actual")) } / ${colors_ts_1.green(colors_ts_1.bold("Expected"))}`, ); messages.push(""); messages.push(""); diffResult.forEach((result) => { const c = createColor(result.type); messages.push(c(`${createSign(result.type)}${result.value}`)); }); messages.push(""); return messages; } function isKeyedCollection(x) { return [Symbol.iterator, "size"].every((k) => k in x); } function equal(c, d) { const seen = new Map(); return (function compare(a, b) { // Have to render RegExp & Date for string comparison // unless it's mistreated as object if ( a && b && ((a instanceof RegExp && b instanceof RegExp) || (a instanceof Date && b instanceof Date)) ) { return String(a) === String(b); } if (Object.is(a, b)) { return true; } if (a && typeof a === "object" && b && typeof b === "object") { if (seen.get(a) === b) { return true; } if (Object.keys(a || {}).length !== Object.keys(b || {}).length) { return false; } if (isKeyedCollection(a) && isKeyedCollection(b)) { if (a.size !== b.size) { return false; } let unmatchedEntries = a.size; for (const [aKey, aValue] of a.entries()) { for (const [bKey, bValue] of b.entries()) { /* Given that Map keys can be references, we need * to ensure that they are also deeply equal */ if ( (aKey === aValue && bKey === bValue && compare(aKey, bKey)) || (compare(aKey, bKey) && compare(aValue, bValue)) ) { unmatchedEntries--; } } } return unmatchedEntries === 0; } const merged = { ...a, ...b }; for (const key in merged) { if (!compare(a && a[key], b && b[key])) { return false; } } seen.set(a, b); return true; } return false; })(c, d); } exports_7("equal", equal); /** Make an assertion, if not `true`, then throw. */ function assert(expr, msg = "") { if (!expr) { throw new AssertionError(msg); } } exports_7("assert", assert); /** * Make an assertion that `actual` and `expected` are equal, deeply. If not * deeply equal, then throw. */ function assertEquals(actual, expected, msg) { if (equal(actual, expected)) { return; } let message = ""; const actualString = format(actual); const expectedString = format(expected); try { const diffResult = diff_ts_1.default( actualString.split("\n"), expectedString.split("\n"), ); const diffMsg = buildMessage(diffResult).join("\n"); message = `Values are not equal:\n${diffMsg}`; } catch (e) { message = `\n${colors_ts_1.red(CAN_NOT_DISPLAY)} + \n\n`; } if (msg) { message = msg; } throw new AssertionError(message); } exports_7("assertEquals", assertEquals); /** * Make an assertion that `actual` and `expected` are not equal, deeply. * If not then throw. */ function assertNotEquals(actual, expected, msg) { if (!equal(actual, expected)) { return; } let actualString; let expectedString; try { actualString = String(actual); } catch (e) { actualString = "[Cannot display]"; } try { expectedString = String(expected); } catch (e) { expectedString = "[Cannot display]"; } if (!msg) { msg = `actual: ${actualString} expected: ${expectedString}`; } throw new AssertionError(msg); } exports_7("assertNotEquals", assertNotEquals); /** * Make an assertion that `actual` and `expected` are strictly equal. If * not then throw. */ function assertStrictEq(actual, expected, msg) { if (actual === expected) { return; } let message; if (msg) { message = msg; } else { const actualString = format(actual); const expectedString = format(expected); if (actualString === expectedString) { const withOffset = actualString .split("\n") .map((l) => ` ${l}`) .join("\n"); message = `Values have the same structure but are not reference-equal:\n\n${ colors_ts_1.red(withOffset) }\n`; } else { try { const diffResult = diff_ts_1.default( actualString.split("\n"), expectedString.split("\n"), ); const diffMsg = buildMessage(diffResult).join("\n"); message = `Values are not strictly equal:\n${diffMsg}`; } catch (e) { message = `\n${colors_ts_1.red(CAN_NOT_DISPLAY)} + \n\n`; } } } throw new AssertionError(message); } exports_7("assertStrictEq", assertStrictEq); /** * Make an assertion that actual contains expected. If not * then thrown. */ function assertStrContains(actual, expected, msg) { if (!actual.includes(expected)) { if (!msg) { msg = `actual: "${actual}" expected to contain: "${expected}"`; } throw new AssertionError(msg); } } exports_7("assertStrContains", assertStrContains); /** * Make an assertion that `actual` contains the `expected` values * If not then thrown. */ function assertArrayContains(actual, expected, msg) { const missing = []; for (let i = 0; i < expected.length; i++) { let found = false; for (let j = 0; j < actual.length; j++) { if (equal(expected[i], actual[j])) { found = true; break; } } if (!found) { missing.push(expected[i]); } } if (missing.length === 0) { return; } if (!msg) { msg = `actual: "${format(actual)}" expected to contain: "${ format(expected) }"\nmissing: ${format(missing)}`; } throw new AssertionError(msg); } exports_7("assertArrayContains", assertArrayContains); /** * Make an assertion that `actual` match RegExp `expected`. If not * then thrown */ function assertMatch(actual, expected, msg) { if (!expected.test(actual)) { if (!msg) { msg = `actual: "${actual}" expected to match: "${expected}"`; } throw new AssertionError(msg); } } exports_7("assertMatch", assertMatch); /** * Forcefully throws a failed assertion */ function fail(msg) { // eslint-disable-next-line @typescript-eslint/no-use-before-define assert(false, `Failed assertion${msg ? `: ${msg}` : "."}`); } exports_7("fail", fail); /** Executes a function, expecting it to throw. If it does not, then it * throws. An error class and a string that should be included in the * error message can also be asserted. */ function assertThrows(fn, ErrorClass, msgIncludes = "", msg) { let doesThrow = false; let error = null; try { fn(); } catch (e) { if ( ErrorClass && !(Object.getPrototypeOf(e) === ErrorClass.prototype) ) { msg = `Expected error to be instance of "${ErrorClass.name}", but was "${e.constructor.name}"${ msg ? `: ${msg}` : "." }`; throw new AssertionError(msg); } if ( msgIncludes && !colors_ts_1.stripColor(e.message).includes( colors_ts_1.stripColor(msgIncludes), ) ) { msg = `Expected error message to include "${msgIncludes}", but got "${e.message}"${ msg ? `: ${msg}` : "." }`; throw new AssertionError(msg); } doesThrow = true; error = e; } if (!doesThrow) { msg = `Expected function to throw${msg ? `: ${msg}` : "."}`; throw new AssertionError(msg); } return error; } exports_7("assertThrows", assertThrows); async function assertThrowsAsync(fn, ErrorClass, msgIncludes = "", msg) { let doesThrow = false; let error = null; try { await fn(); } catch (e) { if ( ErrorClass && !(Object.getPrototypeOf(e) === ErrorClass.prototype) ) { msg = `Expected error to be instance of "${ErrorClass.name}", but got "${e.name}"${ msg ? `: ${msg}` : "." }`; throw new AssertionError(msg); } if ( msgIncludes && !colors_ts_1.stripColor(e.message).includes( colors_ts_1.stripColor(msgIncludes), ) ) { msg = `Expected error message to include "${msgIncludes}", but got "${e.message}"${ msg ? `: ${msg}` : "." }`; throw new AssertionError(msg); } doesThrow = true; error = e; } if (!doesThrow) { msg = `Expected function to throw${msg ? `: ${msg}` : "."}`; throw new AssertionError(msg); } return error; } exports_7("assertThrowsAsync", assertThrowsAsync); /** Use this to stub out methods that will throw when invoked. */ function unimplemented(msg) { throw new AssertionError(msg || "unimplemented"); } exports_7("unimplemented", unimplemented); /** Use this to assert unreachable code. */ function unreachable() { throw new AssertionError("unreachable"); } exports_7("unreachable", unreachable); return { setters: [ function (colors_ts_1_1) { colors_ts_1 = colors_ts_1_1; }, function (diff_ts_1_1) { diff_ts_1 = diff_ts_1_1; }, ], execute: function () { CAN_NOT_DISPLAY = "[Cannot display]"; AssertionError = class AssertionError extends Error { constructor(message) { super(message); this.name = "AssertionError"; } }; exports_7("AssertionError", AssertionError); }, }; }, ); // Copyright the Browserify authors. MIT License. // Ported from https://github.com/browserify/path-browserify/ /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/win32", [ "https://deno.land/std@0.56.0/path/_constants", "https://deno.land/std@0.56.0/path/_util", "https://deno.land/std@0.56.0/testing/asserts", ], function (exports_8, context_8) { "use strict"; var _constants_ts_2, _util_ts_1, asserts_ts_1, sep, delimiter; var __moduleName = context_8 && context_8.id; function resolve(...pathSegments) { let resolvedDevice = ""; let resolvedTail = ""; let resolvedAbsolute = false; for (let i = pathSegments.length - 1; i >= -1; i--) { let path; if (i >= 0) { path = pathSegments[i]; } else if (!resolvedDevice) { if (globalThis.Deno == null) { throw new TypeError( "Resolved a drive-letter-less path without a CWD.", ); } path = Deno.cwd(); } else { if (globalThis.Deno == null) { throw new TypeError("Resolved a relative path without a CWD."); } // Windows has the concept of drive-specific current working // directories. If we've resolved a drive letter but not yet an // absolute path, get cwd for that drive, or the process cwd if // the drive cwd is not available. We're sure the device is not // a UNC path at this points, because UNC paths are always absolute. path = Deno.env.get(`=${resolvedDevice}`) || Deno.cwd(); // Verify that a cwd was found and that it actually points // to our drive. If not, default to the drive's root. if ( path === undefined || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\` ) { path = `${resolvedDevice}\\`; } } _util_ts_1.assertPath(path); const len = path.length; // Skip empty entries if (len === 0) { continue; } let rootEnd = 0; let device = ""; let isAbsolute = false; const code = path.charCodeAt(0); // Try to match a root if (len > 1) { if (_util_ts_1.isPathSeparator(code)) { // Possible UNC root // If we started with a separator, we know we at least have an // absolute path of some kind (UNC or otherwise) isAbsolute = true; if (_util_ts_1.isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning let j = 2; let last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { const firstPart = path.slice(last, j); // Matched! last = j; // Match 1 or more path separators for (; j < len; ++j) { if (!_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { // Matched! last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j === len) { // We matched a UNC root only device = `\\\\${firstPart}\\${path.slice(last)}`; rootEnd = j; } else if (j !== last) { // We matched a UNC root with leftovers device = `\\\\${firstPart}\\${path.slice(last, j)}`; rootEnd = j; } } } } else { rootEnd = 1; } } else if (_util_ts_1.isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === _constants_ts_2.CHAR_COLON) { device = path.slice(0, 2); rootEnd = 2; if (len > 2) { if (_util_ts_1.isPathSeparator(path.charCodeAt(2))) { // Treat separator following drive name as an absolute path // indicator isAbsolute = true; rootEnd = 3; } } } } } else if (_util_ts_1.isPathSeparator(code)) { // `path` contains just a path separator rootEnd = 1; isAbsolute = true; } if ( device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase() ) { // This path points to another device so it is not applicable continue; } if (resolvedDevice.length === 0 && device.length > 0) { resolvedDevice = device; } if (!resolvedAbsolute) { resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`; resolvedAbsolute = isAbsolute; } if (resolvedAbsolute && resolvedDevice.length > 0) { break; } } // At this point the path should be resolved to a full absolute path, // but handle relative paths to be safe (might happen when process.cwd() // fails) // Normalize the tail path resolvedTail = _util_ts_1.normalizeString( resolvedTail, !resolvedAbsolute, "\\", _util_ts_1.isPathSeparator, ); return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || "."; } exports_8("resolve", resolve); function normalize(path) { _util_ts_1.assertPath(path); const len = path.length; if (len === 0) { return "."; } let rootEnd = 0; let device; let isAbsolute = false; const code = path.charCodeAt(0); // Try to match a root if (len > 1) { if (_util_ts_1.isPathSeparator(code)) { // Possible UNC root // If we started with a separator, we know we at least have an absolute // path of some kind (UNC or otherwise) isAbsolute = true; if (_util_ts_1.isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning let j = 2; let last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { const firstPart = path.slice(last, j); // Matched! last = j; // Match 1 or more path separators for (; j < len; ++j) { if (!_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { // Matched! last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j === len) { // We matched a UNC root only // Return the normalized version of the UNC root since there // is nothing left to process return `\\\\${firstPart}\\${path.slice(last)}\\`; } else if (j !== last) { // We matched a UNC root with leftovers device = `\\\\${firstPart}\\${path.slice(last, j)}`; rootEnd = j; } } } } else { rootEnd = 1; } } else if (_util_ts_1.isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === _constants_ts_2.CHAR_COLON) { device = path.slice(0, 2); rootEnd = 2; if (len > 2) { if (_util_ts_1.isPathSeparator(path.charCodeAt(2))) { // Treat separator following drive name as an absolute path // indicator isAbsolute = true; rootEnd = 3; } } } } } else if (_util_ts_1.isPathSeparator(code)) { // `path` contains just a path separator, exit early to avoid unnecessary // work return "\\"; } let tail; if (rootEnd < len) { tail = _util_ts_1.normalizeString( path.slice(rootEnd), !isAbsolute, "\\", _util_ts_1.isPathSeparator, ); } else { tail = ""; } if (tail.length === 0 && !isAbsolute) { tail = "."; } if ( tail.length > 0 && _util_ts_1.isPathSeparator(path.charCodeAt(len - 1)) ) { tail += "\\"; } if (device === undefined) { if (isAbsolute) { if (tail.length > 0) { return `\\${tail}`; } else { return "\\"; } } else if (tail.length > 0) { return tail; } else { return ""; } } else if (isAbsolute) { if (tail.length > 0) { return `${device}\\${tail}`; } else { return `${device}\\`; } } else if (tail.length > 0) { return device + tail; } else { return device; } } exports_8("normalize", normalize); function isAbsolute(path) { _util_ts_1.assertPath(path); const len = path.length; if (len === 0) { return false; } const code = path.charCodeAt(0); if (_util_ts_1.isPathSeparator(code)) { return true; } else if (_util_ts_1.isWindowsDeviceRoot(code)) { // Possible device root if (len > 2 && path.charCodeAt(1) === _constants_ts_2.CHAR_COLON) { if (_util_ts_1.isPathSeparator(path.charCodeAt(2))) { return true; } } } return false; } exports_8("isAbsolute", isAbsolute); function join(...paths) { const pathsCount = paths.length; if (pathsCount === 0) { return "."; } let joined; let firstPart = null; for (let i = 0; i < pathsCount; ++i) { const path = paths[i]; _util_ts_1.assertPath(path); if (path.length > 0) { if (joined === undefined) { joined = firstPart = path; } else { joined += `\\${path}`; } } } if (joined === undefined) { return "."; } // Make sure that the joined path doesn't start with two slashes, because // normalize() will mistake it for an UNC path then. // // This step is skipped when it is very clear that the user actually // intended to point at an UNC path. This is assumed when the first // non-empty string arguments starts with exactly two slashes followed by // at least one more non-slash character. // // Note that for normalize() to treat a path as an UNC path it needs to // have at least 2 components, so we don't filter for that here. // This means that the user can use join to construct UNC paths from // a server name and a share name; for example: // path.join('//server', 'share') -> '\\\\server\\share\\') let needsReplace = true; let slashCount = 0; asserts_ts_1.assert(firstPart != null); if (_util_ts_1.isPathSeparator(firstPart.charCodeAt(0))) { ++slashCount; const firstLen = firstPart.length; if (firstLen > 1) { if (_util_ts_1.isPathSeparator(firstPart.charCodeAt(1))) { ++slashCount; if (firstLen > 2) { if (_util_ts_1.isPathSeparator(firstPart.charCodeAt(2))) { ++slashCount; } else { // We matched a UNC path in the first part needsReplace = false; } } } } } if (needsReplace) { // Find any more consecutive slashes we need to replace for (; slashCount < joined.length; ++slashCount) { if (!_util_ts_1.isPathSeparator(joined.charCodeAt(slashCount))) { break; } } // Replace the slashes if needed if (slashCount >= 2) { joined = `\\${joined.slice(slashCount)}`; } } return normalize(joined); } exports_8("join", join); // It will solve the relative path from `from` to `to`, for instance: // from = 'C:\\orandea\\test\\aaa' // to = 'C:\\orandea\\impl\\bbb' // The output of the function should be: '..\\..\\impl\\bbb' function relative(from, to) { _util_ts_1.assertPath(from); _util_ts_1.assertPath(to); if (from === to) { return ""; } const fromOrig = resolve(from); const toOrig = resolve(to); if (fromOrig === toOrig) { return ""; } from = fromOrig.toLowerCase(); to = toOrig.toLowerCase(); if (from === to) { return ""; } // Trim any leading backslashes let fromStart = 0; let fromEnd = from.length; for (; fromStart < fromEnd; ++fromStart) { if ( from.charCodeAt(fromStart) !== _constants_ts_2.CHAR_BACKWARD_SLASH ) { break; } } // Trim trailing backslashes (applicable to UNC paths only) for (; fromEnd - 1 > fromStart; --fromEnd) { if ( from.charCodeAt(fromEnd - 1) !== _constants_ts_2.CHAR_BACKWARD_SLASH ) { break; } } const fromLen = fromEnd - fromStart; // Trim any leading backslashes let toStart = 0; let toEnd = to.length; for (; toStart < toEnd; ++toStart) { if (to.charCodeAt(toStart) !== _constants_ts_2.CHAR_BACKWARD_SLASH) { break; } } // Trim trailing backslashes (applicable to UNC paths only) for (; toEnd - 1 > toStart; --toEnd) { if (to.charCodeAt(toEnd - 1) !== _constants_ts_2.CHAR_BACKWARD_SLASH) { break; } } const toLen = toEnd - toStart; // Compare paths to find the longest common path from root const length = fromLen < toLen ? fromLen : toLen; let lastCommonSep = -1; let i = 0; for (; i <= length; ++i) { if (i === length) { if (toLen > length) { if ( to.charCodeAt(toStart + i) === _constants_ts_2.CHAR_BACKWARD_SLASH ) { // We get here if `from` is the exact base path for `to`. // For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz' return toOrig.slice(toStart + i + 1); } else if (i === 2) { // We get here if `from` is the device root. // For example: from='C:\\'; to='C:\\foo' return toOrig.slice(toStart + i); } } if (fromLen > length) { if ( from.charCodeAt(fromStart + i) === _constants_ts_2.CHAR_BACKWARD_SLASH ) { // We get here if `to` is the exact base path for `from`. // For example: from='C:\\foo\\bar'; to='C:\\foo' lastCommonSep = i; } else if (i === 2) { // We get here if `to` is the device root. // For example: from='C:\\foo\\bar'; to='C:\\' lastCommonSep = 3; } } break; } const fromCode = from.charCodeAt(fromStart + i); const toCode = to.charCodeAt(toStart + i); if (fromCode !== toCode) { break; } else if (fromCode === _constants_ts_2.CHAR_BACKWARD_SLASH) { lastCommonSep = i; } } // We found a mismatch before the first common path separator was seen, so // return the original `to`. if (i !== length && lastCommonSep === -1) { return toOrig; } let out = ""; if (lastCommonSep === -1) { lastCommonSep = 0; } // Generate the relative path based on the path difference between `to` and // `from` for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { if ( i === fromEnd || from.charCodeAt(i) === _constants_ts_2.CHAR_BACKWARD_SLASH ) { if (out.length === 0) { out += ".."; } else { out += "\\.."; } } } // Lastly, append the rest of the destination (`to`) path that comes after // the common path parts if (out.length > 0) { return out + toOrig.slice(toStart + lastCommonSep, toEnd); } else { toStart += lastCommonSep; if ( toOrig.charCodeAt(toStart) === _constants_ts_2.CHAR_BACKWARD_SLASH ) { ++toStart; } return toOrig.slice(toStart, toEnd); } } exports_8("relative", relative); function toNamespacedPath(path) { // Note: this will *probably* throw somewhere. if (typeof path !== "string") { return path; } if (path.length === 0) { return ""; } const resolvedPath = resolve(path); if (resolvedPath.length >= 3) { if ( resolvedPath.charCodeAt(0) === _constants_ts_2.CHAR_BACKWARD_SLASH ) { // Possible UNC root if ( resolvedPath.charCodeAt(1) === _constants_ts_2.CHAR_BACKWARD_SLASH ) { const code = resolvedPath.charCodeAt(2); if ( code !== _constants_ts_2.CHAR_QUESTION_MARK && code !== _constants_ts_2.CHAR_DOT ) { // Matched non-long UNC root, convert the path to a long UNC path return `\\\\?\\UNC\\${resolvedPath.slice(2)}`; } } } else if (_util_ts_1.isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) { // Possible device root if ( resolvedPath.charCodeAt(1) === _constants_ts_2.CHAR_COLON && resolvedPath.charCodeAt(2) === _constants_ts_2.CHAR_BACKWARD_SLASH ) { // Matched device root, convert the path to a long UNC path return `\\\\?\\${resolvedPath}`; } } } return path; } exports_8("toNamespacedPath", toNamespacedPath); function dirname(path) { _util_ts_1.assertPath(path); const len = path.length; if (len === 0) { return "."; } let rootEnd = -1; let end = -1; let matchedSlash = true; let offset = 0; const code = path.charCodeAt(0); // Try to match a root if (len > 1) { if (_util_ts_1.isPathSeparator(code)) { // Possible UNC root rootEnd = offset = 1; if (_util_ts_1.isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning let j = 2; let last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { // Matched! last = j; // Match 1 or more path separators for (; j < len; ++j) { if (!_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { // Matched! last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j === len) { // We matched a UNC root only return path; } if (j !== last) { // We matched a UNC root with leftovers // Offset by 1 to include the separator after the UNC root to // treat it as a "normal root" on top of a (UNC) root rootEnd = offset = j + 1; } } } } } else if (_util_ts_1.isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === _constants_ts_2.CHAR_COLON) { rootEnd = offset = 2; if (len > 2) { if (_util_ts_1.isPathSeparator(path.charCodeAt(2))) { rootEnd = offset = 3; } } } } } else if (_util_ts_1.isPathSeparator(code)) { // `path` contains just a path separator, exit early to avoid // unnecessary work return path; } for (let i = len - 1; i >= offset; --i) { if (_util_ts_1.isPathSeparator(path.charCodeAt(i))) { if (!matchedSlash) { end = i; break; } } else { // We saw the first non-path separator matchedSlash = false; } } if (end === -1) { if (rootEnd === -1) { return "."; } else { end = rootEnd; } } return path.slice(0, end); } exports_8("dirname", dirname); function basename(path, ext = "") { if (ext !== undefined && typeof ext !== "string") { throw new TypeError('"ext" argument must be a string'); } _util_ts_1.assertPath(path); let start = 0; let end = -1; let matchedSlash = true; let i; // Check for a drive letter prefix so as not to mistake the following // path separator as an extra separator at the end of the path that can be // disregarded if (path.length >= 2) { const drive = path.charCodeAt(0); if (_util_ts_1.isWindowsDeviceRoot(drive)) { if (path.charCodeAt(1) === _constants_ts_2.CHAR_COLON) { start = 2; } } } if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { if (ext.length === path.length && ext === path) { return ""; } let extIdx = ext.length - 1; let firstNonSlashEnd = -1; for (i = path.length - 1; i >= start; --i) { const code = path.charCodeAt(i); if (_util_ts_1.isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else { if (firstNonSlashEnd === -1) { // We saw the first non-path separator, remember this index in case // we need it if the extension ends up not matching matchedSlash = false; firstNonSlashEnd = i + 1; } if (extIdx >= 0) { // Try to match the explicit extension if (code === ext.charCodeAt(extIdx)) { if (--extIdx === -1) { // We matched the extension, so mark this as the end of our path // component end = i; } } else { // Extension does not match, so our result is the entire path // component extIdx = -1; end = firstNonSlashEnd; } } } } if (start === end) { end = firstNonSlashEnd; } else if (end === -1) { end = path.length; } return path.slice(start, end); } else { for (i = path.length - 1; i >= start; --i) { if (_util_ts_1.isPathSeparator(path.charCodeAt(i))) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else if (end === -1) { // We saw the first non-path separator, mark this as the end of our // path component matchedSlash = false; end = i + 1; } } if (end === -1) { return ""; } return path.slice(start, end); } } exports_8("basename", basename); function extname(path) { _util_ts_1.assertPath(path); let start = 0; let startDot = -1; let startPart = 0; let end = -1; let matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find let preDotState = 0; // Check for a drive letter prefix so as not to mistake the following // path separator as an extra separator at the end of the path that can be // disregarded if ( path.length >= 2 && path.charCodeAt(1) === _constants_ts_2.CHAR_COLON && _util_ts_1.isWindowsDeviceRoot(path.charCodeAt(0)) ) { start = startPart = 2; } for (let i = path.length - 1; i >= start; --i) { const code = path.charCodeAt(i); if (_util_ts_1.isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === _constants_ts_2.CHAR_DOT) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) { startDot = i; } else if (preDotState !== 1) { preDotState = 1; } } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if ( startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) ) { return ""; } return path.slice(startDot, end); } exports_8("extname", extname); function format(pathObject) { /* eslint-disable max-len */ if (pathObject === null || typeof pathObject !== "object") { throw new TypeError( `The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`, ); } return _util_ts_1._format("\\", pathObject); } exports_8("format", format); function parse(path) { _util_ts_1.assertPath(path); const ret = { root: "", dir: "", base: "", ext: "", name: "" }; const len = path.length; if (len === 0) { return ret; } let rootEnd = 0; let code = path.charCodeAt(0); // Try to match a root if (len > 1) { if (_util_ts_1.isPathSeparator(code)) { // Possible UNC root rootEnd = 1; if (_util_ts_1.isPathSeparator(path.charCodeAt(1))) { // Matched double path separator at beginning let j = 2; let last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { // Matched! last = j; // Match 1 or more path separators for (; j < len; ++j) { if (!_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j < len && j !== last) { // Matched! last = j; // Match 1 or more non-path separators for (; j < len; ++j) { if (_util_ts_1.isPathSeparator(path.charCodeAt(j))) { break; } } if (j === len) { // We matched a UNC root only rootEnd = j; } else if (j !== last) { // We matched a UNC root with leftovers rootEnd = j + 1; } } } } } else if (_util_ts_1.isWindowsDeviceRoot(code)) { // Possible device root if (path.charCodeAt(1) === _constants_ts_2.CHAR_COLON) { rootEnd = 2; if (len > 2) { if (_util_ts_1.isPathSeparator(path.charCodeAt(2))) { if (len === 3) { // `path` contains just a drive root, exit early to avoid // unnecessary work ret.root = ret.dir = path; return ret; } rootEnd = 3; } } else { // `path` contains just a drive root, exit early to avoid // unnecessary work ret.root = ret.dir = path; return ret; } } } } else if (_util_ts_1.isPathSeparator(code)) { // `path` contains just a path separator, exit early to avoid // unnecessary work ret.root = ret.dir = path; return ret; } if (rootEnd > 0) { ret.root = path.slice(0, rootEnd); } let startDot = -1; let startPart = rootEnd; let end = -1; let matchedSlash = true; let i = path.length - 1; // Track the state of characters (if any) we see before our first dot and // after any path separator we find let preDotState = 0; // Get non-dir info for (; i >= rootEnd; --i) { code = path.charCodeAt(i); if (_util_ts_1.isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === _constants_ts_2.CHAR_DOT) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) { startDot = i; } else if (preDotState !== 1) { preDotState = 1; } } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if ( startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) ) { if (end !== -1) { ret.base = ret.name = path.slice(startPart, end); } } else { ret.name = path.slice(startPart, startDot); ret.base = path.slice(startPart, end); ret.ext = path.slice(startDot, end); } // If the directory is the root, use the entire root as the `dir` including // the trailing slash if any (`C:\abc` -> `C:\`). Otherwise, strip out the // trailing slash (`C:\abc\def` -> `C:\abc`). if (startPart > 0 && startPart !== rootEnd) { ret.dir = path.slice(0, startPart - 1); } else { ret.dir = ret.root; } return ret; } exports_8("parse", parse); /** Converts a file URL to a path string. * * fromFileUrl("file:///C:/Users/foo"); // "C:\\Users\\foo" * fromFileUrl("file:///home/foo"); // "\\home\\foo" * * Note that non-file URLs are treated as file URLs and irrelevant components * are ignored. */ function fromFileUrl(url) { return new URL(url).pathname .replace(/^\/*([A-Za-z]:)(\/|$)/, "$1/") .replace(/\//g, "\\"); } exports_8("fromFileUrl", fromFileUrl); return { setters: [ function (_constants_ts_2_1) { _constants_ts_2 = _constants_ts_2_1; }, function (_util_ts_1_1) { _util_ts_1 = _util_ts_1_1; }, function (asserts_ts_1_1) { asserts_ts_1 = asserts_ts_1_1; }, ], execute: function () { exports_8("sep", sep = "\\"); exports_8("delimiter", delimiter = ";"); }, }; }, ); // Copyright the Browserify authors. MIT License. // Ported from https://github.com/browserify/path-browserify/ /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/posix", [ "https://deno.land/std@0.56.0/path/_constants", "https://deno.land/std@0.56.0/path/_util", ], function (exports_9, context_9) { "use strict"; var _constants_ts_3, _util_ts_2, sep, delimiter; var __moduleName = context_9 && context_9.id; // path.resolve([from ...], to) function resolve(...pathSegments) { let resolvedPath = ""; let resolvedAbsolute = false; for (let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--) { let path; if (i >= 0) { path = pathSegments[i]; } else { if (globalThis.Deno == null) { throw new TypeError("Resolved a relative path without a CWD."); } path = Deno.cwd(); } _util_ts_2.assertPath(path); // Skip empty entries if (path.length === 0) { continue; } resolvedPath = `${path}/${resolvedPath}`; resolvedAbsolute = path.charCodeAt(0) === _constants_ts_3.CHAR_FORWARD_SLASH; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = _util_ts_2.normalizeString( resolvedPath, !resolvedAbsolute, "/", _util_ts_2.isPosixPathSeparator, ); if (resolvedAbsolute) { if (resolvedPath.length > 0) { return `/${resolvedPath}`; } else { return "/"; } } else if (resolvedPath.length > 0) { return resolvedPath; } else { return "."; } } exports_9("resolve", resolve); function normalize(path) { _util_ts_2.assertPath(path); if (path.length === 0) { return "."; } const isAbsolute = path.charCodeAt(0) === _constants_ts_3.CHAR_FORWARD_SLASH; const trailingSeparator = path.charCodeAt(path.length - 1) === _constants_ts_3.CHAR_FORWARD_SLASH; // Normalize the path path = _util_ts_2.normalizeString( path, !isAbsolute, "/", _util_ts_2.isPosixPathSeparator, ); if (path.length === 0 && !isAbsolute) { path = "."; } if (path.length > 0 && trailingSeparator) { path += "/"; } if (isAbsolute) { return `/${path}`; } return path; } exports_9("normalize", normalize); function isAbsolute(path) { _util_ts_2.assertPath(path); return path.length > 0 && path.charCodeAt(0) === _constants_ts_3.CHAR_FORWARD_SLASH; } exports_9("isAbsolute", isAbsolute); function join(...paths) { if (paths.length === 0) { return "."; } let joined; for (let i = 0, len = paths.length; i < len; ++i) { const path = paths[i]; _util_ts_2.assertPath(path); if (path.length > 0) { if (!joined) { joined = path; } else { joined += `/${path}`; } } } if (!joined) { return "."; } return normalize(joined); } exports_9("join", join); function relative(from, to) { _util_ts_2.assertPath(from); _util_ts_2.assertPath(to); if (from === to) { return ""; } from = resolve(from); to = resolve(to); if (from === to) { return ""; } // Trim any leading backslashes let fromStart = 1; const fromEnd = from.length; for (; fromStart < fromEnd; ++fromStart) { if (from.charCodeAt(fromStart) !== _constants_ts_3.CHAR_FORWARD_SLASH) { break; } } const fromLen = fromEnd - fromStart; // Trim any leading backslashes let toStart = 1; const toEnd = to.length; for (; toStart < toEnd; ++toStart) { if (to.charCodeAt(toStart) !== _constants_ts_3.CHAR_FORWARD_SLASH) { break; } } const toLen = toEnd - toStart; // Compare paths to find the longest common path from root const length = fromLen < toLen ? fromLen : toLen; let lastCommonSep = -1; let i = 0; for (; i <= length; ++i) { if (i === length) { if (toLen > length) { if ( to.charCodeAt(toStart + i) === _constants_ts_3.CHAR_FORWARD_SLASH ) { // We get here if `from` is the exact base path for `to`. // For example: from='/foo/bar'; to='/foo/bar/baz' return to.slice(toStart + i + 1); } else if (i === 0) { // We get here if `from` is the root // For example: from='/'; to='/foo' return to.slice(toStart + i); } } else if (fromLen > length) { if ( from.charCodeAt(fromStart + i) === _constants_ts_3.CHAR_FORWARD_SLASH ) { // We get here if `to` is the exact base path for `from`. // For example: from='/foo/bar/baz'; to='/foo/bar' lastCommonSep = i; } else if (i === 0) { // We get here if `to` is the root. // For example: from='/foo'; to='/' lastCommonSep = 0; } } break; } const fromCode = from.charCodeAt(fromStart + i); const toCode = to.charCodeAt(toStart + i); if (fromCode !== toCode) { break; } else if (fromCode === _constants_ts_3.CHAR_FORWARD_SLASH) { lastCommonSep = i; } } let out = ""; // Generate the relative path based on the path difference between `to` // and `from` for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { if ( i === fromEnd || from.charCodeAt(i) === _constants_ts_3.CHAR_FORWARD_SLASH ) { if (out.length === 0) { out += ".."; } else { out += "/.."; } } } // Lastly, append the rest of the destination (`to`) path that comes after // the common path parts if (out.length > 0) { return out + to.slice(toStart + lastCommonSep); } else { toStart += lastCommonSep; if (to.charCodeAt(toStart) === _constants_ts_3.CHAR_FORWARD_SLASH) { ++toStart; } return to.slice(toStart); } } exports_9("relative", relative); function toNamespacedPath(path) { // Non-op on posix systems return path; } exports_9("toNamespacedPath", toNamespacedPath); function dirname(path) { _util_ts_2.assertPath(path); if (path.length === 0) { return "."; } const hasRoot = path.charCodeAt(0) === _constants_ts_3.CHAR_FORWARD_SLASH; let end = -1; let matchedSlash = true; for (let i = path.length - 1; i >= 1; --i) { if (path.charCodeAt(i) === _constants_ts_3.CHAR_FORWARD_SLASH) { if (!matchedSlash) { end = i; break; } } else { // We saw the first non-path separator matchedSlash = false; } } if (end === -1) { return hasRoot ? "/" : "."; } if (hasRoot && end === 1) { return "//"; } return path.slice(0, end); } exports_9("dirname", dirname); function basename(path, ext = "") { if (ext !== undefined && typeof ext !== "string") { throw new TypeError('"ext" argument must be a string'); } _util_ts_2.assertPath(path); let start = 0; let end = -1; let matchedSlash = true; let i; if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { if (ext.length === path.length && ext === path) { return ""; } let extIdx = ext.length - 1; let firstNonSlashEnd = -1; for (i = path.length - 1; i >= 0; --i) { const code = path.charCodeAt(i); if (code === _constants_ts_3.CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else { if (firstNonSlashEnd === -1) { // We saw the first non-path separator, remember this index in case // we need it if the extension ends up not matching matchedSlash = false; firstNonSlashEnd = i + 1; } if (extIdx >= 0) { // Try to match the explicit extension if (code === ext.charCodeAt(extIdx)) { if (--extIdx === -1) { // We matched the extension, so mark this as the end of our path // component end = i; } } else { // Extension does not match, so our result is the entire path // component extIdx = -1; end = firstNonSlashEnd; } } } } if (start === end) { end = firstNonSlashEnd; } else if (end === -1) { end = path.length; } return path.slice(start, end); } else { for (i = path.length - 1; i >= 0; --i) { if (path.charCodeAt(i) === _constants_ts_3.CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else if (end === -1) { // We saw the first non-path separator, mark this as the end of our // path component matchedSlash = false; end = i + 1; } } if (end === -1) { return ""; } return path.slice(start, end); } } exports_9("basename", basename); function extname(path) { _util_ts_2.assertPath(path); let startDot = -1; let startPart = 0; let end = -1; let matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find let preDotState = 0; for (let i = path.length - 1; i >= 0; --i) { const code = path.charCodeAt(i); if (code === _constants_ts_3.CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === _constants_ts_3.CHAR_DOT) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) { startDot = i; } else if (preDotState !== 1) { preDotState = 1; } } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if ( startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) ) { return ""; } return path.slice(startDot, end); } exports_9("extname", extname); function format(pathObject) { /* eslint-disable max-len */ if (pathObject === null || typeof pathObject !== "object") { throw new TypeError( `The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`, ); } return _util_ts_2._format("/", pathObject); } exports_9("format", format); function parse(path) { _util_ts_2.assertPath(path); const ret = { root: "", dir: "", base: "", ext: "", name: "" }; if (path.length === 0) { return ret; } const isAbsolute = path.charCodeAt(0) === _constants_ts_3.CHAR_FORWARD_SLASH; let start; if (isAbsolute) { ret.root = "/"; start = 1; } else { start = 0; } let startDot = -1; let startPart = 0; let end = -1; let matchedSlash = true; let i = path.length - 1; // Track the state of characters (if any) we see before our first dot and // after any path separator we find let preDotState = 0; // Get non-dir info for (; i >= start; --i) { const code = path.charCodeAt(i); if (code === _constants_ts_3.CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === _constants_ts_3.CHAR_DOT) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) { startDot = i; } else if (preDotState !== 1) { preDotState = 1; } } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if ( startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) ) { if (end !== -1) { if (startPart === 0 && isAbsolute) { ret.base = ret.name = path.slice(1, end); } else { ret.base = ret.name = path.slice(startPart, end); } } } else { if (startPart === 0 && isAbsolute) { ret.name = path.slice(1, startDot); ret.base = path.slice(1, end); } else { ret.name = path.slice(startPart, startDot); ret.base = path.slice(startPart, end); } ret.ext = path.slice(startDot, end); } if (startPart > 0) { ret.dir = path.slice(0, startPart - 1); } else if (isAbsolute) { ret.dir = "/"; } return ret; } exports_9("parse", parse); /** Converts a file URL to a path string. * * fromFileUrl("file:///home/foo"); // "/home/foo" * * Note that non-file URLs are treated as file URLs and irrelevant components * are ignored. */ function fromFileUrl(url) { return new URL(url).pathname; } exports_9("fromFileUrl", fromFileUrl); return { setters: [ function (_constants_ts_3_1) { _constants_ts_3 = _constants_ts_3_1; }, function (_util_ts_2_1) { _util_ts_2 = _util_ts_2_1; }, ], execute: function () { exports_9("sep", sep = "/"); exports_9("delimiter", delimiter = ":"); }, }; }, ); // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/separator", ["https://deno.land/std@0.56.0/path/_constants"], function (exports_10, context_10) { "use strict"; var _constants_ts_4, SEP, SEP_PATTERN; var __moduleName = context_10 && context_10.id; return { setters: [ function (_constants_ts_4_1) { _constants_ts_4 = _constants_ts_4_1; }, ], execute: function () { exports_10("SEP", SEP = _constants_ts_4.isWindows ? "\\" : "/"); exports_10( "SEP_PATTERN", SEP_PATTERN = _constants_ts_4.isWindows ? /[\\/]+/ : /\/+/, ); }, }; }, ); // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/common", ["https://deno.land/std@0.56.0/path/separator"], function (exports_11, context_11) { "use strict"; var separator_ts_1; var __moduleName = context_11 && context_11.id; /** Determines the common path from a set of paths, using an optional separator, * which defaults to the OS default separator. * * import { common } from "https://deno.land/std/path/mod.ts"; * const p = common([ * "./deno/std/path/mod.ts", * "./deno/std/fs/mod.ts", * ]); * console.log(p); // "./deno/std/" * */ function common(paths, sep = separator_ts_1.SEP) { const [first = "", ...remaining] = paths; if (first === "" || remaining.length === 0) { return first.substring(0, first.lastIndexOf(sep) + 1); } const parts = first.split(sep); let endOfPrefix = parts.length; for (const path of remaining) { const compare = path.split(sep); for (let i = 0; i < endOfPrefix; i++) { if (compare[i] !== parts[i]) { endOfPrefix = i; } } if (endOfPrefix === 0) { return ""; } } const prefix = parts.slice(0, endOfPrefix).join(sep); return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`; } exports_11("common", common); return { setters: [ function (separator_ts_1_1) { separator_ts_1 = separator_ts_1_1; }, ], execute: function () { }, }; }, ); // This file is ported from globrex@0.1.2 // MIT License // Copyright (c) 2018 Terkel Gjervig Nielsen /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/_globrex", ["https://deno.land/std@0.56.0/path/_constants"], function (exports_12, context_12) { "use strict"; var _constants_ts_5, SEP, SEP_ESC, SEP_RAW, GLOBSTAR, WILDCARD, GLOBSTAR_SEGMENT, WILDCARD_SEGMENT; var __moduleName = context_12 && context_12.id; /** * Convert any glob pattern to a JavaScript Regexp object * @param glob Glob pattern to convert * @param opts Configuration object * @returns Converted object with string, segments and RegExp object */ function globrex( glob, { extended = false, globstar = false, strict = false, filepath = false, flags = "", } = {}, ) { const sepPattern = new RegExp(`^${SEP}${strict ? "" : "+"}$`); let regex = ""; let segment = ""; let pathRegexStr = ""; const pathSegments = []; // If we are doing extended matching, this boolean is true when we are inside // a group (eg {*.html,*.js}), and false otherwise. let inGroup = false; let inRange = false; // extglob stack. Keep track of scope const ext = []; // Helper function to build string and segments function add(str, options = { split: false, last: false, only: "" }) { const { split, last, only } = options; if (only !== "path") { regex += str; } if (filepath && only !== "regex") { pathRegexStr += str.match(sepPattern) ? SEP : str; if (split) { if (last) { segment += str; } if (segment !== "") { // change it 'includes' if (!flags.includes("g")) { segment = `^${segment}$`; } pathSegments.push(new RegExp(segment, flags)); } segment = ""; } else { segment += str; } } } let c, n; for (let i = 0; i < glob.length; i++) { c = glob[i]; n = glob[i + 1]; if (["\\", "$", "^", ".", "="].includes(c)) { add(`\\${c}`); continue; } if (c.match(sepPattern)) { add(SEP, { split: true }); if (n != null && n.match(sepPattern) && !strict) { regex += "?"; } continue; } if (c === "(") { if (ext.length) { add(`${c}?:`); continue; } add(`\\${c}`); continue; } if (c === ")") { if (ext.length) { add(c); const type = ext.pop(); if (type === "@") { add("{1}"); } else if (type === "!") { add(WILDCARD); } else { add(type); } continue; } add(`\\${c}`); continue; } if (c === "|") { if (ext.length) { add(c); continue; } add(`\\${c}`); continue; } if (c === "+") { if (n === "(" && extended) { ext.push(c); continue; } add(`\\${c}`); continue; } if (c === "@" && extended) { if (n === "(") { ext.push(c); continue; } } if (c === "!") { if (extended) { if (inRange) { add("^"); continue; } if (n === "(") { ext.push(c); add("(?!"); i++; continue; } add(`\\${c}`); continue; } add(`\\${c}`); continue; } if (c === "?") { if (extended) { if (n === "(") { ext.push(c); } else { add("."); } continue; } add(`\\${c}`); continue; } if (c === "[") { if (inRange && n === ":") { i++; // skip [ let value = ""; while (glob[++i] !== ":") { value += glob[i]; } if (value === "alnum") { add("(?:\\w|\\d)"); } else if (value === "space") { add("\\s"); } else if (value === "digit") { add("\\d"); } i++; // skip last ] continue; } if (extended) { inRange = true; add(c); continue; } add(`\\${c}`); continue; } if (c === "]") { if (extended) { inRange = false; add(c); continue; } add(`\\${c}`); continue; } if (c === "{") { if (extended) { inGroup = true; add("(?:"); continue; } add(`\\${c}`); continue; } if (c === "}") { if (extended) { inGroup = false; add(")"); continue; } add(`\\${c}`); continue; } if (c === ",") { if (inGroup) { add("|"); continue; } add(`\\${c}`); continue; } if (c === "*") { if (n === "(" && extended) { ext.push(c); continue; } // Move over all consecutive "*"'s. // Also store the previous and next characters const prevChar = glob[i - 1]; let starCount = 1; while (glob[i + 1] === "*") { starCount++; i++; } const nextChar = glob[i + 1]; if (!globstar) { // globstar is disabled, so treat any number of "*" as one add(".*"); } else { // globstar is enabled, so determine if this is a globstar segment const isGlobstar = starCount > 1 && // multiple "*"'s // from the start of the segment [SEP_RAW, "/", undefined].includes(prevChar) && // to the end of the segment [SEP_RAW, "/", undefined].includes(nextChar); if (isGlobstar) { // it's a globstar, so match zero or more path segments add(GLOBSTAR, { only: "regex" }); add(GLOBSTAR_SEGMENT, { only: "path", last: true, split: true }); i++; // move over the "/" } else { // it's not a globstar, so only match one path segment add(WILDCARD, { only: "regex" }); add(WILDCARD_SEGMENT, { only: "path" }); } } continue; } add(c); } // When regexp 'g' flag is specified don't // constrain the regular expression with ^ & $ if (!flags.includes("g")) { regex = `^${regex}$`; segment = `^${segment}$`; if (filepath) { pathRegexStr = `^${pathRegexStr}$`; } } const result = { regex: new RegExp(regex, flags) }; // Push the last segment if (filepath) { pathSegments.push(new RegExp(segment, flags)); result.path = { regex: new RegExp(pathRegexStr, flags), segments: pathSegments, globstar: new RegExp( !flags.includes("g") ? `^${GLOBSTAR_SEGMENT}$` : GLOBSTAR_SEGMENT, flags, ), }; } return result; } exports_12("globrex", globrex); return { setters: [ function (_constants_ts_5_1) { _constants_ts_5 = _constants_ts_5_1; }, ], execute: function () { SEP = _constants_ts_5.isWindows ? `(?:\\\\|\\/)` : `\\/`; SEP_ESC = _constants_ts_5.isWindows ? `\\\\` : `/`; SEP_RAW = _constants_ts_5.isWindows ? `\\` : `/`; GLOBSTAR = `(?:(?:[^${SEP_ESC}/]*(?:${SEP_ESC}|\/|$))*)`; WILDCARD = `(?:[^${SEP_ESC}/]*)`; GLOBSTAR_SEGMENT = `((?:[^${SEP_ESC}/]*(?:${SEP_ESC}|\/|$))*)`; WILDCARD_SEGMENT = `(?:[^${SEP_ESC}/]*)`; }, }; }, ); // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/glob", [ "https://deno.land/std@0.56.0/path/separator", "https://deno.land/std@0.56.0/path/_globrex", "https://deno.land/std@0.56.0/path/mod", "https://deno.land/std@0.56.0/testing/asserts", ], function (exports_13, context_13) { "use strict"; var separator_ts_2, _globrex_ts_1, mod_ts_1, asserts_ts_2; var __moduleName = context_13 && context_13.id; /** * Generate a regex based on glob pattern and options * This was meant to be using the the `fs.walk` function * but can be used anywhere else. * Examples: * * Looking for all the `ts` files: * walkSync(".", { * match: [globToRegExp("*.ts")] * }) * * Looking for all the `.json` files in any subfolder: * walkSync(".", { * match: [globToRegExp(join("a", "**", "*.json"),{ * flags: "g", * extended: true, * globstar: true * })] * }) * * @param glob - Glob pattern to be used * @param options - Specific options for the glob pattern * @returns A RegExp for the glob pattern */ function globToRegExp(glob, { extended = false, globstar = true } = {}) { const result = _globrex_ts_1.globrex(glob, { extended, globstar, strict: false, filepath: true, }); asserts_ts_2.assert(result.path != null); return result.path.regex; } exports_13("globToRegExp", globToRegExp); /** Test whether the given string is a glob */ function isGlob(str) { const chars = { "{": "}", "(": ")", "[": "]" }; /* eslint-disable-next-line max-len */ const regex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; if (str === "") { return false; } let match; while ((match = regex.exec(str))) { if (match[2]) { return true; } let idx = match.index + match[0].length; // if an open bracket/brace/paren is escaped, // set the index to the next closing character const open = match[1]; const close = open ? chars[open] : null; if (open && close) { const n = str.indexOf(close, idx); if (n !== -1) { idx = n + 1; } } str = str.slice(idx); } return false; } exports_13("isGlob", isGlob); /** Like normalize(), but doesn't collapse "**\/.." when `globstar` is true. */ function normalizeGlob(glob, { globstar = false } = {}) { if (!!glob.match(/\0/g)) { throw new Error(`Glob contains invalid characters: "${glob}"`); } if (!globstar) { return mod_ts_1.normalize(glob); } const s = separator_ts_2.SEP_PATTERN.source; const badParentPattern = new RegExp( `(?<=(${s}|^)\\*\\*${s})\\.\\.(?=${s}|$)`, "g", ); return mod_ts_1.normalize(glob.replace(badParentPattern, "\0")).replace( /\0/g, "..", ); } exports_13("normalizeGlob", normalizeGlob); /** Like join(), but doesn't collapse "**\/.." when `globstar` is true. */ function joinGlobs(globs, { extended = false, globstar = false } = {}) { if (!globstar || globs.length == 0) { return mod_ts_1.join(...globs); } if (globs.length === 0) { return "."; } let joined; for (const glob of globs) { const path = glob; if (path.length > 0) { if (!joined) { joined = path; } else { joined += `${separator_ts_2.SEP}${path}`; } } } if (!joined) { return "."; } return normalizeGlob(joined, { extended, globstar }); } exports_13("joinGlobs", joinGlobs); return { setters: [ function (separator_ts_2_1) { separator_ts_2 = separator_ts_2_1; }, function (_globrex_ts_1_1) { _globrex_ts_1 = _globrex_ts_1_1; }, function (mod_ts_1_1) { mod_ts_1 = mod_ts_1_1; }, function (asserts_ts_2_1) { asserts_ts_2 = asserts_ts_2_1; }, ], execute: function () { }, }; }, ); // Copyright the Browserify authors. MIT License. // Ported mostly from https://github.com/browserify/path-browserify/ /** This module is browser compatible. */ System.register( "https://deno.land/std@0.56.0/path/mod", [ "https://deno.land/std@0.56.0/path/_constants", "https://deno.land/std@0.56.0/path/win32", "https://deno.land/std@0.56.0/path/posix", "https://deno.land/std@0.56.0/path/common", "https://deno.land/std@0.56.0/path/separator", "https://deno.land/std@0.56.0/path/_interface", "https://deno.land/std@0.56.0/path/glob", ], function (exports_14, context_14) { "use strict"; var _constants_ts_6, _win32, _posix, path, win32, posix, basename, delimiter, dirname, extname, format, fromFileUrl, isAbsolute, join, normalize, parse, relative, resolve, sep, toNamespacedPath; var __moduleName = context_14 && context_14.id; var exportedNames_1 = { "win32": true, "posix": true, "basename": true, "delimiter": true, "dirname": true, "extname": true, "format": true, "fromFileUrl": true, "isAbsolute": true, "join": true, "normalize": true, "parse": true, "relative": true, "resolve": true, "sep": true, "toNamespacedPath": true, "SEP": true, "SEP_PATTERN": true, }; function exportStar_1(m) { var exports = {}; for (var n in m) { if (n !== "default" && !exportedNames_1.hasOwnProperty(n)) { exports[n] = m[n]; } } exports_14(exports); } return { setters: [ function (_constants_ts_6_1) { _constants_ts_6 = _constants_ts_6_1; }, function (_win32_1) { _win32 = _win32_1; }, function (_posix_1) { _posix = _posix_1; }, function (common_ts_1_1) { exportStar_1(common_ts_1_1); }, function (separator_ts_3_1) { exports_14({ "SEP": separator_ts_3_1["SEP"], "SEP_PATTERN": separator_ts_3_1["SEP_PATTERN"], }); }, function (_interface_ts_1_1) { exportStar_1(_interface_ts_1_1); }, function (glob_ts_1_1) { exportStar_1(glob_ts_1_1); }, ], execute: function () { path = _constants_ts_6.isWindows ? _win32 : _posix; exports_14("win32", win32 = _win32); exports_14("posix", posix = _posix); exports_14("basename", basename = path.basename), exports_14("delimiter", delimiter = path.delimiter), exports_14("dirname", dirname = path.dirname), exports_14("extname", extname = path.extname), exports_14("format", format = path.format), exports_14("fromFileUrl", fromFileUrl = path.fromFileUrl), exports_14("isAbsolute", isAbsolute = path.isAbsolute), exports_14("join", join = path.join), exports_14("normalize", normalize = path.normalize), exports_14("parse", parse = path.parse), exports_14("relative", relative = path.relative), exports_14("resolve", resolve = path.resolve), exports_14("sep", sep = path.sep), exports_14( "toNamespacedPath", toNamespacedPath = path.toNamespacedPath, ); }, }; }, ); System.register( "https://deno.land/std@0.56.0/io/util", [ "https://deno.land/std@0.56.0/path/mod", "https://deno.land/std@0.56.0/encoding/utf8", ], function (exports_15, context_15) { "use strict"; var Buffer, mkdir, open, path, utf8_ts_1; var __moduleName = context_15 && context_15.id; /** * Copy bytes from one Uint8Array to another. Bytes from `src` which don't fit * into `dst` will not be copied. * * @param src Source byte array * @param dst Destination byte array * @param off Offset into `dst` at which to begin writing values from `src`. * @return number of bytes copied */ function copyBytes(src, dst, off = 0) { off = Math.max(0, Math.min(off, dst.byteLength)); const dstBytesAvailable = dst.byteLength - off; if (src.byteLength > dstBytesAvailable) { src = src.subarray(0, dstBytesAvailable); } dst.set(src, off); return src.byteLength; } exports_15("copyBytes", copyBytes); function charCode(s) { return s.charCodeAt(0); } exports_15("charCode", charCode); function stringsReader(s) { return new Buffer(utf8_ts_1.encode(s).buffer); } exports_15("stringsReader", stringsReader); /** Create or open a temporal file at specified directory with prefix and * postfix * */ async function tempFile(dir, opts = { prefix: "", postfix: "" }) { const r = Math.floor(Math.random() * 1000000); const filepath = path.resolve( `${dir}/${opts.prefix || ""}${r}${opts.postfix || ""}`, ); await mkdir(path.dirname(filepath), { recursive: true }); const file = await open(filepath, { create: true, read: true, write: true, append: true, }); return { file, filepath }; } exports_15("tempFile", tempFile); return { setters: [ function (path_1) { path = path_1; }, function (utf8_ts_1_1) { utf8_ts_1 = utf8_ts_1_1; }, ], execute: function () { // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. Buffer = Deno.Buffer, mkdir = Deno.mkdir, open = Deno.open; }, }; }, ); // Based on https://github.com/golang/go/blob/891682/src/bufio/bufio.go // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. System.register( "https://deno.land/std@0.56.0/io/bufio", [ "https://deno.land/std@0.56.0/io/util", "https://deno.land/std@0.56.0/testing/asserts", ], function (exports_16, context_16) { "use strict"; var util_ts_1, asserts_ts_3, DEFAULT_BUF_SIZE, MIN_BUF_SIZE, MAX_CONSECUTIVE_EMPTY_READS, CR, LF, BufferFullError, PartialReadError, BufReader, AbstractBufBase, BufWriter, BufWriterSync; var __moduleName = context_16 && context_16.id; /** Generate longest proper prefix which is also suffix array. */ function createLPS(pat) { const lps = new Uint8Array(pat.length); lps[0] = 0; let prefixEnd = 0; let i = 1; while (i < lps.length) { if (pat[i] == pat[prefixEnd]) { prefixEnd++; lps[i] = prefixEnd; i++; } else if (prefixEnd === 0) { lps[i] = 0; i++; } else { prefixEnd = pat[prefixEnd - 1]; } } return lps; } /** Read delimited bytes from a Reader. */ async function* readDelim(reader, delim) { // Avoid unicode problems const delimLen = delim.length; const delimLPS = createLPS(delim); let inputBuffer = new Deno.Buffer(); const inspectArr = new Uint8Array(Math.max(1024, delimLen + 1)); // Modified KMP let inspectIndex = 0; let matchIndex = 0; while (true) { const result = await reader.read(inspectArr); if (result === null) { // Yield last chunk. yield inputBuffer.bytes(); return; } if (result < 0) { // Discard all remaining and silently fail. return; } const sliceRead = inspectArr.subarray(0, result); await Deno.writeAll(inputBuffer, sliceRead); let sliceToProcess = inputBuffer.bytes(); while (inspectIndex < sliceToProcess.length) { if (sliceToProcess[inspectIndex] === delim[matchIndex]) { inspectIndex++; matchIndex++; if (matchIndex === delimLen) { // Full match const matchEnd = inspectIndex - delimLen; const readyBytes = sliceToProcess.subarray(0, matchEnd); // Copy const pendingBytes = sliceToProcess.slice(inspectIndex); yield readyBytes; // Reset match, different from KMP. sliceToProcess = pendingBytes; inspectIndex = 0; matchIndex = 0; } } else { if (matchIndex === 0) { inspectIndex++; } else { matchIndex = delimLPS[matchIndex - 1]; } } } // Keep inspectIndex and matchIndex. inputBuffer = new Deno.Buffer(sliceToProcess); } } exports_16("readDelim", readDelim); /** Read delimited strings from a Reader. */ async function* readStringDelim(reader, delim) { const encoder = new TextEncoder(); const decoder = new TextDecoder(); for await (const chunk of readDelim(reader, encoder.encode(delim))) { yield decoder.decode(chunk); } } exports_16("readStringDelim", readStringDelim); /** Read strings line-by-line from a Reader. */ // eslint-disable-next-line require-await async function* readLines(reader) { yield* readStringDelim(reader, "\n"); } exports_16("readLines", readLines); return { setters: [ function (util_ts_1_1) { util_ts_1 = util_ts_1_1; }, function (asserts_ts_3_1) { asserts_ts_3 = asserts_ts_3_1; }, ], execute: function () { DEFAULT_BUF_SIZE = 4096; MIN_BUF_SIZE = 16; MAX_CONSECUTIVE_EMPTY_READS = 100; CR = util_ts_1.charCode("\r"); LF = util_ts_1.charCode("\n"); BufferFullError = class BufferFullError extends Error { constructor(partial) { super("Buffer full"); this.partial = partial; this.name = "BufferFullError"; } }; exports_16("BufferFullError", BufferFullError); PartialReadError = class PartialReadError extends Deno.errors.UnexpectedEof { constructor() { super("Encountered UnexpectedEof, data only partially read"); this.name = "PartialReadError"; } }; exports_16("PartialReadError", PartialReadError); /** BufReader implements buffering for a Reader object. */ BufReader = class BufReader { constructor(rd, size = DEFAULT_BUF_SIZE) { this.r = 0; // buf read position. this.w = 0; // buf write position. this.eof = false; if (size < MIN_BUF_SIZE) { size = MIN_BUF_SIZE; } this._reset(new Uint8Array(size), rd); } // private lastByte: number; // private lastCharSize: number; /** return new BufReader unless r is BufReader */ static create(r, size = DEFAULT_BUF_SIZE) { return r instanceof BufReader ? r : new BufReader(r, size); } /** Returns the size of the underlying buffer in bytes. */ size() { return this.buf.byteLength; } buffered() { return this.w - this.r; } // Reads a new chunk into the buffer. async _fill() { // Slide existing data to beginning. if (this.r > 0) { this.buf.copyWithin(0, this.r, this.w); this.w -= this.r; this.r = 0; } if (this.w >= this.buf.byteLength) { throw Error("bufio: tried to fill full buffer"); } // Read new data: try a limited number of times. for (let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--) { const rr = await this.rd.read(this.buf.subarray(this.w)); if (rr === null) { this.eof = true; return; } asserts_ts_3.assert(rr >= 0, "negative read"); this.w += rr; if (rr > 0) { return; } } throw new Error( `No progress after ${MAX_CONSECUTIVE_EMPTY_READS} read() calls`, ); } /** Discards any buffered data, resets all state, and switches * the buffered reader to read from r. */ reset(r) { this._reset(this.buf, r); } _reset(buf, rd) { this.buf = buf; this.rd = rd; this.eof = false; // this.lastByte = -1; // this.lastCharSize = -1; } /** reads data into p. * It returns the number of bytes read into p. * The bytes are taken from at most one Read on the underlying Reader, * hence n may be less than len(p). * To read exactly len(p) bytes, use io.ReadFull(b, p). */ async read(p) { let rr = p.byteLength; if (p.byteLength === 0) { return rr; } if (this.r === this.w) { if (p.byteLength >= this.buf.byteLength) { // Large read, empty buffer. // Read directly into p to avoid copy. const rr = await this.rd.read(p); const nread = rr ?? 0; asserts_ts_3.assert(nread >= 0, "negative read"); // if (rr.nread > 0) { // this.lastByte = p[rr.nread - 1]; // this.lastCharSize = -1; // } return rr; } // One read. // Do not use this.fill, which will loop. this.r = 0; this.w = 0; rr = await this.rd.read(this.buf); if (rr === 0 || rr === null) { return rr; } asserts_ts_3.assert(rr >= 0, "negative read"); this.w += rr; } // copy as much as we can const copied = util_ts_1.copyBytes( this.buf.subarray(this.r, this.w), p, 0, ); this.r += copied; // this.lastByte = this.buf[this.r - 1]; // this.lastCharSize = -1; return copied; } /** reads exactly `p.length` bytes into `p`. * * If successful, `p` is returned. * * If the end of the underlying stream has been reached, and there are no more * bytes available in the buffer, `readFull()` returns `null` instead. * * An error is thrown if some bytes could be read, but not enough to fill `p` * entirely before the underlying stream reported an error or EOF. Any error * thrown will have a `partial` property that indicates the slice of the * buffer that has been successfully filled with data. * * Ported from https://golang.org/pkg/io/#ReadFull */ async readFull(p) { let bytesRead = 0; while (bytesRead < p.length) { try { const rr = await this.read(p.subarray(bytesRead)); if (rr === null) { if (bytesRead === 0) { return null; } else { throw new PartialReadError(); } } bytesRead += rr; } catch (err) { err.partial = p.subarray(0, bytesRead); throw err; } } return p; } /** Returns the next byte [0, 255] or `null`. */ async readByte() { while (this.r === this.w) { if (this.eof) { return null; } await this._fill(); // buffer is empty. } const c = this.buf[this.r]; this.r++; // this.lastByte = c; return c; } /** readString() reads until the first occurrence of delim in the input, * returning a string containing the data up to and including the delimiter. * If ReadString encounters an error before finding a delimiter, * it returns the data read before the error and the error itself * (often `null`). * ReadString returns err != nil if and only if the returned data does not end * in delim. * For simple uses, a Scanner may be more convenient. */ async readString(delim) { if (delim.length !== 1) { throw new Error("Delimiter should be a single character"); } const buffer = await this.readSlice(delim.charCodeAt(0)); if (buffer === null) { return null; } return new TextDecoder().decode(buffer); } /** `readLine()` is a low-level line-reading primitive. Most callers should * use `readString('\n')` instead or use a Scanner. * * `readLine()` tries to return a single line, not including the end-of-line * bytes. If the line was too long for the buffer then `more` is set and the * beginning of the line is returned. The rest of the line will be returned * from future calls. `more` will be false when returning the last fragment * of the line. The returned buffer is only valid until the next call to * `readLine()`. * * The text returned from ReadLine does not include the line end ("\r\n" or * "\n"). * * When the end of the underlying stream is reached, the final bytes in the * stream are returned. No indication or error is given if the input ends * without a final line end. When there are no more trailing bytes to read, * `readLine()` returns `null`. * * Calling `unreadByte()` after `readLine()` will always unread the last byte * read (possibly a character belonging to the line end) even if that byte is * not part of the line returned by `readLine()`. */ async readLine() { let line; try { line = await this.readSlice(LF); } catch (err) { let { partial } = err; asserts_ts_3.assert( partial instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property", ); // Don't throw if `readSlice()` failed with `BufferFullError`, instead we // just return whatever is available and set the `more` flag. if (!(err instanceof BufferFullError)) { throw err; } // Handle the case where "\r\n" straddles the buffer. if ( !this.eof && partial.byteLength > 0 && partial[partial.byteLength - 1] === CR ) { // Put the '\r' back on buf and drop it from line. // Let the next call to ReadLine check for "\r\n". asserts_ts_3.assert( this.r > 0, "bufio: tried to rewind past start of buffer", ); this.r--; partial = partial.subarray(0, partial.byteLength - 1); } return { line: partial, more: !this.eof }; } if (line === null) { return null; } if (line.byteLength === 0) { return { line, more: false }; } if (line[line.byteLength - 1] == LF) { let drop = 1; if (line.byteLength > 1 && line[line.byteLength - 2] === CR) { drop = 2; } line = line.subarray(0, line.byteLength - drop); } return { line, more: false }; } /** `readSlice()` reads until the first occurrence of `delim` in the input, * returning a slice pointing at the bytes in the buffer. The bytes stop * being valid at the next read. * * If `readSlice()` encounters an error before finding a delimiter, or the * buffer fills without finding a delimiter, it throws an error with a * `partial` property that contains the entire buffer. * * If `readSlice()` encounters the end of the underlying stream and there are * any bytes left in the buffer, the rest of the buffer is returned. In other * words, EOF is always treated as a delimiter. Once the buffer is empty, * it returns `null`. * * Because the data returned from `readSlice()` will be overwritten by the * next I/O operation, most clients should use `readString()` instead. */ async readSlice(delim) { let s = 0; // search start index let slice; while (true) { // Search buffer. let i = this.buf.subarray(this.r + s, this.w).indexOf(delim); if (i >= 0) { i += s; slice = this.buf.subarray(this.r, this.r + i + 1); this.r += i + 1; break; } // EOF? if (this.eof) { if (this.r === this.w) { return null; } slice = this.buf.subarray(this.r, this.w); this.r = this.w; break; } // Buffer full? if (this.buffered() >= this.buf.byteLength) { this.r = this.w; // #4521 The internal buffer should not be reused across reads because it causes corruption of data. const oldbuf = this.buf; const newbuf = this.buf.slice(0); this.buf = newbuf; throw new BufferFullError(oldbuf); } s = this.w - this.r; // do not rescan area we scanned before // Buffer is not full. try { await this._fill(); } catch (err) { err.partial = slice; throw err; } } // Handle last byte, if any. // const i = slice.byteLength - 1; // if (i >= 0) { // this.lastByte = slice[i]; // this.lastCharSize = -1 // } return slice; } /** `peek()` returns the next `n` bytes without advancing the reader. The * bytes stop being valid at the next read call. * * When the end of the underlying stream is reached, but there are unread * bytes left in the buffer, those bytes are returned. If there are no bytes * left in the buffer, it returns `null`. * * If an error is encountered before `n` bytes are available, `peek()` throws * an error with the `partial` property set to a slice of the buffer that * contains the bytes that were available before the error occurred. */ async peek(n) { if (n < 0) { throw Error("negative count"); } let avail = this.w - this.r; while (avail < n && avail < this.buf.byteLength && !this.eof) { try { await this._fill(); } catch (err) { err.partial = this.buf.subarray(this.r, this.w); throw err; } avail = this.w - this.r; } if (avail === 0 && this.eof) { return null; } else if (avail < n && this.eof) { return this.buf.subarray(this.r, this.r + avail); } else if (avail < n) { throw new BufferFullError(this.buf.subarray(this.r, this.w)); } return this.buf.subarray(this.r, this.r + n); } }; exports_16("BufReader", BufReader); AbstractBufBase = class AbstractBufBase { constructor() { this.usedBufferBytes = 0; this.err = null; } /** Size returns the size of the underlying buffer in bytes. */ size() { return this.buf.byteLength; } /** Returns how many bytes are unused in the buffer. */ available() { return this.buf.byteLength - this.usedBufferBytes; } /** buffered returns the number of bytes that have been written into the * current buffer. */ buffered() { return this.usedBufferBytes; } checkBytesWritten(numBytesWritten) { if (numBytesWritten < this.usedBufferBytes) { if (numBytesWritten > 0) { this.buf.copyWithin(0, numBytesWritten, this.usedBufferBytes); this.usedBufferBytes -= numBytesWritten; } this.err = new Error("Short write"); throw this.err; } } }; /** BufWriter implements buffering for an deno.Writer object. * If an error occurs writing to a Writer, no more data will be * accepted and all subsequent writes, and flush(), will return the error. * After all data has been written, the client should call the * flush() method to guarantee all data has been forwarded to * the underlying deno.Writer. */ BufWriter = class BufWriter extends AbstractBufBase { constructor(writer, size = DEFAULT_BUF_SIZE) { super(); this.writer = writer; if (size <= 0) { size = DEFAULT_BUF_SIZE; } this.buf = new Uint8Array(size); } /** return new BufWriter unless writer is BufWriter */ static create(writer, size = DEFAULT_BUF_SIZE) { return writer instanceof BufWriter ? writer : new BufWriter(writer, size); } /** Discards any unflushed buffered data, clears any error, and * resets buffer to write its output to w. */ reset(w) { this.err = null; this.usedBufferBytes = 0; this.writer = w; } /** Flush writes any buffered data to the underlying io.Writer. */ async flush() { if (this.err !== null) { throw this.err; } if (this.usedBufferBytes === 0) { return; } let numBytesWritten = 0; try { numBytesWritten = await this.writer.write( this.buf.subarray(0, this.usedBufferBytes), ); } catch (e) { this.err = e; throw e; } this.checkBytesWritten(numBytesWritten); this.usedBufferBytes = 0; } /** Writes the contents of `data` into the buffer. If the contents won't fully * fit into the buffer, those bytes that can are copied into the buffer, the * buffer is the flushed to the writer and the remaining bytes are copied into * the now empty buffer. * * @return the number of bytes written to the buffer. */ async write(data) { if (this.err !== null) { throw this.err; } if (data.length === 0) { return 0; } let totalBytesWritten = 0; let numBytesWritten = 0; while (data.byteLength > this.available()) { if (this.buffered() === 0) { // Large write, empty buffer. // Write directly from data to avoid copy. try { numBytesWritten = await this.writer.write(data); } catch (e) { this.err = e; throw e; } } else { numBytesWritten = util_ts_1.copyBytes( data, this.buf, this.usedBufferBytes, ); this.usedBufferBytes += numBytesWritten; await this.flush(); } totalBytesWritten += numBytesWritten; data = data.subarray(numBytesWritten); } numBytesWritten = util_ts_1.copyBytes( data, this.buf, this.usedBufferBytes, ); this.usedBufferBytes += numBytesWritten; totalBytesWritten += numBytesWritten; return totalBytesWritten; } }; exports_16("BufWriter", BufWriter); /** BufWriterSync implements buffering for a deno.WriterSync object. * If an error occurs writing to a WriterSync, no more data will be * accepted and all subsequent writes, and flush(), will return the error. * After all data has been written, the client should call the * flush() method to guarantee all data has been forwarded to * the underlying deno.WriterSync. */ BufWriterSync = class BufWriterSync extends AbstractBufBase { constructor(writer, size = DEFAULT_BUF_SIZE) { super(); this.writer = writer; if (size <= 0) { size = DEFAULT_BUF_SIZE; } this.buf = new Uint8Array(size); } /** return new BufWriterSync unless writer is BufWriterSync */ static create(writer, size = DEFAULT_BUF_SIZE) { return writer instanceof BufWriterSync ? writer : new BufWriterSync(writer, size); } /** Discards any unflushed buffered data, clears any error, and * resets buffer to write its output to w. */ reset(w) { this.err = null; this.usedBufferBytes = 0; this.writer = w; } /** Flush writes any buffered data to the underlying io.WriterSync. */ flush() { if (this.err !== null) { throw this.err; } if (this.usedBufferBytes === 0) { return; } let numBytesWritten = 0; try { numBytesWritten = this.writer.writeSync( this.buf.subarray(0, this.usedBufferBytes), ); } catch (e) { this.err = e; throw e; } this.checkBytesWritten(numBytesWritten); this.usedBufferBytes = 0; } /** Writes the contents of `data` into the buffer. If the contents won't fully * fit into the buffer, those bytes that can are copied into the buffer, the * buffer is the flushed to the writer and the remaining bytes are copied into * the now empty buffer. * * @return the number of bytes written to the buffer. */ writeSync(data) { if (this.err !== null) { throw this.err; } if (data.length === 0) { return 0; } let totalBytesWritten = 0; let numBytesWritten = 0; while (data.byteLength > this.available()) { if (this.buffered() === 0) { // Large write, empty buffer. // Write directly from data to avoid copy. try { numBytesWritten = this.writer.writeSync(data); } catch (e) { this.err = e; throw e; } } else { numBytesWritten = util_ts_1.copyBytes( data, this.buf, this.usedBufferBytes, ); this.usedBufferBytes += numBytesWritten; this.flush(); } totalBytesWritten += numBytesWritten; data = data.subarray(numBytesWritten); } numBytesWritten = util_ts_1.copyBytes( data, this.buf, this.usedBufferBytes, ); this.usedBufferBytes += numBytesWritten; totalBytesWritten += numBytesWritten; return totalBytesWritten; } }; exports_16("BufWriterSync", BufWriterSync); }, }; }, ); System.register( "https://deno.land/std@0.56.0/async/deferred", [], function (exports_17, context_17) { "use strict"; var __moduleName = context_17 && context_17.id; /** Creates a Promise with the `reject` and `resolve` functions * placed as methods on the promise object itself. It allows you to do: * * const p = deferred(); * // ... * p.resolve(42); */ function deferred() { let methods; const promise = new Promise((resolve, reject) => { methods = { resolve, reject }; }); return Object.assign(promise, methods); } exports_17("deferred", deferred); return { setters: [], execute: function () { }, }; }, ); System.register( "https://deno.land/std@0.56.0/async/delay", [], function (exports_18, context_18) { "use strict"; var __moduleName = context_18 && context_18.id; // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /* Resolves after the given number of milliseconds. */ function delay(ms) { return new Promise((res) => setTimeout(() => { res(); }, ms) ); } exports_18("delay", delay); return { setters: [], execute: function () { }, }; }, ); System.register( "https://deno.land/std@0.56.0/async/mux_async_iterator", ["https://deno.land/std@0.56.0/async/deferred"], function (exports_19, context_19) { "use strict"; var deferred_ts_1, MuxAsyncIterator; var __moduleName = context_19 && context_19.id; return { setters: [ function (deferred_ts_1_1) { deferred_ts_1 = deferred_ts_1_1; }, ], execute: function () { /** The MuxAsyncIterator class multiplexes multiple async iterators into a * single stream. It currently makes a few assumptions: * - The iterators do not throw. * - The final result (the value returned and not yielded from the iterator) * does not matter; if there is any, it is discarded. */ MuxAsyncIterator = class MuxAsyncIterator { constructor() { this.iteratorCount = 0; this.yields = []; this.signal = deferred_ts_1.deferred(); } add(iterator) { ++this.iteratorCount; this.callIteratorNext(iterator); } async callIteratorNext(iterator) { const { value, done } = await iterator.next(); if (done) { --this.iteratorCount; } else { this.yields.push({ iterator, value }); } this.signal.resolve(); } async *iterate() { while (this.iteratorCount > 0) { // Sleep until any of the wrapped iterators yields. await this.signal; // Note that while we're looping over `yields`, new items may be added. for (let i = 0; i < this.yields.length; i++) { const { iterator, value } = this.yields[i]; yield value; this.callIteratorNext(iterator); } // Clear the `yields` list and reset the `signal` promise. this.yields.length = 0; this.signal = deferred_ts_1.deferred(); } } [Symbol.asyncIterator]() { return this.iterate(); } }; exports_19("MuxAsyncIterator", MuxAsyncIterator); }, }; }, ); System.register( "https://deno.land/std@0.56.0/async/mod", [ "https://deno.land/std@0.56.0/async/deferred", "https://deno.land/std@0.56.0/async/delay", "https://deno.land/std@0.56.0/async/mux_async_iterator", ], function (exports_20, context_20) { "use strict"; var __moduleName = context_20 && context_20.id; function exportStar_2(m) { var exports = {}; for (var n in m) { if (n !== "default") exports[n] = m[n]; } exports_20(exports); } return { setters: [ function (deferred_ts_2_1) { exportStar_2(deferred_ts_2_1); }, function (delay_ts_1_1) { exportStar_2(delay_ts_1_1); }, function (mux_async_iterator_ts_1_1) { exportStar_2(mux_async_iterator_ts_1_1); }, ], execute: function () { }, }; }, ); System.register( "https://deno.land/std@0.56.0/bytes/mod", ["https://deno.land/std@0.56.0/io/util"], function (exports_21, context_21) { "use strict"; var util_ts_2; var __moduleName = context_21 && context_21.id; /** Find first index of binary pattern from a. If not found, then return -1 * @param source soruce array * @param pat pattern to find in source array */ function findIndex(source, pat) { const s = pat[0]; for (let i = 0; i < source.length; i++) { if (source[i] !== s) { continue; } const pin = i; let matched = 1; let j = i; while (matched < pat.length) { j++; if (source[j] !== pat[j - pin]) { break; } matched++; } if (matched === pat.length) { return pin; } } return -1; } exports_21("findIndex", findIndex); /** Find last index of binary pattern from a. If not found, then return -1. * @param source soruce array * @param pat pattern to find in source array */ function findLastIndex(source, pat) { const e = pat[pat.length - 1]; for (let i = source.length - 1; i >= 0; i--) { if (source[i] !== e) { continue; } const pin = i; let matched = 1; let j = i; while (matched < pat.length) { j--; if (source[j] !== pat[pat.length - 1 - (pin - j)]) { break; } matched++; } if (matched === pat.length) { return pin - pat.length + 1; } } return -1; } exports_21("findLastIndex", findLastIndex); /** Check whether binary arrays are equal to each other. * @param source first array to check equality * @param match second array to check equality */ function equal(source, match) { if (source.length !== match.length) { return false; } for (let i = 0; i < match.length; i++) { if (source[i] !== match[i]) { return false; } } return true; } exports_21("equal", equal); /** Check whether binary array starts with prefix. * @param source srouce array * @param prefix prefix array to check in source */ function hasPrefix(source, prefix) { for (let i = 0, max = prefix.length; i < max; i++) { if (source[i] !== prefix[i]) { return false; } } return true; } exports_21("hasPrefix", hasPrefix); /** Check whether binary array ends with suffix. * @param source srouce array * @param suffix suffix array to check in source */ function hasSuffix(source, suffix) { for ( let srci = source.length - 1, sfxi = suffix.length - 1; sfxi >= 0; srci--, sfxi-- ) { if (source[srci] !== suffix[sfxi]) { return false; } } return true; } exports_21("hasSuffix", hasSuffix); /** Repeat bytes. returns a new byte slice consisting of `count` copies of `b`. * @param origin The origin bytes * @param count The count you want to repeat. */ function repeat(origin, count) { if (count === 0) { return new Uint8Array(); } if (count < 0) { throw new Error("bytes: negative repeat count"); } else if ((origin.length * count) / count !== origin.length) { throw new Error("bytes: repeat count causes overflow"); } const int = Math.floor(count); if (int !== count) { throw new Error("bytes: repeat count must be an integer"); } const nb = new Uint8Array(origin.length * count); let bp = util_ts_2.copyBytes(origin, nb); for (; bp < nb.length; bp *= 2) { util_ts_2.copyBytes(nb.slice(0, bp), nb, bp); } return nb; } exports_21("repeat", repeat); /** Concatenate two binary arrays and return new one. * @param origin origin array to concatenate * @param b array to concatenate with origin */ function concat(origin, b) { const output = new Uint8Array(origin.length + b.length); output.set(origin, 0); output.set(b, origin.length); return output; } exports_21("concat", concat); /** Check srouce array contains pattern array. * @param source srouce array * @param pat patter array */ function contains(source, pat) { return findIndex(source, pat) != -1; } exports_21("contains", contains); return { setters: [ function (util_ts_2_1) { util_ts_2 = util_ts_2_1; }, ], execute: function () { }, }; }, ); // Based on https://github.com/golang/go/tree/master/src/net/textproto // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. System.register( "https://deno.land/std@0.56.0/textproto/mod", [ "https://deno.land/std@0.56.0/io/util", "https://deno.land/std@0.56.0/bytes/mod", "https://deno.land/std@0.56.0/encoding/utf8", ], function (exports_22, context_22) { "use strict"; var util_ts_3, mod_ts_2, utf8_ts_2, invalidHeaderCharRegex, TextProtoReader; var __moduleName = context_22 && context_22.id; function str(buf) { if (buf == null) { return ""; } else { return utf8_ts_2.decode(buf); } } return { setters: [ function (util_ts_3_1) { util_ts_3 = util_ts_3_1; }, function (mod_ts_2_1) { mod_ts_2 = mod_ts_2_1; }, function (utf8_ts_2_1) { utf8_ts_2 = utf8_ts_2_1; }, ], execute: function () { // FROM https://github.com/denoland/deno/blob/b34628a26ab0187a827aa4ebe256e23178e25d39/cli/js/web/headers.ts#L9 invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/g; TextProtoReader = class TextProtoReader { constructor(r) { this.r = r; } /** readLine() reads a single line from the TextProtoReader, * eliding the final \n or \r\n from the returned string. */ async readLine() { const s = await this.readLineSlice(); if (s === null) { return null; } return str(s); } /** ReadMIMEHeader reads a MIME-style header from r. * The header is a sequence of possibly continued Key: Value lines * ending in a blank line. * The returned map m maps CanonicalMIMEHeaderKey(key) to a * sequence of values in the same order encountered in the input. * * For example, consider this input: * * My-Key: Value 1 * Long-Key: Even * Longer Value * My-Key: Value 2 * * Given that input, ReadMIMEHeader returns the map: * * map[string][]string{ * "My-Key": {"Value 1", "Value 2"}, * "Long-Key": {"Even Longer Value"}, * } */ async readMIMEHeader() { const m = new Headers(); let line; // The first line cannot start with a leading space. let buf = await this.r.peek(1); if (buf === null) { return null; } else if ( buf[0] == util_ts_3.charCode(" ") || buf[0] == util_ts_3.charCode("\t") ) { line = (await this.readLineSlice()); } buf = await this.r.peek(1); if (buf === null) { throw new Deno.errors.UnexpectedEof(); } else if ( buf[0] == util_ts_3.charCode(" ") || buf[0] == util_ts_3.charCode("\t") ) { throw new Deno.errors.InvalidData( `malformed MIME header initial line: ${str(line)}`, ); } while (true) { const kv = await this.readLineSlice(); // readContinuedLineSlice if (kv === null) { throw new Deno.errors.UnexpectedEof(); } if (kv.byteLength === 0) { return m; } // Key ends at first colon let i = kv.indexOf(util_ts_3.charCode(":")); if (i < 0) { throw new Deno.errors.InvalidData( `malformed MIME header line: ${str(kv)}`, ); } //let key = canonicalMIMEHeaderKey(kv.subarray(0, endKey)); const key = str(kv.subarray(0, i)); // As per RFC 7230 field-name is a token, // tokens consist of one or more chars. // We could throw `Deno.errors.InvalidData` here, // but better to be liberal in what we // accept, so if we get an empty key, skip it. if (key == "") { continue; } // Skip initial spaces in value. i++; // skip colon while ( i < kv.byteLength && (kv[i] == util_ts_3.charCode(" ") || kv[i] == util_ts_3.charCode("\t")) ) { i++; } const value = str(kv.subarray(i)).replace( invalidHeaderCharRegex, encodeURI, ); // In case of invalid header we swallow the error // example: "Audio Mode" => invalid due to space in the key try { m.append(key, value); } catch {} } } async readLineSlice() { // this.closeDot(); let line; while (true) { const r = await this.r.readLine(); if (r === null) { return null; } const { line: l, more } = r; // Avoid the copy if the first call produced a full line. if (!line && !more) { // TODO(ry): // This skipSpace() is definitely misplaced, but I don't know where it // comes from nor how to fix it. if (this.skipSpace(l) === 0) { return new Uint8Array(0); } return l; } line = line ? mod_ts_2.concat(line, l) : l; if (!more) { break; } } return line; } skipSpace(l) { let n = 0; for (let i = 0; i < l.length; i++) { if ( l[i] === util_ts_3.charCode(" ") || l[i] === util_ts_3.charCode("\t") ) { continue; } n++; } return n; } }; exports_22("TextProtoReader", TextProtoReader); }, }; }, ); // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. System.register( "https://deno.land/std@0.56.0/http/http_status", [], function (exports_23, context_23) { "use strict"; var Status, STATUS_TEXT; var __moduleName = context_23 && context_23.id; return { setters: [], execute: function () { /** HTTP status codes */ (function (Status) { /** RFC 7231, 6.2.1 */ Status[Status["Continue"] = 100] = "Continue"; /** RFC 7231, 6.2.2 */ Status[Status["SwitchingProtocols"] = 101] = "SwitchingProtocols"; /** RFC 2518, 10.1 */ Status[Status["Processing"] = 102] = "Processing"; /** RFC 8297 **/ Status[Status["EarlyHints"] = 103] = "EarlyHints"; /** RFC 7231, 6.3.1 */ Status[Status["OK"] = 200] = "OK"; /** RFC 7231, 6.3.2 */ Status[Status["Created"] = 201] = "Created"; /** RFC 7231, 6.3.3 */ Status[Status["Accepted"] = 202] = "Accepted"; /** RFC 7231, 6.3.4 */ Status[Status["NonAuthoritativeInfo"] = 203] = "NonAuthoritativeInfo"; /** RFC 7231, 6.3.5 */ Status[Status["NoContent"] = 204] = "NoContent"; /** RFC 7231, 6.3.6 */ Status[Status["ResetContent"] = 205] = "ResetContent"; /** RFC 7233, 4.1 */ Status[Status["PartialContent"] = 206] = "PartialContent"; /** RFC 4918, 11.1 */ Status[Status["MultiStatus"] = 207] = "MultiStatus"; /** RFC 5842, 7.1 */ Status[Status["AlreadyReported"] = 208] = "AlreadyReported"; /** RFC 3229, 10.4.1 */ Status[Status["IMUsed"] = 226] = "IMUsed"; /** RFC 7231, 6.4.1 */ Status[Status["MultipleChoices"] = 300] = "MultipleChoices"; /** RFC 7231, 6.4.2 */ Status[Status["MovedPermanently"] = 301] = "MovedPermanently"; /** RFC 7231, 6.4.3 */ Status[Status["Found"] = 302] = "Found"; /** RFC 7231, 6.4.4 */ Status[Status["SeeOther"] = 303] = "SeeOther"; /** RFC 7232, 4.1 */ Status[Status["NotModified"] = 304] = "NotModified"; /** RFC 7231, 6.4.5 */ Status[Status["UseProxy"] = 305] = "UseProxy"; /** RFC 7231, 6.4.7 */ Status[Status["TemporaryRedirect"] = 307] = "TemporaryRedirect"; /** RFC 7538, 3 */ Status[Status["PermanentRedirect"] = 308] = "PermanentRedirect"; /** RFC 7231, 6.5.1 */ Status[Status["BadRequest"] = 400] = "BadRequest"; /** RFC 7235, 3.1 */ Status[Status["Unauthorized"] = 401] = "Unauthorized"; /** RFC 7231, 6.5.2 */ Status[Status["PaymentRequired"] = 402] = "PaymentRequired"; /** RFC 7231, 6.5.3 */ Status[Status["Forbidden"] = 403] = "Forbidden"; /** RFC 7231, 6.5.4 */ Status[Status["NotFound"] = 404] = "NotFound"; /** RFC 7231, 6.5.5 */ Status[Status["MethodNotAllowed"] = 405] = "MethodNotAllowed"; /** RFC 7231, 6.5.6 */ Status[Status["NotAcceptable"] = 406] = "NotAcceptable"; /** RFC 7235, 3.2 */ Status[Status["ProxyAuthRequired"] = 407] = "ProxyAuthRequired"; /** RFC 7231, 6.5.7 */ Status[Status["RequestTimeout"] = 408] = "RequestTimeout"; /** RFC 7231, 6.5.8 */ Status[Status["Conflict"] = 409] = "Conflict"; /** RFC 7231, 6.5.9 */ Status[Status["Gone"] = 410] = "Gone"; /** RFC 7231, 6.5.10 */ Status[Status["LengthRequired"] = 411] = "LengthRequired"; /** RFC 7232, 4.2 */ Status[Status["PreconditionFailed"] = 412] = "PreconditionFailed"; /** RFC 7231, 6.5.11 */ Status[Status["RequestEntityTooLarge"] = 413] = "RequestEntityTooLarge"; /** RFC 7231, 6.5.12 */ Status[Status["RequestURITooLong"] = 414] = "RequestURITooLong"; /** RFC 7231, 6.5.13 */ Status[Status["UnsupportedMediaType"] = 415] = "UnsupportedMediaType"; /** RFC 7233, 4.4 */ Status[Status["RequestedRangeNotSatisfiable"] = 416] = "RequestedRangeNotSatisfiable"; /** RFC 7231, 6.5.14 */ Status[Status["ExpectationFailed"] = 417] = "ExpectationFailed"; /** RFC 7168, 2.3.3 */ Status[Status["Teapot"] = 418] = "Teapot"; /** RFC 7540, 9.1.2 */ Status[Status["MisdirectedRequest"] = 421] = "MisdirectedRequest"; /** RFC 4918, 11.2 */ Status[Status["UnprocessableEntity"] = 422] = "UnprocessableEntity"; /** RFC 4918, 11.3 */ Status[Status["Locked"] = 423] = "Locked"; /** RFC 4918, 11.4 */ Status[Status["FailedDependency"] = 424] = "FailedDependency"; /** RFC 8470, 5.2 */ Status[Status["TooEarly"] = 425] = "TooEarly"; /** RFC 7231, 6.5.15 */ Status[Status["UpgradeRequired"] = 426] = "UpgradeRequired"; /** RFC 6585, 3 */ Status[Status["PreconditionRequired"] = 428] = "PreconditionRequired"; /** RFC 6585, 4 */ Status[Status["TooManyRequests"] = 429] = "TooManyRequests"; /** RFC 6585, 5 */ Status[Status["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge"; /** RFC 7725, 3 */ Status[Status["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons"; /** RFC 7231, 6.6.1 */ Status[Status["InternalServerError"] = 500] = "InternalServerError"; /** RFC 7231, 6.6.2 */ Status[Status["NotImplemented"] = 501] = "NotImplemented"; /** RFC 7231, 6.6.3 */ Status[Status["BadGateway"] = 502] = "BadGateway"; /** RFC 7231, 6.6.4 */ Status[Status["ServiceUnavailable"] = 503] = "ServiceUnavailable"; /** RFC 7231, 6.6.5 */ Status[Status["GatewayTimeout"] = 504] = "GatewayTimeout"; /** RFC 7231, 6.6.6 */ Status[Status["HTTPVersionNotSupported"] = 505] = "HTTPVersionNotSupported"; /** RFC 2295, 8.1 */ Status[Status["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates"; /** RFC 4918, 11.5 */ Status[Status["InsufficientStorage"] = 507] = "InsufficientStorage"; /** RFC 5842, 7.2 */ Status[Status["LoopDetected"] = 508] = "LoopDetected"; /** RFC 2774, 7 */ Status[Status["NotExtended"] = 510] = "NotExtended"; /** RFC 6585, 6 */ Status[Status["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired"; })(Status || (Status = {})); exports_23("Status", Status); exports_23( "STATUS_TEXT", STATUS_TEXT = new Map([ [Status.Continue, "Continue"], [Status.SwitchingProtocols, "Switching Protocols"], [Status.Processing, "Processing"], [Status.EarlyHints, "Early Hints"], [Status.OK, "OK"], [Status.Created, "Created"], [Status.Accepted, "Accepted"], [Status.NonAuthoritativeInfo, "Non-Authoritative Information"], [Status.NoContent, "No Content"], [Status.ResetContent, "Reset Content"], [Status.PartialContent, "Partial Content"], [Status.MultiStatus, "Multi-Status"], [Status.AlreadyReported, "Already Reported"], [Status.IMUsed, "IM Used"], [Status.MultipleChoices, "Multiple Choices"], [Status.MovedPermanently, "Moved Permanently"], [Status.Found, "Found"], [Status.SeeOther, "See Other"], [Status.NotModified, "Not Modified"], [Status.UseProxy, "Use Proxy"], [Status.TemporaryRedirect, "Temporary Redirect"], [Status.PermanentRedirect, "Permanent Redirect"], [Status.BadRequest, "Bad Request"], [Status.Unauthorized, "Unauthorized"], [Status.PaymentRequired, "Payment Required"], [Status.Forbidden, "Forbidden"], [Status.NotFound, "Not Found"], [Status.MethodNotAllowed, "Method Not Allowed"], [Status.NotAcceptable, "Not Acceptable"], [Status.ProxyAuthRequired, "Proxy Authentication Required"], [Status.RequestTimeout, "Request Timeout"], [Status.Conflict, "Conflict"], [Status.Gone, "Gone"], [Status.LengthRequired, "Length Required"], [Status.PreconditionFailed, "Precondition Failed"], [Status.RequestEntityTooLarge, "Request Entity Too Large"], [Status.RequestURITooLong, "Request URI Too Long"], [Status.UnsupportedMediaType, "Unsupported Media Type"], [ Status.RequestedRangeNotSatisfiable, "Requested Range Not Satisfiable", ], [Status.ExpectationFailed, "Expectation Failed"], [Status.Teapot, "I'm a teapot"], [Status.MisdirectedRequest, "Misdirected Request"], [Status.UnprocessableEntity, "Unprocessable Entity"], [Status.Locked, "Locked"], [Status.FailedDependency, "Failed Dependency"], [Status.TooEarly, "Too Early"], [Status.UpgradeRequired, "Upgrade Required"], [Status.PreconditionRequired, "Precondition Required"], [Status.TooManyRequests, "Too Many Requests"], [ Status.RequestHeaderFieldsTooLarge, "Request Header Fields Too Large", ], [ Status.UnavailableForLegalReasons, "Unavailable For Legal Reasons", ], [Status.InternalServerError, "Internal Server Error"], [Status.NotImplemented, "Not Implemented"], [Status.BadGateway, "Bad Gateway"], [Status.ServiceUnavailable, "Service Unavailable"], [Status.GatewayTimeout, "Gateway Timeout"], [Status.HTTPVersionNotSupported, "HTTP Version Not Supported"], [Status.VariantAlsoNegotiates, "Variant Also Negotiates"], [Status.InsufficientStorage, "Insufficient Storage"], [Status.LoopDetected, "Loop Detected"], [Status.NotExtended, "Not Extended"], [ Status.NetworkAuthenticationRequired, "Network Authentication Required", ], ]), ); }, }; }, ); System.register( "https://deno.land/std@0.56.0/http/_io", [ "https://deno.land/std@0.56.0/io/bufio", "https://deno.land/std@0.56.0/textproto/mod", "https://deno.land/std@0.56.0/testing/asserts", "https://deno.land/std@0.56.0/encoding/utf8", "https://deno.land/std@0.56.0/http/server", "https://deno.land/std@0.56.0/http/http_status", ], function (exports_24, context_24) { "use strict"; var bufio_ts_1, mod_ts_3, asserts_ts_4, utf8_ts_3, server_ts_1, http_status_ts_1; var __moduleName = context_24 && context_24.id; function emptyReader() { return { read(_) { return Promise.resolve(null); }, }; } exports_24("emptyReader", emptyReader); function bodyReader(contentLength, r) { let totalRead = 0; let finished = false; async function read(buf) { if (finished) { return null; } let result; const remaining = contentLength - totalRead; if (remaining >= buf.byteLength) { result = await r.read(buf); } else { const readBuf = buf.subarray(0, remaining); result = await r.read(readBuf); } if (result !== null) { totalRead += result; } finished = totalRead === contentLength; return result; } return { read }; } exports_24("bodyReader", bodyReader); function chunkedBodyReader(h, r) { // Based on https://tools.ietf.org/html/rfc2616#section-19.4.6 const tp = new mod_ts_3.TextProtoReader(r); let finished = false; const chunks = []; async function read(buf) { if (finished) { return null; } const [chunk] = chunks; if (chunk) { const chunkRemaining = chunk.data.byteLength - chunk.offset; const readLength = Math.min(chunkRemaining, buf.byteLength); for (let i = 0; i < readLength; i++) { buf[i] = chunk.data[chunk.offset + i]; } chunk.offset += readLength; if (chunk.offset === chunk.data.byteLength) { chunks.shift(); // Consume \r\n; if ((await tp.readLine()) === null) { throw new Deno.errors.UnexpectedEof(); } } return readLength; } const line = await tp.readLine(); if (line === null) { throw new Deno.errors.UnexpectedEof(); } // TODO: handle chunk extension const [chunkSizeString] = line.split(";"); const chunkSize = parseInt(chunkSizeString, 16); if (Number.isNaN(chunkSize) || chunkSize < 0) { throw new Error("Invalid chunk size"); } if (chunkSize > 0) { if (chunkSize > buf.byteLength) { let eof = await r.readFull(buf); if (eof === null) { throw new Deno.errors.UnexpectedEof(); } const restChunk = new Uint8Array(chunkSize - buf.byteLength); eof = await r.readFull(restChunk); if (eof === null) { throw new Deno.errors.UnexpectedEof(); } else { chunks.push({ offset: 0, data: restChunk, }); } return buf.byteLength; } else { const bufToFill = buf.subarray(0, chunkSize); const eof = await r.readFull(bufToFill); if (eof === null) { throw new Deno.errors.UnexpectedEof(); } // Consume \r\n if ((await tp.readLine()) === null) { throw new Deno.errors.UnexpectedEof(); } return chunkSize; } } else { asserts_ts_4.assert(chunkSize === 0); // Consume \r\n if ((await r.readLine()) === null) { throw new Deno.errors.UnexpectedEof(); } await readTrailers(h, r); finished = true; return null; } } return { read }; } exports_24("chunkedBodyReader", chunkedBodyReader); function isProhibidedForTrailer(key) { const s = new Set(["transfer-encoding", "content-length", "trailer"]); return s.has(key.toLowerCase()); } /** * Read trailer headers from reader and append values to headers. * "trailer" field will be deleted. * */ async function readTrailers(headers, r) { const headerKeys = parseTrailer(headers.get("trailer")); if (!headerKeys) { return; } const tp = new mod_ts_3.TextProtoReader(r); const result = await tp.readMIMEHeader(); asserts_ts_4.assert(result !== null, "trailer must be set"); for (const [k, v] of result) { if (!headerKeys.has(k)) { throw new Error("Undeclared trailer field"); } headerKeys.delete(k); headers.append(k, v); } asserts_ts_4.assert( Array.from(headerKeys).length === 0, "Missing trailers", ); headers.delete("trailer"); } exports_24("readTrailers", readTrailers); function parseTrailer(field) { if (field == null) { return undefined; } const keys = field.split(",").map((v) => v.trim().toLowerCase()); if (keys.length === 0) { throw new Error("Empty trailer"); } for (const key of keys) { if (isProhibidedForTrailer(key)) { throw new Error(`Prohibited field for trailer`); } } return new Headers(keys.map((key) => [key, ""])); } async function writeChunkedBody(w, r) { const writer = bufio_ts_1.BufWriter.create(w); for await (const chunk of Deno.iter(r)) { if (chunk.byteLength <= 0) { continue; } const start = utf8_ts_3.encoder.encode( `${chunk.byteLength.toString(16)}\r\n`, ); const end = utf8_ts_3.encoder.encode("\r\n"); await writer.write(start); await writer.write(chunk); await writer.write(end); } const endChunk = utf8_ts_3.encoder.encode("0\r\n\r\n"); await writer.write(endChunk); } exports_24("writeChunkedBody", writeChunkedBody); /** write trailer headers to writer. it mostly should be called after writeResponse */ async function writeTrailers(w, headers, trailers) { const trailer = headers.get("trailer"); if (trailer === null) { throw new Error('response headers must have "trailer" header field'); } const transferEncoding = headers.get("transfer-encoding"); if (transferEncoding === null || !transferEncoding.match(/^chunked/)) { throw new Error( `trailer headers is only allowed for "transfer-encoding: chunked": got "${transferEncoding}"`, ); } const writer = bufio_ts_1.BufWriter.create(w); const trailerHeaderFields = trailer .split(",") .map((s) => s.trim().toLowerCase()); for (const f of trailerHeaderFields) { asserts_ts_4.assert( !isProhibidedForTrailer(f), `"${f}" is prohibited for trailer header`, ); } for (const [key, value] of trailers) { asserts_ts_4.assert( trailerHeaderFields.includes(key), `Not trailer header field: ${key}`, ); await writer.write(utf8_ts_3.encoder.encode(`${key}: ${value}\r\n`)); } await writer.write(utf8_ts_3.encoder.encode("\r\n")); await writer.flush(); } exports_24("writeTrailers", writeTrailers); async function writeResponse(w, r) { const protoMajor = 1; const protoMinor = 1; const statusCode = r.status || 200; const statusText = http_status_ts_1.STATUS_TEXT.get(statusCode); const writer = bufio_ts_1.BufWriter.create(w); if (!statusText) { throw new Deno.errors.InvalidData("Bad status code"); } if (!r.body) { r.body = new Uint8Array(); } if (typeof r.body === "string") { r.body = utf8_ts_3.encoder.encode(r.body); } let out = `HTTP/${protoMajor}.${protoMinor} ${statusCode} ${statusText}\r\n`; const headers = r.headers ?? new Headers(); if (r.body && !headers.get("content-length")) { if (r.body instanceof Uint8Array) { out += `content-length: ${r.body.byteLength}\r\n`; } else if (!headers.get("transfer-encoding")) { out += "transfer-encoding: chunked\r\n"; } } for (const [key, value] of headers) { out += `${key}: ${value}\r\n`; } out += `\r\n`; const header = utf8_ts_3.encoder.encode(out); const n = await writer.write(header); asserts_ts_4.assert(n === header.byteLength); if (r.body instanceof Uint8Array) { const n = await writer.write(r.body); asserts_ts_4.assert(n === r.body.byteLength); } else if (headers.has("content-length")) { const contentLength = headers.get("content-length"); asserts_ts_4.assert(contentLength != null); const bodyLength = parseInt(contentLength); const n = await Deno.copy(r.body, writer); asserts_ts_4.assert(n === bodyLength); } else { await writeChunkedBody(writer, r.body); } if (r.trailers) { const t = await r.trailers(); await writeTrailers(writer, headers, t); } await writer.flush(); } exports_24("writeResponse", writeResponse); /** * ParseHTTPVersion parses a HTTP version string. * "HTTP/1.0" returns (1, 0). * Ported from https://github.com/golang/go/blob/f5c43b9/src/net/http/request.go#L766-L792 */ function parseHTTPVersion(vers) { switch (vers) { case "HTTP/1.1": return [1, 1]; case "HTTP/1.0": return [1, 0]; default: { const Big = 1000000; // arbitrary upper bound if (!vers.startsWith("HTTP/")) { break; } const dot = vers.indexOf("."); if (dot < 0) { break; } const majorStr = vers.substring(vers.indexOf("/") + 1, dot); const major = Number(majorStr); if (!Number.isInteger(major) || major < 0 || major > Big) { break; } const minorStr = vers.substring(dot + 1); const minor = Number(minorStr); if (!Number.isInteger(minor) || minor < 0 || minor > Big) { break; } return [major, minor]; } } throw new Error(`malformed HTTP version ${vers}`); } exports_24("parseHTTPVersion", parseHTTPVersion); async function readRequest(conn, bufr) { const tp = new mod_ts_3.TextProtoReader(bufr); const firstLine = await tp.readLine(); // e.g. GET /index.html HTTP/1.0 if (firstLine === null) { return null; } const headers = await tp.readMIMEHeader(); if (headers === null) { throw new Deno.errors.UnexpectedEof(); } const req = new server_ts_1.ServerRequest(); req.conn = conn; req.r = bufr; [req.method, req.url, req.proto] = firstLine.split(" ", 3); [req.protoMinor, req.protoMajor] = parseHTTPVersion(req.proto); req.headers = headers; fixLength(req); return req; } exports_24("readRequest", readRequest); function fixLength(req) { const contentLength = req.headers.get("Content-Length"); if (contentLength) { const arrClen = contentLength.split(","); if (arrClen.length > 1) { const distinct = [...new Set(arrClen.map((e) => e.trim()))]; if (distinct.length > 1) { throw Error("cannot contain multiple Content-Length headers"); } else { req.headers.set("Content-Length", distinct[0]); } } const c = req.headers.get("Content-Length"); if (req.method === "HEAD" && c && c !== "0") { throw Error("http: method cannot contain a Content-Length"); } if (c && req.headers.has("transfer-encoding")) { // A sender MUST NOT send a Content-Length header field in any message // that contains a Transfer-Encoding header field. // rfc: https://tools.ietf.org/html/rfc7230#section-3.3.2 throw new Error( "http: Transfer-Encoding and Content-Length cannot be send together", ); } } } return { setters: [ function (bufio_ts_1_1) { bufio_ts_1 = bufio_ts_1_1; }, function (mod_ts_3_1) { mod_ts_3 = mod_ts_3_1; }, function (asserts_ts_4_1) { asserts_ts_4 = asserts_ts_4_1; }, function (utf8_ts_3_1) { utf8_ts_3 = utf8_ts_3_1; }, function (server_ts_1_1) { server_ts_1 = server_ts_1_1; }, function (http_status_ts_1_1) { http_status_ts_1 = http_status_ts_1_1; }, ], execute: function () { }, }; }, ); System.register( "https://deno.land/std@0.56.0/http/server", [ "https://deno.land/std@0.56.0/encoding/utf8", "https://deno.land/std@0.56.0/io/bufio", "https://deno.land/std@0.56.0/testing/asserts", "https://deno.land/std@0.56.0/async/mod", "https://deno.land/std@0.56.0/http/_io", ], function (exports_25, context_25) { "use strict"; var utf8_ts_4, bufio_ts_2, asserts_ts_5, mod_ts_4, _io_ts_1, listen, listenTls, ServerRequest, Server; var __moduleName = context_25 && context_25.id; /** * Create a HTTP server * * import { serve } from "https://deno.land/std/http/server.ts"; * const body = "Hello World\n"; * const server = serve({ port: 8000 }); * for await (const req of server) { * req.respond({ body }); * } */ function serve(addr) { if (typeof addr === "string") { const [hostname, port] = addr.split(":"); addr = { hostname, port: Number(port) }; } const listener = listen(addr); return new Server(listener); } exports_25("serve", serve); /** * Start an HTTP server with given options and request handler * * const body = "Hello World\n"; * const options = { port: 8000 }; * listenAndServe(options, (req) => { * req.respond({ body }); * }); * * @param options Server configuration * @param handler Request handler */ async function listenAndServe(addr, handler) { const server = serve(addr); for await (const request of server) { handler(request); } } exports_25("listenAndServe", listenAndServe); /** * Create an HTTPS server with given options * * const body = "Hello HTTPS"; * const options = { * hostname: "localhost", * port: 443, * certFile: "./path/to/localhost.crt", * keyFile: "./path/to/localhost.key", * }; * for await (const req of serveTLS(options)) { * req.respond({ body }); * } * * @param options Server configuration * @return Async iterable server instance for incoming requests */ function serveTLS(options) { const tlsOptions = { ...options, transport: "tcp", }; const listener = listenTls(tlsOptions); return new Server(listener); } exports_25("serveTLS", serveTLS); /** * Start an HTTPS server with given options and request handler * * const body = "Hello HTTPS"; * const options = { * hostname: "localhost", * port: 443, * certFile: "./path/to/localhost.crt", * keyFile: "./path/to/localhost.key", * }; * listenAndServeTLS(options, (req) => { * req.respond({ body }); * }); * * @param options Server configuration * @param handler Request handler */ async function listenAndServeTLS(options, handler) { const server = serveTLS(options); for await (const request of server) { handler(request); } } exports_25("listenAndServeTLS", listenAndServeTLS); return { setters: [ function (utf8_ts_4_1) { utf8_ts_4 = utf8_ts_4_1; }, function (bufio_ts_2_1) { bufio_ts_2 = bufio_ts_2_1; }, function (asserts_ts_5_1) { asserts_ts_5 = asserts_ts_5_1; }, function (mod_ts_4_1) { mod_ts_4 = mod_ts_4_1; }, function (_io_ts_1_1) { _io_ts_1 = _io_ts_1_1; }, ], execute: function () { listen = Deno.listen, listenTls = Deno.listenTls; ServerRequest = class ServerRequest { constructor() { this.done = mod_ts_4.deferred(); this._contentLength = undefined; this._body = null; this.finalized = false; } /** * Value of Content-Length header. * If null, then content length is invalid or not given (e.g. chunked encoding). */ get contentLength() { // undefined means not cached. // null means invalid or not provided. if (this._contentLength === undefined) { const cl = this.headers.get("content-length"); if (cl) { this._contentLength = parseInt(cl); // Convert NaN to null (as NaN harder to test) if (Number.isNaN(this._contentLength)) { this._contentLength = null; } } else { this._contentLength = null; } } return this._contentLength; } /** * Body of the request. The easiest way to consume the body is: * * const buf: Uint8Array = await Deno.readAll(req.body); */ get body() { if (!this._body) { if (this.contentLength != null) { this._body = _io_ts_1.bodyReader(this.contentLength, this.r); } else { const transferEncoding = this.headers.get("transfer-encoding"); if (transferEncoding != null) { const parts = transferEncoding .split(",") .map((e) => e.trim().toLowerCase()); asserts_ts_5.assert( parts.includes("chunked"), 'transfer-encoding must include "chunked" if content-length is not set', ); this._body = _io_ts_1.chunkedBodyReader(this.headers, this.r); } else { // Neither content-length nor transfer-encoding: chunked this._body = _io_ts_1.emptyReader(); } } } return this._body; } async respond(r) { let err; try { // Write our response! await _io_ts_1.writeResponse(this.w, r); } catch (e) { try { // Eagerly close on error. this.conn.close(); } catch {} err = e; } // Signal that this request has been processed and the next pipelined // request on the same connection can be accepted. this.done.resolve(err); if (err) { // Error during responding, rethrow. throw err; } } async finalize() { if (this.finalized) { return; } // Consume unread body const body = this.body; const buf = new Uint8Array(1024); while ((await body.read(buf)) !== null) {} this.finalized = true; } }; exports_25("ServerRequest", ServerRequest); Server = class Server { constructor(listener) { this.listener = listener; this.closing = false; this.connections = []; } close() { this.closing = true; this.listener.close(); for (const conn of this.connections) { try { conn.close(); } catch (e) { // Connection might have been already closed if (!(e instanceof Deno.errors.BadResource)) { throw e; } } } } // Yields all HTTP requests on a single TCP connection. async *iterateHttpRequests(conn) { const reader = new bufio_ts_2.BufReader(conn); const writer = new bufio_ts_2.BufWriter(conn); while (!this.closing) { let request; try { request = await _io_ts_1.readRequest(conn, reader); } catch (error) { if ( error instanceof Deno.errors.InvalidData || error instanceof Deno.errors.UnexpectedEof ) { // An error was thrown while parsing request headers. await _io_ts_1.writeResponse(writer, { status: 400, body: utf8_ts_4.encode(`${error.message}\r\n\r\n`), }); } break; } if (request === null) { break; } request.w = writer; yield request; // Wait for the request to be processed before we accept a new request on // this connection. const responseError = await request.done; if (responseError) { // Something bad happened during response. // (likely other side closed during pipelined req) // req.done implies this connection already closed, so we can just return. this.untrackConnection(request.conn); return; } // Consume unread body and trailers if receiver didn't consume those data await request.finalize(); } this.untrackConnection(conn); try { conn.close(); } catch (e) { // might have been already closed } } trackConnection(conn) { this.connections.push(conn); } untrackConnection(conn) { const index = this.connections.indexOf(conn); if (index !== -1) { this.connections.splice(index, 1); } } // Accepts a new TCP connection and yields all HTTP requests that arrive on // it. When a connection is accepted, it also creates a new iterator of the // same kind and adds it to the request multiplexer so that another TCP // connection can be accepted. async *acceptConnAndIterateHttpRequests(mux) { if (this.closing) { return; } // Wait for a new connection. let conn; try { conn = await this.listener.accept(); } catch (error) { if (error instanceof Deno.errors.BadResource) { return; } throw error; } this.trackConnection(conn); // Try to accept another connection and add it to the multiplexer. mux.add(this.acceptConnAndIterateHttpRequests(mux)); // Yield the requests that arrive on the just-accepted connection. yield* this.iterateHttpRequests(conn); } [Symbol.asyncIterator]() { const mux = new mod_ts_4.MuxAsyncIterator(); mux.add(this.acceptConnAndIterateHttpRequests(mux)); return mux.iterate(); } }; exports_25("Server", Server); }, }; }, ); System.register( "file:///home/kou029w/deno-example/server", ["https://deno.land/std@0.56.0/http/server"], function (exports_26, context_26) { "use strict"; var server_ts_2; var __moduleName = context_26 && context_26.id; async function main() { const port = 8000; console.log(`http://localhost:${port}/`); for await (const req of server_ts_2.serve({ port })) { req.respond({ body: "Hello World\n" }); } } return { setters: [ function (server_ts_2_1) { server_ts_2 = server_ts_2_1; }, ], execute: function () { main(); }, }; }, ); __instantiate("file:///home/kou029w/deno-example/server");