#!/usr/bin/env node var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod2) => function __require2() { return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, mod2 )); // viewer/node_modules/is-node-process/lib/index.mjs function isNodeProcess() { if (typeof navigator !== "undefined" && navigator.product === "ReactNative") { return true; } if (typeof process !== "undefined") { const type = process.type; if (type === "renderer" || type === "worker") { return false; } return !!(process.versions && process.versions.node); } return false; } var init_lib = __esm({ "viewer/node_modules/is-node-process/lib/index.mjs"() { } }); // viewer/node_modules/is-buffer/index.js var require_is_buffer = __commonJS({ "viewer/node_modules/is-buffer/index.js"(exports, module) { module.exports = function isBuffer2(obj) { return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj); }; } }); // viewer/node_modules/retry/lib/retry_operation.js var require_retry_operation = __commonJS({ "viewer/node_modules/retry/lib/retry_operation.js"(exports, module) { function RetryOperation(timeouts, options) { if (typeof options === "boolean") { options = { forever: options }; } this._originalTimeouts = JSON.parse(JSON.stringify(timeouts)); this._timeouts = timeouts; this._options = options || {}; this._maxRetryTime = options && options.maxRetryTime || Infinity; this._fn = null; this._errors = []; this._attempts = 1; this._operationTimeout = null; this._operationTimeoutCb = null; this._timeout = null; this._operationStart = null; this._timer = null; if (this._options.forever) { this._cachedTimeouts = this._timeouts.slice(0); } } module.exports = RetryOperation; RetryOperation.prototype.reset = function() { this._attempts = 1; this._timeouts = this._originalTimeouts.slice(0); }; RetryOperation.prototype.stop = function() { if (this._timeout) { clearTimeout(this._timeout); } if (this._timer) { clearTimeout(this._timer); } this._timeouts = []; this._cachedTimeouts = null; }; RetryOperation.prototype.retry = function(err) { if (this._timeout) { clearTimeout(this._timeout); } if (!err) { return false; } var currentTime = (/* @__PURE__ */ new Date()).getTime(); if (err && currentTime - this._operationStart >= this._maxRetryTime) { this._errors.push(err); this._errors.unshift(new Error("RetryOperation timeout occurred")); return false; } this._errors.push(err); var timeout = this._timeouts.shift(); if (timeout === void 0) { if (this._cachedTimeouts) { this._errors.splice(0, this._errors.length - 1); timeout = this._cachedTimeouts.slice(-1); } else { return false; } } var self = this; this._timer = setTimeout(function() { self._attempts++; if (self._operationTimeoutCb) { self._timeout = setTimeout(function() { self._operationTimeoutCb(self._attempts); }, self._operationTimeout); if (self._options.unref) { self._timeout.unref(); } } self._fn(self._attempts); }, timeout); if (this._options.unref) { this._timer.unref(); } return true; }; RetryOperation.prototype.attempt = function(fn, timeoutOps) { this._fn = fn; if (timeoutOps) { if (timeoutOps.timeout) { this._operationTimeout = timeoutOps.timeout; } if (timeoutOps.cb) { this._operationTimeoutCb = timeoutOps.cb; } } var self = this; if (this._operationTimeoutCb) { this._timeout = setTimeout(function() { self._operationTimeoutCb(); }, self._operationTimeout); } this._operationStart = (/* @__PURE__ */ new Date()).getTime(); this._fn(this._attempts); }; RetryOperation.prototype.try = function(fn) { console.log("Using RetryOperation.try() is deprecated"); this.attempt(fn); }; RetryOperation.prototype.start = function(fn) { console.log("Using RetryOperation.start() is deprecated"); this.attempt(fn); }; RetryOperation.prototype.start = RetryOperation.prototype.try; RetryOperation.prototype.errors = function() { return this._errors; }; RetryOperation.prototype.attempts = function() { return this._attempts; }; RetryOperation.prototype.mainError = function() { if (this._errors.length === 0) { return null; } var counts = {}; var mainError = null; var mainErrorCount = 0; for (var i = 0; i < this._errors.length; i++) { var error = this._errors[i]; var message = error.message; var count = (counts[message] || 0) + 1; counts[message] = count; if (count >= mainErrorCount) { mainError = error; mainErrorCount = count; } } return mainError; }; } }); // viewer/node_modules/retry/lib/retry.js var require_retry = __commonJS({ "viewer/node_modules/retry/lib/retry.js"(exports) { var RetryOperation = require_retry_operation(); exports.operation = function(options) { var timeouts = exports.timeouts(options); return new RetryOperation(timeouts, { forever: options && (options.forever || options.retries === Infinity), unref: options && options.unref, maxRetryTime: options && options.maxRetryTime }); }; exports.timeouts = function(options) { if (options instanceof Array) { return [].concat(options); } var opts = { retries: 10, factor: 2, minTimeout: 1 * 1e3, maxTimeout: Infinity, randomize: false }; for (var key in options) { opts[key] = options[key]; } if (opts.minTimeout > opts.maxTimeout) { throw new Error("minTimeout is greater than maxTimeout"); } var timeouts = []; for (var i = 0; i < opts.retries; i++) { timeouts.push(this.createTimeout(i, opts)); } if (options && options.forever && !timeouts.length) { timeouts.push(this.createTimeout(i, opts)); } timeouts.sort(function(a, b) { return a - b; }); return timeouts; }; exports.createTimeout = function(attempt, opts) { var random = opts.randomize ? Math.random() + 1 : 1; var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt)); timeout = Math.min(timeout, opts.maxTimeout); return timeout; }; exports.wrap = function(obj, options, methods) { if (options instanceof Array) { methods = options; options = null; } if (!methods) { methods = []; for (var key in obj) { if (typeof obj[key] === "function") { methods.push(key); } } } for (var i = 0; i < methods.length; i++) { var method = methods[i]; var original = obj[method]; obj[method] = function retryWrapper(original2) { var op = exports.operation(options); var args = Array.prototype.slice.call(arguments, 1); var callback = args.pop(); args.push(function(err) { if (op.retry(err)) { return; } if (err) { arguments[0] = op.mainError(); } callback.apply(this, arguments); }); op.attempt(function() { original2.apply(obj, args); }); }.bind(obj, original); obj[method].options = options; } }; } }); // viewer/node_modules/retry/index.js var require_retry2 = __commonJS({ "viewer/node_modules/retry/index.js"(exports, module) { module.exports = require_retry(); } }); // viewer/node_modules/async-retry/lib/index.js var require_lib = __commonJS({ "viewer/node_modules/async-retry/lib/index.js"(exports, module) { var retrier = require_retry2(); function retry2(fn, opts) { function run(resolve, reject) { var options = opts || {}; var op; if (!("randomize" in options)) { options.randomize = true; } op = retrier.operation(options); function bail(err) { reject(err || new Error("Aborted")); } function onError(err, num) { if (err.bail) { bail(err); return; } if (!op.retry(err)) { reject(op.mainError()); } else if (options.onRetry) { options.onRetry(err, num); } } function runAttempt(num) { var val; try { val = fn(bail, num); } catch (err) { onError(err, num); return; } Promise.resolve(val).then(resolve).catch(function catchIt(err) { onError(err, num); }); } op.attempt(runAttempt); } return new Promise(run); } module.exports = retry2; } }); // viewer/node_modules/undici/lib/core/symbols.js var require_symbols = __commonJS({ "viewer/node_modules/undici/lib/core/symbols.js"(exports, module) { module.exports = { kClose: /* @__PURE__ */ Symbol("close"), kDestroy: /* @__PURE__ */ Symbol("destroy"), kDispatch: /* @__PURE__ */ Symbol("dispatch"), kUrl: /* @__PURE__ */ Symbol("url"), kWriting: /* @__PURE__ */ Symbol("writing"), kResuming: /* @__PURE__ */ Symbol("resuming"), kQueue: /* @__PURE__ */ Symbol("queue"), kConnect: /* @__PURE__ */ Symbol("connect"), kConnecting: /* @__PURE__ */ Symbol("connecting"), kKeepAliveDefaultTimeout: /* @__PURE__ */ Symbol("default keep alive timeout"), kKeepAliveMaxTimeout: /* @__PURE__ */ Symbol("max keep alive timeout"), kKeepAliveTimeoutThreshold: /* @__PURE__ */ Symbol("keep alive timeout threshold"), kKeepAliveTimeoutValue: /* @__PURE__ */ Symbol("keep alive timeout"), kKeepAlive: /* @__PURE__ */ Symbol("keep alive"), kHeadersTimeout: /* @__PURE__ */ Symbol("headers timeout"), kBodyTimeout: /* @__PURE__ */ Symbol("body timeout"), kServerName: /* @__PURE__ */ Symbol("server name"), kLocalAddress: /* @__PURE__ */ Symbol("local address"), kHost: /* @__PURE__ */ Symbol("host"), kNoRef: /* @__PURE__ */ Symbol("no ref"), kBodyUsed: /* @__PURE__ */ Symbol("used"), kBody: /* @__PURE__ */ Symbol("abstracted request body"), kRunning: /* @__PURE__ */ Symbol("running"), kBlocking: /* @__PURE__ */ Symbol("blocking"), kPending: /* @__PURE__ */ Symbol("pending"), kSize: /* @__PURE__ */ Symbol("size"), kBusy: /* @__PURE__ */ Symbol("busy"), kQueued: /* @__PURE__ */ Symbol("queued"), kFree: /* @__PURE__ */ Symbol("free"), kConnected: /* @__PURE__ */ Symbol("connected"), kClosed: /* @__PURE__ */ Symbol("closed"), kNeedDrain: /* @__PURE__ */ Symbol("need drain"), kReset: /* @__PURE__ */ Symbol("reset"), kDestroyed: /* @__PURE__ */ Symbol.for("nodejs.stream.destroyed"), kResume: /* @__PURE__ */ Symbol("resume"), kOnError: /* @__PURE__ */ Symbol("on error"), kMaxHeadersSize: /* @__PURE__ */ Symbol("max headers size"), kRunningIdx: /* @__PURE__ */ Symbol("running index"), kPendingIdx: /* @__PURE__ */ Symbol("pending index"), kError: /* @__PURE__ */ Symbol("error"), kClients: /* @__PURE__ */ Symbol("clients"), kClient: /* @__PURE__ */ Symbol("client"), kParser: /* @__PURE__ */ Symbol("parser"), kOnDestroyed: /* @__PURE__ */ Symbol("destroy callbacks"), kPipelining: /* @__PURE__ */ Symbol("pipelining"), kSocket: /* @__PURE__ */ Symbol("socket"), kHostHeader: /* @__PURE__ */ Symbol("host header"), kConnector: /* @__PURE__ */ Symbol("connector"), kStrictContentLength: /* @__PURE__ */ Symbol("strict content length"), kMaxRedirections: /* @__PURE__ */ Symbol("maxRedirections"), kMaxRequests: /* @__PURE__ */ Symbol("maxRequestsPerClient"), kProxy: /* @__PURE__ */ Symbol("proxy agent options"), kCounter: /* @__PURE__ */ Symbol("socket request counter"), kInterceptors: /* @__PURE__ */ Symbol("dispatch interceptors"), kMaxResponseSize: /* @__PURE__ */ Symbol("max response size"), kHTTP2Session: /* @__PURE__ */ Symbol("http2Session"), kHTTP2SessionState: /* @__PURE__ */ Symbol("http2Session state"), kRetryHandlerDefaultRetry: /* @__PURE__ */ Symbol("retry agent default retry"), kConstruct: /* @__PURE__ */ Symbol("constructable"), kListeners: /* @__PURE__ */ Symbol("listeners"), kHTTPContext: /* @__PURE__ */ Symbol("http context"), kMaxConcurrentStreams: /* @__PURE__ */ Symbol("max concurrent streams"), kNoProxyAgent: /* @__PURE__ */ Symbol("no proxy agent"), kHttpProxyAgent: /* @__PURE__ */ Symbol("http proxy agent"), kHttpsProxyAgent: /* @__PURE__ */ Symbol("https proxy agent") }; } }); // viewer/node_modules/undici/lib/core/errors.js var require_errors = __commonJS({ "viewer/node_modules/undici/lib/core/errors.js"(exports, module) { "use strict"; var kUndiciError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR"); var UndiciError = class extends Error { constructor(message) { super(message); this.name = "UndiciError"; this.code = "UND_ERR"; } static [Symbol.hasInstance](instance) { return instance && instance[kUndiciError] === true; } [kUndiciError] = true; }; var kConnectTimeoutError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_CONNECT_TIMEOUT"); var ConnectTimeoutError = class extends UndiciError { constructor(message) { super(message); this.name = "ConnectTimeoutError"; this.message = message || "Connect Timeout Error"; this.code = "UND_ERR_CONNECT_TIMEOUT"; } static [Symbol.hasInstance](instance) { return instance && instance[kConnectTimeoutError] === true; } [kConnectTimeoutError] = true; }; var kHeadersTimeoutError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_HEADERS_TIMEOUT"); var HeadersTimeoutError = class extends UndiciError { constructor(message) { super(message); this.name = "HeadersTimeoutError"; this.message = message || "Headers Timeout Error"; this.code = "UND_ERR_HEADERS_TIMEOUT"; } static [Symbol.hasInstance](instance) { return instance && instance[kHeadersTimeoutError] === true; } [kHeadersTimeoutError] = true; }; var kHeadersOverflowError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_HEADERS_OVERFLOW"); var HeadersOverflowError = class extends UndiciError { constructor(message) { super(message); this.name = "HeadersOverflowError"; this.message = message || "Headers Overflow Error"; this.code = "UND_ERR_HEADERS_OVERFLOW"; } static [Symbol.hasInstance](instance) { return instance && instance[kHeadersOverflowError] === true; } [kHeadersOverflowError] = true; }; var kBodyTimeoutError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_BODY_TIMEOUT"); var BodyTimeoutError = class extends UndiciError { constructor(message) { super(message); this.name = "BodyTimeoutError"; this.message = message || "Body Timeout Error"; this.code = "UND_ERR_BODY_TIMEOUT"; } static [Symbol.hasInstance](instance) { return instance && instance[kBodyTimeoutError] === true; } [kBodyTimeoutError] = true; }; var kResponseStatusCodeError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_RESPONSE_STATUS_CODE"); var ResponseStatusCodeError = class extends UndiciError { constructor(message, statusCode, headers, body) { super(message); this.name = "ResponseStatusCodeError"; this.message = message || "Response Status Code Error"; this.code = "UND_ERR_RESPONSE_STATUS_CODE"; this.body = body; this.status = statusCode; this.statusCode = statusCode; this.headers = headers; } static [Symbol.hasInstance](instance) { return instance && instance[kResponseStatusCodeError] === true; } [kResponseStatusCodeError] = true; }; var kInvalidArgumentError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_INVALID_ARG"); var InvalidArgumentError = class extends UndiciError { constructor(message) { super(message); this.name = "InvalidArgumentError"; this.message = message || "Invalid Argument Error"; this.code = "UND_ERR_INVALID_ARG"; } static [Symbol.hasInstance](instance) { return instance && instance[kInvalidArgumentError] === true; } [kInvalidArgumentError] = true; }; var kInvalidReturnValueError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_INVALID_RETURN_VALUE"); var InvalidReturnValueError = class extends UndiciError { constructor(message) { super(message); this.name = "InvalidReturnValueError"; this.message = message || "Invalid Return Value Error"; this.code = "UND_ERR_INVALID_RETURN_VALUE"; } static [Symbol.hasInstance](instance) { return instance && instance[kInvalidReturnValueError] === true; } [kInvalidReturnValueError] = true; }; var kAbortError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_ABORT"); var AbortError = class extends UndiciError { constructor(message) { super(message); this.name = "AbortError"; this.message = message || "The operation was aborted"; this.code = "UND_ERR_ABORT"; } static [Symbol.hasInstance](instance) { return instance && instance[kAbortError] === true; } [kAbortError] = true; }; var kRequestAbortedError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_ABORTED"); var RequestAbortedError = class extends AbortError { constructor(message) { super(message); this.name = "AbortError"; this.message = message || "Request aborted"; this.code = "UND_ERR_ABORTED"; } static [Symbol.hasInstance](instance) { return instance && instance[kRequestAbortedError] === true; } [kRequestAbortedError] = true; }; var kInformationalError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_INFO"); var InformationalError = class extends UndiciError { constructor(message) { super(message); this.name = "InformationalError"; this.message = message || "Request information"; this.code = "UND_ERR_INFO"; } static [Symbol.hasInstance](instance) { return instance && instance[kInformationalError] === true; } [kInformationalError] = true; }; var kRequestContentLengthMismatchError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_REQ_CONTENT_LENGTH_MISMATCH"); var RequestContentLengthMismatchError = class extends UndiciError { constructor(message) { super(message); this.name = "RequestContentLengthMismatchError"; this.message = message || "Request body length does not match content-length header"; this.code = "UND_ERR_REQ_CONTENT_LENGTH_MISMATCH"; } static [Symbol.hasInstance](instance) { return instance && instance[kRequestContentLengthMismatchError] === true; } [kRequestContentLengthMismatchError] = true; }; var kResponseContentLengthMismatchError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_RES_CONTENT_LENGTH_MISMATCH"); var ResponseContentLengthMismatchError = class extends UndiciError { constructor(message) { super(message); this.name = "ResponseContentLengthMismatchError"; this.message = message || "Response body length does not match content-length header"; this.code = "UND_ERR_RES_CONTENT_LENGTH_MISMATCH"; } static [Symbol.hasInstance](instance) { return instance && instance[kResponseContentLengthMismatchError] === true; } [kResponseContentLengthMismatchError] = true; }; var kClientDestroyedError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_DESTROYED"); var ClientDestroyedError = class extends UndiciError { constructor(message) { super(message); this.name = "ClientDestroyedError"; this.message = message || "The client is destroyed"; this.code = "UND_ERR_DESTROYED"; } static [Symbol.hasInstance](instance) { return instance && instance[kClientDestroyedError] === true; } [kClientDestroyedError] = true; }; var kClientClosedError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_CLOSED"); var ClientClosedError = class extends UndiciError { constructor(message) { super(message); this.name = "ClientClosedError"; this.message = message || "The client is closed"; this.code = "UND_ERR_CLOSED"; } static [Symbol.hasInstance](instance) { return instance && instance[kClientClosedError] === true; } [kClientClosedError] = true; }; var kSocketError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_SOCKET"); var SocketError = class extends UndiciError { constructor(message, socket) { super(message); this.name = "SocketError"; this.message = message || "Socket error"; this.code = "UND_ERR_SOCKET"; this.socket = socket; } static [Symbol.hasInstance](instance) { return instance && instance[kSocketError] === true; } [kSocketError] = true; }; var kNotSupportedError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_NOT_SUPPORTED"); var NotSupportedError = class extends UndiciError { constructor(message) { super(message); this.name = "NotSupportedError"; this.message = message || "Not supported error"; this.code = "UND_ERR_NOT_SUPPORTED"; } static [Symbol.hasInstance](instance) { return instance && instance[kNotSupportedError] === true; } [kNotSupportedError] = true; }; var kBalancedPoolMissingUpstreamError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_BPL_MISSING_UPSTREAM"); var BalancedPoolMissingUpstreamError = class extends UndiciError { constructor(message) { super(message); this.name = "MissingUpstreamError"; this.message = message || "No upstream has been added to the BalancedPool"; this.code = "UND_ERR_BPL_MISSING_UPSTREAM"; } static [Symbol.hasInstance](instance) { return instance && instance[kBalancedPoolMissingUpstreamError] === true; } [kBalancedPoolMissingUpstreamError] = true; }; var kHTTPParserError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_HTTP_PARSER"); var HTTPParserError = class extends Error { constructor(message, code, data) { super(message); this.name = "HTTPParserError"; this.code = code ? `HPE_${code}` : void 0; this.data = data ? data.toString() : void 0; } static [Symbol.hasInstance](instance) { return instance && instance[kHTTPParserError] === true; } [kHTTPParserError] = true; }; var kResponseExceededMaxSizeError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_RES_EXCEEDED_MAX_SIZE"); var ResponseExceededMaxSizeError = class extends UndiciError { constructor(message) { super(message); this.name = "ResponseExceededMaxSizeError"; this.message = message || "Response content exceeded max size"; this.code = "UND_ERR_RES_EXCEEDED_MAX_SIZE"; } static [Symbol.hasInstance](instance) { return instance && instance[kResponseExceededMaxSizeError] === true; } [kResponseExceededMaxSizeError] = true; }; var kRequestRetryError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_REQ_RETRY"); var RequestRetryError = class extends UndiciError { constructor(message, code, { headers, data }) { super(message); this.name = "RequestRetryError"; this.message = message || "Request retry error"; this.code = "UND_ERR_REQ_RETRY"; this.statusCode = code; this.data = data; this.headers = headers; } static [Symbol.hasInstance](instance) { return instance && instance[kRequestRetryError] === true; } [kRequestRetryError] = true; }; var kResponseError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_RESPONSE"); var ResponseError = class extends UndiciError { constructor(message, code, { headers, data }) { super(message); this.name = "ResponseError"; this.message = message || "Response error"; this.code = "UND_ERR_RESPONSE"; this.statusCode = code; this.data = data; this.headers = headers; } static [Symbol.hasInstance](instance) { return instance && instance[kResponseError] === true; } [kResponseError] = true; }; var kSecureProxyConnectionError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_PRX_TLS"); var SecureProxyConnectionError = class extends UndiciError { constructor(cause, message, options) { super(message, { cause, ...options ?? {} }); this.name = "SecureProxyConnectionError"; this.message = message || "Secure Proxy Connection failed"; this.code = "UND_ERR_PRX_TLS"; this.cause = cause; } static [Symbol.hasInstance](instance) { return instance && instance[kSecureProxyConnectionError] === true; } [kSecureProxyConnectionError] = true; }; var kMessageSizeExceededError = /* @__PURE__ */ Symbol.for("undici.error.UND_ERR_WS_MESSAGE_SIZE_EXCEEDED"); var MessageSizeExceededError = class extends UndiciError { constructor(message) { super(message); this.name = "MessageSizeExceededError"; this.message = message || "Max decompressed message size exceeded"; this.code = "UND_ERR_WS_MESSAGE_SIZE_EXCEEDED"; } static [Symbol.hasInstance](instance) { return instance && instance[kMessageSizeExceededError] === true; } get [kMessageSizeExceededError]() { return true; } }; module.exports = { AbortError, HTTPParserError, UndiciError, HeadersTimeoutError, HeadersOverflowError, BodyTimeoutError, RequestContentLengthMismatchError, ConnectTimeoutError, ResponseStatusCodeError, InvalidArgumentError, InvalidReturnValueError, RequestAbortedError, ClientDestroyedError, ClientClosedError, InformationalError, SocketError, NotSupportedError, ResponseContentLengthMismatchError, BalancedPoolMissingUpstreamError, ResponseExceededMaxSizeError, RequestRetryError, ResponseError, SecureProxyConnectionError, MessageSizeExceededError }; } }); // viewer/node_modules/undici/lib/core/constants.js var require_constants = __commonJS({ "viewer/node_modules/undici/lib/core/constants.js"(exports, module) { "use strict"; var headerNameLowerCasedRecord = {}; var wellknownHeaderNames = [ "Accept", "Accept-Encoding", "Accept-Language", "Accept-Ranges", "Access-Control-Allow-Credentials", "Access-Control-Allow-Headers", "Access-Control-Allow-Methods", "Access-Control-Allow-Origin", "Access-Control-Expose-Headers", "Access-Control-Max-Age", "Access-Control-Request-Headers", "Access-Control-Request-Method", "Age", "Allow", "Alt-Svc", "Alt-Used", "Authorization", "Cache-Control", "Clear-Site-Data", "Connection", "Content-Disposition", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-Range", "Content-Security-Policy", "Content-Security-Policy-Report-Only", "Content-Type", "Cookie", "Cross-Origin-Embedder-Policy", "Cross-Origin-Opener-Policy", "Cross-Origin-Resource-Policy", "Date", "Device-Memory", "Downlink", "ECT", "ETag", "Expect", "Expect-CT", "Expires", "Forwarded", "From", "Host", "If-Match", "If-Modified-Since", "If-None-Match", "If-Range", "If-Unmodified-Since", "Keep-Alive", "Last-Modified", "Link", "Location", "Max-Forwards", "Origin", "Permissions-Policy", "Pragma", "Proxy-Authenticate", "Proxy-Authorization", "RTT", "Range", "Referer", "Referrer-Policy", "Refresh", "Retry-After", "Sec-WebSocket-Accept", "Sec-WebSocket-Extensions", "Sec-WebSocket-Key", "Sec-WebSocket-Protocol", "Sec-WebSocket-Version", "Server", "Server-Timing", "Service-Worker-Allowed", "Service-Worker-Navigation-Preload", "Set-Cookie", "SourceMap", "Strict-Transport-Security", "Supports-Loading-Mode", "TE", "Timing-Allow-Origin", "Trailer", "Transfer-Encoding", "Upgrade", "Upgrade-Insecure-Requests", "User-Agent", "Vary", "Via", "WWW-Authenticate", "X-Content-Type-Options", "X-DNS-Prefetch-Control", "X-Frame-Options", "X-Permitted-Cross-Domain-Policies", "X-Powered-By", "X-Requested-With", "X-XSS-Protection" ]; for (let i = 0; i < wellknownHeaderNames.length; ++i) { const key = wellknownHeaderNames[i]; const lowerCasedKey = key.toLowerCase(); headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] = lowerCasedKey; } Object.setPrototypeOf(headerNameLowerCasedRecord, null); module.exports = { wellknownHeaderNames, headerNameLowerCasedRecord }; } }); // viewer/node_modules/undici/lib/core/tree.js var require_tree = __commonJS({ "viewer/node_modules/undici/lib/core/tree.js"(exports, module) { "use strict"; var { wellknownHeaderNames, headerNameLowerCasedRecord } = require_constants(); var TstNode = class _TstNode { /** @type {any} */ value = null; /** @type {null | TstNode} */ left = null; /** @type {null | TstNode} */ middle = null; /** @type {null | TstNode} */ right = null; /** @type {number} */ code; /** * @param {string} key * @param {any} value * @param {number} index */ constructor(key, value, index) { if (index === void 0 || index >= key.length) { throw new TypeError("Unreachable"); } const code = this.code = key.charCodeAt(index); if (code > 127) { throw new TypeError("key must be ascii string"); } if (key.length !== ++index) { this.middle = new _TstNode(key, value, index); } else { this.value = value; } } /** * @param {string} key * @param {any} value */ add(key, value) { const length2 = key.length; if (length2 === 0) { throw new TypeError("Unreachable"); } let index = 0; let node = this; while (true) { const code = key.charCodeAt(index); if (code > 127) { throw new TypeError("key must be ascii string"); } if (node.code === code) { if (length2 === ++index) { node.value = value; break; } else if (node.middle !== null) { node = node.middle; } else { node.middle = new _TstNode(key, value, index); break; } } else if (node.code < code) { if (node.left !== null) { node = node.left; } else { node.left = new _TstNode(key, value, index); break; } } else if (node.right !== null) { node = node.right; } else { node.right = new _TstNode(key, value, index); break; } } } /** * @param {Uint8Array} key * @return {TstNode | null} */ search(key) { const keylength = key.length; let index = 0; let node = this; while (node !== null && index < keylength) { let code = key[index]; if (code <= 90 && code >= 65) { code |= 32; } while (node !== null) { if (code === node.code) { if (keylength === ++index) { return node; } node = node.middle; break; } node = node.code < code ? node.left : node.right; } } return null; } }; var TernarySearchTree = class { /** @type {TstNode | null} */ node = null; /** * @param {string} key * @param {any} value * */ insert(key, value) { if (this.node === null) { this.node = new TstNode(key, value, 0); } else { this.node.add(key, value); } } /** * @param {Uint8Array} key * @return {any} */ lookup(key) { return this.node?.search(key)?.value ?? null; } }; var tree = new TernarySearchTree(); for (let i = 0; i < wellknownHeaderNames.length; ++i) { const key = headerNameLowerCasedRecord[wellknownHeaderNames[i]]; tree.insert(key, key); } module.exports = { TernarySearchTree, tree }; } }); // viewer/node_modules/undici/lib/core/util.js var require_util = __commonJS({ "viewer/node_modules/undici/lib/core/util.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { kDestroyed, kBodyUsed, kListeners, kBody } = require_symbols(); var { IncomingMessage } = __require("node:http"); var stream = __require("node:stream"); var net = __require("node:net"); var { Blob: Blob2 } = __require("node:buffer"); var nodeUtil = __require("node:util"); var { stringify } = __require("node:querystring"); var { EventEmitter: EE } = __require("node:events"); var { InvalidArgumentError } = require_errors(); var { headerNameLowerCasedRecord } = require_constants(); var { tree } = require_tree(); var [nodeMajor, nodeMinor] = process.versions.node.split(".").map((v) => Number(v)); var BodyAsyncIterable = class { constructor(body) { this[kBody] = body; this[kBodyUsed] = false; } async *[Symbol.asyncIterator]() { assert(!this[kBodyUsed], "disturbed"); this[kBodyUsed] = true; yield* this[kBody]; } }; function wrapRequestBody(body) { if (isStream2(body)) { if (bodyLength(body) === 0) { body.on("data", function() { assert(false); }); } if (typeof body.readableDidRead !== "boolean") { body[kBodyUsed] = false; EE.prototype.on.call(body, "data", function() { this[kBodyUsed] = true; }); } return body; } else if (body && typeof body.pipeTo === "function") { return new BodyAsyncIterable(body); } else if (body && typeof body !== "string" && !ArrayBuffer.isView(body) && isIterable(body)) { return new BodyAsyncIterable(body); } else { return body; } } function nop() { } function isStream2(obj) { return obj && typeof obj === "object" && typeof obj.pipe === "function" && typeof obj.on === "function"; } function isBlobLike(object) { if (object === null) { return false; } else if (object instanceof Blob2) { return true; } else if (typeof object !== "object") { return false; } else { const sTag = object[Symbol.toStringTag]; return (sTag === "Blob" || sTag === "File") && ("stream" in object && typeof object.stream === "function" || "arrayBuffer" in object && typeof object.arrayBuffer === "function"); } } function buildURL(url, queryParams) { if (url.includes("?") || url.includes("#")) { throw new Error('Query params cannot be passed when url already contains "?" or "#".'); } const stringified = stringify(queryParams); if (stringified) { url += "?" + stringified; } return url; } function isValidPort(port2) { const value = parseInt(port2, 10); return value === Number(port2) && value >= 0 && value <= 65535; } function isHttpOrHttpsPrefixed(value) { return value != null && value[0] === "h" && value[1] === "t" && value[2] === "t" && value[3] === "p" && (value[4] === ":" || value[4] === "s" && value[5] === ":"); } function parseURL(url) { if (typeof url === "string") { url = new URL(url); if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`."); } return url; } if (!url || typeof url !== "object") { throw new InvalidArgumentError("Invalid URL: The URL argument must be a non-null object."); } if (!(url instanceof URL)) { if (url.port != null && url.port !== "" && isValidPort(url.port) === false) { throw new InvalidArgumentError("Invalid URL: port must be a valid integer or a string representation of an integer."); } if (url.path != null && typeof url.path !== "string") { throw new InvalidArgumentError("Invalid URL path: the path must be a string or null/undefined."); } if (url.pathname != null && typeof url.pathname !== "string") { throw new InvalidArgumentError("Invalid URL pathname: the pathname must be a string or null/undefined."); } if (url.hostname != null && typeof url.hostname !== "string") { throw new InvalidArgumentError("Invalid URL hostname: the hostname must be a string or null/undefined."); } if (url.origin != null && typeof url.origin !== "string") { throw new InvalidArgumentError("Invalid URL origin: the origin must be a string or null/undefined."); } if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`."); } const port2 = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80; let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port2}`; let path14 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`; if (origin[origin.length - 1] === "/") { origin = origin.slice(0, origin.length - 1); } if (path14 && path14[0] !== "/") { path14 = `/${path14}`; } return new URL(`${origin}${path14}`); } if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`."); } return url; } function parseOrigin(url) { url = parseURL(url); if (url.pathname !== "/" || url.search || url.hash) { throw new InvalidArgumentError("invalid url"); } return url; } function getHostname(host2) { if (host2[0] === "[") { const idx2 = host2.indexOf("]"); assert(idx2 !== -1); return host2.substring(1, idx2); } const idx = host2.indexOf(":"); if (idx === -1) return host2; return host2.substring(0, idx); } function getServerName(host2) { if (!host2) { return null; } assert(typeof host2 === "string"); const servername = getHostname(host2); if (net.isIP(servername)) { return ""; } return servername; } function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); } function isAsyncIterable(obj) { return !!(obj != null && typeof obj[Symbol.asyncIterator] === "function"); } function isIterable(obj) { return !!(obj != null && (typeof obj[Symbol.iterator] === "function" || typeof obj[Symbol.asyncIterator] === "function")); } function bodyLength(body) { if (body == null) { return 0; } else if (isStream2(body)) { const state = body._readableState; return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) ? state.length : null; } else if (isBlobLike(body)) { return body.size != null ? body.size : null; } else if (isBuffer2(body)) { return body.byteLength; } return null; } function isDestroyed(body) { return body && !!(body.destroyed || body[kDestroyed] || stream.isDestroyed?.(body)); } function destroy(stream2, err) { if (stream2 == null || !isStream2(stream2) || isDestroyed(stream2)) { return; } if (typeof stream2.destroy === "function") { if (Object.getPrototypeOf(stream2).constructor === IncomingMessage) { stream2.socket = null; } stream2.destroy(err); } else if (err) { queueMicrotask(() => { stream2.emit("error", err); }); } if (stream2.destroyed !== true) { stream2[kDestroyed] = true; } } var KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/; function parseKeepAliveTimeout(val) { const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR); return m ? parseInt(m[1], 10) * 1e3 : null; } function headerNameToString(value) { return typeof value === "string" ? headerNameLowerCasedRecord[value] ?? value.toLowerCase() : tree.lookup(value) ?? value.toString("latin1").toLowerCase(); } function bufferToLowerCasedHeaderName(value) { return tree.lookup(value) ?? value.toString("latin1").toLowerCase(); } function parseHeaders(headers, obj) { if (obj === void 0) obj = {}; for (let i = 0; i < headers.length; i += 2) { const key = headerNameToString(headers[i]); let val = obj[key]; if (val) { if (typeof val === "string") { val = [val]; obj[key] = val; } val.push(headers[i + 1].toString("utf8")); } else { const headersValue = headers[i + 1]; if (typeof headersValue === "string") { obj[key] = headersValue; } else { obj[key] = Array.isArray(headersValue) ? headersValue.map((x) => x.toString("utf8")) : headersValue.toString("utf8"); } } } if ("content-length" in obj && "content-disposition" in obj) { obj["content-disposition"] = Buffer.from(obj["content-disposition"]).toString("latin1"); } return obj; } function parseRawHeaders(headers) { const len = headers.length; const ret = new Array(len); let hasContentLength = false; let contentDispositionIdx = -1; let key; let val; let kLen = 0; for (let n = 0; n < headers.length; n += 2) { key = headers[n]; val = headers[n + 1]; typeof key !== "string" && (key = key.toString()); typeof val !== "string" && (val = val.toString("utf8")); kLen = key.length; if (kLen === 14 && key[7] === "-" && (key === "content-length" || key.toLowerCase() === "content-length")) { hasContentLength = true; } else if (kLen === 19 && key[7] === "-" && (key === "content-disposition" || key.toLowerCase() === "content-disposition")) { contentDispositionIdx = n + 1; } ret[n] = key; ret[n + 1] = val; } if (hasContentLength && contentDispositionIdx !== -1) { ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString("latin1"); } return ret; } function isBuffer2(buffer) { return buffer instanceof Uint8Array || Buffer.isBuffer(buffer); } function validateHandler(handler, method, upgrade) { if (!handler || typeof handler !== "object") { throw new InvalidArgumentError("handler must be an object"); } if (typeof handler.onConnect !== "function") { throw new InvalidArgumentError("invalid onConnect method"); } if (typeof handler.onError !== "function") { throw new InvalidArgumentError("invalid onError method"); } if (typeof handler.onBodySent !== "function" && handler.onBodySent !== void 0) { throw new InvalidArgumentError("invalid onBodySent method"); } if (upgrade || method === "CONNECT") { if (typeof handler.onUpgrade !== "function") { throw new InvalidArgumentError("invalid onUpgrade method"); } } else { if (typeof handler.onHeaders !== "function") { throw new InvalidArgumentError("invalid onHeaders method"); } if (typeof handler.onData !== "function") { throw new InvalidArgumentError("invalid onData method"); } if (typeof handler.onComplete !== "function") { throw new InvalidArgumentError("invalid onComplete method"); } } } function isDisturbed(body) { return !!(body && (stream.isDisturbed(body) || body[kBodyUsed])); } function isErrored(body) { return !!(body && stream.isErrored(body)); } function isReadable(body) { return !!(body && stream.isReadable(body)); } function getSocketInfo(socket) { return { localAddress: socket.localAddress, localPort: socket.localPort, remoteAddress: socket.remoteAddress, remotePort: socket.remotePort, remoteFamily: socket.remoteFamily, timeout: socket.timeout, bytesWritten: socket.bytesWritten, bytesRead: socket.bytesRead }; } function ReadableStreamFrom(iterable) { let iterator; return new ReadableStream( { async start() { iterator = iterable[Symbol.asyncIterator](); }, async pull(controller) { const { done, value } = await iterator.next(); if (done) { queueMicrotask(() => { controller.close(); controller.byobRequest?.respond(0); }); } else { const buf = Buffer.isBuffer(value) ? value : Buffer.from(value); if (buf.byteLength) { controller.enqueue(new Uint8Array(buf)); } } return controller.desiredSize > 0; }, async cancel(reason) { await iterator.return(); }, type: "bytes" } ); } function isFormDataLike(object) { return object && typeof object === "object" && typeof object.append === "function" && typeof object.delete === "function" && typeof object.get === "function" && typeof object.getAll === "function" && typeof object.has === "function" && typeof object.set === "function" && object[Symbol.toStringTag] === "FormData"; } function addAbortListener(signal, listener) { if ("addEventListener" in signal) { signal.addEventListener("abort", listener, { once: true }); return () => signal.removeEventListener("abort", listener); } signal.addListener("abort", listener); return () => signal.removeListener("abort", listener); } var hasToWellFormed = typeof String.prototype.toWellFormed === "function"; var hasIsWellFormed = typeof String.prototype.isWellFormed === "function"; function toUSVString(val) { return hasToWellFormed ? `${val}`.toWellFormed() : nodeUtil.toUSVString(val); } function isUSVString(val) { return hasIsWellFormed ? `${val}`.isWellFormed() : toUSVString(val) === `${val}`; } function isTokenCharCode(c) { switch (c) { case 34: case 40: case 41: case 44: case 47: case 58: case 59: case 60: case 61: case 62: case 63: case 64: case 91: case 92: case 93: case 123: case 125: return false; default: return c >= 33 && c <= 126; } } function isValidHTTPToken(characters) { if (characters.length === 0) { return false; } for (let i = 0; i < characters.length; ++i) { if (!isTokenCharCode(characters.charCodeAt(i))) { return false; } } return true; } var headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; function isValidHeaderValue(characters) { return !headerCharRegex.test(characters); } function parseRangeHeader(range) { if (range == null || range === "") return { start: 0, end: null, size: null }; const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null; return m ? { start: parseInt(m[1]), end: m[2] ? parseInt(m[2]) : null, size: m[3] ? parseInt(m[3]) : null } : null; } function addListener(obj, name, listener) { const listeners = obj[kListeners] ??= []; listeners.push([name, listener]); obj.on(name, listener); return obj; } function removeAllListeners(obj) { for (const [name, listener] of obj[kListeners] ?? []) { obj.removeListener(name, listener); } obj[kListeners] = null; } function errorRequest(client, request, err) { try { request.onError(err); assert(request.aborted); } catch (err2) { client.emit("error", err2); } } var kEnumerableProperty = /* @__PURE__ */ Object.create(null); kEnumerableProperty.enumerable = true; var normalizedMethodRecordsBase = { delete: "DELETE", DELETE: "DELETE", get: "GET", GET: "GET", head: "HEAD", HEAD: "HEAD", options: "OPTIONS", OPTIONS: "OPTIONS", post: "POST", POST: "POST", put: "PUT", PUT: "PUT" }; var normalizedMethodRecords = { ...normalizedMethodRecordsBase, patch: "patch", PATCH: "PATCH" }; Object.setPrototypeOf(normalizedMethodRecordsBase, null); Object.setPrototypeOf(normalizedMethodRecords, null); module.exports = { kEnumerableProperty, nop, isDisturbed, isErrored, isReadable, toUSVString, isUSVString, isBlobLike, parseOrigin, parseURL, getServerName, isStream: isStream2, isIterable, isAsyncIterable, isDestroyed, headerNameToString, bufferToLowerCasedHeaderName, addListener, removeAllListeners, errorRequest, parseRawHeaders, parseHeaders, parseKeepAliveTimeout, destroy, bodyLength, deepClone, ReadableStreamFrom, isBuffer: isBuffer2, validateHandler, getSocketInfo, isFormDataLike, buildURL, addAbortListener, isValidHTTPToken, isValidHeaderValue, isTokenCharCode, parseRangeHeader, normalizedMethodRecordsBase, normalizedMethodRecords, isValidPort, isHttpOrHttpsPrefixed, nodeMajor, nodeMinor, safeHTTPMethods: ["GET", "HEAD", "OPTIONS", "TRACE"], wrapRequestBody }; } }); // viewer/node_modules/undici/lib/core/diagnostics.js var require_diagnostics = __commonJS({ "viewer/node_modules/undici/lib/core/diagnostics.js"(exports, module) { "use strict"; var diagnosticsChannel = __require("node:diagnostics_channel"); var util = __require("node:util"); var undiciDebugLog = util.debuglog("undici"); var fetchDebuglog = util.debuglog("fetch"); var websocketDebuglog = util.debuglog("websocket"); var isClientSet = false; var channels = { // Client beforeConnect: diagnosticsChannel.channel("undici:client:beforeConnect"), connected: diagnosticsChannel.channel("undici:client:connected"), connectError: diagnosticsChannel.channel("undici:client:connectError"), sendHeaders: diagnosticsChannel.channel("undici:client:sendHeaders"), // Request create: diagnosticsChannel.channel("undici:request:create"), bodySent: diagnosticsChannel.channel("undici:request:bodySent"), headers: diagnosticsChannel.channel("undici:request:headers"), trailers: diagnosticsChannel.channel("undici:request:trailers"), error: diagnosticsChannel.channel("undici:request:error"), // WebSocket open: diagnosticsChannel.channel("undici:websocket:open"), close: diagnosticsChannel.channel("undici:websocket:close"), socketError: diagnosticsChannel.channel("undici:websocket:socket_error"), ping: diagnosticsChannel.channel("undici:websocket:ping"), pong: diagnosticsChannel.channel("undici:websocket:pong") }; if (undiciDebugLog.enabled || fetchDebuglog.enabled) { const debuglog = fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog; diagnosticsChannel.channel("undici:client:beforeConnect").subscribe((evt) => { const { connectParams: { version, protocol, port: port2, host: host2 } } = evt; debuglog( "connecting to %s using %s%s", `${host2}${port2 ? `:${port2}` : ""}`, protocol, version ); }); diagnosticsChannel.channel("undici:client:connected").subscribe((evt) => { const { connectParams: { version, protocol, port: port2, host: host2 } } = evt; debuglog( "connected to %s using %s%s", `${host2}${port2 ? `:${port2}` : ""}`, protocol, version ); }); diagnosticsChannel.channel("undici:client:connectError").subscribe((evt) => { const { connectParams: { version, protocol, port: port2, host: host2 }, error } = evt; debuglog( "connection to %s using %s%s errored - %s", `${host2}${port2 ? `:${port2}` : ""}`, protocol, version, error.message ); }); diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => { const { request: { method, path: path14, origin } } = evt; debuglog("sending request to %s %s/%s", method, origin, path14); }); diagnosticsChannel.channel("undici:request:headers").subscribe((evt) => { const { request: { method, path: path14, origin }, response: { statusCode } } = evt; debuglog( "received response to %s %s/%s - HTTP %d", method, origin, path14, statusCode ); }); diagnosticsChannel.channel("undici:request:trailers").subscribe((evt) => { const { request: { method, path: path14, origin } } = evt; debuglog("trailers received from %s %s/%s", method, origin, path14); }); diagnosticsChannel.channel("undici:request:error").subscribe((evt) => { const { request: { method, path: path14, origin }, error } = evt; debuglog( "request to %s %s/%s errored - %s", method, origin, path14, error.message ); }); isClientSet = true; } if (websocketDebuglog.enabled) { if (!isClientSet) { const debuglog = undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog; diagnosticsChannel.channel("undici:client:beforeConnect").subscribe((evt) => { const { connectParams: { version, protocol, port: port2, host: host2 } } = evt; debuglog( "connecting to %s%s using %s%s", host2, port2 ? `:${port2}` : "", protocol, version ); }); diagnosticsChannel.channel("undici:client:connected").subscribe((evt) => { const { connectParams: { version, protocol, port: port2, host: host2 } } = evt; debuglog( "connected to %s%s using %s%s", host2, port2 ? `:${port2}` : "", protocol, version ); }); diagnosticsChannel.channel("undici:client:connectError").subscribe((evt) => { const { connectParams: { version, protocol, port: port2, host: host2 }, error } = evt; debuglog( "connection to %s%s using %s%s errored - %s", host2, port2 ? `:${port2}` : "", protocol, version, error.message ); }); diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => { const { request: { method, path: path14, origin } } = evt; debuglog("sending request to %s %s/%s", method, origin, path14); }); } diagnosticsChannel.channel("undici:websocket:open").subscribe((evt) => { const { address: { address, port: port2 } } = evt; websocketDebuglog("connection opened %s%s", address, port2 ? `:${port2}` : ""); }); diagnosticsChannel.channel("undici:websocket:close").subscribe((evt) => { const { websocket, code, reason } = evt; websocketDebuglog( "closed connection to %s - %s %s", websocket.url, code, reason ); }); diagnosticsChannel.channel("undici:websocket:socket_error").subscribe((err) => { websocketDebuglog("connection errored - %s", err.message); }); diagnosticsChannel.channel("undici:websocket:ping").subscribe((evt) => { websocketDebuglog("ping received"); }); diagnosticsChannel.channel("undici:websocket:pong").subscribe((evt) => { websocketDebuglog("pong received"); }); } module.exports = { channels }; } }); // viewer/node_modules/undici/lib/core/request.js var require_request = __commonJS({ "viewer/node_modules/undici/lib/core/request.js"(exports, module) { "use strict"; var { InvalidArgumentError, NotSupportedError } = require_errors(); var assert = __require("node:assert"); var { isValidHTTPToken, isValidHeaderValue, isStream: isStream2, destroy, isBuffer: isBuffer2, isFormDataLike, isIterable, isBlobLike, buildURL, validateHandler, getServerName, normalizedMethodRecords } = require_util(); var { channels } = require_diagnostics(); var { headerNameLowerCasedRecord } = require_constants(); var invalidPathRegex = /[^\u0021-\u00ff]/; var kHandler = /* @__PURE__ */ Symbol("handler"); var Request2 = class { constructor(origin, { path: path14, method, body, headers, query, idempotent, blocking, upgrade, headersTimeout, bodyTimeout, reset, throwOnError, expectContinue, servername }, handler) { if (typeof path14 !== "string") { throw new InvalidArgumentError("path must be a string"); } else if (path14[0] !== "/" && !(path14.startsWith("http://") || path14.startsWith("https://")) && method !== "CONNECT") { throw new InvalidArgumentError("path must be an absolute URL or start with a slash"); } else if (invalidPathRegex.test(path14)) { throw new InvalidArgumentError("invalid request path"); } if (typeof method !== "string") { throw new InvalidArgumentError("method must be a string"); } else if (normalizedMethodRecords[method] === void 0 && !isValidHTTPToken(method)) { throw new InvalidArgumentError("invalid request method"); } if (upgrade && typeof upgrade !== "string") { throw new InvalidArgumentError("upgrade must be a string"); } if (upgrade && !isValidHeaderValue(upgrade)) { throw new InvalidArgumentError("invalid upgrade header"); } if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { throw new InvalidArgumentError("invalid headersTimeout"); } if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { throw new InvalidArgumentError("invalid bodyTimeout"); } if (reset != null && typeof reset !== "boolean") { throw new InvalidArgumentError("invalid reset"); } if (expectContinue != null && typeof expectContinue !== "boolean") { throw new InvalidArgumentError("invalid expectContinue"); } this.headersTimeout = headersTimeout; this.bodyTimeout = bodyTimeout; this.throwOnError = throwOnError === true; this.method = method; this.abort = null; if (body == null) { this.body = null; } else if (isStream2(body)) { this.body = body; const rState = this.body._readableState; if (!rState || !rState.autoDestroy) { this.endHandler = function autoDestroy() { destroy(this); }; this.body.on("end", this.endHandler); } this.errorHandler = (err) => { if (this.abort) { this.abort(err); } else { this.error = err; } }; this.body.on("error", this.errorHandler); } else if (isBuffer2(body)) { this.body = body.byteLength ? body : null; } else if (ArrayBuffer.isView(body)) { this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null; } else if (body instanceof ArrayBuffer) { this.body = body.byteLength ? Buffer.from(body) : null; } else if (typeof body === "string") { this.body = body.length ? Buffer.from(body) : null; } else if (isFormDataLike(body) || isIterable(body) || isBlobLike(body)) { this.body = body; } else { throw new InvalidArgumentError("body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable"); } this.completed = false; this.aborted = false; this.upgrade = upgrade || null; this.path = query ? buildURL(path14, query) : path14; this.origin = origin; this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent; this.blocking = blocking == null ? false : blocking; this.reset = reset == null ? null : reset; this.host = null; this.contentLength = null; this.contentType = null; this.headers = []; this.expectContinue = expectContinue != null ? expectContinue : false; if (Array.isArray(headers)) { if (headers.length % 2 !== 0) { throw new InvalidArgumentError("headers array must be even"); } for (let i = 0; i < headers.length; i += 2) { processHeader(this, headers[i], headers[i + 1]); } } else if (headers && typeof headers === "object") { if (headers[Symbol.iterator]) { for (const header of headers) { if (!Array.isArray(header) || header.length !== 2) { throw new InvalidArgumentError("headers must be in key-value pair format"); } processHeader(this, header[0], header[1]); } } else { const keys = Object.keys(headers); for (let i = 0; i < keys.length; ++i) { processHeader(this, keys[i], headers[keys[i]]); } } } else if (headers != null) { throw new InvalidArgumentError("headers must be an object or an array"); } validateHandler(handler, method, upgrade); this.servername = servername || getServerName(this.host); this[kHandler] = handler; if (channels.create.hasSubscribers) { channels.create.publish({ request: this }); } } onBodySent(chunk) { if (this[kHandler].onBodySent) { try { return this[kHandler].onBodySent(chunk); } catch (err) { this.abort(err); } } } onRequestSent() { if (channels.bodySent.hasSubscribers) { channels.bodySent.publish({ request: this }); } if (this[kHandler].onRequestSent) { try { return this[kHandler].onRequestSent(); } catch (err) { this.abort(err); } } } onConnect(abort) { assert(!this.aborted); assert(!this.completed); if (this.error) { abort(this.error); } else { this.abort = abort; return this[kHandler].onConnect(abort); } } onResponseStarted() { return this[kHandler].onResponseStarted?.(); } onHeaders(statusCode, headers, resume, statusText) { assert(!this.aborted); assert(!this.completed); if (channels.headers.hasSubscribers) { channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); } try { return this[kHandler].onHeaders(statusCode, headers, resume, statusText); } catch (err) { this.abort(err); } } onData(chunk) { assert(!this.aborted); assert(!this.completed); try { return this[kHandler].onData(chunk); } catch (err) { this.abort(err); return false; } } onUpgrade(statusCode, headers, socket) { assert(!this.aborted); assert(!this.completed); return this[kHandler].onUpgrade(statusCode, headers, socket); } onComplete(trailers) { this.onFinally(); assert(!this.aborted); this.completed = true; if (channels.trailers.hasSubscribers) { channels.trailers.publish({ request: this, trailers }); } try { return this[kHandler].onComplete(trailers); } catch (err) { this.onError(err); } } onError(error) { this.onFinally(); if (channels.error.hasSubscribers) { channels.error.publish({ request: this, error }); } if (this.aborted) { return; } this.aborted = true; return this[kHandler].onError(error); } onFinally() { if (this.errorHandler) { this.body.off("error", this.errorHandler); this.errorHandler = null; } if (this.endHandler) { this.body.off("end", this.endHandler); this.endHandler = null; } } addHeader(key, value) { processHeader(this, key, value); return this; } }; function processHeader(request, key, val) { if (val && (typeof val === "object" && !Array.isArray(val))) { throw new InvalidArgumentError(`invalid ${key} header`); } else if (val === void 0) { return; } let headerName = headerNameLowerCasedRecord[key]; if (headerName === void 0) { headerName = key.toLowerCase(); if (headerNameLowerCasedRecord[headerName] === void 0 && !isValidHTTPToken(headerName)) { throw new InvalidArgumentError("invalid header key"); } } if (Array.isArray(val)) { const arr = []; for (let i = 0; i < val.length; i++) { if (typeof val[i] === "string") { if (!isValidHeaderValue(val[i])) { throw new InvalidArgumentError(`invalid ${key} header`); } arr.push(val[i]); } else if (val[i] === null) { arr.push(""); } else if (typeof val[i] === "object") { throw new InvalidArgumentError(`invalid ${key} header`); } else { arr.push(`${val[i]}`); } } val = arr; } else if (typeof val === "string") { if (!isValidHeaderValue(val)) { throw new InvalidArgumentError(`invalid ${key} header`); } } else if (val === null) { val = ""; } else { val = `${val}`; } if (headerName === "host") { if (request.host !== null) { throw new InvalidArgumentError("duplicate host header"); } if (typeof val !== "string") { throw new InvalidArgumentError("invalid host header"); } request.host = val; } else if (headerName === "content-length") { if (request.contentLength !== null) { throw new InvalidArgumentError("duplicate content-length header"); } request.contentLength = parseInt(val, 10); if (!Number.isFinite(request.contentLength)) { throw new InvalidArgumentError("invalid content-length header"); } } else if (request.contentType === null && headerName === "content-type") { request.contentType = val; request.headers.push(key, val); } else if (headerName === "transfer-encoding" || headerName === "keep-alive" || headerName === "upgrade") { throw new InvalidArgumentError(`invalid ${headerName} header`); } else if (headerName === "connection") { const value = typeof val === "string" ? val.toLowerCase() : null; if (value !== "close" && value !== "keep-alive") { throw new InvalidArgumentError("invalid connection header"); } if (value === "close") { request.reset = true; } } else if (headerName === "expect") { throw new NotSupportedError("expect header not supported"); } else { request.headers.push(key, val); } } module.exports = Request2; } }); // viewer/node_modules/undici/lib/dispatcher/dispatcher.js var require_dispatcher = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/dispatcher.js"(exports, module) { "use strict"; var EventEmitter = __require("node:events"); var Dispatcher = class extends EventEmitter { dispatch() { throw new Error("not implemented"); } close() { throw new Error("not implemented"); } destroy() { throw new Error("not implemented"); } compose(...args) { const interceptors = Array.isArray(args[0]) ? args[0] : args; let dispatch = this.dispatch.bind(this); for (const interceptor of interceptors) { if (interceptor == null) { continue; } if (typeof interceptor !== "function") { throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`); } dispatch = interceptor(dispatch); if (dispatch == null || typeof dispatch !== "function" || dispatch.length !== 2) { throw new TypeError("invalid interceptor"); } } return new ComposedDispatcher(this, dispatch); } }; var ComposedDispatcher = class extends Dispatcher { #dispatcher = null; #dispatch = null; constructor(dispatcher, dispatch) { super(); this.#dispatcher = dispatcher; this.#dispatch = dispatch; } dispatch(...args) { this.#dispatch(...args); } close(...args) { return this.#dispatcher.close(...args); } destroy(...args) { return this.#dispatcher.destroy(...args); } }; module.exports = Dispatcher; } }); // viewer/node_modules/undici/lib/dispatcher/dispatcher-base.js var require_dispatcher_base = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; var Dispatcher = require_dispatcher(); var { ClientDestroyedError, ClientClosedError, InvalidArgumentError } = require_errors(); var { kDestroy, kClose, kClosed, kDestroyed, kDispatch, kInterceptors } = require_symbols(); var kOnDestroyed = /* @__PURE__ */ Symbol("onDestroyed"); var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); this[kDestroyed] = false; this[kOnDestroyed] = null; this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; } get webSocketOptions() { return { maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } get destroyed() { return this[kDestroyed]; } get closed() { return this[kClosed]; } get interceptors() { return this[kInterceptors]; } set interceptors(newInterceptors) { if (newInterceptors) { for (let i = newInterceptors.length - 1; i >= 0; i--) { const interceptor = this[kInterceptors][i]; if (typeof interceptor !== "function") { throw new InvalidArgumentError("interceptor must be an function"); } } } this[kInterceptors] = newInterceptors; } close(callback) { if (callback === void 0) { return new Promise((resolve, reject) => { this.close((err, data) => { return err ? reject(err) : resolve(data); }); }); } if (typeof callback !== "function") { throw new InvalidArgumentError("invalid callback"); } if (this[kDestroyed]) { queueMicrotask(() => callback(new ClientDestroyedError(), null)); return; } if (this[kClosed]) { if (this[kOnClosed]) { this[kOnClosed].push(callback); } else { queueMicrotask(() => callback(null, null)); } return; } this[kClosed] = true; this[kOnClosed].push(callback); const onClosed = () => { const callbacks = this[kOnClosed]; this[kOnClosed] = null; for (let i = 0; i < callbacks.length; i++) { callbacks[i](null, null); } }; this[kClose]().then(() => this.destroy()).then(() => { queueMicrotask(onClosed); }); } destroy(err, callback) { if (typeof err === "function") { callback = err; err = null; } if (callback === void 0) { return new Promise((resolve, reject) => { this.destroy(err, (err2, data) => { return err2 ? ( /* istanbul ignore next: should never error */ reject(err2) ) : resolve(data); }); }); } if (typeof callback !== "function") { throw new InvalidArgumentError("invalid callback"); } if (this[kDestroyed]) { if (this[kOnDestroyed]) { this[kOnDestroyed].push(callback); } else { queueMicrotask(() => callback(null, null)); } return; } if (!err) { err = new ClientDestroyedError(); } this[kDestroyed] = true; this[kOnDestroyed] = this[kOnDestroyed] || []; this[kOnDestroyed].push(callback); const onDestroyed = () => { const callbacks = this[kOnDestroyed]; this[kOnDestroyed] = null; for (let i = 0; i < callbacks.length; i++) { callbacks[i](null, null); } }; this[kDestroy](err).then(() => { queueMicrotask(onDestroyed); }); } [kInterceptedDispatch](opts, handler) { if (!this[kInterceptors] || this[kInterceptors].length === 0) { this[kInterceptedDispatch] = this[kDispatch]; return this[kDispatch](opts, handler); } let dispatch = this[kDispatch].bind(this); for (let i = this[kInterceptors].length - 1; i >= 0; i--) { dispatch = this[kInterceptors][i](dispatch); } this[kInterceptedDispatch] = dispatch; return dispatch(opts, handler); } dispatch(opts, handler) { if (!handler || typeof handler !== "object") { throw new InvalidArgumentError("handler must be an object"); } try { if (!opts || typeof opts !== "object") { throw new InvalidArgumentError("opts must be an object."); } if (this[kDestroyed] || this[kOnDestroyed]) { throw new ClientDestroyedError(); } if (this[kClosed]) { throw new ClientClosedError(); } return this[kInterceptedDispatch](opts, handler); } catch (err) { if (typeof handler.onError !== "function") { throw new InvalidArgumentError("invalid onError method"); } handler.onError(err); return false; } } }; module.exports = DispatcherBase; } }); // viewer/node_modules/undici/lib/util/timers.js var require_timers = __commonJS({ "viewer/node_modules/undici/lib/util/timers.js"(exports, module) { "use strict"; var fastNow = 0; var RESOLUTION_MS = 1e3; var TICK_MS = (RESOLUTION_MS >> 1) - 1; var fastNowTimeout; var kFastTimer = /* @__PURE__ */ Symbol("kFastTimer"); var fastTimers = []; var NOT_IN_LIST = -2; var TO_BE_CLEARED = -1; var PENDING = 0; var ACTIVE = 1; function onTick() { fastNow += TICK_MS; let idx = 0; let len = fastTimers.length; while (idx < len) { const timer = fastTimers[idx]; if (timer._state === PENDING) { timer._idleStart = fastNow - TICK_MS; timer._state = ACTIVE; } else if (timer._state === ACTIVE && fastNow >= timer._idleStart + timer._idleTimeout) { timer._state = TO_BE_CLEARED; timer._idleStart = -1; timer._onTimeout(timer._timerArg); } if (timer._state === TO_BE_CLEARED) { timer._state = NOT_IN_LIST; if (--len !== 0) { fastTimers[idx] = fastTimers[len]; } } else { ++idx; } } fastTimers.length = len; if (fastTimers.length !== 0) { refreshTimeout(); } } function refreshTimeout() { if (fastNowTimeout) { fastNowTimeout.refresh(); } else { clearTimeout(fastNowTimeout); fastNowTimeout = setTimeout(onTick, TICK_MS); if (fastNowTimeout.unref) { fastNowTimeout.unref(); } } } var FastTimer = class { [kFastTimer] = true; /** * The state of the timer, which can be one of the following: * - NOT_IN_LIST (-2) * - TO_BE_CLEARED (-1) * - PENDING (0) * - ACTIVE (1) * * @type {-2|-1|0|1} * @private */ _state = NOT_IN_LIST; /** * The number of milliseconds to wait before calling the callback. * * @type {number} * @private */ _idleTimeout = -1; /** * The time in milliseconds when the timer was started. This value is used to * calculate when the timer should expire. * * @type {number} * @default -1 * @private */ _idleStart = -1; /** * The function to be executed when the timer expires. * @type {Function} * @private */ _onTimeout; /** * The argument to be passed to the callback when the timer expires. * * @type {*} * @private */ _timerArg; /** * @constructor * @param {Function} callback A function to be executed after the timer * expires. * @param {number} delay The time, in milliseconds that the timer should wait * before the specified function or code is executed. * @param {*} arg */ constructor(callback, delay, arg) { this._onTimeout = callback; this._idleTimeout = delay; this._timerArg = arg; this.refresh(); } /** * Sets the timer's start time to the current time, and reschedules the timer * to call its callback at the previously specified duration adjusted to the * current time. * Using this on a timer that has already called its callback will reactivate * the timer. * * @returns {void} */ refresh() { if (this._state === NOT_IN_LIST) { fastTimers.push(this); } if (!fastNowTimeout || fastTimers.length === 1) { refreshTimeout(); } this._state = PENDING; } /** * The `clear` method cancels the timer, preventing it from executing. * * @returns {void} * @private */ clear() { this._state = TO_BE_CLEARED; this._idleStart = -1; } }; module.exports = { /** * The setTimeout() method sets a timer which executes a function once the * timer expires. * @param {Function} callback A function to be executed after the timer * expires. * @param {number} delay The time, in milliseconds that the timer should * wait before the specified function or code is executed. * @param {*} [arg] An optional argument to be passed to the callback function * when the timer expires. * @returns {NodeJS.Timeout|FastTimer} */ setTimeout(callback, delay, arg) { return delay <= RESOLUTION_MS ? setTimeout(callback, delay, arg) : new FastTimer(callback, delay, arg); }, /** * The clearTimeout method cancels an instantiated Timer previously created * by calling setTimeout. * * @param {NodeJS.Timeout|FastTimer} timeout */ clearTimeout(timeout) { if (timeout[kFastTimer]) { timeout.clear(); } else { clearTimeout(timeout); } }, /** * The setFastTimeout() method sets a fastTimer which executes a function once * the timer expires. * @param {Function} callback A function to be executed after the timer * expires. * @param {number} delay The time, in milliseconds that the timer should * wait before the specified function or code is executed. * @param {*} [arg] An optional argument to be passed to the callback function * when the timer expires. * @returns {FastTimer} */ setFastTimeout(callback, delay, arg) { return new FastTimer(callback, delay, arg); }, /** * The clearTimeout method cancels an instantiated FastTimer previously * created by calling setFastTimeout. * * @param {FastTimer} timeout */ clearFastTimeout(timeout) { timeout.clear(); }, /** * The now method returns the value of the internal fast timer clock. * * @returns {number} */ now() { return fastNow; }, /** * Trigger the onTick function to process the fastTimers array. * Exported for testing purposes only. * Marking as deprecated to discourage any use outside of testing. * @deprecated * @param {number} [delay=0] The delay in milliseconds to add to the now value. */ tick(delay = 0) { fastNow += delay - RESOLUTION_MS + 1; onTick(); onTick(); }, /** * Reset FastTimers. * Exported for testing purposes only. * Marking as deprecated to discourage any use outside of testing. * @deprecated */ reset() { fastNow = 0; fastTimers.length = 0; clearTimeout(fastNowTimeout); fastNowTimeout = null; }, /** * Exporting for testing purposes only. * Marking as deprecated to discourage any use outside of testing. * @deprecated */ kFastTimer }; } }); // viewer/node_modules/undici/lib/core/connect.js var require_connect = __commonJS({ "viewer/node_modules/undici/lib/core/connect.js"(exports, module) { "use strict"; var net = __require("node:net"); var assert = __require("node:assert"); var util = require_util(); var { InvalidArgumentError, ConnectTimeoutError } = require_errors(); var timers = require_timers(); function noop() { } var tls; var SessionCache; if (global.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) { SessionCache = class WeakSessionCache { constructor(maxCachedSessions) { this._maxCachedSessions = maxCachedSessions; this._sessionCache = /* @__PURE__ */ new Map(); this._sessionRegistry = new global.FinalizationRegistry((key) => { if (this._sessionCache.size < this._maxCachedSessions) { return; } const ref = this._sessionCache.get(key); if (ref !== void 0 && ref.deref() === void 0) { this._sessionCache.delete(key); } }); } get(sessionKey) { const ref = this._sessionCache.get(sessionKey); return ref ? ref.deref() : null; } set(sessionKey, session) { if (this._maxCachedSessions === 0) { return; } this._sessionCache.set(sessionKey, new WeakRef(session)); this._sessionRegistry.register(session, sessionKey); } }; } else { SessionCache = class SimpleSessionCache { constructor(maxCachedSessions) { this._maxCachedSessions = maxCachedSessions; this._sessionCache = /* @__PURE__ */ new Map(); } get(sessionKey) { return this._sessionCache.get(sessionKey); } set(sessionKey, session) { if (this._maxCachedSessions === 0) { return; } if (this._sessionCache.size >= this._maxCachedSessions) { const { value: oldestKey } = this._sessionCache.keys().next(); this._sessionCache.delete(oldestKey); } this._sessionCache.set(sessionKey, session); } }; } function buildConnector({ allowH2, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { throw new InvalidArgumentError("maxCachedSessions must be a positive integer or zero"); } const options = { path: socketPath, ...opts }; const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions); timeout = timeout == null ? 1e4 : timeout; allowH2 = allowH2 != null ? allowH2 : false; return function connect({ hostname, host: host2, protocol, port: port2, servername, localAddress, httpSocket }, callback) { let socket; if (protocol === "https:") { if (!tls) { tls = __require("node:tls"); } servername = servername || options.servername || util.getServerName(host2) || null; const sessionKey = servername || hostname; assert(sessionKey); const session = customSession || sessionCache.get(sessionKey) || null; port2 = port2 || 443; socket = tls.connect({ highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... ...options, servername, session, localAddress, // TODO(HTTP/2): Add support for h2c ALPNProtocols: allowH2 ? ["http/1.1", "h2"] : ["http/1.1"], socket: httpSocket, // upgrade socket connection port: port2, host: hostname }); socket.on("session", function(session2) { sessionCache.set(sessionKey, session2); }); } else { assert(!httpSocket, "httpSocket can only be sent on TLS update"); port2 = port2 || 80; socket = net.connect({ highWaterMark: 64 * 1024, // Same as nodejs fs streams. ...options, localAddress, port: port2, host: hostname }); } if (options.keepAlive == null || options.keepAlive) { const keepAliveInitialDelay = options.keepAliveInitialDelay === void 0 ? 6e4 : options.keepAliveInitialDelay; socket.setKeepAlive(true, keepAliveInitialDelay); } const clearConnectTimeout = setupConnectTimeout(new WeakRef(socket), { timeout, hostname, port: port2 }); socket.setNoDelay(true).once(protocol === "https:" ? "secureConnect" : "connect", function() { queueMicrotask(clearConnectTimeout); if (callback) { const cb = callback; callback = null; cb(null, this); } }).on("error", function(err) { queueMicrotask(clearConnectTimeout); if (callback) { const cb = callback; callback = null; cb(err); } }); return socket; }; } var setupConnectTimeout = process.platform === "win32" ? (socketWeakRef, opts) => { if (!opts.timeout) { return noop; } let s1 = null; let s2 = null; const fastTimer = timers.setFastTimeout(() => { s1 = setImmediate(() => { s2 = setImmediate(() => onConnectTimeout(socketWeakRef.deref(), opts)); }); }, opts.timeout); return () => { timers.clearFastTimeout(fastTimer); clearImmediate(s1); clearImmediate(s2); }; } : (socketWeakRef, opts) => { if (!opts.timeout) { return noop; } let s1 = null; const fastTimer = timers.setFastTimeout(() => { s1 = setImmediate(() => { onConnectTimeout(socketWeakRef.deref(), opts); }); }, opts.timeout); return () => { timers.clearFastTimeout(fastTimer); clearImmediate(s1); }; }; function onConnectTimeout(socket, opts) { if (socket == null) { return; } let message = "Connect Timeout Error"; if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(", ")},`; } else { message += ` (attempted address: ${opts.hostname}:${opts.port},`; } message += ` timeout: ${opts.timeout}ms)`; util.destroy(socket, new ConnectTimeoutError(message)); } module.exports = buildConnector; } }); // viewer/node_modules/undici/lib/llhttp/utils.js var require_utils = __commonJS({ "viewer/node_modules/undici/lib/llhttp/utils.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.enumToMap = void 0; function enumToMap(obj) { const res = {}; Object.keys(obj).forEach((key) => { const value = obj[key]; if (typeof value === "number") { res[key] = value; } }); return res; } exports.enumToMap = enumToMap; } }); // viewer/node_modules/undici/lib/llhttp/constants.js var require_constants2 = __commonJS({ "viewer/node_modules/undici/lib/llhttp/constants.js"(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; var utils_1 = require_utils(); var ERROR; (function(ERROR2) { ERROR2[ERROR2["OK"] = 0] = "OK"; ERROR2[ERROR2["INTERNAL"] = 1] = "INTERNAL"; ERROR2[ERROR2["STRICT"] = 2] = "STRICT"; ERROR2[ERROR2["LF_EXPECTED"] = 3] = "LF_EXPECTED"; ERROR2[ERROR2["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; ERROR2[ERROR2["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; ERROR2[ERROR2["INVALID_METHOD"] = 6] = "INVALID_METHOD"; ERROR2[ERROR2["INVALID_URL"] = 7] = "INVALID_URL"; ERROR2[ERROR2["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; ERROR2[ERROR2["INVALID_VERSION"] = 9] = "INVALID_VERSION"; ERROR2[ERROR2["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; ERROR2[ERROR2["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; ERROR2[ERROR2["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; ERROR2[ERROR2["INVALID_STATUS"] = 13] = "INVALID_STATUS"; ERROR2[ERROR2["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; ERROR2[ERROR2["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; ERROR2[ERROR2["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; ERROR2[ERROR2["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; ERROR2[ERROR2["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; ERROR2[ERROR2["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; ERROR2[ERROR2["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; ERROR2[ERROR2["PAUSED"] = 21] = "PAUSED"; ERROR2[ERROR2["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; ERROR2[ERROR2["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; ERROR2[ERROR2["USER"] = 24] = "USER"; })(ERROR = exports.ERROR || (exports.ERROR = {})); var TYPE; (function(TYPE2) { TYPE2[TYPE2["BOTH"] = 0] = "BOTH"; TYPE2[TYPE2["REQUEST"] = 1] = "REQUEST"; TYPE2[TYPE2["RESPONSE"] = 2] = "RESPONSE"; })(TYPE = exports.TYPE || (exports.TYPE = {})); var FLAGS; (function(FLAGS2) { FLAGS2[FLAGS2["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; FLAGS2[FLAGS2["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; FLAGS2[FLAGS2["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; FLAGS2[FLAGS2["CHUNKED"] = 8] = "CHUNKED"; FLAGS2[FLAGS2["UPGRADE"] = 16] = "UPGRADE"; FLAGS2[FLAGS2["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; FLAGS2[FLAGS2["SKIPBODY"] = 64] = "SKIPBODY"; FLAGS2[FLAGS2["TRAILING"] = 128] = "TRAILING"; FLAGS2[FLAGS2["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; })(FLAGS = exports.FLAGS || (exports.FLAGS = {})); var LENIENT_FLAGS; (function(LENIENT_FLAGS2) { LENIENT_FLAGS2[LENIENT_FLAGS2["HEADERS"] = 1] = "HEADERS"; LENIENT_FLAGS2[LENIENT_FLAGS2["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; LENIENT_FLAGS2[LENIENT_FLAGS2["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; })(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); var METHODS; (function(METHODS2) { METHODS2[METHODS2["DELETE"] = 0] = "DELETE"; METHODS2[METHODS2["GET"] = 1] = "GET"; METHODS2[METHODS2["HEAD"] = 2] = "HEAD"; METHODS2[METHODS2["POST"] = 3] = "POST"; METHODS2[METHODS2["PUT"] = 4] = "PUT"; METHODS2[METHODS2["CONNECT"] = 5] = "CONNECT"; METHODS2[METHODS2["OPTIONS"] = 6] = "OPTIONS"; METHODS2[METHODS2["TRACE"] = 7] = "TRACE"; METHODS2[METHODS2["COPY"] = 8] = "COPY"; METHODS2[METHODS2["LOCK"] = 9] = "LOCK"; METHODS2[METHODS2["MKCOL"] = 10] = "MKCOL"; METHODS2[METHODS2["MOVE"] = 11] = "MOVE"; METHODS2[METHODS2["PROPFIND"] = 12] = "PROPFIND"; METHODS2[METHODS2["PROPPATCH"] = 13] = "PROPPATCH"; METHODS2[METHODS2["SEARCH"] = 14] = "SEARCH"; METHODS2[METHODS2["UNLOCK"] = 15] = "UNLOCK"; METHODS2[METHODS2["BIND"] = 16] = "BIND"; METHODS2[METHODS2["REBIND"] = 17] = "REBIND"; METHODS2[METHODS2["UNBIND"] = 18] = "UNBIND"; METHODS2[METHODS2["ACL"] = 19] = "ACL"; METHODS2[METHODS2["REPORT"] = 20] = "REPORT"; METHODS2[METHODS2["MKACTIVITY"] = 21] = "MKACTIVITY"; METHODS2[METHODS2["CHECKOUT"] = 22] = "CHECKOUT"; METHODS2[METHODS2["MERGE"] = 23] = "MERGE"; METHODS2[METHODS2["M-SEARCH"] = 24] = "M-SEARCH"; METHODS2[METHODS2["NOTIFY"] = 25] = "NOTIFY"; METHODS2[METHODS2["SUBSCRIBE"] = 26] = "SUBSCRIBE"; METHODS2[METHODS2["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; METHODS2[METHODS2["PATCH"] = 28] = "PATCH"; METHODS2[METHODS2["PURGE"] = 29] = "PURGE"; METHODS2[METHODS2["MKCALENDAR"] = 30] = "MKCALENDAR"; METHODS2[METHODS2["LINK"] = 31] = "LINK"; METHODS2[METHODS2["UNLINK"] = 32] = "UNLINK"; METHODS2[METHODS2["SOURCE"] = 33] = "SOURCE"; METHODS2[METHODS2["PRI"] = 34] = "PRI"; METHODS2[METHODS2["DESCRIBE"] = 35] = "DESCRIBE"; METHODS2[METHODS2["ANNOUNCE"] = 36] = "ANNOUNCE"; METHODS2[METHODS2["SETUP"] = 37] = "SETUP"; METHODS2[METHODS2["PLAY"] = 38] = "PLAY"; METHODS2[METHODS2["PAUSE"] = 39] = "PAUSE"; METHODS2[METHODS2["TEARDOWN"] = 40] = "TEARDOWN"; METHODS2[METHODS2["GET_PARAMETER"] = 41] = "GET_PARAMETER"; METHODS2[METHODS2["SET_PARAMETER"] = 42] = "SET_PARAMETER"; METHODS2[METHODS2["REDIRECT"] = 43] = "REDIRECT"; METHODS2[METHODS2["RECORD"] = 44] = "RECORD"; METHODS2[METHODS2["FLUSH"] = 45] = "FLUSH"; })(METHODS = exports.METHODS || (exports.METHODS = {})); exports.METHODS_HTTP = [ METHODS.DELETE, METHODS.GET, METHODS.HEAD, METHODS.POST, METHODS.PUT, METHODS.CONNECT, METHODS.OPTIONS, METHODS.TRACE, METHODS.COPY, METHODS.LOCK, METHODS.MKCOL, METHODS.MOVE, METHODS.PROPFIND, METHODS.PROPPATCH, METHODS.SEARCH, METHODS.UNLOCK, METHODS.BIND, METHODS.REBIND, METHODS.UNBIND, METHODS.ACL, METHODS.REPORT, METHODS.MKACTIVITY, METHODS.CHECKOUT, METHODS.MERGE, METHODS["M-SEARCH"], METHODS.NOTIFY, METHODS.SUBSCRIBE, METHODS.UNSUBSCRIBE, METHODS.PATCH, METHODS.PURGE, METHODS.MKCALENDAR, METHODS.LINK, METHODS.UNLINK, METHODS.PRI, // TODO(indutny): should we allow it with HTTP? METHODS.SOURCE ]; exports.METHODS_ICE = [ METHODS.SOURCE ]; exports.METHODS_RTSP = [ METHODS.OPTIONS, METHODS.DESCRIBE, METHODS.ANNOUNCE, METHODS.SETUP, METHODS.PLAY, METHODS.PAUSE, METHODS.TEARDOWN, METHODS.GET_PARAMETER, METHODS.SET_PARAMETER, METHODS.REDIRECT, METHODS.RECORD, METHODS.FLUSH, // For AirPlay METHODS.GET, METHODS.POST ]; exports.METHOD_MAP = utils_1.enumToMap(METHODS); exports.H_METHOD_MAP = {}; Object.keys(exports.METHOD_MAP).forEach((key) => { if (/^H/.test(key)) { exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; } }); var FINISH; (function(FINISH2) { FINISH2[FINISH2["SAFE"] = 0] = "SAFE"; FINISH2[FINISH2["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; FINISH2[FINISH2["UNSAFE"] = 2] = "UNSAFE"; })(FINISH = exports.FINISH || (exports.FINISH = {})); exports.ALPHA = []; for (let i = "A".charCodeAt(0); i <= "Z".charCodeAt(0); i++) { exports.ALPHA.push(String.fromCharCode(i)); exports.ALPHA.push(String.fromCharCode(i + 32)); } exports.NUM_MAP = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9 }; exports.HEX_MAP = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15 }; exports.NUM = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ]; exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); exports.MARK = ["-", "_", ".", "!", "~", "*", "'", "(", ")"]; exports.USERINFO_CHARS = exports.ALPHANUM.concat(exports.MARK).concat(["%", ";", ":", "&", "=", "+", "$", ","]); exports.STRICT_URL_CHAR = [ "!", '"', "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "@", "[", "\\", "]", "^", "_", "`", "{", "|", "}", "~" ].concat(exports.ALPHANUM); exports.URL_CHAR = exports.STRICT_URL_CHAR.concat([" ", "\f"]); for (let i = 128; i <= 255; i++) { exports.URL_CHAR.push(i); } exports.HEX = exports.NUM.concat(["a", "b", "c", "d", "e", "f", "A", "B", "C", "D", "E", "F"]); exports.STRICT_TOKEN = [ "!", "#", "$", "%", "&", "'", "*", "+", "-", ".", "^", "_", "`", "|", "~" ].concat(exports.ALPHANUM); exports.TOKEN = exports.STRICT_TOKEN.concat([" "]); exports.HEADER_CHARS = [" "]; for (let i = 32; i <= 255; i++) { if (i !== 127) { exports.HEADER_CHARS.push(i); } } exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); exports.MAJOR = exports.NUM_MAP; exports.MINOR = exports.MAJOR; var HEADER_STATE; (function(HEADER_STATE2) { HEADER_STATE2[HEADER_STATE2["GENERAL"] = 0] = "GENERAL"; HEADER_STATE2[HEADER_STATE2["CONNECTION"] = 1] = "CONNECTION"; HEADER_STATE2[HEADER_STATE2["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; HEADER_STATE2[HEADER_STATE2["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; HEADER_STATE2[HEADER_STATE2["UPGRADE"] = 4] = "UPGRADE"; HEADER_STATE2[HEADER_STATE2["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; HEADER_STATE2[HEADER_STATE2["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; HEADER_STATE2[HEADER_STATE2["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; HEADER_STATE2[HEADER_STATE2["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; })(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); exports.SPECIAL_HEADERS = { "connection": HEADER_STATE.CONNECTION, "content-length": HEADER_STATE.CONTENT_LENGTH, "proxy-connection": HEADER_STATE.CONNECTION, "transfer-encoding": HEADER_STATE.TRANSFER_ENCODING, "upgrade": HEADER_STATE.UPGRADE }; } }); // viewer/node_modules/undici/lib/llhttp/llhttp-wasm.js var require_llhttp_wasm = __commonJS({ "viewer/node_modules/undici/lib/llhttp/llhttp-wasm.js"(exports, module) { "use strict"; var { Buffer: Buffer2 } = __require("node:buffer"); module.exports = Buffer2.from("AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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PgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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iQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB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CABB3AgLii1JbnZhbGlkIGNoYXIgaW4gdXJsIHF1ZXJ5AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fYm9keQBDb250ZW50LUxlbmd0aCBvdmVyZmxvdwBDaHVuayBzaXplIG92ZXJmbG93AFJlc3BvbnNlIG92ZXJmbG93AEludmFsaWQgbWV0aG9kIGZvciBIVFRQL3gueCByZXF1ZXN0AEludmFsaWQgbWV0aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zAFVzZXIgY2FsbGJhY2sgZXJyb3IAYG9uX3Jlc2V0YCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfaGVhZGVyYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9iZWdpbmAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3N0YXR1c19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3ZlcnNpb25fY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl91cmxfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXRob2RfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfZmllbGRfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fbmFtZWAgY2FsbGJhY2sgZXJyb3IAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzZXJ2ZXIASW52YWxpZCBoZWFkZXIgdmFsdWUgY2hhcgBJbnZhbGlkIGhlYWRlciBmaWVsZCBjaGFyAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdmVyc2lvbgBJbnZhbGlkIG1pbm9yIHZlcnNpb24ASW52YWxpZCBtYWpvciB2ZXJzaW9uAEV4cGVjdGVkIHNwYWNlIGFmdGVyIHZlcnNpb24ARXhwZWN0ZWQgQ1JMRiBhZnRlciB2ZXJzaW9uAEludmFsaWQgSFRUUCB2ZXJzaW9uAEludmFsaWQgaGVhZGVyIHRva2VuAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdXJsAEludmFsaWQgY2hhcmFjdGVycyBpbiB1cmwAVW5leHBlY3RlZCBzdGFydCBjaGFyIGluIHVybABEb3VibGUgQCBpbiB1cmwARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgARHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhciBpbiB1cmwgcGF0aABDb250ZW50LUxlbmd0aCBjYW4ndCBiZSBwcmVzZW50IHdpdGggVHJhbnNmZXItRW5jb2RpbmcASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgc2l6ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl92YWx1ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlZCB2YWx1ZQBQYXVzZWQgYnkgb25faGVhZGVyc19jb21wbGV0ZQBJbnZhbGlkIEVPRiBzdGF0ZQBvbl9yZXNldCBwYXVzZQBvbl9jaHVua19oZWFkZXIgcGF1c2UAb25fbWVzc2FnZV9iZWdpbiBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fdmFsdWUgcGF1c2UAb25fc3RhdHVzX2NvbXBsZXRlIHBhdXNlAG9uX3ZlcnNpb25fY29tcGxldGUgcGF1c2UAb25fdXJsX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXNzYWdlX2NvbXBsZXRlIHBhdXNlAG9uX21ldGhvZF9jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfZmllbGRfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUgcGF1c2UAVW5leHBlY3RlZCBzcGFjZSBhZnRlciBzdGFydCBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAFBhdXNlIG9uIENPTk5FQ1QvVXBncmFkZQBQYXVzZSBvbiBQUkkvVXBncmFkZQBFeHBlY3RlZCBIVFRQLzIgQ29ubmVjdGlvbiBQcmVmYWNlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fbWV0aG9kAEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl9maWVsZABQYXVzZWQASW52YWxpZCB3b3JkIGVuY291bnRlcmVkAEludmFsaWQgbWV0aG9kIGVuY291bnRlcmVkAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2NoZW1hAFJlcXVlc3QgaGFzIGludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYABTV0lUQ0hfUFJPWFkAVVNFX1BST1hZAE1LQUNUSVZJVFkAVU5QUk9DRVNTQUJMRV9FTlRJVFkAQ09QWQBNT1ZFRF9QRVJNQU5FTlRMWQBUT09fRUFSTFkATk9USUZZAEZBSUxFRF9ERVBFTkRFTkNZAEJBRF9HQVRFV0FZAFBMQVkAUFVUAENIRUNLT1VUAEdBVEVXQVlfVElNRU9VVABSRVFVRVNUX1RJTUVPVVQATkVUV09SS19DT05ORUNUX1RJTUVPVVQAQ09OTkVDVElPTl9USU1FT1VUAExPR0lOX1RJTUVPVVQATkVUV09SS19SRUFEX1RJTUVPVVQAUE9TVABNSVNESVJFQ1RFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX0xPQURfQkFMQU5DRURfUkVRVUVTVABCQURfUkVRVUVTVABIVFRQX1JFUVVFU1RfU0VOVF9UT19IVFRQU19QT1JUAFJFUE9SVABJTV9BX1RFQVBPVABSRVNFVF9DT05URU5UAE5PX0NPTlRFTlQAUEFSVElBTF9DT05URU5UAEhQRV9JTlZBTElEX0NPTlNUQU5UAEhQRV9DQl9SRVNFVABHRVQASFBFX1NUUklDVABDT05GTElDVABURU1QT1JBUllfUkVESVJFQ1QAUEVSTUFORU5UX1JFRElSRUNUAENPTk5FQ1QATVVMVElfU1RBVFVTAEhQRV9JTlZBTElEX1NUQVRVUwBUT09fTUFOWV9SRVFVRVNUUwBFQVJMWV9ISU5UUwBVTkFWQUlMQUJMRV9GT1JfTEVHQUxfUkVBU09OUwBPUFRJT05TAFNXSVRDSElOR19QUk9UT0NPTFMAVkFSSUFOVF9BTFNPX05FR09USUFURVMATVVMVElQTEVfQ0hPSUNFUwBJTlRFUk5BTF9TRVJWRVJfRVJST1IAV0VCX1NFUlZFUl9VTktOT1dOX0VSUk9SAFJBSUxHVU5fRVJST1IASURFTlRJVFlfUFJPVklERVJfQVVUSEVOVElDQVRJT05fRVJST1IAU1NMX0NFUlRJRklDQVRFX0VSUk9SAElOVkFMSURfWF9GT1JXQVJERURfRk9SAFNFVF9QQVJBTUVURVIAR0VUX1BBUkFNRVRFUgBIUEVfVVNFUgBTRUVfT1RIRVIASFBFX0NCX0NIVU5LX0hFQURFUgBNS0NBTEVOREFSAFNFVFVQAFdFQl9TRVJWRVJfSVNfRE9XTgBURUFSRE9XTgBIUEVfQ0xPU0VEX0NPTk5FQ1RJT04ASEVVUklTVElDX0VYUElSQVRJT04ARElTQ09OTkVDVEVEX09QRVJBVElPTgBOT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTgBIUEVfSU5WQUxJRF9WRVJTSU9OAEhQRV9DQl9NRVNTQUdFX0JFR0lOAFNJVEVfSVNfRlJPWkVOAEhQRV9JTlZBTElEX0hFQURFUl9UT0tFTgBJTlZBTElEX1RPS0VOAEZPUkJJRERFTgBFTkhBTkNFX1lPVVJfQ0FMTQBIUEVfSU5WQUxJRF9VUkwAQkxPQ0tFRF9CWV9QQVJFTlRBTF9DT05UUk9MAE1LQ09MAEFDTABIUEVfSU5URVJOQUwAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRV9VTk9GRklDSUFMAEhQRV9PSwBVTkxJTksAVU5MT0NLAFBSSQBSRVRSWV9XSVRIAEhQRV9JTlZBTElEX0NPTlRFTlRfTEVOR1RIAEhQRV9VTkVYUEVDVEVEX0NPTlRFTlRfTEVOR1RIAEZMVVNIAFBST1BQQVRDSABNLVNFQVJDSABVUklfVE9PX0xPTkcAUFJPQ0VTU0lORwBNSVNDRUxMQU5FT1VTX1BFUlNJU1RFTlRfV0FSTklORwBNSVNDRUxMQU5FT1VTX1dBUk5JTkcASFBFX0lOVkFMSURfVFJBTlNGRVJfRU5DT0RJTkcARXhwZWN0ZWQgQ1JMRgBIUEVfSU5WQUxJRF9DSFVOS19TSVpFAE1PVkUAQ09OVElOVUUASFBFX0NCX1NUQVRVU19DT01QTEVURQBIUEVfQ0JfSEVBREVSU19DT01QTEVURQBIUEVfQ0JfVkVSU0lPTl9DT01QTEVURQBIUEVfQ0JfVVJMX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8AAF4TAAAmEwAAMBAAAPAXAACdEwAAFRIAADkXAADwEgAAChAAAHUSAACtEgAAghMAAE8UAAB/EAAAoBUAACMUAACJEgAAixQAAE0VAADUEQAAzxQAABAYAADJFgAA3BYAAMERAADgFwAAuxQAAHQUAAB8FQAA5RQAAAgXAAAfEAAAZRUAAKMUAAAoFQAAAhUAAJkVAAAsEAAAixkAAE8PAADUDgAAahAAAM4QAAACFwAAiQ4AAG4TAAAcEwAAZhQAAFYXAADBEwAAzRMAAGwTAABoFwAAZhcAAF8XAAAiEwAAzg8AAGkOAADYDgAAYxYAAMsTAACqDgAAKBcAACYXAADFEwAAXRYAAOgRAABnEwAAZRMAAPIWAABzEwAAHRcAAPkWAADzEQAAzw4AAM4VAAAMEgAAsxEAAKURAABhEAAAMhcAALsTAEH5NQsBAQBBkDYL4AEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB/TcLAQEAQZE4C14CAwICAgICAAACAgACAgACAgICAgICAgICAAQAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEH9OQsBAQBBkToLXgIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAQfA7Cw1sb3NlZWVwLWFsaXZlAEGJPAsBAQBBoDwL4AEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBiT4LAQEAQaA+C+cBAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAEGwwAALXwEBAAEBAQEBAAABAQABAQABAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAEGQwgALIWVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgBBwMIACy1yYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AQfnCAAsFAQIAAQMAQZDDAAvgAQQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH5xAALBQECAAEDAEGQxQAL4AEEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cYACwQBAAABAEGRxwAL3wEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH6yAALBAEAAAIAQZDJAAtfAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAQfrKAAsEAQAAAQBBkMsACwEBAEGqywALQQIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEH6zAALBAEAAAEAQZDNAAsBAQBBms0ACwYCAAAAAAIAQbHNAAs6AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB8M4AC5YBTk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRU9SRElSRUNUT1JUUkNIUEFSQU1FVEVSVVJDRUJTQ1JJQkVBUkRPV05BQ0VJTkROS0NLVUJTQ1JJQkVIVFRQL0FEVFAv", "base64"); } }); // viewer/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js var require_llhttp_simd_wasm = __commonJS({ "viewer/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js"(exports, module) { "use strict"; var { Buffer: Buffer2 } = __require("node:buffer"); module.exports = Buffer2.from("AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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PgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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iQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB9ysPC0GQMQ8LQdcxDwtBoi0PC0HUJw8LQeArDwtBnywPC0HrMQ8LQdUfDwtByjEPC0HeJQ8LQdQeDwtB9BwPC0GnMg8LQbEdDwtBoB0PC0G5MQ8LQbwwDwtBkiEPC0GzJg8LQeksDwtBrB4PC0HUKw8LQfcmDwtBgCYPC0GwIQ8LQf4eDwtBjSMPC0GJLQ8LQfciDwtBoDEPC0GuHw8LQcYlDwtB6B4PC0GTIg8LQcIvDwtBwx0PC0GLLA8LQeEdDwtBjS8PC0HqIQ8LQbQtDwtB0i8PC0HfMg8LQdIyDwtB8DAPC0GpIg8LQfkjDwtBmR4PC0G1LA8LQZswDwtBkjIPC0G2Kw8LQcIiDwtB+DIPC0GeJQ8LQdAiDwtBuh4PC0GBHg8LAAtB1iEhAQsgAQsWACAAIAAtAC1B/gFxIAFBAEdyOgAtCxkAIAAgAC0ALUH9AXEgAUEAR0EBdHI6AC0LGQAgACAALQAtQfsBcSABQQBHQQJ0cjoALQsZACAAIAAtAC1B9wFxIAFBAEdBA3RyOgAtCz4BAn8CQCAAKAI4IgNFDQAgAygCBCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBxhE2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCCCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB9go2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCDCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB7Ro2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCECIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBlRA2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCFCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBqhs2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCGCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB7RM2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCKCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB9gg2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCHCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBwhk2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCICIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBlBQ2AhBBGCEECyAEC1kBAn8CQCAALQAoQQFGDQAgAC8BMiIBQeQAa0HkAEkNACABQcwBRg0AIAFBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhAiAAQYgEcUGABEYNACAAQShxRSECCyACC4wBAQJ/AkACQAJAIAAtACpFDQAgAC0AK0UNACAALwEwIgFBAnFFDQEMAgsgAC8BMCIBQQFxRQ0BC0EBIQIgAC0AKEEBRg0AIAAvATIiAEHkAGtB5ABJDQAgAEHMAUYNACAAQbACRg0AIAFBwABxDQBBACECIAFBiARxQYAERg0AIAFBKHFBAEchAgsgAgtzACAAQRBq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAA/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAAQTBq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAAQSBq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAAQd0BNgIcCwYAIAAQMguaLQELfyMAQRBrIgokAEGk0AAoAgAiCUUEQEHk0wAoAgAiBUUEQEHw0wBCfzcCAEHo0wBCgICEgICAwAA3AgBB5NMAIApBCGpBcHFB2KrVqgVzIgU2AgBB+NMAQQA2AgBByNMAQQA2AgALQczTAEGA1AQ2AgBBnNAAQYDUBDYCAEGw0AAgBTYCAEGs0ABBfzYCAEHQ0wBBgKwDNgIAA0AgAUHI0ABqIAFBvNAAaiICNgIAIAIgAUG00ABqIgM2AgAgAUHA0ABqIAM2AgAgAUHQ0ABqIAFBxNAAaiIDNgIAIAMgAjYCACABQdjQAGogAUHM0ABqIgI2AgAgAiADNgIAIAFB1NAAaiACNgIAIAFBIGoiAUGAAkcNAAtBjNQEQcGrAzYCAEGo0ABB9NMAKAIANgIAQZjQAEHAqwM2AgBBpNAAQYjUBDYCAEHM/wdBODYCAEGI1AQhCQsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAQewBTQRAQYzQACgCACIGQRAgAEETakFwcSAAQQtJGyIEQQN2IgB2IgFBA3EEQAJAIAFBAXEgAHJBAXMiAkEDdCIAQbTQAGoiASAAQbzQAGooAgAiACgCCCIDRgRAQYzQACAGQX4gAndxNgIADAELIAEgAzYCCCADIAE2AgwLIABBCGohASAAIAJBA3QiAkEDcjYCBCAAIAJqIgAgACgCBEEBcjYCBAwRC0GU0AAoAgAiCCAETw0BIAEEQAJAQQIgAHQiAkEAIAJrciABIAB0cWgiAEEDdCICQbTQAGoiASACQbzQAGooAgAiAigCCCIDRgRAQYzQACAGQX4gAHdxIgY2AgAMAQsgASADNgIIIAMgATYCDAsgAiAEQQNyNgIEIABBA3QiACAEayEFIAAgAmogBTYCACACIARqIgQgBUEBcjYCBCAIBEAgCEF4cUG00ABqIQBBoNAAKAIAIQMCf0EBIAhBA3Z0IgEgBnFFBEBBjNAAIAEgBnI2AgAgAAwBCyAAKAIICyIBIAM2AgwgACADNgIIIAMgADYCDCADIAE2AggLIAJBCGohAUGg0AAgBDYCAEGU0AAgBTYCAAwRC0GQ0AAoAgAiC0UNASALaEECdEG80gBqKAIAIgAoAgRBeHEgBGshBSAAIQIDQAJAIAIoAhAiAUUEQCACQRRqKAIAIgFFDQELIAEoAgRBeHEgBGsiAyAFSSECIAMgBSACGyEFIAEgACACGyEAIAEhAgwBCwsgACgCGCEJIAAoAgwiAyAARwRAQZzQACgCABogAyAAKAIIIgE2AgggASADNgIMDBALIABBFGoiAigCACIBRQRAIAAoAhAiAUUNAyAAQRBqIQILA0AgAiEHIAEiA0EUaiICKAIAIgENACADQRBqIQIgAygCECIBDQALIAdBADYCAAwPC0F/IQQgAEG/f0sNACAAQRNqIgFBcHEhBEGQ0AAoAgAiCEUNAEEAIARrIQUCQAJAAkACf0EAIARBgAJJDQAaQR8gBEH///8HSw0AGiAEQSYgAUEIdmciAGt2QQFxIABBAXRrQT5qCyIGQQJ0QbzSAGooAgAiAkUEQEEAIQFBACEDDAELQQAhASAEQRkgBkEBdmtBACAGQR9HG3QhAEEAIQMDQAJAIAIoAgRBeHEgBGsiByAFTw0AIAIhAyAHIgUNAEEAIQUgAiEBDAMLIAEgAkEUaigCACIHIAcgAiAAQR12QQRxakEQaigCACICRhsgASAHGyEBIABBAXQhACACDQALCyABIANyRQRAQQAhA0ECIAZ0IgBBACAAa3IgCHEiAEUNAyAAaEECdEG80gBqKAIAIQELIAFFDQELA0AgASgCBEF4cSAEayICIAVJIQAgAiAFIAAbIQUgASADIAAbIQMgASgCECIABH8gAAUgAUEUaigCAAsiAQ0ACwsgA0UNACAFQZTQACgCACAEa08NACADKAIYIQcgAyADKAIMIgBHBEBBnNAAKAIAGiAAIAMoAggiATYCCCABIAA2AgwMDgsgA0EUaiICKAIAIgFFBEAgAygCECIBRQ0DIANBEGohAgsDQCACIQYgASIAQRRqIgIoAgAiAQ0AIABBEGohAiAAKAIQIgENAAsgBkEANgIADA0LQZTQACgCACIDIARPBEBBoNAAKAIAIQECQCADIARrIgJBEE8EQCABIARqIgAgAkEBcjYCBCABIANqIAI2AgAgASAEQQNyNgIEDAELIAEgA0EDcjYCBCABIANqIgAgACgCBEEBcjYCBEEAIQBBACECC0GU0AAgAjYCAEGg0AAgADYCACABQQhqIQEMDwtBmNAAKAIAIgMgBEsEQCAEIAlqIgAgAyAEayIBQQFyNgIEQaTQACAANgIAQZjQACABNgIAIAkgBEEDcjYCBCAJQQhqIQEMDwtBACEBIAQCf0Hk0wAoAgAEQEHs0wAoAgAMAQtB8NMAQn83AgBB6NMAQoCAhICAgMAANwIAQeTTACAKQQxqQXBxQdiq1aoFczYCAEH40wBBADYCAEHI0wBBADYCAEGAgAQLIgAgBEHHAGoiBWoiBkEAIABrIgdxIgJPBEBB/NMAQTA2AgAMDwsCQEHE0wAoAgAiAUUNAEG80wAoAgAiCCACaiEAIAAgAU0gACAIS3ENAEEAIQFB/NMAQTA2AgAMDwtByNMALQAAQQRxDQQCQAJAIAkEQEHM0wAhAQNAIAEoAgAiACAJTQRAIAAgASgCBGogCUsNAwsgASgCCCIBDQALC0EAEDMiAEF/Rg0FIAIhBkHo0wAoAgAiAUEBayIDIABxBEAgAiAAayAAIANqQQAgAWtxaiEGCyAEIAZPDQUgBkH+////B0sNBUHE0wAoAgAiAwRAQbzTACgCACIHIAZqIQEgASAHTQ0GIAEgA0sNBgsgBhAzIgEgAEcNAQwHCyAGIANrIAdxIgZB/v///wdLDQQgBhAzIQAgACABKAIAIAEoAgRqRg0DIAAhAQsCQCAGIARByABqTw0AIAFBf0YNAEHs0wAoAgAiACAFIAZrakEAIABrcSIAQf7///8HSwRAIAEhAAwHCyAAEDNBf0cEQCAAIAZqIQYgASEADAcLQQAgBmsQMxoMBAsgASIAQX9HDQUMAwtBACEDDAwLQQAhAAwKCyAAQX9HDQILQcjTAEHI0wAoAgBBBHI2AgALIAJB/v///wdLDQEgAhAzIQBBABAzIQEgAEF/Rg0BIAFBf0YNASAAIAFPDQEgASAAayIGIARBOGpNDQELQbzTAEG80wAoAgAgBmoiATYCAEHA0wAoAgAgAUkEQEHA0wAgATYCAAsCQAJAAkBBpNAAKAIAIgIEQEHM0wAhAQNAIAAgASgCACIDIAEoAgQiBWpGDQIgASgCCCIBDQALDAILQZzQACgCACIBQQBHIAAgAU9xRQRAQZzQACAANgIAC0EAIQFB0NMAIAY2AgBBzNMAIAA2AgBBrNAAQX82AgBBsNAAQeTTACgCADYCAEHY0wBBADYCAANAIAFByNAAaiABQbzQAGoiAjYCACACIAFBtNAAaiIDNgIAIAFBwNAAaiADNgIAIAFB0NAAaiABQcTQAGoiAzYCACADIAI2AgAgAUHY0ABqIAFBzNAAaiICNgIAIAIgAzYCACABQdTQAGogAjYCACABQSBqIgFBgAJHDQALQXggAGtBD3EiASAAaiICIAZBOGsiAyABayIBQQFyNgIEQajQAEH00wAoAgA2AgBBmNAAIAE2AgBBpNAAIAI2AgAgACADakE4NgIEDAILIAAgAk0NACACIANJDQAgASgCDEEIcQ0AQXggAmtBD3EiACACaiIDQZjQACgCACAGaiIHIABrIgBBAXI2AgQgASAFIAZqNgIEQajQAEH00wAoAgA2AgBBmNAAIAA2AgBBpNAAIAM2AgAgAiAHakE4NgIEDAELIABBnNAAKAIASQRAQZzQACAANgIACyAAIAZqIQNBzNMAIQECQAJAAkADQCADIAEoAgBHBEAgASgCCCIBDQEMAgsLIAEtAAxBCHFFDQELQczTACEBA0AgASgCACIDIAJNBEAgAyABKAIEaiIFIAJLDQMLIAEoAgghAQwACwALIAEgADYCACABIAEoAgQgBmo2AgQgAEF4IABrQQ9xaiIJIARBA3I2AgQgA0F4IANrQQ9xaiIGIAQgCWoiBGshASACIAZGBEBBpNAAIAQ2AgBBmNAAQZjQACgCACABaiIANgIAIAQgAEEBcjYCBAwIC0Gg0AAoAgAgBkYEQEGg0AAgBDYCAEGU0ABBlNAAKAIAIAFqIgA2AgAgBCAAQQFyNgIEIAAgBGogADYCAAwICyAGKAIEIgVBA3FBAUcNBiAFQXhxIQggBUH/AU0EQCAFQQN2IQMgBigCCCIAIAYoAgwiAkYEQEGM0ABBjNAAKAIAQX4gA3dxNgIADAcLIAIgADYCCCAAIAI2AgwMBgsgBigCGCEHIAYgBigCDCIARwRAIAAgBigCCCICNgIIIAIgADYCDAwFCyAGQRRqIgIoAgAiBUUEQCAGKAIQIgVFDQQgBkEQaiECCwNAIAIhAyAFIgBBFGoiAigCACIFDQAgAEEQaiECIAAoAhAiBQ0ACyADQQA2AgAMBAtBeCAAa0EPcSIBIABqIgcgBkE4ayIDIAFrIgFBAXI2AgQgACADakE4NgIEIAIgBUE3IAVrQQ9xakE/ayIDIAMgAkEQakkbIgNBIzYCBEGo0ABB9NMAKAIANgIAQZjQACABNgIAQaTQACAHNgIAIANBEGpB1NMAKQIANwIAIANBzNMAKQIANwIIQdTTACADQQhqNgIAQdDTACAGNgIAQczTACAANgIAQdjTAEEANgIAIANBJGohAQNAIAFBBzYCACAFIAFBBGoiAUsNAAsgAiADRg0AIAMgAygCBEF+cTYCBCADIAMgAmsiBTYCACACIAVBAXI2AgQgBUH/AU0EQCAFQXhxQbTQAGohAAJ/QYzQACgCACIBQQEgBUEDdnQiA3FFBEBBjNAAIAEgA3I2AgAgAAwBCyAAKAIICyIBIAI2AgwgACACNgIIIAIgADYCDCACIAE2AggMAQtBHyEBIAVB////B00EQCAFQSYgBUEIdmciAGt2QQFxIABBAXRrQT5qIQELIAIgATYCHCACQgA3AhAgAUECdEG80gBqIQBBkNAAKAIAIgNBASABdCIGcUUEQCAAIAI2AgBBkNAAIAMgBnI2AgAgAiAANgIYIAIgAjYCCCACIAI2AgwMAQsgBUEZIAFBAXZrQQAgAUEfRxt0IQEgACgCACEDAkADQCADIgAoAgRBeHEgBUYNASABQR12IQMgAUEBdCEBIAAgA0EEcWpBEGoiBigCACIDDQALIAYgAjYCACACIAA2AhggAiACNgIMIAIgAjYCCAwBCyAAKAIIIgEgAjYCDCAAIAI2AgggAkEANgIYIAIgADYCDCACIAE2AggLQZjQACgCACIBIARNDQBBpNAAKAIAIgAgBGoiAiABIARrIgFBAXI2AgRBmNAAIAE2AgBBpNAAIAI2AgAgACAEQQNyNgIEIABBCGohAQwIC0EAIQFB/NMAQTA2AgAMBwtBACEACyAHRQ0AAkAgBigCHCICQQJ0QbzSAGoiAygCACAGRgRAIAMgADYCACAADQFBkNAAQZDQACgCAEF+IAJ3cTYCAAwCCyAHQRBBFCAHKAIQIAZGG2ogADYCACAARQ0BCyAAIAc2AhggBigCECICBEAgACACNgIQIAIgADYCGAsgBkEUaigCACICRQ0AIABBFGogAjYCACACIAA2AhgLIAEgCGohASAGIAhqIgYoAgQhBQsgBiAFQX5xNgIEIAEgBGogATYCACAEIAFBAXI2AgQgAUH/AU0EQCABQXhxQbTQAGohAAJ/QYzQACgCACICQQEgAUEDdnQiAXFFBEBBjNAAIAEgAnI2AgAgAAwBCyAAKAIICyIBIAQ2AgwgACAENgIIIAQgADYCDCAEIAE2AggMAQtBHyEFIAFB////B00EQCABQSYgAUEIdmciAGt2QQFxIABBAXRrQT5qIQULIAQgBTYCHCAEQgA3AhAgBUECdEG80gBqIQBBkNAAKAIAIgJBASAFdCIDcUUEQCAAIAQ2AgBBkNAAIAIgA3I2AgAgBCAANgIYIAQgBDYCCCAEIAQ2AgwMAQsgAUEZIAVBAXZrQQAgBUEfRxt0IQUgACgCACEAAkADQCAAIgIoAgRBeHEgAUYNASAFQR12IQAgBUEBdCEFIAIgAEEEcWpBEGoiAygCACIADQALIAMgBDYCACAEIAI2AhggBCAENgIMIAQgBDYCCAwBCyACKAIIIgAgBDYCDCACIAQ2AgggBEEANgIYIAQgAjYCDCAEIAA2AggLIAlBCGohAQwCCwJAIAdFDQACQCADKAIcIgFBAnRBvNIAaiICKAIAIANGBEAgAiAANgIAIAANAUGQ0AAgCEF+IAF3cSIINgIADAILIAdBEEEUIAcoAhAgA0YbaiAANgIAIABFDQELIAAgBzYCGCADKAIQIgEEQCAAIAE2AhAgASAANgIYCyADQRRqKAIAIgFFDQAgAEEUaiABNgIAIAEgADYCGAsCQCAFQQ9NBEAgAyAEIAVqIgBBA3I2AgQgACADaiIAIAAoAgRBAXI2AgQMAQsgAyAEaiICIAVBAXI2AgQgAyAEQQNyNgIEIAIgBWogBTYCACAFQf8BTQRAIAVBeHFBtNAAaiEAAn9BjNAAKAIAIgFBASAFQQN2dCIFcUUEQEGM0AAgASAFcjYCACAADAELIAAoAggLIgEgAjYCDCAAIAI2AgggAiAANgIMIAIgATYCCAwBC0EfIQEgBUH///8HTQRAIAVBJiAFQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAQsgAiABNgIcIAJCADcCECABQQJ0QbzSAGohAEEBIAF0IgQgCHFFBEAgACACNgIAQZDQACAEIAhyNgIAIAIgADYCGCACIAI2AgggAiACNgIMDAELIAVBGSABQQF2a0EAIAFBH0cbdCEBIAAoAgAhBAJAA0AgBCIAKAIEQXhxIAVGDQEgAUEddiEEIAFBAXQhASAAIARBBHFqQRBqIgYoAgAiBA0ACyAGIAI2AgAgAiAANgIYIAIgAjYCDCACIAI2AggMAQsgACgCCCIBIAI2AgwgACACNgIIIAJBADYCGCACIAA2AgwgAiABNgIICyADQQhqIQEMAQsCQCAJRQ0AAkAgACgCHCIBQQJ0QbzSAGoiAigCACAARgRAIAIgAzYCACADDQFBkNAAIAtBfiABd3E2AgAMAgsgCUEQQRQgCSgCECAARhtqIAM2AgAgA0UNAQsgAyAJNgIYIAAoAhAiAQRAIAMgATYCECABIAM2AhgLIABBFGooAgAiAUUNACADQRRqIAE2AgAgASADNgIYCwJAIAVBD00EQCAAIAQgBWoiAUEDcjYCBCAAIAFqIgEgASgCBEEBcjYCBAwBCyAAIARqIgcgBUEBcjYCBCAAIARBA3I2AgQgBSAHaiAFNgIAIAgEQCAIQXhxQbTQAGohAUGg0AAoAgAhAwJ/QQEgCEEDdnQiAiAGcUUEQEGM0AAgAiAGcjYCACABDAELIAEoAggLIgIgAzYCDCABIAM2AgggAyABNgIMIAMgAjYCCAtBoNAAIAc2AgBBlNAAIAU2AgALIABBCGohAQsgCkEQaiQAIAELQwAgAEUEQD8AQRB0DwsCQCAAQf//A3ENACAAQQBIDQAgAEEQdkAAIgBBf0YEQEH80wBBMDYCAEF/DwsgAEEQdA8LAAsL3D8iAEGACAsJAQAAAAIAAAADAEGUCAsFBAAAAAUAQaQICwkGAAAABwAAAAgAQdwIC4otSW52YWxpZCBjaGFyIGluIHVybCBxdWVyeQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2JvZHkAQ29udGVudC1MZW5ndGggb3ZlcmZsb3cAQ2h1bmsgc2l6ZSBvdmVyZmxvdwBSZXNwb25zZSBvdmVyZmxvdwBJbnZhbGlkIG1ldGhvZCBmb3IgSFRUUC94LnggcmVxdWVzdABJbnZhbGlkIG1ldGhvZCBmb3IgUlRTUC94LnggcmVxdWVzdABFeHBlY3RlZCBTT1VSQ0UgbWV0aG9kIGZvciBJQ0UveC54IHJlcXVlc3QASW52YWxpZCBjaGFyIGluIHVybCBmcmFnbWVudCBzdGFydABFeHBlY3RlZCBkb3QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9zdGF0dXMASW52YWxpZCByZXNwb25zZSBzdGF0dXMASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucwBVc2VyIGNhbGxiYWNrIGVycm9yAGBvbl9yZXNldGAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2hlYWRlcmAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfYmVnaW5gIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwBB+TULAQEAQZA2C+ABAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQf03CwEBAEGROAteAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgBB/TkLAQEAQZE6C14CAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEHwOwsNbG9zZWVlcC1hbGl2ZQBBiTwLAQEAQaA8C+ABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQYk+CwEBAEGgPgvnAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZABBsMAAC18BAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQBBkMIACyFlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AQcDCAAstcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQoNClNNDQoNClRUUC9DRS9UU1AvAEH5wgALBQECAAEDAEGQwwAL4AEEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cQACwUBAgABAwBBkMUAC+ABBAEBBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQfnGAAsEAQAAAQBBkccAC98BAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+sgACwQBAAACAEGQyQALXwMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAEH6ygALBAEAAAEAQZDLAAsBAQBBqssAC0ECAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB+swACwQBAAABAEGQzQALAQEAQZrNAAsGAgAAAAACAEGxzQALOgMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQfDOAAuWAU5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==", "base64"); } }); // viewer/node_modules/undici/lib/web/fetch/constants.js var require_constants3 = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/constants.js"(exports, module) { "use strict"; var corsSafeListedMethods = ( /** @type {const} */ ["GET", "HEAD", "POST"] ); var corsSafeListedMethodsSet = new Set(corsSafeListedMethods); var nullBodyStatus = ( /** @type {const} */ [101, 204, 205, 304] ); var redirectStatus = ( /** @type {const} */ [301, 302, 303, 307, 308] ); var redirectStatusSet = new Set(redirectStatus); var badPorts = ( /** @type {const} */ [ "1", "7", "9", "11", "13", "15", "17", "19", "20", "21", "22", "23", "25", "37", "42", "43", "53", "69", "77", "79", "87", "95", "101", "102", "103", "104", "109", "110", "111", "113", "115", "117", "119", "123", "135", "137", "139", "143", "161", "179", "389", "427", "465", "512", "513", "514", "515", "526", "530", "531", "532", "540", "548", "554", "556", "563", "587", "601", "636", "989", "990", "993", "995", "1719", "1720", "1723", "2049", "3659", "4045", "4190", "5060", "5061", "6000", "6566", "6665", "6666", "6667", "6668", "6669", "6679", "6697", "10080" ] ); var badPortsSet = new Set(badPorts); var referrerPolicy = ( /** @type {const} */ [ "", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url" ] ); var referrerPolicySet = new Set(referrerPolicy); var requestRedirect = ( /** @type {const} */ ["follow", "manual", "error"] ); var safeMethods = ( /** @type {const} */ ["GET", "HEAD", "OPTIONS", "TRACE"] ); var safeMethodsSet = new Set(safeMethods); var requestMode = ( /** @type {const} */ ["navigate", "same-origin", "no-cors", "cors"] ); var requestCredentials = ( /** @type {const} */ ["omit", "same-origin", "include"] ); var requestCache = ( /** @type {const} */ [ "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" ] ); var requestBodyHeader = ( /** @type {const} */ [ "content-encoding", "content-language", "content-location", "content-type", // See https://github.com/nodejs/undici/issues/2021 // 'Content-Length' is a forbidden header name, which is typically // removed in the Headers implementation. However, undici doesn't // filter out headers, so we add it here. "content-length" ] ); var requestDuplex = ( /** @type {const} */ [ "half" ] ); var forbiddenMethods = ( /** @type {const} */ ["CONNECT", "TRACE", "TRACK"] ); var forbiddenMethodsSet = new Set(forbiddenMethods); var subresource = ( /** @type {const} */ [ "audio", "audioworklet", "font", "image", "manifest", "paintworklet", "script", "style", "track", "video", "xslt", "" ] ); var subresourceSet = new Set(subresource); module.exports = { subresource, forbiddenMethods, requestBodyHeader, referrerPolicy, requestRedirect, requestMode, requestCredentials, requestCache, redirectStatus, corsSafeListedMethods, nullBodyStatus, safeMethods, badPorts, requestDuplex, subresourceSet, badPortsSet, redirectStatusSet, corsSafeListedMethodsSet, safeMethodsSet, forbiddenMethodsSet, referrerPolicySet }; } }); // viewer/node_modules/undici/lib/web/fetch/global.js var require_global = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/global.js"(exports, module) { "use strict"; var globalOrigin = /* @__PURE__ */ Symbol.for("undici.globalOrigin.1"); function getGlobalOrigin() { return globalThis[globalOrigin]; } function setGlobalOrigin(newOrigin) { if (newOrigin === void 0) { Object.defineProperty(globalThis, globalOrigin, { value: void 0, writable: true, enumerable: false, configurable: false }); return; } const parsedURL = new URL(newOrigin); if (parsedURL.protocol !== "http:" && parsedURL.protocol !== "https:") { throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`); } Object.defineProperty(globalThis, globalOrigin, { value: parsedURL, writable: true, enumerable: false, configurable: false }); } module.exports = { getGlobalOrigin, setGlobalOrigin }; } }); // viewer/node_modules/undici/lib/web/fetch/data-url.js var require_data_url = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/data-url.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var encoder = new TextEncoder(); var HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+\-.^_|~A-Za-z0-9]+$/; var HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/; var ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g; var HTTP_QUOTED_STRING_TOKENS = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/; function dataURLProcessor(dataURL) { assert(dataURL.protocol === "data:"); let input = URLSerializer(dataURL, true); input = input.slice(5); const position = { position: 0 }; let mimeType = collectASequenceOfCodePointsFast( ",", input, position ); const mimeTypeLength = mimeType.length; mimeType = removeASCIIWhitespace(mimeType, true, true); if (position.position >= input.length) { return "failure"; } position.position++; const encodedBody = input.slice(mimeTypeLength + 1); let body = stringPercentDecode(encodedBody); if (/;(\u0020){0,}base64$/i.test(mimeType)) { const stringBody = isomorphicDecode(body); body = forgivingBase64(stringBody); if (body === "failure") { return "failure"; } mimeType = mimeType.slice(0, -6); mimeType = mimeType.replace(/(\u0020)+$/, ""); mimeType = mimeType.slice(0, -1); } if (mimeType.startsWith(";")) { mimeType = "text/plain" + mimeType; } let mimeTypeRecord = parseMIMEType(mimeType); if (mimeTypeRecord === "failure") { mimeTypeRecord = parseMIMEType("text/plain;charset=US-ASCII"); } return { mimeType: mimeTypeRecord, body }; } function URLSerializer(url, excludeFragment = false) { if (!excludeFragment) { return url.href; } const href = url.href; const hashLength = url.hash.length; const serialized = hashLength === 0 ? href : href.substring(0, href.length - hashLength); if (!hashLength && href.endsWith("#")) { return serialized.slice(0, -1); } return serialized; } function collectASequenceOfCodePoints(condition, input, position) { let result = ""; while (position.position < input.length && condition(input[position.position])) { result += input[position.position]; position.position++; } return result; } function collectASequenceOfCodePointsFast(char, input, position) { const idx = input.indexOf(char, position.position); const start = position.position; if (idx === -1) { position.position = input.length; return input.slice(start); } position.position = idx; return input.slice(start, position.position); } function stringPercentDecode(input) { const bytes2 = encoder.encode(input); return percentDecode(bytes2); } function isHexCharByte(byte) { return byte >= 48 && byte <= 57 || byte >= 65 && byte <= 70 || byte >= 97 && byte <= 102; } function hexByteToNumber(byte) { return ( // 0-9 byte >= 48 && byte <= 57 ? byte - 48 : (byte & 223) - 55 ); } function percentDecode(input) { const length2 = input.length; const output = new Uint8Array(length2); let j = 0; for (let i = 0; i < length2; ++i) { const byte = input[i]; if (byte !== 37) { output[j++] = byte; } else if (byte === 37 && !(isHexCharByte(input[i + 1]) && isHexCharByte(input[i + 2]))) { output[j++] = 37; } else { output[j++] = hexByteToNumber(input[i + 1]) << 4 | hexByteToNumber(input[i + 2]); i += 2; } } return length2 === j ? output : output.subarray(0, j); } function parseMIMEType(input) { input = removeHTTPWhitespace(input, true, true); const position = { position: 0 }; const type = collectASequenceOfCodePointsFast( "/", input, position ); if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { return "failure"; } if (position.position > input.length) { return "failure"; } position.position++; let subtype = collectASequenceOfCodePointsFast( ";", input, position ); subtype = removeHTTPWhitespace(subtype, false, true); if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { return "failure"; } const typeLowercase = type.toLowerCase(); const subtypeLowercase = subtype.toLowerCase(); const mimeType = { type: typeLowercase, subtype: subtypeLowercase, /** @type {Map} */ parameters: /* @__PURE__ */ new Map(), // https://mimesniff.spec.whatwg.org/#mime-type-essence essence: `${typeLowercase}/${subtypeLowercase}` }; while (position.position < input.length) { position.position++; collectASequenceOfCodePoints( // https://fetch.spec.whatwg.org/#http-whitespace (char) => HTTP_WHITESPACE_REGEX.test(char), input, position ); let parameterName = collectASequenceOfCodePoints( (char) => char !== ";" && char !== "=", input, position ); parameterName = parameterName.toLowerCase(); if (position.position < input.length) { if (input[position.position] === ";") { continue; } position.position++; } if (position.position > input.length) { break; } let parameterValue = null; if (input[position.position] === '"') { parameterValue = collectAnHTTPQuotedString(input, position, true); collectASequenceOfCodePointsFast( ";", input, position ); } else { parameterValue = collectASequenceOfCodePointsFast( ";", input, position ); parameterValue = removeHTTPWhitespace(parameterValue, false, true); if (parameterValue.length === 0) { continue; } } if (parameterName.length !== 0 && HTTP_TOKEN_CODEPOINTS.test(parameterName) && (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && !mimeType.parameters.has(parameterName)) { mimeType.parameters.set(parameterName, parameterValue); } } return mimeType; } function forgivingBase64(data) { data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, ""); let dataLength = data.length; if (dataLength % 4 === 0) { if (data.charCodeAt(dataLength - 1) === 61) { --dataLength; if (data.charCodeAt(dataLength - 1) === 61) { --dataLength; } } } if (dataLength % 4 === 1) { return "failure"; } if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { return "failure"; } const buffer = Buffer.from(data, "base64"); return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); } function collectAnHTTPQuotedString(input, position, extractValue) { const positionStart = position.position; let value = ""; assert(input[position.position] === '"'); position.position++; while (true) { value += collectASequenceOfCodePoints( (char) => char !== '"' && char !== "\\", input, position ); if (position.position >= input.length) { break; } const quoteOrBackslash = input[position.position]; position.position++; if (quoteOrBackslash === "\\") { if (position.position >= input.length) { value += "\\"; break; } value += input[position.position]; position.position++; } else { assert(quoteOrBackslash === '"'); break; } } if (extractValue) { return value; } return input.slice(positionStart, position.position); } function serializeAMimeType(mimeType) { assert(mimeType !== "failure"); const { parameters, essence } = mimeType; let serialization = essence; for (let [name, value] of parameters.entries()) { serialization += ";"; serialization += name; serialization += "="; if (!HTTP_TOKEN_CODEPOINTS.test(value)) { value = value.replace(/(\\|")/g, "\\$1"); value = '"' + value; value += '"'; } serialization += value; } return serialization; } function isHTTPWhiteSpace(char) { return char === 13 || char === 10 || char === 9 || char === 32; } function removeHTTPWhitespace(str, leading = true, trailing = true) { return removeChars(str, leading, trailing, isHTTPWhiteSpace); } function isASCIIWhitespace(char) { return char === 13 || char === 10 || char === 9 || char === 12 || char === 32; } function removeASCIIWhitespace(str, leading = true, trailing = true) { return removeChars(str, leading, trailing, isASCIIWhitespace); } function removeChars(str, leading, trailing, predicate) { let lead = 0; let trail = str.length - 1; if (leading) { while (lead < str.length && predicate(str.charCodeAt(lead))) lead++; } if (trailing) { while (trail > 0 && predicate(str.charCodeAt(trail))) trail--; } return lead === 0 && trail === str.length - 1 ? str : str.slice(lead, trail + 1); } function isomorphicDecode(input) { const length2 = input.length; if ((2 << 15) - 1 > length2) { return String.fromCharCode.apply(null, input); } let result = ""; let i = 0; let addition = (2 << 15) - 1; while (i < length2) { if (i + addition > length2) { addition = length2 - i; } result += String.fromCharCode.apply(null, input.subarray(i, i += addition)); } return result; } function minimizeSupportedMimeType(mimeType) { switch (mimeType.essence) { case "application/ecmascript": case "application/javascript": case "application/x-ecmascript": case "application/x-javascript": case "text/ecmascript": case "text/javascript": case "text/javascript1.0": case "text/javascript1.1": case "text/javascript1.2": case "text/javascript1.3": case "text/javascript1.4": case "text/javascript1.5": case "text/jscript": case "text/livescript": case "text/x-ecmascript": case "text/x-javascript": return "text/javascript"; case "application/json": case "text/json": return "application/json"; case "image/svg+xml": return "image/svg+xml"; case "text/xml": case "application/xml": return "application/xml"; } if (mimeType.subtype.endsWith("+json")) { return "application/json"; } if (mimeType.subtype.endsWith("+xml")) { return "application/xml"; } return ""; } module.exports = { dataURLProcessor, URLSerializer, collectASequenceOfCodePoints, collectASequenceOfCodePointsFast, stringPercentDecode, parseMIMEType, collectAnHTTPQuotedString, serializeAMimeType, removeChars, removeHTTPWhitespace, minimizeSupportedMimeType, HTTP_TOKEN_CODEPOINTS, isomorphicDecode }; } }); // viewer/node_modules/undici/lib/web/fetch/webidl.js var require_webidl = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/webidl.js"(exports, module) { "use strict"; var { types, inspect } = __require("node:util"); var { markAsUncloneable } = __require("node:worker_threads"); var { toUSVString } = require_util(); var webidl = {}; webidl.converters = {}; webidl.util = {}; webidl.errors = {}; webidl.errors.exception = function(message) { return new TypeError(`${message.header}: ${message.message}`); }; webidl.errors.conversionFailed = function(context) { const plural = context.types.length === 1 ? "" : " one of"; const message = `${context.argument} could not be converted to${plural}: ${context.types.join(", ")}.`; return webidl.errors.exception({ header: context.prefix, message }); }; webidl.errors.invalidArgument = function(context) { return webidl.errors.exception({ header: context.prefix, message: `"${context.value}" is an invalid ${context.type}.` }); }; webidl.brandCheck = function(V, I, opts) { if (opts?.strict !== false) { if (!(V instanceof I)) { const err = new TypeError("Illegal invocation"); err.code = "ERR_INVALID_THIS"; throw err; } } else { if (V?.[Symbol.toStringTag] !== I.prototype[Symbol.toStringTag]) { const err = new TypeError("Illegal invocation"); err.code = "ERR_INVALID_THIS"; throw err; } } }; webidl.argumentLengthCheck = function({ length: length2 }, min, ctx) { if (length2 < min) { throw webidl.errors.exception({ message: `${min} argument${min !== 1 ? "s" : ""} required, but${length2 ? " only" : ""} ${length2} found.`, header: ctx }); } }; webidl.illegalConstructor = function() { throw webidl.errors.exception({ header: "TypeError", message: "Illegal constructor" }); }; webidl.util.Type = function(V) { switch (typeof V) { case "undefined": return "Undefined"; case "boolean": return "Boolean"; case "string": return "String"; case "symbol": return "Symbol"; case "number": return "Number"; case "bigint": return "BigInt"; case "function": case "object": { if (V === null) { return "Null"; } return "Object"; } } }; webidl.util.markAsUncloneable = markAsUncloneable || (() => { }); webidl.util.ConvertToInt = function(V, bitLength, signedness, opts) { let upperBound; let lowerBound; if (bitLength === 64) { upperBound = Math.pow(2, 53) - 1; if (signedness === "unsigned") { lowerBound = 0; } else { lowerBound = Math.pow(-2, 53) + 1; } } else if (signedness === "unsigned") { lowerBound = 0; upperBound = Math.pow(2, bitLength) - 1; } else { lowerBound = Math.pow(-2, bitLength) - 1; upperBound = Math.pow(2, bitLength - 1) - 1; } let x = Number(V); if (x === 0) { x = 0; } if (opts?.enforceRange === true) { if (Number.isNaN(x) || x === Number.POSITIVE_INFINITY || x === Number.NEGATIVE_INFINITY) { throw webidl.errors.exception({ header: "Integer conversion", message: `Could not convert ${webidl.util.Stringify(V)} to an integer.` }); } x = webidl.util.IntegerPart(x); if (x < lowerBound || x > upperBound) { throw webidl.errors.exception({ header: "Integer conversion", message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` }); } return x; } if (!Number.isNaN(x) && opts?.clamp === true) { x = Math.min(Math.max(x, lowerBound), upperBound); if (Math.floor(x) % 2 === 0) { x = Math.floor(x); } else { x = Math.ceil(x); } return x; } if (Number.isNaN(x) || x === 0 && Object.is(0, x) || x === Number.POSITIVE_INFINITY || x === Number.NEGATIVE_INFINITY) { return 0; } x = webidl.util.IntegerPart(x); x = x % Math.pow(2, bitLength); if (signedness === "signed" && x >= Math.pow(2, bitLength) - 1) { return x - Math.pow(2, bitLength); } return x; }; webidl.util.IntegerPart = function(n) { const r = Math.floor(Math.abs(n)); if (n < 0) { return -1 * r; } return r; }; webidl.util.Stringify = function(V) { const type = webidl.util.Type(V); switch (type) { case "Symbol": return `Symbol(${V.description})`; case "Object": return inspect(V); case "String": return `"${V}"`; default: return `${V}`; } }; webidl.sequenceConverter = function(converter) { return (V, prefix, argument, Iterable) => { if (webidl.util.Type(V) !== "Object") { throw webidl.errors.exception({ header: prefix, message: `${argument} (${webidl.util.Stringify(V)}) is not iterable.` }); } const method = typeof Iterable === "function" ? Iterable() : V?.[Symbol.iterator]?.(); const seq = []; let index = 0; if (method === void 0 || typeof method.next !== "function") { throw webidl.errors.exception({ header: prefix, message: `${argument} is not iterable.` }); } while (true) { const { done, value } = method.next(); if (done) { break; } seq.push(converter(value, prefix, `${argument}[${index++}]`)); } return seq; }; }; webidl.recordConverter = function(keyConverter, valueConverter) { return (O, prefix, argument) => { if (webidl.util.Type(O) !== "Object") { throw webidl.errors.exception({ header: prefix, message: `${argument} ("${webidl.util.Type(O)}") is not an Object.` }); } const result = {}; if (!types.isProxy(O)) { const keys2 = [...Object.getOwnPropertyNames(O), ...Object.getOwnPropertySymbols(O)]; for (const key of keys2) { const typedKey = keyConverter(key, prefix, argument); const typedValue = valueConverter(O[key], prefix, argument); result[typedKey] = typedValue; } return result; } const keys = Reflect.ownKeys(O); for (const key of keys) { const desc = Reflect.getOwnPropertyDescriptor(O, key); if (desc?.enumerable) { const typedKey = keyConverter(key, prefix, argument); const typedValue = valueConverter(O[key], prefix, argument); result[typedKey] = typedValue; } } return result; }; }; webidl.interfaceConverter = function(i) { return (V, prefix, argument, opts) => { if (opts?.strict !== false && !(V instanceof i)) { throw webidl.errors.exception({ header: prefix, message: `Expected ${argument} ("${webidl.util.Stringify(V)}") to be an instance of ${i.name}.` }); } return V; }; }; webidl.dictionaryConverter = function(converters) { return (dictionary, prefix, argument) => { const type = webidl.util.Type(dictionary); const dict = {}; if (type === "Null" || type === "Undefined") { return dict; } else if (type !== "Object") { throw webidl.errors.exception({ header: prefix, message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` }); } for (const options of converters) { const { key, defaultValue, required, converter } = options; if (required === true) { if (!Object.hasOwn(dictionary, key)) { throw webidl.errors.exception({ header: prefix, message: `Missing required key "${key}".` }); } } let value = dictionary[key]; const hasDefault = Object.hasOwn(options, "defaultValue"); if (hasDefault && value !== null) { value ??= defaultValue(); } if (required || hasDefault || value !== void 0) { value = converter(value, prefix, `${argument}.${key}`); if (options.allowedValues && !options.allowedValues.includes(value)) { throw webidl.errors.exception({ header: prefix, message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(", ")}.` }); } dict[key] = value; } } return dict; }; }; webidl.nullableConverter = function(converter) { return (V, prefix, argument) => { if (V === null) { return V; } return converter(V, prefix, argument); }; }; webidl.converters.DOMString = function(V, prefix, argument, opts) { if (V === null && opts?.legacyNullToEmptyString) { return ""; } if (typeof V === "symbol") { throw webidl.errors.exception({ header: prefix, message: `${argument} is a symbol, which cannot be converted to a DOMString.` }); } return String(V); }; webidl.converters.ByteString = function(V, prefix, argument) { const x = webidl.converters.DOMString(V, prefix, argument); for (let index = 0; index < x.length; index++) { if (x.charCodeAt(index) > 255) { throw new TypeError( `Cannot convert argument to a ByteString because the character at index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` ); } } return x; }; webidl.converters.USVString = toUSVString; webidl.converters.boolean = function(V) { const x = Boolean(V); return x; }; webidl.converters.any = function(V) { return V; }; webidl.converters["long long"] = function(V, prefix, argument) { const x = webidl.util.ConvertToInt(V, 64, "signed", void 0, prefix, argument); return x; }; webidl.converters["unsigned long long"] = function(V, prefix, argument) { const x = webidl.util.ConvertToInt(V, 64, "unsigned", void 0, prefix, argument); return x; }; webidl.converters["unsigned long"] = function(V, prefix, argument) { const x = webidl.util.ConvertToInt(V, 32, "unsigned", void 0, prefix, argument); return x; }; webidl.converters["unsigned short"] = function(V, prefix, argument, opts) { const x = webidl.util.ConvertToInt(V, 16, "unsigned", opts, prefix, argument); return x; }; webidl.converters.ArrayBuffer = function(V, prefix, argument, opts) { if (webidl.util.Type(V) !== "Object" || !types.isAnyArrayBuffer(V)) { throw webidl.errors.conversionFailed({ prefix, argument: `${argument} ("${webidl.util.Stringify(V)}")`, types: ["ArrayBuffer"] }); } if (opts?.allowShared === false && types.isSharedArrayBuffer(V)) { throw webidl.errors.exception({ header: "ArrayBuffer", message: "SharedArrayBuffer is not allowed." }); } if (V.resizable || V.growable) { throw webidl.errors.exception({ header: "ArrayBuffer", message: "Received a resizable ArrayBuffer." }); } return V; }; webidl.converters.TypedArray = function(V, T, prefix, name, opts) { if (webidl.util.Type(V) !== "Object" || !types.isTypedArray(V) || V.constructor.name !== T.name) { throw webidl.errors.conversionFailed({ prefix, argument: `${name} ("${webidl.util.Stringify(V)}")`, types: [T.name] }); } if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { throw webidl.errors.exception({ header: "ArrayBuffer", message: "SharedArrayBuffer is not allowed." }); } if (V.buffer.resizable || V.buffer.growable) { throw webidl.errors.exception({ header: "ArrayBuffer", message: "Received a resizable ArrayBuffer." }); } return V; }; webidl.converters.DataView = function(V, prefix, name, opts) { if (webidl.util.Type(V) !== "Object" || !types.isDataView(V)) { throw webidl.errors.exception({ header: prefix, message: `${name} is not a DataView.` }); } if (opts?.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { throw webidl.errors.exception({ header: "ArrayBuffer", message: "SharedArrayBuffer is not allowed." }); } if (V.buffer.resizable || V.buffer.growable) { throw webidl.errors.exception({ header: "ArrayBuffer", message: "Received a resizable ArrayBuffer." }); } return V; }; webidl.converters.BufferSource = function(V, prefix, name, opts) { if (types.isAnyArrayBuffer(V)) { return webidl.converters.ArrayBuffer(V, prefix, name, { ...opts, allowShared: false }); } if (types.isTypedArray(V)) { return webidl.converters.TypedArray(V, V.constructor, prefix, name, { ...opts, allowShared: false }); } if (types.isDataView(V)) { return webidl.converters.DataView(V, prefix, name, { ...opts, allowShared: false }); } throw webidl.errors.conversionFailed({ prefix, argument: `${name} ("${webidl.util.Stringify(V)}")`, types: ["BufferSource"] }); }; webidl.converters["sequence"] = webidl.sequenceConverter( webidl.converters.ByteString ); webidl.converters["sequence>"] = webidl.sequenceConverter( webidl.converters["sequence"] ); webidl.converters["record"] = webidl.recordConverter( webidl.converters.ByteString, webidl.converters.ByteString ); module.exports = { webidl }; } }); // viewer/node_modules/undici/lib/web/fetch/util.js var require_util2 = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/util.js"(exports, module) { "use strict"; var { Transform } = __require("node:stream"); var zlib = __require("node:zlib"); var { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require_constants3(); var { getGlobalOrigin } = require_global(); var { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = require_data_url(); var { performance: performance2 } = __require("node:perf_hooks"); var { isBlobLike, ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require_util(); var assert = __require("node:assert"); var { isUint8Array } = __require("node:util/types"); var { webidl } = require_webidl(); var supportedHashes = []; var crypto2; try { crypto2 = __require("node:crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); } catch { } function responseURL(response) { const urlList = response.urlList; const length2 = urlList.length; return length2 === 0 ? null : urlList[length2 - 1].toString(); } function responseLocationURL(response, requestFragment) { if (!redirectStatusSet.has(response.status)) { return null; } let location = response.headersList.get("location", true); if (location !== null && isValidHeaderValue(location)) { if (!isValidEncodedURL(location)) { location = normalizeBinaryStringToUtf8(location); } location = new URL(location, responseURL(response)); } if (location && !location.hash) { location.hash = requestFragment; } return location; } function isValidEncodedURL(url) { for (let i = 0; i < url.length; ++i) { const code = url.charCodeAt(i); if (code > 126 || // Non-US-ASCII + DEL code < 32) { return false; } } return true; } function normalizeBinaryStringToUtf8(value) { return Buffer.from(value, "binary").toString("utf8"); } function requestCurrentURL(request) { return request.urlList[request.urlList.length - 1]; } function requestBadPort(request) { const url = requestCurrentURL(request); if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { return "blocked"; } return "allowed"; } function isErrorLike(object) { return object instanceof Error || (object?.constructor?.name === "Error" || object?.constructor?.name === "DOMException"); } function isValidReasonPhrase(statusText) { for (let i = 0; i < statusText.length; ++i) { const c = statusText.charCodeAt(i); if (!(c === 9 || // HTAB c >= 32 && c <= 126 || // SP / VCHAR c >= 128 && c <= 255)) { return false; } } return true; } var isValidHeaderName = isValidHTTPToken; function isValidHeaderValue(potentialValue) { return (potentialValue[0] === " " || potentialValue[0] === " " || potentialValue[potentialValue.length - 1] === " " || potentialValue[potentialValue.length - 1] === " " || potentialValue.includes("\n") || potentialValue.includes("\r") || potentialValue.includes("\0")) === false; } function setRequestReferrerPolicyOnRedirect(request, actualResponse) { const { headersList } = actualResponse; const policyHeader = (headersList.get("referrer-policy", true) ?? "").split(","); let policy = ""; if (policyHeader.length > 0) { for (let i = policyHeader.length; i !== 0; i--) { const token = policyHeader[i - 1].trim(); if (referrerPolicyTokens.has(token)) { policy = token; break; } } } if (policy !== "") { request.referrerPolicy = policy; } } function crossOriginResourcePolicyCheck() { return "allowed"; } function corsCheck() { return "success"; } function TAOCheck() { return "success"; } function appendFetchMetadata(httpRequest) { let header = null; header = httpRequest.mode; httpRequest.headersList.set("sec-fetch-mode", header, true); } function appendRequestOriginHeader(request) { let serializedOrigin = request.origin; if (serializedOrigin === "client" || serializedOrigin === void 0) { return; } if (request.responseTainting === "cors" || request.mode === "websocket") { request.headersList.append("origin", serializedOrigin, true); } else if (request.method !== "GET" && request.method !== "HEAD") { switch (request.referrerPolicy) { case "no-referrer": serializedOrigin = null; break; case "no-referrer-when-downgrade": case "strict-origin": case "strict-origin-when-cross-origin": if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { serializedOrigin = null; } break; case "same-origin": if (!sameOrigin(request, requestCurrentURL(request))) { serializedOrigin = null; } break; default: } request.headersList.append("origin", serializedOrigin, true); } } function coarsenTime(timestamp, crossOriginIsolatedCapability) { return timestamp; } function clampAndCoarsenConnectionTimingInfo(connectionTimingInfo, defaultStartTime, crossOriginIsolatedCapability) { if (!connectionTimingInfo?.startTime || connectionTimingInfo.startTime < defaultStartTime) { return { domainLookupStartTime: defaultStartTime, domainLookupEndTime: defaultStartTime, connectionStartTime: defaultStartTime, connectionEndTime: defaultStartTime, secureConnectionStartTime: defaultStartTime, ALPNNegotiatedProtocol: connectionTimingInfo?.ALPNNegotiatedProtocol }; } return { domainLookupStartTime: coarsenTime(connectionTimingInfo.domainLookupStartTime, crossOriginIsolatedCapability), domainLookupEndTime: coarsenTime(connectionTimingInfo.domainLookupEndTime, crossOriginIsolatedCapability), connectionStartTime: coarsenTime(connectionTimingInfo.connectionStartTime, crossOriginIsolatedCapability), connectionEndTime: coarsenTime(connectionTimingInfo.connectionEndTime, crossOriginIsolatedCapability), secureConnectionStartTime: coarsenTime(connectionTimingInfo.secureConnectionStartTime, crossOriginIsolatedCapability), ALPNNegotiatedProtocol: connectionTimingInfo.ALPNNegotiatedProtocol }; } function coarsenedSharedCurrentTime(crossOriginIsolatedCapability) { return coarsenTime(performance2.now(), crossOriginIsolatedCapability); } function createOpaqueTimingInfo(timingInfo) { return { startTime: timingInfo.startTime ?? 0, redirectStartTime: 0, redirectEndTime: 0, postRedirectStartTime: timingInfo.startTime ?? 0, finalServiceWorkerStartTime: 0, finalNetworkResponseStartTime: 0, finalNetworkRequestStartTime: 0, endTime: 0, encodedBodySize: 0, decodedBodySize: 0, finalConnectionTimingInfo: null }; } function makePolicyContainer() { return { referrerPolicy: "strict-origin-when-cross-origin" }; } function clonePolicyContainer(policyContainer) { return { referrerPolicy: policyContainer.referrerPolicy }; } function determineRequestsReferrer(request) { const policy = request.referrerPolicy; assert(policy); let referrerSource = null; if (request.referrer === "client") { const globalOrigin = getGlobalOrigin(); if (!globalOrigin || globalOrigin.origin === "null") { return "no-referrer"; } referrerSource = new URL(globalOrigin); } else if (request.referrer instanceof URL) { referrerSource = request.referrer; } let referrerURL = stripURLForReferrer(referrerSource); const referrerOrigin = stripURLForReferrer(referrerSource, true); if (referrerURL.toString().length > 4096) { referrerURL = referrerOrigin; } const areSameOrigin = sameOrigin(request, referrerURL); const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(request.url); switch (policy) { case "origin": return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true); case "unsafe-url": return referrerURL; case "same-origin": return areSameOrigin ? referrerOrigin : "no-referrer"; case "origin-when-cross-origin": return areSameOrigin ? referrerURL : referrerOrigin; case "strict-origin-when-cross-origin": { const currentURL = requestCurrentURL(request); if (sameOrigin(referrerURL, currentURL)) { return referrerURL; } if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { return "no-referrer"; } return referrerOrigin; } case "strict-origin": // eslint-disable-line /** * 1. If referrerURL is a potentially trustworthy URL and * request’s current URL is not a potentially trustworthy URL, * then return no referrer. * 2. Return referrerOrigin */ case "no-referrer-when-downgrade": // eslint-disable-line /** * 1. If referrerURL is a potentially trustworthy URL and * request’s current URL is not a potentially trustworthy URL, * then return no referrer. * 2. Return referrerOrigin */ default: return isNonPotentiallyTrustWorthy ? "no-referrer" : referrerOrigin; } } function stripURLForReferrer(url, originOnly) { assert(url instanceof URL); url = new URL(url); if (url.protocol === "file:" || url.protocol === "about:" || url.protocol === "blank:") { return "no-referrer"; } url.username = ""; url.password = ""; url.hash = ""; if (originOnly) { url.pathname = ""; url.search = ""; } return url; } function isURLPotentiallyTrustworthy(url) { if (!(url instanceof URL)) { return false; } if (url.href === "about:blank" || url.href === "about:srcdoc") { return true; } if (url.protocol === "data:") return true; if (url.protocol === "file:") return true; return isOriginPotentiallyTrustworthy(url.origin); function isOriginPotentiallyTrustworthy(origin) { if (origin == null || origin === "null") return false; const originAsURL = new URL(origin); if (originAsURL.protocol === "https:" || originAsURL.protocol === "wss:") { return true; } if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || (originAsURL.hostname === "localhost" || originAsURL.hostname.includes("localhost.")) || originAsURL.hostname.endsWith(".localhost")) { return true; } return false; } } function bytesMatch(bytes2, metadataList) { if (crypto2 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); if (parsedMetadata === "no metadata") { return true; } if (parsedMetadata.length === 0) { return true; } const strongest = getStrongestMetadata(parsedMetadata); const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest); for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; let actualValue = crypto2.createHash(algorithm).update(bytes2).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); } else { actualValue = actualValue.slice(0, -1); } } if (compareBase64Mixed(actualValue, expectedValue)) { return true; } } return false; } var parseHashWithOptions = /(?sha256|sha384|sha512)-((?[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i; function parseMetadata(metadata) { const result = []; let empty = true; for (const token of metadata.split(" ")) { empty = false; const parsedToken = parseHashWithOptions.exec(token); if (parsedToken === null || parsedToken.groups === void 0 || parsedToken.groups.algo === void 0) { continue; } const algorithm = parsedToken.groups.algo.toLowerCase(); if (supportedHashes.includes(algorithm)) { result.push(parsedToken.groups); } } if (empty === true) { return "no metadata"; } return result; } function getStrongestMetadata(metadataList) { let algorithm = metadataList[0].algo; if (algorithm[3] === "5") { return algorithm; } for (let i = 1; i < metadataList.length; ++i) { const metadata = metadataList[i]; if (metadata.algo[3] === "5") { algorithm = "sha512"; break; } else if (algorithm[3] === "3") { continue; } else if (metadata.algo[3] === "3") { algorithm = "sha384"; } } return algorithm; } function filterMetadataListByAlgorithm(metadataList, algorithm) { if (metadataList.length === 1) { return metadataList; } let pos = 0; for (let i = 0; i < metadataList.length; ++i) { if (metadataList[i].algo === algorithm) { metadataList[pos++] = metadataList[i]; } } metadataList.length = pos; return metadataList; } function compareBase64Mixed(actualValue, expectedValue) { if (actualValue.length !== expectedValue.length) { return false; } for (let i = 0; i < actualValue.length; ++i) { if (actualValue[i] !== expectedValue[i]) { if (actualValue[i] === "+" && expectedValue[i] === "-" || actualValue[i] === "/" && expectedValue[i] === "_") { continue; } return false; } } return true; } function tryUpgradeRequestToAPotentiallyTrustworthyURL(request) { } function sameOrigin(A, B) { if (A.origin === B.origin && A.origin === "null") { return true; } if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { return true; } return false; } function createDeferredPromise() { let res; let rej; const promise = new Promise((resolve, reject) => { res = resolve; rej = reject; }); return { promise, resolve: res, reject: rej }; } function isAborted(fetchParams) { return fetchParams.controller.state === "aborted"; } function isCancelled(fetchParams) { return fetchParams.controller.state === "aborted" || fetchParams.controller.state === "terminated"; } function normalizeMethod(method) { return normalizedMethodRecordsBase[method.toLowerCase()] ?? method; } function serializeJavascriptValueToJSONString(value) { const result = JSON.stringify(value); if (result === void 0) { throw new TypeError("Value is not JSON serializable"); } assert(typeof result === "string"); return result; } var esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())); function createIterator(name, kInternalIterator, keyIndex = 0, valueIndex = 1) { class FastIterableIterator { /** @type {any} */ #target; /** @type {'key' | 'value' | 'key+value'} */ #kind; /** @type {number} */ #index; /** * @see https://webidl.spec.whatwg.org/#dfn-default-iterator-object * @param {unknown} target * @param {'key' | 'value' | 'key+value'} kind */ constructor(target, kind) { this.#target = target; this.#kind = kind; this.#index = 0; } next() { if (typeof this !== "object" || this === null || !(#target in this)) { throw new TypeError( `'next' called on an object that does not implement interface ${name} Iterator.` ); } const index = this.#index; const values = this.#target[kInternalIterator]; const len = values.length; if (index >= len) { return { value: void 0, done: true }; } const { [keyIndex]: key, [valueIndex]: value } = values[index]; this.#index = index + 1; let result; switch (this.#kind) { case "key": result = key; break; case "value": result = value; break; case "key+value": result = [key, value]; break; } return { value: result, done: false }; } } delete FastIterableIterator.prototype.constructor; Object.setPrototypeOf(FastIterableIterator.prototype, esIteratorPrototype); Object.defineProperties(FastIterableIterator.prototype, { [Symbol.toStringTag]: { writable: false, enumerable: false, configurable: true, value: `${name} Iterator` }, next: { writable: true, enumerable: true, configurable: true } }); return function(target, kind) { return new FastIterableIterator(target, kind); }; } function iteratorMixin(name, object, kInternalIterator, keyIndex = 0, valueIndex = 1) { const makeIterator = createIterator(name, kInternalIterator, keyIndex, valueIndex); const properties = { keys: { writable: true, enumerable: true, configurable: true, value: function keys() { webidl.brandCheck(this, object); return makeIterator(this, "key"); } }, values: { writable: true, enumerable: true, configurable: true, value: function values() { webidl.brandCheck(this, object); return makeIterator(this, "value"); } }, entries: { writable: true, enumerable: true, configurable: true, value: function entries() { webidl.brandCheck(this, object); return makeIterator(this, "key+value"); } }, forEach: { writable: true, enumerable: true, configurable: true, value: function forEach(callbackfn, thisArg = globalThis) { webidl.brandCheck(this, object); webidl.argumentLengthCheck(arguments, 1, `${name}.forEach`); if (typeof callbackfn !== "function") { throw new TypeError( `Failed to execute 'forEach' on '${name}': parameter 1 is not of type 'Function'.` ); } for (const { 0: key, 1: value } of makeIterator(this, "key+value")) { callbackfn.call(thisArg, value, key, this); } } } }; return Object.defineProperties(object.prototype, { ...properties, [Symbol.iterator]: { writable: true, enumerable: false, configurable: true, value: properties.entries.value } }); } async function fullyReadBody(body, processBody, processBodyError) { const successSteps = processBody; const errorSteps = processBodyError; let reader; try { reader = body.stream.getReader(); } catch (e) { errorSteps(e); return; } try { successSteps(await readAllBytes(reader)); } catch (e) { errorSteps(e); } } function isReadableStreamLike(stream) { return stream instanceof ReadableStream || stream[Symbol.toStringTag] === "ReadableStream" && typeof stream.tee === "function"; } function readableStreamClose(controller) { try { controller.close(); controller.byobRequest?.respond(0); } catch (err) { if (!err.message.includes("Controller is already closed") && !err.message.includes("ReadableStream is already closed")) { throw err; } } } var invalidIsomorphicEncodeValueRegex = /[^\x00-\xFF]/; function isomorphicEncode(input) { assert(!invalidIsomorphicEncodeValueRegex.test(input)); return input; } async function readAllBytes(reader) { const bytes2 = []; let byteLength = 0; while (true) { const { done, value: chunk } = await reader.read(); if (done) { return Buffer.concat(bytes2, byteLength); } if (!isUint8Array(chunk)) { throw new TypeError("Received non-Uint8Array chunk"); } bytes2.push(chunk); byteLength += chunk.length; } } function urlIsLocal(url) { assert("protocol" in url); const protocol = url.protocol; return protocol === "about:" || protocol === "blob:" || protocol === "data:"; } function urlHasHttpsScheme(url) { return typeof url === "string" && url[5] === ":" && url[0] === "h" && url[1] === "t" && url[2] === "t" && url[3] === "p" && url[4] === "s" || url.protocol === "https:"; } function urlIsHttpHttpsScheme(url) { assert("protocol" in url); const protocol = url.protocol; return protocol === "http:" || protocol === "https:"; } function simpleRangeHeaderValue(value, allowWhitespace) { const data = value; if (!data.startsWith("bytes")) { return "failure"; } const position = { position: 5 }; if (allowWhitespace) { collectASequenceOfCodePoints( (char) => char === " " || char === " ", data, position ); } if (data.charCodeAt(position.position) !== 61) { return "failure"; } position.position++; if (allowWhitespace) { collectASequenceOfCodePoints( (char) => char === " " || char === " ", data, position ); } const rangeStart = collectASequenceOfCodePoints( (char) => { const code = char.charCodeAt(0); return code >= 48 && code <= 57; }, data, position ); const rangeStartValue = rangeStart.length ? Number(rangeStart) : null; if (allowWhitespace) { collectASequenceOfCodePoints( (char) => char === " " || char === " ", data, position ); } if (data.charCodeAt(position.position) !== 45) { return "failure"; } position.position++; if (allowWhitespace) { collectASequenceOfCodePoints( (char) => char === " " || char === " ", data, position ); } const rangeEnd = collectASequenceOfCodePoints( (char) => { const code = char.charCodeAt(0); return code >= 48 && code <= 57; }, data, position ); const rangeEndValue = rangeEnd.length ? Number(rangeEnd) : null; if (position.position < data.length) { return "failure"; } if (rangeEndValue === null && rangeStartValue === null) { return "failure"; } if (rangeStartValue > rangeEndValue) { return "failure"; } return { rangeStartValue, rangeEndValue }; } function buildContentRange(rangeStart, rangeEnd, fullLength) { let contentRange = "bytes "; contentRange += isomorphicEncode(`${rangeStart}`); contentRange += "-"; contentRange += isomorphicEncode(`${rangeEnd}`); contentRange += "/"; contentRange += isomorphicEncode(`${fullLength}`); return contentRange; } var InflateStream = class extends Transform { #zlibOptions; /** @param {zlib.ZlibOptions} [zlibOptions] */ constructor(zlibOptions) { super(); this.#zlibOptions = zlibOptions; } _transform(chunk, encoding, callback) { if (!this._inflateStream) { if (chunk.length === 0) { callback(); return; } this._inflateStream = (chunk[0] & 15) === 8 ? zlib.createInflate(this.#zlibOptions) : zlib.createInflateRaw(this.#zlibOptions); this._inflateStream.on("data", this.push.bind(this)); this._inflateStream.on("end", () => this.push(null)); this._inflateStream.on("error", (err) => this.destroy(err)); } this._inflateStream.write(chunk, encoding, callback); } _final(callback) { if (this._inflateStream) { this._inflateStream.end(); this._inflateStream = null; } callback(); } }; function createInflate(zlibOptions) { return new InflateStream(zlibOptions); } function extractMimeType(headers) { let charset = null; let essence = null; let mimeType = null; const values = getDecodeSplit("content-type", headers); if (values === null) { return "failure"; } for (const value of values) { const temporaryMimeType = parseMIMEType(value); if (temporaryMimeType === "failure" || temporaryMimeType.essence === "*/*") { continue; } mimeType = temporaryMimeType; if (mimeType.essence !== essence) { charset = null; if (mimeType.parameters.has("charset")) { charset = mimeType.parameters.get("charset"); } essence = mimeType.essence; } else if (!mimeType.parameters.has("charset") && charset !== null) { mimeType.parameters.set("charset", charset); } } if (mimeType == null) { return "failure"; } return mimeType; } function gettingDecodingSplitting(value) { const input = value; const position = { position: 0 }; const values = []; let temporaryValue = ""; while (position.position < input.length) { temporaryValue += collectASequenceOfCodePoints( (char) => char !== '"' && char !== ",", input, position ); if (position.position < input.length) { if (input.charCodeAt(position.position) === 34) { temporaryValue += collectAnHTTPQuotedString( input, position ); if (position.position < input.length) { continue; } } else { assert(input.charCodeAt(position.position) === 44); position.position++; } } temporaryValue = removeChars(temporaryValue, true, true, (char) => char === 9 || char === 32); values.push(temporaryValue); temporaryValue = ""; } return values; } function getDecodeSplit(name, list2) { const value = list2.get(name, true); if (value === null) { return null; } return gettingDecodingSplitting(value); } var textDecoder = new TextDecoder(); function utf8DecodeBytes(buffer) { if (buffer.length === 0) { return ""; } if (buffer[0] === 239 && buffer[1] === 187 && buffer[2] === 191) { buffer = buffer.subarray(3); } const output = textDecoder.decode(buffer); return output; } var EnvironmentSettingsObjectBase = class { get baseUrl() { return getGlobalOrigin(); } get origin() { return this.baseUrl?.origin; } policyContainer = makePolicyContainer(); }; var EnvironmentSettingsObject = class { settingsObject = new EnvironmentSettingsObjectBase(); }; var environmentSettingsObject = new EnvironmentSettingsObject(); module.exports = { isAborted, isCancelled, isValidEncodedURL, createDeferredPromise, ReadableStreamFrom, tryUpgradeRequestToAPotentiallyTrustworthyURL, clampAndCoarsenConnectionTimingInfo, coarsenedSharedCurrentTime, determineRequestsReferrer, makePolicyContainer, clonePolicyContainer, appendFetchMetadata, appendRequestOriginHeader, TAOCheck, corsCheck, crossOriginResourcePolicyCheck, createOpaqueTimingInfo, setRequestReferrerPolicyOnRedirect, isValidHTTPToken, requestBadPort, requestCurrentURL, responseURL, responseLocationURL, isBlobLike, isURLPotentiallyTrustworthy, isValidReasonPhrase, sameOrigin, normalizeMethod, serializeJavascriptValueToJSONString, iteratorMixin, createIterator, isValidHeaderName, isValidHeaderValue, isErrorLike, fullyReadBody, bytesMatch, isReadableStreamLike, readableStreamClose, isomorphicEncode, urlIsLocal, urlHasHttpsScheme, urlIsHttpHttpsScheme, readAllBytes, simpleRangeHeaderValue, buildContentRange, parseMetadata, createInflate, extractMimeType, getDecodeSplit, utf8DecodeBytes, environmentSettingsObject }; } }); // viewer/node_modules/undici/lib/web/fetch/symbols.js var require_symbols2 = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/symbols.js"(exports, module) { "use strict"; module.exports = { kUrl: /* @__PURE__ */ Symbol("url"), kHeaders: /* @__PURE__ */ Symbol("headers"), kSignal: /* @__PURE__ */ Symbol("signal"), kState: /* @__PURE__ */ Symbol("state"), kDispatcher: /* @__PURE__ */ Symbol("dispatcher") }; } }); // viewer/node_modules/undici/lib/web/fetch/file.js var require_file = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/file.js"(exports, module) { "use strict"; var { Blob: Blob2, File } = __require("node:buffer"); var { kState } = require_symbols2(); var { webidl } = require_webidl(); var FileLike = class _FileLike { constructor(blobLike, fileName, options = {}) { const n = fileName; const t = options.type; const d = options.lastModified ?? Date.now(); this[kState] = { blobLike, name: n, type: t, lastModified: d }; } stream(...args) { webidl.brandCheck(this, _FileLike); return this[kState].blobLike.stream(...args); } arrayBuffer(...args) { webidl.brandCheck(this, _FileLike); return this[kState].blobLike.arrayBuffer(...args); } slice(...args) { webidl.brandCheck(this, _FileLike); return this[kState].blobLike.slice(...args); } text(...args) { webidl.brandCheck(this, _FileLike); return this[kState].blobLike.text(...args); } get size() { webidl.brandCheck(this, _FileLike); return this[kState].blobLike.size; } get type() { webidl.brandCheck(this, _FileLike); return this[kState].blobLike.type; } get name() { webidl.brandCheck(this, _FileLike); return this[kState].name; } get lastModified() { webidl.brandCheck(this, _FileLike); return this[kState].lastModified; } get [Symbol.toStringTag]() { return "File"; } }; webidl.converters.Blob = webidl.interfaceConverter(Blob2); function isFileLike(object) { return object instanceof File || object && (typeof object.stream === "function" || typeof object.arrayBuffer === "function") && object[Symbol.toStringTag] === "File"; } module.exports = { FileLike, isFileLike }; } }); // viewer/node_modules/undici/lib/web/fetch/formdata.js var require_formdata = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/formdata.js"(exports, module) { "use strict"; var { isBlobLike, iteratorMixin } = require_util2(); var { kState } = require_symbols2(); var { kEnumerableProperty } = require_util(); var { FileLike, isFileLike } = require_file(); var { webidl } = require_webidl(); var { File: NativeFile } = __require("node:buffer"); var nodeUtil = __require("node:util"); var File = globalThis.File ?? NativeFile; var FormData = class _FormData { constructor(form) { webidl.util.markAsUncloneable(this); if (form !== void 0) { throw webidl.errors.conversionFailed({ prefix: "FormData constructor", argument: "Argument 1", types: ["undefined"] }); } this[kState] = []; } append(name, value, filename = void 0) { webidl.brandCheck(this, _FormData); const prefix = "FormData.append"; webidl.argumentLengthCheck(arguments, 2, prefix); if (arguments.length === 3 && !isBlobLike(value)) { throw new TypeError( "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" ); } name = webidl.converters.USVString(name, prefix, "name"); value = isBlobLike(value) ? webidl.converters.Blob(value, prefix, "value", { strict: false }) : webidl.converters.USVString(value, prefix, "value"); filename = arguments.length === 3 ? webidl.converters.USVString(filename, prefix, "filename") : void 0; const entry = makeEntry(name, value, filename); this[kState].push(entry); } delete(name) { webidl.brandCheck(this, _FormData); const prefix = "FormData.delete"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name, prefix, "name"); this[kState] = this[kState].filter((entry) => entry.name !== name); } get(name) { webidl.brandCheck(this, _FormData); const prefix = "FormData.get"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name, prefix, "name"); const idx = this[kState].findIndex((entry) => entry.name === name); if (idx === -1) { return null; } return this[kState][idx].value; } getAll(name) { webidl.brandCheck(this, _FormData); const prefix = "FormData.getAll"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name, prefix, "name"); return this[kState].filter((entry) => entry.name === name).map((entry) => entry.value); } has(name) { webidl.brandCheck(this, _FormData); const prefix = "FormData.has"; webidl.argumentLengthCheck(arguments, 1, prefix); name = webidl.converters.USVString(name, prefix, "name"); return this[kState].findIndex((entry) => entry.name === name) !== -1; } set(name, value, filename = void 0) { webidl.brandCheck(this, _FormData); const prefix = "FormData.set"; webidl.argumentLengthCheck(arguments, 2, prefix); if (arguments.length === 3 && !isBlobLike(value)) { throw new TypeError( "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" ); } name = webidl.converters.USVString(name, prefix, "name"); value = isBlobLike(value) ? webidl.converters.Blob(value, prefix, "name", { strict: false }) : webidl.converters.USVString(value, prefix, "name"); filename = arguments.length === 3 ? webidl.converters.USVString(filename, prefix, "name") : void 0; const entry = makeEntry(name, value, filename); const idx = this[kState].findIndex((entry2) => entry2.name === name); if (idx !== -1) { this[kState] = [ ...this[kState].slice(0, idx), entry, ...this[kState].slice(idx + 1).filter((entry2) => entry2.name !== name) ]; } else { this[kState].push(entry); } } [nodeUtil.inspect.custom](depth, options) { const state = this[kState].reduce((a, b) => { if (a[b.name]) { if (Array.isArray(a[b.name])) { a[b.name].push(b.value); } else { a[b.name] = [a[b.name], b.value]; } } else { a[b.name] = b.value; } return a; }, { __proto__: null }); options.depth ??= depth; options.colors ??= true; const output = nodeUtil.formatWithOptions(options, state); return `FormData ${output.slice(output.indexOf("]") + 2)}`; } }; iteratorMixin("FormData", FormData, kState, "name", "value"); Object.defineProperties(FormData.prototype, { append: kEnumerableProperty, delete: kEnumerableProperty, get: kEnumerableProperty, getAll: kEnumerableProperty, has: kEnumerableProperty, set: kEnumerableProperty, [Symbol.toStringTag]: { value: "FormData", configurable: true } }); function makeEntry(name, value, filename) { if (typeof value === "string") { } else { if (!isFileLike(value)) { value = value instanceof Blob ? new File([value], "blob", { type: value.type }) : new FileLike(value, "blob", { type: value.type }); } if (filename !== void 0) { const options = { type: value.type, lastModified: value.lastModified }; value = value instanceof NativeFile ? new File([value], filename, options) : new FileLike(value, filename, options); } } return { name, value }; } module.exports = { FormData, makeEntry }; } }); // viewer/node_modules/undici/lib/web/fetch/formdata-parser.js var require_formdata_parser = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/formdata-parser.js"(exports, module) { "use strict"; var { isUSVString, bufferToLowerCasedHeaderName } = require_util(); var { utf8DecodeBytes } = require_util2(); var { HTTP_TOKEN_CODEPOINTS, isomorphicDecode } = require_data_url(); var { isFileLike } = require_file(); var { makeEntry } = require_formdata(); var assert = __require("node:assert"); var { File: NodeFile } = __require("node:buffer"); var File = globalThis.File ?? NodeFile; var formDataNameBuffer = Buffer.from('form-data; name="'); var filenameBuffer = Buffer.from("; filename"); var dd = Buffer.from("--"); var ddcrlf = Buffer.from("--\r\n"); function isAsciiString(chars) { for (let i = 0; i < chars.length; ++i) { if ((chars.charCodeAt(i) & ~127) !== 0) { return false; } } return true; } function validateBoundary(boundary) { const length2 = boundary.length; if (length2 < 27 || length2 > 70) { return false; } for (let i = 0; i < length2; ++i) { const cp = boundary.charCodeAt(i); if (!(cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 39 || cp === 45 || cp === 95)) { return false; } } return true; } function multipartFormDataParser(input, mimeType) { assert(mimeType !== "failure" && mimeType.essence === "multipart/form-data"); const boundaryString = mimeType.parameters.get("boundary"); if (boundaryString === void 0) { return "failure"; } const boundary = Buffer.from(`--${boundaryString}`, "utf8"); const entryList = []; const position = { position: 0 }; while (input[position.position] === 13 && input[position.position + 1] === 10) { position.position += 2; } let trailing = input.length; while (input[trailing - 1] === 10 && input[trailing - 2] === 13) { trailing -= 2; } if (trailing !== input.length) { input = input.subarray(0, trailing); } while (true) { if (input.subarray(position.position, position.position + boundary.length).equals(boundary)) { position.position += boundary.length; } else { return "failure"; } if (position.position === input.length - 2 && bufferStartsWith(input, dd, position) || position.position === input.length - 4 && bufferStartsWith(input, ddcrlf, position)) { return entryList; } if (input[position.position] !== 13 || input[position.position + 1] !== 10) { return "failure"; } position.position += 2; const result = parseMultipartFormDataHeaders(input, position); if (result === "failure") { return "failure"; } let { name, filename, contentType, encoding } = result; position.position += 2; let body; { const boundaryIndex = input.indexOf(boundary.subarray(2), position.position); if (boundaryIndex === -1) { return "failure"; } body = input.subarray(position.position, boundaryIndex - 4); position.position += body.length; if (encoding === "base64") { body = Buffer.from(body.toString(), "base64"); } } if (input[position.position] !== 13 || input[position.position + 1] !== 10) { return "failure"; } else { position.position += 2; } let value; if (filename !== null) { contentType ??= "text/plain"; if (!isAsciiString(contentType)) { contentType = ""; } value = new File([body], filename, { type: contentType }); } else { value = utf8DecodeBytes(Buffer.from(body)); } assert(isUSVString(name)); assert(typeof value === "string" && isUSVString(value) || isFileLike(value)); entryList.push(makeEntry(name, value, filename)); } } function parseMultipartFormDataHeaders(input, position) { let name = null; let filename = null; let contentType = null; let encoding = null; while (true) { if (input[position.position] === 13 && input[position.position + 1] === 10) { if (name === null) { return "failure"; } return { name, filename, contentType, encoding }; } let headerName = collectASequenceOfBytes( (char) => char !== 10 && char !== 13 && char !== 58, input, position ); headerName = removeChars(headerName, true, true, (char) => char === 9 || char === 32); if (!HTTP_TOKEN_CODEPOINTS.test(headerName.toString())) { return "failure"; } if (input[position.position] !== 58) { return "failure"; } position.position++; collectASequenceOfBytes( (char) => char === 32 || char === 9, input, position ); switch (bufferToLowerCasedHeaderName(headerName)) { case "content-disposition": { name = filename = null; if (!bufferStartsWith(input, formDataNameBuffer, position)) { return "failure"; } position.position += 17; name = parseMultipartFormDataName(input, position); if (name === null) { return "failure"; } if (bufferStartsWith(input, filenameBuffer, position)) { let check = position.position + filenameBuffer.length; if (input[check] === 42) { position.position += 1; check += 1; } if (input[check] !== 61 || input[check + 1] !== 34) { return "failure"; } position.position += 12; filename = parseMultipartFormDataName(input, position); if (filename === null) { return "failure"; } } break; } case "content-type": { let headerValue = collectASequenceOfBytes( (char) => char !== 10 && char !== 13, input, position ); headerValue = removeChars(headerValue, false, true, (char) => char === 9 || char === 32); contentType = isomorphicDecode(headerValue); break; } case "content-transfer-encoding": { let headerValue = collectASequenceOfBytes( (char) => char !== 10 && char !== 13, input, position ); headerValue = removeChars(headerValue, false, true, (char) => char === 9 || char === 32); encoding = isomorphicDecode(headerValue); break; } default: { collectASequenceOfBytes( (char) => char !== 10 && char !== 13, input, position ); } } if (input[position.position] !== 13 && input[position.position + 1] !== 10) { return "failure"; } else { position.position += 2; } } } function parseMultipartFormDataName(input, position) { assert(input[position.position - 1] === 34); let name = collectASequenceOfBytes( (char) => char !== 10 && char !== 13 && char !== 34, input, position ); if (input[position.position] !== 34) { return null; } else { position.position++; } name = new TextDecoder().decode(name).replace(/%0A/ig, "\n").replace(/%0D/ig, "\r").replace(/%22/g, '"'); return name; } function collectASequenceOfBytes(condition, input, position) { let start = position.position; while (start < input.length && condition(input[start])) { ++start; } return input.subarray(position.position, position.position = start); } function removeChars(buf, leading, trailing, predicate) { let lead = 0; let trail = buf.length - 1; if (leading) { while (lead < buf.length && predicate(buf[lead])) lead++; } if (trailing) { while (trail > 0 && predicate(buf[trail])) trail--; } return lead === 0 && trail === buf.length - 1 ? buf : buf.subarray(lead, trail + 1); } function bufferStartsWith(buffer, start, position) { if (buffer.length < start.length) { return false; } for (let i = 0; i < start.length; i++) { if (start[i] !== buffer[position.position + i]) { return false; } } return true; } module.exports = { multipartFormDataParser, validateBoundary }; } }); // viewer/node_modules/undici/lib/web/fetch/body.js var require_body = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/body.js"(exports, module) { "use strict"; var util = require_util(); var { ReadableStreamFrom, isBlobLike, isReadableStreamLike, readableStreamClose, createDeferredPromise, fullyReadBody, extractMimeType, utf8DecodeBytes } = require_util2(); var { FormData } = require_formdata(); var { kState } = require_symbols2(); var { webidl } = require_webidl(); var { Blob: Blob2 } = __require("node:buffer"); var assert = __require("node:assert"); var { isErrored, isDisturbed } = __require("node:stream"); var { isArrayBuffer } = __require("node:util/types"); var { serializeAMimeType } = require_data_url(); var { multipartFormDataParser } = require_formdata_parser(); var random; try { const crypto2 = __require("node:crypto"); random = (max) => crypto2.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } var textEncoder2 = new TextEncoder(); function noop() { } var hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf("v18") !== 0; var streamRegistry; if (hasFinalizationRegistry) { streamRegistry = new FinalizationRegistry((weakRef) => { const stream = weakRef.deref(); if (stream && !stream.locked && !isDisturbed(stream) && !isErrored(stream)) { stream.cancel("Response object has been garbage collected").catch(noop); } }); } function extractBody(object, keepalive = false) { let stream = null; if (object instanceof ReadableStream) { stream = object; } else if (isBlobLike(object)) { stream = object.stream(); } else { stream = new ReadableStream({ async pull(controller) { const buffer = typeof source === "string" ? textEncoder2.encode(source) : source; if (buffer.byteLength) { controller.enqueue(buffer); } queueMicrotask(() => readableStreamClose(controller)); }, start() { }, type: "bytes" }); } assert(isReadableStreamLike(stream)); let action = null; let source = null; let length2 = null; let type = null; if (typeof object === "string") { source = object; type = "text/plain;charset=UTF-8"; } else if (object instanceof URLSearchParams) { source = object.toString(); type = "application/x-www-form-urlencoded;charset=UTF-8"; } else if (isArrayBuffer(object)) { source = new Uint8Array(object.slice()); } else if (ArrayBuffer.isView(object)) { source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)); } else if (util.isFormDataLike(object)) { const boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, "0")}`; const prefix = `--${boundary}\r Content-Disposition: form-data`; const escape = (str) => str.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22"); const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, "\r\n"); const blobParts = []; const rn = new Uint8Array([13, 10]); length2 = 0; let hasUnknownSizeValue = false; for (const [name, value] of object) { if (typeof value === "string") { const chunk2 = textEncoder2.encode(prefix + `; name="${escape(normalizeLinefeeds(name))}"\r \r ${normalizeLinefeeds(value)}\r `); blobParts.push(chunk2); length2 += chunk2.byteLength; } else { const chunk2 = textEncoder2.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + (value.name ? `; filename="${escape(value.name)}"` : "") + `\r Content-Type: ${value.type || "application/octet-stream"}\r \r `); blobParts.push(chunk2, value, rn); if (typeof value.size === "number") { length2 += chunk2.byteLength + value.size + rn.byteLength; } else { hasUnknownSizeValue = true; } } } const chunk = textEncoder2.encode(`--${boundary}--\r `); blobParts.push(chunk); length2 += chunk.byteLength; if (hasUnknownSizeValue) { length2 = null; } source = object; action = async function* () { for (const part of blobParts) { if (part.stream) { yield* part.stream(); } else { yield part; } } }; type = `multipart/form-data; boundary=${boundary}`; } else if (isBlobLike(object)) { source = object; length2 = object.size; if (object.type) { type = object.type; } } else if (typeof object[Symbol.asyncIterator] === "function") { if (keepalive) { throw new TypeError("keepalive"); } if (util.isDisturbed(object) || object.locked) { throw new TypeError( "Response body object should not be disturbed or locked" ); } stream = object instanceof ReadableStream ? object : ReadableStreamFrom(object); } if (typeof source === "string" || util.isBuffer(source)) { length2 = Buffer.byteLength(source); } if (action != null) { let iterator; stream = new ReadableStream({ async start() { iterator = action(object)[Symbol.asyncIterator](); }, async pull(controller) { const { value, done } = await iterator.next(); if (done) { queueMicrotask(() => { controller.close(); controller.byobRequest?.respond(0); }); } else { if (!isErrored(stream)) { const buffer = new Uint8Array(value); if (buffer.byteLength) { controller.enqueue(buffer); } } } return controller.desiredSize > 0; }, async cancel(reason) { await iterator.return(); }, type: "bytes" }); } const body = { stream, source, length: length2 }; return [body, type]; } function safelyExtractBody(object, keepalive = false) { if (object instanceof ReadableStream) { assert(!util.isDisturbed(object), "The body has already been consumed."); assert(!object.locked, "The stream is locked."); } return extractBody(object, keepalive); } function cloneBody(instance, body) { const [out1, out2] = body.stream.tee(); body.stream = out1; return { stream: out2, length: body.length, source: body.source }; } function throwIfAborted(state) { if (state.aborted) { throw new DOMException("The operation was aborted.", "AbortError"); } } function bodyMixinMethods(instance) { const methods = { blob() { return consumeBody(this, (bytes2) => { let mimeType = bodyMimeType(this); if (mimeType === null) { mimeType = ""; } else if (mimeType) { mimeType = serializeAMimeType(mimeType); } return new Blob2([bytes2], { type: mimeType }); }, instance); }, arrayBuffer() { return consumeBody(this, (bytes2) => { return new Uint8Array(bytes2).buffer; }, instance); }, text() { return consumeBody(this, utf8DecodeBytes, instance); }, json() { return consumeBody(this, parseJSONFromBytes, instance); }, formData() { return consumeBody(this, (value) => { const mimeType = bodyMimeType(this); if (mimeType !== null) { switch (mimeType.essence) { case "multipart/form-data": { const parsed = multipartFormDataParser(value, mimeType); if (parsed === "failure") { throw new TypeError("Failed to parse body as FormData."); } const fd = new FormData(); fd[kState] = parsed; return fd; } case "application/x-www-form-urlencoded": { const entries = new URLSearchParams(value.toString()); const fd = new FormData(); for (const [name, value2] of entries) { fd.append(name, value2); } return fd; } } } throw new TypeError( 'Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".' ); }, instance); }, bytes() { return consumeBody(this, (bytes2) => { return new Uint8Array(bytes2); }, instance); } }; return methods; } function mixinBody(prototype) { Object.assign(prototype.prototype, bodyMixinMethods(prototype)); } async function consumeBody(object, convertBytesToJSValue, instance) { webidl.brandCheck(object, instance); if (bodyUnusable(object)) { throw new TypeError("Body is unusable: Body has already been read"); } throwIfAborted(object[kState]); const promise = createDeferredPromise(); const errorSteps = (error) => promise.reject(error); const successSteps = (data) => { try { promise.resolve(convertBytesToJSValue(data)); } catch (e) { errorSteps(e); } }; if (object[kState].body == null) { successSteps(Buffer.allocUnsafe(0)); return promise.promise; } await fullyReadBody(object[kState].body, successSteps, errorSteps); return promise.promise; } function bodyUnusable(object) { const body = object[kState].body; return body != null && (body.stream.locked || util.isDisturbed(body.stream)); } function parseJSONFromBytes(bytes2) { return JSON.parse(utf8DecodeBytes(bytes2)); } function bodyMimeType(requestOrResponse) { const headers = requestOrResponse[kState].headersList; const mimeType = extractMimeType(headers); if (mimeType === "failure") { return null; } return mimeType; } module.exports = { extractBody, safelyExtractBody, cloneBody, mixinBody, streamRegistry, hasFinalizationRegistry, bodyUnusable }; } }); // viewer/node_modules/undici/lib/dispatcher/client-h1.js var require_client_h1 = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/client-h1.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var util = require_util(); var { channels } = require_diagnostics(); var timers = require_timers(); var { RequestContentLengthMismatchError, ResponseContentLengthMismatchError, RequestAbortedError, HeadersTimeoutError, HeadersOverflowError, SocketError, InformationalError, BodyTimeoutError, HTTPParserError, ResponseExceededMaxSizeError } = require_errors(); var { kUrl, kReset, kClient, kParser, kBlocking, kRunning, kPending, kSize, kWriting, kQueue, kNoRef, kKeepAliveDefaultTimeout, kHostHeader, kPendingIdx, kRunningIdx, kError, kPipelining, kSocket, kKeepAliveTimeoutValue, kMaxHeadersSize, kKeepAliveMaxTimeout, kKeepAliveTimeoutThreshold, kHeadersTimeout, kBodyTimeout, kStrictContentLength, kMaxRequests, kCounter, kMaxResponseSize, kOnError, kResume, kHTTPContext } = require_symbols(); var constants = require_constants2(); var EMPTY_BUF = Buffer.alloc(0); var FastBuffer = Buffer[Symbol.species]; var addListener = util.addListener; var removeAllListeners = util.removeAllListeners; var extractBody; async function lazyllhttp() { const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm() : void 0; let mod2; try { mod2 = await WebAssembly.compile(require_llhttp_simd_wasm()); } catch (e) { mod2 = await WebAssembly.compile(llhttpWasmData || require_llhttp_wasm()); } return await WebAssembly.instantiate(mod2, { env: { /* eslint-disable camelcase */ wasm_on_url: (p, at, len) => { return 0; }, wasm_on_status: (p, at, len) => { assert(currentParser.ptr === p); const start = at - currentBufferPtr + currentBufferRef.byteOffset; return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0; }, wasm_on_message_begin: (p) => { assert(currentParser.ptr === p); return currentParser.onMessageBegin() || 0; }, wasm_on_header_field: (p, at, len) => { assert(currentParser.ptr === p); const start = at - currentBufferPtr + currentBufferRef.byteOffset; return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0; }, wasm_on_header_value: (p, at, len) => { assert(currentParser.ptr === p); const start = at - currentBufferPtr + currentBufferRef.byteOffset; return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0; }, wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { assert(currentParser.ptr === p); return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0; }, wasm_on_body: (p, at, len) => { assert(currentParser.ptr === p); const start = at - currentBufferPtr + currentBufferRef.byteOffset; return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0; }, wasm_on_message_complete: (p) => { assert(currentParser.ptr === p); return currentParser.onMessageComplete() || 0; } /* eslint-enable camelcase */ } }); } var llhttpInstance = null; var llhttpPromise = lazyllhttp(); llhttpPromise.catch(); var currentParser = null; var currentBufferRef = null; var currentBufferSize = 0; var currentBufferPtr = null; var USE_NATIVE_TIMER = 0; var USE_FAST_TIMER = 1; var TIMEOUT_HEADERS = 2 | USE_FAST_TIMER; var TIMEOUT_BODY = 4 | USE_FAST_TIMER; var TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER; var Parser2 = class { constructor(client, socket, { exports: exports2 }) { assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0); this.llhttp = exports2; this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE); this.client = client; this.socket = socket; this.timeout = null; this.timeoutValue = null; this.timeoutType = null; this.statusCode = null; this.statusText = ""; this.upgrade = false; this.headers = []; this.headersSize = 0; this.headersMaxSize = client[kMaxHeadersSize]; this.shouldKeepAlive = false; this.paused = false; this.resume = this.resume.bind(this); this.bytesRead = 0; this.keepAlive = ""; this.contentLength = ""; this.connection = ""; this.maxResponseSize = client[kMaxResponseSize]; } setTimeout(delay, type) { if (delay !== this.timeoutValue || type & USE_FAST_TIMER ^ this.timeoutType & USE_FAST_TIMER) { if (this.timeout) { timers.clearTimeout(this.timeout); this.timeout = null; } if (delay) { if (type & USE_FAST_TIMER) { this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this)); } else { this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this)); this.timeout.unref(); } } this.timeoutValue = delay; } else if (this.timeout) { if (this.timeout.refresh) { this.timeout.refresh(); } } this.timeoutType = type; } resume() { if (this.socket.destroyed || !this.paused) { return; } assert(this.ptr != null); assert(currentParser == null); this.llhttp.llhttp_resume(this.ptr); assert(this.timeoutType === TIMEOUT_BODY); if (this.timeout) { if (this.timeout.refresh) { this.timeout.refresh(); } } this.paused = false; this.execute(this.socket.read() || EMPTY_BUF); this.readMore(); } readMore() { while (!this.paused && this.ptr) { const chunk = this.socket.read(); if (chunk === null) { break; } this.execute(chunk); } } execute(data) { assert(this.ptr != null); assert(currentParser == null); assert(!this.paused); const { socket, llhttp } = this; if (data.length > currentBufferSize) { if (currentBufferPtr) { llhttp.free(currentBufferPtr); } currentBufferSize = Math.ceil(data.length / 4096) * 4096; currentBufferPtr = llhttp.malloc(currentBufferSize); } new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data); try { let ret; try { currentBufferRef = data; currentParser = this; ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length); } catch (err) { throw err; } finally { currentParser = null; currentBufferRef = null; } const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr; if (ret !== constants.ERROR.OK) { const body = data.subarray(offset); if (ret === constants.ERROR.PAUSED_UPGRADE) { this.onUpgrade(body); } else if (ret === constants.ERROR.PAUSED) { this.paused = true; socket.unshift(body); } else { throw this.createError(ret, body); } } } catch (err) { util.destroy(socket, err); } } finish() { assert(currentParser === null); assert(this.ptr != null); assert(!this.paused); const { llhttp } = this; let ret; try { currentParser = this; ret = llhttp.llhttp_finish(this.ptr); } finally { currentParser = null; } if (ret === constants.ERROR.OK) { return null; } if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) { this.paused = true; return null; } return this.createError(ret, EMPTY_BUF); } createError(ret, data) { const { llhttp, contentLength, bytesRead } = this; if (contentLength && bytesRead !== parseInt(contentLength, 10)) { return new ResponseContentLengthMismatchError(); } const ptr = llhttp.llhttp_get_error_reason(this.ptr); let message = ""; if (ptr) { const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0); message = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")"; } return new HTTPParserError(message, constants.ERROR[ret], data); } destroy() { assert(this.ptr != null); assert(currentParser == null); this.llhttp.llhttp_free(this.ptr); this.ptr = null; this.timeout && timers.clearTimeout(this.timeout); this.timeout = null; this.timeoutValue = null; this.timeoutType = null; this.paused = false; } onStatus(buf) { this.statusText = buf.toString(); } onMessageBegin() { const { socket, client } = this; if (socket.destroyed) { return -1; } const request = client[kQueue][client[kRunningIdx]]; if (!request) { return -1; } request.onResponseStarted(); } onHeaderField(buf) { const len = this.headers.length; if ((len & 1) === 0) { this.headers.push(buf); } else { this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]); } this.trackHeader(buf.length); } onHeaderValue(buf) { let len = this.headers.length; if ((len & 1) === 1) { this.headers.push(buf); len += 1; } else { this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]); } const key = this.headers[len - 2]; if (key.length === 10) { const headerName = util.bufferToLowerCasedHeaderName(key); if (headerName === "keep-alive") { this.keepAlive += buf.toString(); } else if (headerName === "connection") { this.connection += buf.toString(); } } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === "content-length") { this.contentLength += buf.toString(); } this.trackHeader(buf.length); } trackHeader(len) { this.headersSize += len; if (this.headersSize >= this.headersMaxSize) { util.destroy(this.socket, new HeadersOverflowError()); } } onUpgrade(head2) { const { upgrade, client, socket, headers, statusCode } = this; assert(upgrade); assert(client[kSocket] === socket); assert(!socket.destroyed); assert(!this.paused); assert((headers.length & 1) === 0); const request = client[kQueue][client[kRunningIdx]]; assert(request); assert(request.upgrade || request.method === "CONNECT"); this.statusCode = null; this.statusText = ""; this.shouldKeepAlive = null; this.headers = []; this.headersSize = 0; socket.unshift(head2); socket[kParser].destroy(); socket[kParser] = null; socket[kClient] = null; socket[kError] = null; removeAllListeners(socket); client[kSocket] = null; client[kHTTPContext] = null; client[kQueue][client[kRunningIdx]++] = null; client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade")); try { request.onUpgrade(statusCode, headers, socket); } catch (err) { util.destroy(socket, err); } client[kResume](); } onHeadersComplete(statusCode, upgrade, shouldKeepAlive) { const { client, socket, headers, statusText } = this; if (socket.destroyed) { return -1; } const request = client[kQueue][client[kRunningIdx]]; if (!request) { return -1; } assert(!this.upgrade); assert(this.statusCode < 200); if (statusCode === 100) { util.destroy(socket, new SocketError("bad response", util.getSocketInfo(socket))); return -1; } if (upgrade && !request.upgrade) { util.destroy(socket, new SocketError("bad upgrade", util.getSocketInfo(socket))); return -1; } assert(this.timeoutType === TIMEOUT_HEADERS); this.statusCode = statusCode; this.shouldKeepAlive = shouldKeepAlive || // Override llhttp value which does not allow keepAlive for HEAD. request.method === "HEAD" && !socket[kReset] && this.connection.toLowerCase() === "keep-alive"; if (this.statusCode >= 200) { const bodyTimeout = request.bodyTimeout != null ? request.bodyTimeout : client[kBodyTimeout]; this.setTimeout(bodyTimeout, TIMEOUT_BODY); } else if (this.timeout) { if (this.timeout.refresh) { this.timeout.refresh(); } } if (request.method === "CONNECT") { assert(client[kRunning] === 1); this.upgrade = true; return 2; } if (upgrade) { assert(client[kRunning] === 1); this.upgrade = true; return 2; } assert((this.headers.length & 1) === 0); this.headers = []; this.headersSize = 0; if (this.shouldKeepAlive && client[kPipelining]) { const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null; if (keepAliveTimeout != null) { const timeout = Math.min( keepAliveTimeout - client[kKeepAliveTimeoutThreshold], client[kKeepAliveMaxTimeout] ); if (timeout <= 0) { socket[kReset] = true; } else { client[kKeepAliveTimeoutValue] = timeout; } } else { client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout]; } } else { socket[kReset] = true; } const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false; if (request.aborted) { return -1; } if (request.method === "HEAD") { return 1; } if (statusCode < 200) { return 1; } if (socket[kBlocking]) { socket[kBlocking] = false; client[kResume](); } return pause ? constants.ERROR.PAUSED : 0; } onBody(buf) { const { client, socket, statusCode, maxResponseSize } = this; if (socket.destroyed) { return -1; } const request = client[kQueue][client[kRunningIdx]]; assert(request); assert(this.timeoutType === TIMEOUT_BODY); if (this.timeout) { if (this.timeout.refresh) { this.timeout.refresh(); } } assert(statusCode >= 200); if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { util.destroy(socket, new ResponseExceededMaxSizeError()); return -1; } this.bytesRead += buf.length; if (request.onData(buf) === false) { return constants.ERROR.PAUSED; } } onMessageComplete() { const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this; if (socket.destroyed && (!statusCode || shouldKeepAlive)) { return -1; } if (upgrade) { return; } assert(statusCode >= 100); assert((this.headers.length & 1) === 0); const request = client[kQueue][client[kRunningIdx]]; assert(request); this.statusCode = null; this.statusText = ""; this.bytesRead = 0; this.contentLength = ""; this.keepAlive = ""; this.connection = ""; this.headers = []; this.headersSize = 0; if (statusCode < 200) { return; } if (request.method !== "HEAD" && contentLength && bytesRead !== parseInt(contentLength, 10)) { util.destroy(socket, new ResponseContentLengthMismatchError()); return -1; } request.onComplete(headers); client[kQueue][client[kRunningIdx]++] = null; if (socket[kWriting]) { assert(client[kRunning] === 0); util.destroy(socket, new InformationalError("reset")); return constants.ERROR.PAUSED; } else if (!shouldKeepAlive) { util.destroy(socket, new InformationalError("reset")); return constants.ERROR.PAUSED; } else if (socket[kReset] && client[kRunning] === 0) { util.destroy(socket, new InformationalError("reset")); return constants.ERROR.PAUSED; } else if (client[kPipelining] == null || client[kPipelining] === 1) { setImmediate(() => client[kResume]()); } else { client[kResume](); } } }; function onParserTimeout(parser) { const { socket, timeoutType, client, paused } = parser.deref(); if (timeoutType === TIMEOUT_HEADERS) { if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { assert(!paused, "cannot be paused while waiting for headers"); util.destroy(socket, new HeadersTimeoutError()); } } else if (timeoutType === TIMEOUT_BODY) { if (!paused) { util.destroy(socket, new BodyTimeoutError()); } } else if (timeoutType === TIMEOUT_KEEP_ALIVE) { assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]); util.destroy(socket, new InformationalError("socket idle timeout")); } } async function connectH1(client, socket) { client[kSocket] = socket; if (!llhttpInstance) { llhttpInstance = await llhttpPromise; llhttpPromise = null; } socket[kNoRef] = false; socket[kWriting] = false; socket[kReset] = false; socket[kBlocking] = false; socket[kParser] = new Parser2(client, socket, llhttpInstance); addListener(socket, "error", function(err) { assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); if (parserErr) { this[kError] = parserErr; this[kClient][kOnError](parserErr); } return; } this[kError] = err; this[kClient][kOnError](err); }); addListener(socket, "readable", function() { const parser = this[kParser]; if (parser) { parser.readMore(); } }); addListener(socket, "end", function() { const parser = this[kParser]; if (parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); if (parserErr) { util.destroy(this, parserErr); } return; } util.destroy(this, new SocketError("other side closed", util.getSocketInfo(this))); }); addListener(socket, "close", function() { const client2 = this[kClient]; const parser = this[kParser]; if (parser) { if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { this[kError] = parser.finish() || this[kError]; } this[kParser].destroy(); this[kParser] = null; } const err = this[kError] || new SocketError("closed", util.getSocketInfo(this)); client2[kSocket] = null; client2[kHTTPContext] = null; if (client2.destroyed) { assert(client2[kPending] === 0); const requests = client2[kQueue].splice(client2[kRunningIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; util.errorRequest(client2, request, err); } } else if (client2[kRunning] > 0 && err.code !== "UND_ERR_INFO") { const request = client2[kQueue][client2[kRunningIdx]]; client2[kQueue][client2[kRunningIdx]++] = null; util.errorRequest(client2, request, err); } client2[kPendingIdx] = client2[kRunningIdx]; assert(client2[kRunning] === 0); client2.emit("disconnect", client2[kUrl], [client2], err); client2[kResume](); }); let closed = false; socket.on("close", () => { closed = true; }); return { version: "h1", defaultPipelining: 1, write(...args) { return writeH1(client, ...args); }, resume() { resumeH1(client); }, destroy(err, callback) { if (closed) { queueMicrotask(callback); } else { socket.destroy(err).on("close", callback); } }, get destroyed() { return socket.destroyed; }, busy(request) { if (socket[kWriting] || socket[kReset] || socket[kBlocking]) { return true; } if (request) { if (client[kRunning] > 0 && !request.idempotent) { return true; } if (client[kRunning] > 0 && (request.upgrade || request.method === "CONNECT")) { return true; } if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) { return true; } } return false; } }; } function resumeH1(client) { const socket = client[kSocket]; if (socket && !socket.destroyed) { if (client[kSize] === 0) { if (!socket[kNoRef] && socket.unref) { socket.unref(); socket[kNoRef] = true; } } else if (socket[kNoRef] && socket.ref) { socket.ref(); socket[kNoRef] = false; } if (client[kSize] === 0) { if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) { socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE); } } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { const request = client[kQueue][client[kRunningIdx]]; const headersTimeout = request.headersTimeout != null ? request.headersTimeout : client[kHeadersTimeout]; socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS); } } } } function shouldSendContentLength(method) { return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT"; } function writeH1(client, request) { const { method, path: path14, host: host2, upgrade, blocking, reset } = request; let { body, headers, contentLength } = request; const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH"; if (util.isFormDataLike(body)) { if (!extractBody) { extractBody = require_body().extractBody; } const [bodyStream, contentType] = extractBody(body); if (request.contentType == null) { headers.push("content-type", contentType); } body = bodyStream.stream; contentLength = bodyStream.length; } else if (util.isBlobLike(body) && request.contentType == null && body.type) { headers.push("content-type", body.type); } if (body && typeof body.read === "function") { body.read(0); } const bodyLength = util.bodyLength(body); contentLength = bodyLength ?? contentLength; if (contentLength === null) { contentLength = request.contentLength; } if (contentLength === 0 && !expectsPayload) { contentLength = null; } if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { if (client[kStrictContentLength]) { util.errorRequest(client, request, new RequestContentLengthMismatchError()); return false; } process.emitWarning(new RequestContentLengthMismatchError()); } const socket = client[kSocket]; const abort = (err) => { if (request.aborted || request.completed) { return; } util.errorRequest(client, request, err || new RequestAbortedError()); util.destroy(body); util.destroy(socket, new InformationalError("aborted")); }; try { request.onConnect(abort); } catch (err) { util.errorRequest(client, request, err); } if (request.aborted) { return false; } if (method === "HEAD") { socket[kReset] = true; } if (upgrade || method === "CONNECT") { socket[kReset] = true; } if (reset != null) { socket[kReset] = reset; } if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { socket[kReset] = true; } if (blocking) { socket[kBlocking] = true; } let header = `${method} ${path14} HTTP/1.1\r `; if (typeof host2 === "string") { header += `host: ${host2}\r `; } else { header += client[kHostHeader]; } if (upgrade) { header += `connection: upgrade\r upgrade: ${upgrade}\r `; } else if (client[kPipelining] && !socket[kReset]) { header += "connection: keep-alive\r\n"; } else { header += "connection: close\r\n"; } if (Array.isArray(headers)) { for (let n = 0; n < headers.length; n += 2) { const key = headers[n + 0]; const val = headers[n + 1]; if (Array.isArray(val)) { for (let i = 0; i < val.length; i++) { header += `${key}: ${val[i]}\r `; } } else { header += `${key}: ${val}\r `; } } } if (channels.sendHeaders.hasSubscribers) { channels.sendHeaders.publish({ request, headers: header, socket }); } if (!body || bodyLength === 0) { writeBuffer(abort, null, client, request, socket, contentLength, header, expectsPayload); } else if (util.isBuffer(body)) { writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload); } else if (util.isBlobLike(body)) { if (typeof body.stream === "function") { writeIterable(abort, body.stream(), client, request, socket, contentLength, header, expectsPayload); } else { writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload); } } else if (util.isStream(body)) { writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload); } else if (util.isIterable(body)) { writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload); } else { assert(false); } return true; } function writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload) { assert(contentLength !== 0 || client[kRunning] === 0, "stream body cannot be pipelined"); let finished = false; const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }); const onData = function(chunk) { if (finished) { return; } try { if (!writer.write(chunk) && this.pause) { this.pause(); } } catch (err) { util.destroy(this, err); } }; const onDrain = function() { if (finished) { return; } if (body.resume) { body.resume(); } }; const onClose = function() { queueMicrotask(() => { body.removeListener("error", onFinished); }); if (!finished) { const err = new RequestAbortedError(); queueMicrotask(() => onFinished(err)); } }; const onFinished = function(err) { if (finished) { return; } finished = true; assert(socket.destroyed || socket[kWriting] && client[kRunning] <= 1); socket.off("drain", onDrain).off("error", onFinished); body.removeListener("data", onData).removeListener("end", onFinished).removeListener("close", onClose); if (!err) { try { writer.end(); } catch (er) { err = er; } } writer.destroy(err); if (err && (err.code !== "UND_ERR_INFO" || err.message !== "reset")) { util.destroy(body, err); } else { util.destroy(body); } }; body.on("data", onData).on("end", onFinished).on("error", onFinished).on("close", onClose); if (body.resume) { body.resume(); } socket.on("drain", onDrain).on("error", onFinished); if (body.errorEmitted ?? body.errored) { setImmediate(() => onFinished(body.errored)); } else if (body.endEmitted ?? body.readableEnded) { setImmediate(() => onFinished(null)); } if (body.closeEmitted ?? body.closed) { setImmediate(onClose); } } function writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload) { try { if (!body) { if (contentLength === 0) { socket.write(`${header}content-length: 0\r \r `, "latin1"); } else { assert(contentLength === null, "no body must not have content length"); socket.write(`${header}\r `, "latin1"); } } else if (util.isBuffer(body)) { assert(contentLength === body.byteLength, "buffer body must have content length"); socket.cork(); socket.write(`${header}content-length: ${contentLength}\r \r `, "latin1"); socket.write(body); socket.uncork(); request.onBodySent(body); if (!expectsPayload && request.reset !== false) { socket[kReset] = true; } } request.onRequestSent(); client[kResume](); } catch (err) { abort(err); } } async function writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload) { assert(contentLength === body.size, "blob body must have content length"); try { if (contentLength != null && contentLength !== body.size) { throw new RequestContentLengthMismatchError(); } const buffer = Buffer.from(await body.arrayBuffer()); socket.cork(); socket.write(`${header}content-length: ${contentLength}\r \r `, "latin1"); socket.write(buffer); socket.uncork(); request.onBodySent(buffer); request.onRequestSent(); if (!expectsPayload && request.reset !== false) { socket[kReset] = true; } client[kResume](); } catch (err) { abort(err); } } async function writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload) { assert(contentLength !== 0 || client[kRunning] === 0, "iterator body cannot be pipelined"); let callback = null; function onDrain() { if (callback) { const cb = callback; callback = null; cb(); } } const waitForDrain = () => new Promise((resolve, reject) => { assert(callback === null); if (socket[kError]) { reject(socket[kError]); } else { callback = resolve; } }); socket.on("close", onDrain).on("drain", onDrain); const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }); try { for await (const chunk of body) { if (socket[kError]) { throw socket[kError]; } if (!writer.write(chunk)) { await waitForDrain(); } } writer.end(); } catch (err) { writer.destroy(err); } finally { socket.off("close", onDrain).off("drain", onDrain); } } var AsyncWriter = class { constructor({ abort, socket, request, contentLength, client, expectsPayload, header }) { this.socket = socket; this.request = request; this.contentLength = contentLength; this.client = client; this.bytesWritten = 0; this.expectsPayload = expectsPayload; this.header = header; this.abort = abort; socket[kWriting] = true; } write(chunk) { const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this; if (socket[kError]) { throw socket[kError]; } if (socket.destroyed) { return false; } const len = Buffer.byteLength(chunk); if (!len) { return true; } if (contentLength !== null && bytesWritten + len > contentLength) { if (client[kStrictContentLength]) { throw new RequestContentLengthMismatchError(); } process.emitWarning(new RequestContentLengthMismatchError()); } socket.cork(); if (bytesWritten === 0) { if (!expectsPayload && request.reset !== false) { socket[kReset] = true; } if (contentLength === null) { socket.write(`${header}transfer-encoding: chunked\r `, "latin1"); } else { socket.write(`${header}content-length: ${contentLength}\r \r `, "latin1"); } } if (contentLength === null) { socket.write(`\r ${len.toString(16)}\r `, "latin1"); } this.bytesWritten += len; const ret = socket.write(chunk); socket.uncork(); request.onBodySent(chunk); if (!ret) { if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { if (socket[kParser].timeout.refresh) { socket[kParser].timeout.refresh(); } } } return ret; } end() { const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this; request.onRequestSent(); socket[kWriting] = false; if (socket[kError]) { throw socket[kError]; } if (socket.destroyed) { return; } if (bytesWritten === 0) { if (expectsPayload) { socket.write(`${header}content-length: 0\r \r `, "latin1"); } else { socket.write(`${header}\r `, "latin1"); } } else if (contentLength === null) { socket.write("\r\n0\r\n\r\n", "latin1"); } if (contentLength !== null && bytesWritten !== contentLength) { if (client[kStrictContentLength]) { throw new RequestContentLengthMismatchError(); } else { process.emitWarning(new RequestContentLengthMismatchError()); } } if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { if (socket[kParser].timeout.refresh) { socket[kParser].timeout.refresh(); } } client[kResume](); } destroy(err) { const { socket, client, abort } = this; socket[kWriting] = false; if (err) { assert(client[kRunning] <= 1, "pipeline should only contain this request"); abort(err); } } }; module.exports = connectH1; } }); // viewer/node_modules/undici/lib/dispatcher/client-h2.js var require_client_h2 = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/client-h2.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { pipeline } = __require("node:stream"); var util = require_util(); var { RequestContentLengthMismatchError, RequestAbortedError, SocketError, InformationalError } = require_errors(); var { kUrl, kReset, kClient, kRunning, kPending, kQueue, kPendingIdx, kRunningIdx, kError, kSocket, kStrictContentLength, kOnError, kMaxConcurrentStreams, kHTTP2Session, kResume, kSize, kHTTPContext } = require_symbols(); var kOpenStreams = /* @__PURE__ */ Symbol("open streams"); var extractBody; var h2ExperimentalWarned = false; var http2; try { http2 = __require("node:http2"); } catch { http2 = { constants: {} }; } var { constants: { HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_METHOD, HTTP2_HEADER_PATH, HTTP2_HEADER_SCHEME, HTTP2_HEADER_CONTENT_LENGTH, HTTP2_HEADER_EXPECT, HTTP2_HEADER_STATUS } } = http2; function parseH2Headers(headers) { const result = []; for (const [name, value] of Object.entries(headers)) { if (Array.isArray(value)) { for (const subvalue of value) { result.push(Buffer.from(name), Buffer.from(subvalue)); } } else { result.push(Buffer.from(name), Buffer.from(value)); } } return result; } async function connectH2(client, socket) { client[kSocket] = socket; if (!h2ExperimentalWarned) { h2ExperimentalWarned = true; process.emitWarning("H2 support is experimental, expect them to change at any time.", { code: "UNDICI-H2" }); } const session = http2.connect(client[kUrl], { createConnection: () => socket, peerMaxConcurrentStreams: client[kMaxConcurrentStreams] }); session[kOpenStreams] = 0; session[kClient] = client; session[kSocket] = socket; util.addListener(session, "error", onHttp2SessionError); util.addListener(session, "frameError", onHttp2FrameError); util.addListener(session, "end", onHttp2SessionEnd); util.addListener(session, "goaway", onHTTP2GoAway); util.addListener(session, "close", function() { const { [kClient]: client2 } = this; const { [kSocket]: socket2 } = client2; const err = this[kSocket][kError] || this[kError] || new SocketError("closed", util.getSocketInfo(socket2)); client2[kHTTP2Session] = null; if (client2.destroyed) { assert(client2[kPending] === 0); const requests = client2[kQueue].splice(client2[kRunningIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; util.errorRequest(client2, request, err); } } }); session.unref(); client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); util.addListener(socket, "end", function() { util.destroy(this, new SocketError("other side closed", util.getSocketInfo(this))); }); util.addListener(socket, "close", function() { const err = this[kError] || new SocketError("closed", util.getSocketInfo(this)); client[kSocket] = null; if (this[kHTTP2Session] != null) { this[kHTTP2Session].destroy(err); } client[kPendingIdx] = client[kRunningIdx]; assert(client[kRunning] === 0); client.emit("disconnect", client[kUrl], [client], err); client[kResume](); }); let closed = false; socket.on("close", () => { closed = true; }); return { version: "h2", defaultPipelining: Infinity, write(...args) { return writeH2(client, ...args); }, resume() { resumeH2(client); }, destroy(err, callback) { if (closed) { queueMicrotask(callback); } else { socket.destroy(err).on("close", callback); } }, get destroyed() { return socket.destroyed; }, busy() { return false; } }; } function resumeH2(client) { const socket = client[kSocket]; if (socket?.destroyed === false) { if (client[kSize] === 0 && client[kMaxConcurrentStreams] === 0) { socket.unref(); client[kHTTP2Session].unref(); } else { socket.ref(); client[kHTTP2Session].ref(); } } } function onHttp2SessionError(err) { assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } function onHttp2FrameError(type, code, id) { if (id === 0) { const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`); this[kSocket][kError] = err; this[kClient][kOnError](err); } } function onHttp2SessionEnd() { const err = new SocketError("other side closed", util.getSocketInfo(this[kSocket])); this.destroy(err); util.destroy(this[kSocket], err); } function onHTTP2GoAway(code) { const err = this[kError] || new SocketError(`HTTP/2: "GOAWAY" frame received with code ${code}`, util.getSocketInfo(this)); const client = this[kClient]; client[kSocket] = null; client[kHTTPContext] = null; if (this[kHTTP2Session] != null) { this[kHTTP2Session].destroy(err); this[kHTTP2Session] = null; } util.destroy(this[kSocket], err); if (client[kRunningIdx] < client[kQueue].length) { const request = client[kQueue][client[kRunningIdx]]; client[kQueue][client[kRunningIdx]++] = null; util.errorRequest(client, request, err); client[kPendingIdx] = client[kRunningIdx]; } assert(client[kRunning] === 0); client.emit("disconnect", client[kUrl], [client], err); client[kResume](); } function shouldSendContentLength(method) { return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT"; } function writeH2(client, request) { const session = client[kHTTP2Session]; const { method, path: path14, host: host2, upgrade, expectContinue, signal, headers: reqHeaders } = request; let { body } = request; if (upgrade) { util.errorRequest(client, request, new Error("Upgrade not supported for H2")); return false; } const headers = {}; for (let n = 0; n < reqHeaders.length; n += 2) { const key = reqHeaders[n + 0]; const val = reqHeaders[n + 1]; if (Array.isArray(val)) { for (let i = 0; i < val.length; i++) { if (headers[key]) { headers[key] += `,${val[i]}`; } else { headers[key] = val[i]; } } } else { headers[key] = val; } } let stream; const { hostname, port: port2 } = client[kUrl]; headers[HTTP2_HEADER_AUTHORITY] = host2 || `${hostname}${port2 ? `:${port2}` : ""}`; headers[HTTP2_HEADER_METHOD] = method; const abort = (err) => { if (request.aborted || request.completed) { return; } err = err || new RequestAbortedError(); util.errorRequest(client, request, err); if (stream != null) { util.destroy(stream, err); } util.destroy(body, err); client[kQueue][client[kRunningIdx]++] = null; client[kResume](); }; try { request.onConnect(abort); } catch (err) { util.errorRequest(client, request, err); } if (request.aborted) { return false; } if (method === "CONNECT") { session.ref(); stream = session.request(headers, { endStream: false, signal }); if (stream.id && !stream.pending) { request.onUpgrade(null, null, stream); ++session[kOpenStreams]; client[kQueue][client[kRunningIdx]++] = null; } else { stream.once("ready", () => { request.onUpgrade(null, null, stream); ++session[kOpenStreams]; client[kQueue][client[kRunningIdx]++] = null; }); } stream.once("close", () => { session[kOpenStreams] -= 1; if (session[kOpenStreams] === 0) session.unref(); }); return true; } headers[HTTP2_HEADER_PATH] = path14; headers[HTTP2_HEADER_SCHEME] = "https"; const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH"; if (body && typeof body.read === "function") { body.read(0); } let contentLength = util.bodyLength(body); if (util.isFormDataLike(body)) { extractBody ??= require_body().extractBody; const [bodyStream, contentType] = extractBody(body); headers["content-type"] = contentType; body = bodyStream.stream; contentLength = bodyStream.length; } if (contentLength == null) { contentLength = request.contentLength; } if (contentLength === 0 || !expectsPayload) { contentLength = null; } if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { if (client[kStrictContentLength]) { util.errorRequest(client, request, new RequestContentLengthMismatchError()); return false; } process.emitWarning(new RequestContentLengthMismatchError()); } if (contentLength != null) { assert(body, "no body must not have content length"); headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}`; } session.ref(); const shouldEndStream = method === "GET" || method === "HEAD" || body === null; if (expectContinue) { headers[HTTP2_HEADER_EXPECT] = "100-continue"; stream = session.request(headers, { endStream: shouldEndStream, signal }); stream.once("continue", writeBodyH2); } else { stream = session.request(headers, { endStream: shouldEndStream, signal }); writeBodyH2(); } ++session[kOpenStreams]; stream.once("response", (headers2) => { const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers2; request.onResponseStarted(); if (request.aborted) { const err = new RequestAbortedError(); util.errorRequest(client, request, err); util.destroy(stream, err); return; } if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), "") === false) { stream.pause(); } stream.on("data", (chunk) => { if (request.onData(chunk) === false) { stream.pause(); } }); }); stream.once("end", () => { if (stream.state?.state == null || stream.state.state < 6) { request.onComplete([]); } if (session[kOpenStreams] === 0) { session.unref(); } abort(new InformationalError("HTTP/2: stream half-closed (remote)")); client[kQueue][client[kRunningIdx]++] = null; client[kPendingIdx] = client[kRunningIdx]; client[kResume](); }); stream.once("close", () => { session[kOpenStreams] -= 1; if (session[kOpenStreams] === 0) { session.unref(); } }); stream.once("error", function(err) { abort(err); }); stream.once("frameError", (type, code) => { abort(new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)); }); return true; function writeBodyH2() { if (!body || contentLength === 0) { writeBuffer( abort, stream, null, client, request, client[kSocket], contentLength, expectsPayload ); } else if (util.isBuffer(body)) { writeBuffer( abort, stream, body, client, request, client[kSocket], contentLength, expectsPayload ); } else if (util.isBlobLike(body)) { if (typeof body.stream === "function") { writeIterable( abort, stream, body.stream(), client, request, client[kSocket], contentLength, expectsPayload ); } else { writeBlob( abort, stream, body, client, request, client[kSocket], contentLength, expectsPayload ); } } else if (util.isStream(body)) { writeStream( abort, client[kSocket], expectsPayload, stream, body, client, request, contentLength ); } else if (util.isIterable(body)) { writeIterable( abort, stream, body, client, request, client[kSocket], contentLength, expectsPayload ); } else { assert(false); } } } function writeBuffer(abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { try { if (body != null && util.isBuffer(body)) { assert(contentLength === body.byteLength, "buffer body must have content length"); h2stream.cork(); h2stream.write(body); h2stream.uncork(); h2stream.end(); request.onBodySent(body); } if (!expectsPayload) { socket[kReset] = true; } request.onRequestSent(); client[kResume](); } catch (error) { abort(error); } } function writeStream(abort, socket, expectsPayload, h2stream, body, client, request, contentLength) { assert(contentLength !== 0 || client[kRunning] === 0, "stream body cannot be pipelined"); const pipe = pipeline( body, h2stream, (err) => { if (err) { util.destroy(pipe, err); abort(err); } else { util.removeAllListeners(pipe); request.onRequestSent(); if (!expectsPayload) { socket[kReset] = true; } client[kResume](); } } ); util.addListener(pipe, "data", onPipeData); function onPipeData(chunk) { request.onBodySent(chunk); } } async function writeBlob(abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { assert(contentLength === body.size, "blob body must have content length"); try { if (contentLength != null && contentLength !== body.size) { throw new RequestContentLengthMismatchError(); } const buffer = Buffer.from(await body.arrayBuffer()); h2stream.cork(); h2stream.write(buffer); h2stream.uncork(); h2stream.end(); request.onBodySent(buffer); request.onRequestSent(); if (!expectsPayload) { socket[kReset] = true; } client[kResume](); } catch (err) { abort(err); } } async function writeIterable(abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { assert(contentLength !== 0 || client[kRunning] === 0, "iterator body cannot be pipelined"); let callback = null; function onDrain() { if (callback) { const cb = callback; callback = null; cb(); } } const waitForDrain = () => new Promise((resolve, reject) => { assert(callback === null); if (socket[kError]) { reject(socket[kError]); } else { callback = resolve; } }); h2stream.on("close", onDrain).on("drain", onDrain); try { for await (const chunk of body) { if (socket[kError]) { throw socket[kError]; } const res = h2stream.write(chunk); request.onBodySent(chunk); if (!res) { await waitForDrain(); } } h2stream.end(); request.onRequestSent(); if (!expectsPayload) { socket[kReset] = true; } client[kResume](); } catch (err) { abort(err); } finally { h2stream.off("close", onDrain).off("drain", onDrain); } } module.exports = connectH2; } }); // viewer/node_modules/undici/lib/handler/redirect-handler.js var require_redirect_handler = __commonJS({ "viewer/node_modules/undici/lib/handler/redirect-handler.js"(exports, module) { "use strict"; var util = require_util(); var { kBodyUsed } = require_symbols(); var assert = __require("node:assert"); var { InvalidArgumentError } = require_errors(); var EE = __require("node:events"); var redirectableStatusCodes = [300, 301, 302, 303, 307, 308]; var kBody = /* @__PURE__ */ Symbol("body"); var BodyAsyncIterable = class { constructor(body) { this[kBody] = body; this[kBodyUsed] = false; } async *[Symbol.asyncIterator]() { assert(!this[kBodyUsed], "disturbed"); this[kBodyUsed] = true; yield* this[kBody]; } }; var RedirectHandler = class { constructor(dispatch, maxRedirections, opts, handler) { if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { throw new InvalidArgumentError("maxRedirections must be a positive number"); } util.validateHandler(handler, opts.method, opts.upgrade); this.dispatch = dispatch; this.location = null; this.abort = null; this.opts = { ...opts, maxRedirections: 0 }; this.maxRedirections = maxRedirections; this.handler = handler; this.history = []; this.redirectionLimitReached = false; if (util.isStream(this.opts.body)) { if (util.bodyLength(this.opts.body) === 0) { this.opts.body.on("data", function() { assert(false); }); } if (typeof this.opts.body.readableDidRead !== "boolean") { this.opts.body[kBodyUsed] = false; EE.prototype.on.call(this.opts.body, "data", function() { this[kBodyUsed] = true; }); } } else if (this.opts.body && typeof this.opts.body.pipeTo === "function") { this.opts.body = new BodyAsyncIterable(this.opts.body); } else if (this.opts.body && typeof this.opts.body !== "string" && !ArrayBuffer.isView(this.opts.body) && util.isIterable(this.opts.body)) { this.opts.body = new BodyAsyncIterable(this.opts.body); } } onConnect(abort) { this.abort = abort; this.handler.onConnect(abort, { history: this.history }); } onUpgrade(statusCode, headers, socket) { this.handler.onUpgrade(statusCode, headers, socket); } onError(error) { this.handler.onError(error); } onHeaders(statusCode, headers, resume, statusText) { this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) ? null : parseLocation(statusCode, headers); if (this.opts.throwOnMaxRedirect && this.history.length >= this.maxRedirections) { if (this.request) { this.request.abort(new Error("max redirects")); } this.redirectionLimitReached = true; this.abort(new Error("max redirects")); return; } if (this.opts.origin) { this.history.push(new URL(this.opts.path, this.opts.origin)); } if (!this.location) { return this.handler.onHeaders(statusCode, headers, resume, statusText); } const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))); const path14 = search ? `${pathname}${search}` : pathname; this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin); this.opts.path = path14; this.opts.origin = origin; this.opts.maxRedirections = 0; this.opts.query = null; if (statusCode === 303 && this.opts.method !== "HEAD") { this.opts.method = "GET"; this.opts.body = null; } } onData(chunk) { if (this.location) { } else { return this.handler.onData(chunk); } } onComplete(trailers) { if (this.location) { this.location = null; this.abort = null; this.dispatch(this.opts, this); } else { this.handler.onComplete(trailers); } } onBodySent(chunk) { if (this.handler.onBodySent) { this.handler.onBodySent(chunk); } } }; function parseLocation(statusCode, headers) { if (redirectableStatusCodes.indexOf(statusCode) === -1) { return null; } for (let i = 0; i < headers.length; i += 2) { if (headers[i].length === 8 && util.headerNameToString(headers[i]) === "location") { return headers[i + 1]; } } } function shouldRemoveHeader(header, removeContent, unknownOrigin) { if (header.length === 4) { return util.headerNameToString(header) === "host"; } if (removeContent && util.headerNameToString(header).startsWith("content-")) { return true; } if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { const name = util.headerNameToString(header); return name === "authorization" || name === "cookie" || name === "proxy-authorization"; } return false; } function cleanRequestHeaders(headers, removeContent, unknownOrigin) { const ret = []; if (Array.isArray(headers)) { for (let i = 0; i < headers.length; i += 2) { if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { ret.push(headers[i], headers[i + 1]); } } } else if (headers && typeof headers === "object") { for (const key of Object.keys(headers)) { if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { ret.push(key, headers[key]); } } } else { assert(headers == null, "headers must be an object or an array"); } return ret; } module.exports = RedirectHandler; } }); // viewer/node_modules/undici/lib/interceptor/redirect-interceptor.js var require_redirect_interceptor = __commonJS({ "viewer/node_modules/undici/lib/interceptor/redirect-interceptor.js"(exports, module) { "use strict"; var RedirectHandler = require_redirect_handler(); function createRedirectInterceptor({ maxRedirections: defaultMaxRedirections }) { return (dispatch) => { return function Intercept(opts, handler) { const { maxRedirections = defaultMaxRedirections } = opts; if (!maxRedirections) { return dispatch(opts, handler); } const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler); opts = { ...opts, maxRedirections: 0 }; return dispatch(opts, redirectHandler); }; }; } module.exports = createRedirectInterceptor; } }); // viewer/node_modules/undici/lib/dispatcher/client.js var require_client = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/client.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var net = __require("node:net"); var http2 = __require("node:http"); var util = require_util(); var { channels } = require_diagnostics(); var Request2 = require_request(); var DispatcherBase = require_dispatcher_base(); var { InvalidArgumentError, InformationalError, ClientDestroyedError } = require_errors(); var buildConnector = require_connect(); var { kUrl, kServerName, kClient, kBusy, kConnect, kResuming, kRunning, kPending, kSize, kQueue, kConnected, kConnecting, kNeedDrain, kKeepAliveDefaultTimeout, kHostHeader, kPendingIdx, kRunningIdx, kError, kPipelining, kKeepAliveTimeoutValue, kMaxHeadersSize, kKeepAliveMaxTimeout, kKeepAliveTimeoutThreshold, kHeadersTimeout, kBodyTimeout, kStrictContentLength, kConnector, kMaxRedirections, kMaxRequests, kCounter, kClose, kDestroy, kDispatch, kInterceptors, kLocalAddress, kMaxResponseSize, kOnError, kHTTPContext, kMaxConcurrentStreams, kResume } = require_symbols(); var connectH1 = require_client_h1(); var connectH2 = require_client_h2(); var deprecatedInterceptorWarned = false; var kClosedResolve = /* @__PURE__ */ Symbol("kClosedResolve"); var noop = () => { }; function getPipelining(client) { return client[kPipelining] ?? client[kHTTPContext]?.defaultPipelining ?? 1; } var Client = class extends DispatcherBase { /** * * @param {string|URL} url * @param {import('../../types/client.js').Client.Options} options */ constructor(url, { interceptors, maxHeaderSize, headersTimeout, socketTimeout, requestTimeout, connectTimeout, bodyTimeout, idleTimeout, keepAlive, keepAliveTimeout, maxKeepAliveTimeout, keepAliveMaxTimeout, keepAliveTimeoutThreshold, socketPath, pipelining, tls, strictContentLength, maxCachedSessions, maxRedirections, connect: connect2, maxRequestsPerClient, localAddress, maxResponseSize, autoSelectFamily, autoSelectFamilyAttemptTimeout, // h2 maxConcurrentStreams, allowH2, webSocket } = {}) { super({ webSocket }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } if (socketTimeout !== void 0) { throw new InvalidArgumentError("unsupported socketTimeout, use headersTimeout & bodyTimeout instead"); } if (requestTimeout !== void 0) { throw new InvalidArgumentError("unsupported requestTimeout, use headersTimeout & bodyTimeout instead"); } if (idleTimeout !== void 0) { throw new InvalidArgumentError("unsupported idleTimeout, use keepAliveTimeout instead"); } if (maxKeepAliveTimeout !== void 0) { throw new InvalidArgumentError("unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead"); } if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { throw new InvalidArgumentError("invalid maxHeaderSize"); } if (socketPath != null && typeof socketPath !== "string") { throw new InvalidArgumentError("invalid socketPath"); } if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { throw new InvalidArgumentError("invalid connectTimeout"); } if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { throw new InvalidArgumentError("invalid keepAliveTimeout"); } if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { throw new InvalidArgumentError("invalid keepAliveMaxTimeout"); } if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { throw new InvalidArgumentError("invalid keepAliveTimeoutThreshold"); } if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { throw new InvalidArgumentError("headersTimeout must be a positive integer or zero"); } if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { throw new InvalidArgumentError("bodyTimeout must be a positive integer or zero"); } if (connect2 != null && typeof connect2 !== "function" && typeof connect2 !== "object") { throw new InvalidArgumentError("connect must be a function or an object"); } if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { throw new InvalidArgumentError("maxRedirections must be a positive number"); } if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { throw new InvalidArgumentError("maxRequestsPerClient must be a positive number"); } if (localAddress != null && (typeof localAddress !== "string" || net.isIP(localAddress) === 0)) { throw new InvalidArgumentError("localAddress must be valid string IP address"); } if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { throw new InvalidArgumentError("maxResponseSize must be a positive number"); } if (autoSelectFamilyAttemptTimeout != null && (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1)) { throw new InvalidArgumentError("autoSelectFamilyAttemptTimeout must be a positive number"); } if (allowH2 != null && typeof allowH2 !== "boolean") { throw new InvalidArgumentError("allowH2 must be a valid boolean value"); } if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== "number" || maxConcurrentStreams < 1)) { throw new InvalidArgumentError("maxConcurrentStreams must be a positive integer, greater than 0"); } if (typeof connect2 !== "function") { connect2 = buildConnector({ ...tls, maxCachedSessions, allowH2, socketPath, timeout: connectTimeout, ...autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0, ...connect2 }); } if (interceptors?.Client && Array.isArray(interceptors.Client)) { this[kInterceptors] = interceptors.Client; if (!deprecatedInterceptorWarned) { deprecatedInterceptorWarned = true; process.emitWarning("Client.Options#interceptor is deprecated. Use Dispatcher#compose instead.", { code: "UNDICI-CLIENT-INTERCEPTOR-DEPRECATED" }); } } else { this[kInterceptors] = [createRedirectInterceptor({ maxRedirections })]; } this[kUrl] = util.parseOrigin(url); this[kConnector] = connect2; this[kPipelining] = pipelining != null ? pipelining : 1; this[kMaxHeadersSize] = maxHeaderSize || http2.maxHeaderSize; this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout; this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 6e5 : keepAliveMaxTimeout; this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 2e3 : keepAliveTimeoutThreshold; this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout]; this[kServerName] = null; this[kLocalAddress] = localAddress != null ? localAddress : null; this[kResuming] = 0; this[kNeedDrain] = 0; this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ""}\r `; this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 3e5; this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 3e5; this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength; this[kMaxRedirections] = maxRedirections; this[kMaxRequests] = maxRequestsPerClient; this[kClosedResolve] = null; this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1; this[kMaxConcurrentStreams] = maxConcurrentStreams != null ? maxConcurrentStreams : 100; this[kHTTPContext] = null; this[kQueue] = []; this[kRunningIdx] = 0; this[kPendingIdx] = 0; this[kResume] = (sync) => resume(this, sync); this[kOnError] = (err) => onError(this, err); } get pipelining() { return this[kPipelining]; } set pipelining(value) { this[kPipelining] = value; this[kResume](true); } get [kPending]() { return this[kQueue].length - this[kPendingIdx]; } get [kRunning]() { return this[kPendingIdx] - this[kRunningIdx]; } get [kSize]() { return this[kQueue].length - this[kRunningIdx]; } get [kConnected]() { return !!this[kHTTPContext] && !this[kConnecting] && !this[kHTTPContext].destroyed; } get [kBusy]() { return Boolean( this[kHTTPContext]?.busy(null) || this[kSize] >= (getPipelining(this) || 1) || this[kPending] > 0 ); } /* istanbul ignore: only used for test */ [kConnect](cb) { connect(this); this.once("connect", cb); } [kDispatch](opts, handler) { const origin = opts.origin || this[kUrl].origin; const request = new Request2(origin, opts, handler); this[kQueue].push(request); if (this[kResuming]) { } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { this[kResuming] = 1; queueMicrotask(() => resume(this)); } else { this[kResume](true); } if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { this[kNeedDrain] = 2; } return this[kNeedDrain] < 2; } async [kClose]() { return new Promise((resolve) => { if (this[kSize]) { this[kClosedResolve] = resolve; } else { resolve(null); } }); } async [kDestroy](err) { return new Promise((resolve) => { const requests = this[kQueue].splice(this[kPendingIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; util.errorRequest(this, request, err); } const callback = () => { if (this[kClosedResolve]) { this[kClosedResolve](); this[kClosedResolve] = null; } resolve(null); }; if (this[kHTTPContext]) { this[kHTTPContext].destroy(err, callback); this[kHTTPContext] = null; } else { queueMicrotask(callback); } this[kResume](); }); } }; var createRedirectInterceptor = require_redirect_interceptor(); function onError(client, err) { if (client[kRunning] === 0 && err.code !== "UND_ERR_INFO" && err.code !== "UND_ERR_SOCKET") { assert(client[kPendingIdx] === client[kRunningIdx]); const requests = client[kQueue].splice(client[kRunningIdx]); for (let i = 0; i < requests.length; i++) { const request = requests[i]; util.errorRequest(client, request, err); } assert(client[kSize] === 0); } } async function connect(client) { assert(!client[kConnecting]); assert(!client[kHTTPContext]); let { host: host2, hostname, protocol, port: port2 } = client[kUrl]; if (hostname[0] === "[") { const idx = hostname.indexOf("]"); assert(idx !== -1); const ip = hostname.substring(1, idx); assert(net.isIP(ip)); hostname = ip; } client[kConnecting] = true; if (channels.beforeConnect.hasSubscribers) { channels.beforeConnect.publish({ connectParams: { host: host2, hostname, protocol, port: port2, version: client[kHTTPContext]?.version, servername: client[kServerName], localAddress: client[kLocalAddress] }, connector: client[kConnector] }); } try { const socket = await new Promise((resolve, reject) => { client[kConnector]({ host: host2, hostname, protocol, port: port2, servername: client[kServerName], localAddress: client[kLocalAddress] }, (err, socket2) => { if (err) { reject(err); } else { resolve(socket2); } }); }); if (client.destroyed) { util.destroy(socket.on("error", noop), new ClientDestroyedError()); return; } assert(socket); try { client[kHTTPContext] = socket.alpnProtocol === "h2" ? await connectH2(client, socket) : await connectH1(client, socket); } catch (err) { socket.destroy().on("error", noop); throw err; } client[kConnecting] = false; socket[kCounter] = 0; socket[kMaxRequests] = client[kMaxRequests]; socket[kClient] = client; socket[kError] = null; if (channels.connected.hasSubscribers) { channels.connected.publish({ connectParams: { host: host2, hostname, protocol, port: port2, version: client[kHTTPContext]?.version, servername: client[kServerName], localAddress: client[kLocalAddress] }, connector: client[kConnector], socket }); } client.emit("connect", client[kUrl], [client]); } catch (err) { if (client.destroyed) { return; } client[kConnecting] = false; if (channels.connectError.hasSubscribers) { channels.connectError.publish({ connectParams: { host: host2, hostname, protocol, port: port2, version: client[kHTTPContext]?.version, servername: client[kServerName], localAddress: client[kLocalAddress] }, connector: client[kConnector], error: err }); } if (err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { assert(client[kRunning] === 0); while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { const request = client[kQueue][client[kPendingIdx]++]; util.errorRequest(client, request, err); } } else { onError(client, err); } client.emit("connectionError", client[kUrl], [client], err); } client[kResume](); } function emitDrain(client) { client[kNeedDrain] = 0; client.emit("drain", client[kUrl], [client]); } function resume(client, sync) { if (client[kResuming] === 2) { return; } client[kResuming] = 2; _resume(client, sync); client[kResuming] = 0; if (client[kRunningIdx] > 256) { client[kQueue].splice(0, client[kRunningIdx]); client[kPendingIdx] -= client[kRunningIdx]; client[kRunningIdx] = 0; } } function _resume(client, sync) { while (true) { if (client.destroyed) { assert(client[kPending] === 0); return; } if (client[kClosedResolve] && !client[kSize]) { client[kClosedResolve](); client[kClosedResolve] = null; return; } if (client[kHTTPContext]) { client[kHTTPContext].resume(); } if (client[kBusy]) { client[kNeedDrain] = 2; } else if (client[kNeedDrain] === 2) { if (sync) { client[kNeedDrain] = 1; queueMicrotask(() => emitDrain(client)); } else { emitDrain(client); } continue; } if (client[kPending] === 0) { return; } if (client[kRunning] >= (getPipelining(client) || 1)) { return; } const request = client[kQueue][client[kPendingIdx]]; if (client[kUrl].protocol === "https:" && client[kServerName] !== request.servername) { if (client[kRunning] > 0) { return; } client[kServerName] = request.servername; client[kHTTPContext]?.destroy(new InformationalError("servername changed"), () => { client[kHTTPContext] = null; resume(client); }); } if (client[kConnecting]) { return; } if (!client[kHTTPContext]) { connect(client); return; } if (client[kHTTPContext].destroyed) { return; } if (client[kHTTPContext].busy(request)) { return; } if (!request.aborted && client[kHTTPContext].write(request)) { client[kPendingIdx]++; } else { client[kQueue].splice(client[kPendingIdx], 1); } } } module.exports = Client; } }); // viewer/node_modules/undici/lib/dispatcher/fixed-queue.js var require_fixed_queue = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/fixed-queue.js"(exports, module) { "use strict"; var kSize = 2048; var kMask = kSize - 1; var FixedCircularBuffer = class { constructor() { this.bottom = 0; this.top = 0; this.list = new Array(kSize); this.next = null; } isEmpty() { return this.top === this.bottom; } isFull() { return (this.top + 1 & kMask) === this.bottom; } push(data) { this.list[this.top] = data; this.top = this.top + 1 & kMask; } shift() { const nextItem = this.list[this.bottom]; if (nextItem === void 0) return null; this.list[this.bottom] = void 0; this.bottom = this.bottom + 1 & kMask; return nextItem; } }; module.exports = class FixedQueue { constructor() { this.head = this.tail = new FixedCircularBuffer(); } isEmpty() { return this.head.isEmpty(); } push(data) { if (this.head.isFull()) { this.head = this.head.next = new FixedCircularBuffer(); } this.head.push(data); } shift() { const tail = this.tail; const next = tail.shift(); if (tail.isEmpty() && tail.next !== null) { this.tail = tail.next; } return next; } }; } }); // viewer/node_modules/undici/lib/dispatcher/pool-stats.js var require_pool_stats = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/pool-stats.js"(exports, module) { var { kFree, kConnected, kPending, kQueued, kRunning, kSize } = require_symbols(); var kPool = /* @__PURE__ */ Symbol("pool"); var PoolStats = class { constructor(pool) { this[kPool] = pool; } get connected() { return this[kPool][kConnected]; } get free() { return this[kPool][kFree]; } get pending() { return this[kPool][kPending]; } get queued() { return this[kPool][kQueued]; } get running() { return this[kPool][kRunning]; } get size() { return this[kPool][kSize]; } }; module.exports = PoolStats; } }); // viewer/node_modules/undici/lib/dispatcher/pool-base.js var require_pool_base = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/pool-base.js"(exports, module) { "use strict"; var DispatcherBase = require_dispatcher_base(); var FixedQueue = require_fixed_queue(); var { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = require_symbols(); var PoolStats = require_pool_stats(); var kClients = /* @__PURE__ */ Symbol("clients"); var kNeedDrain = /* @__PURE__ */ Symbol("needDrain"); var kQueue = /* @__PURE__ */ Symbol("queue"); var kClosedResolve = /* @__PURE__ */ Symbol("closed resolve"); var kOnDrain = /* @__PURE__ */ Symbol("onDrain"); var kOnConnect = /* @__PURE__ */ Symbol("onConnect"); var kOnDisconnect = /* @__PURE__ */ Symbol("onDisconnect"); var kOnConnectionError = /* @__PURE__ */ Symbol("onConnectionError"); var kGetDispatcher = /* @__PURE__ */ Symbol("get dispatcher"); var kAddClient = /* @__PURE__ */ Symbol("add client"); var kRemoveClient = /* @__PURE__ */ Symbol("remove client"); var kStats = /* @__PURE__ */ Symbol("stats"); var PoolBase = class extends DispatcherBase { constructor(opts) { super(opts); this[kQueue] = new FixedQueue(); this[kClients] = []; this[kQueued] = 0; const pool = this; this[kOnDrain] = function onDrain(origin, targets) { const queue = pool[kQueue]; let needDrain = false; while (!needDrain) { const item = queue.shift(); if (!item) { break; } pool[kQueued]--; needDrain = !this.dispatch(item.opts, item.handler); } this[kNeedDrain] = needDrain; if (!this[kNeedDrain] && pool[kNeedDrain]) { pool[kNeedDrain] = false; pool.emit("drain", origin, [pool, ...targets]); } if (pool[kClosedResolve] && queue.isEmpty()) { Promise.all(pool[kClients].map((c) => c.close())).then(pool[kClosedResolve]); } }; this[kOnConnect] = (origin, targets) => { pool.emit("connect", origin, [pool, ...targets]); }; this[kOnDisconnect] = (origin, targets, err) => { pool.emit("disconnect", origin, [pool, ...targets], err); }; this[kOnConnectionError] = (origin, targets, err) => { pool.emit("connectionError", origin, [pool, ...targets], err); }; this[kStats] = new PoolStats(this); } get [kBusy]() { return this[kNeedDrain]; } get [kConnected]() { return this[kClients].filter((client) => client[kConnected]).length; } get [kFree]() { return this[kClients].filter((client) => client[kConnected] && !client[kNeedDrain]).length; } get [kPending]() { let ret = this[kQueued]; for (const { [kPending]: pending } of this[kClients]) { ret += pending; } return ret; } get [kRunning]() { let ret = 0; for (const { [kRunning]: running } of this[kClients]) { ret += running; } return ret; } get [kSize]() { let ret = this[kQueued]; for (const { [kSize]: size } of this[kClients]) { ret += size; } return ret; } get stats() { return this[kStats]; } async [kClose]() { if (this[kQueue].isEmpty()) { await Promise.all(this[kClients].map((c) => c.close())); } else { await new Promise((resolve) => { this[kClosedResolve] = resolve; }); } } async [kDestroy](err) { while (true) { const item = this[kQueue].shift(); if (!item) { break; } item.handler.onError(err); } await Promise.all(this[kClients].map((c) => c.destroy(err))); } [kDispatch](opts, handler) { const dispatcher = this[kGetDispatcher](); if (!dispatcher) { this[kNeedDrain] = true; this[kQueue].push({ opts, handler }); this[kQueued]++; } else if (!dispatcher.dispatch(opts, handler)) { dispatcher[kNeedDrain] = true; this[kNeedDrain] = !this[kGetDispatcher](); } return !this[kNeedDrain]; } [kAddClient](client) { client.on("drain", this[kOnDrain]).on("connect", this[kOnConnect]).on("disconnect", this[kOnDisconnect]).on("connectionError", this[kOnConnectionError]); this[kClients].push(client); if (this[kNeedDrain]) { queueMicrotask(() => { if (this[kNeedDrain]) { this[kOnDrain](client[kUrl], [this, client]); } }); } return this; } [kRemoveClient](client) { client.close(() => { const idx = this[kClients].indexOf(client); if (idx !== -1) { this[kClients].splice(idx, 1); } }); this[kNeedDrain] = this[kClients].some((dispatcher) => !dispatcher[kNeedDrain] && dispatcher.closed !== true && dispatcher.destroyed !== true); } }; module.exports = { PoolBase, kClients, kNeedDrain, kAddClient, kRemoveClient, kGetDispatcher }; } }); // viewer/node_modules/undici/lib/dispatcher/pool.js var require_pool = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/pool.js"(exports, module) { "use strict"; var { PoolBase, kClients, kNeedDrain, kAddClient, kGetDispatcher } = require_pool_base(); var Client = require_client(); var { InvalidArgumentError } = require_errors(); var util = require_util(); var { kUrl, kInterceptors } = require_symbols(); var buildConnector = require_connect(); var kOptions = /* @__PURE__ */ Symbol("options"); var kConnections = /* @__PURE__ */ Symbol("connections"); var kFactory = /* @__PURE__ */ Symbol("factory"); function defaultFactory(origin, opts) { return new Client(origin, opts); } var Pool = class extends PoolBase { constructor(origin, { connections, factory = defaultFactory, connect, connectTimeout, tls, maxCachedSessions, socketPath, autoSelectFamily, autoSelectFamilyAttemptTimeout, allowH2, ...options } = {}) { if (connections != null && (!Number.isFinite(connections) || connections < 0)) { throw new InvalidArgumentError("invalid connections"); } if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } if (connect != null && typeof connect !== "function" && typeof connect !== "object") { throw new InvalidArgumentError("connect must be a function or an object"); } if (typeof connect !== "function") { connect = buildConnector({ ...tls, maxCachedSessions, allowH2, socketPath, timeout: connectTimeout, ...autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0, ...connect }); } super(options); this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool) ? options.interceptors.Pool : []; this[kConnections] = connections || null; this[kUrl] = util.parseOrigin(origin); this[kOptions] = { ...util.deepClone(options), connect, allowH2 }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kFactory] = factory; this.on("connectionError", (origin2, targets, error) => { for (const target of targets) { const idx = this[kClients].indexOf(target); if (idx !== -1) { this[kClients].splice(idx, 1); } } }); } [kGetDispatcher]() { for (const client of this[kClients]) { if (!client[kNeedDrain]) { return client; } } if (!this[kConnections] || this[kClients].length < this[kConnections]) { const dispatcher = this[kFactory](this[kUrl], this[kOptions]); this[kAddClient](dispatcher); return dispatcher; } } }; module.exports = Pool; } }); // viewer/node_modules/undici/lib/dispatcher/balanced-pool.js var require_balanced_pool = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/balanced-pool.js"(exports, module) { "use strict"; var { BalancedPoolMissingUpstreamError, InvalidArgumentError } = require_errors(); var { PoolBase, kClients, kNeedDrain, kAddClient, kRemoveClient, kGetDispatcher } = require_pool_base(); var Pool = require_pool(); var { kUrl, kInterceptors } = require_symbols(); var { parseOrigin } = require_util(); var kFactory = /* @__PURE__ */ Symbol("factory"); var kOptions = /* @__PURE__ */ Symbol("options"); var kGreatestCommonDivisor = /* @__PURE__ */ Symbol("kGreatestCommonDivisor"); var kCurrentWeight = /* @__PURE__ */ Symbol("kCurrentWeight"); var kIndex = /* @__PURE__ */ Symbol("kIndex"); var kWeight = /* @__PURE__ */ Symbol("kWeight"); var kMaxWeightPerServer = /* @__PURE__ */ Symbol("kMaxWeightPerServer"); var kErrorPenalty = /* @__PURE__ */ Symbol("kErrorPenalty"); function getGreatestCommonDivisor(a, b) { if (a === 0) return b; while (b !== 0) { const t = b; b = a % b; a = t; } return a; } function defaultFactory(origin, opts) { return new Pool(origin, opts); } var BalancedPool = class extends PoolBase { constructor(upstreams = [], { factory = defaultFactory, ...opts } = {}) { super(); this[kOptions] = opts; this[kIndex] = -1; this[kCurrentWeight] = 0; this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100; this[kErrorPenalty] = this[kOptions].errorPenalty || 15; if (!Array.isArray(upstreams)) { upstreams = [upstreams]; } if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } this[kInterceptors] = opts.interceptors?.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) ? opts.interceptors.BalancedPool : []; this[kFactory] = factory; for (const upstream of upstreams) { this.addUpstream(upstream); } this._updateBalancedPoolStats(); } addUpstream(upstream) { const upstreamOrigin = parseOrigin(upstream).origin; if (this[kClients].find((pool2) => pool2[kUrl].origin === upstreamOrigin && pool2.closed !== true && pool2.destroyed !== true)) { return this; } const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])); this[kAddClient](pool); pool.on("connect", () => { pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]); }); pool.on("connectionError", () => { pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]); this._updateBalancedPoolStats(); }); pool.on("disconnect", (...args) => { const err = args[2]; if (err && err.code === "UND_ERR_SOCKET") { pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]); this._updateBalancedPoolStats(); } }); for (const client of this[kClients]) { client[kWeight] = this[kMaxWeightPerServer]; } this._updateBalancedPoolStats(); return this; } _updateBalancedPoolStats() { let result = 0; for (let i = 0; i < this[kClients].length; i++) { result = getGreatestCommonDivisor(this[kClients][i][kWeight], result); } this[kGreatestCommonDivisor] = result; } removeUpstream(upstream) { const upstreamOrigin = parseOrigin(upstream).origin; const pool = this[kClients].find((pool2) => pool2[kUrl].origin === upstreamOrigin && pool2.closed !== true && pool2.destroyed !== true); if (pool) { this[kRemoveClient](pool); } return this; } get upstreams() { return this[kClients].filter((dispatcher) => dispatcher.closed !== true && dispatcher.destroyed !== true).map((p) => p[kUrl].origin); } [kGetDispatcher]() { if (this[kClients].length === 0) { throw new BalancedPoolMissingUpstreamError(); } const dispatcher = this[kClients].find((dispatcher2) => !dispatcher2[kNeedDrain] && dispatcher2.closed !== true && dispatcher2.destroyed !== true); if (!dispatcher) { return; } const allClientsBusy = this[kClients].map((pool) => pool[kNeedDrain]).reduce((a, b) => a && b, true); if (allClientsBusy) { return; } let counter = 0; let maxWeightIndex = this[kClients].findIndex((pool) => !pool[kNeedDrain]); while (counter++ < this[kClients].length) { this[kIndex] = (this[kIndex] + 1) % this[kClients].length; const pool = this[kClients][this[kIndex]]; if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { maxWeightIndex = this[kIndex]; } if (this[kIndex] === 0) { this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor]; if (this[kCurrentWeight] <= 0) { this[kCurrentWeight] = this[kMaxWeightPerServer]; } } if (pool[kWeight] >= this[kCurrentWeight] && !pool[kNeedDrain]) { return pool; } } this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight]; this[kIndex] = maxWeightIndex; return this[kClients][maxWeightIndex]; } }; module.exports = BalancedPool; } }); // viewer/node_modules/undici/lib/dispatcher/agent.js var require_agent = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/agent.js"(exports, module) { "use strict"; var { InvalidArgumentError } = require_errors(); var { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = require_symbols(); var DispatcherBase = require_dispatcher_base(); var Pool = require_pool(); var Client = require_client(); var util = require_util(); var createRedirectInterceptor = require_redirect_interceptor(); var kOnConnect = /* @__PURE__ */ Symbol("onConnect"); var kOnDisconnect = /* @__PURE__ */ Symbol("onDisconnect"); var kOnConnectionError = /* @__PURE__ */ Symbol("onConnectionError"); var kMaxRedirections = /* @__PURE__ */ Symbol("maxRedirections"); var kOnDrain = /* @__PURE__ */ Symbol("onDrain"); var kFactory = /* @__PURE__ */ Symbol("factory"); var kOptions = /* @__PURE__ */ Symbol("options"); function defaultFactory(origin, opts) { return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } if (connect != null && typeof connect !== "function" && typeof connect !== "object") { throw new InvalidArgumentError("connect must be a function or an object"); } if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { throw new InvalidArgumentError("maxRedirections must be a positive number"); } super(options); if (connect && typeof connect !== "function") { connect = { ...connect }; } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; this[kOptions] = { ...util.deepClone(options), connect }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; this[kClients] = /* @__PURE__ */ new Map(); this[kOnDrain] = (origin, targets) => { this.emit("drain", origin, [this, ...targets]); }; this[kOnConnect] = (origin, targets) => { this.emit("connect", origin, [this, ...targets]); }; this[kOnDisconnect] = (origin, targets, err) => { this.emit("disconnect", origin, [this, ...targets], err); }; this[kOnConnectionError] = (origin, targets, err) => { this.emit("connectionError", origin, [this, ...targets], err); }; } get [kRunning]() { let ret = 0; for (const client of this[kClients].values()) { ret += client[kRunning]; } return ret; } [kDispatch](opts, handler) { let key; if (opts.origin && (typeof opts.origin === "string" || opts.origin instanceof URL)) { key = String(opts.origin); } else { throw new InvalidArgumentError("opts.origin must be a non-empty string or URL."); } let dispatcher = this[kClients].get(key); if (!dispatcher) { dispatcher = this[kFactory](opts.origin, this[kOptions]).on("drain", this[kOnDrain]).on("connect", this[kOnConnect]).on("disconnect", this[kOnDisconnect]).on("connectionError", this[kOnConnectionError]); this[kClients].set(key, dispatcher); } return dispatcher.dispatch(opts, handler); } async [kClose]() { const closePromises = []; for (const client of this[kClients].values()) { closePromises.push(client.close()); } this[kClients].clear(); await Promise.all(closePromises); } async [kDestroy](err) { const destroyPromises = []; for (const client of this[kClients].values()) { destroyPromises.push(client.destroy(err)); } this[kClients].clear(); await Promise.all(destroyPromises); } }; module.exports = Agent; } }); // viewer/node_modules/undici/lib/dispatcher/proxy-agent.js var require_proxy_agent = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/proxy-agent.js"(exports, module) { "use strict"; var { kProxy, kClose, kDestroy, kDispatch, kInterceptors } = require_symbols(); var { URL: URL2 } = __require("node:url"); var Agent = require_agent(); var Pool = require_pool(); var DispatcherBase = require_dispatcher_base(); var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = require_errors(); var buildConnector = require_connect(); var Client = require_client(); var kAgent = /* @__PURE__ */ Symbol("proxy agent"); var kClient = /* @__PURE__ */ Symbol("proxy client"); var kProxyHeaders = /* @__PURE__ */ Symbol("proxy headers"); var kRequestTls = /* @__PURE__ */ Symbol("request tls settings"); var kProxyTls = /* @__PURE__ */ Symbol("proxy tls settings"); var kConnectEndpoint = /* @__PURE__ */ Symbol("connect endpoint function"); var kTunnelProxy = /* @__PURE__ */ Symbol("tunnel proxy"); function defaultProtocolPort(protocol) { return protocol === "https:" ? 443 : 80; } function defaultFactory(origin, opts) { return new Pool(origin, opts); } var noop = () => { }; function defaultAgentFactory(origin, opts) { if (opts.connections === 1) { return new Client(origin, opts); } return new Pool(origin, opts); } var Http1ProxyWrapper = class extends DispatcherBase { #client; constructor(proxyUrl, { headers = {}, connect, factory }) { super(); if (!proxyUrl) { throw new InvalidArgumentError("Proxy URL is mandatory"); } this[kProxyHeaders] = headers; if (factory) { this.#client = factory(proxyUrl, { connect }); } else { this.#client = new Client(proxyUrl, { connect }); } } [kDispatch](opts, handler) { const onHeaders = handler.onHeaders; handler.onHeaders = function(statusCode, data, resume) { if (statusCode === 407) { if (typeof handler.onError === "function") { handler.onError(new InvalidArgumentError("Proxy Authentication Required (407)")); } return; } if (onHeaders) onHeaders.call(this, statusCode, data, resume); }; const { origin, path: path14 = "/", headers = {} } = opts; opts.path = origin + path14; if (!("host" in headers) && !("Host" in headers)) { const { host: host2 } = new URL2(origin); headers.host = host2; } opts.headers = { ...this[kProxyHeaders], ...headers }; return this.#client[kDispatch](opts, handler); } async [kClose]() { return this.#client.close(); } async [kDestroy](err) { return this.#client.destroy(err); } }; var ProxyAgent = class extends DispatcherBase { constructor(opts) { super(); if (!opts || typeof opts === "object" && !(opts instanceof URL2) && !opts.uri) { throw new InvalidArgumentError("Proxy uri is mandatory"); } const { clientFactory = defaultFactory } = opts; if (typeof clientFactory !== "function") { throw new InvalidArgumentError("Proxy opts.clientFactory must be a function."); } const { proxyTunnel = true } = opts; const url = this.#getUrl(opts); const { href, origin, port: port2, protocol, username, password, hostname: proxyHostname } = url; this[kProxy] = { uri: href, protocol }; this[kInterceptors] = opts.interceptors?.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) ? opts.interceptors.ProxyAgent : []; this[kRequestTls] = opts.requestTls; this[kProxyTls] = opts.proxyTls; this[kProxyHeaders] = opts.headers || {}; this[kTunnelProxy] = proxyTunnel; if (opts.auth && opts.token) { throw new InvalidArgumentError("opts.auth cannot be used in combination with opts.token"); } else if (opts.auth) { this[kProxyHeaders]["proxy-authorization"] = `Basic ${opts.auth}`; } else if (opts.token) { this[kProxyHeaders]["proxy-authorization"] = opts.token; } else if (username && password) { this[kProxyHeaders]["proxy-authorization"] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString("base64")}`; } const connect = buildConnector({ ...opts.proxyTls }); this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }); const agentFactory = opts.factory || defaultAgentFactory; const factory = (origin2, options) => { const { protocol: protocol2 } = new URL2(origin2); if (!this[kTunnelProxy] && protocol2 === "http:" && this[kProxy].protocol === "http:") { return new Http1ProxyWrapper(this[kProxy].uri, { headers: this[kProxyHeaders], connect, factory: agentFactory }); } return agentFactory(origin2, options); }; this[kClient] = clientFactory(url, { connect }); this[kAgent] = new Agent({ ...opts, factory, connect: async (opts2, callback) => { let requestedPath = opts2.host; if (!opts2.port) { requestedPath += `:${defaultProtocolPort(opts2.protocol)}`; } try { const { socket, statusCode } = await this[kClient].connect({ origin, port: port2, path: requestedPath, signal: opts2.signal, headers: { ...this[kProxyHeaders], host: opts2.host }, servername: this[kProxyTls]?.servername || proxyHostname }); if (statusCode !== 200) { socket.on("error", noop).destroy(); callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)); } if (opts2.protocol !== "https:") { callback(null, socket); return; } let servername; if (this[kRequestTls]) { servername = this[kRequestTls].servername; } else { servername = opts2.servername; } this[kConnectEndpoint]({ ...opts2, servername, httpSocket: socket }, callback); } catch (err) { if (err.code === "ERR_TLS_CERT_ALTNAME_INVALID") { callback(new SecureProxyConnectionError(err)); } else { callback(err); } } } }); } dispatch(opts, handler) { const headers = buildHeaders(opts.headers); throwIfProxyAuthIsSent(headers); if (headers && !("host" in headers) && !("Host" in headers)) { const { host: host2 } = new URL2(opts.origin); headers.host = host2; } return this[kAgent].dispatch( { ...opts, headers }, handler ); } /** * @param {import('../types/proxy-agent').ProxyAgent.Options | string | URL} opts * @returns {URL} */ #getUrl(opts) { if (typeof opts === "string") { return new URL2(opts); } else if (opts instanceof URL2) { return opts; } else { return new URL2(opts.uri); } } async [kClose]() { await this[kAgent].close(); await this[kClient].close(); } async [kDestroy]() { await this[kAgent].destroy(); await this[kClient].destroy(); } }; function buildHeaders(headers) { if (Array.isArray(headers)) { const headersPair = {}; for (let i = 0; i < headers.length; i += 2) { headersPair[headers[i]] = headers[i + 1]; } return headersPair; } return headers; } function throwIfProxyAuthIsSent(headers) { const existProxyAuth = headers && Object.keys(headers).find((key) => key.toLowerCase() === "proxy-authorization"); if (existProxyAuth) { throw new InvalidArgumentError("Proxy-Authorization should be sent in ProxyAgent constructor"); } } module.exports = ProxyAgent; } }); // viewer/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js var require_env_http_proxy_agent = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js"(exports, module) { "use strict"; var DispatcherBase = require_dispatcher_base(); var { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = require_symbols(); var ProxyAgent = require_proxy_agent(); var Agent = require_agent(); var DEFAULT_PORTS = { "http:": 80, "https:": 443 }; var experimentalWarned = false; var EnvHttpProxyAgent = class extends DispatcherBase { #noProxyValue = null; #noProxyEntries = null; #opts = null; constructor(opts = {}) { super(); this.#opts = opts; if (!experimentalWarned) { experimentalWarned = true; process.emitWarning("EnvHttpProxyAgent is experimental, expect them to change at any time.", { code: "UNDICI-EHPA" }); } const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts; this[kNoProxyAgent] = new Agent(agentOpts); const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY; if (HTTP_PROXY) { this[kHttpProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTP_PROXY }); } else { this[kHttpProxyAgent] = this[kNoProxyAgent]; } const HTTPS_PROXY = httpsProxy ?? process.env.https_proxy ?? process.env.HTTPS_PROXY; if (HTTPS_PROXY) { this[kHttpsProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTPS_PROXY }); } else { this[kHttpsProxyAgent] = this[kHttpProxyAgent]; } this.#parseNoProxy(); } [kDispatch](opts, handler) { const url = new URL(opts.origin); const agent = this.#getProxyAgentForUrl(url); return agent.dispatch(opts, handler); } async [kClose]() { await this[kNoProxyAgent].close(); if (!this[kHttpProxyAgent][kClosed]) { await this[kHttpProxyAgent].close(); } if (!this[kHttpsProxyAgent][kClosed]) { await this[kHttpsProxyAgent].close(); } } async [kDestroy](err) { await this[kNoProxyAgent].destroy(err); if (!this[kHttpProxyAgent][kDestroyed]) { await this[kHttpProxyAgent].destroy(err); } if (!this[kHttpsProxyAgent][kDestroyed]) { await this[kHttpsProxyAgent].destroy(err); } } #getProxyAgentForUrl(url) { let { protocol, host: hostname, port: port2 } = url; hostname = hostname.replace(/:\d*$/, "").toLowerCase(); port2 = Number.parseInt(port2, 10) || DEFAULT_PORTS[protocol] || 0; if (!this.#shouldProxy(hostname, port2)) { return this[kNoProxyAgent]; } if (protocol === "https:") { return this[kHttpsProxyAgent]; } return this[kHttpProxyAgent]; } #shouldProxy(hostname, port2) { if (this.#noProxyChanged) { this.#parseNoProxy(); } if (this.#noProxyEntries.length === 0) { return true; } if (this.#noProxyValue === "*") { return false; } for (let i = 0; i < this.#noProxyEntries.length; i++) { const entry = this.#noProxyEntries[i]; if (entry.port && entry.port !== port2) { continue; } if (!/^[.*]/.test(entry.hostname)) { if (hostname === entry.hostname) { return false; } } else { if (hostname.endsWith(entry.hostname.replace(/^\*/, ""))) { return false; } } } return true; } #parseNoProxy() { const noProxyValue = this.#opts.noProxy ?? this.#noProxyEnv; const noProxySplit = noProxyValue.split(/[,\s]/); const noProxyEntries = []; for (let i = 0; i < noProxySplit.length; i++) { const entry = noProxySplit[i]; if (!entry) { continue; } const parsed = entry.match(/^(.+):(\d+)$/); noProxyEntries.push({ hostname: (parsed ? parsed[1] : entry).toLowerCase(), port: parsed ? Number.parseInt(parsed[2], 10) : 0 }); } this.#noProxyValue = noProxyValue; this.#noProxyEntries = noProxyEntries; } get #noProxyChanged() { if (this.#opts.noProxy !== void 0) { return false; } return this.#noProxyValue !== this.#noProxyEnv; } get #noProxyEnv() { return process.env.no_proxy ?? process.env.NO_PROXY ?? ""; } }; module.exports = EnvHttpProxyAgent; } }); // viewer/node_modules/undici/lib/handler/retry-handler.js var require_retry_handler = __commonJS({ "viewer/node_modules/undici/lib/handler/retry-handler.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { kRetryHandlerDefaultRetry } = require_symbols(); var { RequestRetryError } = require_errors(); var { isDisturbed, parseHeaders, parseRangeHeader, wrapRequestBody } = require_util(); function calculateRetryAfterHeader(retryAfter) { const current = Date.now(); return new Date(retryAfter).getTime() - current; } var RetryHandler = class _RetryHandler { constructor(opts, handlers) { const { retryOptions, ...dispatchOpts } = opts; const { // Retry scoped retry: retryFn, maxRetries, maxTimeout, minTimeout, timeoutFactor, // Response scoped methods, errorCodes, retryAfter, statusCodes } = retryOptions ?? {}; this.dispatch = handlers.dispatch; this.handler = handlers.handler; this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }; this.abort = null; this.aborted = false; this.retryOpts = { retry: retryFn ?? _RetryHandler[kRetryHandlerDefaultRetry], retryAfter: retryAfter ?? true, maxTimeout: maxTimeout ?? 30 * 1e3, // 30s, minTimeout: minTimeout ?? 500, // .5s timeoutFactor: timeoutFactor ?? 2, maxRetries: maxRetries ?? 5, // What errors we should retry methods: methods ?? ["GET", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"], // Indicates which errors to retry statusCodes: statusCodes ?? [500, 502, 503, 504, 429], // List of errors to retry errorCodes: errorCodes ?? [ "ECONNRESET", "ECONNREFUSED", "ENOTFOUND", "ENETDOWN", "ENETUNREACH", "EHOSTDOWN", "EHOSTUNREACH", "EPIPE", "UND_ERR_SOCKET" ] }; this.retryCount = 0; this.retryCountCheckpoint = 0; this.start = 0; this.end = null; this.etag = null; this.resume = null; this.handler.onConnect((reason) => { this.aborted = true; if (this.abort) { this.abort(reason); } else { this.reason = reason; } }); } onRequestSent() { if (this.handler.onRequestSent) { this.handler.onRequestSent(); } } onUpgrade(statusCode, headers, socket) { if (this.handler.onUpgrade) { this.handler.onUpgrade(statusCode, headers, socket); } } onConnect(abort) { if (this.aborted) { abort(this.reason); } else { this.abort = abort; } } onBodySent(chunk) { if (this.handler.onBodySent) return this.handler.onBodySent(chunk); } static [kRetryHandlerDefaultRetry](err, { state, opts }, cb) { const { statusCode, code, headers } = err; const { method, retryOptions } = opts; const { maxRetries, minTimeout, maxTimeout, timeoutFactor, statusCodes, errorCodes, methods } = retryOptions; const { counter } = state; if (code && code !== "UND_ERR_REQ_RETRY" && !errorCodes.includes(code)) { cb(err); return; } if (Array.isArray(methods) && !methods.includes(method)) { cb(err); return; } if (statusCode != null && Array.isArray(statusCodes) && !statusCodes.includes(statusCode)) { cb(err); return; } if (counter > maxRetries) { cb(err); return; } let retryAfterHeader = headers?.["retry-after"]; if (retryAfterHeader) { retryAfterHeader = Number(retryAfterHeader); retryAfterHeader = Number.isNaN(retryAfterHeader) ? calculateRetryAfterHeader(retryAfterHeader) : retryAfterHeader * 1e3; } const retryTimeout = retryAfterHeader > 0 ? Math.min(retryAfterHeader, maxTimeout) : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout); setTimeout(() => cb(null), retryTimeout); } onHeaders(statusCode, rawHeaders, resume, statusMessage) { const headers = parseHeaders(rawHeaders); this.retryCount += 1; if (statusCode >= 300) { if (this.retryOpts.statusCodes.includes(statusCode) === false) { return this.handler.onHeaders( statusCode, rawHeaders, resume, statusMessage ); } else { this.abort( new RequestRetryError("Request failed", statusCode, { headers, data: { count: this.retryCount } }) ); return false; } } if (this.resume != null) { this.resume = null; if (statusCode !== 206 && (this.start > 0 || statusCode !== 200)) { this.abort( new RequestRetryError("server does not support the range header and the payload was partially consumed", statusCode, { headers, data: { count: this.retryCount } }) ); return false; } const contentRange = parseRangeHeader(headers["content-range"]); if (!contentRange) { this.abort( new RequestRetryError("Content-Range mismatch", statusCode, { headers, data: { count: this.retryCount } }) ); return false; } if (this.etag != null && this.etag !== headers.etag) { this.abort( new RequestRetryError("ETag mismatch", statusCode, { headers, data: { count: this.retryCount } }) ); return false; } const { start, size, end = size - 1 } = contentRange; assert(this.start === start, "content-range mismatch"); assert(this.end == null || this.end === end, "content-range mismatch"); this.resume = resume; return true; } if (this.end == null) { if (statusCode === 206) { const range = parseRangeHeader(headers["content-range"]); if (range == null) { return this.handler.onHeaders( statusCode, rawHeaders, resume, statusMessage ); } const { start, size, end = size - 1 } = range; assert( start != null && Number.isFinite(start), "content-range mismatch" ); assert(end != null && Number.isFinite(end), "invalid content-length"); this.start = start; this.end = end; } if (this.end == null) { const contentLength = headers["content-length"]; this.end = contentLength != null ? Number(contentLength) - 1 : null; } assert(Number.isFinite(this.start)); assert( this.end == null || Number.isFinite(this.end), "invalid content-length" ); this.resume = resume; this.etag = headers.etag != null ? headers.etag : null; if (this.etag != null && this.etag.startsWith("W/")) { this.etag = null; } return this.handler.onHeaders( statusCode, rawHeaders, resume, statusMessage ); } const err = new RequestRetryError("Request failed", statusCode, { headers, data: { count: this.retryCount } }); this.abort(err); return false; } onData(chunk) { this.start += chunk.length; return this.handler.onData(chunk); } onComplete(rawTrailers) { this.retryCount = 0; return this.handler.onComplete(rawTrailers); } onError(err) { if (this.aborted || isDisturbed(this.opts.body)) { return this.handler.onError(err); } if (this.retryCount - this.retryCountCheckpoint > 0) { this.retryCount = this.retryCountCheckpoint + (this.retryCount - this.retryCountCheckpoint); } else { this.retryCount += 1; } this.retryOpts.retry( err, { state: { counter: this.retryCount }, opts: { retryOptions: this.retryOpts, ...this.opts } }, onRetry.bind(this) ); function onRetry(err2) { if (err2 != null || this.aborted || isDisturbed(this.opts.body)) { return this.handler.onError(err2); } if (this.start !== 0) { const headers = { range: `bytes=${this.start}-${this.end ?? ""}` }; if (this.etag != null) { headers["if-match"] = this.etag; } this.opts = { ...this.opts, headers: { ...this.opts.headers, ...headers } }; } try { this.retryCountCheckpoint = this.retryCount; this.dispatch(this.opts, this); } catch (err3) { this.handler.onError(err3); } } } }; module.exports = RetryHandler; } }); // viewer/node_modules/undici/lib/dispatcher/retry-agent.js var require_retry_agent = __commonJS({ "viewer/node_modules/undici/lib/dispatcher/retry-agent.js"(exports, module) { "use strict"; var Dispatcher = require_dispatcher(); var RetryHandler = require_retry_handler(); var RetryAgent = class extends Dispatcher { #agent = null; #options = null; constructor(agent, options = {}) { super(options); this.#agent = agent; this.#options = options; } dispatch(opts, handler) { const retry2 = new RetryHandler({ ...opts, retryOptions: this.#options }, { dispatch: this.#agent.dispatch.bind(this.#agent), handler }); return this.#agent.dispatch(opts, retry2); } close() { return this.#agent.close(); } destroy() { return this.#agent.destroy(); } }; module.exports = RetryAgent; } }); // viewer/node_modules/undici/lib/api/readable.js var require_readable = __commonJS({ "viewer/node_modules/undici/lib/api/readable.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { Readable: Readable2 } = __require("node:stream"); var { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = require_errors(); var util = require_util(); var { ReadableStreamFrom } = require_util(); var kConsume = /* @__PURE__ */ Symbol("kConsume"); var kReading = /* @__PURE__ */ Symbol("kReading"); var kBody = /* @__PURE__ */ Symbol("kBody"); var kAbort = /* @__PURE__ */ Symbol("kAbort"); var kContentType = /* @__PURE__ */ Symbol("kContentType"); var kContentLength = /* @__PURE__ */ Symbol("kContentLength"); var noop = () => { }; var BodyReadable = class extends Readable2 { constructor({ resume, abort, contentType = "", contentLength, highWaterMark = 64 * 1024 // Same as nodejs fs streams. }) { super({ autoDestroy: true, read: resume, highWaterMark }); this._readableState.dataEmitted = false; this[kAbort] = abort; this[kConsume] = null; this[kBody] = null; this[kContentType] = contentType; this[kContentLength] = contentLength; this[kReading] = false; } destroy(err) { if (!err && !this._readableState.endEmitted) { err = new RequestAbortedError(); } if (err) { this[kAbort](); } return super.destroy(err); } _destroy(err, callback) { if (!this[kReading]) { setImmediate(() => { callback(err); }); } else { callback(err); } } on(ev, ...args) { if (ev === "data" || ev === "readable") { this[kReading] = true; } return super.on(ev, ...args); } addListener(ev, ...args) { return this.on(ev, ...args); } off(ev, ...args) { const ret = super.off(ev, ...args); if (ev === "data" || ev === "readable") { this[kReading] = this.listenerCount("data") > 0 || this.listenerCount("readable") > 0; } return ret; } removeListener(ev, ...args) { return this.off(ev, ...args); } push(chunk) { if (this[kConsume] && chunk !== null) { consumePush(this[kConsume], chunk); return this[kReading] ? super.push(chunk) : true; } return super.push(chunk); } // https://fetch.spec.whatwg.org/#dom-body-text async text() { return consume(this, "text"); } // https://fetch.spec.whatwg.org/#dom-body-json async json() { return consume(this, "json"); } // https://fetch.spec.whatwg.org/#dom-body-blob async blob() { return consume(this, "blob"); } // https://fetch.spec.whatwg.org/#dom-body-bytes async bytes() { return consume(this, "bytes"); } // https://fetch.spec.whatwg.org/#dom-body-arraybuffer async arrayBuffer() { return consume(this, "arrayBuffer"); } // https://fetch.spec.whatwg.org/#dom-body-formdata async formData() { throw new NotSupportedError(); } // https://fetch.spec.whatwg.org/#dom-body-bodyused get bodyUsed() { return util.isDisturbed(this); } // https://fetch.spec.whatwg.org/#dom-body-body get body() { if (!this[kBody]) { this[kBody] = ReadableStreamFrom(this); if (this[kConsume]) { this[kBody].getReader(); assert(this[kBody].locked); } } return this[kBody]; } async dump(opts) { let limit = Number.isFinite(opts?.limit) ? opts.limit : 128 * 1024; const signal = opts?.signal; if (signal != null && (typeof signal !== "object" || !("aborted" in signal))) { throw new InvalidArgumentError("signal must be an AbortSignal"); } signal?.throwIfAborted(); if (this._readableState.closeEmitted) { return null; } return await new Promise((resolve, reject) => { if (this[kContentLength] > limit) { this.destroy(new AbortError()); } const onAbort = () => { this.destroy(signal.reason ?? new AbortError()); }; signal?.addEventListener("abort", onAbort); this.on("close", function() { signal?.removeEventListener("abort", onAbort); if (signal?.aborted) { reject(signal.reason ?? new AbortError()); } else { resolve(null); } }).on("error", noop).on("data", function(chunk) { limit -= chunk.length; if (limit <= 0) { this.destroy(); } }).resume(); }); } }; function isLocked(self) { return self[kBody] && self[kBody].locked === true || self[kConsume]; } function isUnusable(self) { return util.isDisturbed(self) || isLocked(self); } async function consume(stream, type) { assert(!stream[kConsume]); return new Promise((resolve, reject) => { if (isUnusable(stream)) { const rState = stream._readableState; if (rState.destroyed && rState.closeEmitted === false) { stream.on("error", (err) => { reject(err); }).on("close", () => { reject(new TypeError("unusable")); }); } else { reject(rState.errored ?? new TypeError("unusable")); } } else { queueMicrotask(() => { stream[kConsume] = { type, stream, resolve, reject, length: 0, body: [] }; stream.on("error", function(err) { consumeFinish(this[kConsume], err); }).on("close", function() { if (this[kConsume].body !== null) { consumeFinish(this[kConsume], new RequestAbortedError()); } }); consumeStart(stream[kConsume]); }); } }); } function consumeStart(consume2) { if (consume2.body === null) { return; } const { _readableState: state } = consume2.stream; if (state.bufferIndex) { const start = state.bufferIndex; const end = state.buffer.length; for (let n = start; n < end; n++) { consumePush(consume2, state.buffer[n]); } } else { for (const chunk of state.buffer) { consumePush(consume2, chunk); } } if (state.endEmitted) { consumeEnd(this[kConsume]); } else { consume2.stream.on("end", function() { consumeEnd(this[kConsume]); }); } consume2.stream.resume(); while (consume2.stream.read() != null) { } } function chunksDecode(chunks, length2) { if (chunks.length === 0 || length2 === 0) { return ""; } const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, length2); const bufferLength = buffer.length; const start = bufferLength > 2 && buffer[0] === 239 && buffer[1] === 187 && buffer[2] === 191 ? 3 : 0; return buffer.utf8Slice(start, bufferLength); } function chunksConcat(chunks, length2) { if (chunks.length === 0 || length2 === 0) { return new Uint8Array(0); } if (chunks.length === 1) { return new Uint8Array(chunks[0]); } const buffer = new Uint8Array(Buffer.allocUnsafeSlow(length2).buffer); let offset = 0; for (let i = 0; i < chunks.length; ++i) { const chunk = chunks[i]; buffer.set(chunk, offset); offset += chunk.length; } return buffer; } function consumeEnd(consume2) { const { type, body, resolve, stream, length: length2 } = consume2; try { if (type === "text") { resolve(chunksDecode(body, length2)); } else if (type === "json") { resolve(JSON.parse(chunksDecode(body, length2))); } else if (type === "arrayBuffer") { resolve(chunksConcat(body, length2).buffer); } else if (type === "blob") { resolve(new Blob(body, { type: stream[kContentType] })); } else if (type === "bytes") { resolve(chunksConcat(body, length2)); } consumeFinish(consume2); } catch (err) { stream.destroy(err); } } function consumePush(consume2, chunk) { consume2.length += chunk.length; consume2.body.push(chunk); } function consumeFinish(consume2, err) { if (consume2.body === null) { return; } if (err) { consume2.reject(err); } else { consume2.resolve(); } consume2.type = null; consume2.stream = null; consume2.resolve = null; consume2.reject = null; consume2.length = 0; consume2.body = null; } module.exports = { Readable: BodyReadable, chunksDecode }; } }); // viewer/node_modules/undici/lib/api/util.js var require_util3 = __commonJS({ "viewer/node_modules/undici/lib/api/util.js"(exports, module) { var assert = __require("node:assert"); var { ResponseStatusCodeError } = require_errors(); var { chunksDecode } = require_readable(); var CHUNK_LIMIT = 128 * 1024; async function getResolveErrorBodyCallback({ callback, body, contentType, statusCode, statusMessage, headers }) { assert(body); let chunks = []; let length2 = 0; try { for await (const chunk of body) { chunks.push(chunk); length2 += chunk.length; if (length2 > CHUNK_LIMIT) { chunks = []; length2 = 0; break; } } } catch { chunks = []; length2 = 0; } const message = `Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ""}`; if (statusCode === 204 || !contentType || !length2) { queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers))); return; } const stackTraceLimit = Error.stackTraceLimit; Error.stackTraceLimit = 0; let payload; try { if (isContentTypeApplicationJson(contentType)) { payload = JSON.parse(chunksDecode(chunks, length2)); } else if (isContentTypeText(contentType)) { payload = chunksDecode(chunks, length2); } } catch { } finally { Error.stackTraceLimit = stackTraceLimit; } queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers, payload))); } var isContentTypeApplicationJson = (contentType) => { return contentType.length > 15 && contentType[11] === "/" && contentType[0] === "a" && contentType[1] === "p" && contentType[2] === "p" && contentType[3] === "l" && contentType[4] === "i" && contentType[5] === "c" && contentType[6] === "a" && contentType[7] === "t" && contentType[8] === "i" && contentType[9] === "o" && contentType[10] === "n" && contentType[12] === "j" && contentType[13] === "s" && contentType[14] === "o" && contentType[15] === "n"; }; var isContentTypeText = (contentType) => { return contentType.length > 4 && contentType[4] === "/" && contentType[0] === "t" && contentType[1] === "e" && contentType[2] === "x" && contentType[3] === "t"; }; module.exports = { getResolveErrorBodyCallback, isContentTypeApplicationJson, isContentTypeText }; } }); // viewer/node_modules/undici/lib/api/api-request.js var require_api_request = __commonJS({ "viewer/node_modules/undici/lib/api/api-request.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { Readable: Readable2 } = require_readable(); var { InvalidArgumentError, RequestAbortedError } = require_errors(); var util = require_util(); var { getResolveErrorBodyCallback } = require_util3(); var { AsyncResource } = __require("node:async_hooks"); var RequestHandler = class extends AsyncResource { constructor(opts, callback) { if (!opts || typeof opts !== "object") { throw new InvalidArgumentError("invalid opts"); } const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts; try { if (typeof callback !== "function") { throw new InvalidArgumentError("invalid callback"); } if (highWaterMark && (typeof highWaterMark !== "number" || highWaterMark < 0)) { throw new InvalidArgumentError("invalid highWaterMark"); } if (signal && typeof signal.on !== "function" && typeof signal.addEventListener !== "function") { throw new InvalidArgumentError("signal must be an EventEmitter or EventTarget"); } if (method === "CONNECT") { throw new InvalidArgumentError("invalid method"); } if (onInfo && typeof onInfo !== "function") { throw new InvalidArgumentError("invalid onInfo callback"); } super("UNDICI_REQUEST"); } catch (err) { if (util.isStream(body)) { util.destroy(body.on("error", util.nop), err); } throw err; } this.method = method; this.responseHeaders = responseHeaders || null; this.opaque = opaque || null; this.callback = callback; this.res = null; this.abort = null; this.body = body; this.trailers = {}; this.context = null; this.onInfo = onInfo || null; this.throwOnError = throwOnError; this.highWaterMark = highWaterMark; this.signal = signal; this.reason = null; this.removeAbortListener = null; if (util.isStream(body)) { body.on("error", (err) => { this.onError(err); }); } if (this.signal) { if (this.signal.aborted) { this.reason = this.signal.reason ?? new RequestAbortedError(); } else { this.removeAbortListener = util.addAbortListener(this.signal, () => { this.reason = this.signal.reason ?? new RequestAbortedError(); if (this.res) { util.destroy(this.res.on("error", util.nop), this.reason); } else if (this.abort) { this.abort(this.reason); } if (this.removeAbortListener) { this.res?.off("close", this.removeAbortListener); this.removeAbortListener(); this.removeAbortListener = null; } }); } } } onConnect(abort, context) { if (this.reason) { abort(this.reason); return; } assert(this.callback); this.abort = abort; this.context = context; } onHeaders(statusCode, rawHeaders, resume, statusMessage) { const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this; const headers = responseHeaders === "raw" ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); if (statusCode < 200) { if (this.onInfo) { this.onInfo({ statusCode, headers }); } return; } const parsedHeaders = responseHeaders === "raw" ? util.parseHeaders(rawHeaders) : headers; const contentType = parsedHeaders["content-type"]; const contentLength = parsedHeaders["content-length"]; const res = new Readable2({ resume, abort, contentType, contentLength: this.method !== "HEAD" && contentLength ? Number(contentLength) : null, highWaterMark }); if (this.removeAbortListener) { res.on("close", this.removeAbortListener); } this.callback = null; this.res = res; if (callback !== null) { if (this.throwOnError && statusCode >= 400) { this.runInAsyncScope( getResolveErrorBodyCallback, null, { callback, body: res, contentType, statusCode, statusMessage, headers } ); } else { this.runInAsyncScope(callback, null, null, { statusCode, headers, trailers: this.trailers, opaque, body: res, context }); } } } onData(chunk) { return this.res.push(chunk); } onComplete(trailers) { util.parseHeaders(trailers, this.trailers); this.res.push(null); } onError(err) { const { res, callback, body, opaque } = this; if (callback) { this.callback = null; queueMicrotask(() => { this.runInAsyncScope(callback, null, err, { opaque }); }); } if (res) { this.res = null; queueMicrotask(() => { util.destroy(res, err); }); } if (body) { this.body = null; util.destroy(body, err); } if (this.removeAbortListener) { res?.off("close", this.removeAbortListener); this.removeAbortListener(); this.removeAbortListener = null; } } }; function request(opts, callback) { if (callback === void 0) { return new Promise((resolve, reject) => { request.call(this, opts, (err, data) => { return err ? reject(err) : resolve(data); }); }); } try { this.dispatch(opts, new RequestHandler(opts, callback)); } catch (err) { if (typeof callback !== "function") { throw err; } const opaque = opts?.opaque; queueMicrotask(() => callback(err, { opaque })); } } module.exports = request; module.exports.RequestHandler = RequestHandler; } }); // viewer/node_modules/undici/lib/api/abort-signal.js var require_abort_signal = __commonJS({ "viewer/node_modules/undici/lib/api/abort-signal.js"(exports, module) { var { addAbortListener } = require_util(); var { RequestAbortedError } = require_errors(); var kListener = /* @__PURE__ */ Symbol("kListener"); var kSignal = /* @__PURE__ */ Symbol("kSignal"); function abort(self) { if (self.abort) { self.abort(self[kSignal]?.reason); } else { self.reason = self[kSignal]?.reason ?? new RequestAbortedError(); } removeSignal(self); } function addSignal(self, signal) { self.reason = null; self[kSignal] = null; self[kListener] = null; if (!signal) { return; } if (signal.aborted) { abort(self); return; } self[kSignal] = signal; self[kListener] = () => { abort(self); }; addAbortListener(self[kSignal], self[kListener]); } function removeSignal(self) { if (!self[kSignal]) { return; } if ("removeEventListener" in self[kSignal]) { self[kSignal].removeEventListener("abort", self[kListener]); } else { self[kSignal].removeListener("abort", self[kListener]); } self[kSignal] = null; self[kListener] = null; } module.exports = { addSignal, removeSignal }; } }); // viewer/node_modules/undici/lib/api/api-stream.js var require_api_stream = __commonJS({ "viewer/node_modules/undici/lib/api/api-stream.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { finished, PassThrough } = __require("node:stream"); var { InvalidArgumentError, InvalidReturnValueError } = require_errors(); var util = require_util(); var { getResolveErrorBodyCallback } = require_util3(); var { AsyncResource } = __require("node:async_hooks"); var { addSignal, removeSignal } = require_abort_signal(); var StreamHandler = class extends AsyncResource { constructor(opts, factory, callback) { if (!opts || typeof opts !== "object") { throw new InvalidArgumentError("invalid opts"); } const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts; try { if (typeof callback !== "function") { throw new InvalidArgumentError("invalid callback"); } if (typeof factory !== "function") { throw new InvalidArgumentError("invalid factory"); } if (signal && typeof signal.on !== "function" && typeof signal.addEventListener !== "function") { throw new InvalidArgumentError("signal must be an EventEmitter or EventTarget"); } if (method === "CONNECT") { throw new InvalidArgumentError("invalid method"); } if (onInfo && typeof onInfo !== "function") { throw new InvalidArgumentError("invalid onInfo callback"); } super("UNDICI_STREAM"); } catch (err) { if (util.isStream(body)) { util.destroy(body.on("error", util.nop), err); } throw err; } this.responseHeaders = responseHeaders || null; this.opaque = opaque || null; this.factory = factory; this.callback = callback; this.res = null; this.abort = null; this.context = null; this.trailers = null; this.body = body; this.onInfo = onInfo || null; this.throwOnError = throwOnError || false; if (util.isStream(body)) { body.on("error", (err) => { this.onError(err); }); } addSignal(this, signal); } onConnect(abort, context) { if (this.reason) { abort(this.reason); return; } assert(this.callback); this.abort = abort; this.context = context; } onHeaders(statusCode, rawHeaders, resume, statusMessage) { const { factory, opaque, context, callback, responseHeaders } = this; const headers = responseHeaders === "raw" ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); if (statusCode < 200) { if (this.onInfo) { this.onInfo({ statusCode, headers }); } return; } this.factory = null; let res; if (this.throwOnError && statusCode >= 400) { const parsedHeaders = responseHeaders === "raw" ? util.parseHeaders(rawHeaders) : headers; const contentType = parsedHeaders["content-type"]; res = new PassThrough(); this.callback = null; this.runInAsyncScope( getResolveErrorBodyCallback, null, { callback, body: res, contentType, statusCode, statusMessage, headers } ); } else { if (factory === null) { return; } res = this.runInAsyncScope(factory, null, { statusCode, headers, opaque, context }); if (!res || typeof res.write !== "function" || typeof res.end !== "function" || typeof res.on !== "function") { throw new InvalidReturnValueError("expected Writable"); } finished(res, { readable: false }, (err) => { const { callback: callback2, res: res2, opaque: opaque2, trailers, abort } = this; this.res = null; if (err || !res2.readable) { util.destroy(res2, err); } this.callback = null; this.runInAsyncScope(callback2, null, err || null, { opaque: opaque2, trailers }); if (err) { abort(); } }); } res.on("drain", resume); this.res = res; const needDrain = res.writableNeedDrain !== void 0 ? res.writableNeedDrain : res._writableState?.needDrain; return needDrain !== true; } onData(chunk) { const { res } = this; return res ? res.write(chunk) : true; } onComplete(trailers) { const { res } = this; removeSignal(this); if (!res) { return; } this.trailers = util.parseHeaders(trailers); res.end(); } onError(err) { const { res, callback, opaque, body } = this; removeSignal(this); this.factory = null; if (res) { this.res = null; util.destroy(res, err); } else if (callback) { this.callback = null; queueMicrotask(() => { this.runInAsyncScope(callback, null, err, { opaque }); }); } if (body) { this.body = null; util.destroy(body, err); } } }; function stream(opts, factory, callback) { if (callback === void 0) { return new Promise((resolve, reject) => { stream.call(this, opts, factory, (err, data) => { return err ? reject(err) : resolve(data); }); }); } try { this.dispatch(opts, new StreamHandler(opts, factory, callback)); } catch (err) { if (typeof callback !== "function") { throw err; } const opaque = opts?.opaque; queueMicrotask(() => callback(err, { opaque })); } } module.exports = stream; } }); // viewer/node_modules/undici/lib/api/api-pipeline.js var require_api_pipeline = __commonJS({ "viewer/node_modules/undici/lib/api/api-pipeline.js"(exports, module) { "use strict"; var { Readable: Readable2, Duplex, PassThrough } = __require("node:stream"); var { InvalidArgumentError, InvalidReturnValueError, RequestAbortedError } = require_errors(); var util = require_util(); var { AsyncResource } = __require("node:async_hooks"); var { addSignal, removeSignal } = require_abort_signal(); var assert = __require("node:assert"); var kResume = /* @__PURE__ */ Symbol("resume"); var PipelineRequest = class extends Readable2 { constructor() { super({ autoDestroy: true }); this[kResume] = null; } _read() { const { [kResume]: resume } = this; if (resume) { this[kResume] = null; resume(); } } _destroy(err, callback) { this._read(); callback(err); } }; var PipelineResponse = class extends Readable2 { constructor(resume) { super({ autoDestroy: true }); this[kResume] = resume; } _read() { this[kResume](); } _destroy(err, callback) { if (!err && !this._readableState.endEmitted) { err = new RequestAbortedError(); } callback(err); } }; var PipelineHandler = class extends AsyncResource { constructor(opts, handler) { if (!opts || typeof opts !== "object") { throw new InvalidArgumentError("invalid opts"); } if (typeof handler !== "function") { throw new InvalidArgumentError("invalid handler"); } const { signal, method, opaque, onInfo, responseHeaders } = opts; if (signal && typeof signal.on !== "function" && typeof signal.addEventListener !== "function") { throw new InvalidArgumentError("signal must be an EventEmitter or EventTarget"); } if (method === "CONNECT") { throw new InvalidArgumentError("invalid method"); } if (onInfo && typeof onInfo !== "function") { throw new InvalidArgumentError("invalid onInfo callback"); } super("UNDICI_PIPELINE"); this.opaque = opaque || null; this.responseHeaders = responseHeaders || null; this.handler = handler; this.abort = null; this.context = null; this.onInfo = onInfo || null; this.req = new PipelineRequest().on("error", util.nop); this.ret = new Duplex({ readableObjectMode: opts.objectMode, autoDestroy: true, read: () => { const { body } = this; if (body?.resume) { body.resume(); } }, write: (chunk, encoding, callback) => { const { req } = this; if (req.push(chunk, encoding) || req._readableState.destroyed) { callback(); } else { req[kResume] = callback; } }, destroy: (err, callback) => { const { body, req, res, ret, abort } = this; if (!err && !ret._readableState.endEmitted) { err = new RequestAbortedError(); } if (abort && err) { abort(); } util.destroy(body, err); util.destroy(req, err); util.destroy(res, err); removeSignal(this); callback(err); } }).on("prefinish", () => { const { req } = this; req.push(null); }); this.res = null; addSignal(this, signal); } onConnect(abort, context) { const { ret, res } = this; if (this.reason) { abort(this.reason); return; } assert(!res, "pipeline cannot be retried"); assert(!ret.destroyed); this.abort = abort; this.context = context; } onHeaders(statusCode, rawHeaders, resume) { const { opaque, handler, context } = this; if (statusCode < 200) { if (this.onInfo) { const headers = this.responseHeaders === "raw" ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); this.onInfo({ statusCode, headers }); } return; } this.res = new PipelineResponse(resume); let body; try { this.handler = null; const headers = this.responseHeaders === "raw" ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); body = this.runInAsyncScope(handler, null, { statusCode, headers, opaque, body: this.res, context }); } catch (err) { this.res.on("error", util.nop); throw err; } if (!body || typeof body.on !== "function") { throw new InvalidReturnValueError("expected Readable"); } body.on("data", (chunk) => { const { ret, body: body2 } = this; if (!ret.push(chunk) && body2.pause) { body2.pause(); } }).on("error", (err) => { const { ret } = this; util.destroy(ret, err); }).on("end", () => { const { ret } = this; ret.push(null); }).on("close", () => { const { ret } = this; if (!ret._readableState.ended) { util.destroy(ret, new RequestAbortedError()); } }); this.body = body; } onData(chunk) { const { res } = this; return res.push(chunk); } onComplete(trailers) { const { res } = this; res.push(null); } onError(err) { const { ret } = this; this.handler = null; util.destroy(ret, err); } }; function pipeline(opts, handler) { try { const pipelineHandler = new PipelineHandler(opts, handler); this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler); return pipelineHandler.ret; } catch (err) { return new PassThrough().destroy(err); } } module.exports = pipeline; } }); // viewer/node_modules/undici/lib/api/api-upgrade.js var require_api_upgrade = __commonJS({ "viewer/node_modules/undici/lib/api/api-upgrade.js"(exports, module) { "use strict"; var { InvalidArgumentError, SocketError } = require_errors(); var { AsyncResource } = __require("node:async_hooks"); var util = require_util(); var { addSignal, removeSignal } = require_abort_signal(); var assert = __require("node:assert"); var UpgradeHandler = class extends AsyncResource { constructor(opts, callback) { if (!opts || typeof opts !== "object") { throw new InvalidArgumentError("invalid opts"); } if (typeof callback !== "function") { throw new InvalidArgumentError("invalid callback"); } const { signal, opaque, responseHeaders } = opts; if (signal && typeof signal.on !== "function" && typeof signal.addEventListener !== "function") { throw new InvalidArgumentError("signal must be an EventEmitter or EventTarget"); } super("UNDICI_UPGRADE"); this.responseHeaders = responseHeaders || null; this.opaque = opaque || null; this.callback = callback; this.abort = null; this.context = null; addSignal(this, signal); } onConnect(abort, context) { if (this.reason) { abort(this.reason); return; } assert(this.callback); this.abort = abort; this.context = null; } onHeaders() { throw new SocketError("bad upgrade", null); } onUpgrade(statusCode, rawHeaders, socket) { assert(statusCode === 101); const { callback, opaque, context } = this; removeSignal(this); this.callback = null; const headers = this.responseHeaders === "raw" ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); this.runInAsyncScope(callback, null, null, { headers, socket, opaque, context }); } onError(err) { const { callback, opaque } = this; removeSignal(this); if (callback) { this.callback = null; queueMicrotask(() => { this.runInAsyncScope(callback, null, err, { opaque }); }); } } }; function upgrade(opts, callback) { if (callback === void 0) { return new Promise((resolve, reject) => { upgrade.call(this, opts, (err, data) => { return err ? reject(err) : resolve(data); }); }); } try { const upgradeHandler = new UpgradeHandler(opts, callback); this.dispatch({ ...opts, method: opts.method || "GET", upgrade: opts.protocol || "Websocket" }, upgradeHandler); } catch (err) { if (typeof callback !== "function") { throw err; } const opaque = opts?.opaque; queueMicrotask(() => callback(err, { opaque })); } } module.exports = upgrade; } }); // viewer/node_modules/undici/lib/api/api-connect.js var require_api_connect = __commonJS({ "viewer/node_modules/undici/lib/api/api-connect.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { AsyncResource } = __require("node:async_hooks"); var { InvalidArgumentError, SocketError } = require_errors(); var util = require_util(); var { addSignal, removeSignal } = require_abort_signal(); var ConnectHandler = class extends AsyncResource { constructor(opts, callback) { if (!opts || typeof opts !== "object") { throw new InvalidArgumentError("invalid opts"); } if (typeof callback !== "function") { throw new InvalidArgumentError("invalid callback"); } const { signal, opaque, responseHeaders } = opts; if (signal && typeof signal.on !== "function" && typeof signal.addEventListener !== "function") { throw new InvalidArgumentError("signal must be an EventEmitter or EventTarget"); } super("UNDICI_CONNECT"); this.opaque = opaque || null; this.responseHeaders = responseHeaders || null; this.callback = callback; this.abort = null; addSignal(this, signal); } onConnect(abort, context) { if (this.reason) { abort(this.reason); return; } assert(this.callback); this.abort = abort; this.context = context; } onHeaders() { throw new SocketError("bad connect", null); } onUpgrade(statusCode, rawHeaders, socket) { const { callback, opaque, context } = this; removeSignal(this); this.callback = null; let headers = rawHeaders; if (headers != null) { headers = this.responseHeaders === "raw" ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders); } this.runInAsyncScope(callback, null, null, { statusCode, headers, socket, opaque, context }); } onError(err) { const { callback, opaque } = this; removeSignal(this); if (callback) { this.callback = null; queueMicrotask(() => { this.runInAsyncScope(callback, null, err, { opaque }); }); } } }; function connect(opts, callback) { if (callback === void 0) { return new Promise((resolve, reject) => { connect.call(this, opts, (err, data) => { return err ? reject(err) : resolve(data); }); }); } try { const connectHandler = new ConnectHandler(opts, callback); this.dispatch({ ...opts, method: "CONNECT" }, connectHandler); } catch (err) { if (typeof callback !== "function") { throw err; } const opaque = opts?.opaque; queueMicrotask(() => callback(err, { opaque })); } } module.exports = connect; } }); // viewer/node_modules/undici/lib/api/index.js var require_api = __commonJS({ "viewer/node_modules/undici/lib/api/index.js"(exports, module) { "use strict"; module.exports.request = require_api_request(); module.exports.stream = require_api_stream(); module.exports.pipeline = require_api_pipeline(); module.exports.upgrade = require_api_upgrade(); module.exports.connect = require_api_connect(); } }); // viewer/node_modules/undici/lib/mock/mock-errors.js var require_mock_errors = __commonJS({ "viewer/node_modules/undici/lib/mock/mock-errors.js"(exports, module) { "use strict"; var { UndiciError } = require_errors(); var kMockNotMatchedError = /* @__PURE__ */ Symbol.for("undici.error.UND_MOCK_ERR_MOCK_NOT_MATCHED"); var MockNotMatchedError = class _MockNotMatchedError extends UndiciError { constructor(message) { super(message); Error.captureStackTrace(this, _MockNotMatchedError); this.name = "MockNotMatchedError"; this.message = message || "The request does not match any registered mock dispatches"; this.code = "UND_MOCK_ERR_MOCK_NOT_MATCHED"; } static [Symbol.hasInstance](instance) { return instance && instance[kMockNotMatchedError] === true; } [kMockNotMatchedError] = true; }; module.exports = { MockNotMatchedError }; } }); // viewer/node_modules/undici/lib/mock/mock-symbols.js var require_mock_symbols = __commonJS({ "viewer/node_modules/undici/lib/mock/mock-symbols.js"(exports, module) { "use strict"; module.exports = { kAgent: /* @__PURE__ */ Symbol("agent"), kOptions: /* @__PURE__ */ Symbol("options"), kFactory: /* @__PURE__ */ Symbol("factory"), kDispatches: /* @__PURE__ */ Symbol("dispatches"), kDispatchKey: /* @__PURE__ */ Symbol("dispatch key"), kDefaultHeaders: /* @__PURE__ */ Symbol("default headers"), kDefaultTrailers: /* @__PURE__ */ Symbol("default trailers"), kContentLength: /* @__PURE__ */ Symbol("content length"), kMockAgent: /* @__PURE__ */ Symbol("mock agent"), kMockAgentSet: /* @__PURE__ */ Symbol("mock agent set"), kMockAgentGet: /* @__PURE__ */ Symbol("mock agent get"), kMockDispatch: /* @__PURE__ */ Symbol("mock dispatch"), kClose: /* @__PURE__ */ Symbol("close"), kOriginalClose: /* @__PURE__ */ Symbol("original agent close"), kOrigin: /* @__PURE__ */ Symbol("origin"), kIsMockActive: /* @__PURE__ */ Symbol("is mock active"), kNetConnect: /* @__PURE__ */ Symbol("net connect"), kGetNetConnect: /* @__PURE__ */ Symbol("get net connect"), kConnected: /* @__PURE__ */ Symbol("connected") }; } }); // viewer/node_modules/undici/lib/mock/mock-utils.js var require_mock_utils = __commonJS({ "viewer/node_modules/undici/lib/mock/mock-utils.js"(exports, module) { "use strict"; var { MockNotMatchedError } = require_mock_errors(); var { kDispatches, kMockAgent, kOriginalDispatch, kOrigin, kGetNetConnect } = require_mock_symbols(); var { buildURL } = require_util(); var { STATUS_CODES } = __require("node:http"); var { types: { isPromise } } = __require("node:util"); function matchValue(match, value) { if (typeof match === "string") { return match === value; } if (match instanceof RegExp) { return match.test(value); } if (typeof match === "function") { return match(value) === true; } return false; } function lowerCaseEntries(headers) { return Object.fromEntries( Object.entries(headers).map(([headerName, headerValue]) => { return [headerName.toLocaleLowerCase(), headerValue]; }) ); } function getHeaderByName(headers, key) { if (Array.isArray(headers)) { for (let i = 0; i < headers.length; i += 2) { if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { return headers[i + 1]; } } return void 0; } else if (typeof headers.get === "function") { return headers.get(key); } else { return lowerCaseEntries(headers)[key.toLocaleLowerCase()]; } } function buildHeadersFromArray(headers) { const clone = headers.slice(); const entries = []; for (let index = 0; index < clone.length; index += 2) { entries.push([clone[index], clone[index + 1]]); } return Object.fromEntries(entries); } function matchHeaders(mockDispatch2, headers) { if (typeof mockDispatch2.headers === "function") { if (Array.isArray(headers)) { headers = buildHeadersFromArray(headers); } return mockDispatch2.headers(headers ? lowerCaseEntries(headers) : {}); } if (typeof mockDispatch2.headers === "undefined") { return true; } if (typeof headers !== "object" || typeof mockDispatch2.headers !== "object") { return false; } for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch2.headers)) { const headerValue = getHeaderByName(headers, matchHeaderName); if (!matchValue(matchHeaderValue, headerValue)) { return false; } } return true; } function safeUrl(path14) { if (typeof path14 !== "string") { return path14; } const pathSegments = path14.split("?"); if (pathSegments.length !== 2) { return path14; } const qp = new URLSearchParams(pathSegments.pop()); qp.sort(); return [...pathSegments, qp.toString()].join("?"); } function matchKey(mockDispatch2, { path: path14, method, body, headers }) { const pathMatch = matchValue(mockDispatch2.path, path14); const methodMatch = matchValue(mockDispatch2.method, method); const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true; const headersMatch = matchHeaders(mockDispatch2, headers); return pathMatch && methodMatch && bodyMatch && headersMatch; } function getResponseData(data) { if (Buffer.isBuffer(data)) { return data; } else if (data instanceof Uint8Array) { return data; } else if (data instanceof ArrayBuffer) { return data; } else if (typeof data === "object") { return JSON.stringify(data); } else { return data.toString(); } } function getMockDispatch(mockDispatches, key) { const basePath = key.query ? buildURL(key.path, key.query) : key.path; const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath; let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path14 }) => matchValue(safeUrl(path14), resolvedPath)); if (matchedMockDispatches.length === 0) { throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`); } matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)); if (matchedMockDispatches.length === 0) { throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}' on path '${resolvedPath}'`); } matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== "undefined" ? matchValue(body, key.body) : true); if (matchedMockDispatches.length === 0) { throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}' on path '${resolvedPath}'`); } matchedMockDispatches = matchedMockDispatches.filter((mockDispatch2) => matchHeaders(mockDispatch2, key.headers)); if (matchedMockDispatches.length === 0) { const headers = typeof key.headers === "object" ? JSON.stringify(key.headers) : key.headers; throw new MockNotMatchedError(`Mock dispatch not matched for headers '${headers}' on path '${resolvedPath}'`); } return matchedMockDispatches[0]; } function addMockDispatch(mockDispatches, key, data) { const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false }; const replyData = typeof data === "function" ? { callback: data } : { ...data }; const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } }; mockDispatches.push(newMockDispatch); return newMockDispatch; } function deleteMockDispatch(mockDispatches, key) { const index = mockDispatches.findIndex((dispatch) => { if (!dispatch.consumed) { return false; } return matchKey(dispatch, key); }); if (index !== -1) { mockDispatches.splice(index, 1); } } function buildKey(opts) { const { path: path14, method, body, headers, query } = opts; return { path: path14, method, body, headers, query }; } function generateKeyValues(data) { const keys = Object.keys(data); const result = []; for (let i = 0; i < keys.length; ++i) { const key = keys[i]; const value = data[key]; const name = Buffer.from(`${key}`); if (Array.isArray(value)) { for (let j = 0; j < value.length; ++j) { result.push(name, Buffer.from(`${value[j]}`)); } } else { result.push(name, Buffer.from(`${value}`)); } } return result; } function getStatusText(statusCode) { return STATUS_CODES[statusCode] || "unknown"; } async function getResponse(body) { const buffers = []; for await (const data of body) { buffers.push(data); } return Buffer.concat(buffers).toString("utf8"); } function mockDispatch(opts, handler) { const key = buildKey(opts); const mockDispatch2 = getMockDispatch(this[kDispatches], key); mockDispatch2.timesInvoked++; if (mockDispatch2.data.callback) { mockDispatch2.data = { ...mockDispatch2.data, ...mockDispatch2.data.callback(opts) }; } const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch2; const { timesInvoked, times } = mockDispatch2; mockDispatch2.consumed = !persist && timesInvoked >= times; mockDispatch2.pending = timesInvoked < times; if (error !== null) { deleteMockDispatch(this[kDispatches], key); handler.onError(error); return true; } if (typeof delay === "number" && delay > 0) { setTimeout(() => { handleReply(this[kDispatches]); }, delay); } else { handleReply(this[kDispatches]); } function handleReply(mockDispatches, _data = data) { const optsHeaders = Array.isArray(opts.headers) ? buildHeadersFromArray(opts.headers) : opts.headers; const body = typeof _data === "function" ? _data({ ...opts, headers: optsHeaders }) : _data; if (isPromise(body)) { body.then((newData) => handleReply(mockDispatches, newData)); return; } const responseData = getResponseData(body); const responseHeaders = generateKeyValues(headers); const responseTrailers = generateKeyValues(trailers); handler.onConnect?.((err) => handler.onError(err), null); handler.onHeaders?.(statusCode, responseHeaders, resume, getStatusText(statusCode)); handler.onData?.(Buffer.from(responseData)); handler.onComplete?.(responseTrailers); deleteMockDispatch(mockDispatches, key); } function resume() { } return true; } function buildMockDispatch() { const agent = this[kMockAgent]; const origin = this[kOrigin]; const originalDispatch = this[kOriginalDispatch]; return function dispatch(opts, handler) { if (agent.isMockActive) { try { mockDispatch.call(this, opts, handler); } catch (error) { if (error instanceof MockNotMatchedError) { const netConnect = agent[kGetNetConnect](); if (netConnect === false) { throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`); } if (checkNetConnect(netConnect, origin)) { originalDispatch.call(this, opts, handler); } else { throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`); } } else { throw error; } } } else { originalDispatch.call(this, opts, handler); } }; } function checkNetConnect(netConnect, origin) { const url = new URL(origin); if (netConnect === true) { return true; } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { return true; } return false; } function buildMockOptions(opts) { if (opts) { const { agent, ...mockOptions } = opts; return mockOptions; } } module.exports = { getResponseData, getMockDispatch, addMockDispatch, deleteMockDispatch, buildKey, generateKeyValues, matchValue, getResponse, getStatusText, mockDispatch, buildMockDispatch, checkNetConnect, buildMockOptions, getHeaderByName, buildHeadersFromArray }; } }); // viewer/node_modules/undici/lib/mock/mock-interceptor.js var require_mock_interceptor = __commonJS({ "viewer/node_modules/undici/lib/mock/mock-interceptor.js"(exports, module) { "use strict"; var { getResponseData, buildKey, addMockDispatch } = require_mock_utils(); var { kDispatches, kDispatchKey, kDefaultHeaders, kDefaultTrailers, kContentLength, kMockDispatch } = require_mock_symbols(); var { InvalidArgumentError } = require_errors(); var { buildURL } = require_util(); var MockScope = class { constructor(mockDispatch) { this[kMockDispatch] = mockDispatch; } /** * Delay a reply by a set amount in ms. */ delay(waitInMs) { if (typeof waitInMs !== "number" || !Number.isInteger(waitInMs) || waitInMs <= 0) { throw new InvalidArgumentError("waitInMs must be a valid integer > 0"); } this[kMockDispatch].delay = waitInMs; return this; } /** * For a defined reply, never mark as consumed. */ persist() { this[kMockDispatch].persist = true; return this; } /** * Allow one to define a reply for a set amount of matching requests. */ times(repeatTimes) { if (typeof repeatTimes !== "number" || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { throw new InvalidArgumentError("repeatTimes must be a valid integer > 0"); } this[kMockDispatch].times = repeatTimes; return this; } }; var MockInterceptor = class { constructor(opts, mockDispatches) { if (typeof opts !== "object") { throw new InvalidArgumentError("opts must be an object"); } if (typeof opts.path === "undefined") { throw new InvalidArgumentError("opts.path must be defined"); } if (typeof opts.method === "undefined") { opts.method = "GET"; } if (typeof opts.path === "string") { if (opts.query) { opts.path = buildURL(opts.path, opts.query); } else { const parsedURL = new URL(opts.path, "data://"); opts.path = parsedURL.pathname + parsedURL.search; } } if (typeof opts.method === "string") { opts.method = opts.method.toUpperCase(); } this[kDispatchKey] = buildKey(opts); this[kDispatches] = mockDispatches; this[kDefaultHeaders] = {}; this[kDefaultTrailers] = {}; this[kContentLength] = false; } createMockScopeDispatchData({ statusCode, data, responseOptions }) { const responseData = getResponseData(data); const contentLength = this[kContentLength] ? { "content-length": responseData.length } : {}; const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers }; const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers }; return { statusCode, data, headers, trailers }; } validateReplyParameters(replyParameters) { if (typeof replyParameters.statusCode === "undefined") { throw new InvalidArgumentError("statusCode must be defined"); } if (typeof replyParameters.responseOptions !== "object" || replyParameters.responseOptions === null) { throw new InvalidArgumentError("responseOptions must be an object"); } } /** * Mock an undici request with a defined reply. */ reply(replyOptionsCallbackOrStatusCode) { if (typeof replyOptionsCallbackOrStatusCode === "function") { const wrappedDefaultsCallback = (opts) => { const resolvedData = replyOptionsCallbackOrStatusCode(opts); if (typeof resolvedData !== "object" || resolvedData === null) { throw new InvalidArgumentError("reply options callback must return an object"); } const replyParameters2 = { data: "", responseOptions: {}, ...resolvedData }; this.validateReplyParameters(replyParameters2); return { ...this.createMockScopeDispatchData(replyParameters2) }; }; const newMockDispatch2 = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback); return new MockScope(newMockDispatch2); } const replyParameters = { statusCode: replyOptionsCallbackOrStatusCode, data: arguments[1] === void 0 ? "" : arguments[1], responseOptions: arguments[2] === void 0 ? {} : arguments[2] }; this.validateReplyParameters(replyParameters); const dispatchData = this.createMockScopeDispatchData(replyParameters); const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData); return new MockScope(newMockDispatch); } /** * Mock an undici request with a defined error. */ replyWithError(error) { if (typeof error === "undefined") { throw new InvalidArgumentError("error must be defined"); } const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }); return new MockScope(newMockDispatch); } /** * Set default reply headers on the interceptor for subsequent replies */ defaultReplyHeaders(headers) { if (typeof headers === "undefined") { throw new InvalidArgumentError("headers must be defined"); } this[kDefaultHeaders] = headers; return this; } /** * Set default reply trailers on the interceptor for subsequent replies */ defaultReplyTrailers(trailers) { if (typeof trailers === "undefined") { throw new InvalidArgumentError("trailers must be defined"); } this[kDefaultTrailers] = trailers; return this; } /** * Set reply content length header for replies on the interceptor */ replyContentLength() { this[kContentLength] = true; return this; } }; module.exports.MockInterceptor = MockInterceptor; module.exports.MockScope = MockScope; } }); // viewer/node_modules/undici/lib/mock/mock-client.js var require_mock_client = __commonJS({ "viewer/node_modules/undici/lib/mock/mock-client.js"(exports, module) { "use strict"; var { promisify } = __require("node:util"); var Client = require_client(); var { buildMockDispatch } = require_mock_utils(); var { kDispatches, kMockAgent, kClose, kOriginalClose, kOrigin, kOriginalDispatch, kConnected } = require_mock_symbols(); var { MockInterceptor } = require_mock_interceptor(); var Symbols = require_symbols(); var { InvalidArgumentError } = require_errors(); var MockClient = class extends Client { constructor(origin, opts) { super(origin, opts); if (!opts || !opts.agent || typeof opts.agent.dispatch !== "function") { throw new InvalidArgumentError("Argument opts.agent must implement Agent"); } this[kMockAgent] = opts.agent; this[kOrigin] = origin; this[kDispatches] = []; this[kConnected] = 1; this[kOriginalDispatch] = this.dispatch; this[kOriginalClose] = this.close.bind(this); this.dispatch = buildMockDispatch.call(this); this.close = this[kClose]; } get [Symbols.kConnected]() { return this[kConnected]; } /** * Sets up the base interceptor for mocking replies from undici. */ intercept(opts) { return new MockInterceptor(opts, this[kDispatches]); } async [kClose]() { await promisify(this[kOriginalClose])(); this[kConnected] = 0; this[kMockAgent][Symbols.kClients].delete(this[kOrigin]); } }; module.exports = MockClient; } }); // viewer/node_modules/undici/lib/mock/mock-pool.js var require_mock_pool = __commonJS({ "viewer/node_modules/undici/lib/mock/mock-pool.js"(exports, module) { "use strict"; var { promisify } = __require("node:util"); var Pool = require_pool(); var { buildMockDispatch } = require_mock_utils(); var { kDispatches, kMockAgent, kClose, kOriginalClose, kOrigin, kOriginalDispatch, kConnected } = require_mock_symbols(); var { MockInterceptor } = require_mock_interceptor(); var Symbols = require_symbols(); var { InvalidArgumentError } = require_errors(); var MockPool = class extends Pool { constructor(origin, opts) { super(origin, opts); if (!opts || !opts.agent || typeof opts.agent.dispatch !== "function") { throw new InvalidArgumentError("Argument opts.agent must implement Agent"); } this[kMockAgent] = opts.agent; this[kOrigin] = origin; this[kDispatches] = []; this[kConnected] = 1; this[kOriginalDispatch] = this.dispatch; this[kOriginalClose] = this.close.bind(this); this.dispatch = buildMockDispatch.call(this); this.close = this[kClose]; } get [Symbols.kConnected]() { return this[kConnected]; } /** * Sets up the base interceptor for mocking replies from undici. */ intercept(opts) { return new MockInterceptor(opts, this[kDispatches]); } async [kClose]() { await promisify(this[kOriginalClose])(); this[kConnected] = 0; this[kMockAgent][Symbols.kClients].delete(this[kOrigin]); } }; module.exports = MockPool; } }); // viewer/node_modules/undici/lib/mock/pluralizer.js var require_pluralizer = __commonJS({ "viewer/node_modules/undici/lib/mock/pluralizer.js"(exports, module) { "use strict"; var singulars = { pronoun: "it", is: "is", was: "was", this: "this" }; var plurals = { pronoun: "they", is: "are", was: "were", this: "these" }; module.exports = class Pluralizer { constructor(singular, plural) { this.singular = singular; this.plural = plural; } pluralize(count) { const one = count === 1; const keys = one ? singulars : plurals; const noun = one ? this.singular : this.plural; return { ...keys, count, noun }; } }; } }); // viewer/node_modules/undici/lib/mock/pending-interceptors-formatter.js var require_pending_interceptors_formatter = __commonJS({ "viewer/node_modules/undici/lib/mock/pending-interceptors-formatter.js"(exports, module) { "use strict"; var { Transform } = __require("node:stream"); var { Console } = __require("node:console"); var PERSISTENT = process.versions.icu ? "\u2705" : "Y "; var NOT_PERSISTENT = process.versions.icu ? "\u274C" : "N "; module.exports = class PendingInterceptorsFormatter { constructor({ disableColors } = {}) { this.transform = new Transform({ transform(chunk, _enc, cb) { cb(null, chunk); } }); this.logger = new Console({ stdout: this.transform, inspectOptions: { colors: !disableColors && !process.env.CI } }); } format(pendingInterceptors) { const withPrettyHeaders = pendingInterceptors.map( ({ method, path: path14, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ Method: method, Origin: origin, Path: path14, "Status code": statusCode, Persistent: persist ? PERSISTENT : NOT_PERSISTENT, Invocations: timesInvoked, Remaining: persist ? Infinity : times - timesInvoked }) ); this.logger.table(withPrettyHeaders); return this.transform.read().toString(); } }; } }); // viewer/node_modules/undici/lib/mock/mock-agent.js var require_mock_agent = __commonJS({ "viewer/node_modules/undici/lib/mock/mock-agent.js"(exports, module) { "use strict"; var { kClients } = require_symbols(); var Agent = require_agent(); var { kAgent, kMockAgentSet, kMockAgentGet, kDispatches, kIsMockActive, kNetConnect, kGetNetConnect, kOptions, kFactory } = require_mock_symbols(); var MockClient = require_mock_client(); var MockPool = require_mock_pool(); var { matchValue, buildMockOptions } = require_mock_utils(); var { InvalidArgumentError, UndiciError } = require_errors(); var Dispatcher = require_dispatcher(); var Pluralizer = require_pluralizer(); var PendingInterceptorsFormatter = require_pending_interceptors_formatter(); var MockAgent = class extends Dispatcher { constructor(opts) { super(opts); this[kNetConnect] = true; this[kIsMockActive] = true; if (opts?.agent && typeof opts.agent.dispatch !== "function") { throw new InvalidArgumentError("Argument opts.agent must implement Agent"); } const agent = opts?.agent ? opts.agent : new Agent(opts); this[kAgent] = agent; this[kClients] = agent[kClients]; this[kOptions] = buildMockOptions(opts); } get(origin) { let dispatcher = this[kMockAgentGet](origin); if (!dispatcher) { dispatcher = this[kFactory](origin); this[kMockAgentSet](origin, dispatcher); } return dispatcher; } dispatch(opts, handler) { this.get(opts.origin); return this[kAgent].dispatch(opts, handler); } async close() { await this[kAgent].close(); this[kClients].clear(); } deactivate() { this[kIsMockActive] = false; } activate() { this[kIsMockActive] = true; } enableNetConnect(matcher) { if (typeof matcher === "string" || typeof matcher === "function" || matcher instanceof RegExp) { if (Array.isArray(this[kNetConnect])) { this[kNetConnect].push(matcher); } else { this[kNetConnect] = [matcher]; } } else if (typeof matcher === "undefined") { this[kNetConnect] = true; } else { throw new InvalidArgumentError("Unsupported matcher. Must be one of String|Function|RegExp."); } } disableNetConnect() { this[kNetConnect] = false; } // This is required to bypass issues caused by using global symbols - see: // https://github.com/nodejs/undici/issues/1447 get isMockActive() { return this[kIsMockActive]; } [kMockAgentSet](origin, dispatcher) { this[kClients].set(origin, dispatcher); } [kFactory](origin) { const mockOptions = Object.assign({ agent: this }, this[kOptions]); return this[kOptions] && this[kOptions].connections === 1 ? new MockClient(origin, mockOptions) : new MockPool(origin, mockOptions); } [kMockAgentGet](origin) { const client = this[kClients].get(origin); if (client) { return client; } if (typeof origin !== "string") { const dispatcher = this[kFactory]("http://localhost:9999"); this[kMockAgentSet](origin, dispatcher); return dispatcher; } for (const [keyMatcher, nonExplicitDispatcher] of Array.from(this[kClients])) { if (nonExplicitDispatcher && typeof keyMatcher !== "string" && matchValue(keyMatcher, origin)) { const dispatcher = this[kFactory](origin); this[kMockAgentSet](origin, dispatcher); dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches]; return dispatcher; } } } [kGetNetConnect]() { return this[kNetConnect]; } pendingInterceptors() { const mockAgentClients = this[kClients]; return Array.from(mockAgentClients.entries()).flatMap(([origin, scope]) => scope[kDispatches].map((dispatch) => ({ ...dispatch, origin }))).filter(({ pending }) => pending); } assertNoPendingInterceptors({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { const pending = this.pendingInterceptors(); if (pending.length === 0) { return; } const pluralizer = new Pluralizer("interceptor", "interceptors").pluralize(pending.length); throw new UndiciError(` ${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: ${pendingInterceptorsFormatter.format(pending)} `.trim()); } }; module.exports = MockAgent; } }); // viewer/node_modules/undici/lib/global.js var require_global2 = __commonJS({ "viewer/node_modules/undici/lib/global.js"(exports, module) { "use strict"; var globalDispatcher = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.1"); var { InvalidArgumentError } = require_errors(); var Agent = require_agent(); if (getGlobalDispatcher() === void 0) { setGlobalDispatcher(new Agent()); } function setGlobalDispatcher(agent) { if (!agent || typeof agent.dispatch !== "function") { throw new InvalidArgumentError("Argument agent must implement Agent"); } Object.defineProperty(globalThis, globalDispatcher, { value: agent, writable: true, enumerable: false, configurable: false }); } function getGlobalDispatcher() { return globalThis[globalDispatcher]; } module.exports = { setGlobalDispatcher, getGlobalDispatcher }; } }); // viewer/node_modules/undici/lib/handler/decorator-handler.js var require_decorator_handler = __commonJS({ "viewer/node_modules/undici/lib/handler/decorator-handler.js"(exports, module) { "use strict"; module.exports = class DecoratorHandler { #handler; constructor(handler) { if (typeof handler !== "object" || handler === null) { throw new TypeError("handler must be an object"); } this.#handler = handler; } onConnect(...args) { return this.#handler.onConnect?.(...args); } onError(...args) { return this.#handler.onError?.(...args); } onUpgrade(...args) { return this.#handler.onUpgrade?.(...args); } onResponseStarted(...args) { return this.#handler.onResponseStarted?.(...args); } onHeaders(...args) { return this.#handler.onHeaders?.(...args); } onData(...args) { return this.#handler.onData?.(...args); } onComplete(...args) { return this.#handler.onComplete?.(...args); } onBodySent(...args) { return this.#handler.onBodySent?.(...args); } }; } }); // viewer/node_modules/undici/lib/interceptor/redirect.js var require_redirect = __commonJS({ "viewer/node_modules/undici/lib/interceptor/redirect.js"(exports, module) { "use strict"; var RedirectHandler = require_redirect_handler(); module.exports = (opts) => { const globalMaxRedirections = opts?.maxRedirections; return (dispatch) => { return function redirectInterceptor(opts2, handler) { const { maxRedirections = globalMaxRedirections, ...baseOpts } = opts2; if (!maxRedirections) { return dispatch(opts2, handler); } const redirectHandler = new RedirectHandler( dispatch, maxRedirections, opts2, handler ); return dispatch(baseOpts, redirectHandler); }; }; }; } }); // viewer/node_modules/undici/lib/interceptor/retry.js var require_retry3 = __commonJS({ "viewer/node_modules/undici/lib/interceptor/retry.js"(exports, module) { "use strict"; var RetryHandler = require_retry_handler(); module.exports = (globalOpts) => { return (dispatch) => { return function retryInterceptor(opts, handler) { return dispatch( opts, new RetryHandler( { ...opts, retryOptions: { ...globalOpts, ...opts.retryOptions } }, { handler, dispatch } ) ); }; }; }; } }); // viewer/node_modules/undici/lib/interceptor/dump.js var require_dump = __commonJS({ "viewer/node_modules/undici/lib/interceptor/dump.js"(exports, module) { "use strict"; var util = require_util(); var { InvalidArgumentError, RequestAbortedError } = require_errors(); var DecoratorHandler = require_decorator_handler(); var DumpHandler = class extends DecoratorHandler { #maxSize = 1024 * 1024; #abort = null; #dumped = false; #aborted = false; #size = 0; #reason = null; #handler = null; constructor({ maxSize }, handler) { super(handler); if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) { throw new InvalidArgumentError("maxSize must be a number greater than 0"); } this.#maxSize = maxSize ?? this.#maxSize; this.#handler = handler; } onConnect(abort) { this.#abort = abort; this.#handler.onConnect(this.#customAbort.bind(this)); } #customAbort(reason) { this.#aborted = true; this.#reason = reason; } // TODO: will require adjustment after new hooks are out onHeaders(statusCode, rawHeaders, resume, statusMessage) { const headers = util.parseHeaders(rawHeaders); const contentLength = headers["content-length"]; if (contentLength != null && contentLength > this.#maxSize) { throw new RequestAbortedError( `Response size (${contentLength}) larger than maxSize (${this.#maxSize})` ); } if (this.#aborted) { return true; } return this.#handler.onHeaders( statusCode, rawHeaders, resume, statusMessage ); } onError(err) { if (this.#dumped) { return; } err = this.#reason ?? err; this.#handler.onError(err); } onData(chunk) { this.#size = this.#size + chunk.length; if (this.#size >= this.#maxSize) { this.#dumped = true; if (this.#aborted) { this.#handler.onError(this.#reason); } else { this.#handler.onComplete([]); } } return true; } onComplete(trailers) { if (this.#dumped) { return; } if (this.#aborted) { this.#handler.onError(this.reason); return; } this.#handler.onComplete(trailers); } }; function createDumpInterceptor({ maxSize: defaultMaxSize } = { maxSize: 1024 * 1024 }) { return (dispatch) => { return function Intercept(opts, handler) { const { dumpMaxSize = defaultMaxSize } = opts; const dumpHandler = new DumpHandler( { maxSize: dumpMaxSize }, handler ); return dispatch(opts, dumpHandler); }; }; } module.exports = createDumpInterceptor; } }); // viewer/node_modules/undici/lib/interceptor/dns.js var require_dns = __commonJS({ "viewer/node_modules/undici/lib/interceptor/dns.js"(exports, module) { "use strict"; var { isIP } = __require("node:net"); var { lookup } = __require("node:dns"); var DecoratorHandler = require_decorator_handler(); var { InvalidArgumentError, InformationalError } = require_errors(); var maxInt = Math.pow(2, 31) - 1; var DNSInstance = class { #maxTTL = 0; #maxItems = 0; #records = /* @__PURE__ */ new Map(); dualStack = true; affinity = null; lookup = null; pick = null; constructor(opts) { this.#maxTTL = opts.maxTTL; this.#maxItems = opts.maxItems; this.dualStack = opts.dualStack; this.affinity = opts.affinity; this.lookup = opts.lookup ?? this.#defaultLookup; this.pick = opts.pick ?? this.#defaultPick; } get full() { return this.#records.size === this.#maxItems; } runLookup(origin, opts, cb) { const ips = this.#records.get(origin.hostname); if (ips == null && this.full) { cb(null, origin.origin); return; } const newOpts = { affinity: this.affinity, dualStack: this.dualStack, lookup: this.lookup, pick: this.pick, ...opts.dns, maxTTL: this.#maxTTL, maxItems: this.#maxItems }; if (ips == null) { this.lookup(origin, newOpts, (err, addresses) => { if (err || addresses == null || addresses.length === 0) { cb(err ?? new InformationalError("No DNS entries found")); return; } this.setRecords(origin, addresses); const records = this.#records.get(origin.hostname); const ip = this.pick( origin, records, newOpts.affinity ); let port2; if (typeof ip.port === "number") { port2 = `:${ip.port}`; } else if (origin.port !== "") { port2 = `:${origin.port}`; } else { port2 = ""; } cb( null, `${origin.protocol}//${ip.family === 6 ? `[${ip.address}]` : ip.address}${port2}` ); }); } else { const ip = this.pick( origin, ips, newOpts.affinity ); if (ip == null) { this.#records.delete(origin.hostname); this.runLookup(origin, opts, cb); return; } let port2; if (typeof ip.port === "number") { port2 = `:${ip.port}`; } else if (origin.port !== "") { port2 = `:${origin.port}`; } else { port2 = ""; } cb( null, `${origin.protocol}//${ip.family === 6 ? `[${ip.address}]` : ip.address}${port2}` ); } } #defaultLookup(origin, opts, cb) { lookup( origin.hostname, { all: true, family: this.dualStack === false ? this.affinity : 0, order: "ipv4first" }, (err, addresses) => { if (err) { return cb(err); } const results = /* @__PURE__ */ new Map(); for (const addr of addresses) { results.set(`${addr.address}:${addr.family}`, addr); } cb(null, results.values()); } ); } #defaultPick(origin, hostnameRecords, affinity) { let ip = null; const { records, offset } = hostnameRecords; let family; if (this.dualStack) { if (affinity == null) { if (offset == null || offset === maxInt) { hostnameRecords.offset = 0; affinity = 4; } else { hostnameRecords.offset++; affinity = (hostnameRecords.offset & 1) === 1 ? 6 : 4; } } if (records[affinity] != null && records[affinity].ips.length > 0) { family = records[affinity]; } else { family = records[affinity === 4 ? 6 : 4]; } } else { family = records[affinity]; } if (family == null || family.ips.length === 0) { return ip; } if (family.offset == null || family.offset === maxInt) { family.offset = 0; } else { family.offset++; } const position = family.offset % family.ips.length; ip = family.ips[position] ?? null; if (ip == null) { return ip; } if (Date.now() - ip.timestamp > ip.ttl) { family.ips.splice(position, 1); return this.pick(origin, hostnameRecords, affinity); } return ip; } setRecords(origin, addresses) { const timestamp = Date.now(); const records = { records: { 4: null, 6: null } }; for (const record of addresses) { record.timestamp = timestamp; if (typeof record.ttl === "number") { record.ttl = Math.min(record.ttl, this.#maxTTL); } else { record.ttl = this.#maxTTL; } const familyRecords = records.records[record.family] ?? { ips: [] }; familyRecords.ips.push(record); records.records[record.family] = familyRecords; } this.#records.set(origin.hostname, records); } getHandler(meta, opts) { return new DNSDispatchHandler(this, meta, opts); } }; var DNSDispatchHandler = class extends DecoratorHandler { #state = null; #opts = null; #dispatch = null; #handler = null; #origin = null; constructor(state, { origin, handler, dispatch }, opts) { super(handler); this.#origin = origin; this.#handler = handler; this.#opts = { ...opts }; this.#state = state; this.#dispatch = dispatch; } onError(err) { switch (err.code) { case "ETIMEDOUT": case "ECONNREFUSED": { if (this.#state.dualStack) { this.#state.runLookup(this.#origin, this.#opts, (err2, newOrigin) => { if (err2) { return this.#handler.onError(err2); } const dispatchOpts = { ...this.#opts, origin: newOrigin }; this.#dispatch(dispatchOpts, this); }); return; } this.#handler.onError(err); return; } case "ENOTFOUND": this.#state.deleteRecord(this.#origin); // eslint-disable-next-line no-fallthrough default: this.#handler.onError(err); break; } } }; module.exports = (interceptorOpts) => { if (interceptorOpts?.maxTTL != null && (typeof interceptorOpts?.maxTTL !== "number" || interceptorOpts?.maxTTL < 0)) { throw new InvalidArgumentError("Invalid maxTTL. Must be a positive number"); } if (interceptorOpts?.maxItems != null && (typeof interceptorOpts?.maxItems !== "number" || interceptorOpts?.maxItems < 1)) { throw new InvalidArgumentError( "Invalid maxItems. Must be a positive number and greater than zero" ); } if (interceptorOpts?.affinity != null && interceptorOpts?.affinity !== 4 && interceptorOpts?.affinity !== 6) { throw new InvalidArgumentError("Invalid affinity. Must be either 4 or 6"); } if (interceptorOpts?.dualStack != null && typeof interceptorOpts?.dualStack !== "boolean") { throw new InvalidArgumentError("Invalid dualStack. Must be a boolean"); } if (interceptorOpts?.lookup != null && typeof interceptorOpts?.lookup !== "function") { throw new InvalidArgumentError("Invalid lookup. Must be a function"); } if (interceptorOpts?.pick != null && typeof interceptorOpts?.pick !== "function") { throw new InvalidArgumentError("Invalid pick. Must be a function"); } const dualStack = interceptorOpts?.dualStack ?? true; let affinity; if (dualStack) { affinity = interceptorOpts?.affinity ?? null; } else { affinity = interceptorOpts?.affinity ?? 4; } const opts = { maxTTL: interceptorOpts?.maxTTL ?? 1e4, // Expressed in ms lookup: interceptorOpts?.lookup ?? null, pick: interceptorOpts?.pick ?? null, dualStack, affinity, maxItems: interceptorOpts?.maxItems ?? Infinity }; const instance = new DNSInstance(opts); return (dispatch) => { return function dnsInterceptor(origDispatchOpts, handler) { const origin = origDispatchOpts.origin.constructor === URL ? origDispatchOpts.origin : new URL(origDispatchOpts.origin); if (isIP(origin.hostname) !== 0) { return dispatch(origDispatchOpts, handler); } instance.runLookup(origin, origDispatchOpts, (err, newOrigin) => { if (err) { return handler.onError(err); } let dispatchOpts = null; dispatchOpts = { ...origDispatchOpts, servername: origin.hostname, // For SNI on TLS origin: newOrigin, headers: { host: origin.hostname, ...origDispatchOpts.headers } }; dispatch( dispatchOpts, instance.getHandler({ origin, dispatch, handler }, origDispatchOpts) ); }); return true; }; }; }; } }); // viewer/node_modules/undici/lib/web/fetch/headers.js var require_headers = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/headers.js"(exports, module) { "use strict"; var { kConstruct } = require_symbols(); var { kEnumerableProperty } = require_util(); var { iteratorMixin, isValidHeaderName, isValidHeaderValue } = require_util2(); var { webidl } = require_webidl(); var assert = __require("node:assert"); var util = __require("node:util"); var kHeadersMap = /* @__PURE__ */ Symbol("headers map"); var kHeadersSortedMap = /* @__PURE__ */ Symbol("headers map sorted"); function isHTTPWhiteSpaceCharCode(code) { return code === 10 || code === 13 || code === 9 || code === 32; } function headerValueNormalize(potentialValue) { let i = 0; let j = potentialValue.length; while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j; while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i; return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j); } function fill(headers, object) { if (Array.isArray(object)) { for (let i = 0; i < object.length; ++i) { const header = object[i]; if (header.length !== 2) { throw webidl.errors.exception({ header: "Headers constructor", message: `expected name/value pair to be length 2, found ${header.length}.` }); } appendHeader(headers, header[0], header[1]); } } else if (typeof object === "object" && object !== null) { const keys = Object.keys(object); for (let i = 0; i < keys.length; ++i) { appendHeader(headers, keys[i], object[keys[i]]); } } else { throw webidl.errors.conversionFailed({ prefix: "Headers constructor", argument: "Argument 1", types: ["sequence>", "record"] }); } } function appendHeader(headers, name, value) { value = headerValueNormalize(value); if (!isValidHeaderName(name)) { throw webidl.errors.invalidArgument({ prefix: "Headers.append", value: name, type: "header name" }); } else if (!isValidHeaderValue(value)) { throw webidl.errors.invalidArgument({ prefix: "Headers.append", value, type: "header value" }); } if (getHeadersGuard(headers) === "immutable") { throw new TypeError("immutable"); } return getHeadersList(headers).append(name, value, false); } function compareHeaderName(a, b) { return a[0] < b[0] ? -1 : 1; } var HeadersList = class _HeadersList { /** @type {[string, string][]|null} */ cookies = null; constructor(init) { if (init instanceof _HeadersList) { this[kHeadersMap] = new Map(init[kHeadersMap]); this[kHeadersSortedMap] = init[kHeadersSortedMap]; this.cookies = init.cookies === null ? null : [...init.cookies]; } else { this[kHeadersMap] = new Map(init); this[kHeadersSortedMap] = null; } } /** * @see https://fetch.spec.whatwg.org/#header-list-contains * @param {string} name * @param {boolean} isLowerCase */ contains(name, isLowerCase) { return this[kHeadersMap].has(isLowerCase ? name : name.toLowerCase()); } clear() { this[kHeadersMap].clear(); this[kHeadersSortedMap] = null; this.cookies = null; } /** * @see https://fetch.spec.whatwg.org/#concept-header-list-append * @param {string} name * @param {string} value * @param {boolean} isLowerCase */ append(name, value, isLowerCase) { this[kHeadersSortedMap] = null; const lowercaseName = isLowerCase ? name : name.toLowerCase(); const exists = this[kHeadersMap].get(lowercaseName); if (exists) { const delimiter = lowercaseName === "cookie" ? "; " : ", "; this[kHeadersMap].set(lowercaseName, { name: exists.name, value: `${exists.value}${delimiter}${value}` }); } else { this[kHeadersMap].set(lowercaseName, { name, value }); } if (lowercaseName === "set-cookie") { (this.cookies ??= []).push(value); } } /** * @see https://fetch.spec.whatwg.org/#concept-header-list-set * @param {string} name * @param {string} value * @param {boolean} isLowerCase */ set(name, value, isLowerCase) { this[kHeadersSortedMap] = null; const lowercaseName = isLowerCase ? name : name.toLowerCase(); if (lowercaseName === "set-cookie") { this.cookies = [value]; } this[kHeadersMap].set(lowercaseName, { name, value }); } /** * @see https://fetch.spec.whatwg.org/#concept-header-list-delete * @param {string} name * @param {boolean} isLowerCase */ delete(name, isLowerCase) { this[kHeadersSortedMap] = null; if (!isLowerCase) name = name.toLowerCase(); if (name === "set-cookie") { this.cookies = null; } this[kHeadersMap].delete(name); } /** * @see https://fetch.spec.whatwg.org/#concept-header-list-get * @param {string} name * @param {boolean} isLowerCase * @returns {string | null} */ get(name, isLowerCase) { return this[kHeadersMap].get(isLowerCase ? name : name.toLowerCase())?.value ?? null; } *[Symbol.iterator]() { for (const { 0: name, 1: { value } } of this[kHeadersMap]) { yield [name, value]; } } get entries() { const headers = {}; if (this[kHeadersMap].size !== 0) { for (const { name, value } of this[kHeadersMap].values()) { headers[name] = value; } } return headers; } rawValues() { return this[kHeadersMap].values(); } get entriesList() { const headers = []; if (this[kHeadersMap].size !== 0) { for (const { 0: lowerName, 1: { name, value } } of this[kHeadersMap]) { if (lowerName === "set-cookie") { for (const cookie of this.cookies) { headers.push([name, cookie]); } } else { headers.push([name, value]); } } } return headers; } // https://fetch.spec.whatwg.org/#convert-header-names-to-a-sorted-lowercase-set toSortedArray() { const size = this[kHeadersMap].size; const array = new Array(size); if (size <= 32) { if (size === 0) { return array; } const iterator = this[kHeadersMap][Symbol.iterator](); const firstValue = iterator.next().value; array[0] = [firstValue[0], firstValue[1].value]; assert(firstValue[1].value !== null); for (let i = 1, j = 0, right = 0, left = 0, pivot = 0, x, value; i < size; ++i) { value = iterator.next().value; x = array[i] = [value[0], value[1].value]; assert(x[1] !== null); left = 0; right = i; while (left < right) { pivot = left + (right - left >> 1); if (array[pivot][0] <= x[0]) { left = pivot + 1; } else { right = pivot; } } if (i !== pivot) { j = i; while (j > left) { array[j] = array[--j]; } array[left] = x; } } if (!iterator.next().done) { throw new TypeError("Unreachable"); } return array; } else { let i = 0; for (const { 0: name, 1: { value } } of this[kHeadersMap]) { array[i++] = [name, value]; assert(value !== null); } return array.sort(compareHeaderName); } } }; var Headers2 = class _Headers { #guard; #headersList; constructor(init = void 0) { webidl.util.markAsUncloneable(this); if (init === kConstruct) { return; } this.#headersList = new HeadersList(); this.#guard = "none"; if (init !== void 0) { init = webidl.converters.HeadersInit(init, "Headers contructor", "init"); fill(this, init); } } // https://fetch.spec.whatwg.org/#dom-headers-append append(name, value) { webidl.brandCheck(this, _Headers); webidl.argumentLengthCheck(arguments, 2, "Headers.append"); const prefix = "Headers.append"; name = webidl.converters.ByteString(name, prefix, "name"); value = webidl.converters.ByteString(value, prefix, "value"); return appendHeader(this, name, value); } // https://fetch.spec.whatwg.org/#dom-headers-delete delete(name) { webidl.brandCheck(this, _Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.delete"); const prefix = "Headers.delete"; name = webidl.converters.ByteString(name, prefix, "name"); if (!isValidHeaderName(name)) { throw webidl.errors.invalidArgument({ prefix: "Headers.delete", value: name, type: "header name" }); } if (this.#guard === "immutable") { throw new TypeError("immutable"); } if (!this.#headersList.contains(name, false)) { return; } this.#headersList.delete(name, false); } // https://fetch.spec.whatwg.org/#dom-headers-get get(name) { webidl.brandCheck(this, _Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.get"); const prefix = "Headers.get"; name = webidl.converters.ByteString(name, prefix, "name"); if (!isValidHeaderName(name)) { throw webidl.errors.invalidArgument({ prefix, value: name, type: "header name" }); } return this.#headersList.get(name, false); } // https://fetch.spec.whatwg.org/#dom-headers-has has(name) { webidl.brandCheck(this, _Headers); webidl.argumentLengthCheck(arguments, 1, "Headers.has"); const prefix = "Headers.has"; name = webidl.converters.ByteString(name, prefix, "name"); if (!isValidHeaderName(name)) { throw webidl.errors.invalidArgument({ prefix, value: name, type: "header name" }); } return this.#headersList.contains(name, false); } // https://fetch.spec.whatwg.org/#dom-headers-set set(name, value) { webidl.brandCheck(this, _Headers); webidl.argumentLengthCheck(arguments, 2, "Headers.set"); const prefix = "Headers.set"; name = webidl.converters.ByteString(name, prefix, "name"); value = webidl.converters.ByteString(value, prefix, "value"); value = headerValueNormalize(value); if (!isValidHeaderName(name)) { throw webidl.errors.invalidArgument({ prefix, value: name, type: "header name" }); } else if (!isValidHeaderValue(value)) { throw webidl.errors.invalidArgument({ prefix, value, type: "header value" }); } if (this.#guard === "immutable") { throw new TypeError("immutable"); } this.#headersList.set(name, value, false); } // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie getSetCookie() { webidl.brandCheck(this, _Headers); const list2 = this.#headersList.cookies; if (list2) { return [...list2]; } return []; } // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine get [kHeadersSortedMap]() { if (this.#headersList[kHeadersSortedMap]) { return this.#headersList[kHeadersSortedMap]; } const headers = []; const names = this.#headersList.toSortedArray(); const cookies = this.#headersList.cookies; if (cookies === null || cookies.length === 1) { return this.#headersList[kHeadersSortedMap] = names; } for (let i = 0; i < names.length; ++i) { const { 0: name, 1: value } = names[i]; if (name === "set-cookie") { for (let j = 0; j < cookies.length; ++j) { headers.push([name, cookies[j]]); } } else { headers.push([name, value]); } } return this.#headersList[kHeadersSortedMap] = headers; } [util.inspect.custom](depth, options) { options.depth ??= depth; return `Headers ${util.formatWithOptions(options, this.#headersList.entries)}`; } static getHeadersGuard(o) { return o.#guard; } static setHeadersGuard(o, guard) { o.#guard = guard; } static getHeadersList(o) { return o.#headersList; } static setHeadersList(o, list2) { o.#headersList = list2; } }; var { getHeadersGuard, setHeadersGuard, getHeadersList, setHeadersList } = Headers2; Reflect.deleteProperty(Headers2, "getHeadersGuard"); Reflect.deleteProperty(Headers2, "setHeadersGuard"); Reflect.deleteProperty(Headers2, "getHeadersList"); Reflect.deleteProperty(Headers2, "setHeadersList"); iteratorMixin("Headers", Headers2, kHeadersSortedMap, 0, 1); Object.defineProperties(Headers2.prototype, { append: kEnumerableProperty, delete: kEnumerableProperty, get: kEnumerableProperty, has: kEnumerableProperty, set: kEnumerableProperty, getSetCookie: kEnumerableProperty, [Symbol.toStringTag]: { value: "Headers", configurable: true }, [util.inspect.custom]: { enumerable: false } }); webidl.converters.HeadersInit = function(V, prefix, argument) { if (webidl.util.Type(V) === "Object") { const iterator = Reflect.get(V, Symbol.iterator); if (!util.types.isProxy(V) && iterator === Headers2.prototype.entries) { try { return getHeadersList(V).entriesList; } catch { } } if (typeof iterator === "function") { return webidl.converters["sequence>"](V, prefix, argument, iterator.bind(V)); } return webidl.converters["record"](V, prefix, argument); } throw webidl.errors.conversionFailed({ prefix: "Headers constructor", argument: "Argument 1", types: ["sequence>", "record"] }); }; module.exports = { fill, // for test. compareHeaderName, Headers: Headers2, HeadersList, getHeadersGuard, setHeadersGuard, setHeadersList, getHeadersList }; } }); // viewer/node_modules/undici/lib/web/fetch/response.js var require_response = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/response.js"(exports, module) { "use strict"; var { Headers: Headers2, HeadersList, fill, getHeadersGuard, setHeadersGuard, setHeadersList } = require_headers(); var { extractBody, cloneBody, mixinBody, hasFinalizationRegistry, streamRegistry, bodyUnusable } = require_body(); var util = require_util(); var nodeUtil = __require("node:util"); var { kEnumerableProperty } = util; var { isValidReasonPhrase, isCancelled, isAborted, isBlobLike, serializeJavascriptValueToJSONString, isErrorLike, isomorphicEncode, environmentSettingsObject: relevantRealm } = require_util2(); var { redirectStatusSet, nullBodyStatus } = require_constants3(); var { kState, kHeaders } = require_symbols2(); var { webidl } = require_webidl(); var { FormData } = require_formdata(); var { URLSerializer } = require_data_url(); var { kConstruct } = require_symbols(); var assert = __require("node:assert"); var { types } = __require("node:util"); var textEncoder2 = new TextEncoder("utf-8"); var Response2 = class _Response { // Creates network error Response. static error() { const responseObject = fromInnerResponse(makeNetworkError(), "immutable"); return responseObject; } // https://fetch.spec.whatwg.org/#dom-response-json static json(data, init = {}) { webidl.argumentLengthCheck(arguments, 1, "Response.json"); if (init !== null) { init = webidl.converters.ResponseInit(init); } const bytes2 = textEncoder2.encode( serializeJavascriptValueToJSONString(data) ); const body = extractBody(bytes2); const responseObject = fromInnerResponse(makeResponse({}), "response"); initializeResponse(responseObject, init, { body: body[0], type: "application/json" }); return responseObject; } // Creates a redirect Response that redirects to url with status status. static redirect(url, status = 302) { webidl.argumentLengthCheck(arguments, 1, "Response.redirect"); url = webidl.converters.USVString(url); status = webidl.converters["unsigned short"](status); let parsedURL; try { parsedURL = new URL(url, relevantRealm.settingsObject.baseUrl); } catch (err) { throw new TypeError(`Failed to parse URL from ${url}`, { cause: err }); } if (!redirectStatusSet.has(status)) { throw new RangeError(`Invalid status code ${status}`); } const responseObject = fromInnerResponse(makeResponse({}), "immutable"); responseObject[kState].status = status; const value = isomorphicEncode(URLSerializer(parsedURL)); responseObject[kState].headersList.append("location", value, true); return responseObject; } // https://fetch.spec.whatwg.org/#dom-response constructor(body = null, init = {}) { webidl.util.markAsUncloneable(this); if (body === kConstruct) { return; } if (body !== null) { body = webidl.converters.BodyInit(body); } init = webidl.converters.ResponseInit(init); this[kState] = makeResponse({}); this[kHeaders] = new Headers2(kConstruct); setHeadersGuard(this[kHeaders], "response"); setHeadersList(this[kHeaders], this[kState].headersList); let bodyWithType = null; if (body != null) { const [extractedBody, type] = extractBody(body); bodyWithType = { body: extractedBody, type }; } initializeResponse(this, init, bodyWithType); } // Returns response’s type, e.g., "cors". get type() { webidl.brandCheck(this, _Response); return this[kState].type; } // Returns response’s URL, if it has one; otherwise the empty string. get url() { webidl.brandCheck(this, _Response); const urlList = this[kState].urlList; const url = urlList[urlList.length - 1] ?? null; if (url === null) { return ""; } return URLSerializer(url, true); } // Returns whether response was obtained through a redirect. get redirected() { webidl.brandCheck(this, _Response); return this[kState].urlList.length > 1; } // Returns response’s status. get status() { webidl.brandCheck(this, _Response); return this[kState].status; } // Returns whether response’s status is an ok status. get ok() { webidl.brandCheck(this, _Response); return this[kState].status >= 200 && this[kState].status <= 299; } // Returns response’s status message. get statusText() { webidl.brandCheck(this, _Response); return this[kState].statusText; } // Returns response’s headers as Headers. get headers() { webidl.brandCheck(this, _Response); return this[kHeaders]; } get body() { webidl.brandCheck(this, _Response); return this[kState].body ? this[kState].body.stream : null; } get bodyUsed() { webidl.brandCheck(this, _Response); return !!this[kState].body && util.isDisturbed(this[kState].body.stream); } // Returns a clone of response. clone() { webidl.brandCheck(this, _Response); if (bodyUnusable(this)) { throw webidl.errors.exception({ header: "Response.clone", message: "Body has already been consumed." }); } const clonedResponse = cloneResponse(this[kState]); if (hasFinalizationRegistry && this[kState].body?.stream) { streamRegistry.register(this, new WeakRef(this[kState].body.stream)); } return fromInnerResponse(clonedResponse, getHeadersGuard(this[kHeaders])); } [nodeUtil.inspect.custom](depth, options) { if (options.depth === null) { options.depth = 2; } options.colors ??= true; const properties = { status: this.status, statusText: this.statusText, headers: this.headers, body: this.body, bodyUsed: this.bodyUsed, ok: this.ok, redirected: this.redirected, type: this.type, url: this.url }; return `Response ${nodeUtil.formatWithOptions(options, properties)}`; } }; mixinBody(Response2); Object.defineProperties(Response2.prototype, { type: kEnumerableProperty, url: kEnumerableProperty, status: kEnumerableProperty, ok: kEnumerableProperty, redirected: kEnumerableProperty, statusText: kEnumerableProperty, headers: kEnumerableProperty, clone: kEnumerableProperty, body: kEnumerableProperty, bodyUsed: kEnumerableProperty, [Symbol.toStringTag]: { value: "Response", configurable: true } }); Object.defineProperties(Response2, { json: kEnumerableProperty, redirect: kEnumerableProperty, error: kEnumerableProperty }); function cloneResponse(response) { if (response.internalResponse) { return filterResponse( cloneResponse(response.internalResponse), response.type ); } const newResponse = makeResponse({ ...response, body: null }); if (response.body != null) { newResponse.body = cloneBody(newResponse, response.body); } return newResponse; } function makeResponse(init) { return { aborted: false, rangeRequested: false, timingAllowPassed: false, requestIncludesCredentials: false, type: "default", status: 200, timingInfo: null, cacheState: "", statusText: "", ...init, headersList: init?.headersList ? new HeadersList(init?.headersList) : new HeadersList(), urlList: init?.urlList ? [...init.urlList] : [] }; } function makeNetworkError(reason) { const isError2 = isErrorLike(reason); return makeResponse({ type: "error", status: 0, error: isError2 ? reason : new Error(reason ? String(reason) : reason), aborted: reason && reason.name === "AbortError" }); } function isNetworkError2(response) { return ( // A network error is a response whose type is "error", response.type === "error" && // status is 0 response.status === 0 ); } function makeFilteredResponse(response, state) { state = { internalResponse: response, ...state }; return new Proxy(response, { get(target, p) { return p in state ? state[p] : target[p]; }, set(target, p, value) { assert(!(p in state)); target[p] = value; return true; } }); } function filterResponse(response, type) { if (type === "basic") { return makeFilteredResponse(response, { type: "basic", headersList: response.headersList }); } else if (type === "cors") { return makeFilteredResponse(response, { type: "cors", headersList: response.headersList }); } else if (type === "opaque") { return makeFilteredResponse(response, { type: "opaque", urlList: Object.freeze([]), status: 0, statusText: "", body: null }); } else if (type === "opaqueredirect") { return makeFilteredResponse(response, { type: "opaqueredirect", status: 0, statusText: "", headersList: [], body: null }); } else { assert(false); } } function makeAppropriateNetworkError(fetchParams, err = null) { assert(isCancelled(fetchParams)); return isAborted(fetchParams) ? makeNetworkError(Object.assign(new DOMException("The operation was aborted.", "AbortError"), { cause: err })) : makeNetworkError(Object.assign(new DOMException("Request was cancelled."), { cause: err })); } function initializeResponse(response, init, body) { if (init.status !== null && (init.status < 200 || init.status > 599)) { throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.'); } if ("statusText" in init && init.statusText != null) { if (!isValidReasonPhrase(String(init.statusText))) { throw new TypeError("Invalid statusText"); } } if ("status" in init && init.status != null) { response[kState].status = init.status; } if ("statusText" in init && init.statusText != null) { response[kState].statusText = init.statusText; } if ("headers" in init && init.headers != null) { fill(response[kHeaders], init.headers); } if (body) { if (nullBodyStatus.includes(response.status)) { throw webidl.errors.exception({ header: "Response constructor", message: `Invalid response status code ${response.status}` }); } response[kState].body = body.body; if (body.type != null && !response[kState].headersList.contains("content-type", true)) { response[kState].headersList.append("content-type", body.type, true); } } } function fromInnerResponse(innerResponse, guard) { const response = new Response2(kConstruct); response[kState] = innerResponse; response[kHeaders] = new Headers2(kConstruct); setHeadersList(response[kHeaders], innerResponse.headersList); setHeadersGuard(response[kHeaders], guard); if (hasFinalizationRegistry && innerResponse.body?.stream) { streamRegistry.register(response, new WeakRef(innerResponse.body.stream)); } return response; } webidl.converters.ReadableStream = webidl.interfaceConverter( ReadableStream ); webidl.converters.FormData = webidl.interfaceConverter( FormData ); webidl.converters.URLSearchParams = webidl.interfaceConverter( URLSearchParams ); webidl.converters.XMLHttpRequestBodyInit = function(V, prefix, name) { if (typeof V === "string") { return webidl.converters.USVString(V, prefix, name); } if (isBlobLike(V)) { return webidl.converters.Blob(V, prefix, name, { strict: false }); } if (ArrayBuffer.isView(V) || types.isArrayBuffer(V)) { return webidl.converters.BufferSource(V, prefix, name); } if (util.isFormDataLike(V)) { return webidl.converters.FormData(V, prefix, name, { strict: false }); } if (V instanceof URLSearchParams) { return webidl.converters.URLSearchParams(V, prefix, name); } return webidl.converters.DOMString(V, prefix, name); }; webidl.converters.BodyInit = function(V, prefix, argument) { if (V instanceof ReadableStream) { return webidl.converters.ReadableStream(V, prefix, argument); } if (V?.[Symbol.asyncIterator]) { return V; } return webidl.converters.XMLHttpRequestBodyInit(V, prefix, argument); }; webidl.converters.ResponseInit = webidl.dictionaryConverter([ { key: "status", converter: webidl.converters["unsigned short"], defaultValue: () => 200 }, { key: "statusText", converter: webidl.converters.ByteString, defaultValue: () => "" }, { key: "headers", converter: webidl.converters.HeadersInit } ]); module.exports = { isNetworkError: isNetworkError2, makeNetworkError, makeResponse, makeAppropriateNetworkError, filterResponse, Response: Response2, cloneResponse, fromInnerResponse }; } }); // viewer/node_modules/undici/lib/web/fetch/dispatcher-weakref.js var require_dispatcher_weakref = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/dispatcher-weakref.js"(exports, module) { "use strict"; var { kConnected, kSize } = require_symbols(); var CompatWeakRef = class { constructor(value) { this.value = value; } deref() { return this.value[kConnected] === 0 && this.value[kSize] === 0 ? void 0 : this.value; } }; var CompatFinalizer = class { constructor(finalizer) { this.finalizer = finalizer; } register(dispatcher, key) { if (dispatcher.on) { dispatcher.on("disconnect", () => { if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { this.finalizer(key); } }); } } unregister(key) { } }; module.exports = function() { if (process.env.NODE_V8_COVERAGE && process.version.startsWith("v18")) { process._rawDebug("Using compatibility WeakRef and FinalizationRegistry"); return { WeakRef: CompatWeakRef, FinalizationRegistry: CompatFinalizer }; } return { WeakRef, FinalizationRegistry }; }; } }); // viewer/node_modules/undici/lib/web/fetch/request.js var require_request2 = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/request.js"(exports, module) { "use strict"; var { extractBody, mixinBody, cloneBody, bodyUnusable } = require_body(); var { Headers: Headers2, fill: fillHeaders, HeadersList, setHeadersGuard, getHeadersGuard, setHeadersList, getHeadersList } = require_headers(); var { FinalizationRegistry: FinalizationRegistry2 } = require_dispatcher_weakref()(); var util = require_util(); var nodeUtil = __require("node:util"); var { isValidHTTPToken, sameOrigin, environmentSettingsObject } = require_util2(); var { forbiddenMethodsSet, corsSafeListedMethodsSet, referrerPolicy, requestRedirect, requestMode, requestCredentials, requestCache, requestDuplex } = require_constants3(); var { kEnumerableProperty, normalizedMethodRecordsBase, normalizedMethodRecords } = util; var { kHeaders, kSignal, kState, kDispatcher } = require_symbols2(); var { webidl } = require_webidl(); var { URLSerializer } = require_data_url(); var { kConstruct } = require_symbols(); var assert = __require("node:assert"); var { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = __require("node:events"); var kAbortController = /* @__PURE__ */ Symbol("abortController"); var requestFinalizer = new FinalizationRegistry2(({ signal, abort }) => { signal.removeEventListener("abort", abort); }); var dependentControllerMap = /* @__PURE__ */ new WeakMap(); function buildAbort(acRef) { return abort; function abort() { const ac = acRef.deref(); if (ac !== void 0) { requestFinalizer.unregister(abort); this.removeEventListener("abort", abort); ac.abort(this.reason); const controllerList = dependentControllerMap.get(ac.signal); if (controllerList !== void 0) { if (controllerList.size !== 0) { for (const ref of controllerList) { const ctrl = ref.deref(); if (ctrl !== void 0) { ctrl.abort(this.reason); } } controllerList.clear(); } dependentControllerMap.delete(ac.signal); } } } } var patchMethodWarning = false; var Request2 = class _Request { // https://fetch.spec.whatwg.org/#dom-request constructor(input, init = {}) { webidl.util.markAsUncloneable(this); if (input === kConstruct) { return; } const prefix = "Request constructor"; webidl.argumentLengthCheck(arguments, 1, prefix); input = webidl.converters.RequestInfo(input, prefix, "input"); init = webidl.converters.RequestInit(init, prefix, "init"); let request = null; let fallbackMode = null; const baseUrl = environmentSettingsObject.settingsObject.baseUrl; let signal = null; if (typeof input === "string") { this[kDispatcher] = init.dispatcher; let parsedURL; try { parsedURL = new URL(input, baseUrl); } catch (err) { throw new TypeError("Failed to parse URL from " + input, { cause: err }); } if (parsedURL.username || parsedURL.password) { throw new TypeError( "Request cannot be constructed from a URL that includes credentials: " + input ); } request = makeRequest({ urlList: [parsedURL] }); fallbackMode = "cors"; } else { this[kDispatcher] = init.dispatcher || input[kDispatcher]; assert(input instanceof _Request); request = input[kState]; signal = input[kSignal]; } const origin = environmentSettingsObject.settingsObject.origin; let window2 = "client"; if (request.window?.constructor?.name === "EnvironmentSettingsObject" && sameOrigin(request.window, origin)) { window2 = request.window; } if (init.window != null) { throw new TypeError(`'window' option '${window2}' must be null`); } if ("window" in init) { window2 = "no-window"; } request = makeRequest({ // URL request’s URL. // undici implementation note: this is set as the first item in request's urlList in makeRequest // method request’s method. method: request.method, // header list A copy of request’s header list. // undici implementation note: headersList is cloned in makeRequest headersList: request.headersList, // unsafe-request flag Set. unsafeRequest: request.unsafeRequest, // client This’s relevant settings object. client: environmentSettingsObject.settingsObject, // window window. window: window2, // priority request’s priority. priority: request.priority, // origin request’s origin. The propagation of the origin is only significant for navigation requests // being handled by a service worker. In this scenario a request can have an origin that is different // from the current client. origin: request.origin, // referrer request’s referrer. referrer: request.referrer, // referrer policy request’s referrer policy. referrerPolicy: request.referrerPolicy, // mode request’s mode. mode: request.mode, // credentials mode request’s credentials mode. credentials: request.credentials, // cache mode request’s cache mode. cache: request.cache, // redirect mode request’s redirect mode. redirect: request.redirect, // integrity metadata request’s integrity metadata. integrity: request.integrity, // keepalive request’s keepalive. keepalive: request.keepalive, // reload-navigation flag request’s reload-navigation flag. reloadNavigation: request.reloadNavigation, // history-navigation flag request’s history-navigation flag. historyNavigation: request.historyNavigation, // URL list A clone of request’s URL list. urlList: [...request.urlList] }); const initHasKey = Object.keys(init).length !== 0; if (initHasKey) { if (request.mode === "navigate") { request.mode = "same-origin"; } request.reloadNavigation = false; request.historyNavigation = false; request.origin = "client"; request.referrer = "client"; request.referrerPolicy = ""; request.url = request.urlList[request.urlList.length - 1]; request.urlList = [request.url]; } if (init.referrer !== void 0) { const referrer = init.referrer; if (referrer === "") { request.referrer = "no-referrer"; } else { let parsedReferrer; try { parsedReferrer = new URL(referrer, baseUrl); } catch (err) { throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }); } if (parsedReferrer.protocol === "about:" && parsedReferrer.hostname === "client" || origin && !sameOrigin(parsedReferrer, environmentSettingsObject.settingsObject.baseUrl)) { request.referrer = "client"; } else { request.referrer = parsedReferrer; } } } if (init.referrerPolicy !== void 0) { request.referrerPolicy = init.referrerPolicy; } let mode; if (init.mode !== void 0) { mode = init.mode; } else { mode = fallbackMode; } if (mode === "navigate") { throw webidl.errors.exception({ header: "Request constructor", message: "invalid request mode navigate." }); } if (mode != null) { request.mode = mode; } if (init.credentials !== void 0) { request.credentials = init.credentials; } if (init.cache !== void 0) { request.cache = init.cache; } if (request.cache === "only-if-cached" && request.mode !== "same-origin") { throw new TypeError( "'only-if-cached' can be set only with 'same-origin' mode" ); } if (init.redirect !== void 0) { request.redirect = init.redirect; } if (init.integrity != null) { request.integrity = String(init.integrity); } if (init.keepalive !== void 0) { request.keepalive = Boolean(init.keepalive); } if (init.method !== void 0) { let method = init.method; const mayBeNormalized = normalizedMethodRecords[method]; if (mayBeNormalized !== void 0) { request.method = mayBeNormalized; } else { if (!isValidHTTPToken(method)) { throw new TypeError(`'${method}' is not a valid HTTP method.`); } const upperCase = method.toUpperCase(); if (forbiddenMethodsSet.has(upperCase)) { throw new TypeError(`'${method}' HTTP method is unsupported.`); } method = normalizedMethodRecordsBase[upperCase] ?? method; request.method = method; } if (!patchMethodWarning && request.method === "patch") { process.emitWarning("Using `patch` is highly likely to result in a `405 Method Not Allowed`. `PATCH` is much more likely to succeed.", { code: "UNDICI-FETCH-patch" }); patchMethodWarning = true; } } if (init.signal !== void 0) { signal = init.signal; } this[kState] = request; const ac = new AbortController(); this[kSignal] = ac.signal; if (signal != null) { if (!signal || typeof signal.aborted !== "boolean" || typeof signal.addEventListener !== "function") { throw new TypeError( "Failed to construct 'Request': member signal is not of type AbortSignal." ); } if (signal.aborted) { ac.abort(signal.reason); } else { this[kAbortController] = ac; const acRef = new WeakRef(ac); const abort = buildAbort(acRef); try { if (typeof getMaxListeners === "function" && getMaxListeners(signal) === defaultMaxListeners) { setMaxListeners(1500, signal); } else if (getEventListeners(signal, "abort").length >= defaultMaxListeners) { setMaxListeners(1500, signal); } } catch { } util.addAbortListener(signal, abort); requestFinalizer.register(ac, { signal, abort }, abort); } } this[kHeaders] = new Headers2(kConstruct); setHeadersList(this[kHeaders], request.headersList); setHeadersGuard(this[kHeaders], "request"); if (mode === "no-cors") { if (!corsSafeListedMethodsSet.has(request.method)) { throw new TypeError( `'${request.method} is unsupported in no-cors mode.` ); } setHeadersGuard(this[kHeaders], "request-no-cors"); } if (initHasKey) { const headersList = getHeadersList(this[kHeaders]); const headers = init.headers !== void 0 ? init.headers : new HeadersList(headersList); headersList.clear(); if (headers instanceof HeadersList) { for (const { name, value } of headers.rawValues()) { headersList.append(name, value, false); } headersList.cookies = headers.cookies; } else { fillHeaders(this[kHeaders], headers); } } const inputBody = input instanceof _Request ? input[kState].body : null; if ((init.body != null || inputBody != null) && (request.method === "GET" || request.method === "HEAD")) { throw new TypeError("Request with GET/HEAD method cannot have body."); } let initBody = null; if (init.body != null) { const [extractedBody, contentType] = extractBody( init.body, request.keepalive ); initBody = extractedBody; if (contentType && !getHeadersList(this[kHeaders]).contains("content-type", true)) { this[kHeaders].append("content-type", contentType); } } const inputOrInitBody = initBody ?? inputBody; if (inputOrInitBody != null && inputOrInitBody.source == null) { if (initBody != null && init.duplex == null) { throw new TypeError("RequestInit: duplex option is required when sending a body."); } if (request.mode !== "same-origin" && request.mode !== "cors") { throw new TypeError( 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' ); } request.useCORSPreflightFlag = true; } let finalBody = inputOrInitBody; if (initBody == null && inputBody != null) { if (bodyUnusable(input)) { throw new TypeError( "Cannot construct a Request with a Request object that has already been used." ); } const identityTransform = new TransformStream(); inputBody.stream.pipeThrough(identityTransform); finalBody = { source: inputBody.source, length: inputBody.length, stream: identityTransform.readable }; } this[kState].body = finalBody; } // Returns request’s HTTP method, which is "GET" by default. get method() { webidl.brandCheck(this, _Request); return this[kState].method; } // Returns the URL of request as a string. get url() { webidl.brandCheck(this, _Request); return URLSerializer(this[kState].url); } // Returns a Headers object consisting of the headers associated with request. // Note that headers added in the network layer by the user agent will not // be accounted for in this object, e.g., the "Host" header. get headers() { webidl.brandCheck(this, _Request); return this[kHeaders]; } // Returns the kind of resource requested by request, e.g., "document" // or "script". get destination() { webidl.brandCheck(this, _Request); return this[kState].destination; } // Returns the referrer of request. Its value can be a same-origin URL if // explicitly set in init, the empty string to indicate no referrer, and // "about:client" when defaulting to the global’s default. This is used // during fetching to determine the value of the `Referer` header of the // request being made. get referrer() { webidl.brandCheck(this, _Request); if (this[kState].referrer === "no-referrer") { return ""; } if (this[kState].referrer === "client") { return "about:client"; } return this[kState].referrer.toString(); } // Returns the referrer policy associated with request. // This is used during fetching to compute the value of the request’s // referrer. get referrerPolicy() { webidl.brandCheck(this, _Request); return this[kState].referrerPolicy; } // Returns the mode associated with request, which is a string indicating // whether the request will use CORS, or will be restricted to same-origin // URLs. get mode() { webidl.brandCheck(this, _Request); return this[kState].mode; } // Returns the credentials mode associated with request, // which is a string indicating whether credentials will be sent with the // request always, never, or only when sent to a same-origin URL. get credentials() { return this[kState].credentials; } // Returns the cache mode associated with request, // which is a string indicating how the request will // interact with the browser’s cache when fetching. get cache() { webidl.brandCheck(this, _Request); return this[kState].cache; } // Returns the redirect mode associated with request, // which is a string indicating how redirects for the // request will be handled during fetching. A request // will follow redirects by default. get redirect() { webidl.brandCheck(this, _Request); return this[kState].redirect; } // Returns request’s subresource integrity metadata, which is a // cryptographic hash of the resource being fetched. Its value // consists of multiple hashes separated by whitespace. [SRI] get integrity() { webidl.brandCheck(this, _Request); return this[kState].integrity; } // Returns a boolean indicating whether or not request can outlive the // global in which it was created. get keepalive() { webidl.brandCheck(this, _Request); return this[kState].keepalive; } // Returns a boolean indicating whether or not request is for a reload // navigation. get isReloadNavigation() { webidl.brandCheck(this, _Request); return this[kState].reloadNavigation; } // Returns a boolean indicating whether or not request is for a history // navigation (a.k.a. back-forward navigation). get isHistoryNavigation() { webidl.brandCheck(this, _Request); return this[kState].historyNavigation; } // Returns the signal associated with request, which is an AbortSignal // object indicating whether or not request has been aborted, and its // abort event handler. get signal() { webidl.brandCheck(this, _Request); return this[kSignal]; } get body() { webidl.brandCheck(this, _Request); return this[kState].body ? this[kState].body.stream : null; } get bodyUsed() { webidl.brandCheck(this, _Request); return !!this[kState].body && util.isDisturbed(this[kState].body.stream); } get duplex() { webidl.brandCheck(this, _Request); return "half"; } // Returns a clone of request. clone() { webidl.brandCheck(this, _Request); if (bodyUnusable(this)) { throw new TypeError("unusable"); } const clonedRequest = cloneRequest(this[kState]); const ac = new AbortController(); if (this.signal.aborted) { ac.abort(this.signal.reason); } else { let list2 = dependentControllerMap.get(this.signal); if (list2 === void 0) { list2 = /* @__PURE__ */ new Set(); dependentControllerMap.set(this.signal, list2); } const acRef = new WeakRef(ac); list2.add(acRef); util.addAbortListener( ac.signal, buildAbort(acRef) ); } return fromInnerRequest(clonedRequest, ac.signal, getHeadersGuard(this[kHeaders])); } [nodeUtil.inspect.custom](depth, options) { if (options.depth === null) { options.depth = 2; } options.colors ??= true; const properties = { method: this.method, url: this.url, headers: this.headers, destination: this.destination, referrer: this.referrer, referrerPolicy: this.referrerPolicy, mode: this.mode, credentials: this.credentials, cache: this.cache, redirect: this.redirect, integrity: this.integrity, keepalive: this.keepalive, isReloadNavigation: this.isReloadNavigation, isHistoryNavigation: this.isHistoryNavigation, signal: this.signal }; return `Request ${nodeUtil.formatWithOptions(options, properties)}`; } }; mixinBody(Request2); function makeRequest(init) { return { method: init.method ?? "GET", localURLsOnly: init.localURLsOnly ?? false, unsafeRequest: init.unsafeRequest ?? false, body: init.body ?? null, client: init.client ?? null, reservedClient: init.reservedClient ?? null, replacesClientId: init.replacesClientId ?? "", window: init.window ?? "client", keepalive: init.keepalive ?? false, serviceWorkers: init.serviceWorkers ?? "all", initiator: init.initiator ?? "", destination: init.destination ?? "", priority: init.priority ?? null, origin: init.origin ?? "client", policyContainer: init.policyContainer ?? "client", referrer: init.referrer ?? "client", referrerPolicy: init.referrerPolicy ?? "", mode: init.mode ?? "no-cors", useCORSPreflightFlag: init.useCORSPreflightFlag ?? false, credentials: init.credentials ?? "same-origin", useCredentials: init.useCredentials ?? false, cache: init.cache ?? "default", redirect: init.redirect ?? "follow", integrity: init.integrity ?? "", cryptoGraphicsNonceMetadata: init.cryptoGraphicsNonceMetadata ?? "", parserMetadata: init.parserMetadata ?? "", reloadNavigation: init.reloadNavigation ?? false, historyNavigation: init.historyNavigation ?? false, userActivation: init.userActivation ?? false, taintedOrigin: init.taintedOrigin ?? false, redirectCount: init.redirectCount ?? 0, responseTainting: init.responseTainting ?? "basic", preventNoCacheCacheControlHeaderModification: init.preventNoCacheCacheControlHeaderModification ?? false, done: init.done ?? false, timingAllowFailed: init.timingAllowFailed ?? false, urlList: init.urlList, url: init.urlList[0], headersList: init.headersList ? new HeadersList(init.headersList) : new HeadersList() }; } function cloneRequest(request) { const newRequest = makeRequest({ ...request, body: null }); if (request.body != null) { newRequest.body = cloneBody(newRequest, request.body); } return newRequest; } function fromInnerRequest(innerRequest, signal, guard) { const request = new Request2(kConstruct); request[kState] = innerRequest; request[kSignal] = signal; request[kHeaders] = new Headers2(kConstruct); setHeadersList(request[kHeaders], innerRequest.headersList); setHeadersGuard(request[kHeaders], guard); return request; } Object.defineProperties(Request2.prototype, { method: kEnumerableProperty, url: kEnumerableProperty, headers: kEnumerableProperty, redirect: kEnumerableProperty, clone: kEnumerableProperty, signal: kEnumerableProperty, duplex: kEnumerableProperty, destination: kEnumerableProperty, body: kEnumerableProperty, bodyUsed: kEnumerableProperty, isHistoryNavigation: kEnumerableProperty, isReloadNavigation: kEnumerableProperty, keepalive: kEnumerableProperty, integrity: kEnumerableProperty, cache: kEnumerableProperty, credentials: kEnumerableProperty, attribute: kEnumerableProperty, referrerPolicy: kEnumerableProperty, referrer: kEnumerableProperty, mode: kEnumerableProperty, [Symbol.toStringTag]: { value: "Request", configurable: true } }); webidl.converters.Request = webidl.interfaceConverter( Request2 ); webidl.converters.RequestInfo = function(V, prefix, argument) { if (typeof V === "string") { return webidl.converters.USVString(V, prefix, argument); } if (V instanceof Request2) { return webidl.converters.Request(V, prefix, argument); } return webidl.converters.USVString(V, prefix, argument); }; webidl.converters.AbortSignal = webidl.interfaceConverter( AbortSignal ); webidl.converters.RequestInit = webidl.dictionaryConverter([ { key: "method", converter: webidl.converters.ByteString }, { key: "headers", converter: webidl.converters.HeadersInit }, { key: "body", converter: webidl.nullableConverter( webidl.converters.BodyInit ) }, { key: "referrer", converter: webidl.converters.USVString }, { key: "referrerPolicy", converter: webidl.converters.DOMString, // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy allowedValues: referrerPolicy }, { key: "mode", converter: webidl.converters.DOMString, // https://fetch.spec.whatwg.org/#concept-request-mode allowedValues: requestMode }, { key: "credentials", converter: webidl.converters.DOMString, // https://fetch.spec.whatwg.org/#requestcredentials allowedValues: requestCredentials }, { key: "cache", converter: webidl.converters.DOMString, // https://fetch.spec.whatwg.org/#requestcache allowedValues: requestCache }, { key: "redirect", converter: webidl.converters.DOMString, // https://fetch.spec.whatwg.org/#requestredirect allowedValues: requestRedirect }, { key: "integrity", converter: webidl.converters.DOMString }, { key: "keepalive", converter: webidl.converters.boolean }, { key: "signal", converter: webidl.nullableConverter( (signal) => webidl.converters.AbortSignal( signal, "RequestInit", "signal", { strict: false } ) ) }, { key: "window", converter: webidl.converters.any }, { key: "duplex", converter: webidl.converters.DOMString, allowedValues: requestDuplex }, { key: "dispatcher", // undici specific option converter: webidl.converters.any } ]); module.exports = { Request: Request2, makeRequest, fromInnerRequest, cloneRequest }; } }); // viewer/node_modules/undici/lib/web/fetch/index.js var require_fetch = __commonJS({ "viewer/node_modules/undici/lib/web/fetch/index.js"(exports, module) { "use strict"; var { makeNetworkError, makeAppropriateNetworkError, filterResponse, makeResponse, fromInnerResponse } = require_response(); var { HeadersList } = require_headers(); var { Request: Request2, cloneRequest } = require_request2(); var zlib = __require("node:zlib"); var { bytesMatch, makePolicyContainer, clonePolicyContainer, requestBadPort, TAOCheck, appendRequestOriginHeader, responseLocationURL, requestCurrentURL, setRequestReferrerPolicyOnRedirect, tryUpgradeRequestToAPotentiallyTrustworthyURL, createOpaqueTimingInfo, appendFetchMetadata, corsCheck, crossOriginResourcePolicyCheck, determineRequestsReferrer, coarsenedSharedCurrentTime, createDeferredPromise, isBlobLike, sameOrigin, isCancelled, isAborted, isErrorLike, fullyReadBody, readableStreamClose, isomorphicEncode, urlIsLocal, urlIsHttpHttpsScheme, urlHasHttpsScheme, clampAndCoarsenConnectionTimingInfo, simpleRangeHeaderValue, buildContentRange, createInflate, extractMimeType } = require_util2(); var { kState, kDispatcher } = require_symbols2(); var assert = __require("node:assert"); var { safelyExtractBody, extractBody } = require_body(); var { redirectStatusSet, nullBodyStatus, safeMethodsSet, requestBodyHeader, subresourceSet } = require_constants3(); var EE = __require("node:events"); var { Readable: Readable2, pipeline, finished } = __require("node:stream"); var { addAbortListener, isErrored, isReadable, bufferToLowerCasedHeaderName } = require_util(); var { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require_data_url(); var { getGlobalDispatcher } = require_global2(); var { webidl } = require_webidl(); var { STATUS_CODES } = __require("node:http"); var GET_OR_HEAD = ["GET", "HEAD"]; var defaultUserAgent = typeof __UNDICI_IS_NODE__ !== "undefined" || typeof esbuildDetection !== "undefined" ? "node" : "undici"; var resolveObjectURL; var Fetch = class extends EE { constructor(dispatcher) { super(); this.dispatcher = dispatcher; this.connection = null; this.dump = false; this.state = "ongoing"; } terminate(reason) { if (this.state !== "ongoing") { return; } this.state = "terminated"; this.connection?.destroy(reason); this.emit("terminated", reason); } // https://fetch.spec.whatwg.org/#fetch-controller-abort abort(error) { if (this.state !== "ongoing") { return; } this.state = "aborted"; if (!error) { error = new DOMException("The operation was aborted.", "AbortError"); } this.serializedAbortReason = error; this.connection?.destroy(error); this.emit("terminated", error); } }; function handleFetchDone(response) { finalizeAndReportTiming(response, "fetch"); } function fetch3(input, init = void 0) { webidl.argumentLengthCheck(arguments, 1, "globalThis.fetch"); let p = createDeferredPromise(); let requestObject; try { requestObject = new Request2(input, init); } catch (e) { p.reject(e); return p.promise; } const request = requestObject[kState]; if (requestObject.signal.aborted) { abortFetch(p, request, null, requestObject.signal.reason); return p.promise; } const globalObject = request.client.globalObject; if (globalObject?.constructor?.name === "ServiceWorkerGlobalScope") { request.serviceWorkers = "none"; } let responseObject = null; let locallyAborted = false; let controller = null; addAbortListener( requestObject.signal, () => { locallyAborted = true; assert(controller != null); controller.abort(requestObject.signal.reason); const realResponse = responseObject?.deref(); abortFetch(p, request, realResponse, requestObject.signal.reason); } ); const processResponse = (response) => { if (locallyAborted) { return; } if (response.aborted) { abortFetch(p, request, responseObject, controller.serializedAbortReason); return; } if (response.type === "error") { p.reject(new TypeError("fetch failed", { cause: response.error })); return; } responseObject = new WeakRef(fromInnerResponse(response, "immutable")); p.resolve(responseObject.deref()); p = null; }; controller = fetching({ request, processResponseEndOfBody: handleFetchDone, processResponse, dispatcher: requestObject[kDispatcher] // undici }); return p.promise; } function finalizeAndReportTiming(response, initiatorType = "other") { if (response.type === "error" && response.aborted) { return; } if (!response.urlList?.length) { return; } const originalURL = response.urlList[0]; let timingInfo = response.timingInfo; let cacheState = response.cacheState; if (!urlIsHttpHttpsScheme(originalURL)) { return; } if (timingInfo === null) { return; } if (!response.timingAllowPassed) { timingInfo = createOpaqueTimingInfo({ startTime: timingInfo.startTime }); cacheState = ""; } timingInfo.endTime = coarsenedSharedCurrentTime(); response.timingInfo = timingInfo; markResourceTiming( timingInfo, originalURL.href, initiatorType, globalThis, cacheState ); } var markResourceTiming = performance.markResourceTiming; function abortFetch(p, request, responseObject, error) { if (p) { p.reject(error); } if (request.body != null && isReadable(request.body?.stream)) { request.body.stream.cancel(error).catch((err) => { if (err.code === "ERR_INVALID_STATE") { return; } throw err; }); } if (responseObject == null) { return; } const response = responseObject[kState]; if (response.body != null && isReadable(response.body?.stream)) { response.body.stream.cancel(error).catch((err) => { if (err.code === "ERR_INVALID_STATE") { return; } throw err; }); } } function fetching({ request, processRequestBodyChunkLength, processRequestEndOfBody, processResponse, processResponseEndOfBody, processResponseConsumeBody, useParallelQueue = false, dispatcher = getGlobalDispatcher() // undici }) { assert(dispatcher); let taskDestination = null; let crossOriginIsolatedCapability = false; if (request.client != null) { taskDestination = request.client.globalObject; crossOriginIsolatedCapability = request.client.crossOriginIsolatedCapability; } const currentTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability); const timingInfo = createOpaqueTimingInfo({ startTime: currentTime }); const fetchParams = { controller: new Fetch(dispatcher), request, timingInfo, processRequestBodyChunkLength, processRequestEndOfBody, processResponse, processResponseConsumeBody, processResponseEndOfBody, taskDestination, crossOriginIsolatedCapability }; assert(!request.body || request.body.stream); if (request.window === "client") { request.window = request.client?.globalObject?.constructor?.name === "Window" ? request.client : "no-window"; } if (request.origin === "client") { request.origin = request.client.origin; } if (request.policyContainer === "client") { if (request.client != null) { request.policyContainer = clonePolicyContainer( request.client.policyContainer ); } else { request.policyContainer = makePolicyContainer(); } } if (!request.headersList.contains("accept", true)) { const value = "*/*"; request.headersList.append("accept", value, true); } if (!request.headersList.contains("accept-language", true)) { request.headersList.append("accept-language", "*", true); } if (request.priority === null) { } if (subresourceSet.has(request.destination)) { } mainFetch(fetchParams).catch((err) => { fetchParams.controller.terminate(err); }); return fetchParams.controller; } async function mainFetch(fetchParams, recursive = false) { const request = fetchParams.request; let response = null; if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { response = makeNetworkError("local URLs only"); } tryUpgradeRequestToAPotentiallyTrustworthyURL(request); if (requestBadPort(request) === "blocked") { response = makeNetworkError("bad port"); } if (request.referrerPolicy === "") { request.referrerPolicy = request.policyContainer.referrerPolicy; } if (request.referrer !== "no-referrer") { request.referrer = determineRequestsReferrer(request); } if (response === null) { response = await (async () => { const currentURL = requestCurrentURL(request); if ( // - request’s current URL’s origin is same origin with request’s origin, // and request’s response tainting is "basic" sameOrigin(currentURL, request.url) && request.responseTainting === "basic" || // request’s current URL’s scheme is "data" currentURL.protocol === "data:" || // - request’s mode is "navigate" or "websocket" (request.mode === "navigate" || request.mode === "websocket") ) { request.responseTainting = "basic"; return await schemeFetch(fetchParams); } if (request.mode === "same-origin") { return makeNetworkError('request mode cannot be "same-origin"'); } if (request.mode === "no-cors") { if (request.redirect !== "follow") { return makeNetworkError( 'redirect mode cannot be "follow" for "no-cors" request' ); } request.responseTainting = "opaque"; return await schemeFetch(fetchParams); } if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { return makeNetworkError("URL scheme must be a HTTP(S) scheme"); } request.responseTainting = "cors"; return await httpFetch(fetchParams); })(); } if (recursive) { return response; } if (response.status !== 0 && !response.internalResponse) { if (request.responseTainting === "cors") { } if (request.responseTainting === "basic") { response = filterResponse(response, "basic"); } else if (request.responseTainting === "cors") { response = filterResponse(response, "cors"); } else if (request.responseTainting === "opaque") { response = filterResponse(response, "opaque"); } else { assert(false); } } let internalResponse = response.status === 0 ? response : response.internalResponse; if (internalResponse.urlList.length === 0) { internalResponse.urlList.push(...request.urlList); } if (!request.timingAllowFailed) { response.timingAllowPassed = true; } if (response.type === "opaque" && internalResponse.status === 206 && internalResponse.rangeRequested && !request.headers.contains("range", true)) { response = internalResponse = makeNetworkError(); } if (response.status !== 0 && (request.method === "HEAD" || request.method === "CONNECT" || nullBodyStatus.includes(internalResponse.status))) { internalResponse.body = null; fetchParams.controller.dump = true; } if (request.integrity) { const processBodyError = (reason) => fetchFinale(fetchParams, makeNetworkError(reason)); if (request.responseTainting === "opaque" || response.body == null) { processBodyError(response.error); return; } const processBody = (bytes2) => { if (!bytesMatch(bytes2, request.integrity)) { processBodyError("integrity mismatch"); return; } response.body = safelyExtractBody(bytes2)[0]; fetchFinale(fetchParams, response); }; await fullyReadBody(response.body, processBody, processBodyError); } else { fetchFinale(fetchParams, response); } } function schemeFetch(fetchParams) { if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { return Promise.resolve(makeAppropriateNetworkError(fetchParams)); } const { request } = fetchParams; const { protocol: scheme } = requestCurrentURL(request); switch (scheme) { case "about:": { return Promise.resolve(makeNetworkError("about scheme is not supported")); } case "blob:": { if (!resolveObjectURL) { resolveObjectURL = __require("node:buffer").resolveObjectURL; } const blobURLEntry = requestCurrentURL(request); if (blobURLEntry.search.length !== 0) { return Promise.resolve(makeNetworkError("NetworkError when attempting to fetch resource.")); } const blob = resolveObjectURL(blobURLEntry.toString()); if (request.method !== "GET" || !isBlobLike(blob)) { return Promise.resolve(makeNetworkError("invalid method")); } const response = makeResponse(); const fullLength = blob.size; const serializedFullLength = isomorphicEncode(`${fullLength}`); const type = blob.type; if (!request.headersList.contains("range", true)) { const bodyWithType = extractBody(blob); response.statusText = "OK"; response.body = bodyWithType[0]; response.headersList.set("content-length", serializedFullLength, true); response.headersList.set("content-type", type, true); } else { response.rangeRequested = true; const rangeHeader = request.headersList.get("range", true); const rangeValue = simpleRangeHeaderValue(rangeHeader, true); if (rangeValue === "failure") { return Promise.resolve(makeNetworkError("failed to fetch the data URL")); } let { rangeStartValue: rangeStart, rangeEndValue: rangeEnd } = rangeValue; if (rangeStart === null) { rangeStart = fullLength - rangeEnd; rangeEnd = rangeStart + rangeEnd - 1; } else { if (rangeStart >= fullLength) { return Promise.resolve(makeNetworkError("Range start is greater than the blob's size.")); } if (rangeEnd === null || rangeEnd >= fullLength) { rangeEnd = fullLength - 1; } } const slicedBlob = blob.slice(rangeStart, rangeEnd, type); const slicedBodyWithType = extractBody(slicedBlob); response.body = slicedBodyWithType[0]; const serializedSlicedLength = isomorphicEncode(`${slicedBlob.size}`); const contentRange = buildContentRange(rangeStart, rangeEnd, fullLength); response.status = 206; response.statusText = "Partial Content"; response.headersList.set("content-length", serializedSlicedLength, true); response.headersList.set("content-type", type, true); response.headersList.set("content-range", contentRange, true); } return Promise.resolve(response); } case "data:": { const currentURL = requestCurrentURL(request); const dataURLStruct = dataURLProcessor(currentURL); if (dataURLStruct === "failure") { return Promise.resolve(makeNetworkError("failed to fetch the data URL")); } const mimeType = serializeAMimeType(dataURLStruct.mimeType); return Promise.resolve(makeResponse({ statusText: "OK", headersList: [ ["content-type", { name: "Content-Type", value: mimeType }] ], body: safelyExtractBody(dataURLStruct.body)[0] })); } case "file:": { return Promise.resolve(makeNetworkError("not implemented... yet...")); } case "http:": case "https:": { return httpFetch(fetchParams).catch((err) => makeNetworkError(err)); } default: { return Promise.resolve(makeNetworkError("unknown scheme")); } } } function finalizeResponse(fetchParams, response) { fetchParams.request.done = true; if (fetchParams.processResponseDone != null) { queueMicrotask(() => fetchParams.processResponseDone(response)); } } function fetchFinale(fetchParams, response) { let timingInfo = fetchParams.timingInfo; const processResponseEndOfBody = () => { const unsafeEndTime = Date.now(); if (fetchParams.request.destination === "document") { fetchParams.controller.fullTimingInfo = timingInfo; } fetchParams.controller.reportTimingSteps = () => { if (fetchParams.request.url.protocol !== "https:") { return; } timingInfo.endTime = unsafeEndTime; let cacheState = response.cacheState; const bodyInfo = response.bodyInfo; if (!response.timingAllowPassed) { timingInfo = createOpaqueTimingInfo(timingInfo); cacheState = ""; } let responseStatus = 0; if (fetchParams.request.mode !== "navigator" || !response.hasCrossOriginRedirects) { responseStatus = response.status; const mimeType = extractMimeType(response.headersList); if (mimeType !== "failure") { bodyInfo.contentType = minimizeSupportedMimeType(mimeType); } } if (fetchParams.request.initiatorType != null) { markResourceTiming(timingInfo, fetchParams.request.url.href, fetchParams.request.initiatorType, globalThis, cacheState, bodyInfo, responseStatus); } }; const processResponseEndOfBodyTask = () => { fetchParams.request.done = true; if (fetchParams.processResponseEndOfBody != null) { queueMicrotask(() => fetchParams.processResponseEndOfBody(response)); } if (fetchParams.request.initiatorType != null) { fetchParams.controller.reportTimingSteps(); } }; queueMicrotask(() => processResponseEndOfBodyTask()); }; if (fetchParams.processResponse != null) { queueMicrotask(() => { fetchParams.processResponse(response); fetchParams.processResponse = null; }); } const internalResponse = response.type === "error" ? response : response.internalResponse ?? response; if (internalResponse.body == null) { processResponseEndOfBody(); } else { finished(internalResponse.body.stream, () => { processResponseEndOfBody(); }); } } async function httpFetch(fetchParams) { const request = fetchParams.request; let response = null; let actualResponse = null; const timingInfo = fetchParams.timingInfo; if (request.serviceWorkers === "all") { } if (response === null) { if (request.redirect === "follow") { request.serviceWorkers = "none"; } actualResponse = response = await httpNetworkOrCacheFetch(fetchParams); if (request.responseTainting === "cors" && corsCheck(request, response) === "failure") { return makeNetworkError("cors failure"); } if (TAOCheck(request, response) === "failure") { request.timingAllowFailed = true; } } if ((request.responseTainting === "opaque" || response.type === "opaque") && crossOriginResourcePolicyCheck( request.origin, request.client, request.destination, actualResponse ) === "blocked") { return makeNetworkError("blocked"); } if (redirectStatusSet.has(actualResponse.status)) { if (request.redirect !== "manual") { fetchParams.controller.connection.destroy(void 0, false); } if (request.redirect === "error") { response = makeNetworkError("unexpected redirect"); } else if (request.redirect === "manual") { response = actualResponse; } else if (request.redirect === "follow") { response = await httpRedirectFetch(fetchParams, response); } else { assert(false); } } response.timingInfo = timingInfo; return response; } function httpRedirectFetch(fetchParams, response) { const request = fetchParams.request; const actualResponse = response.internalResponse ? response.internalResponse : response; let locationURL; try { locationURL = responseLocationURL( actualResponse, requestCurrentURL(request).hash ); if (locationURL == null) { return response; } } catch (err) { return Promise.resolve(makeNetworkError(err)); } if (!urlIsHttpHttpsScheme(locationURL)) { return Promise.resolve(makeNetworkError("URL scheme must be a HTTP(S) scheme")); } if (request.redirectCount === 20) { return Promise.resolve(makeNetworkError("redirect count exceeded")); } request.redirectCount += 1; if (request.mode === "cors" && (locationURL.username || locationURL.password) && !sameOrigin(request, locationURL)) { return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')); } if (request.responseTainting === "cors" && (locationURL.username || locationURL.password)) { return Promise.resolve(makeNetworkError( 'URL cannot contain credentials for request mode "cors"' )); } if (actualResponse.status !== 303 && request.body != null && request.body.source == null) { return Promise.resolve(makeNetworkError()); } if ([301, 302].includes(actualResponse.status) && request.method === "POST" || actualResponse.status === 303 && !GET_OR_HEAD.includes(request.method)) { request.method = "GET"; request.body = null; for (const headerName of requestBodyHeader) { request.headersList.delete(headerName); } } if (!sameOrigin(requestCurrentURL(request), locationURL)) { request.headersList.delete("authorization", true); request.headersList.delete("proxy-authorization", true); request.headersList.delete("cookie", true); request.headersList.delete("host", true); } if (request.body != null) { assert(request.body.source != null); request.body = safelyExtractBody(request.body.source)[0]; } const timingInfo = fetchParams.timingInfo; timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); if (timingInfo.redirectStartTime === 0) { timingInfo.redirectStartTime = timingInfo.startTime; } request.urlList.push(locationURL); setRequestReferrerPolicyOnRedirect(request, actualResponse); return mainFetch(fetchParams, true); } async function httpNetworkOrCacheFetch(fetchParams, isAuthenticationFetch = false, isNewConnectionFetch = false) { const request = fetchParams.request; let httpFetchParams = null; let httpRequest = null; let response = null; const httpCache = null; const revalidatingFlag = false; if (request.window === "no-window" && request.redirect === "error") { httpFetchParams = fetchParams; httpRequest = request; } else { httpRequest = cloneRequest(request); httpFetchParams = { ...fetchParams }; httpFetchParams.request = httpRequest; } const includeCredentials = request.credentials === "include" || request.credentials === "same-origin" && request.responseTainting === "basic"; const contentLength = httpRequest.body ? httpRequest.body.length : null; let contentLengthHeaderValue = null; if (httpRequest.body == null && ["POST", "PUT"].includes(httpRequest.method)) { contentLengthHeaderValue = "0"; } if (contentLength != null) { contentLengthHeaderValue = isomorphicEncode(`${contentLength}`); } if (contentLengthHeaderValue != null) { httpRequest.headersList.append("content-length", contentLengthHeaderValue, true); } if (contentLength != null && httpRequest.keepalive) { } if (httpRequest.referrer instanceof URL) { httpRequest.headersList.append("referer", isomorphicEncode(httpRequest.referrer.href), true); } appendRequestOriginHeader(httpRequest); appendFetchMetadata(httpRequest); if (!httpRequest.headersList.contains("user-agent", true)) { httpRequest.headersList.append("user-agent", defaultUserAgent); } if (httpRequest.cache === "default" && (httpRequest.headersList.contains("if-modified-since", true) || httpRequest.headersList.contains("if-none-match", true) || httpRequest.headersList.contains("if-unmodified-since", true) || httpRequest.headersList.contains("if-match", true) || httpRequest.headersList.contains("if-range", true))) { httpRequest.cache = "no-store"; } if (httpRequest.cache === "no-cache" && !httpRequest.preventNoCacheCacheControlHeaderModification && !httpRequest.headersList.contains("cache-control", true)) { httpRequest.headersList.append("cache-control", "max-age=0", true); } if (httpRequest.cache === "no-store" || httpRequest.cache === "reload") { if (!httpRequest.headersList.contains("pragma", true)) { httpRequest.headersList.append("pragma", "no-cache", true); } if (!httpRequest.headersList.contains("cache-control", true)) { httpRequest.headersList.append("cache-control", "no-cache", true); } } if (httpRequest.headersList.contains("range", true)) { httpRequest.headersList.append("accept-encoding", "identity", true); } if (!httpRequest.headersList.contains("accept-encoding", true)) { if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { httpRequest.headersList.append("accept-encoding", "br, gzip, deflate", true); } else { httpRequest.headersList.append("accept-encoding", "gzip, deflate", true); } } httpRequest.headersList.delete("host", true); if (includeCredentials) { } if (httpCache == null) { httpRequest.cache = "no-store"; } if (httpRequest.cache !== "no-store" && httpRequest.cache !== "reload") { } if (response == null) { if (httpRequest.cache === "only-if-cached") { return makeNetworkError("only if cached"); } const forwardResponse = await httpNetworkFetch( httpFetchParams, includeCredentials, isNewConnectionFetch ); if (!safeMethodsSet.has(httpRequest.method) && forwardResponse.status >= 200 && forwardResponse.status <= 399) { } if (revalidatingFlag && forwardResponse.status === 304) { } if (response == null) { response = forwardResponse; } } response.urlList = [...httpRequest.urlList]; if (httpRequest.headersList.contains("range", true)) { response.rangeRequested = true; } response.requestIncludesCredentials = includeCredentials; if (response.status === 407) { if (request.window === "no-window") { return makeNetworkError(); } if (isCancelled(fetchParams)) { return makeAppropriateNetworkError(fetchParams); } return makeNetworkError("proxy authentication required"); } if ( // response’s status is 421 response.status === 421 && // isNewConnectionFetch is false !isNewConnectionFetch && // request’s body is null, or request’s body is non-null and request’s body’s source is non-null (request.body == null || request.body.source != null) ) { if (isCancelled(fetchParams)) { return makeAppropriateNetworkError(fetchParams); } fetchParams.controller.connection.destroy(); response = await httpNetworkOrCacheFetch( fetchParams, isAuthenticationFetch, true ); } if (isAuthenticationFetch) { } return response; } async function httpNetworkFetch(fetchParams, includeCredentials = false, forceNewConnection = false) { assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed); fetchParams.controller.connection = { abort: null, destroyed: false, destroy(err, abort = true) { if (!this.destroyed) { this.destroyed = true; if (abort) { this.abort?.(err ?? new DOMException("The operation was aborted.", "AbortError")); } } } }; const request = fetchParams.request; let response = null; const timingInfo = fetchParams.timingInfo; const httpCache = null; if (httpCache == null) { request.cache = "no-store"; } const newConnection = forceNewConnection ? "yes" : "no"; if (request.mode === "websocket") { } else { } let requestBody = null; if (request.body == null && fetchParams.processRequestEndOfBody) { queueMicrotask(() => fetchParams.processRequestEndOfBody()); } else if (request.body != null) { const processBodyChunk = async function* (bytes2) { if (isCancelled(fetchParams)) { return; } yield bytes2; fetchParams.processRequestBodyChunkLength?.(bytes2.byteLength); }; const processEndOfBody = () => { if (isCancelled(fetchParams)) { return; } if (fetchParams.processRequestEndOfBody) { fetchParams.processRequestEndOfBody(); } }; const processBodyError = (e) => { if (isCancelled(fetchParams)) { return; } if (e.name === "AbortError") { fetchParams.controller.abort(); } else { fetchParams.controller.terminate(e); } }; requestBody = (async function* () { try { for await (const bytes2 of request.body.stream) { yield* processBodyChunk(bytes2); } processEndOfBody(); } catch (err) { processBodyError(err); } })(); } try { const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }); if (socket) { response = makeResponse({ status, statusText, headersList, socket }); } else { const iterator = body[Symbol.asyncIterator](); fetchParams.controller.next = () => iterator.next(); response = makeResponse({ status, statusText, headersList }); } } catch (err) { if (err.name === "AbortError") { fetchParams.controller.connection.destroy(); return makeAppropriateNetworkError(fetchParams, err); } return makeNetworkError(err); } const pullAlgorithm = async () => { await fetchParams.controller.resume(); }; const cancelAlgorithm = (reason) => { if (!isCancelled(fetchParams)) { fetchParams.controller.abort(reason); } }; const stream = new ReadableStream( { async start(controller) { fetchParams.controller.controller = controller; }, async pull(controller) { await pullAlgorithm(controller); }, async cancel(reason) { await cancelAlgorithm(reason); }, type: "bytes" } ); response.body = { stream, source: null, length: null }; fetchParams.controller.onAborted = onAborted; fetchParams.controller.on("terminated", onAborted); fetchParams.controller.resume = async () => { while (true) { let bytes2; let isFailure; try { const { done, value } = await fetchParams.controller.next(); if (isAborted(fetchParams)) { break; } bytes2 = done ? void 0 : value; } catch (err) { if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { bytes2 = void 0; } else { bytes2 = err; isFailure = true; } } if (bytes2 === void 0) { readableStreamClose(fetchParams.controller.controller); finalizeResponse(fetchParams, response); return; } timingInfo.decodedBodySize += bytes2?.byteLength ?? 0; if (isFailure) { fetchParams.controller.terminate(bytes2); return; } const buffer = new Uint8Array(bytes2); if (buffer.byteLength) { fetchParams.controller.controller.enqueue(buffer); } if (isErrored(stream)) { fetchParams.controller.terminate(); return; } if (fetchParams.controller.controller.desiredSize <= 0) { return; } } }; function onAborted(reason) { if (isAborted(fetchParams)) { response.aborted = true; if (isReadable(stream)) { fetchParams.controller.controller.error( fetchParams.controller.serializedAbortReason ); } } else { if (isReadable(stream)) { fetchParams.controller.controller.error(new TypeError("terminated", { cause: isErrorLike(reason) ? reason : void 0 })); } } fetchParams.controller.connection.destroy(); } return response; function dispatch({ body }) { const url = requestCurrentURL(request); const agent = fetchParams.controller.dispatcher; return new Promise((resolve, reject) => agent.dispatch( { path: url.pathname + url.search, origin: url.origin, method: request.method, body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body, headers: request.headersList.entries, maxRedirections: 0, upgrade: request.mode === "websocket" ? "websocket" : void 0 }, { body: null, abort: null, onConnect(abort) { const { connection } = fetchParams.controller; timingInfo.finalConnectionTimingInfo = clampAndCoarsenConnectionTimingInfo(void 0, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability); if (connection.destroyed) { abort(new DOMException("The operation was aborted.", "AbortError")); } else { fetchParams.controller.on("terminated", abort); this.abort = connection.abort = abort; } timingInfo.finalNetworkRequestStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); }, onResponseStarted() { timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); }, onHeaders(status, rawHeaders, resume, statusText) { if (status < 200) { return; } let location = ""; const headersList = new HeadersList(); for (let i = 0; i < rawHeaders.length; i += 2) { headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); this.body = new Readable2({ read: resume }); const decoders = []; const willFollow = location && request.redirect === "follow" && redirectStatusSet.has(status); if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { const contentEncoding = headersList.get("content-encoding", true); const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { const coding = codings[i].trim(); if (coding === "x-gzip" || coding === "gzip") { decoders.push(zlib.createGunzip({ // Be less strict when decoding compressed responses, since sometimes // servers send slightly invalid responses that are still accepted // by common browsers. // Always using Z_SYNC_FLUSH is what cURL does. flush: zlib.constants.Z_SYNC_FLUSH, finishFlush: zlib.constants.Z_SYNC_FLUSH })); } else if (coding === "deflate") { decoders.push(createInflate({ flush: zlib.constants.Z_SYNC_FLUSH, finishFlush: zlib.constants.Z_SYNC_FLUSH })); } else if (coding === "br") { decoders.push(zlib.createBrotliDecompress({ flush: zlib.constants.BROTLI_OPERATION_FLUSH, finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH })); } else { decoders.length = 0; break; } } } const onError = this.onError.bind(this); resolve({ status, statusText, headersList, body: decoders.length ? pipeline(this.body, ...decoders, (err) => { if (err) { this.onError(err); } }).on("error", onError) : this.body.on("error", onError) }); return true; }, onData(chunk) { if (fetchParams.controller.dump) { return; } const bytes2 = chunk; timingInfo.encodedBodySize += bytes2.byteLength; return this.body.push(bytes2); }, onComplete() { if (this.abort) { fetchParams.controller.off("terminated", this.abort); } if (fetchParams.controller.onAborted) { fetchParams.controller.off("terminated", fetchParams.controller.onAborted); } fetchParams.controller.ended = true; this.body.push(null); }, onError(error) { if (this.abort) { fetchParams.controller.off("terminated", this.abort); } this.body?.destroy(error); fetchParams.controller.terminate(error); reject(error); }, onUpgrade(status, rawHeaders, socket) { if (status !== 101) { return; } const headersList = new HeadersList(); for (let i = 0; i < rawHeaders.length; i += 2) { headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } resolve({ status, statusText: STATUS_CODES[status], headersList, socket }); return true; } } )); } } module.exports = { fetch: fetch3, Fetch, fetching, finalizeAndReportTiming }; } }); // viewer/node_modules/undici/lib/web/fileapi/symbols.js var require_symbols3 = __commonJS({ "viewer/node_modules/undici/lib/web/fileapi/symbols.js"(exports, module) { "use strict"; module.exports = { kState: /* @__PURE__ */ Symbol("FileReader state"), kResult: /* @__PURE__ */ Symbol("FileReader result"), kError: /* @__PURE__ */ Symbol("FileReader error"), kLastProgressEventFired: /* @__PURE__ */ Symbol("FileReader last progress event fired timestamp"), kEvents: /* @__PURE__ */ Symbol("FileReader events"), kAborted: /* @__PURE__ */ Symbol("FileReader aborted") }; } }); // viewer/node_modules/undici/lib/web/fileapi/progressevent.js var require_progressevent = __commonJS({ "viewer/node_modules/undici/lib/web/fileapi/progressevent.js"(exports, module) { "use strict"; var { webidl } = require_webidl(); var kState = /* @__PURE__ */ Symbol("ProgressEvent state"); var ProgressEvent = class _ProgressEvent extends Event { constructor(type, eventInitDict = {}) { type = webidl.converters.DOMString(type, "ProgressEvent constructor", "type"); eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}); super(type, eventInitDict); this[kState] = { lengthComputable: eventInitDict.lengthComputable, loaded: eventInitDict.loaded, total: eventInitDict.total }; } get lengthComputable() { webidl.brandCheck(this, _ProgressEvent); return this[kState].lengthComputable; } get loaded() { webidl.brandCheck(this, _ProgressEvent); return this[kState].loaded; } get total() { webidl.brandCheck(this, _ProgressEvent); return this[kState].total; } }; webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ { key: "lengthComputable", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "loaded", converter: webidl.converters["unsigned long long"], defaultValue: () => 0 }, { key: "total", converter: webidl.converters["unsigned long long"], defaultValue: () => 0 }, { key: "bubbles", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "cancelable", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "composed", converter: webidl.converters.boolean, defaultValue: () => false } ]); module.exports = { ProgressEvent }; } }); // viewer/node_modules/undici/lib/web/fileapi/encoding.js var require_encoding = __commonJS({ "viewer/node_modules/undici/lib/web/fileapi/encoding.js"(exports, module) { "use strict"; function getEncoding(label) { if (!label) { return "failure"; } switch (label.trim().toLowerCase()) { case "unicode-1-1-utf-8": case "unicode11utf8": case "unicode20utf8": case "utf-8": case "utf8": case "x-unicode20utf8": return "UTF-8"; case "866": case "cp866": case "csibm866": case "ibm866": return "IBM866"; case "csisolatin2": case "iso-8859-2": case "iso-ir-101": case "iso8859-2": case "iso88592": case "iso_8859-2": case "iso_8859-2:1987": case "l2": case "latin2": return "ISO-8859-2"; case "csisolatin3": case "iso-8859-3": case "iso-ir-109": case "iso8859-3": case "iso88593": case "iso_8859-3": case "iso_8859-3:1988": case "l3": case "latin3": return "ISO-8859-3"; case "csisolatin4": case "iso-8859-4": case "iso-ir-110": case "iso8859-4": case "iso88594": case "iso_8859-4": case "iso_8859-4:1988": case "l4": case "latin4": return "ISO-8859-4"; case "csisolatincyrillic": case "cyrillic": case "iso-8859-5": case "iso-ir-144": case "iso8859-5": case "iso88595": case "iso_8859-5": case "iso_8859-5:1988": return "ISO-8859-5"; case "arabic": case "asmo-708": case "csiso88596e": case "csiso88596i": case "csisolatinarabic": case "ecma-114": case "iso-8859-6": case "iso-8859-6-e": case "iso-8859-6-i": case "iso-ir-127": case "iso8859-6": case "iso88596": case "iso_8859-6": case "iso_8859-6:1987": return "ISO-8859-6"; case "csisolatingreek": case "ecma-118": case "elot_928": case "greek": case "greek8": case "iso-8859-7": case "iso-ir-126": case "iso8859-7": case "iso88597": case "iso_8859-7": case "iso_8859-7:1987": case "sun_eu_greek": return "ISO-8859-7"; case "csiso88598e": case "csisolatinhebrew": case "hebrew": case "iso-8859-8": case "iso-8859-8-e": case "iso-ir-138": case "iso8859-8": case "iso88598": case "iso_8859-8": case "iso_8859-8:1988": case "visual": return "ISO-8859-8"; case "csiso88598i": case "iso-8859-8-i": case "logical": return "ISO-8859-8-I"; case "csisolatin6": case "iso-8859-10": case "iso-ir-157": case "iso8859-10": case "iso885910": case "l6": case "latin6": return "ISO-8859-10"; case "iso-8859-13": case "iso8859-13": case "iso885913": return "ISO-8859-13"; case "iso-8859-14": case "iso8859-14": case "iso885914": return "ISO-8859-14"; case "csisolatin9": case "iso-8859-15": case "iso8859-15": case "iso885915": case "iso_8859-15": case "l9": return "ISO-8859-15"; case "iso-8859-16": return "ISO-8859-16"; case "cskoi8r": case "koi": case "koi8": case "koi8-r": case "koi8_r": return "KOI8-R"; case "koi8-ru": case "koi8-u": return "KOI8-U"; case "csmacintosh": case "mac": case "macintosh": case "x-mac-roman": return "macintosh"; case "iso-8859-11": case "iso8859-11": case "iso885911": case "tis-620": case "windows-874": return "windows-874"; case "cp1250": case "windows-1250": case "x-cp1250": return "windows-1250"; case "cp1251": case "windows-1251": case "x-cp1251": return "windows-1251"; case "ansi_x3.4-1968": case "ascii": case "cp1252": case "cp819": case "csisolatin1": case "ibm819": case "iso-8859-1": case "iso-ir-100": case "iso8859-1": case "iso88591": case "iso_8859-1": case "iso_8859-1:1987": case "l1": case "latin1": case "us-ascii": case "windows-1252": case "x-cp1252": return "windows-1252"; case "cp1253": case "windows-1253": case "x-cp1253": return "windows-1253"; case "cp1254": case "csisolatin5": case "iso-8859-9": case "iso-ir-148": case "iso8859-9": case "iso88599": case "iso_8859-9": case "iso_8859-9:1989": case "l5": case "latin5": case "windows-1254": case "x-cp1254": return "windows-1254"; case "cp1255": case "windows-1255": case "x-cp1255": return "windows-1255"; case "cp1256": case "windows-1256": case "x-cp1256": return "windows-1256"; case "cp1257": case "windows-1257": case "x-cp1257": return "windows-1257"; case "cp1258": case "windows-1258": case "x-cp1258": return "windows-1258"; case "x-mac-cyrillic": case "x-mac-ukrainian": return "x-mac-cyrillic"; case "chinese": case "csgb2312": case "csiso58gb231280": case "gb2312": case "gb_2312": case "gb_2312-80": case "gbk": case "iso-ir-58": case "x-gbk": return "GBK"; case "gb18030": return "gb18030"; case "big5": case "big5-hkscs": case "cn-big5": case "csbig5": case "x-x-big5": return "Big5"; case "cseucpkdfmtjapanese": case "euc-jp": case "x-euc-jp": return "EUC-JP"; case "csiso2022jp": case "iso-2022-jp": return "ISO-2022-JP"; case "csshiftjis": case "ms932": case "ms_kanji": case "shift-jis": case "shift_jis": case "sjis": case "windows-31j": case "x-sjis": return "Shift_JIS"; case "cseuckr": case "csksc56011987": case "euc-kr": case "iso-ir-149": case "korean": case "ks_c_5601-1987": case "ks_c_5601-1989": case "ksc5601": case "ksc_5601": case "windows-949": return "EUC-KR"; case "csiso2022kr": case "hz-gb-2312": case "iso-2022-cn": case "iso-2022-cn-ext": case "iso-2022-kr": case "replacement": return "replacement"; case "unicodefffe": case "utf-16be": return "UTF-16BE"; case "csunicode": case "iso-10646-ucs-2": case "ucs-2": case "unicode": case "unicodefeff": case "utf-16": case "utf-16le": return "UTF-16LE"; case "x-user-defined": return "x-user-defined"; default: return "failure"; } } module.exports = { getEncoding }; } }); // viewer/node_modules/undici/lib/web/fileapi/util.js var require_util4 = __commonJS({ "viewer/node_modules/undici/lib/web/fileapi/util.js"(exports, module) { "use strict"; var { kState, kError, kResult, kAborted, kLastProgressEventFired } = require_symbols3(); var { ProgressEvent } = require_progressevent(); var { getEncoding } = require_encoding(); var { serializeAMimeType, parseMIMEType } = require_data_url(); var { types } = __require("node:util"); var { StringDecoder } = __require("string_decoder"); var { btoa: btoa2 } = __require("node:buffer"); var staticPropertyDescriptors = { enumerable: true, writable: false, configurable: false }; function readOperation(fr, blob, type, encodingName) { if (fr[kState] === "loading") { throw new DOMException("Invalid state", "InvalidStateError"); } fr[kState] = "loading"; fr[kResult] = null; fr[kError] = null; const stream = blob.stream(); const reader = stream.getReader(); const bytes2 = []; let chunkPromise = reader.read(); let isFirstChunk = true; (async () => { while (!fr[kAborted]) { try { const { done, value } = await chunkPromise; if (isFirstChunk && !fr[kAborted]) { queueMicrotask(() => { fireAProgressEvent("loadstart", fr); }); } isFirstChunk = false; if (!done && types.isUint8Array(value)) { bytes2.push(value); if ((fr[kLastProgressEventFired] === void 0 || Date.now() - fr[kLastProgressEventFired] >= 50) && !fr[kAborted]) { fr[kLastProgressEventFired] = Date.now(); queueMicrotask(() => { fireAProgressEvent("progress", fr); }); } chunkPromise = reader.read(); } else if (done) { queueMicrotask(() => { fr[kState] = "done"; try { const result = packageData(bytes2, type, blob.type, encodingName); if (fr[kAborted]) { return; } fr[kResult] = result; fireAProgressEvent("load", fr); } catch (error) { fr[kError] = error; fireAProgressEvent("error", fr); } if (fr[kState] !== "loading") { fireAProgressEvent("loadend", fr); } }); break; } } catch (error) { if (fr[kAborted]) { return; } queueMicrotask(() => { fr[kState] = "done"; fr[kError] = error; fireAProgressEvent("error", fr); if (fr[kState] !== "loading") { fireAProgressEvent("loadend", fr); } }); break; } } })(); } function fireAProgressEvent(e, reader) { const event = new ProgressEvent(e, { bubbles: false, cancelable: false }); reader.dispatchEvent(event); } function packageData(bytes2, type, mimeType, encodingName) { switch (type) { case "DataURL": { let dataURL = "data:"; const parsed = parseMIMEType(mimeType || "application/octet-stream"); if (parsed !== "failure") { dataURL += serializeAMimeType(parsed); } dataURL += ";base64,"; const decoder = new StringDecoder("latin1"); for (const chunk of bytes2) { dataURL += btoa2(decoder.write(chunk)); } dataURL += btoa2(decoder.end()); return dataURL; } case "Text": { let encoding = "failure"; if (encodingName) { encoding = getEncoding(encodingName); } if (encoding === "failure" && mimeType) { const type2 = parseMIMEType(mimeType); if (type2 !== "failure") { encoding = getEncoding(type2.parameters.get("charset")); } } if (encoding === "failure") { encoding = "UTF-8"; } return decode(bytes2, encoding); } case "ArrayBuffer": { const sequence = combineByteSequences(bytes2); return sequence.buffer; } case "BinaryString": { let binaryString = ""; const decoder = new StringDecoder("latin1"); for (const chunk of bytes2) { binaryString += decoder.write(chunk); } binaryString += decoder.end(); return binaryString; } } } function decode(ioQueue, encoding) { const bytes2 = combineByteSequences(ioQueue); const BOMEncoding = BOMSniffing(bytes2); let slice = 0; if (BOMEncoding !== null) { encoding = BOMEncoding; slice = BOMEncoding === "UTF-8" ? 3 : 2; } const sliced = bytes2.slice(slice); return new TextDecoder(encoding).decode(sliced); } function BOMSniffing(ioQueue) { const [a, b, c] = ioQueue; if (a === 239 && b === 187 && c === 191) { return "UTF-8"; } else if (a === 254 && b === 255) { return "UTF-16BE"; } else if (a === 255 && b === 254) { return "UTF-16LE"; } return null; } function combineByteSequences(sequences) { const size = sequences.reduce((a, b) => { return a + b.byteLength; }, 0); let offset = 0; return sequences.reduce((a, b) => { a.set(b, offset); offset += b.byteLength; return a; }, new Uint8Array(size)); } module.exports = { staticPropertyDescriptors, readOperation, fireAProgressEvent }; } }); // viewer/node_modules/undici/lib/web/fileapi/filereader.js var require_filereader = __commonJS({ "viewer/node_modules/undici/lib/web/fileapi/filereader.js"(exports, module) { "use strict"; var { staticPropertyDescriptors, readOperation, fireAProgressEvent } = require_util4(); var { kState, kError, kResult, kEvents, kAborted } = require_symbols3(); var { webidl } = require_webidl(); var { kEnumerableProperty } = require_util(); var FileReader = class _FileReader extends EventTarget { constructor() { super(); this[kState] = "empty"; this[kResult] = null; this[kError] = null; this[kEvents] = { loadend: null, error: null, abort: null, load: null, progress: null, loadstart: null }; } /** * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer * @param {import('buffer').Blob} blob */ readAsArrayBuffer(blob) { webidl.brandCheck(this, _FileReader); webidl.argumentLengthCheck(arguments, 1, "FileReader.readAsArrayBuffer"); blob = webidl.converters.Blob(blob, { strict: false }); readOperation(this, blob, "ArrayBuffer"); } /** * @see https://w3c.github.io/FileAPI/#readAsBinaryString * @param {import('buffer').Blob} blob */ readAsBinaryString(blob) { webidl.brandCheck(this, _FileReader); webidl.argumentLengthCheck(arguments, 1, "FileReader.readAsBinaryString"); blob = webidl.converters.Blob(blob, { strict: false }); readOperation(this, blob, "BinaryString"); } /** * @see https://w3c.github.io/FileAPI/#readAsDataText * @param {import('buffer').Blob} blob * @param {string?} encoding */ readAsText(blob, encoding = void 0) { webidl.brandCheck(this, _FileReader); webidl.argumentLengthCheck(arguments, 1, "FileReader.readAsText"); blob = webidl.converters.Blob(blob, { strict: false }); if (encoding !== void 0) { encoding = webidl.converters.DOMString(encoding, "FileReader.readAsText", "encoding"); } readOperation(this, blob, "Text", encoding); } /** * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL * @param {import('buffer').Blob} blob */ readAsDataURL(blob) { webidl.brandCheck(this, _FileReader); webidl.argumentLengthCheck(arguments, 1, "FileReader.readAsDataURL"); blob = webidl.converters.Blob(blob, { strict: false }); readOperation(this, blob, "DataURL"); } /** * @see https://w3c.github.io/FileAPI/#dfn-abort */ abort() { if (this[kState] === "empty" || this[kState] === "done") { this[kResult] = null; return; } if (this[kState] === "loading") { this[kState] = "done"; this[kResult] = null; } this[kAborted] = true; fireAProgressEvent("abort", this); if (this[kState] !== "loading") { fireAProgressEvent("loadend", this); } } /** * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate */ get readyState() { webidl.brandCheck(this, _FileReader); switch (this[kState]) { case "empty": return this.EMPTY; case "loading": return this.LOADING; case "done": return this.DONE; } } /** * @see https://w3c.github.io/FileAPI/#dom-filereader-result */ get result() { webidl.brandCheck(this, _FileReader); return this[kResult]; } /** * @see https://w3c.github.io/FileAPI/#dom-filereader-error */ get error() { webidl.brandCheck(this, _FileReader); return this[kError]; } get onloadend() { webidl.brandCheck(this, _FileReader); return this[kEvents].loadend; } set onloadend(fn) { webidl.brandCheck(this, _FileReader); if (this[kEvents].loadend) { this.removeEventListener("loadend", this[kEvents].loadend); } if (typeof fn === "function") { this[kEvents].loadend = fn; this.addEventListener("loadend", fn); } else { this[kEvents].loadend = null; } } get onerror() { webidl.brandCheck(this, _FileReader); return this[kEvents].error; } set onerror(fn) { webidl.brandCheck(this, _FileReader); if (this[kEvents].error) { this.removeEventListener("error", this[kEvents].error); } if (typeof fn === "function") { this[kEvents].error = fn; this.addEventListener("error", fn); } else { this[kEvents].error = null; } } get onloadstart() { webidl.brandCheck(this, _FileReader); return this[kEvents].loadstart; } set onloadstart(fn) { webidl.brandCheck(this, _FileReader); if (this[kEvents].loadstart) { this.removeEventListener("loadstart", this[kEvents].loadstart); } if (typeof fn === "function") { this[kEvents].loadstart = fn; this.addEventListener("loadstart", fn); } else { this[kEvents].loadstart = null; } } get onprogress() { webidl.brandCheck(this, _FileReader); return this[kEvents].progress; } set onprogress(fn) { webidl.brandCheck(this, _FileReader); if (this[kEvents].progress) { this.removeEventListener("progress", this[kEvents].progress); } if (typeof fn === "function") { this[kEvents].progress = fn; this.addEventListener("progress", fn); } else { this[kEvents].progress = null; } } get onload() { webidl.brandCheck(this, _FileReader); return this[kEvents].load; } set onload(fn) { webidl.brandCheck(this, _FileReader); if (this[kEvents].load) { this.removeEventListener("load", this[kEvents].load); } if (typeof fn === "function") { this[kEvents].load = fn; this.addEventListener("load", fn); } else { this[kEvents].load = null; } } get onabort() { webidl.brandCheck(this, _FileReader); return this[kEvents].abort; } set onabort(fn) { webidl.brandCheck(this, _FileReader); if (this[kEvents].abort) { this.removeEventListener("abort", this[kEvents].abort); } if (typeof fn === "function") { this[kEvents].abort = fn; this.addEventListener("abort", fn); } else { this[kEvents].abort = null; } } }; FileReader.EMPTY = FileReader.prototype.EMPTY = 0; FileReader.LOADING = FileReader.prototype.LOADING = 1; FileReader.DONE = FileReader.prototype.DONE = 2; Object.defineProperties(FileReader.prototype, { EMPTY: staticPropertyDescriptors, LOADING: staticPropertyDescriptors, DONE: staticPropertyDescriptors, readAsArrayBuffer: kEnumerableProperty, readAsBinaryString: kEnumerableProperty, readAsText: kEnumerableProperty, readAsDataURL: kEnumerableProperty, abort: kEnumerableProperty, readyState: kEnumerableProperty, result: kEnumerableProperty, error: kEnumerableProperty, onloadstart: kEnumerableProperty, onprogress: kEnumerableProperty, onload: kEnumerableProperty, onabort: kEnumerableProperty, onerror: kEnumerableProperty, onloadend: kEnumerableProperty, [Symbol.toStringTag]: { value: "FileReader", writable: false, enumerable: false, configurable: true } }); Object.defineProperties(FileReader, { EMPTY: staticPropertyDescriptors, LOADING: staticPropertyDescriptors, DONE: staticPropertyDescriptors }); module.exports = { FileReader }; } }); // viewer/node_modules/undici/lib/web/cache/symbols.js var require_symbols4 = __commonJS({ "viewer/node_modules/undici/lib/web/cache/symbols.js"(exports, module) { "use strict"; module.exports = { kConstruct: require_symbols().kConstruct }; } }); // viewer/node_modules/undici/lib/web/cache/util.js var require_util5 = __commonJS({ "viewer/node_modules/undici/lib/web/cache/util.js"(exports, module) { "use strict"; var assert = __require("node:assert"); var { URLSerializer } = require_data_url(); var { isValidHeaderName } = require_util2(); function urlEquals(A, B, excludeFragment = false) { const serializedA = URLSerializer(A, excludeFragment); const serializedB = URLSerializer(B, excludeFragment); return serializedA === serializedB; } function getFieldValues(header) { assert(header !== null); const values = []; for (let value of header.split(",")) { value = value.trim(); if (isValidHeaderName(value)) { values.push(value); } } return values; } module.exports = { urlEquals, getFieldValues }; } }); // viewer/node_modules/undici/lib/web/cache/cache.js var require_cache = __commonJS({ "viewer/node_modules/undici/lib/web/cache/cache.js"(exports, module) { "use strict"; var { kConstruct } = require_symbols4(); var { urlEquals, getFieldValues } = require_util5(); var { kEnumerableProperty, isDisturbed } = require_util(); var { webidl } = require_webidl(); var { Response: Response2, cloneResponse, fromInnerResponse } = require_response(); var { Request: Request2, fromInnerRequest } = require_request2(); var { kState } = require_symbols2(); var { fetching } = require_fetch(); var { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = require_util2(); var assert = __require("node:assert"); var Cache = class _Cache { /** * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list * @type {requestResponseList} */ #relevantRequestResponseList; constructor() { if (arguments[0] !== kConstruct) { webidl.illegalConstructor(); } webidl.util.markAsUncloneable(this); this.#relevantRequestResponseList = arguments[1]; } async match(request, options = {}) { webidl.brandCheck(this, _Cache); const prefix = "Cache.match"; webidl.argumentLengthCheck(arguments, 1, prefix); request = webidl.converters.RequestInfo(request, prefix, "request"); options = webidl.converters.CacheQueryOptions(options, prefix, "options"); const p = this.#internalMatchAll(request, options, 1); if (p.length === 0) { return; } return p[0]; } async matchAll(request = void 0, options = {}) { webidl.brandCheck(this, _Cache); const prefix = "Cache.matchAll"; if (request !== void 0) request = webidl.converters.RequestInfo(request, prefix, "request"); options = webidl.converters.CacheQueryOptions(options, prefix, "options"); return this.#internalMatchAll(request, options); } async add(request) { webidl.brandCheck(this, _Cache); const prefix = "Cache.add"; webidl.argumentLengthCheck(arguments, 1, prefix); request = webidl.converters.RequestInfo(request, prefix, "request"); const requests = [request]; const responseArrayPromise = this.addAll(requests); return await responseArrayPromise; } async addAll(requests) { webidl.brandCheck(this, _Cache); const prefix = "Cache.addAll"; webidl.argumentLengthCheck(arguments, 1, prefix); const responsePromises = []; const requestList = []; for (let request of requests) { if (request === void 0) { throw webidl.errors.conversionFailed({ prefix, argument: "Argument 1", types: ["undefined is not allowed"] }); } request = webidl.converters.RequestInfo(request); if (typeof request === "string") { continue; } const r = request[kState]; if (!urlIsHttpHttpsScheme(r.url) || r.method !== "GET") { throw webidl.errors.exception({ header: prefix, message: "Expected http/s scheme when method is not GET." }); } } const fetchControllers = []; for (const request of requests) { const r = new Request2(request)[kState]; if (!urlIsHttpHttpsScheme(r.url)) { throw webidl.errors.exception({ header: prefix, message: "Expected http/s scheme." }); } r.initiator = "fetch"; r.destination = "subresource"; requestList.push(r); const responsePromise = createDeferredPromise(); fetchControllers.push(fetching({ request: r, processResponse(response) { if (response.type === "error" || response.status === 206 || response.status < 200 || response.status > 299) { responsePromise.reject(webidl.errors.exception({ header: "Cache.addAll", message: "Received an invalid status code or the request failed." })); } else if (response.headersList.contains("vary")) { const fieldValues = getFieldValues(response.headersList.get("vary")); for (const fieldValue of fieldValues) { if (fieldValue === "*") { responsePromise.reject(webidl.errors.exception({ header: "Cache.addAll", message: "invalid vary field value" })); for (const controller of fetchControllers) { controller.abort(); } return; } } } }, processResponseEndOfBody(response) { if (response.aborted) { responsePromise.reject(new DOMException("aborted", "AbortError")); return; } responsePromise.resolve(response); } })); responsePromises.push(responsePromise.promise); } const p = Promise.all(responsePromises); const responses = await p; const operations = []; let index = 0; for (const response of responses) { const operation = { type: "put", // 7.3.2 request: requestList[index], // 7.3.3 response // 7.3.4 }; operations.push(operation); index++; } const cacheJobPromise = createDeferredPromise(); let errorData = null; try { this.#batchCacheOperations(operations); } catch (e) { errorData = e; } queueMicrotask(() => { if (errorData === null) { cacheJobPromise.resolve(void 0); } else { cacheJobPromise.reject(errorData); } }); return cacheJobPromise.promise; } async put(request, response) { webidl.brandCheck(this, _Cache); const prefix = "Cache.put"; webidl.argumentLengthCheck(arguments, 2, prefix); request = webidl.converters.RequestInfo(request, prefix, "request"); response = webidl.converters.Response(response, prefix, "response"); let innerRequest = null; if (request instanceof Request2) { innerRequest = request[kState]; } else { innerRequest = new Request2(request)[kState]; } if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== "GET") { throw webidl.errors.exception({ header: prefix, message: "Expected an http/s scheme when method is not GET" }); } const innerResponse = response[kState]; if (innerResponse.status === 206) { throw webidl.errors.exception({ header: prefix, message: "Got 206 status" }); } if (innerResponse.headersList.contains("vary")) { const fieldValues = getFieldValues(innerResponse.headersList.get("vary")); for (const fieldValue of fieldValues) { if (fieldValue === "*") { throw webidl.errors.exception({ header: prefix, message: "Got * vary field value" }); } } } if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { throw webidl.errors.exception({ header: prefix, message: "Response body is locked or disturbed" }); } const clonedResponse = cloneResponse(innerResponse); const bodyReadPromise = createDeferredPromise(); if (innerResponse.body != null) { const stream = innerResponse.body.stream; const reader = stream.getReader(); readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject); } else { bodyReadPromise.resolve(void 0); } const operations = []; const operation = { type: "put", // 14. request: innerRequest, // 15. response: clonedResponse // 16. }; operations.push(operation); const bytes2 = await bodyReadPromise.promise; if (clonedResponse.body != null) { clonedResponse.body.source = bytes2; } const cacheJobPromise = createDeferredPromise(); let errorData = null; try { this.#batchCacheOperations(operations); } catch (e) { errorData = e; } queueMicrotask(() => { if (errorData === null) { cacheJobPromise.resolve(); } else { cacheJobPromise.reject(errorData); } }); return cacheJobPromise.promise; } async delete(request, options = {}) { webidl.brandCheck(this, _Cache); const prefix = "Cache.delete"; webidl.argumentLengthCheck(arguments, 1, prefix); request = webidl.converters.RequestInfo(request, prefix, "request"); options = webidl.converters.CacheQueryOptions(options, prefix, "options"); let r = null; if (request instanceof Request2) { r = request[kState]; if (r.method !== "GET" && !options.ignoreMethod) { return false; } } else { assert(typeof request === "string"); r = new Request2(request)[kState]; } const operations = []; const operation = { type: "delete", request: r, options }; operations.push(operation); const cacheJobPromise = createDeferredPromise(); let errorData = null; let requestResponses; try { requestResponses = this.#batchCacheOperations(operations); } catch (e) { errorData = e; } queueMicrotask(() => { if (errorData === null) { cacheJobPromise.resolve(!!requestResponses?.length); } else { cacheJobPromise.reject(errorData); } }); return cacheJobPromise.promise; } /** * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys * @param {any} request * @param {import('../../types/cache').CacheQueryOptions} options * @returns {Promise} */ async keys(request = void 0, options = {}) { webidl.brandCheck(this, _Cache); const prefix = "Cache.keys"; if (request !== void 0) request = webidl.converters.RequestInfo(request, prefix, "request"); options = webidl.converters.CacheQueryOptions(options, prefix, "options"); let r = null; if (request !== void 0) { if (request instanceof Request2) { r = request[kState]; if (r.method !== "GET" && !options.ignoreMethod) { return []; } } else if (typeof request === "string") { r = new Request2(request)[kState]; } } const promise = createDeferredPromise(); const requests = []; if (request === void 0) { for (const requestResponse of this.#relevantRequestResponseList) { requests.push(requestResponse[0]); } } else { const requestResponses = this.#queryCache(r, options); for (const requestResponse of requestResponses) { requests.push(requestResponse[0]); } } queueMicrotask(() => { const requestList = []; for (const request2 of requests) { const requestObject = fromInnerRequest( request2, new AbortController().signal, "immutable" ); requestList.push(requestObject); } promise.resolve(Object.freeze(requestList)); }); return promise.promise; } /** * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm * @param {CacheBatchOperation[]} operations * @returns {requestResponseList} */ #batchCacheOperations(operations) { const cache = this.#relevantRequestResponseList; const backupCache = [...cache]; const addedItems = []; const resultList = []; try { for (const operation of operations) { if (operation.type !== "delete" && operation.type !== "put") { throw webidl.errors.exception({ header: "Cache.#batchCacheOperations", message: 'operation type does not match "delete" or "put"' }); } if (operation.type === "delete" && operation.response != null) { throw webidl.errors.exception({ header: "Cache.#batchCacheOperations", message: "delete operation should not have an associated response" }); } if (this.#queryCache(operation.request, operation.options, addedItems).length) { throw new DOMException("???", "InvalidStateError"); } let requestResponses; if (operation.type === "delete") { requestResponses = this.#queryCache(operation.request, operation.options); if (requestResponses.length === 0) { return []; } for (const requestResponse of requestResponses) { const idx = cache.indexOf(requestResponse); assert(idx !== -1); cache.splice(idx, 1); } } else if (operation.type === "put") { if (operation.response == null) { throw webidl.errors.exception({ header: "Cache.#batchCacheOperations", message: "put operation should have an associated response" }); } const r = operation.request; if (!urlIsHttpHttpsScheme(r.url)) { throw webidl.errors.exception({ header: "Cache.#batchCacheOperations", message: "expected http or https scheme" }); } if (r.method !== "GET") { throw webidl.errors.exception({ header: "Cache.#batchCacheOperations", message: "not get method" }); } if (operation.options != null) { throw webidl.errors.exception({ header: "Cache.#batchCacheOperations", message: "options must not be defined" }); } requestResponses = this.#queryCache(operation.request); for (const requestResponse of requestResponses) { const idx = cache.indexOf(requestResponse); assert(idx !== -1); cache.splice(idx, 1); } cache.push([operation.request, operation.response]); addedItems.push([operation.request, operation.response]); } resultList.push([operation.request, operation.response]); } return resultList; } catch (e) { this.#relevantRequestResponseList.length = 0; this.#relevantRequestResponseList = backupCache; throw e; } } /** * @see https://w3c.github.io/ServiceWorker/#query-cache * @param {any} requestQuery * @param {import('../../types/cache').CacheQueryOptions} options * @param {requestResponseList} targetStorage * @returns {requestResponseList} */ #queryCache(requestQuery, options, targetStorage) { const resultList = []; const storage = targetStorage ?? this.#relevantRequestResponseList; for (const requestResponse of storage) { const [cachedRequest, cachedResponse] = requestResponse; if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { resultList.push(requestResponse); } } return resultList; } /** * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm * @param {any} requestQuery * @param {any} request * @param {any | null} response * @param {import('../../types/cache').CacheQueryOptions | undefined} options * @returns {boolean} */ #requestMatchesCachedItem(requestQuery, request, response = null, options) { const queryURL = new URL(requestQuery.url); const cachedURL = new URL(request.url); if (options?.ignoreSearch) { cachedURL.search = ""; queryURL.search = ""; } if (!urlEquals(queryURL, cachedURL, true)) { return false; } if (response == null || options?.ignoreVary || !response.headersList.contains("vary")) { return true; } const fieldValues = getFieldValues(response.headersList.get("vary")); for (const fieldValue of fieldValues) { if (fieldValue === "*") { return false; } const requestValue = request.headersList.get(fieldValue); const queryValue = requestQuery.headersList.get(fieldValue); if (requestValue !== queryValue) { return false; } } return true; } #internalMatchAll(request, options, maxResponses = Infinity) { let r = null; if (request !== void 0) { if (request instanceof Request2) { r = request[kState]; if (r.method !== "GET" && !options.ignoreMethod) { return []; } } else if (typeof request === "string") { r = new Request2(request)[kState]; } } const responses = []; if (request === void 0) { for (const requestResponse of this.#relevantRequestResponseList) { responses.push(requestResponse[1]); } } else { const requestResponses = this.#queryCache(r, options); for (const requestResponse of requestResponses) { responses.push(requestResponse[1]); } } const responseList = []; for (const response of responses) { const responseObject = fromInnerResponse(response, "immutable"); responseList.push(responseObject.clone()); if (responseList.length >= maxResponses) { break; } } return Object.freeze(responseList); } }; Object.defineProperties(Cache.prototype, { [Symbol.toStringTag]: { value: "Cache", configurable: true }, match: kEnumerableProperty, matchAll: kEnumerableProperty, add: kEnumerableProperty, addAll: kEnumerableProperty, put: kEnumerableProperty, delete: kEnumerableProperty, keys: kEnumerableProperty }); var cacheQueryOptionConverters = [ { key: "ignoreSearch", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "ignoreMethod", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "ignoreVary", converter: webidl.converters.boolean, defaultValue: () => false } ]; webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters); webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ ...cacheQueryOptionConverters, { key: "cacheName", converter: webidl.converters.DOMString } ]); webidl.converters.Response = webidl.interfaceConverter(Response2); webidl.converters["sequence"] = webidl.sequenceConverter( webidl.converters.RequestInfo ); module.exports = { Cache }; } }); // viewer/node_modules/undici/lib/web/cache/cachestorage.js var require_cachestorage = __commonJS({ "viewer/node_modules/undici/lib/web/cache/cachestorage.js"(exports, module) { "use strict"; var { kConstruct } = require_symbols4(); var { Cache } = require_cache(); var { webidl } = require_webidl(); var { kEnumerableProperty } = require_util(); var CacheStorage = class _CacheStorage { /** * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map * @type {Map} */ async has(cacheName) { webidl.brandCheck(this, _CacheStorage); const prefix = "CacheStorage.has"; webidl.argumentLengthCheck(arguments, 1, prefix); cacheName = webidl.converters.DOMString(cacheName, prefix, "cacheName"); return this.#caches.has(cacheName); } /** * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open * @param {string} cacheName * @returns {Promise} */ async open(cacheName) { webidl.brandCheck(this, _CacheStorage); const prefix = "CacheStorage.open"; webidl.argumentLengthCheck(arguments, 1, prefix); cacheName = webidl.converters.DOMString(cacheName, prefix, "cacheName"); if (this.#caches.has(cacheName)) { const cache2 = this.#caches.get(cacheName); return new Cache(kConstruct, cache2); } const cache = []; this.#caches.set(cacheName, cache); return new Cache(kConstruct, cache); } /** * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete * @param {string} cacheName * @returns {Promise} */ async delete(cacheName) { webidl.brandCheck(this, _CacheStorage); const prefix = "CacheStorage.delete"; webidl.argumentLengthCheck(arguments, 1, prefix); cacheName = webidl.converters.DOMString(cacheName, prefix, "cacheName"); return this.#caches.delete(cacheName); } /** * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys * @returns {Promise} */ async keys() { webidl.brandCheck(this, _CacheStorage); const keys = this.#caches.keys(); return [...keys]; } }; Object.defineProperties(CacheStorage.prototype, { [Symbol.toStringTag]: { value: "CacheStorage", configurable: true }, match: kEnumerableProperty, has: kEnumerableProperty, open: kEnumerableProperty, delete: kEnumerableProperty, keys: kEnumerableProperty }); module.exports = { CacheStorage }; } }); // viewer/node_modules/undici/lib/web/cookies/constants.js var require_constants4 = __commonJS({ "viewer/node_modules/undici/lib/web/cookies/constants.js"(exports, module) { "use strict"; var maxAttributeValueSize = 1024; var maxNameValuePairSize = 4096; module.exports = { maxAttributeValueSize, maxNameValuePairSize }; } }); // viewer/node_modules/undici/lib/web/cookies/util.js var require_util6 = __commonJS({ "viewer/node_modules/undici/lib/web/cookies/util.js"(exports, module) { "use strict"; function isCTLExcludingHtab(value) { for (let i = 0; i < value.length; ++i) { const code = value.charCodeAt(i); if (code >= 0 && code <= 8 || code >= 10 && code <= 31 || code === 127) { return true; } } return false; } function validateCookieName(name) { for (let i = 0; i < name.length; ++i) { const code = name.charCodeAt(i); if (code < 33 || // exclude CTLs (0-31), SP and HT code > 126 || // exclude non-ascii and DEL code === 34 || // " code === 40 || // ( code === 41 || // ) code === 60 || // < code === 62 || // > code === 64 || // @ code === 44 || // , code === 59 || // ; code === 58 || // : code === 92 || // \ code === 47 || // / code === 91 || // [ code === 93 || // ] code === 63 || // ? code === 61 || // = code === 123 || // { code === 125) { throw new Error("Invalid cookie name"); } } } function validateCookieValue(value) { let len = value.length; let i = 0; if (value[0] === '"') { if (len === 1 || value[len - 1] !== '"') { throw new Error("Invalid cookie value"); } --len; ++i; } while (i < len) { const code = value.charCodeAt(i++); if (code < 33 || // exclude CTLs (0-31) code > 126 || // non-ascii and DEL (127) code === 34 || // " code === 44 || // , code === 59 || // ; code === 92) { throw new Error("Invalid cookie value"); } } } function validateCookiePath(path14) { for (let i = 0; i < path14.length; ++i) { const code = path14.charCodeAt(i); if (code < 32 || // exclude CTLs (0-31) code === 127 || // DEL code === 59) { throw new Error("Invalid cookie path"); } } } function validateCookieDomain(domain) { if (domain.startsWith("-") || domain.endsWith(".") || domain.endsWith("-")) { throw new Error("Invalid cookie domain"); } } var IMFDays = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ]; var IMFMonths = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; var IMFPaddedNumbers = Array(61).fill(0).map((_, i) => i.toString().padStart(2, "0")); function toIMFDate(date) { if (typeof date === "number") { date = new Date(date); } return `${IMFDays[date.getUTCDay()]}, ${IMFPaddedNumbers[date.getUTCDate()]} ${IMFMonths[date.getUTCMonth()]} ${date.getUTCFullYear()} ${IMFPaddedNumbers[date.getUTCHours()]}:${IMFPaddedNumbers[date.getUTCMinutes()]}:${IMFPaddedNumbers[date.getUTCSeconds()]} GMT`; } function validateCookieMaxAge(maxAge) { if (maxAge < 0) { throw new Error("Invalid cookie max-age"); } } function stringify(cookie) { if (cookie.name.length === 0) { return null; } validateCookieName(cookie.name); validateCookieValue(cookie.value); const out = [`${cookie.name}=${cookie.value}`]; if (cookie.name.startsWith("__Secure-")) { cookie.secure = true; } if (cookie.name.startsWith("__Host-")) { cookie.secure = true; cookie.domain = null; cookie.path = "/"; } if (cookie.secure) { out.push("Secure"); } if (cookie.httpOnly) { out.push("HttpOnly"); } if (typeof cookie.maxAge === "number") { validateCookieMaxAge(cookie.maxAge); out.push(`Max-Age=${cookie.maxAge}`); } if (cookie.domain) { validateCookieDomain(cookie.domain); out.push(`Domain=${cookie.domain}`); } if (cookie.path) { validateCookiePath(cookie.path); out.push(`Path=${cookie.path}`); } if (cookie.expires && cookie.expires.toString() !== "Invalid Date") { out.push(`Expires=${toIMFDate(cookie.expires)}`); } if (cookie.sameSite) { out.push(`SameSite=${cookie.sameSite}`); } for (const part of cookie.unparsed) { if (!part.includes("=")) { throw new Error("Invalid unparsed"); } const [key, ...value] = part.split("="); out.push(`${key.trim()}=${value.join("=")}`); } return out.join("; "); } module.exports = { isCTLExcludingHtab, validateCookieName, validateCookiePath, validateCookieValue, toIMFDate, stringify }; } }); // viewer/node_modules/undici/lib/web/cookies/parse.js var require_parse = __commonJS({ "viewer/node_modules/undici/lib/web/cookies/parse.js"(exports, module) { "use strict"; var { maxNameValuePairSize, maxAttributeValueSize } = require_constants4(); var { isCTLExcludingHtab } = require_util6(); var { collectASequenceOfCodePointsFast } = require_data_url(); var assert = __require("node:assert"); function parseSetCookie(header) { if (isCTLExcludingHtab(header)) { return null; } let nameValuePair = ""; let unparsedAttributes = ""; let name = ""; let value = ""; if (header.includes(";")) { const position = { position: 0 }; nameValuePair = collectASequenceOfCodePointsFast(";", header, position); unparsedAttributes = header.slice(position.position); } else { nameValuePair = header; } if (!nameValuePair.includes("=")) { value = nameValuePair; } else { const position = { position: 0 }; name = collectASequenceOfCodePointsFast( "=", nameValuePair, position ); value = nameValuePair.slice(position.position + 1); } name = name.trim(); value = value.trim(); if (name.length + value.length > maxNameValuePairSize) { return null; } return { name, value, ...parseUnparsedAttributes(unparsedAttributes) }; } function parseUnparsedAttributes(unparsedAttributes, cookieAttributeList = {}) { if (unparsedAttributes.length === 0) { return cookieAttributeList; } assert(unparsedAttributes[0] === ";"); unparsedAttributes = unparsedAttributes.slice(1); let cookieAv = ""; if (unparsedAttributes.includes(";")) { cookieAv = collectASequenceOfCodePointsFast( ";", unparsedAttributes, { position: 0 } ); unparsedAttributes = unparsedAttributes.slice(cookieAv.length); } else { cookieAv = unparsedAttributes; unparsedAttributes = ""; } let attributeName = ""; let attributeValue = ""; if (cookieAv.includes("=")) { const position = { position: 0 }; attributeName = collectASequenceOfCodePointsFast( "=", cookieAv, position ); attributeValue = cookieAv.slice(position.position + 1); } else { attributeName = cookieAv; } attributeName = attributeName.trim(); attributeValue = attributeValue.trim(); if (attributeValue.length > maxAttributeValueSize) { return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); } const attributeNameLowercase = attributeName.toLowerCase(); if (attributeNameLowercase === "expires") { const expiryTime = new Date(attributeValue); cookieAttributeList.expires = expiryTime; } else if (attributeNameLowercase === "max-age") { const charCode = attributeValue.charCodeAt(0); if ((charCode < 48 || charCode > 57) && attributeValue[0] !== "-") { return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); } if (!/^\d+$/.test(attributeValue)) { return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); } const deltaSeconds = Number(attributeValue); cookieAttributeList.maxAge = deltaSeconds; } else if (attributeNameLowercase === "domain") { let cookieDomain = attributeValue; if (cookieDomain[0] === ".") { cookieDomain = cookieDomain.slice(1); } cookieDomain = cookieDomain.toLowerCase(); cookieAttributeList.domain = cookieDomain; } else if (attributeNameLowercase === "path") { let cookiePath = ""; if (attributeValue.length === 0 || attributeValue[0] !== "/") { cookiePath = "/"; } else { cookiePath = attributeValue; } cookieAttributeList.path = cookiePath; } else if (attributeNameLowercase === "secure") { cookieAttributeList.secure = true; } else if (attributeNameLowercase === "httponly") { cookieAttributeList.httpOnly = true; } else if (attributeNameLowercase === "samesite") { let enforcement = "Default"; const attributeValueLowercase = attributeValue.toLowerCase(); if (attributeValueLowercase.includes("none")) { enforcement = "None"; } if (attributeValueLowercase.includes("strict")) { enforcement = "Strict"; } if (attributeValueLowercase.includes("lax")) { enforcement = "Lax"; } cookieAttributeList.sameSite = enforcement; } else { cookieAttributeList.unparsed ??= []; cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`); } return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList); } module.exports = { parseSetCookie, parseUnparsedAttributes }; } }); // viewer/node_modules/undici/lib/web/cookies/index.js var require_cookies = __commonJS({ "viewer/node_modules/undici/lib/web/cookies/index.js"(exports, module) { "use strict"; var { parseSetCookie } = require_parse(); var { stringify } = require_util6(); var { webidl } = require_webidl(); var { Headers: Headers2 } = require_headers(); function getCookies(headers) { webidl.argumentLengthCheck(arguments, 1, "getCookies"); webidl.brandCheck(headers, Headers2, { strict: false }); const cookie = headers.get("cookie"); const out = {}; if (!cookie) { return out; } for (const piece of cookie.split(";")) { const [name, ...value] = piece.split("="); out[name.trim()] = value.join("="); } return out; } function deleteCookie(headers, name, attributes) { webidl.brandCheck(headers, Headers2, { strict: false }); const prefix = "deleteCookie"; webidl.argumentLengthCheck(arguments, 2, prefix); name = webidl.converters.DOMString(name, prefix, "name"); attributes = webidl.converters.DeleteCookieAttributes(attributes); setCookie(headers, { name, value: "", expires: /* @__PURE__ */ new Date(0), ...attributes }); } function getSetCookies(headers) { webidl.argumentLengthCheck(arguments, 1, "getSetCookies"); webidl.brandCheck(headers, Headers2, { strict: false }); const cookies = headers.getSetCookie(); if (!cookies) { return []; } return cookies.map((pair) => parseSetCookie(pair)); } function setCookie(headers, cookie) { webidl.argumentLengthCheck(arguments, 2, "setCookie"); webidl.brandCheck(headers, Headers2, { strict: false }); cookie = webidl.converters.Cookie(cookie); const str = stringify(cookie); if (str) { headers.append("Set-Cookie", str); } } webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ { converter: webidl.nullableConverter(webidl.converters.DOMString), key: "path", defaultValue: () => null }, { converter: webidl.nullableConverter(webidl.converters.DOMString), key: "domain", defaultValue: () => null } ]); webidl.converters.Cookie = webidl.dictionaryConverter([ { converter: webidl.converters.DOMString, key: "name" }, { converter: webidl.converters.DOMString, key: "value" }, { converter: webidl.nullableConverter((value) => { if (typeof value === "number") { return webidl.converters["unsigned long long"](value); } return new Date(value); }), key: "expires", defaultValue: () => null }, { converter: webidl.nullableConverter(webidl.converters["long long"]), key: "maxAge", defaultValue: () => null }, { converter: webidl.nullableConverter(webidl.converters.DOMString), key: "domain", defaultValue: () => null }, { converter: webidl.nullableConverter(webidl.converters.DOMString), key: "path", defaultValue: () => null }, { converter: webidl.nullableConverter(webidl.converters.boolean), key: "secure", defaultValue: () => null }, { converter: webidl.nullableConverter(webidl.converters.boolean), key: "httpOnly", defaultValue: () => null }, { converter: webidl.converters.USVString, key: "sameSite", allowedValues: ["Strict", "Lax", "None"] }, { converter: webidl.sequenceConverter(webidl.converters.DOMString), key: "unparsed", defaultValue: () => new Array(0) } ]); module.exports = { getCookies, deleteCookie, getSetCookies, setCookie }; } }); // viewer/node_modules/undici/lib/web/websocket/events.js var require_events = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/events.js"(exports, module) { "use strict"; var { webidl } = require_webidl(); var { kEnumerableProperty } = require_util(); var { kConstruct } = require_symbols(); var { MessagePort } = __require("node:worker_threads"); var MessageEvent = class _MessageEvent extends Event { #eventInit; constructor(type, eventInitDict = {}) { if (type === kConstruct) { super(arguments[1], arguments[2]); webidl.util.markAsUncloneable(this); return; } const prefix = "MessageEvent constructor"; webidl.argumentLengthCheck(arguments, 1, prefix); type = webidl.converters.DOMString(type, prefix, "type"); eventInitDict = webidl.converters.MessageEventInit(eventInitDict, prefix, "eventInitDict"); super(type, eventInitDict); this.#eventInit = eventInitDict; webidl.util.markAsUncloneable(this); } get data() { webidl.brandCheck(this, _MessageEvent); return this.#eventInit.data; } get origin() { webidl.brandCheck(this, _MessageEvent); return this.#eventInit.origin; } get lastEventId() { webidl.brandCheck(this, _MessageEvent); return this.#eventInit.lastEventId; } get source() { webidl.brandCheck(this, _MessageEvent); return this.#eventInit.source; } get ports() { webidl.brandCheck(this, _MessageEvent); if (!Object.isFrozen(this.#eventInit.ports)) { Object.freeze(this.#eventInit.ports); } return this.#eventInit.ports; } initMessageEvent(type, bubbles = false, cancelable = false, data = null, origin = "", lastEventId = "", source = null, ports = []) { webidl.brandCheck(this, _MessageEvent); webidl.argumentLengthCheck(arguments, 1, "MessageEvent.initMessageEvent"); return new _MessageEvent(type, { bubbles, cancelable, data, origin, lastEventId, source, ports }); } static createFastMessageEvent(type, init) { const messageEvent = new _MessageEvent(kConstruct, type, init); messageEvent.#eventInit = init; messageEvent.#eventInit.data ??= null; messageEvent.#eventInit.origin ??= ""; messageEvent.#eventInit.lastEventId ??= ""; messageEvent.#eventInit.source ??= null; messageEvent.#eventInit.ports ??= []; return messageEvent; } }; var { createFastMessageEvent } = MessageEvent; delete MessageEvent.createFastMessageEvent; var CloseEvent = class _CloseEvent extends Event { #eventInit; constructor(type, eventInitDict = {}) { const prefix = "CloseEvent constructor"; webidl.argumentLengthCheck(arguments, 1, prefix); type = webidl.converters.DOMString(type, prefix, "type"); eventInitDict = webidl.converters.CloseEventInit(eventInitDict); super(type, eventInitDict); this.#eventInit = eventInitDict; webidl.util.markAsUncloneable(this); } get wasClean() { webidl.brandCheck(this, _CloseEvent); return this.#eventInit.wasClean; } get code() { webidl.brandCheck(this, _CloseEvent); return this.#eventInit.code; } get reason() { webidl.brandCheck(this, _CloseEvent); return this.#eventInit.reason; } }; var ErrorEvent = class _ErrorEvent extends Event { #eventInit; constructor(type, eventInitDict) { const prefix = "ErrorEvent constructor"; webidl.argumentLengthCheck(arguments, 1, prefix); super(type, eventInitDict); webidl.util.markAsUncloneable(this); type = webidl.converters.DOMString(type, prefix, "type"); eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}); this.#eventInit = eventInitDict; } get message() { webidl.brandCheck(this, _ErrorEvent); return this.#eventInit.message; } get filename() { webidl.brandCheck(this, _ErrorEvent); return this.#eventInit.filename; } get lineno() { webidl.brandCheck(this, _ErrorEvent); return this.#eventInit.lineno; } get colno() { webidl.brandCheck(this, _ErrorEvent); return this.#eventInit.colno; } get error() { webidl.brandCheck(this, _ErrorEvent); return this.#eventInit.error; } }; Object.defineProperties(MessageEvent.prototype, { [Symbol.toStringTag]: { value: "MessageEvent", configurable: true }, data: kEnumerableProperty, origin: kEnumerableProperty, lastEventId: kEnumerableProperty, source: kEnumerableProperty, ports: kEnumerableProperty, initMessageEvent: kEnumerableProperty }); Object.defineProperties(CloseEvent.prototype, { [Symbol.toStringTag]: { value: "CloseEvent", configurable: true }, reason: kEnumerableProperty, code: kEnumerableProperty, wasClean: kEnumerableProperty }); Object.defineProperties(ErrorEvent.prototype, { [Symbol.toStringTag]: { value: "ErrorEvent", configurable: true }, message: kEnumerableProperty, filename: kEnumerableProperty, lineno: kEnumerableProperty, colno: kEnumerableProperty, error: kEnumerableProperty }); webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort); webidl.converters["sequence"] = webidl.sequenceConverter( webidl.converters.MessagePort ); var eventInit = [ { key: "bubbles", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "cancelable", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "composed", converter: webidl.converters.boolean, defaultValue: () => false } ]; webidl.converters.MessageEventInit = webidl.dictionaryConverter([ ...eventInit, { key: "data", converter: webidl.converters.any, defaultValue: () => null }, { key: "origin", converter: webidl.converters.USVString, defaultValue: () => "" }, { key: "lastEventId", converter: webidl.converters.DOMString, defaultValue: () => "" }, { key: "source", // Node doesn't implement WindowProxy or ServiceWorker, so the only // valid value for source is a MessagePort. converter: webidl.nullableConverter(webidl.converters.MessagePort), defaultValue: () => null }, { key: "ports", converter: webidl.converters["sequence"], defaultValue: () => new Array(0) } ]); webidl.converters.CloseEventInit = webidl.dictionaryConverter([ ...eventInit, { key: "wasClean", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "code", converter: webidl.converters["unsigned short"], defaultValue: () => 0 }, { key: "reason", converter: webidl.converters.USVString, defaultValue: () => "" } ]); webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ ...eventInit, { key: "message", converter: webidl.converters.DOMString, defaultValue: () => "" }, { key: "filename", converter: webidl.converters.USVString, defaultValue: () => "" }, { key: "lineno", converter: webidl.converters["unsigned long"], defaultValue: () => 0 }, { key: "colno", converter: webidl.converters["unsigned long"], defaultValue: () => 0 }, { key: "error", converter: webidl.converters.any } ]); module.exports = { MessageEvent, CloseEvent, ErrorEvent, createFastMessageEvent }; } }); // viewer/node_modules/undici/lib/web/websocket/constants.js var require_constants5 = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/constants.js"(exports, module) { "use strict"; var uid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; var staticPropertyDescriptors = { enumerable: true, writable: false, configurable: false }; var states = { CONNECTING: 0, OPEN: 1, CLOSING: 2, CLOSED: 3 }; var sentCloseFrameState = { NOT_SENT: 0, PROCESSING: 1, SENT: 2 }; var opcodes = { CONTINUATION: 0, TEXT: 1, BINARY: 2, CLOSE: 8, PING: 9, PONG: 10 }; var maxUnsigned16Bit = 2 ** 16 - 1; var parserStates = { INFO: 0, PAYLOADLENGTH_16: 2, PAYLOADLENGTH_64: 3, READ_DATA: 4 }; var emptyBuffer = Buffer.allocUnsafe(0); var sendHints = { string: 1, typedArray: 2, arrayBuffer: 3, blob: 4 }; module.exports = { uid, sentCloseFrameState, staticPropertyDescriptors, states, opcodes, maxUnsigned16Bit, parserStates, emptyBuffer, sendHints }; } }); // viewer/node_modules/undici/lib/web/websocket/symbols.js var require_symbols5 = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/symbols.js"(exports, module) { "use strict"; module.exports = { kWebSocketURL: /* @__PURE__ */ Symbol("url"), kReadyState: /* @__PURE__ */ Symbol("ready state"), kController: /* @__PURE__ */ Symbol("controller"), kResponse: /* @__PURE__ */ Symbol("response"), kBinaryType: /* @__PURE__ */ Symbol("binary type"), kSentClose: /* @__PURE__ */ Symbol("sent close"), kReceivedClose: /* @__PURE__ */ Symbol("received close"), kByteParser: /* @__PURE__ */ Symbol("byte parser") }; } }); // viewer/node_modules/undici/lib/web/websocket/util.js var require_util7 = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/util.js"(exports, module) { "use strict"; var { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = require_symbols5(); var { states, opcodes } = require_constants5(); var { ErrorEvent, createFastMessageEvent } = require_events(); var { isUtf8 } = __require("node:buffer"); var { collectASequenceOfCodePointsFast, removeHTTPWhitespace } = require_data_url(); function isConnecting(ws) { return ws[kReadyState] === states.CONNECTING; } function isEstablished(ws) { return ws[kReadyState] === states.OPEN; } function isClosing(ws) { return ws[kReadyState] === states.CLOSING; } function isClosed(ws) { return ws[kReadyState] === states.CLOSED; } function fireEvent(e, target, eventFactory = (type, init) => new Event(type, init), eventInitDict = {}) { const event = eventFactory(e, eventInitDict); target.dispatchEvent(event); } function websocketMessageReceived(ws, type, data) { if (ws[kReadyState] !== states.OPEN) { return; } let dataForEvent; if (type === opcodes.TEXT) { try { dataForEvent = utf8Decode(data); } catch { failWebsocketConnection(ws, "Received invalid UTF-8 in text frame."); return; } } else if (type === opcodes.BINARY) { if (ws[kBinaryType] === "blob") { dataForEvent = new Blob([data]); } else { dataForEvent = toArrayBuffer(data); } } fireEvent("message", ws, createFastMessageEvent, { origin: ws[kWebSocketURL].origin, data: dataForEvent }); } function toArrayBuffer(buffer) { if (buffer.byteLength === buffer.buffer.byteLength) { return buffer.buffer; } return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); } function isValidSubprotocol(protocol) { if (protocol.length === 0) { return false; } for (let i = 0; i < protocol.length; ++i) { const code = protocol.charCodeAt(i); if (code < 33 || // CTL, contains SP (0x20) and HT (0x09) code > 126 || code === 34 || // " code === 40 || // ( code === 41 || // ) code === 44 || // , code === 47 || // / code === 58 || // : code === 59 || // ; code === 60 || // < code === 61 || // = code === 62 || // > code === 63 || // ? code === 64 || // @ code === 91 || // [ code === 92 || // \ code === 93 || // ] code === 123 || // { code === 125) { return false; } } return true; } function isValidStatusCode(code) { if (code >= 1e3 && code < 1015) { return code !== 1004 && // reserved code !== 1005 && // "MUST NOT be set as a status code" code !== 1006; } return code >= 3e3 && code <= 4999; } function failWebsocketConnection(ws, reason) { const { [kController]: controller, [kResponse]: response } = ws; controller.abort(); if (response?.socket && !response.socket.destroyed) { response.socket.destroy(); } if (reason) { fireEvent("error", ws, (type, init) => new ErrorEvent(type, init), { error: new Error(reason), message: reason }); } } function isControlFrame(opcode) { return opcode === opcodes.CLOSE || opcode === opcodes.PING || opcode === opcodes.PONG; } function isContinuationFrame(opcode) { return opcode === opcodes.CONTINUATION; } function isTextBinaryFrame(opcode) { return opcode === opcodes.TEXT || opcode === opcodes.BINARY; } function isValidOpcode(opcode) { return isTextBinaryFrame(opcode) || isContinuationFrame(opcode) || isControlFrame(opcode); } function parseExtensions(extensions) { const position = { position: 0 }; const extensionList = /* @__PURE__ */ new Map(); while (position.position < extensions.length) { const pair = collectASequenceOfCodePointsFast(";", extensions, position); const [name, value = ""] = pair.split("="); extensionList.set( removeHTTPWhitespace(name, true, false), removeHTTPWhitespace(value, false, true) ); position.position++; } return extensionList; } function isValidClientWindowBits(value) { if (value.length === 0) { return false; } for (let i = 0; i < value.length; i++) { const byte = value.charCodeAt(i); if (byte < 48 || byte > 57) { return false; } } const num = Number.parseInt(value, 10); return num >= 8 && num <= 15; } var hasIntl = typeof process.versions.icu === "string"; var fatalDecoder = hasIntl ? new TextDecoder("utf-8", { fatal: true }) : void 0; var utf8Decode = hasIntl ? fatalDecoder.decode.bind(fatalDecoder) : function(buffer) { if (isUtf8(buffer)) { return buffer.toString("utf-8"); } throw new TypeError("Invalid utf-8 received."); }; module.exports = { isConnecting, isEstablished, isClosing, isClosed, fireEvent, isValidSubprotocol, isValidStatusCode, failWebsocketConnection, websocketMessageReceived, utf8Decode, isControlFrame, isContinuationFrame, isTextBinaryFrame, isValidOpcode, parseExtensions, isValidClientWindowBits }; } }); // viewer/node_modules/undici/lib/web/websocket/frame.js var require_frame = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/frame.js"(exports, module) { "use strict"; var { maxUnsigned16Bit } = require_constants5(); var BUFFER_SIZE = 16386; var crypto2; var buffer = null; var bufIdx = BUFFER_SIZE; try { crypto2 = __require("node:crypto"); } catch { crypto2 = { // not full compatibility, but minimum. randomFillSync: function randomFillSync(buffer2, _offset, _size) { for (let i = 0; i < buffer2.length; ++i) { buffer2[i] = Math.random() * 255 | 0; } return buffer2; } }; } function generateMask() { if (bufIdx === BUFFER_SIZE) { bufIdx = 0; crypto2.randomFillSync(buffer ??= Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE); } return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]]; } var WebsocketFrameSend = class { /** * @param {Buffer|undefined} data */ constructor(data) { this.frameData = data; } createFrame(opcode) { const frameData = this.frameData; const maskKey = generateMask(); const bodyLength = frameData?.byteLength ?? 0; let payloadLength = bodyLength; let offset = 6; if (bodyLength > maxUnsigned16Bit) { offset += 8; payloadLength = 127; } else if (bodyLength > 125) { offset += 2; payloadLength = 126; } const buffer2 = Buffer.allocUnsafe(bodyLength + offset); buffer2[0] = buffer2[1] = 0; buffer2[0] |= 128; buffer2[0] = (buffer2[0] & 240) + opcode; buffer2[offset - 4] = maskKey[0]; buffer2[offset - 3] = maskKey[1]; buffer2[offset - 2] = maskKey[2]; buffer2[offset - 1] = maskKey[3]; buffer2[1] = payloadLength; if (payloadLength === 126) { buffer2.writeUInt16BE(bodyLength, 2); } else if (payloadLength === 127) { buffer2[2] = buffer2[3] = 0; buffer2.writeUIntBE(bodyLength, 4, 6); } buffer2[1] |= 128; for (let i = 0; i < bodyLength; ++i) { buffer2[offset + i] = frameData[i] ^ maskKey[i & 3]; } return buffer2; } }; module.exports = { WebsocketFrameSend }; } }); // viewer/node_modules/undici/lib/web/websocket/connection.js var require_connection = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/connection.js"(exports, module) { "use strict"; var { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = require_constants5(); var { kReadyState, kSentClose, kByteParser, kReceivedClose, kResponse } = require_symbols5(); var { fireEvent, failWebsocketConnection, isClosing, isClosed, isEstablished, parseExtensions } = require_util7(); var { channels } = require_diagnostics(); var { CloseEvent } = require_events(); var { makeRequest } = require_request2(); var { fetching } = require_fetch(); var { Headers: Headers2, getHeadersList } = require_headers(); var { getDecodeSplit } = require_util2(); var { WebsocketFrameSend } = require_frame(); var crypto2; try { crypto2 = __require("node:crypto"); } catch { } function establishWebSocketConnection(url, protocols, client, ws, onEstablish, options) { const requestURL = url; requestURL.protocol = url.protocol === "ws:" ? "http:" : "https:"; const request = makeRequest({ urlList: [requestURL], client, serviceWorkers: "none", referrer: "no-referrer", mode: "websocket", credentials: "include", cache: "no-store", redirect: "error" }); if (options.headers) { const headersList = getHeadersList(new Headers2(options.headers)); request.headersList = headersList; } const keyValue = crypto2.randomBytes(16).toString("base64"); request.headersList.append("sec-websocket-key", keyValue); request.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { request.headersList.append("sec-websocket-protocol", protocol); } const permessageDeflate = "permessage-deflate; client_max_window_bits"; request.headersList.append("sec-websocket-extensions", permessageDeflate); const controller = fetching({ request, useParallelQueue: true, dispatcher: options.dispatcher, processResponse(response) { if (response.type === "error" || response.status !== 101) { failWebsocketConnection(ws, "Received network error or non-101 status code."); return; } if (protocols.length !== 0 && !response.headersList.get("Sec-WebSocket-Protocol")) { failWebsocketConnection(ws, "Server did not respond with sent protocols."); return; } if (response.headersList.get("Upgrade")?.toLowerCase() !== "websocket") { failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".'); return; } if (response.headersList.get("Connection")?.toLowerCase() !== "upgrade") { failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".'); return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; } const secExtension = response.headersList.get("Sec-WebSocket-Extensions"); let extensions; if (secExtension !== null) { extensions = parseExtensions(secExtension); if (!extensions.has("permessage-deflate")) { failWebsocketConnection(ws, "Sec-WebSocket-Extensions header does not match."); return; } } const secProtocol = response.headersList.get("Sec-WebSocket-Protocol"); if (secProtocol !== null) { const requestProtocols = getDecodeSplit("sec-websocket-protocol", request.headersList); if (!requestProtocols.includes(secProtocol)) { failWebsocketConnection(ws, "Protocol was not set in the opening handshake."); return; } } response.socket.on("data", onSocketData); response.socket.on("close", onSocketClose); response.socket.on("error", onSocketError); if (channels.open.hasSubscribers) { channels.open.publish({ address: response.socket.address(), protocol: secProtocol, extensions: secExtension }); } onEstablish(response, extensions); } }); return controller; } function closeWebSocketConnection(ws, code, reason, reasonByteLength) { if (isClosing(ws) || isClosed(ws)) { } else if (!isEstablished(ws)) { failWebsocketConnection(ws, "Connection was closed before it was established."); ws[kReadyState] = states.CLOSING; } else if (ws[kSentClose] === sentCloseFrameState.NOT_SENT) { ws[kSentClose] = sentCloseFrameState.PROCESSING; const frame = new WebsocketFrameSend(); if (code !== void 0 && reason === void 0) { frame.frameData = Buffer.allocUnsafe(2); frame.frameData.writeUInt16BE(code, 0); } else if (code !== void 0 && reason !== void 0) { frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength); frame.frameData.writeUInt16BE(code, 0); frame.frameData.write(reason, 2, "utf-8"); } else { frame.frameData = emptyBuffer; } const socket = ws[kResponse].socket; socket.write(frame.createFrame(opcodes.CLOSE)); ws[kSentClose] = sentCloseFrameState.SENT; ws[kReadyState] = states.CLOSING; } else { ws[kReadyState] = states.CLOSING; } } function onSocketData(chunk) { if (!this.ws[kByteParser].write(chunk)) { this.pause(); } } function onSocketClose() { const { ws } = this; const { [kResponse]: response } = ws; response.socket.off("data", onSocketData); response.socket.off("close", onSocketClose); response.socket.off("error", onSocketError); const wasClean = ws[kSentClose] === sentCloseFrameState.SENT && ws[kReceivedClose]; let code = 1005; let reason = ""; const result = ws[kByteParser].closingInfo; if (result && !result.error) { code = result.code ?? 1005; reason = result.reason; } else if (!ws[kReceivedClose]) { code = 1006; } ws[kReadyState] = states.CLOSED; fireEvent("close", ws, (type, init) => new CloseEvent(type, init), { wasClean, code, reason }); if (channels.close.hasSubscribers) { channels.close.publish({ websocket: ws, code, reason }); } } function onSocketError(error) { const { ws } = this; ws[kReadyState] = states.CLOSING; if (channels.socketError.hasSubscribers) { channels.socketError.publish(error); } this.destroy(); } module.exports = { establishWebSocketConnection, closeWebSocketConnection }; } }); // viewer/node_modules/undici/lib/web/websocket/permessage-deflate.js var require_permessage_deflate = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/permessage-deflate.js"(exports, module) { "use strict"; var { createInflateRaw, Z_DEFAULT_WINDOWBITS } = __require("node:zlib"); var { isValidClientWindowBits } = require_util7(); var { MessageSizeExceededError } = require_errors(); var tail = Buffer.from([0, 0, 255, 255]); var kBuffer = /* @__PURE__ */ Symbol("kBuffer"); var kLength = /* @__PURE__ */ Symbol("kLength"); var PerMessageDeflate = class { /** @type {import('node:zlib').InflateRaw} */ #inflate; #options = {}; #maxPayloadSize = 0; /** * @param {Map} extensions */ constructor(extensions, options) { this.#options.serverNoContextTakeover = extensions.has("server_no_context_takeover"); this.#options.serverMaxWindowBits = extensions.get("server_max_window_bits"); this.#maxPayloadSize = options.maxPayloadSize; } /** * Decompress a compressed payload. * @param {Buffer} chunk Compressed data * @param {boolean} fin Final fragment flag * @param {Function} callback Callback function */ decompress(chunk, fin, callback) { if (!this.#inflate) { let windowBits = Z_DEFAULT_WINDOWBITS; if (this.#options.serverMaxWindowBits) { if (!isValidClientWindowBits(this.#options.serverMaxWindowBits)) { callback(new Error("Invalid server_max_window_bits")); return; } windowBits = Number.parseInt(this.#options.serverMaxWindowBits); } try { this.#inflate = createInflateRaw({ windowBits }); } catch (err) { callback(err); return; } this.#inflate[kBuffer] = []; this.#inflate[kLength] = 0; this.#inflate.on("data", (data) => { this.#inflate[kLength] += data.length; if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) { callback(new MessageSizeExceededError()); this.#inflate.removeAllListeners(); this.#inflate = null; return; } this.#inflate[kBuffer].push(data); }); this.#inflate.on("error", (err) => { this.#inflate = null; callback(err); }); } this.#inflate.write(chunk); if (fin) { this.#inflate.write(tail); } this.#inflate.flush(() => { if (!this.#inflate) { return; } const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength]); this.#inflate[kBuffer].length = 0; this.#inflate[kLength] = 0; callback(null, full); }); } }; module.exports = { PerMessageDeflate }; } }); // viewer/node_modules/undici/lib/web/websocket/receiver.js var require_receiver = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/receiver.js"(exports, module) { "use strict"; var { Writable } = __require("node:stream"); var assert = __require("node:assert"); var { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = require_constants5(); var { kReadyState, kSentClose, kResponse, kReceivedClose } = require_symbols5(); var { channels } = require_diagnostics(); var { isValidStatusCode, isValidOpcode, failWebsocketConnection, websocketMessageReceived, utf8Decode, isControlFrame, isTextBinaryFrame, isContinuationFrame } = require_util7(); var { WebsocketFrameSend } = require_frame(); var { closeWebSocketConnection } = require_connection(); var { PerMessageDeflate } = require_permessage_deflate(); var { MessageSizeExceededError } = require_errors(); var ByteParser = class extends Writable { #buffers = []; #fragmentsBytes = 0; #byteOffset = 0; #loop = false; #state = parserStates.INFO; #info = {}; #fragments = []; /** @type {Map} */ #extensions; /** @type {number} */ #maxPayloadSize; /** * @param {import('./websocket').WebSocket} ws * @param {Map|null} extensions * @param {{ maxPayloadSize?: number }} [options] */ constructor(ws, extensions, options = {}) { super(); this.ws = ws; this.#extensions = extensions == null ? /* @__PURE__ */ new Map() : extensions; this.#maxPayloadSize = options.maxPayloadSize ?? 0; if (this.#extensions.has("permessage-deflate")) { this.#extensions.set("permessage-deflate", new PerMessageDeflate(extensions, options)); } } /** * @param {Buffer} chunk * @param {() => void} callback */ _write(chunk, _, callback) { this.#buffers.push(chunk); this.#byteOffset += chunk.length; this.#loop = true; this.run(callback); } #validatePayloadLength() { if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength > this.#maxPayloadSize) { failWebsocketConnection(this.ws, "Payload size exceeds maximum allowed size"); return false; } return true; } /** * Runs whenever a new chunk is received. * Callback is called whenever there are no more chunks buffering, * or not enough bytes are buffered to parse. */ run(callback) { while (this.#loop) { if (this.#state === parserStates.INFO) { if (this.#byteOffset < 2) { return callback(); } const buffer = this.consume(2); const fin = (buffer[0] & 128) !== 0; const opcode = buffer[0] & 15; const masked = (buffer[1] & 128) === 128; const fragmented = !fin && opcode !== opcodes.CONTINUATION; const payloadLength = buffer[1] & 127; const rsv1 = buffer[0] & 64; const rsv2 = buffer[0] & 32; const rsv3 = buffer[0] & 16; if (!isValidOpcode(opcode)) { failWebsocketConnection(this.ws, "Invalid opcode received"); return callback(); } if (masked) { failWebsocketConnection(this.ws, "Frame cannot be masked"); return callback(); } if (rsv1 !== 0 && !this.#extensions.has("permessage-deflate")) { failWebsocketConnection(this.ws, "Expected RSV1 to be clear."); return; } if (rsv2 !== 0 || rsv3 !== 0) { failWebsocketConnection(this.ws, "RSV1, RSV2, RSV3 must be clear"); return; } if (fragmented && !isTextBinaryFrame(opcode)) { failWebsocketConnection(this.ws, "Invalid frame type was fragmented."); return; } if (isTextBinaryFrame(opcode) && this.#fragments.length > 0) { failWebsocketConnection(this.ws, "Expected continuation frame"); return; } if (this.#info.fragmented && fragmented) { failWebsocketConnection(this.ws, "Fragmented frame exceeded 125 bytes."); return; } if ((payloadLength > 125 || fragmented) && isControlFrame(opcode)) { failWebsocketConnection(this.ws, "Control frame either too large or fragmented"); return; } if (isContinuationFrame(opcode) && this.#fragments.length === 0 && !this.#info.compressed) { failWebsocketConnection(this.ws, "Unexpected continuation frame"); return; } if (payloadLength <= 125) { this.#info.payloadLength = payloadLength; this.#state = parserStates.READ_DATA; if (!this.#validatePayloadLength()) { return; } } else if (payloadLength === 126) { this.#state = parserStates.PAYLOADLENGTH_16; } else if (payloadLength === 127) { this.#state = parserStates.PAYLOADLENGTH_64; } if (isTextBinaryFrame(opcode)) { this.#info.binaryType = opcode; this.#info.compressed = rsv1 !== 0; } this.#info.opcode = opcode; this.#info.masked = masked; this.#info.fin = fin; this.#info.fragmented = fragmented; } else if (this.#state === parserStates.PAYLOADLENGTH_16) { if (this.#byteOffset < 2) { return callback(); } const buffer = this.consume(2); this.#info.payloadLength = buffer.readUInt16BE(0); this.#state = parserStates.READ_DATA; if (!this.#validatePayloadLength()) { return; } } else if (this.#state === parserStates.PAYLOADLENGTH_64) { if (this.#byteOffset < 8) { return callback(); } const buffer = this.consume(8); const upper = buffer.readUInt32BE(0); const lower = buffer.readUInt32BE(4); if (upper !== 0 || lower > 2 ** 31 - 1) { failWebsocketConnection(this.ws, "Received payload length > 2^31 bytes."); return; } this.#info.payloadLength = lower; this.#state = parserStates.READ_DATA; if (!this.#validatePayloadLength()) { return; } } else if (this.#state === parserStates.READ_DATA) { if (this.#byteOffset < this.#info.payloadLength) { return callback(); } const body = this.consume(this.#info.payloadLength); if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; } else { if (!this.#info.compressed) { this.writeFragments(body); if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) { failWebsocketConnection(this.ws, new MessageSizeExceededError().message); return; } if (!this.#info.fragmented && this.#info.fin) { websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments()); } this.#state = parserStates.INFO; } else { this.#extensions.get("permessage-deflate").decompress( body, this.#info.fin, (error, data) => { if (error) { failWebsocketConnection(this.ws, error.message); return; } this.writeFragments(data); if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) { failWebsocketConnection(this.ws, new MessageSizeExceededError().message); return; } if (!this.#info.fin) { this.#state = parserStates.INFO; this.#loop = true; this.run(callback); return; } websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments()); this.#loop = true; this.#state = parserStates.INFO; this.run(callback); } ); this.#loop = false; break; } } } } } /** * Take n bytes from the buffered Buffers * @param {number} n * @returns {Buffer} */ consume(n) { if (n > this.#byteOffset) { throw new Error("Called consume() before buffers satiated."); } else if (n === 0) { return emptyBuffer; } if (this.#buffers[0].length === n) { this.#byteOffset -= this.#buffers[0].length; return this.#buffers.shift(); } const buffer = Buffer.allocUnsafe(n); let offset = 0; while (offset !== n) { const next = this.#buffers[0]; const { length: length2 } = next; if (length2 + offset === n) { buffer.set(this.#buffers.shift(), offset); break; } else if (length2 + offset > n) { buffer.set(next.subarray(0, n - offset), offset); this.#buffers[0] = next.subarray(n - offset); break; } else { buffer.set(this.#buffers.shift(), offset); offset += next.length; } } this.#byteOffset -= n; return buffer; } writeFragments(fragment) { this.#fragmentsBytes += fragment.length; this.#fragments.push(fragment); } consumeFragments() { const fragments = this.#fragments; if (fragments.length === 1) { this.#fragmentsBytes = 0; return fragments.shift(); } const output = Buffer.concat(fragments, this.#fragmentsBytes); this.#fragments = []; this.#fragmentsBytes = 0; return output; } parseCloseBody(data) { assert(data.length !== 1); let code; if (data.length >= 2) { code = data.readUInt16BE(0); } if (code !== void 0 && !isValidStatusCode(code)) { return { code: 1002, reason: "Invalid status code", error: true }; } let reason = data.subarray(2); if (reason[0] === 239 && reason[1] === 187 && reason[2] === 191) { reason = reason.subarray(3); } try { reason = utf8Decode(reason); } catch { return { code: 1007, reason: "Invalid UTF-8", error: true }; } return { code, reason, error: false }; } /** * Parses control frames. * @param {Buffer} body */ parseControlFrame(body) { const { opcode, payloadLength } = this.#info; if (opcode === opcodes.CLOSE) { if (payloadLength === 1) { failWebsocketConnection(this.ws, "Received close frame with a 1-byte body."); return false; } this.#info.closeInfo = this.parseCloseBody(body); if (this.#info.closeInfo.error) { const { code, reason } = this.#info.closeInfo; closeWebSocketConnection(this.ws, code, reason, reason.length); failWebsocketConnection(this.ws, reason); return false; } if (this.ws[kSentClose] !== sentCloseFrameState.SENT) { let body2 = emptyBuffer; if (this.#info.closeInfo.code) { body2 = Buffer.allocUnsafe(2); body2.writeUInt16BE(this.#info.closeInfo.code, 0); } const closeFrame = new WebsocketFrameSend(body2); this.ws[kResponse].socket.write( closeFrame.createFrame(opcodes.CLOSE), (err) => { if (!err) { this.ws[kSentClose] = sentCloseFrameState.SENT; } } ); } this.ws[kReadyState] = states.CLOSING; this.ws[kReceivedClose] = true; return false; } else if (opcode === opcodes.PING) { if (!this.ws[kReceivedClose]) { const frame = new WebsocketFrameSend(body); this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)); if (channels.ping.hasSubscribers) { channels.ping.publish({ payload: body }); } } } else if (opcode === opcodes.PONG) { if (channels.pong.hasSubscribers) { channels.pong.publish({ payload: body }); } } return true; } get closingInfo() { return this.#info.closeInfo; } }; module.exports = { ByteParser }; } }); // viewer/node_modules/undici/lib/web/websocket/sender.js var require_sender = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/sender.js"(exports, module) { "use strict"; var { WebsocketFrameSend } = require_frame(); var { opcodes, sendHints } = require_constants5(); var FixedQueue = require_fixed_queue(); var FastBuffer = Buffer[Symbol.species]; var SendQueue = class { /** * @type {FixedQueue} */ #queue = new FixedQueue(); /** * @type {boolean} */ #running = false; /** @type {import('node:net').Socket} */ #socket; constructor(socket) { this.#socket = socket; } add(item, cb, hint) { if (hint !== sendHints.blob) { const frame = createFrame(item, hint); if (!this.#running) { this.#socket.write(frame, cb); } else { const node2 = { promise: null, callback: cb, frame }; this.#queue.push(node2); } return; } const node = { promise: item.arrayBuffer().then((ab) => { node.promise = null; node.frame = createFrame(ab, hint); }), callback: cb, frame: null }; this.#queue.push(node); if (!this.#running) { this.#run(); } } async #run() { this.#running = true; const queue = this.#queue; while (!queue.isEmpty()) { const node = queue.shift(); if (node.promise !== null) { await node.promise; } this.#socket.write(node.frame, node.callback); node.callback = node.frame = null; } this.#running = false; } }; function createFrame(data, hint) { return new WebsocketFrameSend(toBuffer(data, hint)).createFrame(hint === sendHints.string ? opcodes.TEXT : opcodes.BINARY); } function toBuffer(data, hint) { switch (hint) { case sendHints.string: return Buffer.from(data); case sendHints.arrayBuffer: case sendHints.blob: return new FastBuffer(data); case sendHints.typedArray: return new FastBuffer(data.buffer, data.byteOffset, data.byteLength); } } module.exports = { SendQueue }; } }); // viewer/node_modules/undici/lib/web/websocket/websocket.js var require_websocket = __commonJS({ "viewer/node_modules/undici/lib/web/websocket/websocket.js"(exports, module) { "use strict"; var { webidl } = require_webidl(); var { URLSerializer } = require_data_url(); var { environmentSettingsObject } = require_util2(); var { staticPropertyDescriptors, states, sentCloseFrameState, sendHints } = require_constants5(); var { kWebSocketURL, kReadyState, kController, kBinaryType, kResponse, kSentClose, kByteParser } = require_symbols5(); var { isConnecting, isEstablished, isClosing, isValidSubprotocol, fireEvent } = require_util7(); var { establishWebSocketConnection, closeWebSocketConnection } = require_connection(); var { ByteParser } = require_receiver(); var { kEnumerableProperty, isBlobLike } = require_util(); var { getGlobalDispatcher } = require_global2(); var { types } = __require("node:util"); var { ErrorEvent, CloseEvent } = require_events(); var { SendQueue } = require_sender(); var WebSocket = class _WebSocket extends EventTarget { #events = { open: null, error: null, close: null, message: null }; #bufferedAmount = 0; #protocol = ""; #extensions = ""; /** @type {SendQueue} */ #sendQueue; /** * @param {string} url * @param {string|string[]} protocols */ constructor(url, protocols = []) { super(); webidl.util.markAsUncloneable(this); const prefix = "WebSocket constructor"; webidl.argumentLengthCheck(arguments, 1, prefix); const options = webidl.converters["DOMString or sequence or WebSocketInit"](protocols, prefix, "options"); url = webidl.converters.USVString(url, prefix, "url"); protocols = options.protocols; const baseURL = environmentSettingsObject.settingsObject.baseUrl; let urlRecord; try { urlRecord = new URL(url, baseURL); } catch (e) { throw new DOMException(e, "SyntaxError"); } if (urlRecord.protocol === "http:") { urlRecord.protocol = "ws:"; } else if (urlRecord.protocol === "https:") { urlRecord.protocol = "wss:"; } if (urlRecord.protocol !== "ws:" && urlRecord.protocol !== "wss:") { throw new DOMException( `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, "SyntaxError" ); } if (urlRecord.hash || urlRecord.href.endsWith("#")) { throw new DOMException("Got fragment", "SyntaxError"); } if (typeof protocols === "string") { protocols = [protocols]; } if (protocols.length !== new Set(protocols.map((p) => p.toLowerCase())).size) { throw new DOMException("Invalid Sec-WebSocket-Protocol value", "SyntaxError"); } if (protocols.length > 0 && !protocols.every((p) => isValidSubprotocol(p))) { throw new DOMException("Invalid Sec-WebSocket-Protocol value", "SyntaxError"); } this[kWebSocketURL] = new URL(urlRecord.href); const client = environmentSettingsObject.settingsObject; this[kController] = establishWebSocketConnection( urlRecord, protocols, client, this, (response, extensions) => this.#onConnectionEstablished(response, extensions), options ); this[kReadyState] = _WebSocket.CONNECTING; this[kSentClose] = sentCloseFrameState.NOT_SENT; this[kBinaryType] = "blob"; } /** * @see https://websockets.spec.whatwg.org/#dom-websocket-close * @param {number|undefined} code * @param {string|undefined} reason */ close(code = void 0, reason = void 0) { webidl.brandCheck(this, _WebSocket); const prefix = "WebSocket.close"; if (code !== void 0) { code = webidl.converters["unsigned short"](code, prefix, "code", { clamp: true }); } if (reason !== void 0) { reason = webidl.converters.USVString(reason, prefix, "reason"); } if (code !== void 0) { if (code !== 1e3 && (code < 3e3 || code > 4999)) { throw new DOMException("invalid code", "InvalidAccessError"); } } let reasonByteLength = 0; if (reason !== void 0) { reasonByteLength = Buffer.byteLength(reason); if (reasonByteLength > 123) { throw new DOMException( `Reason must be less than 123 bytes; received ${reasonByteLength}`, "SyntaxError" ); } } closeWebSocketConnection(this, code, reason, reasonByteLength); } /** * @see https://websockets.spec.whatwg.org/#dom-websocket-send * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data */ send(data) { webidl.brandCheck(this, _WebSocket); const prefix = "WebSocket.send"; webidl.argumentLengthCheck(arguments, 1, prefix); data = webidl.converters.WebSocketSendData(data, prefix, "data"); if (isConnecting(this)) { throw new DOMException("Sent before connected.", "InvalidStateError"); } if (!isEstablished(this) || isClosing(this)) { return; } if (typeof data === "string") { const length2 = Buffer.byteLength(data); this.#bufferedAmount += length2; this.#sendQueue.add(data, () => { this.#bufferedAmount -= length2; }, sendHints.string); } else if (types.isArrayBuffer(data)) { this.#bufferedAmount += data.byteLength; this.#sendQueue.add(data, () => { this.#bufferedAmount -= data.byteLength; }, sendHints.arrayBuffer); } else if (ArrayBuffer.isView(data)) { this.#bufferedAmount += data.byteLength; this.#sendQueue.add(data, () => { this.#bufferedAmount -= data.byteLength; }, sendHints.typedArray); } else if (isBlobLike(data)) { this.#bufferedAmount += data.size; this.#sendQueue.add(data, () => { this.#bufferedAmount -= data.size; }, sendHints.blob); } } get readyState() { webidl.brandCheck(this, _WebSocket); return this[kReadyState]; } get bufferedAmount() { webidl.brandCheck(this, _WebSocket); return this.#bufferedAmount; } get url() { webidl.brandCheck(this, _WebSocket); return URLSerializer(this[kWebSocketURL]); } get extensions() { webidl.brandCheck(this, _WebSocket); return this.#extensions; } get protocol() { webidl.brandCheck(this, _WebSocket); return this.#protocol; } get onopen() { webidl.brandCheck(this, _WebSocket); return this.#events.open; } set onopen(fn) { webidl.brandCheck(this, _WebSocket); if (this.#events.open) { this.removeEventListener("open", this.#events.open); } if (typeof fn === "function") { this.#events.open = fn; this.addEventListener("open", fn); } else { this.#events.open = null; } } get onerror() { webidl.brandCheck(this, _WebSocket); return this.#events.error; } set onerror(fn) { webidl.brandCheck(this, _WebSocket); if (this.#events.error) { this.removeEventListener("error", this.#events.error); } if (typeof fn === "function") { this.#events.error = fn; this.addEventListener("error", fn); } else { this.#events.error = null; } } get onclose() { webidl.brandCheck(this, _WebSocket); return this.#events.close; } set onclose(fn) { webidl.brandCheck(this, _WebSocket); if (this.#events.close) { this.removeEventListener("close", this.#events.close); } if (typeof fn === "function") { this.#events.close = fn; this.addEventListener("close", fn); } else { this.#events.close = null; } } get onmessage() { webidl.brandCheck(this, _WebSocket); return this.#events.message; } set onmessage(fn) { webidl.brandCheck(this, _WebSocket); if (this.#events.message) { this.removeEventListener("message", this.#events.message); } if (typeof fn === "function") { this.#events.message = fn; this.addEventListener("message", fn); } else { this.#events.message = null; } } get binaryType() { webidl.brandCheck(this, _WebSocket); return this[kBinaryType]; } set binaryType(type) { webidl.brandCheck(this, _WebSocket); if (type !== "blob" && type !== "arraybuffer") { this[kBinaryType] = "blob"; } else { this[kBinaryType] = type; } } /** * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol */ #onConnectionEstablished(response, parsedExtensions) { this[kResponse] = response; const maxPayloadSize = this[kController]?.dispatcher?.webSocketOptions?.maxPayloadSize; const parser = new ByteParser(this, parsedExtensions, { maxPayloadSize }); parser.on("drain", onParserDrain); parser.on("error", onParserError.bind(this)); response.socket.ws = this; this[kByteParser] = parser; this.#sendQueue = new SendQueue(response.socket); this[kReadyState] = states.OPEN; const extensions = response.headersList.get("sec-websocket-extensions"); if (extensions !== null) { this.#extensions = extensions; } const protocol = response.headersList.get("sec-websocket-protocol"); if (protocol !== null) { this.#protocol = protocol; } fireEvent("open", this); } }; WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING; WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN; WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING; WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED; Object.defineProperties(WebSocket.prototype, { CONNECTING: staticPropertyDescriptors, OPEN: staticPropertyDescriptors, CLOSING: staticPropertyDescriptors, CLOSED: staticPropertyDescriptors, url: kEnumerableProperty, readyState: kEnumerableProperty, bufferedAmount: kEnumerableProperty, onopen: kEnumerableProperty, onerror: kEnumerableProperty, onclose: kEnumerableProperty, close: kEnumerableProperty, onmessage: kEnumerableProperty, binaryType: kEnumerableProperty, send: kEnumerableProperty, extensions: kEnumerableProperty, protocol: kEnumerableProperty, [Symbol.toStringTag]: { value: "WebSocket", writable: false, enumerable: false, configurable: true } }); Object.defineProperties(WebSocket, { CONNECTING: staticPropertyDescriptors, OPEN: staticPropertyDescriptors, CLOSING: staticPropertyDescriptors, CLOSED: staticPropertyDescriptors }); webidl.converters["sequence"] = webidl.sequenceConverter( webidl.converters.DOMString ); webidl.converters["DOMString or sequence"] = function(V, prefix, argument) { if (webidl.util.Type(V) === "Object" && Symbol.iterator in V) { return webidl.converters["sequence"](V); } return webidl.converters.DOMString(V, prefix, argument); }; webidl.converters.WebSocketInit = webidl.dictionaryConverter([ { key: "protocols", converter: webidl.converters["DOMString or sequence"], defaultValue: () => new Array(0) }, { key: "dispatcher", converter: webidl.converters.any, defaultValue: () => getGlobalDispatcher() }, { key: "headers", converter: webidl.nullableConverter(webidl.converters.HeadersInit) } ]); webidl.converters["DOMString or sequence or WebSocketInit"] = function(V) { if (webidl.util.Type(V) === "Object" && !(Symbol.iterator in V)) { return webidl.converters.WebSocketInit(V); } return { protocols: webidl.converters["DOMString or sequence"](V) }; }; webidl.converters.WebSocketSendData = function(V) { if (webidl.util.Type(V) === "Object") { if (isBlobLike(V)) { return webidl.converters.Blob(V, { strict: false }); } if (ArrayBuffer.isView(V) || types.isArrayBuffer(V)) { return webidl.converters.BufferSource(V); } } return webidl.converters.USVString(V); }; function onParserDrain() { this.ws[kResponse].socket.resume(); } function onParserError(err) { let message; let code; if (err instanceof CloseEvent) { message = err.reason; code = err.code; } else { message = err.message; } fireEvent("error", this, () => new ErrorEvent("error", { error: err, message })); closeWebSocketConnection(this, code); } module.exports = { WebSocket }; } }); // viewer/node_modules/undici/lib/web/eventsource/util.js var require_util8 = __commonJS({ "viewer/node_modules/undici/lib/web/eventsource/util.js"(exports, module) { "use strict"; function isValidLastEventId(value) { return value.indexOf("\0") === -1; } function isASCIINumber(value) { if (value.length === 0) return false; for (let i = 0; i < value.length; i++) { if (value.charCodeAt(i) < 48 || value.charCodeAt(i) > 57) return false; } return true; } function delay(ms) { return new Promise((resolve) => { setTimeout(resolve, ms).unref(); }); } module.exports = { isValidLastEventId, isASCIINumber, delay }; } }); // viewer/node_modules/undici/lib/web/eventsource/eventsource-stream.js var require_eventsource_stream = __commonJS({ "viewer/node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; var LF = 10; var CR = 13; var COLON = 58; var SPACE = 32; var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} */ state = null; /** * Leading byte-order-mark check. * @type {boolean} */ checkBOM = true; /** * @type {boolean} */ crlfCheck = false; /** * @type {boolean} */ eventEndCheck = false; /** * @type {Buffer} */ buffer = null; pos = 0; event = { data: void 0, event: void 0, id: void 0, retry: void 0 }; /** * @param {object} options * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ constructor(options = {}) { options.readableObjectMode = true; super(options); this.state = options.eventSourceSettings || {}; if (options.push) { this.push = options.push; } } /** * @param {Buffer} chunk * @param {string} _encoding * @param {Function} callback * @returns {void} */ _transform(chunk, _encoding, callback) { if (chunk.length === 0) { callback(); return; } if (this.buffer) { this.buffer = Buffer.concat([this.buffer, chunk]); } else { this.buffer = chunk; } if (this.checkBOM) { switch (this.buffer.length) { case 1: if (this.buffer[0] === BOM[0]) { callback(); return; } this.checkBOM = false; callback(); return; case 2: if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1]) { callback(); return; } this.checkBOM = false; break; case 3: if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { this.buffer = Buffer.alloc(0); this.checkBOM = false; callback(); return; } this.checkBOM = false; break; default: if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) { this.buffer = this.buffer.subarray(3); } this.checkBOM = false; break; } } while (this.pos < this.buffer.length) { if (this.eventEndCheck) { if (this.crlfCheck) { if (this.buffer[this.pos] === LF) { this.buffer = this.buffer.subarray(this.pos + 1); this.pos = 0; this.crlfCheck = false; continue; } this.crlfCheck = false; } if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { if (this.buffer[this.pos] === CR) { this.crlfCheck = true; } this.buffer = this.buffer.subarray(this.pos + 1); this.pos = 0; if (this.event.data !== void 0 || this.event.event || this.event.id || this.event.retry) { this.processEvent(this.event); } this.clearEvent(); continue; } this.eventEndCheck = false; continue; } if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { if (this.buffer[this.pos] === CR) { this.crlfCheck = true; } this.parseLine(this.buffer.subarray(0, this.pos), this.event); this.buffer = this.buffer.subarray(this.pos + 1); this.pos = 0; this.eventEndCheck = true; continue; } this.pos++; } callback(); } /** * @param {Buffer} line * @param {EventStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { return; } const colonPosition = line.indexOf(COLON); if (colonPosition === 0) { return; } let field = ""; let value = ""; if (colonPosition !== -1) { field = line.subarray(0, colonPosition).toString("utf8"); let valueStart = colonPosition + 1; if (line[valueStart] === SPACE) { ++valueStart; } value = line.subarray(valueStart).toString("utf8"); } else { field = line.toString("utf8"); value = ""; } switch (field) { case "data": if (event[field] === void 0) { event[field] = value; } else { event[field] += ` ${value}`; } break; case "retry": if (isASCIINumber(value)) { event[field] = value; } break; case "id": if (isValidLastEventId(value)) { event[field] = value; } break; case "event": if (value.length > 0) { event[field] = value; } break; } } /** * @param {EventSourceStreamEvent} event */ processEvent(event) { if (event.retry && isASCIINumber(event.retry)) { this.state.reconnectionTime = parseInt(event.retry, 10); } if (event.id && isValidLastEventId(event.id)) { this.state.lastEventId = event.id; } if (event.data !== void 0) { this.push({ type: event.event || "message", options: { data: event.data, lastEventId: this.state.lastEventId, origin: this.state.origin } }); } } clearEvent() { this.event = { data: void 0, event: void 0, id: void 0, retry: void 0 }; } }; module.exports = { EventSourceStream }; } }); // viewer/node_modules/undici/lib/web/eventsource/eventsource.js var require_eventsource = __commonJS({ "viewer/node_modules/undici/lib/web/eventsource/eventsource.js"(exports, module) { "use strict"; var { pipeline } = __require("node:stream"); var { fetching } = require_fetch(); var { makeRequest } = require_request2(); var { webidl } = require_webidl(); var { EventSourceStream } = require_eventsource_stream(); var { parseMIMEType } = require_data_url(); var { createFastMessageEvent } = require_events(); var { isNetworkError: isNetworkError2 } = require_response(); var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; var OPEN = 1; var CLOSED = 2; var ANONYMOUS = "anonymous"; var USE_CREDENTIALS = "use-credentials"; var EventSource = class _EventSource extends EventTarget { #events = { open: null, error: null, message: null }; #url = null; #withCredentials = false; #readyState = CONNECTING; #request = null; #controller = null; #dispatcher; /** * @type {import('./eventsource-stream').eventSourceSettings} */ #state; /** * Creates a new EventSource object. * @param {string} url * @param {EventSourceInit} [eventSourceInitDict] * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#the-eventsource-interface */ constructor(url, eventSourceInitDict = {}) { super(); webidl.util.markAsUncloneable(this); const prefix = "EventSource constructor"; webidl.argumentLengthCheck(arguments, 1, prefix); if (!experimentalWarned) { experimentalWarned = true; process.emitWarning("EventSource is experimental, expect them to change at any time.", { code: "UNDICI-ES" }); } url = webidl.converters.USVString(url, prefix, "url"); eventSourceInitDict = webidl.converters.EventSourceInitDict(eventSourceInitDict, prefix, "eventSourceInitDict"); this.#dispatcher = eventSourceInitDict.dispatcher; this.#state = { lastEventId: "", reconnectionTime: defaultReconnectionTime }; const settings = environmentSettingsObject; let urlRecord; try { urlRecord = new URL(url, settings.settingsObject.baseUrl); this.#state.origin = urlRecord.origin; } catch (e) { throw new DOMException(e, "SyntaxError"); } this.#url = urlRecord.href; let corsAttributeState = ANONYMOUS; if (eventSourceInitDict.withCredentials) { corsAttributeState = USE_CREDENTIALS; this.#withCredentials = true; } const initRequest = { redirect: "follow", keepalive: true, // @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes mode: "cors", credentials: corsAttributeState === "anonymous" ? "same-origin" : "omit", referrer: "no-referrer" }; initRequest.client = environmentSettingsObject.settingsObject; initRequest.headersList = [["accept", { name: "accept", value: "text/event-stream" }]]; initRequest.cache = "no-store"; initRequest.initiator = "other"; initRequest.urlList = [new URL(this.#url)]; this.#request = makeRequest(initRequest); this.#connect(); } /** * Returns the state of this EventSource object's connection. It can have the * values described below. * @returns {0|1|2} * @readonly */ get readyState() { return this.#readyState; } /** * Returns the URL providing the event stream. * @readonly * @returns {string} */ get url() { return this.#url; } /** * Returns a boolean indicating whether the EventSource object was * instantiated with CORS credentials set (true), or not (false, the default). */ get withCredentials() { return this.#withCredentials; } #connect() { if (this.#readyState === CLOSED) return; this.#readyState = CONNECTING; const fetchParams = { request: this.#request, dispatcher: this.#dispatcher }; const processEventSourceEndOfBody = (response) => { if (isNetworkError2(response)) { this.dispatchEvent(new Event("error")); this.close(); } this.#reconnect(); }; fetchParams.processResponseEndOfBody = processEventSourceEndOfBody; fetchParams.processResponse = (response) => { if (isNetworkError2(response)) { if (response.aborted) { this.close(); this.dispatchEvent(new Event("error")); return; } else { this.#reconnect(); return; } } const contentType = response.headersList.get("content-type", true); const mimeType = contentType !== null ? parseMIMEType(contentType) : "failure"; const contentTypeValid = mimeType !== "failure" && mimeType.essence === "text/event-stream"; if (response.status !== 200 || contentTypeValid === false) { this.close(); this.dispatchEvent(new Event("error")); return; } this.#readyState = OPEN; this.dispatchEvent(new Event("open")); this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, event.options )); } }); pipeline( response.body.stream, eventSourceStream, (error) => { if (error?.aborted === false) { this.close(); this.dispatchEvent(new Event("error")); } } ); }; this.#controller = fetching(fetchParams); } /** * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#sse-processing-model * @returns {Promise} */ async #reconnect() { if (this.#readyState === CLOSED) return; this.#readyState = CONNECTING; this.dispatchEvent(new Event("error")); await delay(this.#state.reconnectionTime); if (this.#readyState !== CONNECTING) return; if (this.#state.lastEventId.length) { this.#request.headersList.set("last-event-id", this.#state.lastEventId, true); } this.#connect(); } /** * Closes the connection, if any, and sets the readyState attribute to * CLOSED. */ close() { webidl.brandCheck(this, _EventSource); if (this.#readyState === CLOSED) return; this.#readyState = CLOSED; this.#controller.abort(); this.#request = null; } get onopen() { return this.#events.open; } set onopen(fn) { if (this.#events.open) { this.removeEventListener("open", this.#events.open); } if (typeof fn === "function") { this.#events.open = fn; this.addEventListener("open", fn); } else { this.#events.open = null; } } get onmessage() { return this.#events.message; } set onmessage(fn) { if (this.#events.message) { this.removeEventListener("message", this.#events.message); } if (typeof fn === "function") { this.#events.message = fn; this.addEventListener("message", fn); } else { this.#events.message = null; } } get onerror() { return this.#events.error; } set onerror(fn) { if (this.#events.error) { this.removeEventListener("error", this.#events.error); } if (typeof fn === "function") { this.#events.error = fn; this.addEventListener("error", fn); } else { this.#events.error = null; } } }; var constantsPropertyDescriptors = { CONNECTING: { __proto__: null, configurable: false, enumerable: true, value: CONNECTING, writable: false }, OPEN: { __proto__: null, configurable: false, enumerable: true, value: OPEN, writable: false }, CLOSED: { __proto__: null, configurable: false, enumerable: true, value: CLOSED, writable: false } }; Object.defineProperties(EventSource, constantsPropertyDescriptors); Object.defineProperties(EventSource.prototype, constantsPropertyDescriptors); Object.defineProperties(EventSource.prototype, { close: kEnumerableProperty, onerror: kEnumerableProperty, onmessage: kEnumerableProperty, onopen: kEnumerableProperty, readyState: kEnumerableProperty, url: kEnumerableProperty, withCredentials: kEnumerableProperty }); webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([ { key: "withCredentials", converter: webidl.converters.boolean, defaultValue: () => false }, { key: "dispatcher", // undici only converter: webidl.converters.any } ]); module.exports = { EventSource, defaultReconnectionTime }; } }); // viewer/node_modules/undici/index.js var require_undici = __commonJS({ "viewer/node_modules/undici/index.js"(exports, module) { "use strict"; var Client = require_client(); var Dispatcher = require_dispatcher(); var Pool = require_pool(); var BalancedPool = require_balanced_pool(); var Agent = require_agent(); var ProxyAgent = require_proxy_agent(); var EnvHttpProxyAgent = require_env_http_proxy_agent(); var RetryAgent = require_retry_agent(); var errors = require_errors(); var util = require_util(); var { InvalidArgumentError } = errors; var api = require_api(); var buildConnector = require_connect(); var MockClient = require_mock_client(); var MockAgent = require_mock_agent(); var MockPool = require_mock_pool(); var mockErrors = require_mock_errors(); var RetryHandler = require_retry_handler(); var { getGlobalDispatcher, setGlobalDispatcher } = require_global2(); var DecoratorHandler = require_decorator_handler(); var RedirectHandler = require_redirect_handler(); var createRedirectInterceptor = require_redirect_interceptor(); Object.assign(Dispatcher.prototype, api); module.exports.Dispatcher = Dispatcher; module.exports.Client = Client; module.exports.Pool = Pool; module.exports.BalancedPool = BalancedPool; module.exports.Agent = Agent; module.exports.ProxyAgent = ProxyAgent; module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent; module.exports.RetryAgent = RetryAgent; module.exports.RetryHandler = RetryHandler; module.exports.DecoratorHandler = DecoratorHandler; module.exports.RedirectHandler = RedirectHandler; module.exports.createRedirectInterceptor = createRedirectInterceptor; module.exports.interceptors = { redirect: require_redirect(), retry: require_retry3(), dump: require_dump(), dns: require_dns() }; module.exports.buildConnector = buildConnector; module.exports.errors = errors; module.exports.util = { parseHeaders: util.parseHeaders, headerNameToString: util.headerNameToString }; function makeDispatcher(fn) { return (url, opts, handler) => { if (typeof opts === "function") { handler = opts; opts = null; } if (!url || typeof url !== "string" && typeof url !== "object" && !(url instanceof URL)) { throw new InvalidArgumentError("invalid url"); } if (opts != null && typeof opts !== "object") { throw new InvalidArgumentError("invalid opts"); } if (opts && opts.path != null) { if (typeof opts.path !== "string") { throw new InvalidArgumentError("invalid opts.path"); } let path14 = opts.path; if (!opts.path.startsWith("/")) { path14 = `/${path14}`; } url = new URL(util.parseOrigin(url).origin + path14); } else { if (!opts) { opts = typeof url === "object" ? url : {}; } url = util.parseURL(url); } const { agent, dispatcher = getGlobalDispatcher() } = opts; if (agent) { throw new InvalidArgumentError("unsupported opts.agent. Did you mean opts.client?"); } return fn.call(dispatcher, { ...opts, origin: url.origin, path: url.search ? `${url.pathname}${url.search}` : url.pathname, method: opts.method || (opts.body ? "PUT" : "GET") }, handler); }; } module.exports.setGlobalDispatcher = setGlobalDispatcher; module.exports.getGlobalDispatcher = getGlobalDispatcher; var fetchImpl = require_fetch().fetch; module.exports.fetch = async function fetch3(init, options = void 0) { try { return await fetchImpl(init, options); } catch (err) { if (err && typeof err === "object") { Error.captureStackTrace(err); } throw err; } }; module.exports.Headers = require_headers().Headers; module.exports.Response = require_response().Response; module.exports.Request = require_request2().Request; module.exports.FormData = require_formdata().FormData; module.exports.File = globalThis.File ?? __require("node:buffer").File; module.exports.FileReader = require_filereader().FileReader; var { setGlobalOrigin, getGlobalOrigin } = require_global(); module.exports.setGlobalOrigin = setGlobalOrigin; module.exports.getGlobalOrigin = getGlobalOrigin; var { CacheStorage } = require_cachestorage(); var { kConstruct } = require_symbols4(); module.exports.caches = new CacheStorage(kConstruct); var { deleteCookie, getCookies, getSetCookies, setCookie } = require_cookies(); module.exports.deleteCookie = deleteCookie; module.exports.getCookies = getCookies; module.exports.getSetCookies = getSetCookies; module.exports.setCookie = setCookie; var { parseMIMEType, serializeAMimeType } = require_data_url(); module.exports.parseMIMEType = parseMIMEType; module.exports.serializeAMimeType = serializeAMimeType; var { CloseEvent, ErrorEvent, MessageEvent } = require_events(); module.exports.WebSocket = require_websocket().WebSocket; module.exports.CloseEvent = CloseEvent; module.exports.ErrorEvent = ErrorEvent; module.exports.MessageEvent = MessageEvent; module.exports.request = makeDispatcher(api.request); module.exports.stream = makeDispatcher(api.stream); module.exports.pipeline = makeDispatcher(api.pipeline); module.exports.connect = makeDispatcher(api.connect); module.exports.upgrade = makeDispatcher(api.upgrade); module.exports.MockClient = MockClient; module.exports.MockPool = MockPool; module.exports.MockAgent = MockAgent; module.exports.mockErrors = mockErrors; var { EventSource } = require_eventsource(); module.exports.EventSource = EventSource; } }); // viewer/node_modules/throttleit/index.js var require_throttleit = __commonJS({ "viewer/node_modules/throttleit/index.js"(exports, module) { function throttle3(function_, wait) { if (typeof function_ !== "function") { throw new TypeError(`Expected the first argument to be a \`function\`, got \`${typeof function_}\`.`); } let timeoutId; let lastCallTime = 0; return function throttled(...arguments_) { clearTimeout(timeoutId); const now = Date.now(); const timeSinceLastCall = now - lastCallTime; const delayForNextCall = wait - timeSinceLastCall; if (delayForNextCall <= 0) { lastCallTime = now; function_.apply(this, arguments_); } else { timeoutId = setTimeout(() => { lastCallTime = Date.now(); function_.apply(this, arguments_); }, delayForNextCall); } }; } module.exports = throttle3; } }); // viewer/node_modules/@vercel/blob/dist/chunk-3D2SZ6M2.js import { Readable } from "stream"; async function toReadableStream(value) { if (value instanceof ReadableStream) { return value; } if (value instanceof Blob) { return value.stream(); } if (isNodeJsReadableStream(value)) { return Readable.toWeb(value); } let streamValue; if (value instanceof ArrayBuffer) { streamValue = new Uint8Array(value); } else if (isNodeJsBuffer(value)) { streamValue = value; } else { streamValue = stringToUint8Array(value); } if (await supportsNewBlobFromArrayBuffer) { return new Blob([streamValue]).stream(); } return new ReadableStream({ start(controller) { controller.enqueue(streamValue); controller.close(); } }); } function isNodeJsReadableStream(value) { return typeof value === "object" && typeof value.pipe === "function" && value.readable && typeof value._read === "function" && // @ts-expect-error _readableState does exists on Readable typeof value._readableState === "object"; } function stringToUint8Array(s) { const enc = new TextEncoder(); return enc.encode(s); } function isNodeJsBuffer(value) { return (0, import_is_buffer.default)(value); } function readEnv(name) { try { const value = process.env[name]; return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0; } catch { return void 0; } } function getVercelOidcToken() { var _a3; const tokenFromContext = (_a3 = getContext().headers) == null ? void 0 : _a3["x-vercel-oidc-token"]; if (typeof tokenFromContext === "string" && tokenFromContext.trim() !== "") { return tokenFromContext.trim(); } return readEnv("VERCEL_OIDC_TOKEN"); } function bytes(val) { if (typeof val === "number" && !Number.isNaN(val)) { return val; } if (typeof val !== "string") { return null; } const results = parseRegExp.exec(val); let floatValue; let unit = "b"; if (!results) { floatValue = parseInt(val, 10); } else { const [, res, , , unitMatch] = results; if (!res) { return null; } floatValue = parseFloat(res); if (unitMatch) { unit = unitMatch.toLowerCase(); } } if (Number.isNaN(floatValue)) { return null; } return Math.floor(map[unit] * floatValue); } function readEnv2(name) { try { const value = process.env[name]; return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0; } catch { return void 0; } } function parseStoreIdFromReadWriteToken(token) { const [, , , storeId = ""] = token.split("_"); return storeId; } function base64UrlDecodeDelegationSegment(segment) { let base64 = segment.replace(/-/g, "+").replace(/_/g, "/"); const padding = 4 - base64.length % 4; if (padding !== 4) { base64 += "=".repeat(padding); } if (typeof atob === "function") { return atob(base64); } if (typeof Buffer !== "undefined") { return Buffer.from(base64, "base64").toString("utf8"); } throw new BlobError("Cannot decode base64: no atob or Buffer available."); } function parseStoreIdFromDelegationToken(delegationToken) { const dot3 = delegationToken.indexOf("."); if (dot3 < 0) { throw new BlobError("Invalid delegation token format."); } const payloadSeg = delegationToken.slice(0, dot3); let parsed; try { parsed = JSON.parse(base64UrlDecodeDelegationSegment(payloadSeg)); } catch { throw new BlobError("Invalid delegation token payload."); } if (!parsed.storeId || typeof parsed.storeId !== "string") { throw new BlobError("Delegation token payload is missing `storeId`."); } return normalizeStoreId(parsed.storeId); } function parseStoreIdFromPresignedUrl(presignedUrlPayload) { const delegation = presignedUrlPayload.delegationToken; return parseStoreIdFromDelegationToken(delegation); } function normalizeStoreId(storeId) { return storeId.startsWith("store_") ? storeId.slice("store_".length) : storeId; } function resolveBlobAuth(options) { var _a3, _b2; if (options == null ? void 0 : options.presignedUrlPayload) { const storeId = parseStoreIdFromDelegationToken( options.presignedUrlPayload.delegationToken ); return { kind: "presigned", storeId }; } if (options == null ? void 0 : options.token) { const storeId = parseStoreIdFromReadWriteToken(options.token); return { kind: "readWrite", token: options.token, storeId }; } const manualOidcToken = (_a3 = options == null ? void 0 : options.oidcToken) == null ? void 0 : _a3.trim(); const oidcToken = manualOidcToken || getVercelOidcToken(); if (oidcToken) { const manualStoreId = (_b2 = options == null ? void 0 : options.storeId) == null ? void 0 : _b2.trim(); if (manualStoreId) { return { kind: "oidc", token: oidcToken, storeId: normalizeStoreId(manualStoreId) }; } const blobStoreId = readEnv2("BLOB_STORE_ID"); if (blobStoreId) { return { kind: "oidc", token: oidcToken, storeId: normalizeStoreId(blobStoreId) }; } if (manualOidcToken) { throw new BlobError( "oidcToken was passed, but no storeId was found. Pass a `storeId` option or set `BLOB_STORE_ID` to use OIDC auth" ); } } const readWrite = readEnv2("BLOB_READ_WRITE_TOKEN"); if (readWrite) { const storeId = parseStoreIdFromReadWriteToken(readWrite); return { kind: "readWrite", token: readWrite, storeId }; } throw new BlobError( "No blob credentials found. Pass a `token` option, set `BLOB_READ_WRITE_TOKEN`, or use `oidcToken` (or `VERCEL_OIDC_TOKEN`) with `storeId` or `BLOB_STORE_ID`." ); } function getDownloadUrl(blobUrl) { const url = new URL(blobUrl); url.searchParams.set("download", "1"); return url.toString(); } function isPlainObject(value) { if (typeof value !== "object" || value === null) { return false; } const prototype = Object.getPrototypeOf(value); return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value); } function getApiUrl(pathname = "") { let baseUrl = null; try { baseUrl = process.env.VERCEL_BLOB_API_URL || process.env.NEXT_PUBLIC_VERCEL_BLOB_API_URL; } catch { } return `${baseUrl || defaultVercelBlobApiUrl}${pathname}`; } function computeBodyLength(body) { if (!body) { return 0; } if (typeof body === "string") { if (TEXT_ENCODER) { return TEXT_ENCODER.encode(body).byteLength; } return new Blob([body]).size; } if ("byteLength" in body && typeof body.byteLength === "number") { return body.byteLength; } if ("size" in body && typeof body.size === "number") { return body.size; } return 0; } function isReadableStream(value) { return globalThis.ReadableStream && // TODO: Can be removed once Node.js 16 is no more required internally value instanceof ReadableStream; } function isStream(value) { if (isReadableStream(value)) { return true; } if (isNodeJsReadableStream(value)) { return true; } return false; } function isUrl(urlOrPathname) { return urlOrPathname.startsWith("http://") || urlOrPathname.startsWith("https://"); } function constructBlobUrl(storeId, pathname, access) { return `https://${storeId}.${access}.blob.vercel-storage.com/${pathname}`; } function debug(message, ...args) { if (debugIsActive) { console.debug(`vercel-blob: ${message}`, ...args); } } function isNetworkError(error) { const isValid = error && isError(error) && error.name === "TypeError" && typeof error.message === "string"; if (!isValid) { return false; } if (error.message === "Load failed") { return error.stack === void 0; } return errorMessages.has(error.message); } function getApiVersion() { let versionOverride = null; try { versionOverride = process.env.VERCEL_BLOB_API_VERSION_OVERRIDE || process.env.NEXT_PUBLIC_VERCEL_BLOB_API_VERSION_OVERRIDE; } catch { } return `${versionOverride != null ? versionOverride : BLOB_API_VERSION}`; } function getRetries() { try { const retries = process.env.VERCEL_BLOB_RETRIES || "10"; return parseInt(retries, 10); } catch { return 10; } } function createBlobServiceRateLimited(response) { const retryAfter = response.headers.get("retry-after"); return new BlobServiceRateLimited( retryAfter ? parseInt(retryAfter, 10) : void 0 ); } async function getBlobError(response) { var _a3, _b2, _c; let code; let message; try { const data = await response.json(); code = (_b2 = (_a3 = data.error) == null ? void 0 : _a3.code) != null ? _b2 : "unknown_error"; message = (_c = data.error) == null ? void 0 : _c.message; } catch { code = "unknown_error"; } if ((message == null ? void 0 : message.includes("contentType")) && message.includes("is not allowed")) { code = "content_type_not_allowed"; } if ((message == null ? void 0 : message.includes('"pathname"')) && message.includes("does not match the token payload")) { code = "client_token_pathname_mismatch"; } if (message === "Token expired") { code = "client_token_expired"; } if (message == null ? void 0 : message.includes("the file length cannot be greater than")) { code = "file_too_large"; } if ((message == null ? void 0 : message.startsWith("OIDC is enabled for this project, but not for the")) && message.includes("environment.")) { code = "oidc_environment_not_allowed"; } let error; switch (code) { case "store_suspended": error = new BlobStoreSuspendedError(); break; case "forbidden": error = new BlobAccessError(); break; case "oidc_environment_not_allowed": error = new BlobOidcEnvironmentNotAllowedError(message); break; case "content_type_not_allowed": error = new BlobContentTypeNotAllowedError(message); break; case "client_token_pathname_mismatch": error = new BlobPathnameMismatchError(message); break; case "client_token_expired": error = new BlobClientTokenExpiredError(); break; case "file_too_large": error = new BlobFileTooLargeError(message); break; case "not_found": error = new BlobNotFoundError(); break; case "client_token_not_allowed": error = new BlobError( message != null ? message : "This operation is not available when using a client token. Use a read\u2013write or OIDC token on the server." ); break; case "store_not_found": error = new BlobStoreNotFoundError(); break; case "bad_request": error = new BlobError(message != null ? message : "Bad request"); break; case "service_unavailable": error = new BlobServiceNotAvailable(); break; case "rate_limited": error = createBlobServiceRateLimited(response); break; case "precondition_failed": error = new BlobPreconditionFailedError(); break; case "unknown_error": case "not_allowed": default: error = new BlobUnknownError(); break; } return { code, error }; } async function requestApi(pathname, init, commandOptions) { const apiVersion = getApiVersion(); const auth = resolveBlobAuth(commandOptions); const bearerToken = auth.kind === "presigned" ? void 0 : auth.token; const extraHeaders = getProxyThroughAlternativeApiHeaderFromEnv(); let requestInput = getApiUrl(pathname); if (commandOptions == null ? void 0 : commandOptions.presignedUrlPayload) { requestInput = addPresignedParams( requestInput, commandOptions.presignedUrlPayload ); } const requestId = `${auth.storeId}:${Date.now()}:${Math.random().toString(16).slice(2)}`; let retryCount = 0; let bodyLength = 0; let totalLoaded = 0; const sendBodyLength = (commandOptions == null ? void 0 : commandOptions.onUploadProgress) || shouldUseXContentLength(); if (init.body && // 1. For upload progress we always need to know the total size of the body // 2. In development we need the header for put() to work correctly when passing a stream sendBodyLength) { bodyLength = computeBodyLength(init.body); } if (commandOptions == null ? void 0 : commandOptions.onUploadProgress) { commandOptions.onUploadProgress({ loaded: 0, total: bodyLength, percentage: 0 }); } const apiResponse = await (0, import_async_retry.default)( async (bail) => { let res; try { res = await blobRequest({ input: requestInput, init: { ...init, headers: { "x-api-blob-request-id": requestId, // Store ID is not encoded in OIDC token, so pass it separately as a header "x-vercel-blob-store-id": auth.storeId, "x-api-blob-request-attempt": String(retryCount), "x-api-version": apiVersion, ...sendBodyLength ? { "x-content-length": String(bodyLength) } : {}, ...bearerToken !== void 0 ? { authorization: `Bearer ${bearerToken}` } : {}, ...extraHeaders, ...init.headers } }, onUploadProgress: (commandOptions == null ? void 0 : commandOptions.onUploadProgress) ? (loaded) => { var _a3; const total = bodyLength !== 0 ? bodyLength : loaded; totalLoaded = loaded; const percentage = bodyLength > 0 ? Number((loaded / total * 100).toFixed(2)) : 0; if (percentage === 100 && bodyLength > 0) { return; } (_a3 = commandOptions.onUploadProgress) == null ? void 0 : _a3.call(commandOptions, { loaded, // When passing a stream to put(), we have no way to know the total size of the body. // Instead of defining total as total?: number we decided to set the total to the currently // loaded number. This is not inaccurate and way more practical for DX. // Passing down a stream to put() is very rare total, percentage }); } : void 0 }); } catch (error2) { if (error2 instanceof DOMException2 && error2.name === "AbortError") { bail(new BlobRequestAbortedError()); return; } if (isNetworkError(error2)) { throw error2; } if (error2 instanceof TypeError) { bail(error2); return; } throw error2; } if (res.ok) { return res; } const { code, error } = await getBlobError(res); if (code === "unknown_error" || code === "service_unavailable" || code === "internal_server_error") { throw error; } bail(error); }, { retries: getRetries(), onRetry: (error) => { if (error instanceof Error) { debug(`retrying API request to ${pathname}`, error.message); } retryCount = retryCount + 1; } } ); if (!apiResponse) { throw new BlobUnknownError(); } if (commandOptions == null ? void 0 : commandOptions.onUploadProgress) { commandOptions.onUploadProgress({ loaded: totalLoaded, total: totalLoaded, percentage: 100 }); } return await apiResponse.json(); } function getProxyThroughAlternativeApiHeaderFromEnv() { const extraHeaders = {}; try { if ("VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API" in process.env && process.env.VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API !== void 0) { extraHeaders["x-proxy-through-alternative-api"] = process.env.VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API; } else if ("NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API" in process.env && process.env.NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API !== void 0) { extraHeaders["x-proxy-through-alternative-api"] = process.env.NEXT_PUBLIC_VERCEL_BLOB_PROXY_THROUGH_ALTERNATIVE_API; } } catch { } return extraHeaders; } function shouldUseXContentLength() { try { return process.env.VERCEL_BLOB_USE_X_CONTENT_LENGTH === "1"; } catch { return false; } } function createPutHeaders(allowedOptions, options) { const headers = {}; headers[putOptionHeaderMap.access] = options.access; if (allowedOptions.includes("contentType") && options.contentType) { headers[putOptionHeaderMap.contentType] = options.contentType; } if (allowedOptions.includes("addRandomSuffix") && options.addRandomSuffix !== void 0) { headers[putOptionHeaderMap.addRandomSuffix] = options.addRandomSuffix ? "1" : "0"; } if (allowedOptions.includes("ifMatch") && options.ifMatch) { if (options.allowOverwrite === false) { throw new BlobError( "ifMatch and allowOverwrite: false are contradictory. ifMatch is used for conditional overwrites, which requires allowOverwrite to be true." ); } headers[putOptionHeaderMap.ifMatch] = options.ifMatch; if (allowedOptions.includes("allowOverwrite") && options.allowOverwrite === void 0) { headers[putOptionHeaderMap.allowOverwrite] = "1"; } } if (allowedOptions.includes("allowOverwrite") && options.allowOverwrite !== void 0) { headers[putOptionHeaderMap.allowOverwrite] = options.allowOverwrite ? "1" : "0"; } if (allowedOptions.includes("cacheControlMaxAge") && options.cacheControlMaxAge !== void 0) { headers[putOptionHeaderMap.cacheControlMaxAge] = options.cacheControlMaxAge.toString(); } return headers; } async function createPutOptions({ pathname, options, extraChecks, getToken }) { if (!pathname) { throw new BlobError("pathname is required"); } if (pathname.length > MAXIMUM_PATHNAME_LENGTH) { throw new BlobError( `pathname is too long, maximum length is ${MAXIMUM_PATHNAME_LENGTH}` ); } for (const invalidCharacter of disallowedPathnameCharacters) { if (pathname.includes(invalidCharacter)) { throw new BlobError( `pathname cannot contain "${invalidCharacter}", please encode it if needed` ); } } if (!options) { throw new BlobError("missing options, see usage"); } if (options.access !== "public" && options.access !== "private") { throw new BlobError( 'access must be "private" or "public", see https://vercel.com/docs/vercel-blob' ); } if (extraChecks) { extraChecks(options); } if (getToken) { options.token = await getToken(pathname, options); } return options; } function createCompleteMultipartUploadMethod({ allowedOptions, getToken, extraChecks }) { return async (pathname, parts, optionsInput) => { const options = await createPutOptions({ pathname, options: optionsInput, extraChecks, getToken }); const headers = createPutHeaders(allowedOptions, options); return completeMultipartUpload({ uploadId: options.uploadId, key: options.key, pathname, headers, options, parts }); }; } async function completeMultipartUpload({ uploadId, key, pathname, parts, headers, options }) { const params = new URLSearchParams({ pathname }); try { const response = await requestApi( `/mpu?${params.toString()}`, { method: "POST", headers: { ...headers, "content-type": "application/json", "x-mpu-action": "complete", "x-mpu-upload-id": uploadId, // key can be any utf8 character so we need to encode it as HTTP headers can only be us-ascii // https://www.rfc-editor.org/rfc/rfc7230#swection-3.2.4 "x-mpu-key": encodeURIComponent(key) }, body: JSON.stringify(parts), signal: options.abortSignal }, options ); debug("mpu: complete", response); return response; } catch (error) { if (error instanceof TypeError && (error.message === "Failed to fetch" || error.message === "fetch failed")) { throw new BlobServiceNotAvailable(); } else { throw error; } } } function createCreateMultipartUploadMethod({ allowedOptions, getToken, extraChecks }) { return async (pathname, optionsInput) => { const options = await createPutOptions({ pathname, options: optionsInput, extraChecks, getToken }); const headers = createPutHeaders(allowedOptions, options); const createMultipartUploadResponse = await createMultipartUpload( pathname, headers, options ); return { key: createMultipartUploadResponse.key, uploadId: createMultipartUploadResponse.uploadId }; }; } async function createMultipartUpload(pathname, headers, options) { debug("mpu: create", "pathname:", pathname); const params = new URLSearchParams({ pathname }); try { const response = await requestApi( `/mpu?${params.toString()}`, { method: "POST", headers: { ...headers, "x-mpu-action": "create" }, signal: options.abortSignal }, options ); debug("mpu: create", response); return response; } catch (error) { if (error instanceof TypeError && (error.message === "Failed to fetch" || error.message === "fetch failed")) { throw new BlobServiceNotAvailable(); } throw error; } } function createUploadPartMethod({ allowedOptions, getToken, extraChecks }) { return async (pathname, body, optionsInput) => { const options = await createPutOptions({ pathname, options: optionsInput, extraChecks, getToken }); const headers = createPutHeaders(allowedOptions, options); if (isPlainObject(body)) { throw new BlobError( "Body must be a string, buffer or stream. You sent a plain JavaScript object, double check what you're trying to upload." ); } const result = await uploadPart({ uploadId: options.uploadId, key: options.key, pathname, part: { blob: body, partNumber: options.partNumber }, headers, options }); return { etag: result.etag, partNumber: options.partNumber }; }; } async function uploadPart({ uploadId, key, pathname, headers, options, internalAbortController = new AbortController(), part }) { var _a3, _b2, _c; const params = new URLSearchParams({ pathname }); const responsePromise = requestApi( `/mpu?${params.toString()}`, { signal: internalAbortController.signal, method: "POST", headers: { ...headers, "x-mpu-action": "upload", "x-mpu-key": encodeURIComponent(key), "x-mpu-upload-id": uploadId, "x-mpu-part-number": part.partNumber.toString() }, // weird things between undici types and native fetch types body: part.blob }, options ); function handleAbort() { internalAbortController.abort(); } if ((_a3 = options.abortSignal) == null ? void 0 : _a3.aborted) { handleAbort(); } else { (_b2 = options.abortSignal) == null ? void 0 : _b2.addEventListener("abort", handleAbort); } const response = await responsePromise; (_c = options.abortSignal) == null ? void 0 : _c.removeEventListener("abort", handleAbort); return response; } function uploadAllParts({ uploadId, key, pathname, stream, headers, options, totalToLoad }) { debug("mpu: upload init", "key:", key); const internalAbortController = new AbortController(); return new Promise((resolve, reject) => { const partsToUpload = []; const completedParts = []; const reader = stream.getReader(); let activeUploads = 0; let reading = false; let currentPartNumber = 1; let rejected = false; let currentBytesInMemory = 0; let doneReading = false; let bytesSent = 0; let arrayBuffers = []; let currentPartBytesRead = 0; let onUploadProgress; const totalLoadedPerPartNumber = {}; if (options.onUploadProgress) { onUploadProgress = (0, import_throttleit.default)(() => { var _a3; const loaded = Object.values(totalLoadedPerPartNumber).reduce( (acc, cur) => { return acc + cur; }, 0 ); const total = totalToLoad || loaded; const percentage = totalToLoad > 0 ? Number(((loaded / totalToLoad || loaded) * 100).toFixed(2)) : 0; (_a3 = options.onUploadProgress) == null ? void 0 : _a3.call(options, { loaded, total, percentage }); }, 150); } read().catch(cancel); async function read() { debug( "mpu: upload read start", "activeUploads:", activeUploads, "currentBytesInMemory:", `${bytes(currentBytesInMemory)}/${bytes(maxBytesInMemory)}`, "bytesSent:", bytes(bytesSent) ); reading = true; while (currentBytesInMemory < maxBytesInMemory && !rejected) { try { const { value, done } = await reader.read(); if (done) { doneReading = true; debug("mpu: upload read consumed the whole stream"); if (arrayBuffers.length > 0) { partsToUpload.push({ partNumber: currentPartNumber++, blob: new Blob(arrayBuffers, { type: "application/octet-stream" }) }); sendParts(); } else if (activeUploads === 0) { reader.releaseLock(); resolve(completedParts); } reading = false; return; } currentBytesInMemory += value.byteLength; let valueOffset = 0; while (valueOffset < value.byteLength) { const remainingPartSize = partSizeInBytes - currentPartBytesRead; const endOffset = Math.min( valueOffset + remainingPartSize, value.byteLength ); const chunk = value.slice(valueOffset, endOffset); arrayBuffers.push(chunk); currentPartBytesRead += chunk.byteLength; valueOffset = endOffset; if (currentPartBytesRead === partSizeInBytes) { partsToUpload.push({ partNumber: currentPartNumber++, blob: new Blob(arrayBuffers, { type: "application/octet-stream" }) }); arrayBuffers = []; currentPartBytesRead = 0; sendParts(); } } } catch (error) { cancel(error); } } debug( "mpu: upload read end", "activeUploads:", activeUploads, "currentBytesInMemory:", `${bytes(currentBytesInMemory)}/${bytes(maxBytesInMemory)}`, "bytesSent:", bytes(bytesSent) ); reading = false; } async function sendPart(part) { activeUploads++; debug( "mpu: upload send part start", "partNumber:", part.partNumber, "size:", part.blob.size, "activeUploads:", activeUploads, "currentBytesInMemory:", `${bytes(currentBytesInMemory)}/${bytes(maxBytesInMemory)}`, "bytesSent:", bytes(bytesSent) ); try { const uploadProgressForPart = options.onUploadProgress ? (event) => { totalLoadedPerPartNumber[part.partNumber] = event.loaded; if (onUploadProgress) { onUploadProgress(); } } : void 0; const completedPart = await uploadPart({ uploadId, key, pathname, headers, options: { ...options, onUploadProgress: uploadProgressForPart }, internalAbortController, part }); debug( "mpu: upload send part end", "partNumber:", part.partNumber, "activeUploads", activeUploads, "currentBytesInMemory:", `${bytes(currentBytesInMemory)}/${bytes(maxBytesInMemory)}`, "bytesSent:", bytes(bytesSent) ); if (rejected) { return; } completedParts.push({ partNumber: part.partNumber, etag: completedPart.etag }); currentBytesInMemory -= part.blob.size; activeUploads--; bytesSent += part.blob.size; if (partsToUpload.length > 0) { sendParts(); } if (doneReading) { if (activeUploads === 0) { reader.releaseLock(); resolve(completedParts); } return; } if (!reading) { read().catch(cancel); } } catch (error) { cancel(error); } } function sendParts() { if (rejected) { return; } debug( "send parts", "activeUploads", activeUploads, "partsToUpload", partsToUpload.length ); while (activeUploads < maxConcurrentUploads && partsToUpload.length > 0) { const partToSend = partsToUpload.shift(); if (partToSend) { void sendPart(partToSend); } } } function cancel(error) { if (rejected) { return; } rejected = true; internalAbortController.abort(); reader.releaseLock(); if (error instanceof TypeError && (error.message === "Failed to fetch" || error.message === "fetch failed")) { reject(new BlobServiceNotAvailable()); } else { reject(error); } } }); } function createCreateMultipartUploaderMethod({ allowedOptions, getToken, extraChecks }) { return async (pathname, optionsInput) => { const options = await createPutOptions({ pathname, options: optionsInput, extraChecks, getToken }); const headers = createPutHeaders(allowedOptions, options); const createMultipartUploadResponse = await createMultipartUpload( pathname, headers, options ); return { key: createMultipartUploadResponse.key, uploadId: createMultipartUploadResponse.uploadId, async uploadPart(partNumber, body) { if (isPlainObject(body)) { throw new BlobError( "Body must be a string, buffer or stream. You sent a plain JavaScript object, double check what you're trying to upload." ); } const result = await uploadPart({ uploadId: createMultipartUploadResponse.uploadId, key: createMultipartUploadResponse.key, pathname, part: { partNumber, blob: body }, headers, options }); return { etag: result.etag, partNumber }; }, async complete(parts) { return completeMultipartUpload({ uploadId: createMultipartUploadResponse.uploadId, key: createMultipartUploadResponse.key, pathname, parts, headers, options }); } }; }; } async function uncontrolledMultipartUpload(pathname, body, headers, options) { debug("mpu: init", "pathname:", pathname, "headers:", headers); const optionsWithoutOnUploadProgress = { ...options, onUploadProgress: void 0 }; if (options.maximumSizeInBytes !== void 0 && !isStream(body) && computeBodyLength(body) > options.maximumSizeInBytes) { throw new BlobError( `Body size of ${computeBodyLength(body)} bytes exceeds the maximum allowed size of ${options.maximumSizeInBytes} bytes` ); } const createMultipartUploadResponse = await createMultipartUpload( pathname, headers, optionsWithoutOnUploadProgress ); const totalToLoad = computeBodyLength(body); const stream = await toReadableStream(body); const parts = await uploadAllParts({ uploadId: createMultipartUploadResponse.uploadId, key: createMultipartUploadResponse.key, pathname, // @ts-expect-error ReadableStream is compatible at runtime stream, headers, options, totalToLoad }); const blob = await completeMultipartUpload({ uploadId: createMultipartUploadResponse.uploadId, key: createMultipartUploadResponse.key, pathname, parts, headers, options: optionsWithoutOnUploadProgress }); return blob; } function createPutMethod({ allowedOptions, getToken, getPresignedUrlPayload, extraChecks }) { return async function put2(pathname, body, optionsInput) { if (!body) { throw new BlobError("body is required"); } if (isPlainObject(body)) { throw new BlobError( "Body must be a string, buffer or stream. You sent a plain JavaScript object, double check what you're trying to upload." ); } const options = await createPutOptions({ pathname, options: optionsInput, extraChecks, getToken }); const presignedUrlPayload = await (getPresignedUrlPayload == null ? void 0 : getPresignedUrlPayload( pathname, options )); const optionsWithPresignedUrlPayload = { ...options, presignedUrlPayload }; const headers = createPutHeaders(allowedOptions, options); if (options.multipart === true) { return uncontrolledMultipartUpload( pathname, body, headers, optionsWithPresignedUrlPayload ); } const onUploadProgress = options.onUploadProgress ? (0, import_throttleit2.default)(options.onUploadProgress, 100) : void 0; const params = new URLSearchParams({ pathname }); const response = await requestApi( `/?${params.toString()}`, { method: "PUT", body, headers, signal: options.abortSignal }, { ...optionsWithPresignedUrlPayload, onUploadProgress } ); return { url: response.url, downloadUrl: response.downloadUrl, pathname: response.pathname, contentType: response.contentType, contentDisposition: response.contentDisposition, etag: response.etag }; }; } function contentTypeAllowedByList(contentType, allowed) { const [type] = contentType.split("/"); const wildcard = `${type}/*`; return allowed.includes(contentType) || (type ? allowed.includes(wildcard) : false); } function assertAllowedContentTypesSubset(optionsTypes, delegationTypes, label) { if (!(optionsTypes == null ? void 0 : optionsTypes.length)) { return; } if (!(delegationTypes == null ? void 0 : delegationTypes.length)) { return; } for (const ct of optionsTypes) { if (!contentTypeAllowedByList(ct, delegationTypes)) { throw new Error( `${label}: allowedContentTypes entry "${ct}" is not permitted by the delegation token.` ); } } } function assertNumberSubset(name, optionVal, delegationVal, label, mode) { if (optionVal === void 0) { return; } if (delegationVal === void 0) { return; } if (mode === "lte" && optionVal > delegationVal) { throw new Error( `${label}: ${name} must be \u2264 delegation (${String(delegationVal)}).` ); } } function isPlausibleAbsoluteUrl(s) { if (typeof URL !== "undefined" && typeof URL.canParse === "function") { return URL.canParse(s); } try { new URL(s); return true; } catch { return false; } } function validatePresignUrlOnUploadCompletedWire(opt, label) { if (!opt) { return; } if (typeof opt.callbackUrl !== "string" || opt.callbackUrl.length === 0) { throw new Error( `${label}: onUploadCompleted.callbackUrl must be a non-empty string.` ); } if (opt.callbackUrl.length > MAX_PRESIGN_CALLBACK_URL_CHARS) { throw new Error(`${label}: onUploadCompleted.callbackUrl is too long.`); } if (!isPlausibleAbsoluteUrl(opt.callbackUrl)) { throw new Error( `${label}: onUploadCompleted.callbackUrl must be a valid URL.` ); } if (opt.tokenPayload !== void 0 && opt.tokenPayload !== null) { if (typeof opt.tokenPayload !== "string") { throw new Error( `${label}: onUploadCompleted.tokenPayload must be a string.` ); } if (opt.tokenPayload.length > MAX_PRESIGN_CALLBACK_TOKEN_PAYLOAD_CHARS) { throw new Error(`${label}: onUploadCompleted.tokenPayload is too long.`); } } } function validateUrlOnlyPresignUploadOptions(urlOptions, label) { if (urlOptions.cacheControlMaxAge !== void 0) { const n = urlOptions.cacheControlMaxAge; if (!Number.isInteger(n) || n < 0 || n > MAX_PRESIGN_CACHE_CONTROL_MAX_AGE_SECONDS) { throw new Error( `${label}: cacheControlMaxAge must be an integer between 0 and ${MAX_PRESIGN_CACHE_CONTROL_MAX_AGE_SECONDS}.` ); } } if (urlOptions.ifMatch !== void 0) { const im = urlOptions.ifMatch; if (typeof im !== "string" || im.length === 0) { throw new Error(`${label}: ifMatch must be a non-empty string.`); } if (im.length > MAX_PRESIGN_IF_MATCH_LENGTH) { throw new Error(`${label}: ifMatch is too long.`); } if (IF_MATCH_CONTROL_CHARS_RE.test(im)) { throw new Error( `${label}: ifMatch contains disallowed control characters.` ); } } } function sortedContentTypesCsv(types) { return [...types].sort((a, b) => a < b ? -1 : a > b ? 1 : 0).join(","); } function resolvePresignUrlValidUntilMs(args) { const { delegationValidUntil, urlOptions, nowMs } = args; let t; if ((urlOptions == null ? void 0 : urlOptions.validUntil) !== void 0) { if (typeof urlOptions.validUntil !== "number" || !Number.isFinite(urlOptions.validUntil)) { throw new Error("presignUrl: validUntil must be a finite number (ms)."); } t = Math.trunc(urlOptions.validUntil); } else { t = Math.trunc(delegationValidUntil); } if (Number.isFinite(delegationValidUntil)) { t = Math.min(t, Math.trunc(delegationValidUntil)); } if (t <= nowMs) { throw new Error( "presignUrl: resolved URL expiry is not after the current time; issue a new delegation token or pass a later validUntil." ); } return t; } function buildPresignCanonicalQueryEntries(args) { const { operation, delegation, urlOptions, nowMs } = args; const label = "presignUrl"; const resolvedUntil = resolvePresignUrlValidUntilMs({ delegationValidUntil: delegation.validUntil, urlOptions, nowMs }); const delegUntil = Math.trunc(delegation.validUntil); const entries = []; if (resolvedUntil < delegUntil) { entries.push([BLOB_PRESIGN_QUERY_VALID_UNTIL, String(resolvedUntil)]); } if (operation === "delete") { if ((urlOptions == null ? void 0 : urlOptions.ifMatch) !== void 0) { entries.push([BLOB_PRESIGN_QUERY_IF_MATCH, urlOptions.ifMatch]); } return entries; } if (operation !== "put" || !urlOptions) { return entries; } assertAllowedContentTypesSubset( urlOptions.allowedContentTypes, delegation.allowedContentTypes, label ); assertNumberSubset( "maximumSizeInBytes", urlOptions.maximumSizeInBytes, delegation.maximumSizeInBytes, label, "lte" ); validateUrlOnlyPresignUploadOptions(urlOptions, label); validatePresignUrlOnUploadCompletedWire(urlOptions.onUploadCompleted, label); if (urlOptions.allowedContentTypes !== void 0) { const csv = sortedContentTypesCsv(urlOptions.allowedContentTypes); if (csv.length > 16384) { throw new Error(`${label}: allowedContentTypes query value is too long.`); } entries.push([BLOB_PRESIGN_QUERY_ALLOWED_CONTENT_TYPES, csv]); } if (urlOptions.maximumSizeInBytes !== void 0) { entries.push([ BLOB_PRESIGN_QUERY_MAXIMUM_SIZE, String(Math.trunc(urlOptions.maximumSizeInBytes)) ]); } if (urlOptions.addRandomSuffix !== void 0) { entries.push([ BLOB_PRESIGN_QUERY_ADD_RANDOM_SUFFIX, urlOptions.addRandomSuffix ? "true" : "false" ]); } if (urlOptions.allowOverwrite !== void 0) { entries.push([ BLOB_PRESIGN_QUERY_ALLOW_OVERWRITE, urlOptions.allowOverwrite ? "true" : "false" ]); } if (urlOptions.cacheControlMaxAge !== void 0) { entries.push([ BLOB_PRESIGN_QUERY_CACHE_CONTROL_MAX_AGE, String(Math.trunc(urlOptions.cacheControlMaxAge)) ]); } if (urlOptions.ifMatch !== void 0) { entries.push([BLOB_PRESIGN_QUERY_IF_MATCH, urlOptions.ifMatch]); } if (urlOptions.onUploadCompleted !== void 0) { const { callbackUrl, tokenPayload } = urlOptions.onUploadCompleted; if (callbackUrl.length > MAX_PRESIGN_CALLBACK_URL_CHARS) { throw new Error(`${label}: onUploadCompleted.callbackUrl is too long.`); } entries.push([BLOB_PRESIGN_QUERY_CALLBACK_URL, callbackUrl]); if (tokenPayload !== void 0 && tokenPayload !== null && tokenPayload !== "") { if (tokenPayload.length > MAX_PRESIGN_CALLBACK_TOKEN_PAYLOAD_CHARS) { throw new Error( `${label}: onUploadCompleted.tokenPayload is too long.` ); } entries.push([BLOB_PRESIGN_QUERY_CALLBACK_TOKEN_PAYLOAD, tokenPayload]); } } return entries; } function assertIssueSignedTokenValidUntilOption(validUntil) { const now = Date.now(); if (typeof validUntil !== "number" || !Number.isInteger(validUntil) || !Number.isFinite(validUntil)) { throw new BlobError( "`issueSignedToken`: validUntil must be an integer milliseconds timestamp." ); } if (validUntil <= now) { throw new BlobError( "`issueSignedToken`: validUntil must be in the future." ); } } async function issueSignedToken(options) { if (!options) { throw new BlobError("`issueSignedToken` requires an options object"); } const body = {}; if (options.pathname !== void 0) { body.pathname = options.pathname; } if (options.operations !== void 0) { if (options.operations.length === 0) { throw new BlobError("`operations` must be a non-empty array if provided"); } body.operations = dedupeOps(options.operations); } if (options.validUntil !== void 0) { assertIssueSignedTokenValidUntilOption(options.validUntil); body.validUntil = options.validUntil; } if (options.maximumSizeInBytes !== void 0) { body.maximumSizeInBytes = options.maximumSizeInBytes; } if (options.allowedContentTypes !== void 0) { body.allowedContentTypes = options.allowedContentTypes; } return requestApi( "/signed-token", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body), signal: options.abortSignal }, options ); } function dedupeOps(operations) { return Array.from(new Set(operations)); } function base64UrlDecodeToString(segment) { let base64 = segment.replace(/-/g, "+").replace(/_/g, "/"); const padding = 4 - base64.length % 4; if (padding !== 4) { base64 += "=".repeat(padding); } if (typeof atob === "function") { return atob(base64); } if (typeof Buffer !== "undefined") { return Buffer.from(base64, "base64").toString("utf8"); } throw new BlobError("Cannot decode base64: no atob or Buffer available."); } function tryDecodePayload(delegationToken) { const dot3 = delegationToken.indexOf("."); if (dot3 < 0) { return null; } const payloadSeg = delegationToken.slice(0, dot3); try { return JSON.parse( base64UrlDecodeToString(payloadSeg) ); } catch { return null; } } function uint8ToBase64(bytes2) { if (typeof Buffer !== "undefined") { return Buffer.from( bytes2.buffer, bytes2.byteOffset, bytes2.byteLength ).toString("base64"); } let s = ""; for (let i = 0; i < bytes2.length; i++) { s += String.fromCharCode(bytes2[i]); } return btoa(s); } async function hmacSha256Base64Url(key, data) { var _a3; if (!((_a3 = globalThis.crypto) == null ? void 0 : _a3.subtle)) { throw new BlobError( "HMAC is not available: expected globalThis.crypto.subtle (Node 20+ or a modern browser)." ); } const enc = new TextEncoder(); const cryptoKey = await globalThis.crypto.subtle.importKey( "raw", enc.encode(key), { name: "HMAC", hash: "SHA-256" }, false, ["sign"] ); const buf = await globalThis.crypto.subtle.sign( "HMAC", cryptoKey, enc.encode(data) ); return toBase64Url(uint8ToBase64(new Uint8Array(buf))); } function toBase64Url(base64) { return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); } async function presign(signedToken, options) { var _a3, _b2, _c, _d; if (!(signedToken == null ? void 0 : signedToken.clientSigningToken) || !(signedToken == null ? void 0 : signedToken.delegationToken)) { throw new BlobError( "`clientSigningToken` and `delegationToken` from `issueSignedToken` are required." ); } const scope = tryDecodePayload(signedToken.delegationToken); if (!scope) { throw new BlobError("Invalid or unreadable `delegationToken` payload."); } const p = scope.pathname; if (p && p !== "*") { if (options.pathname !== p) { throw new BlobError( `Blob path does not match the signed token scope; expected \`${p}\`, got \`${options.pathname}\`.` ); } } if (Number.isFinite(scope.validUntil) && Date.now() > scope.validUntil) { throw new BlobError( "The signed delegation has expired; issue a new token first." ); } if (options.operation === "get" && !((_a3 = scope.operations) == null ? void 0 : _a3.includes("get"))) { throw new BlobError( 'The delegation token is not valid for `GET` requests. Include `"get"` in `operations` when calling `issueSignedToken`.' ); } if (options.operation === "head" && !((_b2 = scope.operations) == null ? void 0 : _b2.includes("head"))) { throw new BlobError( 'The delegation token is not valid for `HEAD` requests. Include `"head"` in `operations` when calling `issueSignedToken`.' ); } if (options.operation === "put" && !((_c = scope.operations) == null ? void 0 : _c.includes("put"))) { throw new BlobError( 'The delegation token is not valid for presigned write requests. Include `"put"` in `operations` when calling `issueSignedToken`.' ); } if (options.operation === "delete" && !((_d = scope.operations) == null ? void 0 : _d.includes("delete"))) { throw new BlobError( 'The delegation token is not valid for presigned delete requests. Include `"delete"` in `operations` when calling `issueSignedToken`.' ); } const delegationForOptions = { validUntil: scope.validUntil, maximumSizeInBytes: scope.maximumSizeInBytes, allowedContentTypes: scope.allowedContentTypes }; let presignEntries; try { presignEntries = buildPresignCanonicalQueryEntries({ operation: options.operation, delegation: delegationForOptions, urlOptions: options, nowMs: Date.now() }); } catch (e) { const msg = e instanceof Error ? e.message : String(e); throw new BlobError(msg); } const canonical = canonicalString( options.pathname, presignEntries, options.operation ); const signature = await hmacSha256Base64Url( signedToken.clientSigningToken, canonical ); return { delegationToken: signedToken.delegationToken, signature, params: Object.fromEntries(presignEntries) }; } function buildPresignedGetUrl(pathnameOrUrl, presignedUrlPayload, options) { const storeId = parseStoreIdFromDelegationToken( presignedUrlPayload.delegationToken ); const blobUrl = isUrl(pathnameOrUrl) ? pathnameOrUrl : constructBlobUrl(storeId, pathnameOrUrl, options.access); return addPresignedParams(blobUrl, presignedUrlPayload); } function buildPresignedPutUrl(pathname, presignedUrlPayload) { const params = new URLSearchParams({ pathname }); const apiUrl = getApiUrl(`/?${params.toString()}`); return addPresignedParams(apiUrl, presignedUrlPayload); } function buildPresignedDeleteUrl(pathname, presignedUrlPayload) { const params = new URLSearchParams({ pathname }); const apiUrl = getApiUrl(`/?${params.toString()}`); return addPresignedParams(apiUrl, presignedUrlPayload); } async function presignUrl(signedToken, options) { const payload = await presign(signedToken, options); if (options.operation === "get" || options.operation === "head") { return { presignedUrl: buildPresignedGetUrl(options.pathname, payload, options) }; } if (options.operation === "put") { return { presignedUrl: buildPresignedPutUrl(options.pathname, payload) }; } if (options.operation === "delete") { return { presignedUrl: buildPresignedDeleteUrl(options.pathname, payload) }; } throw new BlobError(`Unknown operation`); } function canonicalString(pathname, presignEntries, operation) { var _a3; const lines = [`operation=${operation}`, `pathname=${pathname}`]; for (const k of PRESIGN_CANONICAL_QUERY_KEYS) { const v = (_a3 = presignEntries.find(([key]) => key === k)) == null ? void 0 : _a3[1]; if (v) { lines.push(`${k}=${v}`); } } lines.sort((a, b) => compareUtf8(a, b)); return lines.join("\n"); } function compareUtf8(a, b) { const ab = utf8Encoder.encode(a); const bb = utf8Encoder.encode(b); const n = Math.min(ab.length, bb.length); for (let i = 0; i < n; i++) { const d = ab[i] - bb[i]; if (d !== 0) { return d; } } return ab.length - bb.length; } async function createFolder(pathname, options = { access: "public" }) { var _a3; const access = (_a3 = options.access) != null ? _a3 : "public"; const folderPathname = pathname.endsWith("/") ? pathname : `${pathname}/`; const headers = {}; headers[putOptionHeaderMap.access] = access; headers[putOptionHeaderMap.addRandomSuffix] = "0"; const params = new URLSearchParams({ pathname: folderPathname }); const response = await requestApi( `/?${params.toString()}`, { method: "PUT", headers, signal: options.abortSignal }, options ); return { url: response.url, pathname: response.pathname }; } var import_is_buffer, import_async_retry, import_undici, import_throttleit, import_throttleit2, supportsNewBlobFromArrayBuffer, SYMBOL_FOR_REQ_CONTEXT, getContext, parseRegExp, map, defaultVercelBlobApiUrl, BlobError, disallowedPathnameCharacters, supportsRequestStreams, TEXT_ENCODER, createChunkTransformStream, addPresignedParams, debugIsActive, _a, _b, _a2, DOMException2, objectToString, isError, errorMessages, hasFetch, hasFetchWithUploadProgress, CHUNK_SIZE, blobFetch, hasXhr, blobXhr, blobRequest, MAXIMUM_PATHNAME_LENGTH, BlobAccessError, BlobOidcEnvironmentNotAllowedError, BlobContentTypeNotAllowedError, BlobPathnameMismatchError, BlobClientTokenExpiredError, BlobFileTooLargeError, BlobStoreNotFoundError, BlobStoreSuspendedError, BlobUnknownError, BlobNotFoundError, BlobServiceNotAvailable, BlobServiceRateLimited, BlobRequestAbortedError, BlobPreconditionFailedError, BLOB_API_VERSION, putOptionHeaderMap, maxConcurrentUploads, partSizeInBytes, maxBytesInMemory, BLOB_PRESIGN_QUERY_VALID_UNTIL, BLOB_PRESIGN_QUERY_MAXIMUM_SIZE, BLOB_PRESIGN_QUERY_ALLOWED_CONTENT_TYPES, BLOB_PRESIGN_QUERY_ADD_RANDOM_SUFFIX, BLOB_PRESIGN_QUERY_ALLOW_OVERWRITE, BLOB_PRESIGN_QUERY_CACHE_CONTROL_MAX_AGE, BLOB_PRESIGN_QUERY_IF_MATCH, BLOB_PRESIGN_QUERY_CALLBACK_URL, BLOB_PRESIGN_QUERY_CALLBACK_TOKEN_PAYLOAD, PRESIGN_CANONICAL_QUERY_KEYS, MAX_PRESIGN_CALLBACK_URL_CHARS, MAX_PRESIGN_CALLBACK_TOKEN_PAYLOAD_CHARS, MAX_PRESIGN_CACHE_CONTROL_MAX_AGE_SECONDS, MAX_PRESIGN_IF_MATCH_LENGTH, IF_MATCH_CONTROL_CHARS_RE, utf8Encoder; var init_chunk_3D2SZ6M2 = __esm({ "viewer/node_modules/@vercel/blob/dist/chunk-3D2SZ6M2.js"() { init_lib(); import_is_buffer = __toESM(require_is_buffer(), 1); import_async_retry = __toESM(require_lib(), 1); import_undici = __toESM(require_undici(), 1); import_throttleit = __toESM(require_throttleit(), 1); import_throttleit2 = __toESM(require_throttleit(), 1); supportsNewBlobFromArrayBuffer = new Promise((resolve) => { try { const helloAsArrayBuffer = new Uint8Array([104, 101, 108, 108, 111]); const blob = new Blob([helloAsArrayBuffer]); blob.text().then((text) => { resolve(text === "hello"); }).catch(() => { resolve(false); }); } catch { resolve(false); } }); SYMBOL_FOR_REQ_CONTEXT = /* @__PURE__ */ Symbol.for("@vercel/request-context"); getContext = () => { var _a3, _b2, _c; const fromSymbol = globalThis; return (_c = (_b2 = (_a3 = fromSymbol[SYMBOL_FOR_REQ_CONTEXT]) == null ? void 0 : _a3.get) == null ? void 0 : _b2.call(_a3)) != null ? _c : {}; }; parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i; map = { b: 1, kb: 1 << 10, mb: 1 << 20, gb: 1 << 30, tb: 1024 ** 4, pb: 1024 ** 5 }; defaultVercelBlobApiUrl = "https://vercel.com/api/blob"; BlobError = class extends Error { constructor(message) { super(`Vercel Blob: ${message}`); } }; disallowedPathnameCharacters = ["//"]; supportsRequestStreams = (() => { if (isNodeProcess()) { return true; } const apiUrl = getApiUrl(); if (apiUrl.startsWith("http://localhost")) { return false; } let duplexAccessed = false; const hasContentType = new Request(getApiUrl(), { body: new ReadableStream(), method: "POST", // @ts-expect-error -- TypeScript doesn't yet have duplex but it's in the spec: https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1729 get duplex() { duplexAccessed = true; return "half"; } }).headers.has("Content-Type"); return duplexAccessed && !hasContentType; })(); TEXT_ENCODER = typeof TextEncoder === "function" ? new TextEncoder() : null; createChunkTransformStream = (chunkSize, onProgress) => { let buffer = new Uint8Array(0); return new TransformStream({ transform(chunk, controller) { const newBuffer = new Uint8Array(buffer.length + chunk.byteLength); newBuffer.set(buffer); newBuffer.set(new Uint8Array(chunk), buffer.length); buffer = newBuffer; while (buffer.length >= chunkSize) { const newChunk = buffer.slice(0, chunkSize); controller.enqueue(newChunk); onProgress == null ? void 0 : onProgress(newChunk.byteLength); buffer = buffer.slice(chunkSize); } }, flush(controller) { if (buffer.length > 0) { controller.enqueue(buffer); onProgress == null ? void 0 : onProgress(buffer.byteLength); } } }); }; addPresignedParams = (url, presignedUrlPayload) => { const urlObj = new URL(url); for (const [key, value] of Object.entries(presignedUrlPayload.params)) { urlObj.searchParams.set(key, value); } urlObj.searchParams.set( "vercel-blob-delegation", presignedUrlPayload.delegationToken ); urlObj.searchParams.set( "vercel-blob-signature", presignedUrlPayload.signature ); return urlObj.toString(); }; debugIsActive = false; try { if (((_a = process.env.DEBUG) == null ? void 0 : _a.includes("blob")) || ((_b = process.env.NEXT_PUBLIC_DEBUG) == null ? void 0 : _b.includes("blob"))) { debugIsActive = true; } } catch { } DOMException2 = (_a2 = globalThis.DOMException) != null ? _a2 : (() => { try { atob("~"); } catch (err) { return Object.getPrototypeOf(err).constructor; } })(); objectToString = Object.prototype.toString; isError = (value) => objectToString.call(value) === "[object Error]"; errorMessages = /* @__PURE__ */ new Set([ "network error", // Chrome "Failed to fetch", // Chrome "NetworkError when attempting to fetch resource.", // Firefox "The Internet connection appears to be offline.", // Safari 16 "Load failed", // Safari 17+ "Network request failed", // `cross-fetch` "fetch failed", // Undici (Node.js) "terminated" // Undici (Node.js) ]); hasFetch = typeof import_undici.fetch === "function"; hasFetchWithUploadProgress = hasFetch && supportsRequestStreams; CHUNK_SIZE = 64 * 1024; blobFetch = async ({ input, init, onUploadProgress }) => { debug("using fetch"); let body; if (init.body) { if (onUploadProgress) { const stream = await toReadableStream(init.body); let loaded = 0; const chunkTransformStream = createChunkTransformStream( CHUNK_SIZE, (newLoaded) => { loaded += newLoaded; onUploadProgress(loaded); } ); body = stream.pipeThrough(chunkTransformStream); } else { body = init.body; } } const duplex = supportsRequestStreams && body && isStream(body) ? "half" : void 0; return (0, import_undici.fetch)( input, // @ts-expect-error -- Blob and Nodejs Blob are triggering type errors, fine with it { ...init, ...init.body ? { body } : {}, duplex } ); }; hasXhr = typeof XMLHttpRequest !== "undefined"; blobXhr = async ({ input, init, onUploadProgress }) => { debug("using xhr"); let body = null; if (init.body) { if (isReadableStream(init.body)) { body = await new Response(init.body).blob(); } else { body = init.body; } } return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open(init.method || "GET", input.toString(), true); if (onUploadProgress) { xhr.upload.addEventListener("progress", (event) => { if (event.lengthComputable) { onUploadProgress(event.loaded); } }); } xhr.onload = () => { var _a3; if ((_a3 = init.signal) == null ? void 0 : _a3.aborted) { reject(new DOMException("The user aborted the request.", "AbortError")); return; } const headers = new Headers(); const rawHeaders = xhr.getAllResponseHeaders().trim().split(/[\r\n]+/); rawHeaders.forEach((line) => { const parts = line.split(": "); const key = parts.shift(); const value = parts.join(": "); if (key) headers.set(key.toLowerCase(), value); }); const response = new Response(xhr.response, { status: xhr.status, statusText: xhr.statusText, headers }); resolve(response); }; xhr.onerror = () => { reject(new TypeError("Network request failed")); }; xhr.ontimeout = () => { reject(new TypeError("Network request timed out")); }; xhr.onabort = () => { reject(new DOMException("The user aborted a request.", "AbortError")); }; if (init.headers) { const headers = new Headers(init.headers); headers.forEach((value, key) => { xhr.setRequestHeader(key, value); }); } if (init.signal) { init.signal.addEventListener("abort", () => { xhr.abort(); }); if (init.signal.aborted) { xhr.abort(); return; } } xhr.send(body); }); }; blobRequest = async ({ input, init, onUploadProgress }) => { if (onUploadProgress) { if (hasFetchWithUploadProgress) { return blobFetch({ input, init, onUploadProgress }); } if (hasXhr) { return blobXhr({ input, init, onUploadProgress }); } } if (hasFetch) { return blobFetch({ input, init }); } if (hasXhr) { return blobXhr({ input, init }); } throw new Error("No request implementation available"); }; MAXIMUM_PATHNAME_LENGTH = 950; BlobAccessError = class extends BlobError { constructor() { super("Access denied, please provide a valid token for this resource."); } }; BlobOidcEnvironmentNotAllowedError = class extends BlobError { constructor(message) { super( message != null ? message : "OIDC is enabled for this project, but not for this token's environment." ); } }; BlobContentTypeNotAllowedError = class extends BlobError { constructor(message) { super(`Content type mismatch, ${message}.`); } }; BlobPathnameMismatchError = class extends BlobError { constructor(message) { super( `Pathname mismatch, ${message}. Check the pathname used in upload() or put() matches the one from the client token.` ); } }; BlobClientTokenExpiredError = class extends BlobError { constructor() { super("Client token has expired."); } }; BlobFileTooLargeError = class extends BlobError { constructor(message) { super(`File is too large, ${message}.`); } }; BlobStoreNotFoundError = class extends BlobError { constructor() { super("This store does not exist."); } }; BlobStoreSuspendedError = class extends BlobError { constructor() { super("This store has been suspended."); } }; BlobUnknownError = class extends BlobError { constructor() { super("Unknown error, please visit https://vercel.com/help."); } }; BlobNotFoundError = class extends BlobError { constructor() { super("The requested blob does not exist"); } }; BlobServiceNotAvailable = class extends BlobError { constructor() { super("The blob service is currently not available. Please try again."); } }; BlobServiceRateLimited = class extends BlobError { constructor(seconds) { super( `Too many requests please lower the number of concurrent requests ${seconds ? ` - try again in ${seconds} seconds` : ""}.` ); this.retryAfter = seconds != null ? seconds : 0; } }; BlobRequestAbortedError = class extends BlobError { constructor() { super("The request was aborted."); } }; BlobPreconditionFailedError = class extends BlobError { constructor() { super("Precondition failed: ETag mismatch."); } }; BLOB_API_VERSION = 12; putOptionHeaderMap = { cacheControlMaxAge: "x-cache-control-max-age", addRandomSuffix: "x-add-random-suffix", allowOverwrite: "x-allow-overwrite", contentType: "x-content-type", access: "x-vercel-blob-access", ifMatch: "x-if-match" }; maxConcurrentUploads = typeof window !== "undefined" ? 6 : 8; partSizeInBytes = 8 * 1024 * 1024; maxBytesInMemory = maxConcurrentUploads * partSizeInBytes * 2; BLOB_PRESIGN_QUERY_VALID_UNTIL = "vercel-blob-valid-until"; BLOB_PRESIGN_QUERY_MAXIMUM_SIZE = "vercel-blob-maximum-size-in-bytes"; BLOB_PRESIGN_QUERY_ALLOWED_CONTENT_TYPES = "vercel-blob-allowed-content-types"; BLOB_PRESIGN_QUERY_ADD_RANDOM_SUFFIX = "vercel-blob-add-random-suffix"; BLOB_PRESIGN_QUERY_ALLOW_OVERWRITE = "vercel-blob-allow-overwrite"; BLOB_PRESIGN_QUERY_CACHE_CONTROL_MAX_AGE = "vercel-blob-cache-control-max-age"; BLOB_PRESIGN_QUERY_IF_MATCH = "vercel-blob-if-match"; BLOB_PRESIGN_QUERY_CALLBACK_URL = "vercel-blob-callback-url"; BLOB_PRESIGN_QUERY_CALLBACK_TOKEN_PAYLOAD = "vercel-blob-callback-token-payload"; PRESIGN_CANONICAL_QUERY_KEYS = [ BLOB_PRESIGN_QUERY_ADD_RANDOM_SUFFIX, BLOB_PRESIGN_QUERY_ALLOW_OVERWRITE, BLOB_PRESIGN_QUERY_ALLOWED_CONTENT_TYPES, BLOB_PRESIGN_QUERY_CACHE_CONTROL_MAX_AGE, BLOB_PRESIGN_QUERY_CALLBACK_TOKEN_PAYLOAD, BLOB_PRESIGN_QUERY_CALLBACK_URL, BLOB_PRESIGN_QUERY_IF_MATCH, BLOB_PRESIGN_QUERY_MAXIMUM_SIZE, BLOB_PRESIGN_QUERY_VALID_UNTIL ]; MAX_PRESIGN_CALLBACK_URL_CHARS = 4096; MAX_PRESIGN_CALLBACK_TOKEN_PAYLOAD_CHARS = 8192; MAX_PRESIGN_CACHE_CONTROL_MAX_AGE_SECONDS = 365 * 24 * 60 * 60; MAX_PRESIGN_IF_MATCH_LENGTH = 256; IF_MATCH_CONTROL_CHARS_RE = /[\x00-\x1f\x7f]/; utf8Encoder = new TextEncoder(); } }); // viewer/node_modules/@vercel/blob/dist/index.js var dist_exports = {}; __export(dist_exports, { BlobAccessError: () => BlobAccessError, BlobClientTokenExpiredError: () => BlobClientTokenExpiredError, BlobContentTypeNotAllowedError: () => BlobContentTypeNotAllowedError, BlobError: () => BlobError, BlobFileTooLargeError: () => BlobFileTooLargeError, BlobNotFoundError: () => BlobNotFoundError, BlobPathnameMismatchError: () => BlobPathnameMismatchError, BlobPreconditionFailedError: () => BlobPreconditionFailedError, BlobRequestAbortedError: () => BlobRequestAbortedError, BlobServiceNotAvailable: () => BlobServiceNotAvailable, BlobServiceRateLimited: () => BlobServiceRateLimited, BlobStoreNotFoundError: () => BlobStoreNotFoundError, BlobStoreSuspendedError: () => BlobStoreSuspendedError, BlobUnknownError: () => BlobUnknownError, completeMultipartUpload: () => completeMultipartUpload2, copy: () => copy, createFolder: () => createFolder, createMultipartUpload: () => createMultipartUpload2, createMultipartUploader: () => createMultipartUploader, del: () => del, get: () => get, getDownloadUrl: () => getDownloadUrl, head: () => head, issueSignedToken: () => issueSignedToken, list: () => list, parseStoreIdFromDelegationToken: () => parseStoreIdFromDelegationToken, parseStoreIdFromPresignedUrl: () => parseStoreIdFromPresignedUrl, presignUrl: () => presignUrl, put: () => put, uploadPart: () => uploadPart2 }); async function del(urlOrPathname, options) { const urls = Array.isArray(urlOrPathname) ? urlOrPathname : [urlOrPathname]; if ((options == null ? void 0 : options.ifMatch) && urls.length > 1) { throw new BlobError("ifMatch can only be used when deleting a single URL."); } const headers = { "content-type": "application/json" }; if (options == null ? void 0 : options.ifMatch) { headers["x-if-match"] = options.ifMatch; } await requestApi( "/delete", { method: "POST", headers, body: JSON.stringify({ urls }), signal: options == null ? void 0 : options.abortSignal }, options ); } async function head(urlOrPathname, options) { const searchParams = new URLSearchParams({ url: urlOrPathname }); const response = await requestApi( `?${searchParams.toString()}`, // HEAD can't have body as a response, so we use GET { method: "GET", signal: options == null ? void 0 : options.abortSignal }, options ); return { url: response.url, downloadUrl: response.downloadUrl, pathname: response.pathname, size: response.size, contentType: response.contentType, contentDisposition: response.contentDisposition, cacheControl: response.cacheControl, uploadedAt: new Date(response.uploadedAt), etag: response.etag }; } function extractPathnameFromUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.pathname.slice(1); } catch { return url; } } async function get(urlOrPathname, options) { if (!urlOrPathname) { throw new BlobError("url or pathname is required"); } if (!options) { throw new BlobError("missing options, see usage"); } if (options.access !== "public" && options.access !== "private") { throw new BlobError( 'access must be "private" or "public", see https://vercel.com/docs/vercel-blob' ); } const auth = resolveBlobAuth(options); if (auth.kind === "presigned") { throw new BlobError("Presigned URLs are not supported for the get method"); } let blobUrl; let pathname; const access = options.access; if (isUrl(urlOrPathname)) { blobUrl = urlOrPathname; pathname = extractPathnameFromUrl(urlOrPathname); try { const { hostname } = new URL(blobUrl); if (!hostname.endsWith(".blob.vercel-storage.com")) { throw new BlobError( "Invalid URL: the URL does not point to a Vercel Blob store. Use a pathname instead, see https://vercel.com/docs/vercel-blob" ); } } catch (error) { if (error instanceof BlobError) throw error; throw new BlobError("Invalid URL: unable to parse the provided URL"); } } else { if (!auth.storeId) { throw new BlobError("Invalid token: unable to extract store ID"); } pathname = urlOrPathname; blobUrl = constructBlobUrl(auth.storeId, pathname, access); } const requestHeaders = { ...options.ifNoneMatch ? { "If-None-Match": options.ifNoneMatch } : {}, authorization: `Bearer ${auth.token}`, ...options.headers // low-level escape hatch, applied last to override anything }; let fetchUrl = blobUrl; if (options.useCache === false) { const url = new URL(blobUrl); url.searchParams.set("cache", "0"); fetchUrl = url.toString(); } const response = await (0, import_undici2.fetch)(fetchUrl, { method: "GET", headers: requestHeaders, signal: options.abortSignal }); if (response.status === 304) { const downloadUrlObj = new URL(blobUrl); downloadUrlObj.searchParams.set("download", "1"); const lastModified2 = response.headers.get("last-modified"); return { statusCode: 304, stream: null, headers: response.headers, blob: { url: blobUrl, downloadUrl: downloadUrlObj.toString(), pathname, contentType: null, contentDisposition: response.headers.get("content-disposition") || "", cacheControl: response.headers.get("cache-control") || "", size: null, uploadedAt: lastModified2 ? new Date(lastModified2) : /* @__PURE__ */ new Date(), etag: response.headers.get("etag") || "" } }; } if (response.status === 404) { return null; } if (!response.ok) { throw new BlobError( `Failed to fetch blob: ${response.status} ${response.statusText}` ); } const stream = response.body; if (!stream) { throw new BlobError("Response body is null"); } const contentLength = response.headers.get("content-length"); const lastModified = response.headers.get("last-modified"); const downloadUrl = new URL(blobUrl); downloadUrl.searchParams.set("download", "1"); return { statusCode: 200, stream, headers: response.headers, blob: { url: blobUrl, downloadUrl: downloadUrl.toString(), pathname, contentType: response.headers.get("content-type") || "application/octet-stream", contentDisposition: response.headers.get("content-disposition") || "", cacheControl: response.headers.get("cache-control") || "", size: contentLength ? parseInt(contentLength, 10) : 0, uploadedAt: lastModified ? new Date(lastModified) : /* @__PURE__ */ new Date(), etag: response.headers.get("etag") || "" } }; } async function list(options) { var _a3; const searchParams = new URLSearchParams(); if (options == null ? void 0 : options.limit) { searchParams.set("limit", options.limit.toString()); } if (options == null ? void 0 : options.prefix) { searchParams.set("prefix", options.prefix); } if (options == null ? void 0 : options.cursor) { searchParams.set("cursor", options.cursor); } if (options == null ? void 0 : options.mode) { searchParams.set("mode", options.mode); } const response = await requestApi( `?${searchParams.toString()}`, { method: "GET", signal: options == null ? void 0 : options.abortSignal }, options ); if ((options == null ? void 0 : options.mode) === "folded") { return { folders: (_a3 = response.folders) != null ? _a3 : [], cursor: response.cursor, hasMore: response.hasMore, blobs: response.blobs.map(mapBlobResult) }; } return { cursor: response.cursor, hasMore: response.hasMore, blobs: response.blobs.map(mapBlobResult) }; } function mapBlobResult(blobResult) { return { url: blobResult.url, downloadUrl: blobResult.downloadUrl, pathname: blobResult.pathname, size: blobResult.size, uploadedAt: new Date(blobResult.uploadedAt), etag: blobResult.etag }; } async function copy(fromUrlOrPathname, toPathname, options) { if (!options) { throw new BlobError("missing options, see usage"); } if (options.access !== "public" && options.access !== "private") { throw new BlobError( 'access must be "private" or "public", see https://vercel.com/docs/vercel-blob' ); } if (toPathname.length > MAXIMUM_PATHNAME_LENGTH) { throw new BlobError( `pathname is too long, maximum length is ${MAXIMUM_PATHNAME_LENGTH}` ); } for (const invalidCharacter of disallowedPathnameCharacters) { if (toPathname.includes(invalidCharacter)) { throw new BlobError( `pathname cannot contain "${invalidCharacter}", please encode it if needed` ); } } const headers = {}; headers["x-vercel-blob-access"] = options.access; if (options.addRandomSuffix !== void 0) { headers["x-add-random-suffix"] = options.addRandomSuffix ? "1" : "0"; } if (options.allowOverwrite !== void 0) { headers["x-allow-overwrite"] = options.allowOverwrite ? "1" : "0"; } if (options.contentType) { headers["x-content-type"] = options.contentType; } if (options.cacheControlMaxAge !== void 0) { headers["x-cache-control-max-age"] = options.cacheControlMaxAge.toString(); } if (options.ifMatch) { headers["x-if-match"] = options.ifMatch; } const params = new URLSearchParams({ pathname: toPathname, fromUrl: fromUrlOrPathname }); const response = await requestApi( `?${params.toString()}`, { method: "PUT", headers, signal: options.abortSignal }, options ); return { url: response.url, downloadUrl: response.downloadUrl, pathname: response.pathname, contentType: response.contentType, contentDisposition: response.contentDisposition, etag: response.etag }; } var import_undici2, put, createMultipartUpload2, createMultipartUploader, uploadPart2, completeMultipartUpload2; var init_dist = __esm({ "viewer/node_modules/@vercel/blob/dist/index.js"() { init_chunk_3D2SZ6M2(); import_undici2 = __toESM(require_undici(), 1); put = createPutMethod({ allowedOptions: [ "cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "contentType", "ifMatch" ] }); createMultipartUpload2 = createCreateMultipartUploadMethod({ allowedOptions: [ "cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "contentType", "ifMatch" ] }); createMultipartUploader = createCreateMultipartUploaderMethod({ allowedOptions: [ "cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "contentType", "ifMatch" ] }); uploadPart2 = createUploadPartMethod({ allowedOptions: [ "cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "contentType" ] }); completeMultipartUpload2 = createCompleteMultipartUploadMethod({ allowedOptions: [ "cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "contentType" ] }); } }); // viewer/src/server/server.mjs import fs9 from "node:fs"; import http from "node:http"; import path13 from "node:path"; import { fileURLToPath as fileURLToPath2 } from "node:url"; // viewer/src/server/localAssetBackend.mjs import fs7 from "node:fs"; import path8 from "node:path"; import { spawn as spawn2 } from "node:child_process"; // viewer/src/server/catalog/cadDirectoryScanner.mjs import crypto from "node:crypto"; import fs2 from "node:fs"; import path3 from "node:path"; // viewer/packages/cadjs/src/common/stepSidecars.mjs import path from "node:path"; function isPerStepViewerDirectoryName(name) { const normalized = String(name || "").toLowerCase(); return normalized.startsWith(".") && (normalized.endsWith(".step") || normalized.endsWith(".stp")); } function isInlineStepGlbArtifactPath(filePath) { const name = path.basename(String(filePath || "")).toLowerCase(); return name.startsWith(".") && (name.endsWith(".step.glb") || name.endsWith(".stp.glb")); } function isInlineStepParameterPath(filePath) { const name = path.basename(String(filePath || "")).toLowerCase(); return name.startsWith(".") && name.endsWith(".step.js"); } function isPathInsidePerStepViewerDirectory(filePath) { return String(filePath || "").split(path.sep).some((part) => isPerStepViewerDirectoryName(part)); } function inlineStepGlbArtifactPathForSource(sourcePath) { return path.join(path.dirname(sourcePath), `.${path.basename(sourcePath)}.glb`); } function stepParameterPathForStepSource(sourcePath) { const stem = path.basename(sourcePath, path.extname(sourcePath)); return path.join(path.dirname(sourcePath), `.${stem}.step.js`); } // viewer/packages/cadjs/src/common/stepTopology.mjs var STEP_TOPOLOGY_EXTENSION = "STEP_topology"; var STEP_TOPOLOGY_SCHEMA_VERSION = 2; var STEP_EDGE_BARYCENTRIC_ATTRIBUTE = "_CAD_EDGE_BARYCENTRIC"; var STEP_EDGE_CLASS_ATTRIBUTE = "_CAD_EDGE_CLASS"; var STEP_EDGE_FLAGS = Object.freeze({ DEGENERATE: 1 << 1, SEAM: 1 << 2, NOT_REFERENCEABLE: 1 << 3, BOUNDARY: 1 << 4, NON_MANIFOLD: 1 << 5, HARD: 1 << 6, TANGENT: 1 << 7, UNKNOWN_CONTINUITY: 1 << 8 }); var STEP_EDGE_VISIBILITY_CLASSES = Object.freeze({ FEATURE: "feature", TANGENT: "tangent", SEAM: "seam", DEGENERATE: "degenerate", BOUNDARY: "boundary", NON_MANIFOLD: "nonManifold", UNKNOWN: "unknown" }); var STEP_EDGE_SURFACE_CLASS_CODES = Object.freeze({ none: 0, feature: 1, tangent: 2, seam: 3, degenerate: 4, boundary: 5, nonManifold: 6, unknown: 7 }); var STEP_EDGE_RENDER_VISIBILITY_CLASSES = Object.freeze([ STEP_EDGE_VISIBILITY_CLASSES.FEATURE, STEP_EDGE_VISIBILITY_CLASSES.TANGENT, STEP_EDGE_VISIBILITY_CLASSES.SEAM, STEP_EDGE_VISIBILITY_CLASSES.DEGENERATE ]); function isCurrentStepTopologySchemaVersion(value) { return Number(value) === STEP_TOPOLOGY_SCHEMA_VERSION; } // viewer/packages/cadjs/src/lib/pathUtils.mjs import path2 from "node:path"; function toPosixPath(value) { return String(value || "").split(path2.sep).join("/"); } function relativePathStaysInsideRoot(relativePath) { return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relativePath); } function pathIsInside(childPath, parentPath) { const relativePath = path2.relative(path2.resolve(parentPath), path2.resolve(childPath)); return Boolean(relativePath) && relativePathStaysInsideRoot(relativePath); } // viewer/src/server/step/stepMetadata.mjs import fs from "node:fs"; var TEXT_TO_CAD_GENERATOR_PROPERTY = "cadpy:generator"; var TEXT_TO_CAD_ENTRY_KIND_PROPERTY = "cadpy:entryKind"; var TEXT_TO_CAD_SOURCE_PATH_PROPERTY = "cadpy:sourcePath"; var TEXT_TO_CAD_SOURCE_HASH_PROPERTY = "cadpy:sourceHash"; var STEP_STRING_PATTERN = "'(?:''|[^'])*'"; function unescapeStepString(value) { const raw = String(value || "").trim(); const unquoted = raw.startsWith("'") && raw.endsWith("'") ? raw.slice(1, -1) : raw; return unquoted.replace(/''/g, "'"); } function normalizeTextToCadEntryKind(value) { const normalized = String(value || "").trim().toLowerCase(); return normalized === "part" || normalized === "assembly" ? normalized : ""; } function readTextToCadStepMetadataText(stepText) { const text = String(stepText || ""); const descriptiveItems = /* @__PURE__ */ new Map(); const descriptivePattern = new RegExp( `#(\\d+)\\s*=\\s*DESCRIPTIVE_REPRESENTATION_ITEM\\s*\\(\\s*(${STEP_STRING_PATTERN})\\s*,\\s*(${STEP_STRING_PATTERN})\\s*\\)\\s*;`, "gis" ); for (const match of text.matchAll(descriptivePattern)) { descriptiveItems.set(`#${match[1]}`, { value: unescapeStepString(match[3]) }); } const representations = /* @__PURE__ */ new Map(); const representationPattern = new RegExp( `#(\\d+)\\s*=\\s*REPRESENTATION\\s*\\(\\s*(${STEP_STRING_PATTERN})\\s*,\\s*\\(([^)]*)\\)\\s*,\\s*#\\d+\\s*\\)\\s*;`, "gis" ); for (const match of text.matchAll(representationPattern)) { representations.set(`#${match[1]}`, { itemRefs: Array.from(String(match[3] || "").matchAll(/#\d+/g), (itemMatch) => itemMatch[0]) }); } const propertyDefinitions = /* @__PURE__ */ new Map(); const propertyPattern = new RegExp( `#(\\d+)\\s*=\\s*PROPERTY_DEFINITION\\s*\\(\\s*(${STEP_STRING_PATTERN})\\s*,\\s*(${STEP_STRING_PATTERN})\\s*,\\s*#[0-9]+\\s*\\)\\s*;`, "gis" ); for (const match of text.matchAll(propertyPattern)) { const propertyName = unescapeStepString(match[3]); if (propertyName === TEXT_TO_CAD_GENERATOR_PROPERTY || propertyName === TEXT_TO_CAD_ENTRY_KIND_PROPERTY || propertyName === TEXT_TO_CAD_SOURCE_PATH_PROPERTY || propertyName === TEXT_TO_CAD_SOURCE_HASH_PROPERTY || propertyName === "cadpy:entry_kind") { propertyDefinitions.set(`#${match[1]}`, propertyName); } } const metadata = {}; const linkPattern = /#\d+\s*=\s*PROPERTY_DEFINITION_REPRESENTATION\s*\(\s*(#\d+)\s*,\s*(#\d+)\s*\)\s*;/gis; for (const match of text.matchAll(linkPattern)) { const propertyName = propertyDefinitions.get(match[1]); const representation = representations.get(match[2]); if (!propertyName || !representation) { continue; } const item = representation.itemRefs.map((itemRef) => descriptiveItems.get(itemRef)).find(Boolean); if (!item) { continue; } if (propertyName === TEXT_TO_CAD_GENERATOR_PROPERTY) { metadata.generator = item.value; } else if (propertyName === TEXT_TO_CAD_ENTRY_KIND_PROPERTY || propertyName === "cadpy:entry_kind") { const entryKind = normalizeTextToCadEntryKind(item.value); if (entryKind) { metadata.entryKind = entryKind; } } else if (propertyName === TEXT_TO_CAD_SOURCE_HASH_PROPERTY) { metadata.sourceHash = item.value; } else if (propertyName === TEXT_TO_CAD_SOURCE_PATH_PROPERTY) { metadata.sourcePath = item.value; } } return metadata; } function readTextToCadStepMetadataFile(stepPath) { return readTextToCadStepMetadataText(fs.readFileSync(stepPath, "utf-8")); } // viewer/src/server/catalog/cadDirectoryScanner.mjs var DEFAULT_VIEWER_ROOT_DIR = ""; var CAD_CATALOG_SCHEMA_VERSION = 4; var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".step", ".stp", ".stl", ".3mf", ".glb", ".gcode", ".dxf", ".urdf", ".srdf", ".sdf"]); var IMPLICIT_CAD_EXTENSIONS = Object.freeze([".implicit.js", ".implicit.mjs"]); var REGENERATE_STEP_COMMAND = "python -m cadpy.step_artifact --repo-root . --step"; var VIEWER_SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([ ".agents", ".cache", ".viewer", ".git", ".venv", "__pycache__", "build", "coverage", "dist", "node_modules", "viewer" ]); var SRDF_URDF_METADATA_PATTERN = /<\s*(?:tcad|explorer):urdf\b[^>]*\bpath\s*=\s*["']([^"']+)["'][^>]*>/i; var STEP_EDGE_RENDER_CLASS_ORDER = Object.freeze(["feature", "tangent", "seam", "degenerate"]); var TEXT_TO_CAD_COMMENT_METADATA_RE = //g; var PYTHON_GENERATOR_BY_KIND = Object.freeze({ dxf: "gen_dxf", step: "gen_step", stp: "gen_step", urdf: "gen_urdf", srdf: "gen_srdf", sdf: "gen_sdf" }); function encodeUrlPath(repoRelativePath2) { return `/${repoRelativePath2.split("/").map((part) => encodeURIComponent(part)).join("/")}`; } function pathIsImplicitCadSource(value = "") { const pathname = String(value || "").split(/[?#]/, 1)[0].toLowerCase(); return IMPLICIT_CAD_EXTENSIONS.some((extension) => pathname.endsWith(extension)); } function relativePathStaysInsideRoot2(relativePath) { return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${path3.sep}`) && !path3.isAbsolute(relativePath); } function normalizeStepEdgeRenderVisibilityClasses(value) { const rawValues = Array.isArray(value) ? value : value === void 0 || value === null ? [] : [value]; const validValues = new Set(Object.values(STEP_EDGE_VISIBILITY_CLASSES)); const normalized = []; for (const raw of rawValues) { const classId = String(raw || "").trim(); if (validValues.has(classId) && !normalized.includes(classId)) { normalized.push(classId); } } if (!normalized.includes(STEP_EDGE_VISIBILITY_CLASSES.FEATURE)) { normalized.unshift(STEP_EDGE_VISIBILITY_CLASSES.FEATURE); } return [ ...STEP_EDGE_RENDER_CLASS_ORDER.filter((classId) => normalized.includes(classId)), ...normalized.filter((classId) => !STEP_EDGE_RENDER_CLASS_ORDER.includes(classId)) ]; } function normalizeViewerRootDir(value = DEFAULT_VIEWER_ROOT_DIR) { const rawValue = String(value ?? "").trim(); const slashNormalized = rawValue.replace(/\\/g, "/"); const normalized = path3.posix.normalize(slashNormalized); if (!normalized || normalized === ".") { return DEFAULT_VIEWER_ROOT_DIR; } if (normalized === ".." || normalized.startsWith("../")) { throw new Error(`CAD Viewer root directory must stay inside the directory root: ${rawValue}`); } return normalized.replace(/(?!^\/)\/+$/, ""); } function resolveViewerRoot(repoRoot, rootDir = DEFAULT_VIEWER_ROOT_DIR) { const normalizedDir = normalizeViewerRootDir(rootDir); const resolvedRepoRoot = path3.resolve(repoRoot); const rootPath = normalizedDir ? path3.resolve(resolvedRepoRoot, normalizedDir) : resolvedRepoRoot; const relativePath = path3.relative(resolvedRepoRoot, rootPath); if (!relativePathStaysInsideRoot2(relativePath)) { throw new Error(`CAD Viewer root directory must stay inside the directory root: ${normalizedDir}`); } return { dir: normalizedDir, rootPath, rootName: normalizedDir ? path3.basename(rootPath) : path3.basename(resolvedRepoRoot) }; } function repoRelativePath(repoRoot, filePath) { return toPosixPath(path3.relative(path3.resolve(repoRoot), path3.resolve(filePath))); } function scanRelativePath(rootPath, filePath) { return toPosixPath(path3.relative(path3.resolve(rootPath), path3.resolve(filePath))); } function fileStats(filePath) { try { const stats = fs2.statSync(filePath, { bigint: true }); return stats.isFile() ? stats : null; } catch { return null; } } function sha256File(filePath) { const hash = crypto.createHash("sha256"); const fd = fs2.openSync(filePath, "r"); try { const buffer = Buffer.alloc(1024 * 1024); let bytesRead = 0; do { bytesRead = fs2.readSync(fd, buffer, 0, buffer.length, null); if (bytesRead > 0) { hash.update(buffer.subarray(0, bytesRead)); } } while (bytesRead > 0); } finally { fs2.closeSync(fd); } return hash.digest("hex"); } function pathIsInside2(filePath, rootPath) { const relative = path3.relative(path3.resolve(rootPath), path3.resolve(filePath)); return relativePathStaysInsideRoot2(relative); } function dedupePaths(paths) { const result = []; const seen = /* @__PURE__ */ new Set(); for (const rawPath of paths) { const resolved = path3.resolve(rawPath); if (!seen.has(resolved)) { seen.add(resolved); result.push(resolved); } } return result; } function normalizeManifestPath(manifestPath) { const value = String(manifestPath || "").trim(); if (!value || value.includes("\0")) { return ""; } return value.replace(/\\/g, "/"); } function resolveManifestSourcePath(repoRoot, manifestPath, baseDir = repoRoot) { const value = normalizeManifestPath(manifestPath); if (!value) { return null; } const resolved = path3.isAbsolute(value) ? path3.resolve(value) : path3.resolve(baseDir, value); if (!pathIsInside2(resolved, repoRoot)) { return null; } return resolved; } function normalizeManifestRelativePath(manifestPath) { const value = String(manifestPath || "").trim().replace(/\\/g, "/").replace(/^\/+/, ""); if (!value || value === "." || value.startsWith("../")) { return ""; } return value; } function manifestIdentityRootForStep(repoRoot, actualStepPath, manifestStepPath) { const resolvedRepoRoot = path3.resolve(repoRoot); const normalizedStepPath = normalizeManifestRelativePath(manifestStepPath); if (!normalizedStepPath || !actualStepPath) { return resolvedRepoRoot; } const actualRepoPath = repoRelativePath(resolvedRepoRoot, actualStepPath); if (actualRepoPath === normalizedStepPath) { return resolvedRepoRoot; } if (!actualRepoPath.endsWith(`/${normalizedStepPath}`)) { return resolvedRepoRoot; } const prefix = actualRepoPath.slice(0, actualRepoPath.length - normalizedStepPath.length).replace(/\/+$/, ""); if (!prefix) { return resolvedRepoRoot; } const resolvedPrefix = path3.resolve(resolvedRepoRoot, ...prefix.split("/").filter(Boolean)); return pathIsInside2(resolvedPrefix, resolvedRepoRoot) ? resolvedPrefix : resolvedRepoRoot; } function sourcePathFromManifest(repoRoot, manifestPath, { identityRoot = null, baseDir = null } = {}) { const value = normalizeManifestPath(manifestPath); if (!value) { return { sourcePath: "", manifestSourcePath: "", filePath: null, identityRoot: path3.resolve(repoRoot) }; } const resolvedRepoRoot = path3.resolve(repoRoot); const resolvedIdentityRoot = identityRoot && pathIsInside2(identityRoot, resolvedRepoRoot) ? path3.resolve(identityRoot) : resolvedRepoRoot; const roots = dedupePaths([ baseDir ? path3.resolve(baseDir) : null, resolvedIdentityRoot, resolvedRepoRoot ].filter(Boolean)); const candidates = []; for (const root of roots) { if (!pathIsInside2(root, resolvedRepoRoot)) { continue; } const filePath2 = resolveManifestSourcePath(resolvedRepoRoot, value, root); if (!filePath2) { continue; } candidates.push({ sourcePath: repoRelativePath(resolvedRepoRoot, filePath2), manifestSourcePath: value, filePath: filePath2, identityRoot: resolvedIdentityRoot }); } const candidate = candidates.find((entry) => fileStats(entry.filePath)) || candidates[0]; if (candidate) { return candidate; } const filePath = resolveManifestSourcePath(resolvedRepoRoot, value, resolvedRepoRoot); return { sourcePath: value, manifestSourcePath: value, filePath, identityRoot: resolvedIdentityRoot }; } function fileHasGenStep(filePath) { try { return /\bgen_step\s*\(/.test(fs2.readFileSync(filePath, "utf-8")); } catch { return false; } } function generatorSourcePathFromManifest(repoRoot, manifestPath, { identityRoot = null, baseDir = null } = {}) { const candidate = sourcePathFromManifest(repoRoot, manifestPath, { identityRoot, baseDir }); if (candidate.sourcePath && candidate.filePath && path3.extname(candidate.filePath).toLowerCase() === ".py" && path3.basename(candidate.filePath) !== "__init__.py" && fileHasGenStep(candidate.filePath)) { return candidate; } return { sourcePath: "", manifestSourcePath: candidate.manifestSourcePath || "", filePath: null, identityRoot: candidate.identityRoot || path3.resolve(repoRoot) }; } function fileHasPythonGenerator(filePath, generatorName) { if (!generatorName) { return false; } try { const source = fs2.readFileSync(filePath, "utf-8"); return new RegExp(`\\b${generatorName}\\s*\\(`).test(source); } catch { return false; } } function generatorSourcePathFromMetadata(repoRoot, manifestPath, generatorName, { baseDir = null } = {}) { const candidate = sourcePathFromManifest(repoRoot, manifestPath, { baseDir }); if (candidate.sourcePath && candidate.filePath && path3.extname(candidate.filePath).toLowerCase() === ".py" && path3.basename(candidate.filePath) !== "__init__.py" && fileHasPythonGenerator(candidate.filePath, generatorName)) { return candidate; } return { sourcePath: "", filePath: null }; } function readXmlTextToCadMetadata(filePath) { let text = ""; try { text = fs2.readFileSync(filePath, "utf-8"); } catch { return {}; } const metadata = {}; for (const match of text.matchAll(TEXT_TO_CAD_COMMENT_METADATA_RE)) { metadata[String(match[1] || "").trim()] = String(match[2] || "").trim(); } return metadata; } function readDxfTextToCadMetadata(filePath) { let lines = []; try { lines = fs2.readFileSync(filePath, "utf-8").split(/\r?\n/); } catch { return {}; } const metadata = {}; for (let index = 0; index + 1 < lines.length; index += 1) { if (String(lines[index] || "").trim() !== "999") { continue; } const value = String(lines[index + 1] || "").trim(); if (!value.startsWith("cadpy:")) { continue; } const [key, ...rest] = value.slice("cadpy:".length).split("="); const normalizedKey = String(key || "").trim(); if (rest.length && /^[A-Za-z][A-Za-z0-9]*$/.test(normalizedKey)) { metadata[normalizedKey] = rest.join("=").trim(); } } return metadata; } function readGeneratedFileMetadata(filePath, kind) { const normalizedKind = String(kind || "").trim().toLowerCase(); if (normalizedKind === "dxf") { return readDxfTextToCadMetadata(filePath); } if (["urdf", "srdf", "sdf"].includes(normalizedKind)) { return readXmlTextToCadMetadata(filePath); } if (normalizedKind === "step" || normalizedKind === "stp") { try { return readTextToCadStepMetadataFile(filePath); } catch { return {}; } } return {}; } function generatedSourceStatusForFile({ repoRoot, sourcePath, kind }) { const normalizedKind = String(kind || "").trim().toLowerCase(); const generatorName = PYTHON_GENERATOR_BY_KIND[normalizedKind] || ""; if (!generatorName) { return null; } const metadata = readGeneratedFileMetadata(sourcePath, normalizedKind); const metadataSourcePath = String(metadata.sourcePath || "").trim(); if (!metadataSourcePath) { return null; } const sourceIdentity = generatorSourcePathFromMetadata( repoRoot, metadataSourcePath, generatorName, { baseDir: path3.dirname(sourcePath) } ); const base = { sourceKind: "python", source: { file: sourceIdentity.sourcePath || metadataSourcePath, sourcePath: sourceIdentity.sourcePath || metadataSourcePath, ...metadata.sourceHash ? { sourceHash: String(metadata.sourceHash) } : {} } }; if (!sourceIdentity.filePath) { return { ...base, sourceStatus: { ok: false, status: "missing", stale: false, sourceKind: "python", sourcePath: metadataSourcePath, message: "Python generator source is unavailable." } }; } return { ...base, source: { ...base.source, file: sourceIdentity.sourcePath, sourcePath: sourceIdentity.sourcePath, sourceHash: String(metadata.sourceHash || "") } }; } function assetForPath(repoRoot, filePath) { const stats = fileStats(filePath); if (!stats) { return null; } const version = `${stats.size.toString(36)}-${stats.mtimeNs.toString(36)}`; const repoPath = repoRelativePath(repoRoot, filePath); return { url: `${encodeUrlPath(repoPath)}?v=${encodeURIComponent(version)}`, hash: sha256File(filePath), bytes: Number(stats.size) }; } function assetUrlForPath(repoRoot, filePath) { return encodeUrlPath(repoRelativePath(repoRoot, filePath)); } function readExact(fd, length2, position) { const buffer = Buffer.alloc(length2); const bytesRead = fs2.readSync(fd, buffer, 0, length2, position); return bytesRead === length2 ? buffer : null; } function glbBufferViewRange(gltf, binOffset, binLength, viewIndex) { const view = Array.isArray(gltf?.bufferViews) ? gltf.bufferViews[Number(viewIndex)] : null; if (!view || Number(view.buffer || 0) !== 0) { return null; } const byteOffset = binOffset + Number(view.byteOffset || 0); const byteLength = Number(view.byteLength || 0); if (!Number.isFinite(byteOffset) || !Number.isFinite(byteLength) || byteLength < 0) { return null; } if (byteOffset < binOffset || byteOffset + byteLength > binOffset + binLength) { return null; } return { byteOffset, byteLength }; } function parseJsonBufferView(fd, gltf, binOffset, binLength, viewIndex, encoding = "utf-8") { const range = glbBufferViewRange(gltf, binOffset, binLength, viewIndex); if (!range) { throw new Error("STEP topology buffer view range is invalid"); } const bytes2 = readExact(fd, range.byteLength, range.byteOffset); if (!bytes2) { throw new Error("STEP topology buffer view range is invalid"); } const payload = JSON.parse(bytes2.toString(String(encoding || "utf-8"))); if (!payload || typeof payload !== "object" || Array.isArray(payload)) { throw new Error("STEP topology JSON buffer view is not an object"); } return payload; } function gltfPrimitivesHaveSurfaceEdgeAttributes(gltf) { const meshes = Array.isArray(gltf?.meshes) ? gltf.meshes : []; let primitiveCount = 0; for (const mesh of meshes) { for (const primitive of Array.isArray(mesh?.primitives) ? mesh.primitives : []) { primitiveCount += 1; const attributes = primitive?.attributes || {}; if (attributes[STEP_EDGE_BARYCENTRIC_ATTRIBUTE] === void 0 || attributes[STEP_EDGE_CLASS_ATTRIBUTE] === void 0) { return false; } } } return primitiveCount > 0; } function readGlbTopologyContainer(filePath) { let fd = null; try { fd = fs2.openSync(filePath, "r"); const header = readExact(fd, 12, 0); if (!header || header.readUInt32LE(0) !== 1179937895 || header.readUInt32LE(4) !== 2) { throw new Error("Not a GLB v2 file"); } const totalLength = Math.min(header.readUInt32LE(8), fs2.fstatSync(fd).size); let offset = 12; let gltf = null; let binOffset = 0; let binLength = 0; while (offset + 8 <= totalLength) { const chunkHeader = readExact(fd, 8, offset); if (!chunkHeader) { throw new Error("Invalid GLB chunk header"); } const chunkLength = chunkHeader.readUInt32LE(0); const chunkType = chunkHeader.toString("latin1", 4, 8); offset += 8; if (offset + chunkLength > totalLength) { throw new Error("Invalid GLB chunk length"); } if (chunkType === "JSON") { const jsonBytes = readExact(fd, chunkLength, offset); if (!jsonBytes) { throw new Error("GLB is missing JSON chunk"); } gltf = JSON.parse(jsonBytes.toString("utf8").trim()); } else if (chunkType === "BIN\0") { binOffset = offset; binLength = chunkLength; } offset += chunkLength; } return { fd, gltf, binOffset, binLength }; } catch { if (fd !== null) { fs2.closeSync(fd); } throw new Error("Invalid GLB topology container"); } } function stepArtifactError({ code, reason, repoRoot, cadPath, sourcePath, glbPath, details = {} }) { const glbRelPath = repoRelativePath(repoRoot, glbPath); return { ok: false, error: { code, message: `${reason}: ${glbRelPath}.`, cadPath, stepPath: repoRelativePath(repoRoot, sourcePath), glbPath: glbRelPath, regenerateCommand: REGENERATE_STEP_COMMAND, ...details } }; } function staleStepArtifactError({ repoRoot, cadPath, sourcePath, glbPath, manifestSourcePath = "", sourceKind = "step", artifactHash, currentHash }) { return stepArtifactError({ code: "stale_step_artifact", reason: "Generated GLB doesn't match the hash of the STEP file", repoRoot, cadPath, sourcePath, glbPath, details: { stale: true, sourceKind, ...manifestSourcePath ? { sourcePath: manifestSourcePath } : {}, artifactHash, currentHash } }); } function validateStepTopologyArtifact({ repoRoot, sourcePath, cadPath }) { const glbPath = inlineStepGlbArtifactPathForSource(sourcePath); let stepHash = ""; let sourceHash = ""; let artifactSourcePath = ""; const fail = (code, reason) => ({ topology: null, stepArtifact: stepArtifactError({ code, reason, repoRoot, cadPath, sourcePath, glbPath }), glbPath, stepHash, sourceHash }); if (!fileStats(glbPath)) { return fail( "missing_glb", "STEP topology validation requires the generated GLB artifact, but it is missing" ); } let container = null; try { container = readGlbTopologyContainer(glbPath); const extension = container.gltf?.extensions?.[STEP_TOPOLOGY_EXTENSION]; if (!extension || typeof extension !== "object" || Array.isArray(extension)) { return fail( "missing_step_topology", "STEP topology validation requires readable STEP_topology indexView in the GLB" ); } if (!isCurrentStepTopologySchemaVersion(extension.schemaVersion)) { return fail( "unsupported_step_topology", `STEP topology validation requires STEP_topology schemaVersion ${STEP_TOPOLOGY_SCHEMA_VERSION} in the GLB` ); } const manifest = parseJsonBufferView( container.fd, container.gltf, container.binOffset, container.binLength, extension.indexView, extension.encoding ); const topology = { index: manifest, entryKind: String(extension.entryKind || manifest.entryKind || "").trim().toLowerCase(), hasSelector: false, hasDisplayEdges: false }; if (!isCurrentStepTopologySchemaVersion(manifest.schemaVersion)) { return { topology, stepArtifact: stepArtifactError({ code: "unsupported_step_topology", reason: `STEP topology validation requires STEP_topology schemaVersion ${STEP_TOPOLOGY_SCHEMA_VERSION} in the GLB`, repoRoot, cadPath, sourcePath, glbPath }), glbPath, stepHash }; } const artifactSourceKind = String(manifest.sourceKind || "step").trim().toLowerCase(); const artifactUsesPythonSource = artifactSourceKind === "python"; const artifactNormalizedSourceKind = artifactUsesPythonSource ? "python" : "step"; const artifactIdentityDetails = () => ({ sourceKind: artifactNormalizedSourceKind, ...artifactSourcePath ? { sourcePath: artifactSourcePath } : {} }); const manifestIdentityRoot = manifestIdentityRootForStep(repoRoot, sourcePath, manifest.stepPath); const sourceIdentity = artifactUsesPythonSource ? generatorSourcePathFromManifest(repoRoot, manifest.sourcePath, { identityRoot: manifestIdentityRoot, baseDir: path3.dirname(glbPath) }) : sourcePathFromManifest(repoRoot, manifest.sourcePath, { identityRoot: manifestIdentityRoot, baseDir: path3.dirname(glbPath) }); artifactSourcePath = sourceIdentity.sourcePath; if (!artifactSourcePath || !sourceIdentity.filePath) { return { topology, stepArtifact: stepArtifactError({ code: "missing_source_path", reason: "GLB STEP_topology is missing required sourcePath identity", repoRoot, cadPath, sourcePath, glbPath, details: { sourceKind: artifactNormalizedSourceKind } }), glbPath, stepHash, sourceHash }; } stepHash = String(manifest.stepHash || "").trim(); sourceHash = String(manifest.sourceHash || "").trim(); if (!stepHash && fileStats(sourcePath)) { return { topology, stepArtifact: stepArtifactError({ code: "missing_step_hash", reason: "GLB STEP_topology is missing STEP file identity", repoRoot, cadPath, sourcePath, glbPath, details: artifactIdentityDetails() }), glbPath, stepHash, sourceHash }; } const currentStepHash = fileStats(sourcePath) ? sha256File(sourcePath) : ""; if (currentStepHash && stepHash !== currentStepHash) { return { topology, stepArtifact: staleStepArtifactError({ repoRoot, cadPath, sourcePath, glbPath, manifestSourcePath: artifactSourcePath, sourceKind: artifactNormalizedSourceKind, artifactHash: stepHash, currentHash: currentStepHash }), glbPath, stepHash, sourceHash }; } let edgeRendering = null; try { const edgeManifest = parseJsonBufferView( container.fd, container.gltf, container.binOffset, container.binLength, extension.edgeView, extension.encoding ); const edgeVisibilityClasses = edgeManifest?.edgeRendering && typeof edgeManifest.edgeRendering === "object" ? normalizeStepEdgeRenderVisibilityClasses(edgeManifest.edgeRendering.visibilityClasses) : []; const indexEdgeVisibilityClasses = manifest?.edgeRendering && typeof manifest.edgeRendering === "object" ? normalizeStepEdgeRenderVisibilityClasses(manifest.edgeRendering.visibilityClasses) : []; if (!isCurrentStepTopologySchemaVersion(edgeManifest.schemaVersion) || String(edgeManifest.profile || "") !== "surface-edges" || String(edgeManifest.sourcePath || "").trim() !== String(manifest.sourcePath || "").trim() || stepHash && String(edgeManifest.stepHash || "").trim() !== stepHash || !edgeVisibilityClasses.length || edgeVisibilityClasses.join("\n") !== indexEdgeVisibilityClasses.join("\n") || !edgeVisibilityClasses.includes(STEP_EDGE_VISIBILITY_CLASSES.FEATURE) || !edgeManifest?.buffers?.views?.surfaceHalfEdges) { return { topology, stepArtifact: stepArtifactError({ code: "missing_edge_topology", reason: `STEP topology validation requires STEP_topology edgeView schemaVersion ${STEP_TOPOLOGY_SCHEMA_VERSION} in the GLB`, repoRoot, cadPath, sourcePath, glbPath, details: artifactIdentityDetails() }), glbPath, stepHash, sourceHash }; } edgeRendering = edgeManifest.edgeRendering && typeof edgeManifest.edgeRendering === "object" ? { visibilityClasses: edgeVisibilityClasses, generatedVisibilityClasses: (Array.isArray(edgeManifest.edgeRendering.generatedVisibilityClasses) ? edgeManifest.edgeRendering.generatedVisibilityClasses : edgeVisibilityClasses).map((classId) => String(classId || "").trim()).filter((classId, index, list2) => edgeVisibilityClasses.includes(classId) && STEP_EDGE_RENDER_CLASS_ORDER.includes(classId) && list2.indexOf(classId) === index), visibilityClassCounts: edgeManifest.edgeRendering.visibilityClassCounts || {}, generatedVisibilityClassCounts: edgeManifest.edgeRendering.generatedVisibilityClassCounts || {} } : null; if (!gltfPrimitivesHaveSurfaceEdgeAttributes(container.gltf)) { return { topology, stepArtifact: stepArtifactError({ code: "missing_surface_edge_attributes", reason: `STEP topology validation requires ${STEP_EDGE_BARYCENTRIC_ATTRIBUTE} and ${STEP_EDGE_CLASS_ATTRIBUTE} on every STEP mesh primitive`, repoRoot, cadPath, sourcePath, glbPath, details: artifactIdentityDetails() }), glbPath, stepHash, sourceHash }; } } catch { return { topology, stepArtifact: stepArtifactError({ code: "missing_edge_topology", reason: "STEP topology validation requires readable STEP_topology edgeView in the GLB", repoRoot, cadPath, sourcePath, glbPath, details: artifactIdentityDetails() }), glbPath, stepHash, sourceHash }; } topology.hasDisplayEdges = true; try { const selectorManifest = parseJsonBufferView( container.fd, container.gltf, container.binOffset, container.binLength, extension.selectorView, extension.encoding ); if (!isCurrentStepTopologySchemaVersion(selectorManifest.schemaVersion)) { return { topology, stepArtifact: stepArtifactError({ code: "unsupported_step_topology", reason: `STEP topology validation requires STEP_topology schemaVersion ${STEP_TOPOLOGY_SCHEMA_VERSION} in the GLB`, repoRoot, cadPath, sourcePath, glbPath, details: artifactIdentityDetails() }), glbPath, stepHash, sourceHash }; } } catch { return { topology, stepArtifact: stepArtifactError({ code: "missing_selector_topology", reason: "STEP topology validation requires readable STEP_topology selectorView in the GLB", repoRoot, cadPath, sourcePath, glbPath, details: artifactIdentityDetails() }), glbPath, stepHash, sourceHash }; } topology.hasSelector = true; const stepArtifact = { ok: true, glbPath: repoRelativePath(repoRoot, glbPath), ...artifactSourcePath ? { sourcePath: artifactSourcePath } : {}, sourceKind: artifactUsesPythonSource ? "python" : "step", ...edgeRendering ? { edgeRendering } : {}, ...artifactUsesPythonSource ? { sourceHash, ...stepHash ? { stepHash } : {} } : { stepHash } }; return { topology, stepArtifact, glbPath, stepHash, sourceHash }; } catch { return fail( "missing_step_topology", "STEP topology validation requires readable STEP_topology indexView in the GLB" ); } finally { if (container?.fd !== null && container?.fd !== void 0) { try { fs2.closeSync(container.fd); } catch { } } } } function readStepSourceStatus({ repoRoot, stepPath, pythonSourcePath = "", cadPath = "" } = {}) { if (!repoRoot) { throw new Error("repoRoot is required"); } if (!stepPath) { throw new Error("stepPath is required"); } const resolvedRepoRoot = path3.resolve(repoRoot); const resolvedStepPath = path3.resolve(stepPath); const extension = path3.extname(resolvedStepPath) || ".step"; const normalizedCadPath = cadPath || cadPathForStepSource(resolvedRepoRoot, resolvedStepPath, extension); const validation = validateStepTopologyArtifact({ repoRoot: resolvedRepoRoot, sourcePath: resolvedStepPath, cadPath: normalizedCadPath }); const stepArtifact = validation.stepArtifact || {}; const artifact = catalogArtifactFromValidation(stepArtifact) || null; const normalizedPythonSourcePath = pythonSourcePath ? repoRelativePath( resolvedRepoRoot, path3.isAbsolute(pythonSourcePath) ? path3.resolve(pythonSourcePath) : path3.resolve(resolvedRepoRoot, pythonSourcePath) ) : ""; const hasPythonSource = Boolean(normalizedPythonSourcePath) || String(stepArtifact.sourceKind || artifact?.sourceKind || "").trim().toLowerCase() === "python"; const sourceKind = hasPythonSource ? "python" : "step"; const file = repoRelativePath(resolvedRepoRoot, resolvedStepPath); const sourcePath = String(stepArtifact.sourcePath || artifact?.sourcePath || normalizedPythonSourcePath || "").trim(); const base = { ok: true, file, stepPath: file, sourceKind, artifact, ...sourcePath ? { sourcePath } : {} }; if (!fileStats(resolvedStepPath)) { return { ...base, ok: false, step: { ok: false, status: "missing", missing: true, stale: false, message: "STEP file is missing." } }; } return { ...base, step: { ok: true, status: "current", missing: false, stale: false, currentHash: sha256File(resolvedStepPath) } }; } function stepKindFromTopology(topology) { const index = topology?.index && typeof topology.index === "object" ? topology.index : topology; if (topology?.entryKind === "assembly" || index?.entryKind === "assembly") { return "assembly"; } return index?.assembly?.root && typeof index.assembly.root === "object" ? "assembly" : "part"; } function sourceFormatFromExtension(extension) { const normalized = extension.toLowerCase().replace(/^\./, ""); return normalized === "stp" ? "stp" : normalized; } function sourceFormatForPath(sourcePath, extension = path3.extname(sourcePath)) { return pathIsImplicitCadSource(sourcePath) ? "implicit" : sourceFormatFromExtension(extension); } function isPerUrdfViewerDirectoryName(name) { const normalized = String(name || "").toLowerCase(); return normalized.startsWith(".") && normalized.endsWith(".urdf"); } function isHiddenDirectoryName(name) { return String(name || "").startsWith("."); } function isPathInsidePerUrdfViewerDirectory(filePath) { return String(filePath || "").split(path3.sep).some((part) => isPerUrdfViewerDirectoryName(part)); } function fileRefForSource(rootPath, sourcePath) { return scanRelativePath(rootPath, sourcePath); } function cadPathForStepSource(repoRoot, sourcePath, extension) { const relativePath = repoRelativePath(repoRoot, sourcePath); return relativePath.slice(0, -extension.length); } function sourcePathForInlineStepGlbArtifact(glbPath) { const name = path3.basename(glbPath); if (!isInlineStepGlbArtifactPath(glbPath)) { return null; } return path3.join(path3.dirname(glbPath), name.slice(1, -".glb".length)); } function sourcePathForInlineStepParameter(parameterPath) { const name = path3.basename(parameterPath); if (!isInlineStepParameterPath(parameterPath)) { return null; } return path3.join(path3.dirname(parameterPath), name.slice(1, -".js".length)); } function catalogArtifactFromValidation(stepArtifact) { if (!stepArtifact || typeof stepArtifact !== "object") { return void 0; } if (stepArtifact.ok) { return void 0; } const rawError = stepArtifact.error && typeof stepArtifact.error === "object" ? stepArtifact.error : {}; const error = String(rawError.code || stepArtifact.error || "step_artifact_error").trim(); const message = String(rawError.message || "").trim(); const sourceKind = String(rawError.sourceKind || "").trim(); const artifactHash = String(rawError.artifactHash || "").trim(); const currentHash = String(rawError.currentHash || "").trim(); const sourceHash = String(rawError.sourceHash || "").trim(); const stepPath = String(rawError.stepPath || "").trim(); const glbPath = String(rawError.glbPath || "").trim(); const cadPath = String(rawError.cadPath || "").trim(); return { ok: false, error, ...rawError.stale ? { stale: true } : {}, ...stepPath ? { stepPath } : {}, ...glbPath ? { glbPath } : {}, ...cadPath ? { cadPath } : {}, ...sourceKind ? { sourceKind } : {}, ...sourceHash ? { sourceHash } : {}, ...artifactHash ? { artifactHash } : {}, ...currentHash ? { currentHash } : {}, ...message ? { message } : {} }; } function readStepCatalogMetadata({ repoRoot, glbPath, sourcePath = "" } = {}) { if (!fileStats(glbPath)) { return {}; } let container = null; try { container = readGlbTopologyContainer(glbPath); const extension = container.gltf?.extensions?.[STEP_TOPOLOGY_EXTENSION]; if (!extension || typeof extension !== "object" || Array.isArray(extension)) { return {}; } if (!isCurrentStepTopologySchemaVersion(extension.schemaVersion)) { return {}; } const manifest = parseJsonBufferView( container.fd, container.gltf, container.binOffset, container.binLength, extension.indexView, extension.encoding ); const sourceKind = String(manifest?.sourceKind || "step").trim().toLowerCase() === "python" ? "python" : "step"; const manifestIdentityRoot = manifestIdentityRootForStep(repoRoot, sourcePathForInlineStepGlbArtifact(glbPath) || sourcePath, manifest?.stepPath); const sourceIdentity = sourceKind === "python" ? generatorSourcePathFromManifest(repoRoot, manifest?.sourcePath, { identityRoot: manifestIdentityRoot, baseDir: path3.dirname(glbPath) }) : sourcePathFromManifest(repoRoot, manifest?.sourcePath, { identityRoot: manifestIdentityRoot, baseDir: path3.dirname(glbPath) }); return { topology: { index: manifest, entryKind: String(extension.entryKind || manifest?.entryKind || "").trim().toLowerCase(), hasSelector: Boolean(extension.selectorView), hasDisplayEdges: Boolean(extension.edgeView) }, sourceKind, sourcePath: sourceIdentity.sourcePath, sourceHash: String(manifest?.sourceHash || ""), stepHash: String(manifest?.stepHash || "") }; } catch { return {}; } finally { if (container?.fd !== null && container?.fd !== void 0) { try { fs2.closeSync(container.fd); } catch { } } } } function pythonStepSourceFromStepMetadata(repoRoot, stepPath) { const metadata = readGeneratedFileMetadata(stepPath, "step"); const metadataSourcePath = String(metadata.sourcePath || "").trim(); if (!metadataSourcePath) { return null; } const sourceIdentity = sourcePathFromManifest(repoRoot, metadataSourcePath, { baseDir: path3.dirname(stepPath) }); if (!sourceIdentity.sourcePath) { return null; } const sourceExtension = path3.extname(sourceIdentity.filePath || sourceIdentity.sourcePath).toLowerCase(); if (sourceExtension !== ".py") { return null; } return { sourcePath: sourceIdentity.sourcePath, sourceHash: String(metadata.sourceHash || "") }; } function createStepEntry({ repoRoot, rootPath, sourcePath, extension, includeArtifactStatus = true }) { const cadPath = cadPathForStepSource(repoRoot, sourcePath, extension); const validation = includeArtifactStatus ? validateStepTopologyArtifact({ repoRoot, sourcePath, cadPath }) : null; const glbPath = validation?.glbPath || inlineStepGlbArtifactPathForSource(sourcePath); const catalogMetadata = includeArtifactStatus ? {} : readStepCatalogMetadata({ repoRoot, glbPath, sourcePath }); const topology = validation?.topology || catalogMetadata.topology || null; const stepArtifact = validation?.stepArtifact || {}; const glbAsset = assetForPath(repoRoot, glbPath); const stepModuleAsset = assetForPath(repoRoot, stepParameterPathForStepSource(sourcePath)); const artifact = includeArtifactStatus ? catalogArtifactFromValidation(stepArtifact) : void 0; const artifactSourceKind = String( stepArtifact.sourceKind || stepArtifact.error?.sourceKind || catalogMetadata.sourceKind || artifact?.sourceKind || "" ).trim().toLowerCase(); const metadataPythonSource = (!includeArtifactStatus || artifact) && artifactSourceKind !== "python" ? pythonStepSourceFromStepMetadata(repoRoot, sourcePath) : null; const sourceKind = artifactSourceKind === "python" || metadataPythonSource ? "python" : "step"; const artifactSourcePath = String( stepArtifact.sourcePath || stepArtifact.error?.sourcePath || catalogMetadata.sourcePath || "" ).trim(); const pythonSourcePath = artifactSourcePath || metadataPythonSource?.sourcePath || ""; return { file: fileRefForSource(rootPath, sourcePath), kind: stepKindFromTopology(topology), url: glbAsset?.url || assetUrlForPath(repoRoot, glbPath), hash: glbAsset?.hash || "", bytes: glbAsset?.bytes || 0, sourceKind, ...sourceKind === "python" && pythonSourcePath ? { source: { file: pythonSourcePath, sourcePath: pythonSourcePath, ...stepArtifact.sourceHash || catalogMetadata.sourceHash || metadataPythonSource?.sourceHash ? { sourceHash: stepArtifact.sourceHash || catalogMetadata.sourceHash || metadataPythonSource.sourceHash } : {} } } : {}, ...stepModuleAsset ? { moduleUrl: stepModuleAsset.url } : {}, ...artifact ? { artifact } : {} }; } function linkedUrdfPathForSrdf(sourcePath, repoRoot) { let xmlText = ""; try { xmlText = fs2.readFileSync(sourcePath, "utf-8"); } catch { return null; } const match = SRDF_URDF_METADATA_PATTERN.exec(xmlText); const rawRef = String(match?.[1] || "").trim(); if (!rawRef || rawRef.includes("\\") || rawRef.startsWith("/")) { return null; } const resolved = path3.resolve(path3.dirname(sourcePath), rawRef); const relativeToRepo = path3.relative(path3.resolve(repoRoot), resolved); if (!relativePathStaysInsideRoot2(relativeToRepo) || path3.extname(resolved).toLowerCase() !== ".urdf") { return null; } return fileStats(resolved) ? resolved : null; } function createSingleAssetEntry({ repoRoot, rootPath, sourcePath, extension }) { const kind = sourceFormatForPath(sourcePath, extension); const asset = assetForPath(repoRoot, sourcePath); const file = fileRefForSource(rootPath, sourcePath); const generatedSource = generatedSourceStatusForFile({ repoRoot, sourcePath, kind }); const entry = { file, kind, url: asset?.url || assetUrlForPath(repoRoot, sourcePath), hash: asset?.hash || "", bytes: asset?.bytes || 0, ...generatedSource?.sourceKind === "python" ? { sourceKind: "python" } : {}, ...generatedSource?.source ? { source: generatedSource.source } : {}, ...generatedSource?.sourceStatus ? { sourceStatus: generatedSource.sourceStatus } : {} }; if (kind === "srdf") { const linkedUrdfPath = linkedUrdfPathForSrdf(sourcePath, repoRoot); if (linkedUrdfPath) { const urdfAsset = assetForPath(repoRoot, linkedUrdfPath); if (urdfAsset) { entry.relations = { urdf: { file: fileRefForSource(rootPath, linkedUrdfPath), ...urdfAsset } }; } } } return entry; } function shouldSkipDirectory(name) { return VIEWER_SKIPPED_DIRECTORIES.has(name) || isHiddenDirectoryName(name) || isPerStepViewerDirectoryName(name) || isPerUrdfViewerDirectoryName(name); } function scanPathIncluded(includePath, rootPath, entryPath, isDirectory) { if (typeof includePath !== "function") { return true; } return includePath({ filePath: entryPath, relativePath: scanRelativePath(rootPath, entryPath), isDirectory }) !== false; } function collectCadSourceFiles(rootPath, { scanRootPath = rootPath, includePath = null } = {}, result = []) { let entries = []; try { entries = fs2.readdirSync(rootPath, { withFileTypes: true }); } catch { return result; } for (const entry of entries) { const entryPath = path3.join(rootPath, entry.name); if (entry.isDirectory()) { if (!shouldSkipDirectory(entry.name) && scanPathIncluded(includePath, scanRootPath, entryPath, true)) { collectCadSourceFiles(entryPath, { scanRootPath, includePath }, result); } continue; } if (!entry.isFile()) { continue; } if (!scanPathIncluded(includePath, scanRootPath, entryPath, false)) { continue; } const extension = path3.extname(entry.name).toLowerCase(); if (isInlineStepGlbArtifactPath(entryPath)) { const sourcePath = sourcePathForInlineStepGlbArtifact(entryPath); if (sourcePath && !fileStats(sourcePath)) { result.push(entryPath); } continue; } if ((SOURCE_EXTENSIONS.has(extension) || pathIsImplicitCadSource(entryPath)) && !isInlineStepGlbArtifactPath(entryPath)) { result.push(entryPath); continue; } } return result; } function compareEntries(a, b) { return String(a.file || "").localeCompare(String(b.file || ""), void 0, { numeric: true, sensitivity: "base" }); } function pathHasSkippedDirectory(rootPath, filePath) { const relativePath = scanRelativePath(rootPath, filePath); if (!relativePathStaysInsideRoot2(relativePath)) { return true; } const parts = relativePath.split("/").filter(Boolean); return parts.slice(0, -1).some((part) => shouldSkipDirectory(part)); } function logicalStepSourcePathForInlineArtifactPath(filePath) { if (isInlineStepGlbArtifactPath(filePath)) { return sourcePathForInlineStepGlbArtifact(filePath); } if (isInlineStepParameterPath(filePath)) { return sourcePathForInlineStepParameter(filePath); } return null; } function logicalStepSourceExistsForSidecar(sourcePath) { return Boolean( sourcePath && (fileStats(sourcePath) || fileStats(inlineStepGlbArtifactPathForSource(sourcePath)) || fileStats(stepParameterPathForStepSource(sourcePath))) ); } function catalogFileRefForPath({ repoRoot, rootDir = DEFAULT_VIEWER_ROOT_DIR, filePath } = {}) { if (!repoRoot) { throw new Error("repoRoot is required"); } if (!filePath) { throw new Error("filePath is required"); } const resolved = resolveViewerRoot(repoRoot, rootDir); const resolvedFilePath = path3.resolve(filePath); if (!pathIsInside2(resolvedFilePath, resolved.rootPath) || pathHasSkippedDirectory(resolved.rootPath, resolvedFilePath)) { return ""; } const logicalStepSourcePath = logicalStepSourcePathForInlineArtifactPath(resolvedFilePath); if (logicalStepSourcePath) { return fileRefForSource(resolved.rootPath, logicalStepSourcePath); } if (isPathInsidePerStepViewerDirectory(resolvedFilePath) || isPathInsidePerUrdfViewerDirectory(resolvedFilePath)) { return ""; } const extension = path3.extname(resolvedFilePath).toLowerCase(); return SOURCE_EXTENSIONS.has(extension) || pathIsImplicitCadSource(resolvedFilePath) ? fileRefForSource(resolved.rootPath, resolvedFilePath) : ""; } function scanCadFile({ repoRoot, rootDir = DEFAULT_VIEWER_ROOT_DIR, filePath, includeArtifactStatus = true } = {}) { if (!repoRoot) { throw new Error("repoRoot is required"); } if (!filePath) { throw new Error("filePath is required"); } const resolved = resolveViewerRoot(repoRoot, rootDir); const resolvedFilePath = path3.resolve(filePath); if (!pathIsInside2(resolvedFilePath, resolved.rootPath) || pathHasSkippedDirectory(resolved.rootPath, resolvedFilePath)) { return null; } const logicalStepSourcePath = logicalStepSourcePathForInlineArtifactPath(resolvedFilePath); if (logicalStepSourcePath) { if (!logicalStepSourceExistsForSidecar(logicalStepSourcePath)) { return null; } return createStepEntry({ repoRoot, rootPath: resolved.rootPath, sourcePath: logicalStepSourcePath, extension: path3.extname(logicalStepSourcePath).toLowerCase(), includeArtifactStatus }); } if (isPathInsidePerStepViewerDirectory(resolvedFilePath) || isPathInsidePerUrdfViewerDirectory(resolvedFilePath)) { return null; } const extension = path3.extname(resolvedFilePath).toLowerCase(); if (!SOURCE_EXTENSIONS.has(extension) && !pathIsImplicitCadSource(resolvedFilePath) || !fileStats(resolvedFilePath)) { if ((extension === ".step" || extension === ".stp") && fileStats(inlineStepGlbArtifactPathForSource(resolvedFilePath))) { return createStepEntry({ repoRoot, rootPath: resolved.rootPath, sourcePath: resolvedFilePath, extension, includeArtifactStatus }); } return null; } if (extension === ".step" || extension === ".stp") { return createStepEntry({ repoRoot, rootPath: resolved.rootPath, sourcePath: resolvedFilePath, extension, includeArtifactStatus }); } return createSingleAssetEntry({ repoRoot, rootPath: resolved.rootPath, sourcePath: resolvedFilePath, extension }); } function scanCadDirectory({ repoRoot, rootDir = DEFAULT_VIEWER_ROOT_DIR, includePath = null, includeArtifactStatus = true } = {}) { if (!repoRoot) { throw new Error("repoRoot is required"); } const resolved = resolveViewerRoot(repoRoot, rootDir); const entries = collectCadSourceFiles(resolved.rootPath, { scanRootPath: resolved.rootPath, includePath }).map((sourcePath) => { const logicalSourcePath = isInlineStepGlbArtifactPath(sourcePath) ? sourcePathForInlineStepGlbArtifact(sourcePath) : sourcePath; const extension = path3.extname(logicalSourcePath).toLowerCase(); if (extension === ".step" || extension === ".stp") { return createStepEntry({ repoRoot, rootPath: resolved.rootPath, sourcePath: logicalSourcePath, extension, includeArtifactStatus }); } return createSingleAssetEntry({ repoRoot, rootPath: resolved.rootPath, sourcePath, extension }); }).sort(compareEntries); return { schemaVersion: CAD_CATALOG_SCHEMA_VERSION, entries }; } function sortCatalogEntries(entries) { return [...Array.isArray(entries) ? entries : []].sort(compareEntries); } function isServedCadAsset(filePath) { const extension = path3.extname(filePath).toLowerCase(); if (isInlineStepGlbArtifactPath(filePath)) { return true; } if (isInlineStepParameterPath(filePath)) { return true; } if (isPathInsidePerStepViewerDirectory(filePath)) { return false; } if (isPathInsidePerUrdfViewerDirectory(filePath)) { return false; } if (SOURCE_EXTENSIONS.has(extension) || pathIsImplicitCadSource(filePath)) { return true; } return false; } // viewer/src/server/catalog/generationStatus.mjs import fs3 from "node:fs"; import path4 from "node:path"; var GENERATION_STATUS_SCHEMA_VERSION = 1; var GENERATION_LOCK_SUFFIX = ".generation.lock.json"; var DEFAULT_ACTIVE_STATUS_MAX_AGE_MS = 3e4; var IGNORED_STATUS_SCAN_DIRS = /* @__PURE__ */ new Set([ ".cache", ".git", ".hg", ".mypy_cache", ".pytest_cache", ".ruff_cache", ".svn", ".tox", ".venv", "build", "dist", "env", "node_modules", "site-packages", "venv", "__pycache__" ]); function emptyGenerationStatus() { return { schemaVersion: GENERATION_STATUS_SCHEMA_VERSION, runs: [], files: {} }; } function generationStatusDir(repoRoot, rootDir = DEFAULT_VIEWER_ROOT_DIR) { const resolvedRepoRoot = path4.resolve(repoRoot); return resolveViewerRoot(resolvedRepoRoot, normalizeViewerRootDir(rootDir)).rootPath; } function pathIsInside3(filePath, rootPath) { const relative = path4.relative(path4.resolve(rootPath), path4.resolve(filePath)); return relative === "" || relative !== ".." && !relative.startsWith(`..${path4.sep}`) && !path4.isAbsolute(relative); } function isGenerationLockFileName(name) { return String(name || "").startsWith(".") && String(name || "").endsWith(GENERATION_LOCK_SUFFIX); } function resolveStatusPath(repoRoot, value, { statusPath = "", rootPath = "" } = {}) { const raw = String(value || "").trim(); if (!raw) { return ""; } if (raw.includes("\0")) { return ""; } if (path4.isAbsolute(raw)) { return path4.resolve(raw); } const normalized = raw.replace(/\\/g, "/"); const statusDir = statusPath ? path4.dirname(statusPath) : ""; const repoCandidate = path4.resolve(repoRoot, normalized); const shouldPreferStatusDir = statusDir && (normalized.startsWith("../") || normalized.startsWith("./") || !normalized.includes("/")); if (shouldPreferStatusDir) { return path4.resolve(statusDir, normalized); } if (rootPath && pathIsInside3(repoCandidate, rootPath)) { return repoCandidate; } return repoCandidate; } function processIsAlive(pid) { const normalizedPid = Number(pid); if (!Number.isInteger(normalizedPid) || normalizedPid <= 0) { return false; } try { process.kill(normalizedPid, 0); return true; } catch (error) { return error?.code === "EPERM"; } } function timestampMs(value) { const ms = Date.parse(String(value || "")); return Number.isFinite(ms) ? ms : 0; } function statusIsActive(payload, { nowMs = Date.now(), maxAgeMs = DEFAULT_ACTIVE_STATUS_MAX_AGE_MS } = {}) { if (String(payload?.status || "").trim().toLowerCase() !== "running") { return false; } if (!processIsAlive(payload?.pid)) { return false; } const updatedAtMs = timestampMs(payload?.updatedAt || payload?.startedAt); return !updatedAtMs || nowMs - updatedAtMs <= maxAgeMs; } function readStatusPayload(statusPath) { try { const payload = JSON.parse(fs3.readFileSync(statusPath, "utf8")); return payload && typeof payload === "object" ? payload : null; } catch { return null; } } function listStatusFiles(repoRoot, rootDir = DEFAULT_VIEWER_ROOT_DIR) { const statusRoot = generationStatusDir(repoRoot, rootDir); const statusFiles = []; const visit = (directory) => { let entries = []; try { entries = fs3.readdirSync(directory, { withFileTypes: true }); } catch { return; } for (const entry of entries) { const entryPath = path4.join(directory, entry.name); if (entry.isDirectory()) { if (!IGNORED_STATUS_SCAN_DIRS.has(entry.name)) { visit(entryPath); } continue; } if (entry.isFile() && isGenerationLockFileName(entry.name)) { statusFiles.push(entryPath); } } }; visit(statusRoot); return statusFiles; } function outputEntries(payload) { return (Array.isArray(payload?.outputs) ? payload.outputs : []).map((output) => { if (typeof output === "string") { return { path: output, kind: path4.extname(output).toLowerCase().replace(".", "") }; } return { path: String(output?.path || "").trim(), kind: String(output?.kind || "").trim().toLowerCase() }; }).filter((output) => output.path); } function readGenerationStatus({ repoRoot, rootDir = DEFAULT_VIEWER_ROOT_DIR, nowMs = Date.now(), maxAgeMs = DEFAULT_ACTIVE_STATUS_MAX_AGE_MS } = {}) { if (!repoRoot) { throw new Error("repoRoot is required"); } const resolvedRepoRoot = path4.resolve(repoRoot); const resolvedRoot = resolveViewerRoot(resolvedRepoRoot, normalizeViewerRootDir(rootDir)); const status = emptyGenerationStatus(); const runsById = /* @__PURE__ */ new Map(); for (const statusPath of listStatusFiles(resolvedRepoRoot, rootDir)) { const payload = readStatusPayload(statusPath); if (!payload || !statusIsActive(payload, { nowMs, maxAgeMs })) { continue; } const runId = String(payload.id || path4.basename(statusPath, GENERATION_LOCK_SUFFIX)); let run = runsById.get(runId); if (!run) { run = { id: runId, pid: Number(payload.pid) || 0, startedAt: String(payload.startedAt || ""), updatedAt: String(payload.updatedAt || ""), sourcePath: sourcePathFromStatusPayload(resolvedRepoRoot, payload.sourcePath, statusPath), generator: String(payload.generator || ""), files: [] }; runsById.set(runId, run); } for (const output of outputEntries(payload)) { const outputPath = resolveStatusPath(resolvedRepoRoot, output.path, { statusPath, rootPath: resolvedRoot.rootPath }); if (!outputPath || !pathIsInside3(outputPath, resolvedRoot.rootPath)) { continue; } const file = toPosixPath(path4.relative(resolvedRoot.rootPath, outputPath)); if (!file || file.startsWith("../")) { continue; } const fileStatus = { running: true, runId: run.id, pid: run.pid, startedAt: run.startedAt, updatedAt: run.updatedAt, sourcePath: run.sourcePath, generator: run.generator, kind: output.kind }; status.files[file] = fileStatus; if (!run.files.includes(file)) { run.files.push(file); } } } status.runs = Array.from(runsById.values()).filter((run) => run.files.length); return status; } function sourcePathFromStatusPayload(repoRoot, value, statusPath) { const raw = String(value || "").trim(); if (!raw) { return ""; } const resolved = resolveStatusPath(repoRoot, raw, { statusPath, rootPath: repoRoot }); return resolved && pathIsInside3(resolved, repoRoot) ? toPosixPath(path4.relative(path4.resolve(repoRoot), resolved)) : raw.replace(/\\/g, "/"); } // viewer/src/server/step/stepArtifactCompiler.mjs import fs5 from "node:fs"; import path6 from "node:path"; // viewer/src/server/step/pythonStepArtifact.mjs import { spawn } from "node:child_process"; import fs4 from "node:fs"; import path5 from "node:path"; import { fileURLToPath } from "node:url"; var MODULE_DIR = path5.dirname(fileURLToPath(import.meta.url)); var PACKAGE_ROOT = path5.resolve(MODULE_DIR, "../../.."); function firstExistingFile(paths) { return paths.find((candidate) => fs4.existsSync(candidate)) || ""; } function firstExistingDirectory(paths) { return paths.find((candidate) => { try { return fs4.statSync(candidate).isDirectory(); } catch { return false; } }) || ""; } function findUpFile(relativePath) { let current = MODULE_DIR; for (; ; ) { const candidate = path5.join(current, relativePath); if (fs4.existsSync(candidate)) { return candidate; } const next = path5.dirname(current); if (next === current) { return ""; } current = next; } } function findUpDirectory(relativePath) { let current = MODULE_DIR; for (; ; ) { const candidate = path5.join(current, relativePath); if (firstExistingDirectory([candidate])) { return candidate; } const next = path5.dirname(current); if (next === current) { return ""; } current = next; } } function cadPythonExecutable(repoRoot) { const configured = String(process.env.VIEWER_CAD_PYTHON || process.env.CAD_PYTHON || "").trim(); if (configured) { return configured; } const resolvedRepoRoot = path5.resolve(repoRoot || ""); return firstExistingFile([ path5.join(resolvedRepoRoot, ".venv", "bin", "python"), path5.join(process.cwd(), ".venv", "bin", "python"), path5.join(PACKAGE_ROOT, ".venv", "bin", "python"), findUpFile(path5.join(".venv", "bin", "python")) ]) || "python3"; } function cadPythonEnv() { const pythonPathEntries = []; for (const configured of [ process.env.VIEWER_CAD_PYTHONPATH, process.env.CAD_PYTHONPATH, process.env.VIEWER_CADPY_PYTHONPATH ]) { const value = String(configured || "").trim(); if (value) { pythonPathEntries.push(value); } } for (const discovered of [ findUpDirectory(path5.join("scripts", "packages", "cadpy", "src")), findUpDirectory(path5.join("scripts", "packages")), findUpDirectory(path5.join("viewer", "packages", "cadpy", "src")), findUpDirectory(path5.join("packages", "cadpy", "src")), path5.join(PACKAGE_ROOT, "vendor", "python"), findUpDirectory(path5.join("runtime", "vendor", "python")), findUpDirectory(path5.join("vendor", "python")) ]) { if (discovered) { pythonPathEntries.push(discovered); } } const existingPythonPath = String(process.env.PYTHONPATH || "").trim(); if (existingPythonPath) { pythonPathEntries.push(existingPythonPath); } return { ...process.env, ...pythonPathEntries.length ? { PYTHONPATH: pythonPathEntries.join(path5.delimiter) } : {} }; } function ensurePythonStepTopologyArtifact({ repoRoot, stepPath, sourcePath = "", force = false, skipStepWrite = false, writeStepAfterArtifact = false, resolveOnFirstResult = false, verbose = false, meshTolerance = null, meshAngularTolerance = null } = {}) { const resolvedRepoRoot = path5.resolve(repoRoot || ""); const resolvedStepPath = path5.resolve(stepPath || ""); const args = [ "-m", "cadpy.step_artifact", "--repo-root", resolvedRepoRoot, "--step", resolvedStepPath ]; const resolvedSourcePath = sourcePath ? path5.resolve(sourcePath) : ""; if (resolvedSourcePath) { args.push("--source-path", resolvedSourcePath); } if (force) { args.push("--force"); } if (skipStepWrite) { args.push("--skip-step-write"); } if (writeStepAfterArtifact) { args.push("--write-step-after-artifact"); } if (meshTolerance !== null && meshTolerance !== void 0) { args.push("--mesh-tolerance", String(meshTolerance)); } if (meshAngularTolerance !== null && meshAngularTolerance !== void 0) { args.push("--mesh-angular-tolerance", String(meshAngularTolerance)); } if (verbose || process.env.VIEWER_STEP_ARTIFACT_VERBOSE === "1") { args.push("--verbose"); } return new Promise((resolve) => { let resolved = false; const resolveOnce = (result) => { if (resolved) { return; } resolved = true; resolve(result); }; const normalizeResult = (result) => { if (result?.ok) { result.stepPath = resolvedStepPath; result.glbPath = inlineStepGlbArtifactPathForSource(resolvedStepPath); } return result; }; const maybeResolveEarly = () => { if (!resolveOnFirstResult || resolved) { return; } for (const line of stdout.split(/\r?\n/)) { const trimmed = line.trim(); if (!trimmed.startsWith("{")) { continue; } try { const result = normalizeResult(JSON.parse(trimmed)); if (result?.ok) { resolveOnce(result); return; } } catch { } } }; const child = spawn(cadPythonExecutable(resolvedRepoRoot), args, { cwd: resolvedRepoRoot, env: cadPythonEnv(resolvedRepoRoot), stdio: ["ignore", "pipe", "pipe"] }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; maybeResolveEarly(); }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", (error) => { resolveOnce({ ok: false, stepPath: resolvedStepPath, error: error instanceof Error ? error.message : String(error) }); }); child.on("close", (code) => { const output = stdout.trim(); const lastJsonLine = output.split(/\r?\n/).reverse().find((line) => line.trim().startsWith("{")); if (code === 0 && lastJsonLine) { try { resolveOnce(normalizeResult(JSON.parse(lastJsonLine))); return; } catch { } } resolveOnce({ ok: false, stepPath: resolvedStepPath, exitCode: code, error: (stderr || stdout || `STEP artifact generator exited with code ${code}`).trim() }); }); }); } // viewer/src/server/step/stepArtifactCompiler.mjs var STEP_SUFFIXES = /* @__PURE__ */ new Set([".step", ".stp"]); function sameStemPythonGeneratorPath(stepPath) { const extension = path6.extname(stepPath).toLowerCase(); if (!STEP_SUFFIXES.has(extension)) { return ""; } const candidatePath = path6.join( path6.dirname(stepPath), `${path6.basename(stepPath, extension)}.py` ); try { return /\bgen_step\s*\(/.test(fs5.readFileSync(candidatePath, "utf-8")) ? candidatePath : ""; } catch { return ""; } } function cadPathForStepSource2(repoRoot, sourcePath) { const relativePath = repoRelativePath(repoRoot, sourcePath); return relativePath.slice(0, -path6.extname(relativePath).length); } function canBuildStepArtifact(artifact) { const code = String(artifact?.stepArtifact?.error?.code || ""); return !artifact?.stepArtifact?.ok && [ "missing_glb", "missing_step_topology", "missing_edge_topology", "missing_surface_edge_attributes", "missing_selector_topology", "missing_source_path", "missing_step_hash", "stale_step_artifact", "unsupported_step_topology" ].includes(code); } async function compileStepTopologyArtifact({ repoRoot, stepPath, sourcePath = "", targetPath = inlineStepGlbArtifactPathForSource(stepPath), force = true, skipStepWrite = false, writeStepAfterArtifact = false, meshTolerance = null, meshAngularTolerance = null } = {}) { if (!repoRoot) { throw new Error("repoRoot is required"); } if (!stepPath) { throw new Error("stepPath is required"); } const resolvedRepoRoot = path6.resolve(repoRoot); const resolvedStepPath = path6.resolve(stepPath); const resolvedSourcePath = sourcePath ? path6.resolve(sourcePath) : ""; const resolvedTargetPath = path6.resolve(targetPath); const pythonResult = await ensurePythonStepTopologyArtifact({ repoRoot: resolvedRepoRoot, stepPath: resolvedStepPath, sourcePath: resolvedSourcePath, force, skipStepWrite, writeStepAfterArtifact, resolveOnFirstResult: writeStepAfterArtifact, meshTolerance, meshAngularTolerance }); if (!pythonResult?.ok) { throw new Error(pythonResult?.error || `Failed to generate STEP topology artifact: ${resolvedStepPath}`); } const pythonGlbPath = path6.resolve(pythonResult.glbPath || inlineStepGlbArtifactPathForSource(resolvedStepPath)); if (pythonGlbPath !== resolvedTargetPath) { fs5.mkdirSync(path6.dirname(resolvedTargetPath), { recursive: true }); fs5.copyFileSync(pythonGlbPath, resolvedTargetPath); } return { ...pythonResult, ok: true, stepPath: resolvedStepPath, glbPath: resolvedTargetPath }; } async function ensureStepTopologyArtifact({ repoRoot, stepPath, sourcePath = "", force = false, skipStepWrite = false, writeStepAfterArtifact = false, meshTolerance = null, meshAngularTolerance = null } = {}) { const resolvedRepoRoot = path6.resolve(repoRoot); const resolvedStepPath = path6.resolve(stepPath); const resolvedSourcePath = sourcePath ? path6.resolve(sourcePath) : ""; const cadPath = cadPathForStepSource2(resolvedRepoRoot, resolvedStepPath); const current = validateStepTopologyArtifact({ repoRoot: resolvedRepoRoot, sourcePath: resolvedStepPath, cadPath }); const currentArtifactError = current.stepArtifact?.error && typeof current.stepArtifact.error === "object" ? current.stepArtifact.error : {}; const currentSourceKind = String( current.stepArtifact?.sourceKind || currentArtifactError.sourceKind || "" ).trim().toLowerCase(); const currentSourcePath = String( current.stepArtifact?.sourcePath || currentArtifactError.sourcePath || "" ).trim(); const stepFileExists = fs5.existsSync(resolvedStepPath); const shouldInferPythonSource = Boolean( resolvedSourcePath || skipStepWrite || writeStepAfterArtifact || !stepFileExists ); const inferredSourcePath = shouldInferPythonSource ? resolvedSourcePath || (currentSourceKind === "python" && currentSourcePath ? path6.resolve(resolvedRepoRoot, currentSourcePath) : "") || sameStemPythonGeneratorPath(resolvedStepPath) : ""; const resolvedSkipStepWrite = Boolean( skipStepWrite || inferredSourcePath ); const hasMeshOverride = meshTolerance !== null && meshTolerance !== void 0 || meshAngularTolerance !== null && meshAngularTolerance !== void 0; if (!force && !hasMeshOverride && (current.stepArtifact?.ok || !current.stepArtifact?.ok && !canBuildStepArtifact(current))) { return { ok: Boolean(current.stepArtifact?.ok), skipped: true, reason: current.stepArtifact?.error?.code || "", stepPath: resolvedStepPath, glbPath: current.glbPath, validation: current.stepArtifact }; } const targetPath = inlineStepGlbArtifactPathForSource(resolvedStepPath); const result = await compileStepTopologyArtifact({ repoRoot: resolvedRepoRoot, stepPath: resolvedStepPath, sourcePath: inferredSourcePath || void 0, targetPath, force, skipStepWrite: resolvedSkipStepWrite, writeStepAfterArtifact: Boolean(writeStepAfterArtifact && resolvedSkipStepWrite), meshTolerance, meshAngularTolerance }); const next = validateStepTopologyArtifact({ repoRoot: resolvedRepoRoot, sourcePath: resolvedStepPath, cadPath }); return { ...result, ok: Boolean(next.stepArtifact?.ok), validation: next.stepArtifact }; } // viewer/packages/implicitjs/src/lib/implicitCad/export.js import fs6 from "node:fs/promises"; import path7 from "node:path"; import { pathToFileURL } from "node:url"; // viewer/packages/implicitjs/src/common/parameters.js var HEX_COLOR_RE = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/; function isObject(value) { return !!value && typeof value === "object" && !Array.isArray(value); } function normalizeString(value, fallback = "") { const text = String(value ?? fallback).trim(); return text || fallback; } function toFiniteNumber(value, fallback = 0) { const numericValue = Number(value); return Number.isFinite(numericValue) ? numericValue : fallback; } function clamp(value, min, max) { return Math.min(Math.max(value, min), max); } function normalizeParameterType(value) { const type = normalizeString(value, "number").toLowerCase(); if (["number", "boolean", "enum", "select", "color", "string", "button"].includes(type)) { return type === "select" ? "enum" : type; } return "number"; } function normalizeParameterOptions(value) { return (Array.isArray(value) ? value : []).map((option) => { if (isObject(option)) { const valueText2 = normalizeString(option.value); return valueText2 ? { value: valueText2, label: normalizeString(option.label, valueText2) } : null; } const valueText = normalizeString(option); return valueText ? { value: valueText, label: valueText } : null; }).filter(Boolean); } function normalizeParameterValue(definition, value) { const type = normalizeParameterType(definition?.type); if (type === "boolean") { return value === true; } if (type === "color") { const color = normalizeString(value, normalizeString(definition?.defaultValue, "#ffffff")); return HEX_COLOR_RE.test(color) ? color : "#ffffff"; } if (type === "enum") { const options = Array.isArray(definition?.options) ? definition.options : []; const valueText = normalizeString(value, options[0]?.value || ""); return options.some((option) => option.value === valueText) ? valueText : options[0]?.value || ""; } if (type === "string") { return String(value ?? ""); } if (type === "button") { return Math.max(0, Math.floor(toFiniteNumber(value, 0))); } const min = toFiniteNumber(definition?.min, 0); const max = Math.max(toFiniteNumber(definition?.max, min), min); return clamp(toFiniteNumber(value, toFiniteNumber(definition?.defaultValue, min)), min, max); } function normalizeParameterDefinition(id, rawDefinition) { const raw = isObject(rawDefinition) ? rawDefinition : {}; const type = normalizeParameterType(raw.type); const min = toFiniteNumber(raw.min, 0); const max = Math.max(toFiniteNumber(raw.max, type === "number" ? 1 : min), min); const options = normalizeParameterOptions(raw.options || raw.values); const fallbackDefault = type === "boolean" ? false : type === "color" ? "#ffffff" : type === "enum" ? options[0]?.value || "" : type === "string" ? "" : 0; return { id, type, label: normalizeString(raw.label, id), description: normalizeString(raw.description), unit: normalizeString(raw.unit), min, max, step: Math.max(toFiniteNumber(raw.step, type === "number" ? 0.01 : 1), 0), defaultValue: normalizeParameterValue({ type, min, max, options }, raw.default ?? raw.defaultValue ?? fallbackDefault), options }; } function normalizeParameterDefinitions(value) { const entries = Array.isArray(value) ? value.map((definition) => [definition?.id, definition]) : Object.entries(isObject(value) ? value : {}); return entries.map(([id, rawDefinition]) => normalizeParameterDefinition(normalizeString(id), rawDefinition)).filter((definition) => definition.id); } function parameterMapForDefinitions(parameters) { return Object.fromEntries( (Array.isArray(parameters) ? parameters : []).filter((parameter) => parameter?.id).map((parameter) => [parameter.id, parameter]) ); } function normalizeParameterValues(definition, values = {}) { const parameterMap = definition?.parameterMap || {}; return Object.fromEntries( Object.values(parameterMap).map((parameter) => [ parameter.id, normalizeParameterValue(parameter, isObject(values) && Object.hasOwn(values, parameter.id) ? values[parameter.id] : parameter.defaultValue) ]) ); } function normalizeParameterAnimations(value) { const entries = Array.isArray(value) ? value.map((animation) => [animation?.id, animation]) : Object.entries(isObject(value) ? value : {}); return entries.map(([id, rawAnimation]) => { const raw = isObject(rawAnimation) ? rawAnimation : {}; const animationId = normalizeString(id); return animationId ? { id: animationId, label: normalizeString(raw.label, animationId), description: normalizeString(raw.description), duration: Math.max(toFiniteNumber(raw.duration ?? raw.durationSeconds, 1), 1e-3), loop: raw.loop !== false, update: typeof raw.update === "function" ? raw.update : null, raw } : null; }).filter(Boolean); } // viewer/packages/implicitjs/src/lib/implicitCad/sdfEvaluator.js function isVector(value) { return Array.isArray(value); } function finiteNumber(value, fallback = 0) { const numeric = Number(value); return Number.isFinite(numeric) ? numeric : fallback; } function truthy(value) { if (isVector(value)) { return value.some((component) => truthy(component)); } return Boolean(value); } function vec(args, size) { const flat = []; for (const arg of args) { if (isVector(arg)) { flat.push(...arg); } else { flat.push(arg); } } if (flat.length === 0) { flat.push(0); } if (flat.length === 1) { return Array.from({ length: size }, () => finiteNumber(flat[0])); } return Array.from({ length: size }, (_, index) => finiteNumber(flat[index], 0)); } function vec2(x = 0, y = void 0) { return vec(y === void 0 ? [x] : [x, y], 2); } function vec3(x = 0, y = void 0, z = void 0) { return vec(y === void 0 && z === void 0 ? [x] : [x, y, z], 3); } function vec4(x = 0, y = void 0, z = void 0, w = void 0) { return vec(y === void 0 && z === void 0 && w === void 0 ? [x] : [x, y, z, w], 4); } function mapUnary(value, fn) { return isVector(value) ? value.map((component) => fn(component)) : fn(value); } function mapBinary(a, b, fn) { if (isVector(a) && isVector(b)) { const size = Math.max(a.length, b.length); return Array.from({ length: size }, (_, index) => fn(a[index] ?? 0, b[index] ?? 0)); } if (isVector(a)) { return a.map((component) => fn(component, b)); } if (isVector(b)) { return b.map((component) => fn(a, component)); } return fn(a, b); } function add(a, b) { return mapBinary(a, b, (x, y) => x + y); } function sub(a, b) { return mapBinary(a, b, (x, y) => x - y); } function mul(a, b) { return mapBinary(a, b, (x, y) => x * y); } function div(a, b) { return mapBinary(a, b, (x, y) => x / y); } function neg(value) { return mapUnary(value, (component) => -component); } function abs(value) { return mapUnary(value, Math.abs); } function minValue(a, b) { return mapBinary(a, b, Math.min); } function maxValue(a, b) { return mapBinary(a, b, Math.max); } function clamp2(value, low, high) { return minValue(maxValue(value, low), high); } function mix(a, b, t) { return add(mul(a, sub(1, t)), mul(b, t)); } function smoothstep(edge0, edge1, value) { const t = clamp2(div(sub(value, edge0), sub(edge1, edge0)), 0, 1); return mul(mul(t, t), sub(3, mul(2, t))); } function mod(a, b) { return mapBinary(a, b, (x, y) => x - y * Math.floor(x / y)); } function length(value) { if (!isVector(value)) { return Math.abs(value); } return Math.hypot(...value); } function dot(a, b) { const va = isVector(a) ? a : [a]; const vb = isVector(b) ? b : [b]; const size = Math.max(va.length, vb.length); let sum = 0; for (let index = 0; index < size; index += 1) { sum += (va[index] ?? 0) * (vb[index] ?? 0); } return sum; } function cross(a, b) { const va = vec3(a); const vb = vec3(b); return [ va[1] * vb[2] - va[2] * vb[1], va[2] * vb[0] - va[0] * vb[2], va[0] * vb[1] - va[1] * vb[0] ]; } function normalize(value) { const len = length(value); return len > 1e-12 ? div(value, len) : mul(value, 0); } function swizzleIndices(swizzle) { const lookup = { x: 0, y: 1, z: 2, w: 3, r: 0, g: 1, b: 2, a: 3, s: 0, t: 1, p: 2, q: 3 }; return String(swizzle || "").split("").map((component) => lookup[component]); } function getSwizzle(value, swizzle) { const indices = swizzleIndices(swizzle); if (!indices.length || indices.some((index) => index === void 0)) { throw new Error(`Unsupported GLSL member access: .${swizzle}`); } const source = isVector(value) ? value : [value]; const result = indices.map((index) => source[index] ?? 0); return result.length === 1 ? result[0] : result; } function setSwizzle(target, swizzle, value) { if (!isVector(target)) { throw new Error(`Cannot assign .${swizzle} on a scalar value`); } const indices = swizzleIndices(swizzle); const values = isVector(value) ? value : [value]; indices.forEach((targetIndex, index) => { if (targetIndex === void 0) { throw new Error(`Unsupported GLSL member assignment: .${swizzle}`); } target[targetIndex] = finiteNumber(values[index], values[0] ?? 0); }); return target; } function implicit_linear_map(value, inMin, inMax, outMin, outMax) { const slope = (outMax - outMin) / (inMax - inMin); return (value - inMin) * slope + outMin; } function implicit_ramp(value, inMin, inMax, outMin, outMax) { return Math.min(Math.max(implicit_linear_map(value, inMin, inMax, outMin, outMax), outMin), outMax); } function implicit_two_body_field(a, b) { return (a - b) / (a + b); } function implicit_two_body_polar(a, b, angle) { return a * Math.cos(angle) + b * Math.sin(angle); } function implicit_triangle_wave_even(value, period) { if (isVector(value) || isVector(period)) { return mapBinary(value, period, implicit_triangle_wave_even); } const halfPeriod = period * 0.5; const quarterPeriod = period * 0.25; const wrapped = mod(value + halfPeriod, period); return quarterPeriod - Math.abs(wrapped - halfPeriod); } function implicit_triangle_wave_even_positive(value, period) { return add(implicit_triangle_wave_even(value, period), mul(period, 0.25)); } function implicit_triangle_wave_odd(value, period) { return implicit_triangle_wave_even(sub(value, mul(period, 0.5)), period); } function implicit_triangle_wave_odd_positive(value, period) { return add(implicit_triangle_wave_odd(value, period), mul(period, 0.25)); } function implicit_repeat_centered(p, period) { return sub(mod(add(p, mul(period, 0.5)), period), mul(period, 0.5)); } function implicit_intersect_round(a, b, radius) { const k = Math.max(radius, 0); const q = maxValue(add(vec2(a, b), k), 0); return Math.min(-k, Math.max(a, b)) + length(q); } function implicit_intersect_chamfer(a, b, radius) { return Math.max(Math.max(a, b), (a + b + radius) * 0.7071067811865476); } function implicit_intersect_exp(a, b, radius) { const k = Math.max(radius, 1e-6) * 0.5; return k * Math.log(Math.exp(a / k) + Math.exp(b / k)); } function implicit_intersect_lp_norm(a, b, radius, normPower) { const k = Math.max(radius, 0); const p = Math.max(normPower, 1e-6); const q = maxValue(add(vec2(a, b), k), 0); return Math.min(-k, Math.max(a, b)) + Math.pow(Math.pow(q[0], p) + Math.pow(q[1], p), 1 / p); } function implicit_intersect_rvachev(a, b, radius) { const sharp = Math.max(a, b); const k = Math.max(radius, 0); if (k <= 0) { return sharp; } const r0 = a + b - Math.sqrt(a * a + b * b); const t = Math.min(Math.max((sharp + k) / k, 0), 1); const s = t * t * (3 - 2 * t); return sharp < -k ? sharp : mix(sharp, r0, s); } var BUILTINS = { float: (value = 0) => finiteNumber(value), int: (value = 0) => Math.trunc(finiteNumber(value)), bool: (value = false) => truthy(value), vec2, vec3, vec4, abs, min: minValue, max: maxValue, clamp: clamp2, mix, smoothstep, mod, length, dot, cross, normalize, sin: (value) => mapUnary(value, Math.sin), cos: (value) => mapUnary(value, Math.cos), tan: (value) => mapUnary(value, Math.tan), atan: (...args) => args.length >= 2 ? Math.atan2(args[0], args[1]) : mapUnary(args[0], Math.atan), pow: (a, b) => mapBinary(a, b, Math.pow), sqrt: (value) => mapUnary(value, Math.sqrt), exp: (value) => mapUnary(value, Math.exp), log: (value) => mapUnary(value, Math.log), floor: (value) => mapUnary(value, Math.floor), ceil: (value) => mapUnary(value, Math.ceil), fract: (value) => mapUnary(value, (component) => component - Math.floor(component)), sign: (value) => mapUnary(value, Math.sign), implicit_clamp01: (value) => clamp2(value, 0, 1), implicit_linear_map, implicit_ramp, implicit_two_body_field, implicit_two_body_polar, implicit_triangle_wave_even, implicit_triangle_wave_even_positive, implicit_triangle_wave_odd, implicit_triangle_wave_odd_positive, implicit_repeat_centered, implicit_intersect_sharp: (a, b) => Math.max(a, b), implicit_union_sharp: (a, b) => Math.min(a, b), implicit_intersect_round, implicit_union_round: (a, b, radius) => -implicit_intersect_round(-a, -b, radius), implicit_intersect_chamfer, implicit_union_chamfer: (a, b, radius) => -implicit_intersect_chamfer(-a, -b, radius), implicit_intersect_exp, implicit_union_exp: (a, b, radius) => -implicit_intersect_exp(-a, -b, radius), implicit_intersect_lp_norm, implicit_union_lp_norm: (a, b, radius, normPower) => -implicit_intersect_lp_norm(-a, -b, radius, normPower), implicit_intersect_rvachev, implicit_union_rvachev: (a, b, radius) => -implicit_intersect_rvachev(-a, -b, radius), implicit_plane2: (p, origin, normal) => dot(sub(p, origin), normalize(normal)), implicit_line_segment2: (p, a, b) => { const segment = sub(b, a); const segmentLengthSq = dot(segment, segment); if (segmentLengthSq < 1e-12) { return length(sub(p, a)); } const t = clamp2(dot(sub(p, a), segment) / segmentLengthSq, 0, 1); return length(sub(p, add(a, mul(t, segment)))); }, implicit_sphere: (p, center, radius) => length(sub(p, center)) - radius, implicit_box_centered: (p, size, center) => { const q = sub(abs(sub(p, center)), mul(size, 0.5)); return length(maxValue(q, 0)) + Math.min(Math.max(q[0], Math.max(q[1], q[2])), 0); }, implicit_plane: (p, origin, normal) => dot(sub(p, origin), normalize(normal)), implicit_line_segment: (p, a, b) => { const segment = sub(b, a); const segmentLengthSq = dot(segment, segment); if (segmentLengthSq < 1e-12) { return length(sub(p, a)); } const t = clamp2(dot(sub(p, a), segment) / segmentLengthSq, 0, 1); return length(sub(p, add(a, mul(t, segment)))); }, implicit_torus: (p, majorRadius, minorRadius) => { const q = vec2(length(getSwizzle(p, "xy")) - majorRadius, getSwizzle(p, "z")); return length(q) - minorRadius; }, implicit_axis: (p, origin, direction) => { const directionLength = length(direction); if (directionLength < 1e-12) { return length(sub(p, origin)); } const axis = div(direction, directionLength); const toPoint = sub(p, origin); return length(sub(toPoint, mul(dot(toPoint, axis), axis))); }, implicit_cylinder: (p, origin, direction, radius) => BUILTINS.implicit_axis(p, origin, direction) - radius, implicit_cylinder_capped: (p, a, b, radius) => { const axis = sub(b, a); const side = BUILTINS.implicit_cylinder(p, a, axis, radius); const capA = -BUILTINS.implicit_plane(p, a, axis); const capB = BUILTINS.implicit_plane(p, b, axis); return Math.max(side, Math.max(capA, capB)); }, implicit_capsule: (p, a, b, radius) => BUILTINS.implicit_line_segment(p, a, b) - radius, implicit_cone_capsule: (p, a, b, radiusA, radiusB) => { const axis = sub(b, a); const axisLengthSq = dot(axis, axis); if (axisLengthSq < 1e-12) { return BUILTINS.implicit_sphere(p, a, radiusA); } const t = clamp2(dot(sub(p, a), axis) / axisLengthSq, 0, 1); const radius = mix(radiusA, radiusB, t); return length(sub(p, add(a, mul(t, axis)))) - radius; }, implicit_cone: (p, apex, direction, halfAngle) => { const directionLength = length(direction); if (directionLength < 1e-12) { return length(sub(p, apex)); } const axis = div(direction, directionLength); const toPoint = sub(p, apex); const axial = dot(toPoint, axis); const perpendicular = length(sub(toPoint, mul(axial, axis))); return perpendicular - axial * Math.tan(halfAngle); }, implicit_cone_capped: (p, a, b, radiusA, radiusB) => { const axis = sub(b, a); const axisLength = length(axis); if (axisLength < 1e-12) { return BUILTINS.implicit_sphere(p, a, radiusA); } const halfAngle = Math.atan2(Math.abs(radiusB - radiusA), axisLength); const coneDistance = radiusA < radiusB ? BUILTINS.implicit_cone(p, a, axis, halfAngle) - radiusA : BUILTINS.implicit_cone(p, b, neg(axis), halfAngle) - radiusB; const capA = -BUILTINS.implicit_plane(p, a, axis); const capB = BUILTINS.implicit_plane(p, b, axis); return Math.max(coneDistance, Math.max(capA, capB)); }, implicit_shell: (distanceValue, thickness, bias = 0) => Math.abs(distanceValue + bias * thickness * 0.5) - thickness * 0.5, implicit_rotate_axis: (p, origin, direction, angle) => { const k = normalize(direction); const local = sub(p, origin); const c = Math.cos(angle); const s = Math.sin(angle); return add(add(add(origin, mul(local, c)), mul(cross(k, local), s)), mul(k, dot(k, local) * (1 - c))); }, implicit_remap_cylindrical: (p, circumference) => { const radial = length(getSwizzle(p, "xy")); const theta = Math.atan2(p[1], p[0]); return vec3(radial, theta * (circumference / (Math.PI * 2)), p[2]); }, implicit_tpms_gyroid: (p, period, drop) => { const xyz = mul(p, div(Math.PI * 2, period)); const yzx = getSwizzle(xyz, "yzx"); const field = dot(drop, mul(BUILTINS.sin(xyz), BUILTINS.cos(yzx))); return field * (period[0] + period[1] + period[2]) / 18; }, implicit_tpms_schwarz: (p, period, drop, gyroidBlend) => { const xyz = mul(p, div(Math.PI * 2, period)); const yzx = getSwizzle(xyz, "yzx"); const mixTerm = add(vec3(-(1 - gyroidBlend)), mul(BUILTINS.sin(xyz), gyroidBlend)); const field = dot(drop, mul(BUILTINS.cos(yzx), mixTerm)); return field * (period[0] + period[1] + period[2]) / 36; }, implicit_diamond: () => 0 }; BUILTINS.implicit_tpms_diamond = (p, period, drop, gyroidBlend) => { const xyz = mul(p, div(Math.PI * 2, period)); const yzx = getSwizzle(xyz, "yzx"); const zxy = getSwizzle(xyz, "zxy"); const sinXyz = BUILTINS.sin(xyz); const cosYzx = BUILTINS.cos(yzx); const cosZxy = BUILTINS.cos(zxy); const blendFactor = 1 - gyroidBlend; const term1 = blendFactor * sinXyz[0] * sinXyz[1] * sinXyz[2]; const term2 = dot(drop, mul(mul(sinXyz, cosYzx), add(mul(cosZxy, blendFactor), vec3(gyroidBlend)))); return (term1 + term2) * (period[0] + period[1] + period[2]) / (6 * 2.8284271247461903 * 2); }; BUILTINS.implicit_tpms_lidinoid = (p, period, drop, gyroidBlend) => { const xyz = mul(p, div(Math.PI * 2, period)); const yzx = getSwizzle(xyz, "yzx"); const zxy = getSwizzle(xyz, "zxy"); const cos2Xyz = BUILTINS.cos(mul(2, xyz)); const cos2Yzx = getSwizzle(cos2Xyz, "yzx"); const blendFactor = 1 - gyroidBlend; const term1 = dot(drop, mul(mul(BUILTINS.sin(zxy), BUILTINS.cos(yzx)), add(mul(BUILTINS.sin(mul(2, xyz)), blendFactor), vec3(gyroidBlend)))); const term2 = blendFactor * dot(cos2Xyz, cos2Yzx); return (term1 - term2) * (period[0] + period[1] + period[2]) / 72; }; BUILTINS.implicit_tpms_neovius = (p, period, drop, schwarzBlend) => { const xyz = mul(p, div(Math.PI * 2, period)); const cosDrop = mul(BUILTINS.cos(xyz), drop); const term1 = -dot(cosDrop, vec3(1)); const term2 = (1 - schwarzBlend) * (4 / 3) * cosDrop[0] * cosDrop[1] * cosDrop[2]; return (term1 - term2) * (period[0] + period[1] + period[2]) / (6 * (26 / 3)); }; BUILTINS.implicit_tpms_split_p = (p, period, lidinoidBlend, gyroidOctave, schwarzOctave) => { const xyz = mul(p, div(Math.PI * 2, period)); const yzx = getSwizzle(xyz, "yzx"); const zxy = getSwizzle(xyz, "zxy"); const sin2Xyz = BUILTINS.sin(mul(2, xyz)); const cos2Xyz = BUILTINS.cos(mul(2, xyz)); const term1 = -lidinoidBlend * dot(mul(mul(sin2Xyz, BUILTINS.cos(yzx)), BUILTINS.sin(zxy)), vec3(1)); const term2 = gyroidOctave * dot(mul(sin2Xyz, cos2Xyz), vec3(1)); const term3 = schwarzOctave * dot(cos2Xyz, vec3(1)); return (term1 + term2 + term3) * (period[0] + period[1] + period[2]) / 36; }; BUILTINS.implicit_tpms_iwp = (p, period, drop) => { const xyz = mul(p, div(Math.PI * 2, period)); const yzx = getSwizzle(xyz, "yzx"); const term1 = 2 * dot(mul(mul(drop, BUILTINS.cos(xyz)), BUILTINS.cos(yzx)), vec3(1)); const term2 = dot(BUILTINS.cos(mul(2, xyz)), vec3(1)); return (term1 - term2) * (period[0] + period[1] + period[2]) / 48; }; BUILTINS.implicit_cubic_grid = (p, size) => { const d = implicit_triangle_wave_even_positive(p, size); return Math.min(d[0], Math.min(d[1], d[2])); }; BUILTINS.implicit_square_honeycomb = (p, size) => { const d = implicit_triangle_wave_even_positive(getSwizzle(p, "xy"), size); return Math.min(d[0], d[1]); }; BUILTINS.implicit_square_honeycomb_reinforced = (p, size, rotation, rotation2, hasRotation2) => { const pxy = getSwizzle(p, "xy"); const grid = implicit_triangle_wave_even_positive(pxy, size); const squareGrid = Math.min(grid[0], grid[1]); const repeated = implicit_repeat_centered(pxy, size); const angle = Math.PI * rotation; let diagonal = Math.abs(BUILTINS.implicit_plane2(repeated, vec2(0), vec2(Math.cos(angle), Math.sin(angle)))); if (hasRotation2 > 0.5) { const angle2 = Math.PI * rotation2; const diagonal2 = Math.abs(BUILTINS.implicit_plane2(repeated, vec2(0), vec2(Math.cos(angle2), Math.sin(angle2)))); diagonal = Math.min(diagonal, diagonal2); } return Math.min(squareGrid, diagonal); }; BUILTINS.implicit_square_diagonal_honeycomb = (p, size) => { const period = vec2(size[0] + size[1]); const repeated = implicit_repeat_centered(getSwizzle(p, "xy"), period); const positive = Math.abs(BUILTINS.implicit_plane2(repeated, vec2(0), vec2(size[1], size[0]))); const negative = Math.abs(BUILTINS.implicit_plane2(repeated, vec2(0), vec2(size[1], -size[0]))); return Math.min(positive, negative); }; BUILTINS.implicit_octet_honeycomb = (p, size) => { const pxy = getSwizzle(p, "xy"); const square = BUILTINS.implicit_square_honeycomb(p, size); const oddGrid = implicit_triangle_wave_odd_positive(pxy, size); const planeGrid = Math.min(oddGrid[0], oddGrid[1]); const diagonalPeriod = length(size) * 0.5; const rotated = vec2((pxy[0] + pxy[1]) / 1.4142135623730951, (pxy[0] - pxy[1]) / 1.4142135623730951); const diagonal = implicit_triangle_wave_odd_positive(rotated, vec2(diagonalPeriod)); return Math.min(Math.min(square, planeGrid), Math.min(diagonal[0], diagonal[1])); }; BUILTINS.implicit_hexagonal_honeycomb = (p, size, setback) => { const pxy = getSwizzle(p, "xy"); const halfSize = mul(size, 0.5); const quarterSize = mul(size, 0.25); const starCenter = vec2(0, (1 - setback) * halfSize[1]); const transition = vec2(halfSize[0], setback * halfSize[1]); const folded = abs(implicit_repeat_centered(pxy, size)); const reflected = vec2(folded[0] - halfSize[0], halfSize[1] - folded[1]); const foldedStar = Math.min( BUILTINS.implicit_line_segment2(folded, starCenter, vec2(0, size[1])), Math.min( BUILTINS.implicit_line_segment2(folded, starCenter, transition), BUILTINS.implicit_line_segment2(folded, starCenter, vec2(-transition[0], transition[1])) ) ); const reflectedStar = Math.min( BUILTINS.implicit_line_segment2(reflected, starCenter, vec2(0, size[1])), Math.min( BUILTINS.implicit_line_segment2(reflected, starCenter, transition), BUILTINS.implicit_line_segment2(reflected, starCenter, vec2(-transition[0], transition[1])) ) ); return folded[0] < quarterSize[0] ? foldedStar : reflectedStar; }; BUILTINS.implicit_triangular_honeycomb = (p, size) => { const folded = abs(implicit_repeat_centered(getSwizzle(p, "xy"), size)); const halfSize = mul(size, 0.5); const quarterSize = mul(size, 0.25); const normalH = vec2(0, 1); const normalP60 = normalize(vec2(size[1], size[0])); const normalN60 = normalize(vec2(size[1], -size[0])); const foldedStar = Math.min( Math.abs(dot(folded, normalH)), Math.min(Math.abs(dot(folded, normalP60)), Math.abs(dot(folded, normalN60))) ); const shifted = sub(folded, halfSize); const shiftedStar = Math.min( Math.abs(dot(shifted, normalH)), Math.min(Math.abs(dot(shifted, normalP60)), Math.abs(dot(shifted, normalN60))) ); return folded[1] < quarterSize[1] ? foldedStar : shiftedStar; }; var TYPE_KEYWORDS = /* @__PURE__ */ new Set(["float", "int", "bool", "vec2", "vec3", "vec4"]); var QUALIFIERS = /* @__PURE__ */ new Set(["const", "highp", "mediump", "lowp", "in", "out", "uniform", "varying"]); var OPERATORS = ["<=", ">=", "==", "!=", "&&", "||", "+=", "-=", "*=", "/=", "++", "--"]; function stripComments(source) { return String(source || "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, ""); } function tokenize(source) { const tokens = []; const text = stripComments(source); let index = 0; while (index < text.length) { const char = text[index]; if (/\s/.test(char)) { index += 1; continue; } const numberMatch = text.slice(index).match(/^(?:\d+\.\d*|\.\d+|\d+)(?:[eE][+-]?\d+)?/); if (numberMatch) { tokens.push({ type: "number", value: Number(numberMatch[0]) }); index += numberMatch[0].length; continue; } const identifierMatch = text.slice(index).match(/^[A-Za-z_][A-Za-z0-9_]*/); if (identifierMatch) { tokens.push({ type: "identifier", value: identifierMatch[0] }); index += identifierMatch[0].length; continue; } const op = OPERATORS.find((candidate) => text.startsWith(candidate, index)); if (op) { tokens.push({ type: "operator", value: op }); index += op.length; continue; } tokens.push({ type: "punct", value: char }); index += 1; } return tokens; } var Parser = class { constructor(tokens) { this.tokens = tokens; this.index = 0; } peek(offset = 0) { return this.tokens[this.index + offset] || null; } consume(value = null) { const token = this.peek(); if (!token) { throw new Error(`Expected ${value || "token"}, reached end of GLSL source`); } if (value !== null && token.value !== value) { throw new Error(`Expected ${value}, got ${token.value}`); } this.index += 1; return token; } match(value) { if (this.peek()?.value === value) { this.index += 1; return true; } return false; } skipQualifiers() { while (QUALIFIERS.has(this.peek()?.value)) { this.consume(); } } parseProgram() { const globals = []; const functions = /* @__PURE__ */ new Map(); while (this.peek()) { this.skipQualifiers(); const type = this.peek()?.value; if (!TYPE_KEYWORDS.has(type) && type !== "void") { this.consume(); continue; } this.consume(); const name = this.consume().value; if (this.match("(")) { const params = []; if (!this.match(")")) { do { this.skipQualifiers(); const paramType = this.consume().value; const paramName = this.consume().value; params.push({ type: paramType, name: paramName }); } while (this.match(",")); this.consume(")"); } functions.set(name, { name, params, returnType: type, body: this.parseBlock() }); } else { let init = { type: "literal", value: 0 }; if (this.match("=")) { init = this.parseExpression(); } this.consume(";"); globals.push({ type: "var", varType: type, name, init }); } } return { globals, functions }; } parseBlock() { this.consume("{"); const body = []; while (this.peek() && this.peek().value !== "}") { body.push(this.parseStatement()); } this.consume("}"); return { type: "block", body }; } parseStatement() { if (this.peek()?.value === "{") { return this.parseBlock(); } if (this.match(";")) { return { type: "empty" }; } if (this.match("return")) { const expression2 = this.parseExpression(); this.consume(";"); return { type: "return", expression: expression2 }; } if (this.match("if")) { this.consume("("); const condition = this.parseExpression(); this.consume(")"); const consequent = this.parseStatement(); const alternate = this.match("else") ? this.parseStatement() : null; return { type: "if", condition, consequent, alternate }; } if (this.match("for")) { this.consume("("); const init = this.parseForPart(";"); this.consume(";"); const condition = this.peek()?.value === ";" ? null : this.parseExpression(); this.consume(";"); const update = this.peek()?.value === ")" ? null : this.parseExpression(); this.consume(")"); return { type: "for", init, condition, update, body: this.parseStatement() }; } if (TYPE_KEYWORDS.has(this.peek()?.value) || QUALIFIERS.has(this.peek()?.value) && TYPE_KEYWORDS.has(this.peek(1)?.value)) { const statement = this.parseVariableDeclaration(); this.consume(";"); return statement; } const expression = this.parseExpression(); this.consume(";"); return { type: "expr", expression }; } parseForPart() { if (TYPE_KEYWORDS.has(this.peek()?.value) || QUALIFIERS.has(this.peek()?.value) && TYPE_KEYWORDS.has(this.peek(1)?.value)) { return this.parseVariableDeclaration(); } if (this.peek()?.value === ";") { return { type: "empty" }; } return { type: "expr", expression: this.parseExpression() }; } parseVariableDeclaration() { this.skipQualifiers(); const varType = this.consume().value; const name = this.consume().value; let init = { type: "literal", value: defaultValueForType(varType) }; if (this.match("=")) { init = this.parseExpression(); } return { type: "var", varType, name, init }; } parseExpression() { return this.parseAssignment(); } parseAssignment() { const left = this.parseTernary(); const op = this.peek()?.value; if (["=", "+=", "-=", "*=", "/="].includes(op)) { this.consume(); return { type: "assign", op, left, right: this.parseAssignment() }; } return left; } parseTernary() { const condition = this.parseLogicalOr(); if (!this.match("?")) { return condition; } const consequent = this.parseExpression(); this.consume(":"); return { type: "ternary", condition, consequent, alternate: this.parseExpression() }; } parseLogicalOr() { let node = this.parseLogicalAnd(); while (this.match("||")) { node = { type: "binary", op: "||", left: node, right: this.parseLogicalAnd() }; } return node; } parseLogicalAnd() { let node = this.parseEquality(); while (this.match("&&")) { node = { type: "binary", op: "&&", left: node, right: this.parseEquality() }; } return node; } parseEquality() { let node = this.parseComparison(); while (["==", "!="].includes(this.peek()?.value)) { const op = this.consume().value; node = { type: "binary", op, left: node, right: this.parseComparison() }; } return node; } parseComparison() { let node = this.parseAdditive(); while (["<", ">", "<=", ">="].includes(this.peek()?.value)) { const op = this.consume().value; node = { type: "binary", op, left: node, right: this.parseAdditive() }; } return node; } parseAdditive() { let node = this.parseMultiplicative(); while (["+", "-"].includes(this.peek()?.value)) { const op = this.consume().value; node = { type: "binary", op, left: node, right: this.parseMultiplicative() }; } return node; } parseMultiplicative() { let node = this.parseUnary(); while (["*", "/"].includes(this.peek()?.value)) { const op = this.consume().value; node = { type: "binary", op, left: node, right: this.parseUnary() }; } return node; } parseUnary() { if (this.match("+")) { return this.parseUnary(); } if (this.match("-")) { return { type: "unary", op: "-", argument: this.parseUnary() }; } if (this.match("!")) { return { type: "unary", op: "!", argument: this.parseUnary() }; } if (this.match("++")) { return { type: "update", op: "++", argument: this.parseUnary(), prefix: true }; } if (this.match("--")) { return { type: "update", op: "--", argument: this.parseUnary(), prefix: true }; } return this.parsePostfix(); } parsePostfix() { let node = this.parsePrimary(); for (; ; ) { if (this.match(".")) { node = { type: "member", object: node, property: this.consume().value }; continue; } if (this.match("(")) { const args = []; if (!this.match(")")) { do { args.push(this.parseExpression()); } while (this.match(",")); this.consume(")"); } node = { type: "call", callee: node, args }; continue; } if (this.match("++")) { node = { type: "update", op: "++", argument: node, prefix: false }; continue; } if (this.match("--")) { node = { type: "update", op: "--", argument: node, prefix: false }; continue; } break; } return node; } parsePrimary() { const token = this.consume(); if (token.type === "number") { return { type: "literal", value: token.value }; } if (token.value === "true" || token.value === "false") { return { type: "literal", value: token.value === "true" }; } if (token.value === "(") { const expression = this.parseExpression(); this.consume(")"); return expression; } if (token.type === "identifier") { return { type: "identifier", name: token.value }; } throw new Error(`Unexpected GLSL token: ${token.value}`); } }; function defaultValueForType(type) { if (type === "bool") { return false; } if (type === "vec2") { return vec2(0); } if (type === "vec3") { return vec3(0); } if (type === "vec4") { return vec4(0); } return 0; } var ReturnValue = class extends Error { constructor(value) { super("return"); this.value = value; } }; var Scope = class { constructor(parent = null) { this.parent = parent; this.values = /* @__PURE__ */ new Map(); } has(name) { return this.values.has(name) || Boolean(this.parent?.has(name)); } get(name) { if (this.values.has(name)) { return this.values.get(name); } if (this.parent) { return this.parent.get(name); } throw new Error(`Unknown GLSL identifier: ${name}`); } set(name, value) { if (this.values.has(name)) { this.values.set(name, cloneValue(value)); return; } if (this.parent?.has(name)) { this.parent.set(name, value); return; } this.values.set(name, cloneValue(value)); } define(name, value) { this.values.set(name, cloneValue(value)); } }; function cloneValue(value) { return isVector(value) ? [...value] : value; } function castValue(value, type) { if (type === "int") { return Math.trunc(finiteNumber(value)); } if (type === "float") { return finiteNumber(value); } if (type === "bool") { return truthy(value); } if (type === "vec2") { return vec2(value); } if (type === "vec3") { return vec3(value); } if (type === "vec4") { return vec4(value); } return value; } function binaryValue(op, left, right) { switch (op) { case "+": return add(left, right); case "-": return sub(left, right); case "*": return mul(left, right); case "/": return div(left, right); case "<": return left < right; case ">": return left > right; case "<=": return left <= right; case ">=": return left >= right; case "==": return left === right; case "!=": return left !== right; case "&&": return truthy(left) && truthy(right); case "||": return truthy(left) || truthy(right); default: throw new Error(`Unsupported GLSL operator: ${op}`); } } function evalLValue(node, scope, runtime2) { if (node.type === "identifier") { return { get: () => scope.get(node.name), set: (value) => { scope.set(node.name, value); return value; } }; } if (node.type === "member") { const objectLValue = evalLValue(node.object, scope, runtime2); return { get: () => getSwizzle(objectLValue.get(), node.property), set: (value) => { const target = objectLValue.get(); setSwizzle(target, node.property, value); objectLValue.set(target); return value; } }; } throw new Error("Unsupported GLSL assignment target"); } function evalExpression(node, scope, runtime2) { switch (node.type) { case "literal": return cloneValue(node.value); case "identifier": return scope.get(node.name); case "member": return getSwizzle(evalExpression(node.object, scope, runtime2), node.property); case "unary": { const value = evalExpression(node.argument, scope, runtime2); if (node.op === "-") { return neg(value); } if (node.op === "!") { return !truthy(value); } return value; } case "update": { const lvalue = evalLValue(node.argument, scope, runtime2); const current = lvalue.get(); const next = node.op === "++" ? add(current, 1) : sub(current, 1); lvalue.set(next); return node.prefix ? next : current; } case "binary": if (node.op === "&&") { return truthy(evalExpression(node.left, scope, runtime2)) && truthy(evalExpression(node.right, scope, runtime2)); } if (node.op === "||") { return truthy(evalExpression(node.left, scope, runtime2)) || truthy(evalExpression(node.right, scope, runtime2)); } return binaryValue(node.op, evalExpression(node.left, scope, runtime2), evalExpression(node.right, scope, runtime2)); case "ternary": return truthy(evalExpression(node.condition, scope, runtime2)) ? evalExpression(node.consequent, scope, runtime2) : evalExpression(node.alternate, scope, runtime2); case "assign": { const lvalue = evalLValue(node.left, scope, runtime2); const right = evalExpression(node.right, scope, runtime2); const current = lvalue.get(); const value = node.op === "=" ? right : node.op === "+=" ? add(current, right) : node.op === "-=" ? sub(current, right) : node.op === "*=" ? mul(current, right) : div(current, right); return lvalue.set(value); } case "call": { const callee = node.callee.type === "identifier" ? node.callee.name : ""; const args = node.args.map((arg) => evalExpression(arg, scope, runtime2)); if (BUILTINS[callee]) { return BUILTINS[callee](...args); } return runtime2.call(callee, args); } default: throw new Error(`Unsupported GLSL expression node: ${node.type}`); } } function executeStatement(statement, scope, runtime2) { switch (statement.type) { case "empty": return; case "block": for (const child of statement.body) { executeStatement(child, scope, runtime2); } return; case "var": scope.define(statement.name, castValue(evalExpression(statement.init, scope, runtime2), statement.varType)); return; case "expr": evalExpression(statement.expression, scope, runtime2); return; case "return": throw new ReturnValue(evalExpression(statement.expression, scope, runtime2)); case "if": if (truthy(evalExpression(statement.condition, scope, runtime2))) { executeStatement(statement.consequent, scope, runtime2); } else if (statement.alternate) { executeStatement(statement.alternate, scope, runtime2); } return; case "for": { executeStatement(statement.init, scope, runtime2); for (let guard = 0; guard < 1e4; guard += 1) { if (statement.condition && !truthy(evalExpression(statement.condition, scope, runtime2))) { return; } executeStatement(statement.body, scope, runtime2); if (statement.update) { evalExpression(statement.update, scope, runtime2); } } throw new Error("GLSL for-loop exceeded exporter safety limit"); } default: throw new Error(`Unsupported GLSL statement node: ${statement.type}`); } } function normalizedDistanceSource(source) { const text = String(source || "").trim(); if (!text) { throw new Error("Implicit CAD model has no GLSL source"); } return `${text} float implicit_distance(vec3 p) { return sdf(p); } `; } function normalizedColorSource(source) { const text = String(source || "").trim(); if (!text) { throw new Error("Implicit CAD model has no GLSL source"); } const hasColorFunction = /\bvec3\s+color\s*\(/.test(text); return `${text} vec3 implicit_color(vec3 p, vec3 normal) { ${hasColorFunction ? "return color(p, normal);" : "return vec3(0.831372549, 0.831372549, 0.847058824);"} } `; } function createImplicitCadProgramRuntime(model, source, functionName) { const program = new Parser(tokenize(source)).parseProgram(); if (!program.functions.has(functionName)) { throw new Error(`Implicit CAD GLSL source did not define ${functionName}`); } const globals = new Scope(); for (const [name, value] of Object.entries({ PI: Math.PI, TWO_PI: Math.PI * 2 })) { globals.define(name, value); } for (const [name, uniform] of Object.entries(model?.uniforms || {})) { globals.define(name, castValue(uniform?.value, uniform?.type)); } const runtime2 = { call(name, args) { const fn = program.functions.get(name); if (!fn) { throw new Error(`Unknown GLSL function: ${name}`); } const scope = new Scope(globals); fn.params.forEach((param, index) => { scope.define(param.name, castValue(args[index], param.type)); }); try { executeStatement(fn.body, scope, runtime2); } catch (error) { if (error instanceof ReturnValue) { return castValue(error.value, fn.returnType); } throw error; } return defaultValueForType(fn.returnType); } }; for (const global2 of program.globals) { executeStatement(global2, globals, runtime2); } return runtime2; } function createImplicitCadSdfEvaluator(model) { const source = normalizedDistanceSource(model?.glslSource || model?.distanceSource); const runtime2 = createImplicitCadProgramRuntime(model, source, "implicit_distance"); return (x, y, z) => finiteNumber(runtime2.call("implicit_distance", [vec3(x, y, z)]), 1e6); } function createImplicitCadColorEvaluator(model) { const source = normalizedColorSource(model?.colorSource || model?.glslSource || model?.distanceSource); const runtime2 = createImplicitCadProgramRuntime(model, source, "implicit_color"); return (point, normal = [0, 0, 1]) => { const value = runtime2.call("implicit_color", [vec3(point), vec3(normal)]); return vec3(value).map((component) => Math.min(Math.max(finiteNumber(component, 0), 0), 1)); }; } // viewer/packages/implicitjs/src/lib/implicitCad/schema.js var IMPLICIT_CAD_SCHEMA = "implicit.js/0.1.0"; var IMPLICIT_CAD_KIND = "implicit"; var IMPLICIT_CAD_EXTENSIONS2 = Object.freeze([".implicit.js", ".implicit.mjs"]); // viewer/packages/implicitjs/src/lib/implicitCad/model.js var DEFAULT_BOUNDS = Object.freeze({ min: [-50, -50, -50], max: [50, 50, 50] }); var AUTO_BOUNDS_RADII = Object.freeze([4, 8, 16, 32, 64, 128, 256, 512]); var AUTO_BOUNDS_SCAN_SAMPLES = 5; var AUTO_BOUNDS_REFINE_SAMPLES = 9; var AUTO_BOUNDS_CACHE_LIMIT = 32; var DEFAULT_COLOR = "#f4f4f5"; var HEX_COLOR_PATTERN = /^#(?:[0-9a-fA-F]{3}){1,2}$/; var GLSL_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/; var UNIFORM_TYPES = Object.freeze(/* @__PURE__ */ new Set(["float", "int", "bool", "vec2", "vec3", "vec4"])); var PARAM_UNIFORM_TYPES = Object.freeze({ number: "float", boolean: "bool", color: "vec3", button: "int" }); function isObject2(value) { return Boolean(value) && typeof value === "object" && !Array.isArray(value); } function finiteNumber2(value, fallback = 0) { const numeric = Number(value); return Number.isFinite(numeric) ? numeric : fallback; } function finitePositiveNumber(value, fallback) { const numeric = Number(value); return Number.isFinite(numeric) && numeric > 0 ? numeric : fallback; } function finiteVec3(value, fallback) { const source = Array.isArray(value) || ArrayBuffer.isView(value) ? value : []; return [0, 1, 2].map((index) => finiteNumber2(source[index], fallback[index] || 0)); } function finiteVector(value, length2, fallback = []) { const source = Array.isArray(value) || ArrayBuffer.isView(value) ? value : []; return Array.from({ length: length2 }, (_, index) => finiteNumber2(source[index], fallback[index] || 0)); } function normalizeBounds(value, fallback = DEFAULT_BOUNDS) { const radius = finitePositiveNumber(value, null); const raw = radius ? { min: [-radius, -radius, -radius], max: [radius, radius, radius] } : Array.isArray(value) && value.length >= 2 ? { min: value[0], max: value[1] } : isObject2(value) ? value : fallback; const min = finiteVec3(raw.min, DEFAULT_BOUNDS.min); const max = finiteVec3(raw.max, DEFAULT_BOUNDS.max); for (let axis = 0; axis < 3; axis += 1) { if (max[axis] <= min[axis]) { const center = (min[axis] + max[axis]) / 2; min[axis] = center - 0.5; max[axis] = center + 0.5; } } return { min, max }; } function cloneBounds(bounds) { return { min: [...bounds.min], max: [...bounds.max] }; } function hasExplicitBounds(value) { if (value === void 0 || value === null) { return false; } if (String(value).trim().toLowerCase() === "auto") { return false; } return !(isObject2(value) && value.auto === true); } function boundsSize(bounds) { return [ bounds.max[0] - bounds.min[0], bounds.max[1] - bounds.min[1], bounds.max[2] - bounds.min[2] ]; } function expandBounds(min, max, margin) { const safeMargin = Math.max(finiteNumber2(margin, 0), 0.25); return normalizeBounds({ min: [min[0] - safeMargin, min[1] - safeMargin, min[2] - safeMargin], max: [max[0] + safeMargin, max[1] + safeMargin, max[2] + safeMargin] }); } function sampleAutoBounds(sdf, bounds, samples) { const size = boundsSize(bounds); const steps = size.map((axisSize) => axisSize / Math.max(samples - 1, 1)); const threshold = Math.max(Math.min(...steps) * 0.35, 2e-3); const hitMin = [Infinity, Infinity, Infinity]; const hitMax = [-Infinity, -Infinity, -Infinity]; let hitCount = 0; let boundaryTouch = false; for (let iz = 0; iz < samples; iz += 1) { const z = bounds.min[2] + steps[2] * iz; for (let iy = 0; iy < samples; iy += 1) { const y = bounds.min[1] + steps[1] * iy; for (let ix = 0; ix < samples; ix += 1) { const x = bounds.min[0] + steps[0] * ix; const value = finiteNumber2(sdf(x, y, z), 1e6); if (value > threshold) { continue; } hitCount += 1; hitMin[0] = Math.min(hitMin[0], x); hitMin[1] = Math.min(hitMin[1], y); hitMin[2] = Math.min(hitMin[2], z); hitMax[0] = Math.max(hitMax[0], x); hitMax[1] = Math.max(hitMax[1], y); hitMax[2] = Math.max(hitMax[2], z); if (value <= 0 && (ix === 0 || iy === 0 || iz === 0 || ix === samples - 1 || iy === samples - 1 || iz === samples - 1)) { boundaryTouch = true; } } } } return { hitCount, hitMin, hitMax, boundaryTouch, step: steps, threshold }; } function estimateAutoBoundsStartRadius(definition, params) { const largest = definition.parameters.filter((parameter) => parameter.type === "number").filter((parameter) => !likelyPoseParameter(parameter)).reduce((maxValue2, parameter) => { const value = Math.abs(finiteNumber2(params[parameter.id], 0)); return Math.max(maxValue2, value); }, 1); const target = Math.max(largest * 3, 4); return AUTO_BOUNDS_RADII.find((radius) => radius >= target) || AUTO_BOUNDS_RADII[AUTO_BOUNDS_RADII.length - 1]; } function estimateImplicitCadAutoBounds(partialModel, definition, context) { let sdf = null; try { sdf = createImplicitCadSdfEvaluator(partialModel); } catch { return cloneBounds(DEFAULT_BOUNDS); } let candidate = null; const startRadius = estimateAutoBoundsStartRadius(definition, context.params); for (const radius of AUTO_BOUNDS_RADII.filter((candidateRadius) => candidateRadius >= startRadius)) { const bounds = normalizeBounds(radius); const scan = sampleAutoBounds(sdf, bounds, AUTO_BOUNDS_SCAN_SAMPLES); if (!scan.hitCount) { continue; } const margin = Math.max(Math.max(...scan.step) * 1.5, radius * 0.06, 0.5); candidate = expandBounds(scan.hitMin, scan.hitMax, margin); if (!scan.boundaryTouch) { break; } } if (!candidate) { return cloneBounds(DEFAULT_BOUNDS); } for (let pass = 0; pass < 1; pass += 1) { const scan = sampleAutoBounds(sdf, candidate, AUTO_BOUNDS_REFINE_SAMPLES); if (!scan.hitCount) { break; } const margin = Math.max(Math.max(...scan.step) * 1.1, Math.max(...boundsSize(candidate)) * 0.025, 0.25); candidate = expandBounds(scan.hitMin, scan.hitMax, margin); } return candidate; } function likelyPoseParameter(parameter) { const unit = String(parameter?.unit || "").trim().toLowerCase(); if (unit === "deg" || unit === "rad") { return true; } const text = `${parameter?.id || ""} ${parameter?.label || ""}`.toLowerCase(); return [ "angle", "phase", "rotation", "rotate", "orbit", "spin", "yaw", "pitch", "roll" ].some((token) => text.includes(token)); } function autoBoundsCacheKey(definition, params, glslSource) { const values = definition.parameters.filter((parameter) => !likelyPoseParameter(parameter)).filter((parameter) => PARAM_UNIFORM_TYPES[parameter.type]).filter((parameter) => parameter.type !== "color").map((parameter) => { const value = params[parameter.id]; if (typeof value === "number") { return `${parameter.id}:${Number.isFinite(value) ? value.toPrecision(8) : "0"}`; } if (typeof value === "boolean") { return `${parameter.id}:${value ? "1" : "0"}`; } return `${parameter.id}:${String(value ?? "")}`; }).join(";"); return `${glslSource.length}:${values}`; } function readCachedAutoBounds(cache, key, animationPlaying) { if (!cache) { return null; } if (cache.map.has(key)) { return cloneBounds(cache.map.get(key)); } if (animationPlaying && cache.last) { return cloneBounds(cache.last); } return null; } function rememberAutoBounds(cache, key, bounds) { if (!cache) { return; } const cloned = cloneBounds(bounds); cache.map.set(key, cloned); cache.last = cloned; while (cache.map.size > AUTO_BOUNDS_CACHE_LIMIT) { const oldestKey = cache.map.keys().next().value; cache.map.delete(oldestKey); } } function resolveImplicitCadBounds(value, partialModel, definition, context, cache) { if (hasExplicitBounds(value)) { return { bounds: normalizeBounds(value), source: "explicit" }; } const key = autoBoundsCacheKey(definition, context.params, partialModel.glslSource); const cached = readCachedAutoBounds(cache, key, context.animationState.playing); if (cached) { return { bounds: cached, source: "auto" }; } const estimated = estimateImplicitCadAutoBounds(partialModel, definition, context); rememberAutoBounds(cache, key, estimated); return { bounds: estimated, source: "auto" }; } function normalizeHexColor(value, fallback = DEFAULT_COLOR) { const color = String(value || "").trim(); return HEX_COLOR_PATTERN.test(color) ? color : fallback; } function hexToRgb01(hex, fallback = DEFAULT_COLOR) { const value = normalizeHexColor(hex, fallback); const expanded = value.length === 4 ? `${value[1]}${value[1]}${value[2]}${value[2]}${value[3]}${value[3]}` : value.slice(1); return [ parseInt(expanded.slice(0, 2), 16) / 255, parseInt(expanded.slice(2, 4), 16) / 255, parseInt(expanded.slice(4, 6), 16) / 255 ]; } function evaluateValue(value, context) { return typeof value === "function" ? value(context) : value; } function normalizeMaterial() { const material = {}; return { color: normalizeHexColor(material.color, DEFAULT_COLOR), roughness: Math.min(Math.max(finiteNumber2(material.roughness, 0.75), 0), 1), metalness: Math.min(Math.max(finiteNumber2(material.metalness, 0.02), 0), 1) }; } function unwrapModuleExports(moduleValue) { if (typeof moduleValue === "function") { return moduleValue(); } if (!isObject2(moduleValue)) { return moduleValue; } if (moduleValue.default !== void 0) { return typeof moduleValue.default === "function" ? moduleValue.default() : moduleValue.default; } if (moduleValue.model !== void 0) { return typeof moduleValue.model === "function" ? moduleValue.model() : moduleValue.model; } return moduleValue; } function normalizeUniformValue(rawValue, context = {}) { const raw = evaluateValue(rawValue, context); const value = isObject2(raw) && Object.hasOwn(raw, "value") ? evaluateValue(raw.value, context) : raw; const explicitType = isObject2(raw) ? String(raw.type || raw.kind || "").trim().toLowerCase() : ""; const type = UNIFORM_TYPES.has(explicitType) ? explicitType : typeof value === "boolean" ? "bool" : typeof value === "number" ? "float" : typeof value === "string" && HEX_COLOR_PATTERN.test(value) ? "vec3" : Array.isArray(value) || ArrayBuffer.isView(value) ? `vec${Math.min(Math.max(value.length, 2), 4)}` : ""; if (!UNIFORM_TYPES.has(type)) { return null; } if (type === "bool") { return { type, value: value === true }; } if (type === "int") { return { type, value: Math.trunc(finiteNumber2(value, 0)) }; } if (type === "float") { return { type, value: finiteNumber2(value, 0) }; } if (typeof value === "string" && HEX_COLOR_PATTERN.test(value)) { return { type, value: hexToRgb01(value) }; } const length2 = Number(type.slice(3)); const fallback = Array.from({ length: length2 }, () => 0); return { type, value: finiteVector(value, length2, fallback) }; } function uniformsFromParams(parameters = [], params = {}) { return Object.fromEntries( parameters.map((parameter) => { const uniformName = String(parameter?.id || "").trim(); if (!GLSL_IDENTIFIER_PATTERN.test(uniformName) || uniformName.startsWith("gl_")) { throw new Error(`Implicit CAD param "${uniformName}" is not a valid GLSL uniform identifier.`); } const type = PARAM_UNIFORM_TYPES[parameter.type]; if (!type) { return null; } const uniform = normalizeUniformValue({ type, value: params[parameter.id] }); return uniform ? [uniformName, uniform] : null; }).filter(Boolean) ); } function glslSourceFromModel(model, context = {}) { return String(evaluateValue(model.glsl ?? model.glslSource, context) || "").trim(); } function pathIsImplicitCadSource2(value = "") { const pathname = String(value || "").split(/[?#]/, 1)[0].toLowerCase(); return IMPLICIT_CAD_EXTENSIONS2.some((extension) => pathname.endsWith(extension)); } function normalizeAnimationState(value = {}) { const activeId = String(value?.activeId || "").trim(); return { activeId, playing: value?.playing === true, elapsedSec: Math.max(finiteNumber2(value?.elapsedSec ?? value?.elapsed, 0), 0), speed: Math.min(Math.max(finiteNumber2(value?.speed, 1), 0.1), 5) }; } function findAnimation(definition, animationId) { const animations = Array.isArray(definition?.animations) ? definition.animations : []; if (!animations.length) { return null; } const normalizedId = String(animationId || "").trim(); return animations.find((animation) => animation.id === normalizedId) || animations[0] || null; } function buildImplicitCadContext(definition, parameterValues = {}, animationState = {}) { const params = normalizeParameterValues(definition, parameterValues); const normalizedAnimationState = normalizeAnimationState(animationState); const animation = findAnimation(definition, normalizedAnimationState.activeId); const duration = Math.max(Number(animation?.duration) || 0, 1e-3); const elapsedSec = Math.min(normalizedAnimationState.elapsedSec, duration); const progress = animation ? Math.min(Math.max(elapsedSec / duration, 0), 1) : 0; return { ...params, params, parameterValues: params, animation, animationState: { ...normalizedAnimationState, activeId: animation?.id || normalizedAnimationState.activeId, duration: animation?.duration || 0, loop: animation?.loop !== false }, elapsed: elapsedSec, elapsedSec, duration: animation?.duration || 0, progress, cycle: duration > 0 ? elapsedSec / duration : 0, t: elapsedSec, time: elapsedSec }; } function normalizeImplicitCadRuntimeModel(rawModel, definition, parameterValues = {}, animationState = {}, { sourceUrl = "", autoBoundsCache = null } = {}) { const context = buildImplicitCadContext(definition, parameterValues, animationState); const model = rawModel; if (!isObject2(model)) { throw new Error("Implicit CAD module must export an object, or a function returning an object."); } const uniforms = uniformsFromParams(definition.parameters, context.params); const glslSource = glslSourceFromModel(model, context); if (!glslSource) { throw new Error("Implicit CAD module must export GLSL code in glsl."); } const resolvedBounds = resolveImplicitCadBounds( evaluateValue(model.bounds, context), { glslSource, uniforms }, definition, context, autoBoundsCache ); const bounds = resolvedBounds.bounds; const size = [ bounds.max[0] - bounds.min[0], bounds.max[1] - bounds.min[1], bounds.max[2] - bounds.min[2] ]; const center = [ (bounds.min[0] + bounds.max[0]) / 2, (bounds.min[1] + bounds.max[1]) / 2, (bounds.min[2] + bounds.max[2]) / 2 ]; const radius = Math.max(Math.hypot(size[0], size[1], size[2]) / 2, 1e-3); const evaluatedRender = evaluateValue(model.render, context); const render = isObject2(evaluatedRender) ? evaluatedRender : {}; const epsilon = finitePositiveNumber(evaluateValue(render.epsilon, context), Math.max(radius * 7e-4, 2e-3)); const normalEpsilon = finitePositiveNumber( evaluateValue(render.normalEpsilon, context), Math.max(epsilon * 2.5, radius * 1e-3) ); const stepScale = Math.min( Math.max(finiteNumber2(evaluateValue(render.stepScale, context), 0.45), 0.05), 1 ); const maxStep = finitePositiveNumber( evaluateValue(render.maxStep, context), Math.max(radius * 0.035, epsilon * 10) ); return { schema: String(model.schema || IMPLICIT_CAD_SCHEMA), kind: IMPLICIT_CAD_KIND, name: String(model.name || model.title || "Implicit CAD").trim() || "Implicit CAD", description: String(model.description || "").trim(), units: String(model.units || "mm").trim() || "mm", sourceUrl: String(sourceUrl || model.sourceUrl || "").trim(), parameters: definition.parameters, parameterMap: definition.parameterMap, defaultParameterValues: definition.defaultParameterValues, parameterValues: context.params, animations: definition.animations, animationState: context.animationState, glslSource, distanceSource: glslSource, colorSource: /\bvec3\s+color\s*\(/.test(glslSource) ? glslSource : "", uniforms, uniformSignature: Object.entries(uniforms).map(([name, uniform]) => `${name}:${uniform.type}`).sort().join(";"), bounds, boundsSource: resolvedBounds.source, center, size, radius, material: normalizeMaterial(), background: {}, maxSteps: Math.max(16, Math.min(Math.floor(finiteNumber2(evaluateValue(render.steps, context), 192)), 768)), maxDistance: finitePositiveNumber(evaluateValue(render.maxDistance, context), radius * 8), stepScale, maxStep, epsilon, normalEpsilon }; } function normalizeImplicitCadDefinition(moduleValue, { sourceUrl = "" } = {}) { const model = unwrapModuleExports(moduleValue); if (!isObject2(model)) { throw new Error("Implicit CAD module must export an object, or a function returning an object."); } if (model.kind === IMPLICIT_CAD_KIND && model.glslSource && Array.isArray(model.parameters)) { return model.definition ? model : { ...model, definition: null }; } const parameters = normalizeParameterDefinitions(model.params); const parameterMap = parameterMapForDefinitions(parameters); const autoBoundsCache = { map: /* @__PURE__ */ new Map(), last: null }; const definition = { schema: String(model.schema || IMPLICIT_CAD_SCHEMA), kind: IMPLICIT_CAD_KIND, name: String(model.name || model.title || "Implicit CAD").trim() || "Implicit CAD", description: String(model.description || "").trim(), units: String(model.units || "mm").trim() || "mm", sourceUrl: String(sourceUrl || model.sourceUrl || "").trim(), parameters, parameterMap, defaultParameterValues: {}, animations: normalizeParameterAnimations(model.animations), buildModel(parameterValues = {}, animationState = {}) { return normalizeImplicitCadRuntimeModel(model, definition, parameterValues, animationState, { sourceUrl, autoBoundsCache }); } }; definition.defaultParameterValues = normalizeParameterValues( definition, model.values || {} ); const defaultModel = definition.buildModel(definition.defaultParameterValues); return { ...defaultModel, definition }; } function normalizeImplicitCadModel(moduleValue, { sourceUrl = "" } = {}) { return normalizeImplicitCadDefinition(moduleValue, { sourceUrl }); } // viewer/packages/implicitjs/src/lib/implicitCad/animation.js function finiteNumber3(value, fallback = 0) { const numeric = Number(value); return Number.isFinite(numeric) ? numeric : fallback; } function clamp3(value, min, max) { return Math.min(Math.max(value, min), max); } function findImplicitAnimation(definition, animationId = "") { const animations = Array.isArray(definition?.animations) ? definition.animations : []; if (!animations.length) { return null; } const id = String(animationId || "").trim(); return animations.find((animation) => animation.id === id) || animations[0] || null; } function normalizeImplicitAnimationElapsed(elapsedSec, animation) { const duration = Math.max(finiteNumber3(animation?.duration, 1), 1e-3); const elapsed = Math.max(finiteNumber3(elapsedSec, 0), 0); return animation?.loop === false ? Math.min(elapsed, duration) : elapsed % duration; } function animatedImplicitParameterValues(definition, animationOrId, baseValues = {}, elapsedSec = 0) { const animation = typeof animationOrId === "string" ? findImplicitAnimation(definition, animationOrId) : animationOrId; const normalizedBase = normalizeParameterValues(definition, baseValues); if (!definition || typeof animation?.update !== "function") { return normalizedBase; } const duration = Math.max(finiteNumber3(animation.duration, 1), 1e-3); const elapsed = normalizeImplicitAnimationElapsed(elapsedSec, animation); const nextValues = { ...normalizedBase }; const set = (parameterId, value) => { const id = String(parameterId || "").trim(); const parameter = definition.parameterMap?.[id]; if (parameter) { nextValues[id] = normalizeParameterValue(parameter, value); } }; animation.update({ ...normalizedBase, elapsed, elapsedSec: elapsed, duration, progress: clamp3(elapsed / duration, 0, 1), cycle: elapsed / duration, t: elapsed, time: elapsed, loop: animation.loop !== false, params: normalizedBase, set }); return nextValues; } function buildImplicitAnimatedModel(definition, { animationId = "", elapsedSec = 0, params = null, parameterValues = null, playing = false, speed = 1 } = {}) { if (!definition?.buildModel) { throw new Error("Implicit animation export requires a compiled implicit definition."); } const animation = findImplicitAnimation(definition, animationId); const baseValues = params || parameterValues || definition.defaultParameterValues || {}; const animatedValues = animatedImplicitParameterValues(definition, animation, baseValues, elapsedSec); return definition.buildModel(animatedValues, { activeId: animation?.id || animationId, elapsedSec: normalizeImplicitAnimationElapsed(elapsedSec, animation), playing, speed }); } // viewer/packages/implicitjs/src/lib/implicitCad/mesh.js var DEFAULT_RESOLUTION = 96; var DEFAULT_MAX_CELLS = 25e5; var TETRAHEDRA = Object.freeze([ [0, 5, 1, 6], [0, 1, 2, 6], [0, 2, 3, 6], [0, 3, 7, 6], [0, 7, 4, 6], [0, 4, 5, 6] ]); var CUBE_OFFSETS = Object.freeze([ [0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1] ]); function finiteNumber4(value, fallback = 0) { const numeric = Number(value); return Number.isFinite(numeric) ? numeric : fallback; } function clamp4(value, min, max) { return Math.min(Math.max(value, min), max); } function normalizeResolution(value = DEFAULT_RESOLUTION) { return Math.max(8, Math.min(192, Math.floor(finiteNumber4(value, DEFAULT_RESOLUTION)))); } function normalizedGrid(model, { resolution = DEFAULT_RESOLUTION, maxCells = DEFAULT_MAX_CELLS } = {}) { const bounds = model.bounds; const size = model.size; const longest = Math.max(size[0], size[1], size[2], 1e-6); const targetResolution = normalizeResolution(resolution); const cellSize = longest / targetResolution; let nx = Math.max(2, Math.ceil(size[0] / cellSize)); let ny = Math.max(2, Math.ceil(size[1] / cellSize)); let nz = Math.max(2, Math.ceil(size[2] / cellSize)); const maxCellCount = Math.max(4096, Math.floor(finiteNumber4(maxCells, DEFAULT_MAX_CELLS))); const cellCount = nx * ny * nz; if (cellCount > maxCellCount) { const scale = Math.cbrt(maxCellCount / cellCount); nx = Math.max(2, Math.floor(nx * scale)); ny = Math.max(2, Math.floor(ny * scale)); nz = Math.max(2, Math.floor(nz * scale)); } return { min: bounds.min, max: bounds.max, size, nx, ny, nz, step: [ size[0] / nx, size[1] / ny, size[2] / nz ] }; } function pointAt(grid, ix, iy, iz) { return [ grid.min[0] + ix * grid.step[0], grid.min[1] + iy * grid.step[1], grid.min[2] + iz * grid.step[2] ]; } function subtract(a, b) { return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; } function cross2(a, b) { return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; } function dot2(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } function normalize2(v) { const len = Math.hypot(v[0], v[1], v[2]); return len > 1e-12 ? [v[0] / len, v[1] / len, v[2] / len] : [0, 0, 1]; } function midpoint(a, b, c) { return [ (a[0] + b[0] + c[0]) / 3, (a[1] + b[1] + c[1]) / 3, (a[2] + b[2] + c[2]) / 3 ]; } function estimateGradient(sdf, point, epsilon) { const [x, y, z] = point; return normalize2([ sdf(x + epsilon, y, z) - sdf(x - epsilon, y, z), sdf(x, y + epsilon, z) - sdf(x, y - epsilon, z), sdf(x, y, z + epsilon) - sdf(x, y, z - epsilon) ]); } function offsetPoint(point, direction, distance) { return [ point[0] + direction[0] * distance, point[1] + direction[1] * distance, point[2] + direction[2] * distance ]; } function normalFacesOutward(sdf, point, normal, epsilon) { const positive = finiteNumber4(sdf(...offsetPoint(point, normal, epsilon)), 1e6); const negative = finiteNumber4(sdf(...offsetPoint(point, normal, -epsilon)), 1e6); return positive >= negative; } function smoothNormalForVertex(sdf, vertex, epsilon, normalCache) { const key = `${vertex[0].toPrecision(12)},${vertex[1].toPrecision(12)},${vertex[2].toPrecision(12)}`; let normal = normalCache.get(key); if (!normal) { normal = estimateGradient(sdf, vertex, epsilon); normalCache.set(key, normal); } return normal; } function interpolateVertex(a, b, iso = 0) { const denominator = b.value - a.value; const t = Math.abs(denominator) < 1e-12 ? 0.5 : clamp4((iso - a.value) / denominator, 0, 1); return [ a.position[0] + (b.position[0] - a.position[0]) * t, a.position[1] + (b.position[1] - a.position[1]) * t, a.position[2] + (b.position[2] - a.position[2]) * t ]; } function pushTriangle(mesh, sdf, normalEpsilon, a, b, c, { normalCache = null, orientByGradient = false, orientBySdf = true, orientationEpsilon = normalEpsilon, smoothNormals = false } = {}) { let v0 = a; let v1 = b; let v2 = c; let normal = normalize2(cross2(subtract(v1, v0), subtract(v2, v0))); const triangleMidpoint = midpoint(v0, v1, v2); const gradient = orientByGradient ? estimateGradient(sdf, triangleMidpoint, normalEpsilon) : null; const facesOutward = gradient ? dot2(normal, gradient) >= 0 : !orientBySdf || normalFacesOutward(sdf, triangleMidpoint, normal, orientationEpsilon); if (!facesOutward) { v1 = c; v2 = b; normal = [-normal[0], -normal[1], -normal[2]]; } for (const vertex of [v0, v1, v2]) { const vertexNormal = smoothNormals && normalCache ? smoothNormalForVertex(sdf, vertex, normalEpsilon, normalCache) : normal; const alignedNormal = dot2(vertexNormal, normal) < 0 ? [-vertexNormal[0], -vertexNormal[1], -vertexNormal[2]] : vertexNormal; mesh.positions.push(vertex[0], vertex[1], vertex[2]); mesh.normals.push(alignedNormal[0], alignedNormal[1], alignedNormal[2]); } } function polygonizeTetra(mesh, sdf, normalEpsilon, corners, iso = 0, options = {}) { const inside = []; const outside = []; for (const corner of corners) { if (corner.value <= iso) { inside.push(corner); } else { outside.push(corner); } } if (inside.length === 0 || inside.length === 4) { return; } const edge = (a2, b2) => interpolateVertex(a2, b2, iso); if (inside.length === 1) { pushTriangle(mesh, sdf, normalEpsilon, edge(inside[0], outside[0]), edge(inside[0], outside[1]), edge(inside[0], outside[2]), options); return; } if (inside.length === 3) { pushTriangle(mesh, sdf, normalEpsilon, edge(outside[0], inside[0]), edge(outside[0], inside[2]), edge(outside[0], inside[1]), options); return; } const a = edge(inside[0], outside[0]); const b = edge(inside[1], outside[0]); const c = edge(inside[1], outside[1]); const d = edge(inside[0], outside[1]); pushTriangle(mesh, sdf, normalEpsilon, a, b, c, options); pushTriangle(mesh, sdf, normalEpsilon, a, c, d, options); } function sampledValueIndex(grid, ix, iy, iz) { return ix + (grid.nx + 1) * (iy + (grid.ny + 1) * iz); } function meshImplicitCadModel(modelValue, options = {}) { const model = normalizeImplicitCadModel(modelValue); const sdf = typeof options.sdf === "function" ? options.sdf : createImplicitCadSdfEvaluator(model); const grid = normalizedGrid(model, options); const valueCount = (grid.nx + 1) * (grid.ny + 1) * (grid.nz + 1); const values = new Float32Array(valueCount); for (let iz = 0; iz <= grid.nz; iz += 1) { for (let iy = 0; iy <= grid.ny; iy += 1) { for (let ix = 0; ix <= grid.nx; ix += 1) { const p = pointAt(grid, ix, iy, iz); values[sampledValueIndex(grid, ix, iy, iz)] = finiteNumber4(sdf(p[0], p[1], p[2]), 1e6); } } } const mesh = { positions: [], normals: [], format: "triangle-list", sourceModel: model, grid: { resolution: [grid.nx, grid.ny, grid.nz], step: grid.step } }; const normalEpsilon = Math.max(finiteNumber4(options.normalEpsilon, model.normalEpsilon), 1e-5); const orientationEpsilon = Math.max(Math.min(...grid.step) * 0.15, 1e-5); const normalCache = options.smoothNormals === true ? /* @__PURE__ */ new Map() : null; for (let iz = 0; iz < grid.nz; iz += 1) { for (let iy = 0; iy < grid.ny; iy += 1) { for (let ix = 0; ix < grid.nx; ix += 1) { const corners = CUBE_OFFSETS.map(([dx, dy, dz]) => { const cx = ix + dx; const cy = iy + dy; const cz = iz + dz; return { position: pointAt(grid, cx, cy, cz), value: values[sampledValueIndex(grid, cx, cy, cz)] }; }); for (const tetra of TETRAHEDRA) { polygonizeTetra(mesh, sdf, normalEpsilon, tetra.map((index) => corners[index]), 0, { normalCache, orientByGradient: options.orientByGradient === true, orientBySdf: options.orientBySdf !== false, orientationEpsilon, smoothNormals: options.smoothNormals === true }); } } } } return { ...mesh, positions: new Float32Array(mesh.positions), normals: new Float32Array(mesh.normals), vertexCount: mesh.positions.length / 3, triangleCount: mesh.positions.length / 9 }; } // viewer/packages/implicitjs/src/lib/implicitCad/exporters.js var NativeBuffer = globalThis.Buffer; var textEncoder = typeof TextEncoder !== "undefined" ? new TextEncoder() : null; function finiteNumber5(value, fallback = 0) { const numeric = Number(value); return Number.isFinite(numeric) ? numeric : fallback; } function clamp01(value) { return Math.min(Math.max(finiteNumber5(value), 0), 1); } function bytesFromString(value, encoding = "utf-8") { if (NativeBuffer?.from) { return NativeBuffer.from(String(value), encoding); } if (encoding !== "utf-8" && encoding !== "utf8") { const text = String(value); const bytes2 = new Uint8Array(text.length); for (let index = 0; index < text.length; index += 1) { bytes2[index] = text.charCodeAt(index) & 255; } return bytes2; } return textEncoder.encode(String(value)); } function allocBytes(length2, fill = 0) { if (NativeBuffer?.alloc) { return NativeBuffer.alloc(length2, fill); } const bytes2 = new Uint8Array(length2); if (fill) { bytes2.fill(fill); } return bytes2; } function concatBytes(parts, totalLength = void 0) { if (NativeBuffer?.concat) { return NativeBuffer.concat(parts, totalLength); } const length2 = totalLength ?? parts.reduce((sum, part) => sum + part.length, 0); const bytes2 = new Uint8Array(length2); let offset = 0; for (const part of parts) { bytes2.set(part, offset); offset += part.length; } return bytes2; } function typedArrayBytes(array) { return new Uint8Array(array.buffer, array.byteOffset, array.byteLength); } function viewFor(bytes2) { return new DataView(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength); } function writeUInt16LE(bytes2, offset, value) { viewFor(bytes2).setUint16(offset, value, true); } function writeUInt32LE(bytes2, offset, value) { viewFor(bytes2).setUint32(offset, value, true); } function writeFloatLE(bytes2, offset, value) { viewFor(bytes2).setFloat32(offset, value, true); } function writeAscii(bytes2, offset, text, maxLength) { const source = String(text).slice(0, maxLength); for (let index = 0; index < source.length; index += 1) { bytes2[offset + index] = source.charCodeAt(index) & 127; } } function align4Buffer(buffer, fill = 32) { const padding = (4 - buffer.length % 4) % 4; return padding ? concatBytes([buffer, allocBytes(padding, fill)]) : buffer; } function hexToRgb012(hex, fallback = "#d4d4d8") { const raw = String(hex || fallback).trim(); const value = /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(raw) ? raw : fallback; const expanded = value.length === 4 ? `${value[1]}${value[1]}${value[2]}${value[2]}${value[3]}${value[3]}` : value.slice(1); return [ parseInt(expanded.slice(0, 2), 16) / 255, parseInt(expanded.slice(2, 4), 16) / 255, parseInt(expanded.slice(4, 6), 16) / 255 ]; } function hexTo3mfDisplayColor(hex, fallback = "#d4d4d8") { const toChannel = (component) => Math.round(clamp01(component) * 255).toString(16).padStart(2, "0").toUpperCase(); const rgb = hexToRgb012(hex, fallback); return `#${toChannel(rgb[0])}${toChannel(rgb[1])}${toChannel(rgb[2])}FF`; } function triangleNormal(positions, offset) { const ax = positions[offset]; const ay = positions[offset + 1]; const az = positions[offset + 2]; const bx = positions[offset + 3]; const by = positions[offset + 4]; const bz = positions[offset + 5]; const cx = positions[offset + 6]; const cy = positions[offset + 7]; const cz = positions[offset + 8]; const ux = bx - ax; const uy = by - ay; const uz = bz - az; const vx = cx - ax; const vy = cy - ay; const vz = cz - az; const nx = uy * vz - uz * vy; const ny = uz * vx - ux * vz; const nz = ux * vy - uy * vx; const length2 = Math.hypot(nx, ny, nz); return length2 > 1e-12 ? [nx / length2, ny / length2, nz / length2] : [0, 0, 1]; } function sanitizeName(value, fallback = "implicit-cad") { return String(value || fallback).trim().replace(/[\x00-\x1f<>:"/\\|?*]+/g, "-") || fallback; } function boundsForPositions(positions) { const min = [Infinity, Infinity, Infinity]; const max = [-Infinity, -Infinity, -Infinity]; for (let index = 0; index < positions.length; index += 3) { min[0] = Math.min(min[0], positions[index]); min[1] = Math.min(min[1], positions[index + 1]); min[2] = Math.min(min[2], positions[index + 2]); max[0] = Math.max(max[0], positions[index]); max[1] = Math.max(max[1], positions[index + 1]); max[2] = Math.max(max[2], positions[index + 2]); } return { min: min.map((value) => Number.isFinite(value) ? value : 0), max: max.map((value) => Number.isFinite(value) ? value : 0) }; } function buildGlb(gltf, binaryParts) { const binaryChunk = align4Buffer(concatBytes(binaryParts), 0); gltf.buffers = [{ byteLength: binaryChunk.length }]; const jsonChunk = align4Buffer(bytesFromString(JSON.stringify(gltf)), 32); const totalLength = 12 + 8 + jsonChunk.length + 8 + binaryChunk.length; const header = allocBytes(12); writeUInt32LE(header, 0, 1179937895); writeUInt32LE(header, 4, 2); writeUInt32LE(header, 8, totalLength); const jsonHeader = allocBytes(8); writeUInt32LE(jsonHeader, 0, jsonChunk.length); writeUInt32LE(jsonHeader, 4, 1313821514); const binHeader = allocBytes(8); writeUInt32LE(binHeader, 0, binaryChunk.length); writeUInt32LE(binHeader, 4, 5130562); return concatBytes([header, jsonHeader, jsonChunk, binHeader, binaryChunk], totalLength); } function meshToBinaryStl(mesh, { name = "implicit-cad" } = {}) { const positions = mesh.positions || new Float32Array(); const triangleCount = Math.floor(positions.length / 9); const buffer = allocBytes(84 + triangleCount * 50); writeAscii(buffer, 0, `implicit-cad ${sanitizeName(name)}`, 80); writeUInt32LE(buffer, 80, triangleCount); let offset = 84; for (let triangle = 0; triangle < triangleCount; triangle += 1) { const positionOffset = triangle * 9; const normal = triangleNormal(positions, positionOffset); for (const component of normal) { writeFloatLE(buffer, offset, component); offset += 4; } for (let vertex = 0; vertex < 9; vertex += 1) { writeFloatLE(buffer, offset, positions[positionOffset + vertex]); offset += 4; } writeUInt16LE(buffer, offset, 0); offset += 2; } return buffer; } function meshToGlb(mesh, { name = "Implicit CAD", color = "#d4d4d8" } = {}) { const positions = mesh.positions || new Float32Array(); const normals = mesh.normals && mesh.normals.length === positions.length ? mesh.normals : new Float32Array(positions.length); const vertexCount = Math.floor(positions.length / 3); const positionBuffer = typedArrayBytes(positions); const normalBuffer = typedArrayBytes(normals); const positionBounds = boundsForPositions(positions); const baseColor = hexToRgb012(color); const gltf = { asset: { version: "2.0", generator: "implicitjs exporter" }, scene: 0, scenes: [{ nodes: [0] }], nodes: [{ mesh: 0, name: sanitizeName(name, "Implicit CAD"), extras: { cadOccurrenceId: "implicit-cad:0", cadSourceKind: "implicit-cad", cadUnits: "mm" } }], meshes: [{ primitives: [{ attributes: { POSITION: 0, NORMAL: 1 }, material: 0, mode: 4 }] }], materials: [{ name: "Implicit material", doubleSided: true, extras: { cadSourceColor: true }, pbrMetallicRoughness: { baseColorFactor: [...baseColor.map(clamp01), 1], roughnessFactor: 0.72, metallicFactor: 0.02 } }], bufferViews: [ { buffer: 0, byteOffset: 0, byteLength: positionBuffer.length, target: 34962 }, { buffer: 0, byteOffset: positionBuffer.length, byteLength: normalBuffer.length, target: 34962 } ], accessors: [ { bufferView: 0, byteOffset: 0, componentType: 5126, count: vertexCount, type: "VEC3", min: positionBounds.min, max: positionBounds.max }, { bufferView: 1, byteOffset: 0, componentType: 5126, count: vertexCount, type: "VEC3" } ] }; return buildGlb(gltf, [positionBuffer, normalBuffer]); } function meshToAnimatedGlb(mesh, { name = "Implicit CAD", color = "#d4d4d8", duration = 4, times = [], targetPositions = [] } = {}) { const positions = mesh.positions || new Float32Array(); const normals = mesh.normals && mesh.normals.length === positions.length ? mesh.normals : new Float32Array(positions.length); const vertexCount = Math.floor(positions.length / 3); const positionBuffer = typedArrayBytes(positions); const normalBuffer = typedArrayBytes(normals); const positionBounds = boundsForPositions(positions); const cleanTargets = targetPositions.filter((target) => target && target.length === positions.length).map((target) => { const delta = new Float32Array(positions.length); for (let index = 0; index < positions.length; index += 1) { delta[index] = finiteNumber5(target[index], positions[index]) - positions[index]; } return delta; }); if (!cleanTargets.length) { throw new Error("Animated GLB export needs at least one compatible animation frame."); } const keyTimes = Array.isArray(times) && times.length >= 2 ? times.map((value) => Math.max(finiteNumber5(value, 0), 0)) : [0, Math.max(finiteNumber5(duration, 4), 1e-3)]; const targetCount = cleanTargets.length; const weightValues = new Float32Array(keyTimes.length * targetCount); for (let key = 0; key < keyTimes.length; key += 1) { const targetIndex = key - 1; if (targetIndex >= 0 && targetIndex < targetCount) { weightValues[key * targetCount + targetIndex] = 1; } } const targetBuffers = cleanTargets.map((target) => typedArrayBytes(target)); const timeValues = new Float32Array(keyTimes); const timeBuffer = typedArrayBytes(timeValues); const weightBuffer = typedArrayBytes(weightValues); const offsets = []; let byteOffset = 0; for (const part of [positionBuffer, normalBuffer, ...targetBuffers, timeBuffer, weightBuffer]) { offsets.push(byteOffset); byteOffset += part.length; } const baseColor = hexToRgb012(color); const targetAccessorStart = 2; const timeAccessor = targetAccessorStart + targetCount; const weightAccessor = timeAccessor + 1; const gltf = { asset: { version: "2.0", generator: "implicitjs animated exporter" }, scene: 0, scenes: [{ nodes: [0] }], nodes: [{ mesh: 0, name: sanitizeName(name, "Implicit CAD"), weights: Array.from({ length: targetCount }, () => 0), extras: { cadOccurrenceId: "implicit-cad:0", cadSourceKind: "implicit-cad", cadUnits: "mm", implicitjsAnimated: true } }], meshes: [{ weights: Array.from({ length: targetCount }, () => 0), primitives: [{ attributes: { POSITION: 0, NORMAL: 1 }, targets: cleanTargets.map((_, index) => ({ POSITION: targetAccessorStart + index })), material: 0, mode: 4 }] }], materials: [{ name: "Implicit material", doubleSided: true, extras: { cadSourceColor: true }, pbrMetallicRoughness: { baseColorFactor: [...baseColor.map(clamp01), 1], roughnessFactor: 0.72, metallicFactor: 0.02 } }], animations: [{ name: "Implicit parameter animation", channels: [{ sampler: 0, target: { node: 0, path: "weights" } }], samplers: [{ input: timeAccessor, output: weightAccessor, interpolation: "LINEAR" }] }], bufferViews: [ { buffer: 0, byteOffset: offsets[0], byteLength: positionBuffer.length, target: 34962 }, { buffer: 0, byteOffset: offsets[1], byteLength: normalBuffer.length, target: 34962 }, ...targetBuffers.map((target, index) => ({ buffer: 0, byteOffset: offsets[2 + index], byteLength: target.length, target: 34962 })), { buffer: 0, byteOffset: offsets[2 + targetCount], byteLength: timeBuffer.length }, { buffer: 0, byteOffset: offsets[3 + targetCount], byteLength: weightBuffer.length } ], accessors: [ { bufferView: 0, byteOffset: 0, componentType: 5126, count: vertexCount, type: "VEC3", min: positionBounds.min, max: positionBounds.max }, { bufferView: 1, byteOffset: 0, componentType: 5126, count: vertexCount, type: "VEC3" }, ...cleanTargets.map((target, index) => { const bounds = boundsForPositions(target); return { bufferView: targetAccessorStart + index, byteOffset: 0, componentType: 5126, count: vertexCount, type: "VEC3", min: bounds.min, max: bounds.max }; }), { bufferView: timeAccessor, byteOffset: 0, componentType: 5126, count: timeValues.length, type: "SCALAR", min: [Math.min(...keyTimes)], max: [Math.max(...keyTimes)] }, { bufferView: weightAccessor, byteOffset: 0, componentType: 5126, count: weightValues.length, type: "SCALAR", min: [0], max: [1] } ] }; return buildGlb(gltf, [positionBuffer, normalBuffer, ...targetBuffers, timeBuffer, weightBuffer]); } function xmlEscape(value) { return String(value ?? "").replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); } function crc32(buffer) { let table = crc32.table; if (!table) { table = new Uint32Array(256); for (let index = 0; index < 256; index += 1) { let c = index; for (let bit = 0; bit < 8; bit += 1) { c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1; } table[index] = c >>> 0; } crc32.table = table; } let crc = 4294967295; for (const byte of buffer) { crc = table[(crc ^ byte) & 255] ^ crc >>> 8; } return (crc ^ 4294967295) >>> 0; } function dosDateTime(date = /* @__PURE__ */ new Date()) { const year = Math.max(date.getFullYear(), 1980); const dosTime = date.getHours() << 11 | date.getMinutes() << 5 | Math.floor(date.getSeconds() / 2); const dosDate = year - 1980 << 9 | date.getMonth() + 1 << 5 | date.getDate(); return { dosTime, dosDate }; } function zipStore(files) { const localParts = []; const centralParts = []; let offset = 0; const { dosTime, dosDate } = dosDateTime(); for (const file of files) { const nameBuffer = bytesFromString(file.name); const body = file.body instanceof Uint8Array ? file.body : bytesFromString(String(file.body || "")); const crc = crc32(body); const local = allocBytes(30); writeUInt32LE(local, 0, 67324752); writeUInt16LE(local, 4, 20); writeUInt16LE(local, 6, 0); writeUInt16LE(local, 8, 0); writeUInt16LE(local, 10, dosTime); writeUInt16LE(local, 12, dosDate); writeUInt32LE(local, 14, crc); writeUInt32LE(local, 18, body.length); writeUInt32LE(local, 22, body.length); writeUInt16LE(local, 26, nameBuffer.length); writeUInt16LE(local, 28, 0); localParts.push(local, nameBuffer, body); const central = allocBytes(46); writeUInt32LE(central, 0, 33639248); writeUInt16LE(central, 4, 20); writeUInt16LE(central, 6, 20); writeUInt16LE(central, 8, 0); writeUInt16LE(central, 10, 0); writeUInt16LE(central, 12, dosTime); writeUInt16LE(central, 14, dosDate); writeUInt32LE(central, 16, crc); writeUInt32LE(central, 20, body.length); writeUInt32LE(central, 24, body.length); writeUInt16LE(central, 28, nameBuffer.length); writeUInt16LE(central, 30, 0); writeUInt16LE(central, 32, 0); writeUInt16LE(central, 34, 0); writeUInt16LE(central, 36, 0); writeUInt32LE(central, 38, 0); writeUInt32LE(central, 42, offset); centralParts.push(central, nameBuffer); offset += local.length + nameBuffer.length + body.length; } const centralStart = offset; const centralDirectory = concatBytes(centralParts); const end = allocBytes(22); writeUInt32LE(end, 0, 101010256); writeUInt16LE(end, 4, 0); writeUInt16LE(end, 6, 0); writeUInt16LE(end, 8, files.length); writeUInt16LE(end, 10, files.length); writeUInt32LE(end, 12, centralDirectory.length); writeUInt32LE(end, 16, centralStart); writeUInt16LE(end, 20, 0); return concatBytes([...localParts, centralDirectory, end]); } function meshTo3mf(mesh, { name = "Implicit CAD", color = "#d4d4d8" } = {}) { const positions = mesh.positions || new Float32Array(); const vertexCount = Math.floor(positions.length / 3); const triangleCount = Math.floor(positions.length / 9); const displayColor = hexTo3mfDisplayColor(color); const vertices = []; for (let index = 0; index < vertexCount; index += 1) { const offset = index * 3; vertices.push(``); } const triangles = []; for (let index = 0; index < triangleCount; index += 1) { const base = index * 3; triangles.push(``); } const modelXml = ` ${xmlEscape(name)} ${vertices.join("\n ")} ${triangles.join("\n ")} `; const contentTypes = ` `; const relationships = ` `; return zipStore([ { name: "[Content_Types].xml", body: contentTypes }, { name: "_rels/.rels", body: relationships }, { name: "3D/3dmodel.model", body: modelXml } ]); } function meshToFormat(mesh, format, options = {}) { const normalized = String(format || "").trim().toLowerCase().replace(/^\./, ""); if (normalized === "stl") { return { body: meshToBinaryStl(mesh, options), contentType: "model/stl", extension: ".stl" }; } if (normalized === "glb" || normalized === "gltf") { return { body: meshToGlb(mesh, options), contentType: "model/gltf-binary", extension: ".glb" }; } if (normalized === "3mf") { return { body: meshTo3mf(mesh, options), contentType: "model/3mf", extension: ".3mf" }; } throw new Error(`Unsupported implicit CAD export format: ${format || "(missing)"}`); } // viewer/packages/implicitjs/src/lib/implicitCad/exportModel.js var IMPLICIT_CAD_EXPORT_FORMATS = Object.freeze(["glb", "stl", "3mf"]); function isObject3(value) { return Boolean(value) && typeof value === "object" && !Array.isArray(value); } function finiteNumber6(value, fallback = 0) { const numeric = Number(value); return Number.isFinite(numeric) ? numeric : fallback; } function clamp5(value, min, max) { return Math.min(Math.max(value, min), max); } function normalizeImplicitExportFormat(value) { const normalized = String(value || "").trim().toLowerCase().replace(/^\./, ""); if (normalized === "gltf") { return "glb"; } return IMPLICIT_CAD_EXPORT_FORMATS.includes(normalized) ? normalized : ""; } function rgb01ToHex(rgb) { const channel = (value) => { const numeric = Number(value); const clamped = Math.min(Math.max(Number.isFinite(numeric) ? numeric : 0, 0), 1); return Math.round(clamped * 255).toString(16).padStart(2, "0"); }; return `#${channel(rgb?.[0])}${channel(rgb?.[1])}${channel(rgb?.[2])}`; } function sampleImplicitCadMeshColor(model, mesh, { sampleLimit = 768 } = {}) { if (!model?.colorSource) { return model?.material?.color; } try { const colorAt = createImplicitCadColorEvaluator(model); const positions = mesh.positions || new Float32Array(); const normals = mesh.normals && mesh.normals.length === positions.length ? mesh.normals : null; const vertexCount = Math.floor(positions.length / 3); const stride = Math.max(1, Math.floor(vertexCount / Math.max(sampleLimit, 1))); const sum = [0, 0, 0]; let count = 0; for (let vertex = 0; vertex < vertexCount; vertex += stride) { const offset = vertex * 3; const color = colorAt( [positions[offset], positions[offset + 1], positions[offset + 2]], normals ? [normals[offset], normals[offset + 1], normals[offset + 2]] : [0, 0, 1] ); if (!color.every((component) => Number.isFinite(component))) { continue; } sum[0] += color[0]; sum[1] += color[1]; sum[2] += color[2]; count += 1; } return count ? rgb01ToHex(sum.map((component) => component / count)) : model?.material?.color; } catch { return model?.material?.color; } } function estimateGradient2(sdf, point, epsilon) { const [x, y, z] = point; const gradient = [ finiteNumber6(sdf(x + epsilon, y, z), 0) - finiteNumber6(sdf(x - epsilon, y, z), 0), finiteNumber6(sdf(x, y + epsilon, z), 0) - finiteNumber6(sdf(x, y - epsilon, z), 0), finiteNumber6(sdf(x, y, z + epsilon), 0) - finiteNumber6(sdf(x, y, z - epsilon), 0) ]; const length2 = Math.hypot(gradient[0], gradient[1], gradient[2]); return length2 > 1e-9 ? [gradient[0] / length2, gradient[1] / length2, gradient[2] / length2] : [0, 0, 1]; } function projectMeshPositionsToModel(basePositions, targetModel, { iterations = 8, maxStep = null } = {}) { const sdf = createImplicitCadSdfEvaluator(targetModel); const targetPositions = new Float32Array(basePositions.length); const epsilon = Math.max(finiteNumber6(targetModel.normalEpsilon, targetModel.radius * 1e-3), 1e-4); const stepLimit = Math.max( finiteNumber6(maxStep, finiteNumber6(targetModel.maxStep, targetModel.radius * 0.08)), epsilon ); for (let index = 0; index < basePositions.length; index += 3) { const point = [ basePositions[index], basePositions[index + 1], basePositions[index + 2] ]; for (let pass = 0; pass < iterations; pass += 1) { const distance = finiteNumber6(sdf(point[0], point[1], point[2]), 0); if (Math.abs(distance) <= epsilon * 0.35) { break; } const normal = estimateGradient2(sdf, point, epsilon); const step = clamp5(distance, -stepLimit, stepLimit); point[0] -= normal[0] * step; point[1] -= normal[1] * step; point[2] -= normal[2] * step; } targetPositions[index] = point[0]; targetPositions[index + 1] = point[1]; targetPositions[index + 2] = point[2]; } return targetPositions; } function definitionFromModel(modelValue) { if (modelValue?.definition?.buildModel) { return modelValue.definition; } if (modelValue?.buildModel) { return modelValue; } return normalizeImplicitCadModel(modelValue).definition; } function runtimeModelForExport(modelValue, { params = null, parameterValues = null, animationState = null } = {}) { const model = normalizeImplicitCadModel(modelValue); const nextParams = isObject3(params) ? params : isObject3(parameterValues) ? parameterValues : null; if (!nextParams && !animationState) { return model; } return typeof model.definition?.buildModel === "function" ? model.definition.buildModel( nextParams || model.parameterValues || model.defaultParameterValues || {}, isObject3(animationState) ? animationState : model.animationState || {} ) : model; } function exportImplicitCadModel(modelValue, { format = "glb", params = null, parameterValues = null, animationState = null, resolution = 96, maxCells = void 0, normalEpsilon = void 0, smoothNormals = void 0 } = {}) { const model = runtimeModelForExport(modelValue, { params, parameterValues, animationState }); const outputFormat = normalizeImplicitExportFormat(format); const mesh = meshImplicitCadModel(model, { resolution, maxCells, normalEpsilon, smoothNormals: smoothNormals ?? outputFormat === "glb" }); if (!mesh.triangleCount) { throw new Error("Implicit CAD export produced an empty mesh. Check bounds, parameters, and resolution."); } const exported = meshToFormat(mesh, format, { name: model.name, color: sampleImplicitCadMeshColor(model, mesh) }); return { ...exported, mesh, model, format: outputFormat }; } function exportImplicitCadAnimatedGlb(modelOrDefinition, { animationId = "", params = null, parameterValues = null, duration = void 0, frames = 18, resolution = 64, maxCells = void 0, normalEpsilon = void 0, smoothNormals = true, projectionIterations = 8 } = {}) { const definition = definitionFromModel(modelOrDefinition); const animation = findImplicitAnimation(definition, animationId); if (!animation) { throw new Error("Animated GLB export requires an animation on the implicit model."); } const baseValues = isObject3(params) ? params : isObject3(parameterValues) ? parameterValues : modelOrDefinition?.parameterValues || definition.defaultParameterValues || {}; const durationSeconds = Math.max(finiteNumber6(duration, animation.duration), 1e-3); const frameCount = Math.max(3, Math.min(Math.floor(finiteNumber6(frames, 18)), 48)); const baseModel = buildImplicitAnimatedModel(definition, { animationId: animation.id, params: baseValues, elapsedSec: 0, playing: false }); const baseMesh = meshImplicitCadModel(baseModel, { resolution, maxCells, normalEpsilon, smoothNormals }); if (!baseMesh.triangleCount) { throw new Error("Animated GLB export produced an empty base mesh. Check bounds, parameters, and resolution."); } const targetPositions = []; const times = []; for (let frame = 0; frame < frameCount; frame += 1) { const elapsedSec = durationSeconds * frame / (frameCount - 1); times.push(elapsedSec); if (frame === 0 || animation.loop !== false && frame === frameCount - 1) { continue; } const frameModel = buildImplicitAnimatedModel(definition, { animationId: animation.id, params: baseValues, elapsedSec, playing: false }); targetPositions.push(projectMeshPositionsToModel(baseMesh.positions, frameModel, { iterations: projectionIterations })); } const body = meshToAnimatedGlb(baseMesh, { name: baseModel.name, color: sampleImplicitCadMeshColor(baseModel, baseMesh), duration: durationSeconds, times, targetPositions }); return { body, contentType: "model/gltf-binary", extension: ".glb", format: "glb", mesh: baseMesh, model: baseModel, animation, frameCount, duration: durationSeconds }; } // viewer/packages/implicitjs/src/lib/implicitCad/export.js function isObject4(value) { return Boolean(value) && typeof value === "object" && !Array.isArray(value); } function normalizeFormat(value) { return normalizeImplicitExportFormat(value); } function formatFromOutputPath(outputPath) { return normalizeFormat(path7.extname(String(outputPath || "")).slice(1)); } function defaultImplicitCadExportPath(inputPath, format = "glb") { const normalizedFormat = normalizeFormat(format) || "glb"; const raw = String(inputPath || "").trim(); const basename = raw.replace(/\.implicit\.(?:mjs|js)$/i, "").replace(/\.(?:mjs|js)$/i, ""); return `${basename}.${normalizedFormat}`; } async function loadImplicitCadModelFromPath(inputPath, { params = null, parameterValues = null, animationState = null } = {}) { const resolvedInput = path7.resolve(String(inputPath || "")); const stats = await fs6.stat(resolvedInput); if (!stats.isFile()) { throw new Error(`Implicit CAD input is not a file: ${resolvedInput}`); } const inputUrl = pathToFileURL(resolvedInput); inputUrl.searchParams.set("mtime", String(Number(stats.mtimeMs))); const moduleValue = await import(inputUrl.href); const defaultModel = normalizeImplicitCadModel(moduleValue, { sourceUrl: inputUrl.href }); const nextParams = isObject4(params) ? params : isObject4(parameterValues) ? parameterValues : null; if (nextParams || animationState) { return defaultModel.definition.buildModel( nextParams || defaultModel.defaultParameterValues, isObject4(animationState) ? animationState : defaultModel.animationState ); } return defaultModel; } async function exportImplicitCadFile({ input, output = "", format = "", params = null, parameterValues = null, animationState = null, animated = false, frames = void 0, duration = void 0, resolution = 96, maxCells = void 0, normalEpsilon = void 0, smoothNormals = void 0 } = {}) { const inputPath = path7.resolve(String(input || "")); const outputFormat = animated ? "glb" : normalizeFormat(format) || formatFromOutputPath(output) || "glb"; const outputPath = path7.resolve(output || defaultImplicitCadExportPath(inputPath, outputFormat)); const model = await loadImplicitCadModelFromPath(inputPath, { params, parameterValues, animationState }); const result = animated ? exportImplicitCadAnimatedGlb(model, { animationId: animationState?.activeId, params: model.parameterValues, duration, frames, resolution, maxCells, normalEpsilon, smoothNormals }) : exportImplicitCadModel(model, { format: outputFormat, resolution, maxCells, normalEpsilon, smoothNormals }); await fs6.mkdir(path7.dirname(outputPath), { recursive: true }); await fs6.writeFile(outputPath, result.body); return { ok: true, input: inputPath, output: outputPath, format: result.format, contentType: result.contentType, bytes: result.body.length, triangleCount: result.mesh.triangleCount, vertexCount: result.mesh.vertexCount, grid: result.mesh.grid, model: { name: result.model.name, bounds: result.model.bounds, units: result.model.units } }; } // viewer/src/server/localAssetBackend.mjs function toPosixPath2(value) { return String(value || "").split(path8.sep).join("/"); } function absoluteFileRef(filePath) { return toPosixPath2(path8.resolve(filePath)); } function relativeFileRef(rootPath, filePath) { return toPosixPath2(path8.relative(path8.resolve(rootPath), path8.resolve(filePath))); } function pathIsInsideOrEqual(childPath, parentPath) { const relativePath = path8.relative(path8.resolve(parentPath), path8.resolve(childPath)); return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${path8.sep}`) && !path8.isAbsolute(relativePath); } function normalizedFileRef(value) { const raw = String(value || "").trim().replace(/\\/g, "/"); if (!raw) { return ""; } if (raw.includes("\0")) { throw new Error("File path contains an invalid null byte"); } return path8.isAbsolute(raw) ? absoluteFileRef(raw) : raw.replace(/^\/+/, ""); } function normalizedRootDir(value, baseRoot) { const raw = String(value || "").trim(); if (!raw) { return ""; } if (raw.includes("\0")) { throw new Error("CAD Viewer directory contains an invalid null byte"); } return path8.isAbsolute(raw) ? path8.resolve(raw) : path8.resolve(baseRoot, raw); } function requireDirectory(rootPath) { let stats = null; try { stats = fs7.statSync(rootPath); } catch { throw new Error(`CAD Viewer directory not found: ${rootPath}`); } if (!stats.isDirectory()) { throw new Error(`CAD Viewer directory is not a directory: ${rootPath}`); } } function catalogEntryForFileRef(catalog, fileRef) { const normalized = normalizedFileRef(fileRef); if (!normalized || !Array.isArray(catalog?.entries)) { return null; } return catalog.entries.find((entry) => normalizedFileRef(entry?.file) === normalized || normalizedFileRef(entry?.rootRelativeFile) === normalized) || null; } function ensurePathInsideRoot(filePath, resolvedRoot) { if (!(filePath === resolvedRoot.rootPath || pathIsInside(filePath, resolvedRoot.rootPath))) { throw new Error("Requested file is outside the active CAD Viewer root"); } } function normalizedFileAssetKind(value) { const asset = String(value || "output").trim().toLowerCase(); if (asset === "asset") { return "artifact"; } if (asset === "output" || asset === "source" || asset === "artifact") { return asset; } throw new Error(`Unsupported file asset: ${asset || "(missing)"}`); } function normalizedImplicitExportFormat(value) { const format = String(value || "").trim().toLowerCase().replace(/^\./, ""); if (IMPLICIT_CAD_EXPORT_FORMATS.includes(format)) { return format; } throw new Error(`Unsupported implicit CAD export format: ${format || "(missing)"}`); } function fileHasGenStep2(filePath) { try { return /\bgen_step\s*\(/.test(fs7.readFileSync(filePath, "utf-8")); } catch { return false; } } function sameStemPythonGeneratorPath2(stepPath) { const extension = path8.extname(stepPath).toLowerCase(); if (extension !== ".step" && extension !== ".stp") { return ""; } const candidate = path8.join(path8.dirname(stepPath), `${path8.basename(stepPath, extension)}.py`); return fileHasGenStep2(candidate) ? candidate : ""; } function stepArtifactGenerationError(result) { const directError = String(result?.error || "").trim(); if (directError) { return directError; } const validationError = result?.validation?.error; const validationMessage = String(validationError?.message || "").trim(); if (validationMessage) { return validationMessage; } const reason = String(result?.reason || "").trim(); if (reason) { return `STEP artifact was not generated: ${reason}`; } return "STEP artifact generation failed."; } function contentTypeForPath(filePath) { const extension = path8.extname(filePath).toLowerCase(); if (extension === ".js" || extension === ".mjs") { return "text/javascript; charset=utf-8"; } if (extension === ".json") { return "application/json; charset=utf-8"; } if (extension === ".wasm") { return "application/wasm"; } if (extension === ".glb") { return "model/gltf-binary"; } if (extension === ".stl") { return "model/stl"; } if (extension === ".3mf") { return "model/3mf"; } if (extension === ".step" || extension === ".stp") { return "application/step"; } if (extension === ".dxf") { return "application/dxf"; } if (extension === ".gcode" || extension === ".py") { return "text/plain; charset=utf-8"; } if (extension === ".urdf" || extension === ".srdf" || extension === ".sdf") { return "application/xml; charset=utf-8"; } if (extension === ".svg") { return "image/svg+xml"; } if (extension === ".png") { return "image/png"; } return "application/octet-stream"; } function defaultSourceFileOpener(filePath) { let command = ""; let args = []; if (process.platform === "darwin") { command = "open"; args = ["-R", filePath]; } else if (process.platform === "win32") { command = "explorer.exe"; args = [`/select,${filePath}`]; } else { command = "xdg-open"; args = [path8.dirname(filePath)]; } const child = spawn2(command, args, { detached: true, stdio: "ignore" }); child.unref(); return { command }; } function emptyCatalog() { return { schemaVersion: CAD_CATALOG_SCHEMA_VERSION, entries: [] }; } function normalizeCatalog(catalog) { return { schemaVersion: CAD_CATALOG_SCHEMA_VERSION, entries: Array.isArray(catalog?.entries) ? catalog.entries : [] }; } function queryValueFromAssetUrl(rawUrl, name) { try { return new URL(String(rawUrl || ""), "http://cad.local").searchParams.get(name) || ""; } catch { return ""; } } function assetPathFromCatalogUrl(scanRepoRoot, rawUrl) { const text = String(rawUrl || "").trim(); if (!text) { return ""; } try { const url = new URL(text, "http://cad.local"); const explicitFile = url.searchParams.get("file"); if (explicitFile) { return path8.resolve(explicitFile); } return path8.resolve(scanRepoRoot, decodeURIComponent(url.pathname).replace(/^\/+/, "")); } catch { return path8.resolve(scanRepoRoot, text.replace(/[?#].*$/, "").replace(/^\/+/, "")); } } function localAssetUrlForPath(filePath, rawUrl = "", { rootDir = "" } = {}) { const url = new URL("/__cad/asset", "http://cad.local"); url.searchParams.set("file", absoluteFileRef(filePath)); const normalizedRootDir2 = String(rootDir || "").trim(); if (normalizedRootDir2) { url.searchParams.set("dir", normalizedRootDir2); } const version = queryValueFromAssetUrl(rawUrl, "v"); if (version) { url.searchParams.set("v", version); } return `${url.pathname}${url.search}`; } function absolutePathFromCatalogValue(scanRepoRoot, value) { const text = String(value || "").trim(); if (!text) { return ""; } if (path8.isAbsolute(text)) { return path8.resolve(text); } return path8.resolve(scanRepoRoot, text); } function absolutizeArtifact(artifact, scanRepoRoot) { if (!artifact || typeof artifact !== "object") { return artifact; } const next = { ...artifact }; for (const key of ["stepPath", "glbPath", "sourcePath", "cadPath"]) { if (next[key]) { next[key] = absoluteFileRef(absolutePathFromCatalogValue(scanRepoRoot, next[key])); } } return next; } function absolutizeSource(source, scanRepoRoot) { if (!source || typeof source !== "object") { return source; } const next = { ...source }; for (const key of ["file", "path", "sourcePath"]) { if (next[key]) { next[key] = absoluteFileRef(absolutePathFromCatalogValue(scanRepoRoot, next[key])); } } return next; } function absolutizeSourceStatus(sourceStatus, scanRepoRoot) { if (!sourceStatus || typeof sourceStatus !== "object") { return sourceStatus; } const next = { ...sourceStatus }; for (const key of ["sourcePath", "stepPath", "glbPath"]) { if (next[key]) { next[key] = absoluteFileRef(absolutePathFromCatalogValue(scanRepoRoot, next[key])); } } return next; } function absolutizeCatalogEntry(entry, { rootPath, scanRepoRoot, rootDir = "" }) { if (!entry || typeof entry !== "object") { return entry; } const outputPath = path8.resolve(rootPath, String(entry.file || "")); const next = { ...entry, file: absoluteFileRef(outputPath), rootRelativeFile: relativeFileRef(rootPath, outputPath) }; if (entry.url) { const assetPath = assetPathFromCatalogUrl(scanRepoRoot, entry.url); next.url = localAssetUrlForPath(assetPath, entry.url, { rootDir }); next.assetFile = absoluteFileRef(assetPath); } if (entry.moduleUrl) { const modulePath = assetPathFromCatalogUrl(scanRepoRoot, entry.moduleUrl); next.moduleUrl = localAssetUrlForPath(modulePath, entry.moduleUrl, { rootDir }); next.moduleFile = absoluteFileRef(modulePath); } if (entry.source) { next.source = absolutizeSource(entry.source, scanRepoRoot); } if (entry.sourceStatus) { next.sourceStatus = absolutizeSourceStatus(entry.sourceStatus, scanRepoRoot); } if (entry.artifact) { next.artifact = absolutizeArtifact(entry.artifact, scanRepoRoot); } if (entry.relations && typeof entry.relations === "object") { next.relations = { ...entry.relations }; for (const [key, relation] of Object.entries(entry.relations)) { if (!relation || typeof relation !== "object") { continue; } const relationFilePath = path8.resolve(rootPath, String(relation.file || "")); const nextRelation = { ...relation, file: absoluteFileRef(relationFilePath), rootRelativeFile: relativeFileRef(rootPath, relationFilePath) }; if (relation.url) { const relationAssetPath = assetPathFromCatalogUrl(scanRepoRoot, relation.url); nextRelation.url = localAssetUrlForPath(relationAssetPath, relation.url, { rootDir }); nextRelation.assetFile = absoluteFileRef(relationAssetPath); } next.relations[key] = nextRelation; } } return next; } function absolutizeCatalog(catalog, context) { return normalizeCatalog({ ...catalog, entries: (Array.isArray(catalog?.entries) ? catalog.entries : []).map((entry) => absolutizeCatalogEntry(entry, context)).filter(Boolean) }); } function absolutizeGenerationStatus(status, rootPath) { const files = {}; for (const [file, value] of Object.entries(status?.files || {})) { const absolute = absoluteFileRef(path8.resolve(rootPath, String(file || ""))); files[absolute] = { ...value, file: absolute, rootRelativeFile: relativeFileRef(rootPath, absolute) }; } return { schemaVersion: 1, runs: (Array.isArray(status?.runs) ? status.runs : []).map((run) => ({ ...run, files: (Array.isArray(run?.files) ? run.files : []).map((file) => absoluteFileRef(path8.resolve(rootPath, String(file || "")))).filter(Boolean) })), files }; } function createLocalAssetBackend({ directoryRoot: directoryRoot2 = process.cwd(), rootDir = "", defaultFile = "", githubUrl = "", stepArtifactGenerator = ensureStepTopologyArtifact, sourceFileOpener = defaultSourceFileOpener } = {}) { const baseDirectoryRoot = path8.resolve(directoryRoot2 || process.cwd()); const defaultRootDir = rootDir ? absoluteFileRef(normalizedRootDir(rootDir, baseDirectoryRoot)) : absoluteFileRef(baseDirectoryRoot); const catalogCache = /* @__PURE__ */ new Map(); function effectiveRootDirForRequest(rootDir2 = "") { return rootDir2 || defaultRootDir; } function resolveRoot(rootDir2 = defaultRootDir) { const rootPath = normalizedRootDir(rootDir2 || defaultRootDir, baseDirectoryRoot); if (!rootPath) { throw new Error("CAD Viewer local filesystem requests must include a ?dir= path"); } requireDirectory(rootPath); return { dir: absoluteFileRef(rootPath), rootPath, rootName: path8.basename(rootPath) }; } function resolveRequestRoot({ rootDir: rootDir2 = defaultRootDir } = {}) { return resolveRoot(effectiveRootDirForRequest(rootDir2)); } function scanContextForRoot(resolvedRoot) { const rootPath = path8.resolve(resolvedRoot.rootPath); const scanRepoRoot = pathIsInsideOrEqual(rootPath, baseDirectoryRoot) ? baseDirectoryRoot : rootPath; const scanRootDir = scanRepoRoot === rootPath ? "" : toPosixPath2(path8.relative(scanRepoRoot, rootPath)); return { rootDir: resolvedRoot.dir, rootPath, scanRepoRoot, scanRootDir }; } function readCatalog({ rootDir: nextRootDir = defaultRootDir, fileRef = "" } = {}) { const effectiveRootDir = effectiveRootDirForRequest(nextRootDir); const normalizedDir = absoluteFileRef(normalizedRootDir(effectiveRootDir, baseDirectoryRoot)); const normalizedFile = normalizedFileRef(fileRef); const cacheKey = `dir:${normalizedDir}`; if (!catalogCache.has(cacheKey)) { return refreshCatalog({ rootDir: normalizedDir, fileRef: normalizedFile }); } if (normalizedDir && normalizedFile) { const resolvedRoot = resolveRoot(normalizedDir); const requestedPath = filePathFromRef(normalizedFile, resolvedRoot); if (requestedPath === resolvedRoot.rootPath || pathIsInside(requestedPath, resolvedRoot.rootPath)) { return refreshCatalogForPath({ rootDir: resolvedRoot.dir, filePath: requestedPath }); } } return catalogCache.get(cacheKey); } function readCatalogSafe({ rootDir: nextRootDir = defaultRootDir, fileRef = "" } = {}) { try { return readCatalog({ rootDir: nextRootDir, fileRef }); } catch { return emptyCatalog(); } } function refreshCatalog({ rootDir: nextRootDir = defaultRootDir, fileRef = "" } = {}) { const effectiveRootDir = effectiveRootDirForRequest(nextRootDir); const resolvedRoot = resolveRoot(effectiveRootDir); const context = scanContextForRoot(resolvedRoot); const rawCatalog = scanCadDirectory({ repoRoot: context.scanRepoRoot, rootDir: context.scanRootDir, includeArtifactStatus: false }); const catalog = absolutizeCatalog(rawCatalog, context); catalogCache.set(`dir:${resolvedRoot.dir}`, catalog); return catalog; } function replaceCatalogEntry(catalog, fileRef, nextEntry) { const normalizedRef = normalizedFileRef(fileRef); if (!normalizedRef) { return normalizeCatalog(catalog); } const previousEntries = Array.isArray(catalog?.entries) ? catalog.entries : []; const entries = previousEntries.filter((entry) => normalizedFileRef(entry?.file) !== normalizedRef); if (nextEntry) { entries.push(nextEntry); } return normalizeCatalog({ ...catalog, entries: sortCatalogEntries(entries) }); } function refreshCatalogEntryForFile({ rootDir: nextRootDir = defaultRootDir, filePath } = {}) { const resolvedRoot = resolveRoot(nextRootDir); const context = scanContextForRoot(resolvedRoot); const currentCatalog = readCatalog({ rootDir: resolvedRoot.dir }); const rawEntry = scanCadFile({ repoRoot: context.scanRepoRoot, rootDir: context.scanRootDir, filePath, includeArtifactStatus: false }); const nextEntry = rawEntry ? absolutizeCatalogEntry(rawEntry, context) : null; const rawFileRef = rawEntry?.file || catalogFileRefForPath({ repoRoot: context.scanRepoRoot, rootDir: context.scanRootDir, filePath }); const fileRef = nextEntry?.file || (rawFileRef ? absoluteFileRef(path8.resolve(resolvedRoot.rootPath, rawFileRef)) : absoluteFileRef(filePath)); const nextCatalog = replaceCatalogEntry(currentCatalog, fileRef, nextEntry); catalogCache.set(`dir:${resolvedRoot.dir}`, nextCatalog); return nextCatalog; } function refreshCatalogForPythonSource({ rootDir: nextRootDir = defaultRootDir, filePath } = {}) { const resolvedRoot = resolveRoot(nextRootDir); const resolvedFilePath = path8.resolve(filePath); const sourcePath = absoluteFileRef(resolvedFilePath); const currentCatalog = readCatalog({ rootDir: resolvedRoot.dir }); const matchingFileRefs = new Set( currentCatalog.entries.filter((entry) => normalizedFileRef(entry?.source?.sourcePath || entry?.source?.file) === sourcePath).map((entry) => normalizedFileRef(entry.file)).filter(Boolean) ); const sameStemStepPath = path8.join(path8.dirname(resolvedFilePath), `${path8.basename(resolvedFilePath, ".py")}.step`); if (sameStemStepPath === resolvedRoot.rootPath || pathIsInside(sameStemStepPath, resolvedRoot.rootPath)) { const context2 = scanContextForRoot(resolvedRoot); const rawSameStemEntry = scanCadFile({ repoRoot: context2.scanRepoRoot, rootDir: context2.scanRootDir, filePath: sameStemStepPath, includeArtifactStatus: false }); const sameStemEntry = rawSameStemEntry ? absolutizeCatalogEntry(rawSameStemEntry, context2) : null; const sameStemFileRef = sameStemEntry?.file || absoluteFileRef(sameStemStepPath); if (sameStemEntry || catalogEntryForFileRef(currentCatalog, sameStemFileRef)) { matchingFileRefs.add(sameStemFileRef); } } if (!matchingFileRefs.size) { return refreshCatalog({ rootDir: resolvedRoot.dir }); } let nextCatalog = currentCatalog; const context = scanContextForRoot(resolvedRoot); for (const fileRef of matchingFileRefs) { const outputPath = path8.resolve(fileRef); const rawEntry = scanCadFile({ repoRoot: context.scanRepoRoot, rootDir: context.scanRootDir, filePath: outputPath, includeArtifactStatus: false }); nextCatalog = replaceCatalogEntry( nextCatalog, fileRef, rawEntry ? absolutizeCatalogEntry(rawEntry, context) : null ); } catalogCache.set(`dir:${resolvedRoot.dir}`, nextCatalog); return nextCatalog; } function refreshCatalogForPath({ rootDir: nextRootDir = defaultRootDir, filePath } = {}) { const extension = path8.extname(String(filePath || "")).toLowerCase(); if (extension === ".py") { return refreshCatalogForPythonSource({ rootDir: nextRootDir, filePath }); } return refreshCatalogEntryForFile({ rootDir: nextRootDir, filePath }); } function filePathFromRef(fileRef, resolvedRoot) { const normalized = normalizedFileRef(fileRef); if (!normalized) { return ""; } return path8.isAbsolute(normalized) ? path8.resolve(normalized) : path8.resolve(resolvedRoot.rootPath, normalized); } function resolveStepSource(fileRef, { resolvedRoot = resolveRequestRoot({ fileRef }), catalog = null } = {}) { const normalizedRef = normalizedFileRef(fileRef); if (!normalizedRef) { throw new Error("Missing STEP file"); } const candidates = path8.isAbsolute(normalizedRef) ? [ path8.resolve(normalizedRef), path8.resolve(resolvedRoot.rootPath, normalizedRef.replace(/^\/+/, "")) ] : [ path8.resolve(resolvedRoot.rootPath, normalizedRef) ]; for (const candidatePath2 of [...new Set(candidates)]) { if ((candidatePath2 === resolvedRoot.rootPath || pathIsInside(candidatePath2, resolvedRoot.rootPath)) && fs7.existsSync(candidatePath2)) { const extension = path8.extname(candidatePath2).toLowerCase(); if (extension === ".py") { if (!fileHasGenStep2(candidatePath2)) { throw new Error(`Python generator is not a gen_step() source: ${normalizedRef}`); } return { stepPath: path8.join(path8.dirname(candidatePath2), `${path8.basename(candidatePath2, extension)}.step`), sourcePath: candidatePath2, skipStepWrite: true }; } if (extension !== ".step" && extension !== ".stp") { throw new Error("Only STEP/STP sources or same-stem Python generators can generate STEP topology artifacts"); } const generatorPath = sameStemPythonGeneratorPath2(candidatePath2); return { stepPath: candidatePath2, sourcePath: generatorPath, skipStepWrite: Boolean(generatorPath) }; } } const candidatePath = candidates.find((candidate) => candidate === resolvedRoot.rootPath || pathIsInside(candidate, resolvedRoot.rootPath)); if (candidatePath) { const extension = path8.extname(candidatePath).toLowerCase(); const generatorPath = sameStemPythonGeneratorPath2(candidatePath); if ((extension === ".step" || extension === ".stp") && generatorPath) { return { stepPath: candidatePath, sourcePath: generatorPath, skipStepWrite: true }; } throw new Error(`STEP file not found: ${normalizedRef}`); } throw new Error("Requested STEP file is outside the active CAD Viewer root"); } function resolveStepSourceStatus(fileRef, { resolvedRoot = resolveRequestRoot({ fileRef }), catalog = null } = {}) { try { return resolveStepSource(fileRef, { resolvedRoot, catalog }); } catch (error) { const normalizedRef = normalizedFileRef(fileRef); if (!normalizedRef) { throw error; } const candidatePath = filePathFromRef(normalizedRef, resolvedRoot); if (!(candidatePath === resolvedRoot.rootPath || pathIsInside(candidatePath, resolvedRoot.rootPath))) { throw error; } const extension = path8.extname(candidatePath).toLowerCase(); if (extension !== ".step" && extension !== ".stp") { throw error; } const generatorPath = sameStemPythonGeneratorPath2(candidatePath); return { stepPath: candidatePath, sourcePath: generatorPath, skipStepWrite: Boolean(generatorPath) }; } } function requireCatalogEntryForFileRef(fileRef, { resolvedRoot = resolveRequestRoot({ fileRef }), rootDir: nextRootDir = defaultRootDir, catalog = null } = {}) { const normalizedRef = normalizedFileRef(fileRef); if (!normalizedRef) { throw new Error("Missing file"); } const currentCatalog = catalog || readCatalogSafe({ rootDir: nextRootDir, fileRef: normalizedRef }); const entry = catalogEntryForFileRef(currentCatalog, normalizedRef); if (!entry) { throw new Error(`CAD catalog entry not found: ${normalizedRef}`); } return { entry, relativeFileRef: normalizedRef, currentCatalog, resolvedRoot }; } function resolveOutputFilePath(fileRef, options = {}) { const { entry, relativeFileRef: relativeFileRef2, resolvedRoot } = requireCatalogEntryForFileRef(fileRef, options); const outputRef = normalizedFileRef(entry?.file || relativeFileRef2); const outputPath = filePathFromRef(outputRef, resolvedRoot); ensurePathInsideRoot(outputPath, resolvedRoot); if (!fs7.existsSync(outputPath) || !fs7.statSync(outputPath).isFile()) { throw new Error(`Output file not found: ${outputRef || relativeFileRef2}`); } return outputPath; } function artifactFileRefFromEntry2(entry) { const explicitAssetFile = normalizedFileRef(entry?.assetFile || entry?.asset?.file || entry?.artifactFile || entry?.artifact?.file); if (explicitAssetFile) { return explicitAssetFile; } const rawUrl = String(entry?.url || "").trim(); if (!rawUrl) { throw new Error("Artifact asset is not available for this file"); } const assetPath = assetPathFromCatalogUrl("/", rawUrl); return absoluteFileRef(assetPath); } function resolveImplicitCadFilePath(fileRef, options = {}) { const { entry, relativeFileRef: relativeFileRef2, resolvedRoot } = requireCatalogEntryForFileRef(fileRef, options); const outputRef = normalizedFileRef(entry?.file || relativeFileRef2); const outputPath = filePathFromRef(outputRef, resolvedRoot); ensurePathInsideRoot(outputPath, resolvedRoot); if (!pathIsImplicitCadSource2(outputPath) || String(entry?.kind || "").trim().toLowerCase() !== "implicit") { throw new Error(`File is not an implicit CAD source: ${outputRef || relativeFileRef2}`); } if (!fs7.existsSync(outputPath) || !fs7.statSync(outputPath).isFile()) { throw new Error(`Implicit CAD file not found: ${outputRef || relativeFileRef2}`); } return outputPath; } function resolveArtifactFilePath(fileRef, options = {}) { const { entry, relativeFileRef: relativeFileRef2, resolvedRoot } = requireCatalogEntryForFileRef(fileRef, options); const artifactRef = artifactFileRefFromEntry2(entry); if (!artifactRef) { throw new Error(`Artifact asset is not available for ${relativeFileRef2}`); } const artifactPath = filePathFromRef(artifactRef, resolvedRoot); ensurePathInsideRoot(artifactPath, resolvedRoot); if (!fs7.existsSync(artifactPath) || !fs7.statSync(artifactPath).isFile()) { throw new Error(`Artifact file not found: ${artifactRef}`); } return artifactPath; } function resolveSourceCodeFilePath(fileRef, options = {}) { const { entry, relativeFileRef: relativeFileRef2, currentCatalog, resolvedRoot } = requireCatalogEntryForFileRef(fileRef, options); const explicitSourceRef = normalizedFileRef(entry?.source?.file || entry?.sourceFile || ""); if (explicitSourceRef) { const sourceCandidates = [ filePathFromRef(explicitSourceRef, resolvedRoot), path8.resolve(baseDirectoryRoot, explicitSourceRef) ]; for (const sourcePath of [...new Set(sourceCandidates)]) { if ((sourcePath === resolvedRoot.rootPath || pathIsInside(sourcePath, resolvedRoot.rootPath)) && fs7.existsSync(sourcePath) && fs7.statSync(sourcePath).isFile()) { return sourcePath; } } } const extension = path8.extname(relativeFileRef2).toLowerCase(); if (extension === ".step" || extension === ".stp") { const { stepPath, sourcePath } = resolveStepSourceStatus(relativeFileRef2, { resolvedRoot, catalog: currentCatalog }); if (sourcePath && fs7.existsSync(sourcePath) && fs7.statSync(sourcePath).isFile()) { ensurePathInsideRoot(sourcePath, resolvedRoot); return sourcePath; } ensurePathInsideRoot(stepPath, resolvedRoot); } throw new Error(`Source code is not available for ${relativeFileRef2}`); } function resolveFileAssetAccess({ fileRef, asset = "output", resolvedRoot = resolveRequestRoot({ fileRef }), rootDir: nextRootDir = defaultRootDir, catalog = null } = {}) { const assetKind = normalizedFileAssetKind(asset); const filePath = assetKind === "source" ? resolveSourceCodeFilePath(fileRef, { resolvedRoot, rootDir: nextRootDir, catalog }) : assetKind === "artifact" ? resolveArtifactFilePath(fileRef, { resolvedRoot, rootDir: nextRootDir, catalog }) : resolveOutputFilePath(fileRef, { resolvedRoot, rootDir: nextRootDir, catalog }); return { asset: assetKind, file: absoluteFileRef(filePath), rootRelativeFile: relativeFileRef(resolvedRoot.rootPath, filePath), path: filePath, filename: path8.basename(filePath), contentType: contentTypeForPath(filePath) }; } async function openFileAsset(request = {}) { const access = resolveFileAssetAccess(request); await sourceFileOpener(access.path); return { asset: access.asset, file: access.file, filename: access.filename, opened: true }; } function resolveSourceFileAccess(request = {}) { return resolveFileAssetAccess({ ...request, asset: "source" }); } async function openSourceFile(request = {}) { return openFileAsset({ ...request, asset: "source" }); } async function generateStepArtifact({ fileRef, force = false, resolvedRoot = resolveRequestRoot({ fileRef }), catalog = null } = {}) { const { stepPath } = resolveStepSource(fileRef, { resolvedRoot, catalog }); const extension = path8.extname(stepPath).toLowerCase(); let hasStepFile = false; try { hasStepFile = (extension === ".step" || extension === ".stp") && fs7.statSync(stepPath).isFile(); } catch { hasStepFile = false; } if (!hasStepFile) { throw new Error("CAD Viewer only regenerates GLB artifacts for existing STEP/STP files."); } const context = scanContextForRoot(resolvedRoot); const result = await stepArtifactGenerator({ repoRoot: context.scanRepoRoot, stepPath, sourcePath: "", force, skipStepWrite: false, writeStepAfterArtifact: false }); return { ok: Boolean(result?.ok), error: result?.ok ? "" : stepArtifactGenerationError(result), result, stepPath }; } async function generateImplicitExport({ fileRef, format = "glb", parameterValues = null, animationState = null, resolution = 96, maxCells = void 0, resolvedRoot = resolveRoot(), rootDir: nextRootDir = defaultRootDir, catalog = null } = {}) { const exportFormat = normalizedImplicitExportFormat(format); const inputPath = resolveImplicitCadFilePath(fileRef, { resolvedRoot, rootDir: nextRootDir, catalog }); const inputFilename = path8.basename(inputPath); const outputFilename = inputFilename.replace(/\.implicit\.(?:mjs|js)$/i, `.${exportFormat}`).replace(/\.(?:mjs|js)$/i, `.${exportFormat}`); const outputPath = path8.join(path8.dirname(inputPath), outputFilename); ensurePathInsideRoot(outputPath, resolvedRoot); const result = await exportImplicitCadFile({ input: inputPath, output: outputPath, format: exportFormat, params: parameterValues, animationState, resolution, maxCells }); const nextCatalog = refreshCatalogForPath({ rootDir: nextRootDir, filePath: outputPath }); const outputFileRef = path8.relative(resolvedRoot.rootPath, outputPath).split(path8.sep).join("/"); return { ...result, outputFileRef, filename: path8.basename(outputPath), catalog: nextCatalog, entry: catalogEntryForFileRef(nextCatalog, outputFileRef) }; } function readStepSourceStatusForFile({ fileRef, resolvedRoot = resolveRequestRoot({ fileRef }), catalog = null } = {}) { const { stepPath, sourcePath } = resolveStepSourceStatus(fileRef, { resolvedRoot, catalog }); const context = scanContextForRoot(resolvedRoot); const status = readStepSourceStatus({ repoRoot: context.scanRepoRoot, stepPath, pythonSourcePath: sourcePath }); return absolutizeSourceStatus({ ...status, ...status?.artifact ? { artifact: absolutizeArtifact(status.artifact, context.scanRepoRoot) } : {} }, context.scanRepoRoot); } function readGeneratorStatus({ rootDir: nextRootDir = defaultRootDir } = {}) { const resolvedRoot = resolveRoot(effectiveRootDirForRequest(nextRootDir)); const context = scanContextForRoot(resolvedRoot); return absolutizeGenerationStatus(readGenerationStatus({ repoRoot: context.scanRepoRoot, rootDir: context.scanRootDir }), resolvedRoot.rootPath); } function generationStatusDir2(rootDir2 = defaultRootDir) { const resolvedRoot = resolveRoot(effectiveRootDirForRequest(rootDir2)); const context = scanContextForRoot(resolvedRoot); return generationStatusDir(context.scanRepoRoot, context.scanRootDir); } function isGenerationStatusPath(filePath, rootDir2 = defaultRootDir) { const resolvedRoot = resolveRoot(effectiveRootDirForRequest(rootDir2)); const resolvedPath = path8.resolve(filePath); const name = path8.basename(resolvedPath); return (resolvedPath === resolvedRoot.rootPath || pathIsInside(resolvedPath, resolvedRoot.rootPath)) && name.startsWith(".") && name.endsWith(".generation.lock.json"); } function entryForSourcePath(catalog, resolvedRoot, sourcePath) { const fileRef = absoluteFileRef(sourcePath); return Array.isArray(catalog?.entries) ? catalog.entries.find((entry) => normalizedFileRef(entry?.file) === fileRef) || null : null; } function assetPathForFileRef(fileRef, { resolvedRoot = null, rootDir: rootDir2 = "" } = {}) { const normalizedRef = normalizedFileRef(fileRef); if (!normalizedRef || !path8.isAbsolute(normalizedRef)) { return null; } const candidatePath = path8.resolve(normalizedRef); if (!isServedCadAsset(candidatePath)) { return null; } const activeRoot = resolvedRoot || (rootDir2 ? resolveRoot(rootDir2) : null); if (activeRoot && !(candidatePath === activeRoot.rootPath || pathIsInside(candidatePath, activeRoot.rootPath))) { const error = new Error("Forbidden"); error.statusCode = 403; throw error; } return candidatePath; } async function writeAsset({ fileRef, body, resolvedRoot = resolveRequestRoot({ fileRef }) } = {}) { const normalizedRef = normalizedFileRef(fileRef); if (!normalizedRef) { throw new Error("Missing asset path"); } const filePath = filePathFromRef(normalizedRef, resolvedRoot); if (!(filePath === resolvedRoot.rootPath || pathIsInside(filePath, resolvedRoot.rootPath))) { throw new Error("Asset writes must stay inside the active CAD Viewer root"); } if (!isServedCadAsset(filePath)) { throw new Error(`Unsupported CAD Viewer asset write: ${normalizedRef}`); } const bytes2 = Buffer.isBuffer(body) ? body : Buffer.from(body || ""); fs7.mkdirSync(path8.dirname(filePath), { recursive: true }); fs7.writeFileSync(filePath, bytes2); return { path: filePath, bytes: bytes2.length, contentType: contentTypeForPath(filePath) }; } return { kind: "local-fs", canGenerateStepArtifacts: true, repoRoot: baseDirectoryRoot, rootDir: "", defaultFile, githubUrl, resolveRoot, resolveRequestRoot, readCatalog, readCatalogSafe, refreshCatalog, refreshCatalogForPath, resolveStepSource, readStepSourceStatus: readStepSourceStatusForFile, resolveFileAssetAccess, openFileAsset, resolveSourceFileAccess, openSourceFile, readGenerationStatus: readGeneratorStatus, generationStatusDir: generationStatusDir2, isGenerationStatusPath, generateStepArtifact, generateImplicitExport, entryForSourcePath, assetPathForFileRef, writeAsset, contentTypeForPath }; } // viewer/src/server/httpHandlers.mjs import fs8 from "node:fs"; import path9 from "node:path"; var STATIC_CONTENT_TYPES = /* @__PURE__ */ new Map([ [".css", "text/css; charset=utf-8"], [".html", "text/html; charset=utf-8"], [".ico", "image/x-icon"], [".js", "text/javascript; charset=utf-8"], [".json", "application/json; charset=utf-8"], [".map", "application/json; charset=utf-8"], [".svg", "image/svg+xml"], [".wasm", "application/wasm"] ]); function contentTypeForStaticAsset(filePath) { return STATIC_CONTENT_TYPES.get(path9.extname(String(filePath || "")).toLowerCase()) || ""; } function sendJson(res, statusCode, payload, { cacheControl = "no-store" } = {}) { res.statusCode = statusCode; res.setHeader("content-type", "application/json; charset=utf-8"); res.setHeader("cache-control", cacheControl || "no-store"); res.end(JSON.stringify(payload)); } function downloadFilename(value) { const rawFilename = path9.basename(String(value || "").replace(/\\/g, "/")) || "download"; return rawFilename.replace(/[\x00-\x1f"\\]/g, "_"); } function encodeContentDispositionFilename(value) { return encodeURIComponent(value).replace(/['()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`); } function attachmentContentDisposition(filename) { const safeFilename = downloadFilename(filename); const quotedFilename = safeFilename.replace(/[^\x20-\x7e]/g, "_"); return `attachment; filename="${quotedFilename}"; filename*=UTF-8''${encodeContentDispositionFilename(safeFilename)}`; } function errorMessage(error) { return error instanceof Error ? error.message : String(error); } function requestRootDir(requestUrl) { return String(requestUrl?.searchParams?.get("dir") || "").trim(); } function requestFileRef(requestUrl) { return String(requestUrl?.searchParams?.get("file") || "").trim(); } function requestHeader(req, name) { const headers = req?.headers || {}; const value = headers[String(name || "").toLowerCase()]; return Array.isArray(value) ? value[0] : String(value || ""); } function requestRefererUrl(req) { const value = requestHeader(req, "referer") || requestHeader(req, "referrer"); if (!value) { return null; } try { return new URL(value, "http://localhost"); } catch { return null; } } function siblingFileRef(sourceFileRef, relativeFileRef2) { const source = String(sourceFileRef || "").replace(/\\/g, "/"); const relative = String(relativeFileRef2 || "").replace(/\\/g, "/").replace(/^\/+/g, ""); if (!source || !relative) { return ""; } if (path9.isAbsolute(source)) { return path9.resolve(path9.dirname(source), relative); } const sourceDir = path9.posix.dirname(source); return path9.posix.normalize(path9.posix.join(sourceDir === "." ? "" : sourceDir, relative)); } function legacyCadAssetFileRef(requestUrl, req) { if (!requestUrl.pathname.startsWith("/__cad/") || requestUrl.pathname === "/__cad/asset") { return ""; } const relativePath = decodeURIComponent(requestUrl.pathname.slice("/__cad/".length)); if (!relativePath || !path9.extname(relativePath)) { return ""; } const refererUrl = requestRefererUrl(req); return siblingFileRef(requestFileRef(refererUrl), relativePath); } function readJsonBody(req, { limitBytes = 256 * 1024 } = {}) { return new Promise((resolve, reject) => { let body = ""; req.setEncoding?.("utf8"); req.on("data", (chunk) => { body += chunk; if (Buffer.byteLength(body) > limitBytes) { reject(new Error("Request body is too large")); req.destroy?.(); } }); req.on("error", reject); req.on("end", () => { const text = body.trim(); if (!text) { resolve({}); return; } try { resolve(JSON.parse(text)); } catch { reject(new Error("Request body must be valid JSON")); } }); }); } function fileAssetRequest(backend2, requestUrl, { rootDir, catalog } = {}) { const fileRef = requestFileRef(requestUrl); const request = { fileRef, asset: requestUrl.searchParams.get("asset") || "output", rootDir, catalog }; if (typeof backend2.resolveRequestRoot === "function") { request.resolvedRoot = backend2.resolveRequestRoot({ rootDir, fileRef }); } else if (typeof backend2.resolveRoot === "function" && rootDir) { request.resolvedRoot = backend2.resolveRoot(rootDir); } return request; } function sendBufferDownload(res, { body, filename, contentType } = {}) { const bytes2 = Buffer.isBuffer(body) ? body : Buffer.from(body || ""); res.statusCode = 200; res.setHeader("content-type", contentType || "application/octet-stream"); res.setHeader("cache-control", "no-store"); res.setHeader("content-disposition", attachmentContentDisposition(filename)); res.setHeader("content-length", String(bytes2.length)); res.end(bytes2); } function serveStaticFile(filePath, req, res, next, { contentType, headers = {} } = {}) { fs8.stat(filePath, (error, stats) => { if (res.destroyed) { return; } if (error || !stats.isFile()) { next(); return; } if (contentType) { res.setHeader("content-type", contentType); } for (const [name, value] of Object.entries(headers)) { if (value !== void 0 && value !== null && value !== "") { res.setHeader(name, value); } } res.setHeader("cache-control", "no-store"); res.setHeader("content-length", String(stats.size)); const stream = fs8.createReadStream(filePath); res.on("close", () => { if (!res.writableEnded) { stream.destroy(); } }); stream.on("error", () => { if (!res.headersSent) { next(); } else { res.destroy(); } }); stream.pipe(res); }); } function createCadViewerApiMiddleware({ backend: backend2, serverInfo = () => ({}), enableStepArtifactBackend = false, claimDisabledStepArtifactRoute = false, preferFileDownloadRedirects = false, onCatalogChanged = () => { }, onCatalogActivated = () => { }, onDirectoryActivated = () => { }, rootDir, catalogCacheControl = "" } = {}) { if (!backend2) { throw new Error("createCadViewerApiMiddleware requires backend"); } return async function cadViewerApiMiddleware(req, res, next) { const requestUrl = new URL(req.url || "/", "http://localhost"); const activeRootDir = requestRootDir(requestUrl) || rootDir || ""; const activeFileRef = requestFileRef(requestUrl); if (requestUrl.pathname === "/__cad/server") { sendJson(res, 200, serverInfo({ rootDir: activeRootDir, fileRef: activeFileRef })); return; } if (requestUrl.pathname === "/__cad/directory/activate") { const method = String(req.method || "GET").toUpperCase(); if (method !== "POST") { res.setHeader("allow", "POST"); sendJson(res, 405, { error: "Use POST to activate a CAD Viewer directory" }); return; } if (typeof backend2.resolveRequestRoot !== "function" && typeof backend2.resolveRoot !== "function") { sendJson(res, 501, { error: "Directory activation requires a local filesystem CAD Viewer backend" }); return; } try { const resolvedRoot = typeof backend2.resolveRequestRoot === "function" ? backend2.resolveRequestRoot({ rootDir: activeRootDir, fileRef: activeFileRef }) : backend2.resolveRoot(activeRootDir); onDirectoryActivated(resolvedRoot, { rootDir: activeRootDir, fileRef: activeFileRef }); sendJson(res, 200, { ok: true, directory: { dir: String(resolvedRoot?.dir || activeRootDir || ""), rootPath: String(resolvedRoot?.rootPath || ""), rootName: String(resolvedRoot?.rootName || "") }, server: serverInfo({ rootDir: String(resolvedRoot?.dir || activeRootDir || ""), fileRef: activeFileRef }) }); } catch (error) { sendJson(res, 400, { ok: false, error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/catalog") { try { const catalog = await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }); if (typeof backend2.resolveRequestRoot === "function" && (activeRootDir || activeFileRef)) { onCatalogActivated( backend2.resolveRequestRoot({ rootDir: activeRootDir, fileRef: activeFileRef }), { rootDir: activeRootDir, fileRef: activeFileRef } ); } else if (activeRootDir && typeof backend2.resolveRoot === "function") { onCatalogActivated(backend2.resolveRoot(activeRootDir), { rootDir: activeRootDir, fileRef: activeFileRef }); } sendJson(res, 200, catalog, { cacheControl: catalogCacheControl }); } catch (error) { sendJson(res, 400, { error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/generation-status") { if (typeof backend2.readGenerationStatus !== "function") { sendJson(res, 501, { error: "Generation status is not available for this CAD Viewer backend" }); return; } try { sendJson(res, 200, await backend2.readGenerationStatus({ rootDir: activeRootDir })); } catch (error) { sendJson(res, 400, { error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/download") { const method = String(req.method || "GET").toUpperCase(); if (method !== "GET") { res.setHeader("allow", "GET"); sendJson(res, 405, { error: "Use GET to download a file asset" }); return; } try { const catalog = await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }); const request = fileAssetRequest(backend2, requestUrl, { rootDir: activeRootDir, catalog }); if (preferFileDownloadRedirects && typeof backend2.resolveFileAssetAccess === "function") { const access2 = await backend2.resolveFileAssetAccess(request); if (access2?.url) { res.statusCode = 302; res.setHeader("location", access2.url); res.setHeader("cache-control", "no-store"); res.end(""); return; } } if (typeof backend2.readFileAsset === "function") { const result = await backend2.readFileAsset(request); sendBufferDownload(res, result); return; } if (typeof backend2.resolveFileAssetAccess !== "function") { sendJson(res, 501, { error: "File downloads are not available for this CAD Viewer backend" }); return; } const access = await backend2.resolveFileAssetAccess(request); if (access?.path) { serveStaticFile(access.path, req, res, () => { sendJson(res, 404, { error: "File asset not found" }); }, { contentType: access.contentType || backend2.contentTypeForPath?.(access.path) || "application/octet-stream", headers: { "content-disposition": attachmentContentDisposition(access.filename || access.file || access.path) } }); return; } if (access?.url) { res.statusCode = 302; res.setHeader("location", access.url); res.setHeader("cache-control", "no-store"); res.end(""); return; } sendJson(res, 404, { error: "File asset not found" }); } catch (error) { sendJson(res, 400, { ok: false, error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/asset") { const method = String(req.method || "GET").toUpperCase(); if (method !== "GET") { res.setHeader("allow", "GET"); sendJson(res, 405, { error: "Use GET to read a CAD Viewer asset" }); return; } try { if (typeof backend2.assetPathForFileRef !== "function") { sendJson(res, 501, { error: "Direct CAD Viewer assets are not available for this backend" }); return; } const assetPath = backend2.assetPathForFileRef(activeFileRef, { rootDir: activeRootDir, ...typeof backend2.resolveRequestRoot === "function" && (activeRootDir || activeFileRef) ? { resolvedRoot: backend2.resolveRequestRoot({ rootDir: activeRootDir, fileRef: activeFileRef }) } : {} }); if (!assetPath) { sendJson(res, 404, { error: "CAD Viewer asset not found" }); return; } serveStaticFile(assetPath, req, res, () => { sendJson(res, 404, { error: "CAD Viewer asset not found" }); }, { contentType: backend2.contentTypeForPath?.(assetPath) || "application/octet-stream" }); } catch (error) { if (Number(error?.statusCode) === 403) { sendJson(res, 403, { error: "Forbidden" }); return; } sendJson(res, 400, { error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/reveal") { const method = String(req.method || "GET").toUpperCase(); if (method !== "POST") { res.setHeader("allow", "POST"); sendJson(res, 405, { error: "Use POST to reveal a file asset" }); return; } try { if (typeof backend2.openFileAsset !== "function") { sendJson(res, 405, { error: "Revealing files is only available for the local filesystem backend" }); return; } const catalog = await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }); const request = fileAssetRequest(backend2, requestUrl, { rootDir: activeRootDir, catalog }); const result = await backend2.openFileAsset(request); sendJson(res, 200, { ok: true, ...result }); } catch (error) { sendJson(res, 400, { ok: false, error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/implicit-export") { const method = String(req.method || "GET").toUpperCase(); if (method !== "POST") { res.setHeader("allow", "POST"); sendJson(res, 405, { error: "Use POST to export implicit CAD files" }); return; } if (backend2.kind !== "local-fs" || typeof backend2.generateImplicitExport !== "function" || typeof backend2.resolveRoot !== "function") { sendJson(res, 405, { error: "Implicit CAD export is only available for the local filesystem backend" }); return; } try { const body = await readJsonBody(req); const catalog = await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }); const resolvedRoot = typeof backend2.resolveRequestRoot === "function" ? backend2.resolveRequestRoot({ rootDir: activeRootDir, fileRef: activeFileRef }) : backend2.resolveRoot(activeRootDir); const format = requestUrl.searchParams.get("format") || body.format || "glb"; const result = await backend2.generateImplicitExport({ fileRef: activeFileRef || body.file, format, parameterValues: body.parameterValues || body.params || null, animationState: body.animationState || body.implicitAnimationState || null, resolution: body.resolution, maxCells: body.maxCells, resolvedRoot, rootDir: activeRootDir, catalog }); onCatalogChanged(resolvedRoot); sendJson(res, 200, { ok: true, result, entry: result.entry || null, catalog: result.catalog || (typeof backend2.refreshCatalog === "function" ? await backend2.refreshCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }) : await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef })), downloadUrl: `/__cad/download?dir=${encodeURIComponent(activeRootDir)}&file=${encodeURIComponent(result.outputFileRef)}&asset=output`, filename: result.filename }); } catch (error) { sendJson(res, 400, { ok: false, error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/step-source-status") { if (typeof backend2.readStepSourceStatus !== "function") { sendJson(res, 501, { error: "STEP source status is not available for this CAD Viewer backend" }); return; } try { const catalog = await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }); const request = { fileRef: activeFileRef, rootDir: activeRootDir, catalog }; if (typeof backend2.resolveRequestRoot === "function") { request.resolvedRoot = backend2.resolveRequestRoot({ rootDir: activeRootDir, fileRef: activeFileRef }); } else if (typeof backend2.resolveRoot === "function" && activeRootDir) { request.resolvedRoot = backend2.resolveRoot(activeRootDir); } sendJson(res, 200, await backend2.readStepSourceStatus(request)); } catch (error) { sendJson(res, 400, { error: errorMessage(error) }); } return; } if (requestUrl.pathname === "/__cad/step-artifact") { if (!enableStepArtifactBackend) { if (claimDisabledStepArtifactRoute) { sendJson(res, 501, { error: "STEP artifact generation is not enabled for this CAD Viewer backend" }); return; } next(); return; } if (req.method !== "POST") { sendJson(res, 405, { error: "Use POST to generate a STEP artifact" }); return; } if (typeof backend2.resolveRoot !== "function") { sendJson(res, 501, { error: "STEP artifact generation requires a local filesystem CAD Viewer backend" }); return; } try { const catalog = await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }); const resolvedRoot = typeof backend2.resolveRequestRoot === "function" ? backend2.resolveRequestRoot({ rootDir: activeRootDir, fileRef: activeFileRef }) : backend2.resolveRoot(activeRootDir); const result = await backend2.generateStepArtifact({ fileRef: activeFileRef, force: requestUrl.searchParams.get("force") === "1", resolvedRoot, catalog }); const nextCatalog = typeof backend2.refreshCatalog === "function" ? await backend2.refreshCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }) : await backend2.readCatalog({ rootDir: activeRootDir, fileRef: activeFileRef }); onCatalogChanged(resolvedRoot); sendJson(res, result.ok ? 200 : 500, { ok: result.ok, error: result.error, result: result.result, entry: backend2.entryForSourcePath(nextCatalog, resolvedRoot, result.stepPath), catalog: nextCatalog }); } catch (error) { sendJson(res, 400, { error: errorMessage(error) }); } return; } next(); }; } function createLocalAssetMiddleware({ backend: backend2, rootDir } = {}) { if (!backend2) { throw new Error("createLocalAssetMiddleware requires backend"); } return function localAssetMiddleware(req, res, next) { const requestUrl = new URL(req.url || "/", "http://localhost"); const fallbackFileRef = legacyCadAssetFileRef(requestUrl, req); if (requestUrl.pathname !== "/__cad/asset" && !fallbackFileRef || typeof backend2.assetPathForFileRef !== "function") { next(); return; } let assetPath = null; try { const refererUrl = requestRefererUrl(req); const activeRootDir = requestRootDir(requestUrl) || requestRootDir(refererUrl) || rootDir || ""; const activeFileRef = requestFileRef(requestUrl) || fallbackFileRef; assetPath = backend2.assetPathForFileRef(activeFileRef, { rootDir: activeRootDir, ...typeof backend2.resolveRequestRoot === "function" && (activeRootDir || activeFileRef) ? { resolvedRoot: backend2.resolveRequestRoot({ rootDir: activeRootDir, fileRef: activeFileRef }) } : {} }); } catch (error) { if (Number(error?.statusCode) === 403) { res.statusCode = 403; res.end("Forbidden"); return; } next(); return; } if (!assetPath) { next(); return; } serveStaticFile(assetPath, req, res, next, { contentType: backend2.contentTypeForPath?.(assetPath) || void 0 }); }; } function serveDistAsset({ distRoot: distRoot2, indexHtmlPath = path9.join(distRoot2, "index.html") } = {}) { return function distAssetMiddleware(req, res, next) { const requestUrl = new URL(req.url || "/", "http://localhost"); const requestPath = requestUrl.pathname === "/" ? "/index.html" : requestUrl.pathname; let filePath = ""; try { filePath = path9.resolve(distRoot2, decodeURIComponent(requestPath).replace(/^\/+/, "")); } catch { res.statusCode = 400; res.end("Bad request"); return; } if (!(filePath === distRoot2 || filePath.startsWith(`${distRoot2}${path9.sep}`))) { res.statusCode = 403; res.end("Forbidden"); return; } const fileExists = fs8.existsSync(filePath); const isStaticAssetRequest = requestPath.startsWith("/assets/") || path9.extname(requestPath); if (!fileExists && isStaticAssetRequest) { res.statusCode = 404; res.setHeader("content-type", "text/plain; charset=utf-8"); res.setHeader("cache-control", "no-store"); res.end("Not found"); return; } const fallbackPath = fileExists ? filePath : indexHtmlPath; serveStaticFile(fallbackPath, req, res, next, { contentType: contentTypeForStaticAsset(fallbackPath) || void 0 }); }; } // viewer/src/server/vercelBlobAssetBackend.mjs import path10 from "node:path"; var CATALOG_BLOB_CACHE_CONTROL_MAX_AGE_SECONDS = 60; function normalizePrefix(value) { const rawValue = String(value || "").trim(); if (!rawValue) { return ""; } try { return new URL(rawValue).pathname.replace(/^\/+|\/+$/g, ""); } catch { return rawValue.replace(/^\/+|\/+$/g, ""); } } function joinBlobPath(prefix, fileRef) { const normalizedRef = normalizeFileRef(fileRef); return [normalizePrefix(prefix), normalizedRef].filter(Boolean).join("/"); } function publicBlobUrlForRef(prefix, fileRef) { const rawPrefix = String(prefix || "").trim(); if (!rawPrefix) { return ""; } try { const url = new URL(rawPrefix); const prefixPath = url.pathname.replace(/^\/+|\/+$/g, ""); const normalizedRef = normalizeFileRef(fileRef); if (!normalizedRef) { return ""; } url.pathname = `/${[prefixPath, normalizedRef].filter(Boolean).join("/")}`; url.search = ""; url.hash = ""; return url.toString(); } catch { return ""; } } function cacheBypassedCatalogUrl(value) { try { const url = new URL(String(value || "")); url.searchParams.set("_tcad_catalog", "1"); return url.toString(); } catch { return value; } } function normalizeFileRef(value) { const normalized = path10.posix.normalize(String(value || "").trim().replace(/\\/g, "/").replace(/^\/+/, "")); return normalized && normalized !== "." && !normalized.startsWith("../") ? normalized : ""; } function catalogEntryForFileRef2(catalog, fileRef) { const normalized = normalizeFileRef(fileRef); if (!normalized || !Array.isArray(catalog?.entries)) { return null; } return catalog.entries.find((entry) => normalizeFileRef(entry?.file) === normalized) || null; } function normalizeString2(value) { return String(value || "").trim(); } function sourceKindIsPython(value) { return normalizeString2(value).toLowerCase() === "python"; } function artifactErrorCode(artifact) { const rawError = artifact?.error; if (rawError && typeof rawError === "object" && !Array.isArray(rawError)) { return normalizeString2(rawError.code); } return normalizeString2(rawError || artifact?.code); } function shouldSuppressHostedPythonArtifactWarning(entry) { const artifact = entry?.artifact; if (!artifact || typeof artifact !== "object" || Array.isArray(artifact)) { return false; } if (artifactErrorCode(artifact) !== "missing_source_path") { return false; } return sourceKindIsPython(entry?.sourceKind) || sourceKindIsPython(entry?.stepSourceKind) || sourceKindIsPython(artifact?.sourceKind); } function normalizeVercelBlobCatalogEntry(entry) { if (!entry || typeof entry !== "object" || Array.isArray(entry)) { return entry; } if (!shouldSuppressHostedPythonArtifactWarning(entry)) { return entry; } const { artifact, ...nextEntry } = entry; return nextEntry; } function normalizeVercelBlobCatalog(catalog) { if (!catalog || typeof catalog !== "object" || Array.isArray(catalog) || !Array.isArray(catalog.entries)) { return catalog; } let changed = false; const entries = catalog.entries.map((entry) => { const nextEntry = normalizeVercelBlobCatalogEntry(entry); if (nextEntry !== entry) { changed = true; } return nextEntry; }); return changed ? { ...catalog, entries } : catalog; } function sourceUrlFromEntry(entry) { return normalizeString2(entry?.sourceUrl || entry?.source?.url); } function stepUrlFromEntry(entry) { const explicitStepUrl = normalizeString2(entry?.stepUrl || entry?.step?.url); if (explicitStepUrl) { return explicitStepUrl; } const sourceKind = String(entry?.sourceKind || entry?.stepSourceKind || "").trim().toLowerCase(); return sourceKind === "python" ? "" : sourceUrlFromEntry(entry); } function outputUrlFromEntry(entry, fileRef) { const extension = path10.posix.extname(normalizeFileRef(fileRef)).toLowerCase(); if (extension === ".step" || extension === ".stp") { return stepUrlFromEntry(entry); } return normalizeString2(entry?.outputUrl || entry?.output?.url || entry?.url); } function sourceFileRefFromEntry(entry) { return normalizeFileRef(entry?.sourceFile || entry?.source?.file || entry?.source?.path) || normalizeFileRef(filenameFromUrl(sourceUrlFromEntry(entry))); } function stepFileRefFromEntry(entry, fallback = "") { return normalizeFileRef(entry?.stepFile || entry?.step?.file || entry?.step?.path) || normalizeFileRef(fallback); } function filenameFromUrl(url) { try { return path10.posix.basename(new URL(url).pathname); } catch { return ""; } } function artifactFileRefFromEntry(entry) { return normalizeFileRef(entry?.assetFile || entry?.asset?.file || entry?.artifactFile || entry?.artifact?.file) || normalizeFileRef(filenameFromUrl(entry?.url)); } function normalizedFileAssetKind2(value) { const asset = String(value || "output").trim().toLowerCase(); if (asset === "asset") { return "artifact"; } if (asset === "output" || asset === "source" || asset === "artifact") { return asset; } throw new Error(`Unsupported file asset: ${asset || "(missing)"}`); } function contentTypeForFileRef(fileRef, fallback = "") { const extension = path10.posix.extname(normalizeFileRef(fileRef)).toLowerCase(); if (fallback) { return fallback; } if (extension === ".glb") { return "model/gltf-binary"; } if (extension === ".stl") { return "model/stl"; } if (extension === ".3mf") { return "model/3mf"; } if (extension === ".step" || extension === ".stp") { return "application/step"; } if (extension === ".dxf") { return "application/dxf"; } if (extension === ".gcode") { return "text/plain; charset=utf-8"; } if (extension === ".js" || extension === ".mjs") { return "text/javascript; charset=utf-8"; } if (extension === ".json") { return "application/json; charset=utf-8"; } if (extension === ".urdf" || extension === ".srdf" || extension === ".sdf") { return "application/xml; charset=utf-8"; } return "application/octet-stream"; } async function loadBlobClient(client) { if (client) { return client; } try { return await Promise.resolve().then(() => (init_dist(), dist_exports)); } catch (error) { throw new Error( `Vercel Blob backend requires @vercel/blob to be installed: ${error instanceof Error ? error.message : String(error)}` ); } } async function blobErrorDetail(response) { const requestId = normalizeString2(response.headers?.get?.("x-vercel-id")); let body = ""; try { body = normalizeString2(await response.text()).slice(0, 200); } catch { body = ""; } return [ requestId ? `request ${requestId}` : "", body ].filter(Boolean).join(": "); } async function readJsonFromUrl(url, { fetchImpl = globalThis.fetch } = {}) { if (!fetchImpl) { throw new Error("Vercel Blob backend requires fetch to read catalog URLs"); } const response = await fetchImpl(cacheBypassedCatalogUrl(url)); if (!response.ok) { const detail = await blobErrorDetail(response); throw new Error( `Failed to read Vercel Blob catalog: ${response.status} ${response.statusText}${detail ? ` (${detail})` : ""}` ); } return response.json(); } async function readJsonFromBlobGetResult(result, pathname) { if (!result) { throw new Error(`Vercel Blob catalog not found: ${pathname}`); } if (!result.stream) { throw new Error(`Vercel Blob catalog response had no body: ${pathname}`); } return new Response(result.stream).json(); } function hasBlobSdkReadCredentials(token) { return Boolean( normalizeString2(token) || normalizeString2(process.env.BLOB_READ_WRITE_TOKEN) || normalizeString2(process.env.VERCEL_OIDC_TOKEN) && normalizeString2(process.env.BLOB_STORE_ID) ); } function createVercelBlobAssetBackend({ prefix = "", catalogPath = "catalog.json", catalogUrl = "", client = null, fetchImpl = globalThis.fetch, token = process.env.VIEWER_VERCEL_BLOB_READ_WRITE_TOKEN || process.env.BLOB_READ_WRITE_TOKEN, readOnly = false, catalogCacheTtlMs = 0 } = {}) { const normalizedPrefix = normalizePrefix(prefix); const normalizedCatalogPath = joinBlobPath(normalizedPrefix, catalogPath || "catalog.json"); const resolvedCatalogUrl = catalogUrl || publicBlobUrlForRef(prefix, catalogPath || "catalog.json"); let cachedCatalog = null; let cachedCatalogAt = 0; let catalogFetchInFlight = null; async function blobClient() { return loadBlobClient(client); } async function fetchCatalog() { if (resolvedCatalogUrl) { return normalizeVercelBlobCatalog(await readJsonFromUrl(resolvedCatalogUrl, { fetchImpl })); } if (hasBlobSdkReadCredentials(token)) { const blob2 = await blobClient(); if (typeof blob2.get === "function") { const getOptions = { access: "public" }; if (token) { getOptions.token = token; } return normalizeVercelBlobCatalog(await readJsonFromBlobGetResult( await blob2.get(normalizedCatalogPath, getOptions), normalizedCatalogPath )); } } const blob = await blobClient(); const listing = await blob.list({ prefix: normalizedCatalogPath, token }); const catalogBlob = Array.isArray(listing?.blobs) ? listing.blobs.find((entry) => entry.pathname === normalizedCatalogPath) || listing.blobs[0] : null; if (!catalogBlob?.url) { throw new Error(`Vercel Blob catalog not found: ${normalizedCatalogPath}`); } return normalizeVercelBlobCatalog(await readJsonFromUrl(catalogBlob.url, { fetchImpl })); } async function fetchCatalogCached({ force = false } = {}) { if (!(catalogCacheTtlMs > 0)) { return fetchCatalog(); } if (!force && cachedCatalog && Date.now() - cachedCatalogAt < catalogCacheTtlMs) { return cachedCatalog; } if (!catalogFetchInFlight) { catalogFetchInFlight = fetchCatalog().finally(() => { catalogFetchInFlight = null; }); } try { const catalog = await catalogFetchInFlight; cachedCatalog = catalog; cachedCatalogAt = Date.now(); return catalog; } catch (error) { if (cachedCatalog) { console.warn( `Serving cached Vercel Blob catalog after read failure: ${error instanceof Error ? error.message : String(error)}` ); return cachedCatalog; } throw error; } } async function readCatalog() { return fetchCatalogCached(); } async function writeAsset({ fileRef, body, contentType = "application/octet-stream", cacheControlMaxAge } = {}) { const pathname = joinBlobPath(normalizedPrefix, fileRef); if (!pathname) { throw new Error("Missing Vercel Blob asset path"); } const blob = await blobClient(); return blob.put(pathname, body, { access: "public", addRandomSuffix: false, allowOverwrite: true, contentType, ...cacheControlMaxAge !== void 0 ? { cacheControlMaxAge } : {}, token }); } async function writeCatalog(catalog) { const normalizedCatalog = normalizeVercelBlobCatalog(catalog); return writeAsset({ fileRef: catalogPath || "catalog.json", body: JSON.stringify({ schemaVersion: 4, entries: Array.isArray(normalizedCatalog?.entries) ? normalizedCatalog.entries : [] }, null, 2), contentType: "application/json; charset=utf-8", cacheControlMaxAge: CATALOG_BLOB_CACHE_CONTROL_MAX_AGE_SECONDS }); } async function refreshCatalog() { return fetchCatalogCached({ force: true }); } async function urlForBlobRef(fileRef) { const pathname = joinBlobPath(normalizedPrefix, fileRef); if (!pathname) { return ""; } const blob = await blobClient(); const listing = await blob.list({ prefix: pathname, token }); const match = Array.isArray(listing?.blobs) ? listing.blobs.find((entry) => entry.pathname === pathname) : null; return match?.url || ""; } async function resolveFileAssetAccess({ fileRef, asset = "output", catalog = null } = {}) { const assetKind = normalizedFileAssetKind2(asset); const requestedFileRef = normalizeFileRef(fileRef); if (assetKind === "source") { throw new Error( `Source code is not available in Vercel Blob deployments for ${requestedFileRef || "(missing)"}` ); } const currentCatalog = catalog || await readCatalog(); const entry = catalogEntryForFileRef2(currentCatalog, requestedFileRef); if (!entry) { throw new Error(`CAD catalog entry not found: ${requestedFileRef || "(missing)"}`); } const outputRef = normalizeFileRef(entry.file || requestedFileRef); const outputExtension = path10.posix.extname(outputRef).toLowerCase(); const explicitSourceUrl = sourceUrlFromEntry(entry); const explicitSourceRef = sourceFileRefFromEntry(entry); const explicitStepUrl = stepUrlFromEntry(entry); const explicitStepRef = stepFileRefFromEntry(entry, outputRef); const explicitArtifactUrl = normalizeString2(entry?.url); const explicitArtifactRef = artifactFileRefFromEntry(entry); const fileRefForAsset = assetKind === "source" ? explicitSourceRef : assetKind === "artifact" ? explicitArtifactRef : outputExtension === ".step" || outputExtension === ".stp" ? explicitStepRef : outputRef; const fallbackUrl = assetKind === "source" ? explicitSourceUrl : assetKind === "artifact" ? explicitArtifactUrl : outputUrlFromEntry(entry, fileRefForAsset || outputRef || requestedFileRef); const blobUrl = fallbackUrl || !fileRefForAsset ? "" : await urlForBlobRef(fileRefForAsset); const url = fallbackUrl || blobUrl; if (!fileRefForAsset || !url) { throw new Error( assetKind === "source" ? `Source code is not available in Vercel Blob for ${requestedFileRef || "(missing)"}` : assetKind === "artifact" ? `Artifact file is not available in Vercel Blob for ${requestedFileRef || "(missing)"}` : `Output file is not available in Vercel Blob for ${requestedFileRef || "(missing)"}` ); } return { asset: assetKind, file: fileRefForAsset, url, filename: path10.posix.basename(fileRefForAsset) || filenameFromUrl(url), contentType: contentTypeForFileRef(fileRefForAsset) }; } async function readFileAsset(request = {}) { if (!fetchImpl) { throw new Error("Vercel Blob backend requires fetch to download file assets"); } const access = await resolveFileAssetAccess(request); const response = await fetchImpl(access.url); if (!response.ok) { throw new Error(`Failed to download file asset from Blob: ${response.status} ${response.statusText}`); } const contentType = response.headers?.get?.("content-type") || access.contentType; return { ...access, body: Buffer.from(await response.arrayBuffer()), contentType: contentTypeForFileRef(access.file, contentType) }; } async function resolveSourceFileAccess(request = {}) { return resolveFileAssetAccess({ ...request, asset: "source" }); } async function readSourceFile(request = {}) { return readFileAsset({ ...request, asset: "source" }); } async function readStepSourceStatus2({ fileRef, catalog = null } = {}) { const requestedFileRef = normalizeFileRef(fileRef); const currentCatalog = catalog || await readCatalog(); const entry = catalogEntryForFileRef2(currentCatalog, requestedFileRef); if (!entry) { throw new Error(`STEP catalog entry not found: ${requestedFileRef || "(missing)"}`); } const repoStepRef = stepFileRefFromEntry(entry, entry.file || requestedFileRef); const sourceUrl = stepUrlFromEntry(entry) || (readOnly ? "" : await urlForBlobRef(repoStepRef)); return { ok: Boolean(sourceUrl), file: repoStepRef, stepPath: repoStepRef, sourceKind: "step", step: sourceUrl ? { ok: true, status: "current", missing: false, stale: false } : { ok: false, status: "missing", missing: true, stale: false, message: "STEP file is missing." } }; } const backend2 = { kind: "vercel-blob", readOnly: Boolean(readOnly), canGenerateStepArtifacts: false, prefix: normalizedPrefix, catalogPath: normalizedCatalogPath, readCatalog, readStepSourceStatus: readStepSourceStatus2, resolveFileAssetAccess, readFileAsset, resolveSourceFileAccess, readSourceFile, refreshCatalog, urlForBlobRef }; if (!readOnly) { return { ...backend2, writeAsset, writeCatalog }; } return backend2; } // viewer/src/server/viewerEnv.mjs var VIEWER_ASSET_BACKENDS = Object.freeze({ LOCAL_FS: "local-fs", VERCEL_BLOB: "vercel-blob" }); var DEPRECATED_LOCAL_ROOT_ENV_VARS = Object.freeze([ "VIEWER_LOCAL_ROOT_DIR", "VIEWER_LOCAL_WORKSPACE_ROOT" ]); var VALID_VIEWER_ASSET_BACKENDS = new Set(Object.values(VIEWER_ASSET_BACKENDS)); function envValue(env, name, fallback = "") { return String(env?.[name] ?? fallback).trim(); } function normalizeViewerAssetBackend(value, fallback = VIEWER_ASSET_BACKENDS.LOCAL_FS) { const normalized = String(value || fallback || "").trim().toLowerCase(); if (VALID_VIEWER_ASSET_BACKENDS.has(normalized)) { return normalized; } throw new Error( `Unsupported VIEWER_ASSET_BACKEND: ${normalized || "(missing)"}. Expected one of: ${[...VALID_VIEWER_ASSET_BACKENDS].join(", ")}.` ); } function assertNoDeprecatedLocalRootEnv(env = process.env) { const configured = DEPRECATED_LOCAL_ROOT_ENV_VARS.filter((name) => String(env?.[name] || "").trim()); if (configured.length) { throw new Error( `${configured.join(", ")} ${configured.length === 1 ? "is" : "are"} no longer supported. Pass ?dir= in the Viewer URL instead.` ); } } function vercelBlobCatalogUrlFromPrefix(prefix, catalogPath = "catalog.json") { const rawPrefix = envValue({ prefix }, "prefix"); if (!rawPrefix) { return ""; } const normalizedCatalogPath = String(catalogPath || "catalog.json").trim().replace(/^\/+/, ""); if (!normalizedCatalogPath) { return ""; } try { const url = new URL(rawPrefix); const pathname = url.pathname.replace(/^\/+|\/+$/g, ""); url.pathname = `/${[pathname, normalizedCatalogPath].filter(Boolean).join("/")}`; url.search = ""; url.hash = ""; return url.toString(); } catch { return ""; } } function normalizeVercelBlobStoreId(value) { const normalized = String(value || "").trim().replace(/^store_/i, ""); return /^[a-z0-9]+$/i.test(normalized) ? normalized.toLowerCase() : ""; } function vercelBlobStoreIdFromToken(value) { const token = String(value || "").trim(); const parts = token.split("_"); if (parts[0] !== "vercel" || parts[1] !== "blob") { return ""; } const tokenKindLength = parts[2] === "read" && parts[3] === "write" ? 2 : 1; return normalizeVercelBlobStoreId(parts[2 + tokenKindLength]); } function vercelBlobStoreIdFromEnv(env = process.env) { return normalizeVercelBlobStoreId(envValue(env, "VIEWER_VERCEL_BLOB_STORE_ID")) || normalizeVercelBlobStoreId(envValue(env, "BLOB_STORE_ID")) || vercelBlobStoreIdFromToken(envValue(env, "VIEWER_VERCEL_BLOB_READ_WRITE_TOKEN")) || vercelBlobStoreIdFromToken(envValue(env, "BLOB_READ_WRITE_TOKEN")); } function vercelBlobPrefixFromEnv(env = process.env) { const prefix = envValue(env, "VIEWER_VERCEL_BLOB_PREFIX"); const storeId = vercelBlobStoreIdFromEnv(env); if (!prefix || !storeId) { return prefix; } try { const url = new URL(prefix); const hostname = url.hostname.toLowerCase(); if (hostname.endsWith(".public.blob.vercel-storage.com") || hostname === "blob.vercel-storage.com") { url.hostname = `${storeId}.public.blob.vercel-storage.com`; return url.toString(); } } catch { const pathname = prefix.replace(/^\/+|\/+$/g, ""); return `https://${storeId}.public.blob.vercel-storage.com${pathname ? `/${pathname}` : ""}`; } return prefix; } function vercelBlobConfigFromEnv(env = process.env) { const prefix = vercelBlobPrefixFromEnv(env); const catalogPath = envValue(env, "VIEWER_VERCEL_BLOB_CATALOG_PATH", "catalog.json") || "catalog.json"; return { prefix, catalogPath, catalogUrl: vercelBlobCatalogUrlFromPrefix(prefix, catalogPath), token: envValue(env, "VIEWER_VERCEL_BLOB_READ_WRITE_TOKEN") || envValue(env, "BLOB_READ_WRITE_TOKEN") || void 0 }; } // viewer/src/server/vercelApi.mjs function vercelUrlFromHost(value) { const rawValue = String(value || "").trim(); if (!rawValue) { return ""; } try { const url = new URL(rawValue.includes("://") ? rawValue : `https://${rawValue}`); const pathname = url.pathname.replace(/\/+$/g, ""); return `${url.protocol}//${url.host}${pathname === "/" ? "" : pathname}`; } catch { return ""; } } function hostedViewerPublicUrlFromEnv(env = process.env) { const candidates = [ "VERCEL_PROJECT_PRODUCTION_URL", "VERCEL_URL", "VERCEL_BRANCH_URL" ]; for (const name of candidates) { const url = vercelUrlFromHost(envValue(env, name)); if (url) { return url; } } return ""; } function buildHostedViewerServerInfo({ backend: backend2, env = process.env, rootDir = "" } = {}) { return { schemaVersion: 1, app: "cad-viewer", backend: backend2?.kind || "vercel-blob", rootDir, catalogPath: backend2?.catalogPath || vercelBlobConfigFromEnv(env).catalogPath, stepArtifactGenerationAvailable: false, url: hostedViewerPublicUrlFromEnv(env) }; } // viewer/src/server/viewerServerInfo.mjs import path11 from "node:path"; var VIEWER_SERVER_INFO_SCHEMA_VERSION = 1; var VIEWER_SERVER_API_VERSION = 2; var VIEWER_SERVER_APP_ID = "cad-viewer"; var DEFAULT_VIEWER_HOST = "127.0.0.1"; var DEFAULT_VIEWER_PORT = 4178; function normalizeViewerPort(value, fallback = DEFAULT_VIEWER_PORT) { const parsed = Number.parseInt(String(value ?? ""), 10); if (Number.isInteger(parsed) && parsed > 0 && parsed <= 65535) { return parsed; } return fallback; } function normalizeViewerActiveDirectory(value, directoryRoot2) { if (!value || typeof value !== "object") { return null; } const rawDir = String(value.dir || "").trim(); const rawRootPath = String(value.rootPath || "").trim(); if (!rawDir && !rawRootPath) { return null; } const resolvedRawRootPath = rawRootPath ? path11.resolve(path11.isAbsolute(rawRootPath) ? rawRootPath : path11.join(directoryRoot2, rawRootPath)) : ""; const resolvedRoot = rawRootPath ? { dir: rawDir, rootPath: resolvedRawRootPath, rootName: path11.basename(resolvedRawRootPath) } : path11.isAbsolute(rawDir) ? { dir: path11.resolve(rawDir), rootPath: path11.resolve(rawDir), rootName: path11.basename(path11.resolve(rawDir)) } : resolveViewerRoot(directoryRoot2, normalizeViewerRootDir(rawDir)); const dir = rawDir || resolvedRoot.dir || ""; const rootPath = resolvedRoot.rootPath || ""; if (!rootPath) { return null; } return { dir, rootPath, rootName: String(value.rootName || resolvedRoot.rootName || path11.basename(rootPath) || dir || "Directory") }; } function normalizeViewerActiveDirectories(activeDirectories2, directoryRoot2) { if (!Array.isArray(activeDirectories2) || !directoryRoot2) { return []; } const seen = /* @__PURE__ */ new Set(); const normalized = []; for (const value of activeDirectories2) { const directory = normalizeViewerActiveDirectory(value, directoryRoot2); if (!directory || !directory.dir || seen.has(directory.rootPath)) { continue; } seen.add(directory.rootPath); normalized.push(directory); } return normalized; } function buildViewerServerInfo({ directoryRoot: directoryRoot2, rootDir = DEFAULT_VIEWER_ROOT_DIR, port: port2 = DEFAULT_VIEWER_PORT, pid = process.pid, host: host2 = DEFAULT_VIEWER_HOST, backend: backend2 = "local-fs", dynamicRoot = false, stepArtifactGenerationAvailable = true, viewerVersion: viewerVersion2 = "", serverMode = "", git = "", serverFeatures = [], activeDirectories: activeDirectories2 = [] } = {}) { if (!directoryRoot2) { throw new Error("directoryRoot is required"); } const resolvedDirectoryRoot = path11.resolve(directoryRoot2); const rawRootDir = String(rootDir || "").trim(); const resolvedViewerRoot = rawRootDir ? path11.isAbsolute(rawRootDir) ? { dir: path11.resolve(rawRootDir), rootPath: path11.resolve(rawRootDir), rootName: path11.basename(path11.resolve(rawRootDir)) } : resolveViewerRoot(resolvedDirectoryRoot, normalizeViewerRootDir(rawRootDir)) : { dir: DEFAULT_VIEWER_ROOT_DIR, rootPath: "", rootName: "" }; const normalizedPort = normalizeViewerPort(port2); const normalizedServerMode = String(serverMode || "").trim(); const normalizedGit = String(git || "").trim(); const normalizedActiveDirectories = normalizeViewerActiveDirectories(activeDirectories2, resolvedDirectoryRoot); return { schemaVersion: VIEWER_SERVER_INFO_SCHEMA_VERSION, serverApiVersion: VIEWER_SERVER_API_VERSION, app: VIEWER_SERVER_APP_ID, viewerVersion: String(viewerVersion2 || ""), ...normalizedServerMode ? { serverMode: normalizedServerMode } : {}, ...normalizedGit ? { git: normalizedGit } : {}, serverFeatures: Array.isArray(serverFeatures) ? serverFeatures.map((feature) => String(feature || "").trim()).filter(Boolean) : [], backend: backend2, dynamicRoot: Boolean(dynamicRoot), directoryRoot: resolvedDirectoryRoot, rootDir: resolvedViewerRoot.dir, rootPath: resolvedViewerRoot.rootPath, rootName: resolvedViewerRoot.rootName, activeDirectories: normalizedActiveDirectories, port: normalizedPort, pid: Number.isInteger(pid) ? pid : process.pid, stepArtifactGenerationAvailable: stepArtifactGenerationAvailable !== false, url: `http://${host2}:${normalizedPort}` }; } // viewer/src/shared/viewerConfig.mjs var DEFAULT_VIEWER_GITHUB_URL = "https://github.com/earthtojake/text-to-cad"; function normalizeViewerDefaultFile(value = "") { const rawValue = String(value ?? "").trim(); return rawValue.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, ""); } function normalizeViewerGithubUrl(value = "", fallback = DEFAULT_VIEWER_GITHUB_URL) { return normalizeHttpUrlCandidate(value) || normalizeHttpUrlCandidate(fallback); } function normalizeHttpUrlCandidate(value = "") { const rawValue = String(value ?? "").trim(); if (!rawValue) { return ""; } const urlValue = /^[a-z][a-z\d+.-]*:\/\//i.test(rawValue) ? rawValue : `https://${rawValue.replace(/^\/+/, "")}`; try { const url = new URL(urlValue); return ["http:", "https:"].includes(url.protocol) ? url.href : ""; } catch { return ""; } } // viewer/src/server/directoryRoot.mjs import path12 from "node:path"; function resolveDirectoryRoot({ directoryRoot: directoryRoot2 = "", env = process.env, cwd = process.cwd(), appRoot = "", defaultDirectoryRoot: defaultDirectoryRoot2 = "" } = {}) { const explicitRoot = directoryRoot2 || ""; if (explicitRoot) { return path12.resolve(cwd, explicitRoot); } const resolvedAppRoot = appRoot ? path12.resolve(appRoot) : ""; for (const candidate of [env.INIT_CWD, cwd]) { if (!candidate) { continue; } const resolvedCandidate = path12.resolve(candidate); if (!resolvedAppRoot || resolvedCandidate !== resolvedAppRoot && !pathIsInside(resolvedCandidate, resolvedAppRoot)) { return resolvedCandidate; } } return defaultDirectoryRoot2 ? path12.resolve(defaultDirectoryRoot2) : path12.resolve(cwd); } // viewer/src/server/serverLifetime.mjs var MAX_SERVER_LIFETIME_MS = 2147483647; function parseServerLifetimeMs(value, flag = "--shutdown-after") { const rawValue = String(value ?? "").trim().toLowerCase(); const match = /^(\d+(?:\.\d+)?)(ms|s|m|h)?$/.exec(rawValue); if (!match) { throw new Error(`${flag} must be a positive duration such as 30m, 2h, or 43200000.`); } const amount = Number.parseFloat(match[1]); const unit = match[2] || "ms"; const multiplier = { ms: 1, s: 1e3, m: 60 * 1e3, h: 60 * 60 * 1e3 }[unit]; const parsed = Math.round(amount * multiplier); if (!Number.isFinite(parsed) || parsed <= 0 || parsed > MAX_SERVER_LIFETIME_MS) { throw new Error(`${flag} must be between 1ms and ${MAX_SERVER_LIFETIME_MS}ms.`); } return parsed; } function normalizeServerLifetimeMs(value, defaultMs = null) { const rawValue = String(value ?? "").trim(); if (!rawValue) { return defaultMs; } const parsed = Number.parseInt(rawValue, 10); if (!Number.isInteger(parsed) || parsed <= 0 || parsed > MAX_SERVER_LIFETIME_MS) { return defaultMs; } return parsed; } function formatServerLifetime(ms) { if (ms % (60 * 60 * 1e3) === 0) { return `${ms / (60 * 60 * 1e3)}h`; } if (ms % (60 * 1e3) === 0) { return `${ms / (60 * 1e3)}m`; } if (ms % 1e3 === 0) { return `${ms / 1e3}s`; } return `${ms}ms`; } function closeHttpServer(server2) { return new Promise((resolve, reject) => { server2.close((error) => { if (error) { reject(error); return; } resolve(); }); }); } function scheduleProcessShutdown({ lifetimeMs, label = "CAD Viewer server", close = async () => { } } = {}) { const normalizedLifetimeMs = normalizeServerLifetimeMs(lifetimeMs); if (normalizedLifetimeMs === null) { return null; } const timer = setTimeout(() => { console.log(`${label} reached ${formatServerLifetime(normalizedLifetimeMs)} lifetime; shutting down.`); const forceExit = setTimeout(() => process.exit(0), 5e3); forceExit.unref?.(); Promise.resolve().then(() => close()).then( () => process.exit(0), (error) => { console.error(`${label} shutdown failed: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } ); }, normalizedLifetimeMs); timer.unref?.(); return timer; } // viewer/src/server/serverArgs.mjs function requiredValue(argv, index, flag) { const value = argv[index + 1]; if (!value || value.startsWith("--")) { throw new Error(`${flag} requires a value`); } return value; } function parsePort(value, flag) { const parsed = Number.parseInt(String(value ?? ""), 10); if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) { throw new Error(`${flag} must be a TCP port from 1 to 65535`); } return parsed; } function parseServerArgs(argv = []) { const options = { port: null, host: "", rootDir: "", shutdownAfterMs: null, help: false }; for (let index = 0; index < argv.length; index += 1) { const arg = argv[index]; if (arg === "--help" || arg === "-h") { options.help = true; continue; } if (arg.startsWith("--root-dir=")) { throw new Error("--root-dir has been removed; pass ?dir= in the Viewer URL."); } if (arg === "--root-dir") { throw new Error("--root-dir has been removed; pass ?dir= in the Viewer URL."); } if (arg.startsWith("--dir=")) { options.rootDir = arg.slice("--dir=".length).trim(); continue; } if (arg === "--dir") { options.rootDir = requiredValue(argv, index, arg).trim(); index += 1; continue; } if (arg.startsWith("--port=")) { options.port = parsePort(arg.slice("--port=".length), "--port"); continue; } if (arg === "--port") { options.port = parsePort(requiredValue(argv, index, arg), arg); index += 1; continue; } if (arg.startsWith("--host=")) { options.host = arg.slice("--host=".length).trim(); continue; } if (arg === "--host") { options.host = requiredValue(argv, index, arg).trim(); index += 1; continue; } if (arg.startsWith("--shutdown-after=")) { options.shutdownAfterMs = parseServerLifetimeMs(arg.slice("--shutdown-after=".length), "--shutdown-after"); continue; } if (arg === "--shutdown-after") { options.shutdownAfterMs = parseServerLifetimeMs(requiredValue(argv, index, arg), arg); index += 1; continue; } throw new Error(`Unknown argument: ${arg}`); } return options; } function serverHelpText() { return `Usage: node backend/server.mjs [options] Options: --port Port to bind. Defaults to 4178. --host Host to bind. Defaults to 127.0.0.1. --dir Default local directory root. Defaults to startup directory. --shutdown-after