esa-pcg-cli 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_inline-overrides.js +2 -2
- package/dist/adapters/wrappers/node-server.js +6 -2
- package/dist/overrides/tagCache/gateway.js +6 -1
- package/dist/runtime/cdn-purge.d.ts +12 -8
- package/dist/runtime/cdn-purge.js +56 -34
- package/dist/runtime/edge-context.d.ts +26 -0
- package/dist/runtime/edge-context.js +77 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
exports.INLINE_OVERRIDES = {
|
|
3
|
-
"adapters/wrappers/node-server.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod2) => function __require() {\n return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/runtime/image-config.js\nvar require_image_config = __commonJS({\n \"dist/runtime/image-config.js\"(exports, module) {\n \"use strict\";\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports._setMatcherForTests = exports._resetImageConfigCacheForTests = exports.validateImageUrl = void 0;\n var fs = require(\"fs\");\n var path = require(\"path\");\n var cachedConfig;\n var cachedMatcher;\n var warnedMatcherMissing = false;\n function configFilePath() {\n return path.resolve(process.cwd(), \".next\", \"required-server-files.json\");\n }\n function loadImageConfig() {\n var _a, _b, _c;\n if (cachedConfig !== void 0)\n return cachedConfig;\n const filePath = configFilePath();\n let raw;\n try {\n raw = fs.readFileSync(filePath, \"utf-8\");\n } catch (err) {\n console.warn(`[image-config] required-server-files.json not found at ${filePath} \\u2014 allowing all image URLs (${(_a = err.code) !== null && _a !== void 0 ? _a : err.message})`);\n cachedConfig = { mode: \"config-missing\" };\n return cachedConfig;\n }\n try {\n const parsed = JSON.parse(raw);\n const images = (_c = (_b = parsed === null || parsed === void 0 ? void 0 : parsed.config) === null || _b === void 0 ? void 0 : _b.images) !== null && _c !== void 0 ? _c : {};\n cachedConfig = {\n mode: \"loaded\",\n images: {\n remotePatterns: Array.isArray(images.remotePatterns) ? images.remotePatterns : [],\n domains: Array.isArray(images.domains) ? images.domains : [],\n unoptimized: images.unoptimized === true\n }\n };\n return cachedConfig;\n } catch (err) {\n console.warn(`[image-config] failed to parse ${filePath}: ${err.message} \\u2014 allowing all image URLs`);\n cachedConfig = { mode: \"config-missing\" };\n return cachedConfig;\n }\n }\n function loadMatcher() {\n if (cachedMatcher !== void 0)\n return cachedMatcher;\n try {\n const dynamicRequire = eval(\"require\");\n const mod = dynamicRequire(\"next/dist/shared/lib/match-remote-pattern\");\n const hasRemoteMatch = mod === null || mod === void 0 ? void 0 : mod.hasRemoteMatch;\n if (typeof hasRemoteMatch !== \"function\") {\n throw new Error(\"hasRemoteMatch not exported\");\n }\n cachedMatcher = hasRemoteMatch;\n return cachedMatcher;\n } catch (err) {\n if (!warnedMatcherMissing) {\n warnedMatcherMissing = true;\n console.warn(`[image-config] cannot load next/dist/shared/lib/match-remote-pattern (${err.message}) \\u2014 falling back to deny-external-only mode`);\n }\n cachedMatcher = null;\n return null;\n }\n }\n function validateImageUrl(absoluteUrl, hostHeader) {\n const cfg = loadImageConfig();\n if (cfg.mode === \"config-missing\") {\n return { ok: true, reason: \"config-missing\" };\n }\n const { images } = cfg;\n if (images.unoptimized) {\n return { ok: true, reason: \"unoptimized\" };\n }\n const reqHost = hostHeader.toLowerCase();\n const urlHost = absoluteUrl.host.toLowerCase();\n if (reqHost && reqHost === urlHost) {\n return { ok: true, reason: \"same-origin\" };\n }\n const matcher = loadMatcher();\n if (matcher === null) {\n return { ok: false, reason: \"matcher-unavailable\" };\n }\n if (matcher(images.domains, images.remotePatterns, absoluteUrl)) {\n return { ok: true, reason: \"pattern-match\" };\n }\n return { ok: false, reason: \"remote-pattern-not-matched\" };\n }\n exports.validateImageUrl = validateImageUrl;\n function _resetImageConfigCacheForTests() {\n cachedConfig = void 0;\n cachedMatcher = void 0;\n warnedMatcherMissing = false;\n }\n exports._resetImageConfigCacheForTests = _resetImageConfigCacheForTests;\n function _setMatcherForTests(impl) {\n cachedMatcher = impl;\n }\n exports._setMatcherForTests = _setMatcherForTests;\n }\n});\n\n// dist/runtime/image-proxy.js\nvar require_image_proxy = __commonJS({\n \"dist/runtime/image-proxy.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.handleImageProxy = void 0;\n var stream_1 = require(\"stream\");\n var gateway_auth_1 = require_gateway_auth();\n var image_config_1 = require_image_config();\n var GATEWAY_TIMEOUT_MS = 1e4;\n var PASSTHROUGH_HEADERS = [\n \"content-type\",\n \"content-length\",\n \"cache-control\",\n \"etag\",\n \"vary\",\n \"last-modified\",\n \"content-security-policy\"\n ];\n function resolveAbsoluteUrl(rawUrl, req) {\n if (rawUrl.startsWith(\"http://\") || rawUrl.startsWith(\"https://\")) {\n return rawUrl;\n }\n const host = req.headers[\"host\"];\n if (!host)\n return null;\n const protoHeader = req.headers[\"x-forwarded-proto\"];\n const proto = (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || \"https\";\n const path3 = rawUrl.startsWith(\"/\") ? rawUrl : `/${rawUrl}`;\n return `${proto}://${host}${path3}`;\n }\n function writeJson(res, status, body) {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.end(JSON.stringify(body));\n }\n async function handleImageProxy(req, res) {\n const reqUrl = req.url || \"\";\n const qIdx = reqUrl.indexOf(\"?\");\n if (qIdx === -1) {\n return writeJson(res, 400, { error: \"Missing query parameters\" });\n }\n const params = new URLSearchParams(reqUrl.slice(qIdx + 1));\n const rawUrl = params.get(\"url\");\n const w = params.get(\"w\");\n const q = params.get(\"q\");\n if (!rawUrl || !w) {\n return writeJson(res, 400, {\n error: \"Missing required parameters: url, w\"\n });\n }\n const absoluteUrl = resolveAbsoluteUrl(rawUrl, req);\n if (!absoluteUrl) {\n return writeJson(res, 500, {\n error: \"Cannot resolve absolute URL: missing Host header\"\n });\n }\n let parsedUrl;\n try {\n parsedUrl = new URL(absoluteUrl);\n } catch (_a) {\n return writeJson(res, 400, { error: \"Invalid url parameter\" });\n }\n const hostHeader = req.headers[\"host\"] || \"\";\n const verdict = (0, image_config_1.validateImageUrl)(parsedUrl, hostHeader);\n if (!verdict.ok) {\n return writeJson(res, 400, { error: \"url not allowed\" });\n }\n const cfg = (0, gateway_auth_1.loadGatewayAuthConfig)();\n if (!cfg) {\n return writeJson(res, 500, {\n error: \"Gateway auth config missing\"\n });\n }\n const upstreamParams = new URLSearchParams({ url: absoluteUrl, w });\n if (q)\n upstreamParams.set(\"q\", q);\n const upstreamPath = `/image/optimize?${upstreamParams}`;\n const ifNoneMatch = req.headers[\"if-none-match\"];\n const upstreamHeaders = {};\n if (typeof ifNoneMatch === \"string\") {\n upstreamHeaders[\"if-none-match\"] = ifNoneMatch;\n }\n const accept = req.headers[\"accept\"];\n if (typeof accept === \"string\") {\n upstreamHeaders[\"accept\"] = accept;\n }\n let upstream;\n try {\n upstream = await (0, gateway_auth_1.gatewayFetch)(cfg, upstreamPath, {\n method: \"GET\",\n headers: upstreamHeaders,\n timeoutMs: GATEWAY_TIMEOUT_MS\n });\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[image-proxy] Gateway timeout after ${GATEWAY_TIMEOUT_MS}ms: ${absoluteUrl}`);\n return writeJson(res, 504, { error: \"Upstream timeout\" });\n }\n console.warn(`[image-proxy] Gateway fetch error: ${err.message} (url=${absoluteUrl})`);\n return writeJson(res, 502, { error: \"Bad gateway\" });\n }\n res.statusCode = upstream.status;\n for (const name of PASSTHROUGH_HEADERS) {\n const value = upstream.headers.get(name);\n if (value !== null) {\n res.setHeader(name, value);\n }\n }\n if (upstream.status === 304 || !upstream.body) {\n res.end();\n return;\n }\n try {\n const nodeStream = stream_1.Readable.fromWeb(upstream.body);\n nodeStream.on(\"error\", (err) => {\n console.warn(`[image-proxy] Stream error: ${err.message}`);\n if (!res.writableEnded)\n res.end();\n });\n nodeStream.pipe(res);\n } catch (err) {\n console.warn(`[image-proxy] Pipe setup failed: ${err.message}`);\n if (!res.headersSent) {\n writeJson(res, 502, { error: \"Stream setup failed\" });\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n }\n exports2.handleImageProxy = handleImageProxy;\n }\n});\n\n// dist/adapters/wrappers/node-server.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar http = require(\"http\");\nvar fs2 = require(\"fs\");\nvar path2 = require(\"path\");\nvar image_proxy_1 = require_image_proxy();\nvar MIME_TYPES = {\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".css\": \"text/css\",\n \".html\": \"text/html\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".map\": \"application/json\",\n \".txt\": \"text/plain\",\n \".webp\": \"image/webp\"\n};\nfunction parseQuery(url) {\n const idx = url.indexOf(\"?\");\n if (idx === -1)\n return {};\n const params = {};\n const searchParams = new URLSearchParams(url.slice(idx + 1));\n for (const [key, value] of searchParams) {\n const existing = params[key];\n if (existing === void 0) {\n params[key] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n params[key] = [existing, value];\n }\n }\n return params;\n}\nfunction parseCookies(cookieHeader) {\n if (!cookieHeader)\n return {};\n const cookies = {};\n for (const pair of cookieHeader.split(\";\")) {\n const eqIdx = pair.indexOf(\"=\");\n if (eqIdx === -1)\n continue;\n const name = pair.slice(0, eqIdx).trim();\n const value = pair.slice(eqIdx + 1).trim();\n if (name)\n cookies[name] = value;\n }\n return cookies;\n}\nfunction flattenHeaders(rawHeaders) {\n const headers = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === void 0)\n continue;\n headers[key.toLowerCase()] = Array.isArray(value) ? value.join(\", \") : value;\n }\n return headers;\n}\nasync function readBody(req) {\n if (req.method === \"GET\" || req.method === \"HEAD\")\n return void 0;\n return new Promise((resolve, reject) => {\n const chunks = [];\n req.on(\"data\", (chunk) => chunks.push(chunk));\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\nfunction serveStaticFile(assetsDir, req, res) {\n var _a, _b;\n const urlPath = (_b = (_a = req.url) === null || _a === void 0 ? void 0 : _a.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/\" || !urlPath.startsWith(\"/\"))\n return false;\n const filePath = path2.join(assetsDir, urlPath);\n const normalizedPath = path2.normalize(filePath);\n if (!normalizedPath.startsWith(assetsDir)) {\n res.writeHead(403);\n res.end();\n return true;\n }\n let stat;\n try {\n stat = fs2.statSync(normalizedPath);\n } catch (_c) {\n return false;\n }\n if (!stat.isFile())\n return false;\n const ext = path2.extname(normalizedPath);\n const contentType = MIME_TYPES[ext] || \"application/octet-stream\";\n const isHashedAsset = urlPath.startsWith(\"/_next/static/\");\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Content-Length\": stat.size,\n \"Cache-Control\": isHashedAsset ? \"public, max-age=31536000, immutable\" : \"public, max-age=60\"\n });\n fs2.createReadStream(normalizedPath).pipe(res);\n return true;\n}\nfunction bridgeOpenNextHandler(handler) {\n return async (req, res) => {\n var _a, _b, _c, _d, _e, _f;\n try {\n const rawUrl = req.url || \"/\";\n const headers = flattenHeaders(req.headers);\n const body = await readBody(req);\n const host = headers[\"host\"] || `localhost:${(_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\"}`;\n const proto = ((_c = (_b = headers[\"x-forwarded-proto\"]) === null || _b === void 0 ? void 0 : _b.split(\",\")[0]) === null || _c === void 0 ? void 0 : _c.trim()) || \"http\";\n const absoluteUrl = new URL(`${proto}://${host}${rawUrl}`);\n const event = {\n type: \"core\",\n method: req.method || \"GET\",\n rawPath: absoluteUrl.pathname,\n url: absoluteUrl.href,\n body,\n headers,\n query: parseQuery(rawUrl),\n cookies: parseCookies(headers[\"cookie\"]),\n remoteAddress: ((_e = (_d = headers[\"x-forwarded-for\"]) === null || _d === void 0 ? void 0 : _d.split(\",\")[0]) === null || _e === void 0 ? void 0 : _e.trim()) || headers[\"x-real-ip\"] || ((_f = req.socket) === null || _f === void 0 ? void 0 : _f.remoteAddress) || \"127.0.0.1\"\n };\n const abortController = new AbortController();\n res.on(\"close\", () => abortController.abort());\n const streamCreator = {\n writeHeaders(prelude) {\n res.setHeader(\"Set-Cookie\", prelude.cookies);\n res.writeHead(prelude.statusCode, prelude.headers);\n res.flushHeaders();\n return res;\n },\n abortSignal: abortController.signal\n };\n await handler(event, { streamCreator });\n } catch (err) {\n if (!res.headersSent) {\n const isDev = process.env.NODE_ENV !== \"production\";\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"Internal Server Error\",\n ...isDev && { message: err.message, stack: err.stack }\n }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n };\n}\nasync function wrapper(handler) {\n var _a;\n const port = parseInt((_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\", 10);\n const assetsDir = path2.resolve(process.cwd(), \"..\", \"..\", \"assets\");\n if (!fs2.existsSync(assetsDir)) {\n console.warn(`[pcg-node] assets directory not found at ${assetsDir} \\u2014 static file requests will fall through to Next handler`);\n }\n const dispatchToNext = bridgeOpenNextHandler(handler);\n const server = http.createServer(async (req, res) => {\n var _a2, _b;\n const urlPath = (_b = (_a2 = req.url) === null || _a2 === void 0 ? void 0 : _a2.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/__health\") {\n res.writeHead(200, { \"Content-Type\": \"text/plain\" });\n res.end(\"OK\");\n return;\n }\n if (urlPath === \"/_next/image\") {\n try {\n await (0, image_proxy_1.handleImageProxy)(req, res);\n } catch (err) {\n console.error(\"[pcg-node] image-proxy error:\", err);\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Image proxy failed\" }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n return;\n }\n if (serveStaticFile(assetsDir, req, res))\n return;\n await dispatchToNext(req, res);\n });\n let shuttingDown = false;\n const shutdown = (signal) => {\n if (shuttingDown)\n return;\n shuttingDown = true;\n console.log(`[pcg-node] ${signal} received, shutting down...`);\n server.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 5e3).unref();\n };\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n await new Promise((resolve) => {\n server.listen(port, () => {\n console.log(`[pcg-node] Listening on port ${port}`);\n console.log(`[pcg-node] assets: ${assetsDir}`);\n console.log(`[pcg-node] routes: /__health, /_next/image, /_next/static/*, <next>`);\n resolve();\n });\n });\n}\nvar wrapperDef = {\n wrapper,\n name: \"pcg-node\",\n supportStreaming: true\n};\nexports.default = wrapperDef;\n",
|
|
3
|
+
"adapters/wrappers/node-server.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod2) => function __require() {\n return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/runtime/image-config.js\nvar require_image_config = __commonJS({\n \"dist/runtime/image-config.js\"(exports, module) {\n \"use strict\";\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports._setMatcherForTests = exports._resetImageConfigCacheForTests = exports.validateImageUrl = void 0;\n var fs = require(\"fs\");\n var path = require(\"path\");\n var cachedConfig;\n var cachedMatcher;\n var warnedMatcherMissing = false;\n function configFilePath() {\n return path.resolve(process.cwd(), \".next\", \"required-server-files.json\");\n }\n function loadImageConfig() {\n var _a, _b, _c;\n if (cachedConfig !== void 0)\n return cachedConfig;\n const filePath = configFilePath();\n let raw;\n try {\n raw = fs.readFileSync(filePath, \"utf-8\");\n } catch (err) {\n console.warn(`[image-config] required-server-files.json not found at ${filePath} \\u2014 allowing all image URLs (${(_a = err.code) !== null && _a !== void 0 ? _a : err.message})`);\n cachedConfig = { mode: \"config-missing\" };\n return cachedConfig;\n }\n try {\n const parsed = JSON.parse(raw);\n const images = (_c = (_b = parsed === null || parsed === void 0 ? void 0 : parsed.config) === null || _b === void 0 ? void 0 : _b.images) !== null && _c !== void 0 ? _c : {};\n cachedConfig = {\n mode: \"loaded\",\n images: {\n remotePatterns: Array.isArray(images.remotePatterns) ? images.remotePatterns : [],\n domains: Array.isArray(images.domains) ? images.domains : [],\n unoptimized: images.unoptimized === true\n }\n };\n return cachedConfig;\n } catch (err) {\n console.warn(`[image-config] failed to parse ${filePath}: ${err.message} \\u2014 allowing all image URLs`);\n cachedConfig = { mode: \"config-missing\" };\n return cachedConfig;\n }\n }\n function loadMatcher() {\n if (cachedMatcher !== void 0)\n return cachedMatcher;\n try {\n const dynamicRequire = eval(\"require\");\n const mod = dynamicRequire(\"next/dist/shared/lib/match-remote-pattern\");\n const hasRemoteMatch = mod === null || mod === void 0 ? void 0 : mod.hasRemoteMatch;\n if (typeof hasRemoteMatch !== \"function\") {\n throw new Error(\"hasRemoteMatch not exported\");\n }\n cachedMatcher = hasRemoteMatch;\n return cachedMatcher;\n } catch (err) {\n if (!warnedMatcherMissing) {\n warnedMatcherMissing = true;\n console.warn(`[image-config] cannot load next/dist/shared/lib/match-remote-pattern (${err.message}) \\u2014 falling back to deny-external-only mode`);\n }\n cachedMatcher = null;\n return null;\n }\n }\n function validateImageUrl(absoluteUrl, hostHeader) {\n const cfg = loadImageConfig();\n if (cfg.mode === \"config-missing\") {\n return { ok: true, reason: \"config-missing\" };\n }\n const { images } = cfg;\n if (images.unoptimized) {\n return { ok: true, reason: \"unoptimized\" };\n }\n const reqHost = hostHeader.toLowerCase();\n const urlHost = absoluteUrl.host.toLowerCase();\n if (reqHost && reqHost === urlHost) {\n return { ok: true, reason: \"same-origin\" };\n }\n const matcher = loadMatcher();\n if (matcher === null) {\n return { ok: false, reason: \"matcher-unavailable\" };\n }\n if (matcher(images.domains, images.remotePatterns, absoluteUrl)) {\n return { ok: true, reason: \"pattern-match\" };\n }\n return { ok: false, reason: \"remote-pattern-not-matched\" };\n }\n exports.validateImageUrl = validateImageUrl;\n function _resetImageConfigCacheForTests() {\n cachedConfig = void 0;\n cachedMatcher = void 0;\n warnedMatcherMissing = false;\n }\n exports._resetImageConfigCacheForTests = _resetImageConfigCacheForTests;\n function _setMatcherForTests(impl) {\n cachedMatcher = impl;\n }\n exports._setMatcherForTests = _setMatcherForTests;\n }\n});\n\n// dist/runtime/image-proxy.js\nvar require_image_proxy = __commonJS({\n \"dist/runtime/image-proxy.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.handleImageProxy = void 0;\n var stream_1 = require(\"stream\");\n var gateway_auth_1 = require_gateway_auth();\n var image_config_1 = require_image_config();\n var GATEWAY_TIMEOUT_MS = 1e4;\n var PASSTHROUGH_HEADERS = [\n \"content-type\",\n \"content-length\",\n \"cache-control\",\n \"etag\",\n \"vary\",\n \"last-modified\",\n \"content-security-policy\"\n ];\n function resolveAbsoluteUrl(rawUrl, req) {\n if (rawUrl.startsWith(\"http://\") || rawUrl.startsWith(\"https://\")) {\n return rawUrl;\n }\n const host = req.headers[\"host\"];\n if (!host)\n return null;\n const protoHeader = req.headers[\"x-forwarded-proto\"];\n const proto = (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || (Array.isArray(protoHeader) ? protoHeader[0] : protoHeader) || \"https\";\n const path3 = rawUrl.startsWith(\"/\") ? rawUrl : `/${rawUrl}`;\n return `${proto}://${host}${path3}`;\n }\n function writeJson(res, status, body) {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.end(JSON.stringify(body));\n }\n async function handleImageProxy(req, res) {\n const reqUrl = req.url || \"\";\n const qIdx = reqUrl.indexOf(\"?\");\n if (qIdx === -1) {\n return writeJson(res, 400, { error: \"Missing query parameters\" });\n }\n const params = new URLSearchParams(reqUrl.slice(qIdx + 1));\n const rawUrl = params.get(\"url\");\n const w = params.get(\"w\");\n const q = params.get(\"q\");\n if (!rawUrl || !w) {\n return writeJson(res, 400, {\n error: \"Missing required parameters: url, w\"\n });\n }\n const absoluteUrl = resolveAbsoluteUrl(rawUrl, req);\n if (!absoluteUrl) {\n return writeJson(res, 500, {\n error: \"Cannot resolve absolute URL: missing Host header\"\n });\n }\n let parsedUrl;\n try {\n parsedUrl = new URL(absoluteUrl);\n } catch (_a) {\n return writeJson(res, 400, { error: \"Invalid url parameter\" });\n }\n const hostHeader = req.headers[\"host\"] || \"\";\n const verdict = (0, image_config_1.validateImageUrl)(parsedUrl, hostHeader);\n if (!verdict.ok) {\n return writeJson(res, 400, { error: \"url not allowed\" });\n }\n const cfg = (0, gateway_auth_1.loadGatewayAuthConfig)();\n if (!cfg) {\n return writeJson(res, 500, {\n error: \"Gateway auth config missing\"\n });\n }\n const upstreamParams = new URLSearchParams({ url: absoluteUrl, w });\n if (q)\n upstreamParams.set(\"q\", q);\n const upstreamPath = `/image/optimize?${upstreamParams}`;\n const ifNoneMatch = req.headers[\"if-none-match\"];\n const upstreamHeaders = {};\n if (typeof ifNoneMatch === \"string\") {\n upstreamHeaders[\"if-none-match\"] = ifNoneMatch;\n }\n const accept = req.headers[\"accept\"];\n if (typeof accept === \"string\") {\n upstreamHeaders[\"accept\"] = accept;\n }\n let upstream;\n try {\n upstream = await (0, gateway_auth_1.gatewayFetch)(cfg, upstreamPath, {\n method: \"GET\",\n headers: upstreamHeaders,\n timeoutMs: GATEWAY_TIMEOUT_MS\n });\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[image-proxy] Gateway timeout after ${GATEWAY_TIMEOUT_MS}ms: ${absoluteUrl}`);\n return writeJson(res, 504, { error: \"Upstream timeout\" });\n }\n console.warn(`[image-proxy] Gateway fetch error: ${err.message} (url=${absoluteUrl})`);\n return writeJson(res, 502, { error: \"Bad gateway\" });\n }\n res.statusCode = upstream.status;\n for (const name of PASSTHROUGH_HEADERS) {\n const value = upstream.headers.get(name);\n if (value !== null) {\n res.setHeader(name, value);\n }\n }\n if (upstream.status === 304 || !upstream.body) {\n res.end();\n return;\n }\n try {\n const nodeStream = stream_1.Readable.fromWeb(upstream.body);\n nodeStream.on(\"error\", (err) => {\n console.warn(`[image-proxy] Stream error: ${err.message}`);\n if (!res.writableEnded)\n res.end();\n });\n nodeStream.pipe(res);\n } catch (err) {\n console.warn(`[image-proxy] Pipe setup failed: ${err.message}`);\n if (!res.headersSent) {\n writeJson(res, 502, { error: \"Stream setup failed\" });\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n }\n exports2.handleImageProxy = handleImageProxy;\n }\n});\n\n// dist/runtime/edge-context.js\nvar require_edge_context = __commonJS({\n \"dist/runtime/edge-context.js\"(exports2) {\n \"use strict\";\n var _a;\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.getEdgeContext = exports2.runWithEdgeContext = exports2.buildEdgeContextFromHeaders = void 0;\n var node_async_hooks_1 = require(\"node:async_hooks\");\n var ALS_KEY = Symbol.for(\"pcg.edgeContext.als\");\n var globalRef = globalThis;\n var storage = (_a = globalRef[ALS_KEY]) !== null && _a !== void 0 ? _a : globalRef[ALS_KEY] = new node_async_hooks_1.AsyncLocalStorage();\n var SITE_ID_HEADER = \"x-alicdn-site-id\";\n var HOSTNAME_HEADER = \"host\";\n var FORWARDED_HOSTNAME_HEADER = \"x-forwarded-host\";\n function pickHeader(headers, name) {\n var _a2;\n return (_a2 = headers[name]) !== null && _a2 !== void 0 ? _a2 : headers[name.toLowerCase()];\n }\n function parseHostname(raw) {\n var _a2;\n if (!raw)\n return void 0;\n const first = (_a2 = raw.split(\",\")[0]) === null || _a2 === void 0 ? void 0 : _a2.trim();\n return first || void 0;\n }\n function parseSiteId(raw) {\n if (!raw)\n return void 0;\n const trimmed = raw.trim();\n if (!trimmed)\n return void 0;\n const n = Number(trimmed);\n return Number.isFinite(n) && trimmed === String(n) ? n : trimmed;\n }\n function buildEdgeContextFromHeaders(headers) {\n var _a2;\n const ctx = {};\n const siteId = parseSiteId(pickHeader(headers, SITE_ID_HEADER));\n if (siteId !== void 0)\n ctx.siteId = siteId;\n const hostname = (_a2 = parseHostname(pickHeader(headers, HOSTNAME_HEADER))) !== null && _a2 !== void 0 ? _a2 : parseHostname(pickHeader(headers, FORWARDED_HOSTNAME_HEADER));\n if (hostname)\n ctx.hostname = hostname;\n return ctx;\n }\n exports2.buildEdgeContextFromHeaders = buildEdgeContextFromHeaders;\n function runWithEdgeContext(headers, fn) {\n const ctx = buildEdgeContextFromHeaders(headers);\n return storage.run(ctx, fn);\n }\n exports2.runWithEdgeContext = runWithEdgeContext;\n function getEdgeContext() {\n var _a2;\n return (_a2 = storage.getStore()) !== null && _a2 !== void 0 ? _a2 : {};\n }\n exports2.getEdgeContext = getEdgeContext;\n }\n});\n\n// dist/adapters/wrappers/node-server.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar http = require(\"http\");\nvar fs2 = require(\"fs\");\nvar path2 = require(\"path\");\nvar image_proxy_1 = require_image_proxy();\nvar edge_context_1 = require_edge_context();\nvar MIME_TYPES = {\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".css\": \"text/css\",\n \".html\": \"text/html\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".map\": \"application/json\",\n \".txt\": \"text/plain\",\n \".webp\": \"image/webp\"\n};\nfunction parseQuery(url) {\n const idx = url.indexOf(\"?\");\n if (idx === -1)\n return {};\n const params = {};\n const searchParams = new URLSearchParams(url.slice(idx + 1));\n for (const [key, value] of searchParams) {\n const existing = params[key];\n if (existing === void 0) {\n params[key] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n params[key] = [existing, value];\n }\n }\n return params;\n}\nfunction parseCookies(cookieHeader) {\n if (!cookieHeader)\n return {};\n const cookies = {};\n for (const pair of cookieHeader.split(\";\")) {\n const eqIdx = pair.indexOf(\"=\");\n if (eqIdx === -1)\n continue;\n const name = pair.slice(0, eqIdx).trim();\n const value = pair.slice(eqIdx + 1).trim();\n if (name)\n cookies[name] = value;\n }\n return cookies;\n}\nfunction flattenHeaders(rawHeaders) {\n const headers = {};\n for (const [key, value] of Object.entries(rawHeaders)) {\n if (value === void 0)\n continue;\n headers[key.toLowerCase()] = Array.isArray(value) ? value.join(\", \") : value;\n }\n return headers;\n}\nasync function readBody(req) {\n if (req.method === \"GET\" || req.method === \"HEAD\")\n return void 0;\n return new Promise((resolve, reject) => {\n const chunks = [];\n req.on(\"data\", (chunk) => chunks.push(chunk));\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\nfunction serveStaticFile(assetsDir, req, res) {\n var _a, _b;\n const urlPath = (_b = (_a = req.url) === null || _a === void 0 ? void 0 : _a.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/\" || !urlPath.startsWith(\"/\"))\n return false;\n const filePath = path2.join(assetsDir, urlPath);\n const normalizedPath = path2.normalize(filePath);\n if (!normalizedPath.startsWith(assetsDir)) {\n res.writeHead(403);\n res.end();\n return true;\n }\n let stat;\n try {\n stat = fs2.statSync(normalizedPath);\n } catch (_c) {\n return false;\n }\n if (!stat.isFile())\n return false;\n const ext = path2.extname(normalizedPath);\n const contentType = MIME_TYPES[ext] || \"application/octet-stream\";\n const isHashedAsset = urlPath.startsWith(\"/_next/static/\");\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Content-Length\": stat.size,\n \"Cache-Control\": isHashedAsset ? \"public, max-age=31536000, immutable\" : \"public, max-age=60\"\n });\n fs2.createReadStream(normalizedPath).pipe(res);\n return true;\n}\nfunction bridgeOpenNextHandler(handler) {\n return async (req, res) => {\n var _a, _b, _c, _d, _e, _f;\n try {\n const rawUrl = req.url || \"/\";\n const headers = flattenHeaders(req.headers);\n const body = await readBody(req);\n const host = headers[\"host\"] || `localhost:${(_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\"}`;\n const proto = ((_c = (_b = headers[\"x-forwarded-proto\"]) === null || _b === void 0 ? void 0 : _b.split(\",\")[0]) === null || _c === void 0 ? void 0 : _c.trim()) || \"http\";\n const absoluteUrl = new URL(`${proto}://${host}${rawUrl}`);\n const event = {\n type: \"core\",\n method: req.method || \"GET\",\n rawPath: absoluteUrl.pathname,\n url: absoluteUrl.href,\n body,\n headers,\n query: parseQuery(rawUrl),\n cookies: parseCookies(headers[\"cookie\"]),\n remoteAddress: ((_e = (_d = headers[\"x-forwarded-for\"]) === null || _d === void 0 ? void 0 : _d.split(\",\")[0]) === null || _e === void 0 ? void 0 : _e.trim()) || headers[\"x-real-ip\"] || ((_f = req.socket) === null || _f === void 0 ? void 0 : _f.remoteAddress) || \"127.0.0.1\"\n };\n const abortController = new AbortController();\n res.on(\"close\", () => abortController.abort());\n const streamCreator = {\n writeHeaders(prelude) {\n res.setHeader(\"Set-Cookie\", prelude.cookies);\n res.writeHead(prelude.statusCode, prelude.headers);\n res.flushHeaders();\n return res;\n },\n abortSignal: abortController.signal\n };\n await (0, edge_context_1.runWithEdgeContext)(headers, () => handler(event, { streamCreator }));\n } catch (err) {\n if (!res.headersSent) {\n const isDev = process.env.NODE_ENV !== \"production\";\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"Internal Server Error\",\n ...isDev && { message: err.message, stack: err.stack }\n }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n };\n}\nasync function wrapper(handler) {\n var _a;\n const port = parseInt((_a = process.env.PORT) !== null && _a !== void 0 ? _a : \"3000\", 10);\n const assetsDir = path2.resolve(process.cwd(), \"..\", \"..\", \"assets\");\n if (!fs2.existsSync(assetsDir)) {\n console.warn(`[pcg-node] assets directory not found at ${assetsDir} \\u2014 static file requests will fall through to Next handler`);\n }\n const dispatchToNext = bridgeOpenNextHandler(handler);\n const server = http.createServer(async (req, res) => {\n var _a2, _b;\n const urlPath = (_b = (_a2 = req.url) === null || _a2 === void 0 ? void 0 : _a2.split(\"?\")[0]) !== null && _b !== void 0 ? _b : \"/\";\n if (urlPath === \"/__health\") {\n res.writeHead(200, { \"Content-Type\": \"text/plain\" });\n res.end(\"OK\");\n return;\n }\n if (urlPath === \"/_next/image\") {\n try {\n await (0, image_proxy_1.handleImageProxy)(req, res);\n } catch (err) {\n console.error(\"[pcg-node] image-proxy error:\", err);\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Image proxy failed\" }));\n } else if (!res.writableEnded) {\n res.end();\n }\n }\n return;\n }\n if (serveStaticFile(assetsDir, req, res))\n return;\n await dispatchToNext(req, res);\n });\n let shuttingDown = false;\n const shutdown = (signal) => {\n if (shuttingDown)\n return;\n shuttingDown = true;\n console.log(`[pcg-node] ${signal} received, shutting down...`);\n server.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 5e3).unref();\n };\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\"));\n await new Promise((resolve) => {\n server.listen(port, () => {\n console.log(`[pcg-node] Listening on port ${port}`);\n console.log(`[pcg-node] assets: ${assetsDir}`);\n console.log(`[pcg-node] routes: /__health, /_next/image, /_next/static/*, <next>`);\n resolve();\n });\n });\n}\nvar wrapperDef = {\n wrapper,\n name: \"pcg-node\",\n supportStreaming: true\n};\nexports.default = wrapperDef;\n",
|
|
4
4
|
"adapters/converters/passthrough.js": "\"use strict\";\n\n// dist/adapters/converters/passthrough.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar converter = {\n convertFrom: async (event) => event,\n convertTo: async (result) => result,\n name: \"passthrough\"\n};\nexports.default = converter;\n",
|
|
5
5
|
"overrides/incrementalCache/gateway.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// dist/_protocol/types.js\nvar require_types = __commonJS({\n \"dist/_protocol/types.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n }\n});\n\n// dist/_protocol/keys.js\nvar require_keys = __commonJS({\n \"dist/_protocol/keys.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.buildPageMetadataKey = exports2.buildTagKey = exports2.buildStaticAssetKey = exports2.buildOssKey = void 0;\n function stripLeadingSlash(s) {\n return s.replace(/^\\/+/, \"\");\n }\n function buildOssKey(params) {\n const { appId, buildId, cacheType = \"cache\" } = params;\n const key = stripLeadingSlash(params.key);\n if (cacheType === \"fetch\") {\n return `${appId}/__fetch/${buildId}/${key}`;\n }\n return `${appId}/${buildId}/${key}.cache`;\n }\n exports2.buildOssKey = buildOssKey;\n function buildStaticAssetKey(params) {\n const p = stripLeadingSlash(params.path);\n return `${params.appId}/_next/static/${p}`;\n }\n exports2.buildStaticAssetKey = buildStaticAssetKey;\n function buildTagKey(params) {\n return {\n app_id: params.appId,\n tag: `${params.buildId}/${params.tag}`,\n path: `${params.buildId}/${params.path}`\n };\n }\n exports2.buildTagKey = buildTagKey;\n function buildPageMetadataKey(params) {\n return {\n app_id: params.appId,\n url: params.url\n };\n }\n exports2.buildPageMetadataKey = buildPageMetadataKey;\n }\n});\n\n// dist/_protocol/endpoints.js\nvar require_endpoints = __commonJS({\n \"dist/_protocol/endpoints.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.buildCentralEndpoints = void 0;\n function stripTrailingSlashes(s) {\n return s.replace(/\\/+$/, \"\");\n }\n function buildCentralEndpoints(base) {\n const b = stripTrailingSlashes(base);\n return {\n base: b,\n cache: `${b}/cache`,\n cacheRefresh: `${b}/cache/refresh`,\n revalidateTag: `${b}/revalidate/tag`,\n revalidatePath: `${b}/revalidate/path`,\n tagByTag: `${b}/tag/by-tag`,\n tagByPath: `${b}/tag/by-path`,\n tagLastModified: `${b}/tag/last-modified`,\n tagWrite: `${b}/tag/write`,\n deploySts: `${b}/deploy/sts-token`,\n deployTags: `${b}/deploy/tags`\n };\n }\n exports2.buildCentralEndpoints = buildCentralEndpoints;\n }\n});\n\n// dist/_protocol/index.js\nvar require_protocol = __commonJS({\n \"dist/_protocol/index.js\"(exports2) {\n \"use strict\";\n var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {\n if (k2 === void 0) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() {\n return m[k];\n } };\n }\n Object.defineProperty(o, k2, desc);\n } : function(o, m, k, k2) {\n if (k2 === void 0) k2 = k;\n o[k2] = m[k];\n });\n var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);\n };\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n __exportStar(require_types(), exports2);\n __exportStar(require_keys(), exports2);\n __exportStar(require_endpoints(), exports2);\n }\n});\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/overrides/incrementalCache/gateway.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar protocol_1 = require_protocol();\nvar gateway_auth_1 = require_gateway_auth();\nvar GET_TIMEOUT = 5e3;\nvar SET_TIMEOUT = 1e4;\nvar DELETE_TIMEOUT = 5e3;\nfunction buildKey(config, key, isFetch) {\n return (0, protocol_1.buildOssKey)({\n appId: `${config.aliuid}/${config.routinename}`,\n buildId: config.version,\n key,\n cacheType: isFetch ? \"fetch\" : \"cache\"\n });\n}\nvar GatewayIncrementalCache = class {\n constructor() {\n this.name = \"gateway-incremental-cache\";\n this.config = null;\n this.configLoaded = false;\n }\n /**\n * 延迟加载配置,避免在构造函数中因环境变量缺失而阻塞 Function 启动。\n */\n getConfig() {\n if (!this.configLoaded) {\n this.config = (0, gateway_auth_1.loadGatewayAuthConfig)();\n this.configLoaded = true;\n }\n return this.config;\n }\n /**\n * 从 Gateway 读取缓存。\n */\n async get(key, isFetch) {\n const config = this.getConfig();\n if (!config)\n return null;\n const ossKey = buildKey(config, key, isFetch);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, `/storage/${ossKey}`, {\n method: \"GET\",\n timeoutMs: GET_TIMEOUT\n });\n if (res.status === 404)\n return null;\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[incrementalCache] GET \\u88AB\\u62D2\\u7EDD: key=\"${ossKey}\" (${res.status})\\uFF0C\\u8BF7\\u68C0\\u67E5\\u7B7E\\u540D secret \\u6216 key \\u524D\\u7F00`);\n } else {\n console.warn(`[incrementalCache] GET \\u5931\\u8D25: key=\"${ossKey}\", \\u72B6\\u6001\\u7801=${res.status}`);\n }\n return null;\n }\n const body = await res.text();\n let envelope;\n try {\n envelope = JSON.parse(body);\n } catch (_a) {\n console.warn(`[incrementalCache] JSON \\u89E3\\u6790\\u5931\\u8D25: key=\"${ossKey}\"`);\n return null;\n }\n if (!envelope || typeof envelope !== \"object\" || typeof envelope.lastModified !== \"number\") {\n console.warn(`[incrementalCache] envelope \\u683C\\u5F0F\\u5F02\\u5E38\\u6216\\u7F3A lastModified: key=\"${ossKey}\"`);\n return null;\n }\n return { value: envelope.value, lastModified: envelope.lastModified };\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[incrementalCache] GET \\u8D85\\u65F6: key=\"${ossKey}\" (${GET_TIMEOUT}ms)`);\n } else {\n console.warn(`[incrementalCache] GET \\u5F02\\u5E38: key=\"${ossKey}\", ${err.message}`);\n }\n return null;\n }\n }\n /**\n * 向 Gateway 写入缓存。\n */\n async set(key, value, isFetch) {\n const config = this.getConfig();\n if (!config)\n return;\n const ossKey = buildKey(config, key, isFetch);\n const body = JSON.stringify({ lastModified: Date.now(), value });\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, `/storage/${ossKey}`, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n timeoutMs: SET_TIMEOUT\n });\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[incrementalCache] PUT \\u88AB\\u62D2\\u7EDD: key=\"${ossKey}\" (${res.status})\\uFF0C\\u8BF7\\u68C0\\u67E5\\u7B7E\\u540D secret \\u6216 key \\u524D\\u7F00`);\n } else {\n console.warn(`[incrementalCache] PUT \\u5931\\u8D25: key=\"${ossKey}\", \\u72B6\\u6001\\u7801=${res.status}`);\n }\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[incrementalCache] PUT \\u8D85\\u65F6: key=\"${ossKey}\" (${SET_TIMEOUT}ms)`);\n } else {\n console.warn(`[incrementalCache] PUT \\u5F02\\u5E38: key=\"${ossKey}\", ${err.message}`);\n }\n }\n }\n /**\n * 通过 Gateway 删除缓存。\n */\n async delete(key, isFetch) {\n const config = this.getConfig();\n if (!config)\n return;\n const ossKey = buildKey(config, key, isFetch);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, `/storage/${ossKey}`, {\n method: \"DELETE\",\n timeoutMs: DELETE_TIMEOUT\n });\n if (res.status === 404)\n return;\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[incrementalCache] DELETE \\u88AB\\u62D2\\u7EDD: key=\"${ossKey}\" (${res.status})\\uFF0C\\u8BF7\\u68C0\\u67E5\\u7B7E\\u540D secret \\u6216 key \\u524D\\u7F00`);\n } else {\n console.warn(`[incrementalCache] DELETE \\u5931\\u8D25: key=\"${ossKey}\", \\u72B6\\u6001\\u7801=${res.status}`);\n }\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[incrementalCache] DELETE \\u8D85\\u65F6: key=\"${ossKey}\" (${DELETE_TIMEOUT}ms)`);\n } else {\n console.warn(`[incrementalCache] DELETE \\u5F02\\u5E38: key=\"${ossKey}\", ${err.message}`);\n }\n }\n }\n};\nexports.default = GatewayIncrementalCache;\n",
|
|
6
|
-
"overrides/tagCache/gateway.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/runtime/cdn-purge.js\nvar require_cdn_purge = __commonJS({\n \"dist/runtime/cdn-purge.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.createCdnPurgeClient = exports2.loadCdnPurgeConfig = void 0;\n var fs = require(\"fs\");\n var path = require(\"path\");\n var gateway_auth_12 = require_gateway_auth();\n var REFRESH_TIMEOUT_MS = 15e3;\n var URL_BATCH_SIZE = 100;\n var REFRESH_CONCURRENCY = 4;\n var TAG_MANIFEST_FILENAME = \"__pcg_tag_manifest.json\";\n function stripLeadingSlash2(s) {\n return s.replace(/^\\/+/, \"\");\n }\n function ensureLeadingSlash(s) {\n return s.startsWith(\"/\") ? s : `/${s}`;\n }\n function loadCdnPurgeConfig() {\n const base = (0, gateway_auth_12.loadGatewayAuthConfig)();\n if (!base)\n return null;\n const hostname = process.env.ESA_CACHE_GW_HOSTNAME;\n const siteIdRaw = process.env.ESA_CACHE_GW_SITE_ID;\n if (!hostname || !siteIdRaw) {\n return null;\n }\n const siteIdNum = Number(siteIdRaw);\n const siteId = Number.isFinite(siteIdNum) ? siteIdNum : siteIdRaw;\n return {\n ...base,\n hostname,\n siteId\n };\n }\n exports2.loadCdnPurgeConfig = loadCdnPurgeConfig;\n function createCdnPurgeClient(cfg) {\n var _a;\n const buildId = cfg.version;\n const pathPrefix = `${buildId}/`;\n const manifestPath = (_a = cfg.manifestPath) !== null && _a !== void 0 ? _a : path.join(__dirname, TAG_MANIFEST_FILENAME);\n let manifestPromise = null;\n async function loadManifest() {\n if (manifestPromise)\n return manifestPromise;\n manifestPromise = (async () => {\n var _a2, _b, _c, _d;\n const map = /* @__PURE__ */ new Map();\n let raw;\n try {\n raw = await fs.promises.readFile(manifestPath, \"utf-8\");\n } catch (err) {\n if ((err === null || err === void 0 ? void 0 : err.code) !== \"ENOENT\") {\n console.warn(`[cdn-purge] manifest read error ${manifestPath}: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n return /* @__PURE__ */ new Map();\n }\n let rows;\n try {\n const parsed = JSON.parse(raw);\n rows = Array.isArray(parsed) ? parsed : [];\n } catch (err) {\n console.warn(`[cdn-purge] manifest parse error ${manifestPath}: ${(_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err}`);\n return /* @__PURE__ */ new Map();\n }\n for (const row of rows) {\n const tagPk = (_c = row === null || row === void 0 ? void 0 : row.tag) === null || _c === void 0 ? void 0 : _c.S;\n const pathPk = (_d = row === null || row === void 0 ? void 0 : row.path) === null || _d === void 0 ? void 0 : _d.S;\n if (typeof tagPk !== \"string\" || typeof pathPk !== \"string\")\n continue;\n if (!tagPk.startsWith(pathPrefix))\n continue;\n if (!pathPk.startsWith(pathPrefix))\n continue;\n const tag = tagPk.slice(pathPrefix.length);\n const p = pathPk.slice(pathPrefix.length);\n if (!tag || !p)\n continue;\n let bucket = map.get(tag);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n map.set(tag, bucket);\n }\n bucket.add(p);\n }\n const result = /* @__PURE__ */ new Map();\n for (const [tag, set] of map) {\n result.set(tag, Array.from(set));\n }\n return result;\n })();\n return manifestPromise;\n }\n function expandPathsToUrls(paths) {\n const normalized = /* @__PURE__ */ new Set();\n for (const p of paths) {\n if (!p)\n continue;\n normalized.add(ensureLeadingSlash(p));\n }\n if (normalized.size === 0)\n return [];\n const urls = /* @__PURE__ */ new Set();\n for (const p of normalized) {\n urls.add(`https://${cfg.hostname}${p}`);\n const rel = stripLeadingSlash2(p);\n urls.add(`https://${cfg.hostname}/_next/data/${buildId}/${rel || \"index\"}.json`);\n }\n return Array.from(urls);\n }\n async function refreshBatch(urls) {\n var _a2;\n const body = {\n hostname: cfg.hostname,\n siteId: cfg.siteId,\n urls\n };\n let res;\n try {\n res = await (0, gateway_auth_12.gatewayFetch)(cfg, \"/cache/refresh\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n timeoutMs: REFRESH_TIMEOUT_MS\n });\n } catch (err) {\n console.warn(`[cdn-purge] cache/refresh error (${urls.length} urls): ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n return;\n }\n if (!res.ok) {\n let detail = \"\";\n try {\n detail = (await res.text()).slice(0, 200);\n } catch (_b) {\n }\n console.warn(`[cdn-purge] cache/refresh failed status=${res.status} urls=${urls.length} ${detail}`);\n }\n }\n async function refreshUrls(allUrls) {\n if (allUrls.length === 0)\n return;\n const batches = [];\n for (let i = 0; i < allUrls.length; i += URL_BATCH_SIZE) {\n batches.push(allUrls.slice(i, i + URL_BATCH_SIZE));\n }\n let cursor = 0;\n async function worker() {\n while (cursor < batches.length) {\n const idx = cursor++;\n await refreshBatch(batches[idx]);\n }\n }\n const workers = Array.from({ length: Math.min(REFRESH_CONCURRENCY, batches.length) }, () => worker());\n await Promise.all(workers);\n }\n async function purgeByPaths(paths) {\n var _a2;\n try {\n const urls = expandPathsToUrls(paths);\n await refreshUrls(urls);\n } catch (err) {\n console.warn(`[cdn-purge] purgeByPaths error: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n }\n async function purgeByTags(tags) {\n var _a2;\n try {\n const uniqueTags = Array.from(new Set(tags.map((t) => typeof t === \"string\" ? t : \"\").map((t) => t.trim()).filter(Boolean)));\n if (uniqueTags.length === 0)\n return;\n const map = await loadManifest();\n const merged = /* @__PURE__ */ new Set();\n for (const t of uniqueTags) {\n const paths = map.get(t);\n if (!paths)\n continue;\n for (const p of paths)\n merged.add(p);\n }\n if (merged.size === 0)\n return;\n const urls = expandPathsToUrls(Array.from(merged));\n await refreshUrls(urls);\n } catch (err) {\n console.warn(`[cdn-purge] purgeByTags error: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n }\n return { purgeByPaths, purgeByTags };\n }\n exports2.createCdnPurgeClient = createCdnPurgeClient;\n }\n});\n\n// dist/overrides/tagCache/gateway.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar gateway_auth_1 = require_gateway_auth();\nvar cdn_purge_1 = require_cdn_purge();\nvar QUERY_TIMEOUT = 3e3;\nvar WRITE_TIMEOUT = 5e3;\nvar BATCH_SIZE = 200;\nfunction stripLeadingSlash(s) {\n return s.replace(/^\\/+/, \"\");\n}\nvar GatewayTagCache = class {\n constructor() {\n this.name = \"gateway-tag-cache\";\n this.mode = \"nextMode\";\n this.config = null;\n this.configLoaded = false;\n this.purgeClient = null;\n this.purgeClientLoaded = false;\n }\n getConfig() {\n if (!this.configLoaded) {\n this.config = (0, gateway_auth_1.loadGatewayAuthConfig)();\n this.configLoaded = true;\n }\n return this.config;\n }\n getPurgeClient() {\n if (!this.purgeClientLoaded) {\n const cfg = (0, cdn_purge_1.loadCdnPurgeConfig)();\n this.purgeClient = cfg ? (0, cdn_purge_1.createCdnPurgeClient)(cfg) : null;\n this.purgeClientLoaded = true;\n }\n return this.purgeClient;\n }\n buildTagKey(tag) {\n const config = this.getConfig();\n if (!config)\n return tag;\n return `${config.version}/${stripLeadingSlash(tag)}`;\n }\n async getLastRevalidated(tags) {\n const config = this.getConfig();\n if (!config)\n return 0;\n try {\n const rows = await this.batchGetTags(config, tags);\n let maxRevalidatedAt = 0;\n for (const row of rows) {\n if (row.revalidatedAt && row.revalidatedAt > maxRevalidatedAt) {\n maxRevalidatedAt = row.revalidatedAt;\n }\n }\n return maxRevalidatedAt;\n } catch (err) {\n console.warn(`[tagCache] getLastRevalidated error: ${err.message}`);\n return 0;\n }\n }\n async hasBeenRevalidated(tags, lastModified) {\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const now = Date.now();\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.expire !== void 0) {\n if (row.expire <= now && row.expire > lm) {\n return true;\n }\n }\n if (row.revalidatedAt !== void 0 && row.revalidatedAt > lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] hasBeenRevalidated error: ${err.message}`);\n return false;\n }\n }\n async isStale(tags, lastModified) {\n var _a;\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.stale === void 0)\n continue;\n const revalidatedAt = (_a = row.revalidatedAt) !== null && _a !== void 0 ? _a : 0;\n if (revalidatedAt > lm && row.stale >= lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] isStale error: ${err.message}`);\n return false;\n }\n }\n async writeTags(tags) {\n if (!tags || tags.length === 0)\n return;\n const config = this.getConfig();\n if (!config)\n return;\n const writeTs = Date.now();\n const rows = tags.map((input) => {\n const tagStr = typeof input === \"string\" ? input : input.tag;\n const stale = typeof input === \"string\" ? void 0 : input.stale;\n const expire = typeof input === \"string\" ? void 0 : input.expire;\n const tagKey = this.buildTagKey(tagStr);\n const columns = [\n { name: \"revalidatedAt\", value: writeTs }\n ];\n if (stale !== void 0) {\n columns.push({ name: \"stale\", value: stale });\n }\n if (expire !== void 0) {\n columns.push({ name: \"expire\", value: expire });\n }\n return {\n primaryKey: [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: tagKey }\n ],\n columns\n };\n });\n await this.batchWrite(config, rows);\n const purgeClient = this.getPurgeClient();\n if (purgeClient) {\n const tagStrs = tags.map((t) => typeof t === \"string\" ? t : t.tag).filter((s) => typeof s === \"string\" && s.length > 0);\n if (tagStrs.length > 0) {\n purgeClient.purgeByTags(tagStrs).catch((err) => {\n var _a;\n console.warn(`[tagCache] purge fan-out failed: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);\n });\n }\n }\n }\n // ---- private methods ----\n async batchGetTags(config, tags) {\n const primaryKeys = tags.map((tag) => [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: this.buildTagKey(tag) }\n ]);\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-get-row\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ primaryKeys }),\n timeoutMs: QUERY_TIMEOUT\n });\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-get-row rejected (${res.status})`);\n } else {\n console.warn(`[tagCache] batch-get-row failed: status=${res.status}`);\n }\n return [];\n }\n const data = await res.json();\n if (!data.rows)\n return [];\n return data.rows.map((row) => {\n var _a;\n const result = {};\n for (const col of (_a = row.columns) !== null && _a !== void 0 ? _a : []) {\n if (col.name === \"revalidatedAt\" && typeof col.value === \"number\") {\n result.revalidatedAt = col.value;\n } else if (col.name === \"stale\" && typeof col.value === \"number\") {\n result.stale = col.value;\n } else if (col.name === \"expire\" && typeof col.value === \"number\") {\n result.expire = col.value;\n }\n }\n return result;\n });\n }\n async batchWrite(config, rows) {\n if (rows.length === 0)\n return;\n for (let i = 0; i < rows.length; i += BATCH_SIZE) {\n const batch = rows.slice(i, i + BATCH_SIZE);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-write\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ rows: batch }),\n timeoutMs: WRITE_TIMEOUT\n });\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-write rejected (${res.status})`);\n return;\n }\n if (!res.ok) {\n console.warn(`[tagCache] batch-write failed: status=${res.status}`);\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[tagCache] batch-write timeout (${WRITE_TIMEOUT}ms)`);\n } else {\n console.warn(`[tagCache] batch-write error: ${err.message}`);\n }\n }\n }\n }\n};\nexports.default = GatewayTagCache;\n",
|
|
6
|
+
"overrides/tagCache/gateway.js": "\"use strict\";\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// dist/runtime/gateway-auth.js\nvar require_gateway_auth = __commonJS({\n \"dist/runtime/gateway-auth.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.gatewayFetch = exports2.signGatewayHeaders = exports2.loadGatewayAuthConfig = void 0;\n var crypto_1 = require(\"crypto\");\n var DEFAULT_TTL_MS = 5 * 60 * 1e3;\n var DEFAULT_TIMEOUT_MS = 5e3;\n function _fetch(input, init) {\n var _a;\n const fn = globalThis.__nextPatched ? (_a = globalThis.__originalFetch) !== null && _a !== void 0 ? _a : globalThis.fetch : globalThis.fetch;\n return fn(input, init);\n }\n function loadGatewayAuthConfig() {\n const gatewayUrl = process.env.ESA_CACHE_GW_GATEWAY_ENDPOINT;\n const secret = process.env.ESA_CACHE_GW_AUTH_KEY;\n const aliuid = process.env.ESA_CACHE_GW_ALIUID;\n const routinename = process.env.ESA_CACHE_GW_ROUTINENAME;\n const version = process.env.ESA_CACHE_GW_VERSION;\n const missing = [];\n if (!gatewayUrl)\n missing.push(\"ESA_CACHE_GW_GATEWAY_ENDPOINT\");\n if (!secret)\n missing.push(\"ESA_CACHE_GW_AUTH_KEY\");\n if (!aliuid)\n missing.push(\"ESA_CACHE_GW_ALIUID\");\n if (!routinename)\n missing.push(\"ESA_CACHE_GW_ROUTINENAME\");\n if (!version)\n missing.push(\"ESA_CACHE_GW_VERSION\");\n if (missing.length > 0) {\n console.error(`[gateway-auth] \\u7F3A\\u5C11\\u5FC5\\u9700\\u7684\\u73AF\\u5883\\u53D8\\u91CF: ${missing.join(\", \")}`);\n return null;\n }\n return {\n gatewayUrl: gatewayUrl.replace(/\\/+$/, \"\"),\n secret,\n aliuid,\n routinename,\n version\n };\n }\n exports2.loadGatewayAuthConfig = loadGatewayAuthConfig;\n function signGatewayHeaders(cfg, ttlMs = DEFAULT_TTL_MS) {\n const expires = String(Date.now() + ttlMs);\n const authKey = cfg.secret;\n const md5Hash = (0, crypto_1.createHash)(\"md5\").update(`${authKey}${expires}${cfg.aliuid}${cfg.routinename}${cfg.version}`).digest(\"hex\");\n return {\n authorization: `${expires}-${md5Hash}`,\n aliuid: cfg.aliuid,\n routinename: cfg.routinename,\n version: cfg.version\n };\n }\n exports2.signGatewayHeaders = signGatewayHeaders;\n async function gatewayFetch(cfg, pathOrUrl, init) {\n var _a, _b;\n const url = pathOrUrl.startsWith(\"/\") ? `${cfg.gatewayUrl}${pathOrUrl}` : pathOrUrl;\n const signed = signGatewayHeaders(cfg);\n const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);\n headers.set(\"Authorization\", signed.authorization);\n headers.set(\"AliUid\", signed.aliuid);\n headers.set(\"RoutineName\", signed.routinename);\n headers.set(\"Version\", signed.version);\n const timeoutMs = (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await _fetch(url, {\n ...init,\n headers,\n signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n }\n exports2.gatewayFetch = gatewayFetch;\n }\n});\n\n// dist/runtime/edge-context.js\nvar require_edge_context = __commonJS({\n \"dist/runtime/edge-context.js\"(exports2) {\n \"use strict\";\n var _a;\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.getEdgeContext = exports2.runWithEdgeContext = exports2.buildEdgeContextFromHeaders = void 0;\n var node_async_hooks_1 = require(\"node:async_hooks\");\n var ALS_KEY = Symbol.for(\"pcg.edgeContext.als\");\n var globalRef = globalThis;\n var storage = (_a = globalRef[ALS_KEY]) !== null && _a !== void 0 ? _a : globalRef[ALS_KEY] = new node_async_hooks_1.AsyncLocalStorage();\n var SITE_ID_HEADER = \"x-alicdn-site-id\";\n var HOSTNAME_HEADER = \"host\";\n var FORWARDED_HOSTNAME_HEADER = \"x-forwarded-host\";\n function pickHeader(headers, name) {\n var _a2;\n return (_a2 = headers[name]) !== null && _a2 !== void 0 ? _a2 : headers[name.toLowerCase()];\n }\n function parseHostname(raw) {\n var _a2;\n if (!raw)\n return void 0;\n const first = (_a2 = raw.split(\",\")[0]) === null || _a2 === void 0 ? void 0 : _a2.trim();\n return first || void 0;\n }\n function parseSiteId(raw) {\n if (!raw)\n return void 0;\n const trimmed = raw.trim();\n if (!trimmed)\n return void 0;\n const n = Number(trimmed);\n return Number.isFinite(n) && trimmed === String(n) ? n : trimmed;\n }\n function buildEdgeContextFromHeaders(headers) {\n var _a2;\n const ctx = {};\n const siteId = parseSiteId(pickHeader(headers, SITE_ID_HEADER));\n if (siteId !== void 0)\n ctx.siteId = siteId;\n const hostname = (_a2 = parseHostname(pickHeader(headers, HOSTNAME_HEADER))) !== null && _a2 !== void 0 ? _a2 : parseHostname(pickHeader(headers, FORWARDED_HOSTNAME_HEADER));\n if (hostname)\n ctx.hostname = hostname;\n return ctx;\n }\n exports2.buildEdgeContextFromHeaders = buildEdgeContextFromHeaders;\n function runWithEdgeContext(headers, fn) {\n const ctx = buildEdgeContextFromHeaders(headers);\n return storage.run(ctx, fn);\n }\n exports2.runWithEdgeContext = runWithEdgeContext;\n function getEdgeContext() {\n var _a2;\n return (_a2 = storage.getStore()) !== null && _a2 !== void 0 ? _a2 : {};\n }\n exports2.getEdgeContext = getEdgeContext;\n }\n});\n\n// dist/runtime/cdn-purge.js\nvar require_cdn_purge = __commonJS({\n \"dist/runtime/cdn-purge.js\"(exports2) {\n \"use strict\";\n Object.defineProperty(exports2, \"__esModule\", { value: true });\n exports2.createCdnPurgeClient = exports2.loadCdnPurgeConfig = void 0;\n var fs = require(\"fs\");\n var path = require(\"path\");\n var gateway_auth_12 = require_gateway_auth();\n var edge_context_1 = require_edge_context();\n var REFRESH_TIMEOUT_MS = 15e3;\n var URL_BATCH_SIZE = 100;\n var REFRESH_CONCURRENCY = 4;\n var TAG_MANIFEST_FILENAME = \"__pcg_tag_manifest.json\";\n function stripLeadingSlash2(s) {\n return s.replace(/^\\/+/, \"\");\n }\n function ensureLeadingSlash(s) {\n return s.startsWith(\"/\") ? s : `/${s}`;\n }\n function loadCdnPurgeConfig() {\n const base = (0, gateway_auth_12.loadGatewayAuthConfig)();\n if (!base)\n return null;\n return { ...base };\n }\n exports2.loadCdnPurgeConfig = loadCdnPurgeConfig;\n function createCdnPurgeClient(cfg) {\n var _a;\n const buildId = cfg.version;\n const pathPrefix = `${buildId}/`;\n const manifestPath = (_a = cfg.manifestPath) !== null && _a !== void 0 ? _a : path.join(__dirname, TAG_MANIFEST_FILENAME);\n let manifestPromise = null;\n async function loadManifest() {\n if (manifestPromise)\n return manifestPromise;\n manifestPromise = (async () => {\n var _a2, _b, _c, _d;\n const map = /* @__PURE__ */ new Map();\n let raw;\n try {\n raw = await fs.promises.readFile(manifestPath, \"utf-8\");\n } catch (err) {\n if ((err === null || err === void 0 ? void 0 : err.code) !== \"ENOENT\") {\n console.warn(`[cdn-purge] manifest read error ${manifestPath}: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n return /* @__PURE__ */ new Map();\n }\n let rows;\n try {\n const parsed = JSON.parse(raw);\n rows = Array.isArray(parsed) ? parsed : [];\n } catch (err) {\n console.warn(`[cdn-purge] manifest parse error ${manifestPath}: ${(_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err}`);\n return /* @__PURE__ */ new Map();\n }\n for (const row of rows) {\n const tagPk = (_c = row === null || row === void 0 ? void 0 : row.tag) === null || _c === void 0 ? void 0 : _c.S;\n const pathPk = (_d = row === null || row === void 0 ? void 0 : row.path) === null || _d === void 0 ? void 0 : _d.S;\n if (typeof tagPk !== \"string\" || typeof pathPk !== \"string\")\n continue;\n if (!tagPk.startsWith(pathPrefix))\n continue;\n if (!pathPk.startsWith(pathPrefix))\n continue;\n const tag = tagPk.slice(pathPrefix.length);\n const p = pathPk.slice(pathPrefix.length);\n if (!tag || !p)\n continue;\n let bucket = map.get(tag);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n map.set(tag, bucket);\n }\n bucket.add(p);\n }\n const result = /* @__PURE__ */ new Map();\n let totalEntries = 0;\n for (const [tag, set] of map) {\n result.set(tag, Array.from(set));\n totalEntries += set.size;\n }\n console.log(`[cdn-purge] manifest loaded: tags=${result.size} entries=${totalEntries} (${manifestPath})`);\n return result;\n })();\n return manifestPromise;\n }\n function expandPathsToUrls(paths, hostname) {\n const normalized = /* @__PURE__ */ new Set();\n for (const p of paths) {\n if (!p)\n continue;\n normalized.add(ensureLeadingSlash(p));\n }\n if (normalized.size === 0)\n return [];\n const urls = /* @__PURE__ */ new Set();\n for (const p of normalized) {\n urls.add(`https://${hostname}${p}`);\n const rel = stripLeadingSlash2(p);\n urls.add(`https://${hostname}/_next/data/${buildId}/${rel || \"index\"}.json`);\n }\n return Array.from(urls);\n }\n async function refreshBatch(urls, hostname, siteId) {\n var _a2;\n const body = {\n hostname,\n siteId,\n urls\n };\n let res;\n try {\n res = await (0, gateway_auth_12.gatewayFetch)(cfg, \"/cache/refresh\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n timeoutMs: REFRESH_TIMEOUT_MS\n });\n } catch (err) {\n console.warn(`[cdn-purge] cache/refresh error (${urls.length} urls): ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n return;\n }\n if (!res.ok) {\n let detail = \"\";\n try {\n detail = (await res.text()).slice(0, 200);\n } catch (_b) {\n }\n console.warn(`[cdn-purge] cache/refresh failed status=${res.status} urls=${urls.length} ${detail}`);\n return;\n }\n console.log(`[cdn-purge] cache/refresh ok: urls=${urls.length}`);\n }\n async function refreshUrls(allUrls, hostname, siteId) {\n if (allUrls.length === 0)\n return;\n const batches = [];\n for (let i = 0; i < allUrls.length; i += URL_BATCH_SIZE) {\n batches.push(allUrls.slice(i, i + URL_BATCH_SIZE));\n }\n let cursor = 0;\n async function worker() {\n while (cursor < batches.length) {\n const idx = cursor++;\n await refreshBatch(batches[idx], hostname, siteId);\n }\n }\n const workers = Array.from({ length: Math.min(REFRESH_CONCURRENCY, batches.length) }, () => worker());\n await Promise.all(workers);\n }\n function resolveTarget(action) {\n const { hostname, siteId } = (0, edge_context_1.getEdgeContext)();\n if (!hostname || siteId === void 0 || siteId === \"\") {\n console.warn(`[cdn-purge] ${action} skip: edge context missing (hostname=${hostname !== null && hostname !== void 0 ? hostname : \"\\u2205\"} siteId=${siteId !== null && siteId !== void 0 ? siteId : \"\\u2205\"}); \\u8981\\u6C42\\u5165\\u7AD9\\u8BF7\\u6C42\\u5E26 host \\u4E0E x-alicdn-site-id`);\n return null;\n }\n return { hostname, siteId };\n }\n async function purgeByPaths(paths) {\n var _a2;\n try {\n const target = resolveTarget(\"purgeByPaths\");\n if (!target)\n return;\n const urls = expandPathsToUrls(paths, target.hostname);\n console.log(`[cdn-purge] purgeByPaths: input=${paths.length} urls=${urls.length}`);\n await refreshUrls(urls, target.hostname, target.siteId);\n } catch (err) {\n console.warn(`[cdn-purge] purgeByPaths error: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n }\n async function purgeByTags(tags) {\n var _a2;\n try {\n const uniqueTags = Array.from(new Set(tags.map((t) => typeof t === \"string\" ? t : \"\").map((t) => t.trim()).filter(Boolean)));\n if (uniqueTags.length === 0)\n return;\n const target = resolveTarget(\"purgeByTags\");\n if (!target)\n return;\n const map = await loadManifest();\n const merged = /* @__PURE__ */ new Set();\n for (const t of uniqueTags) {\n const paths = map.get(t);\n if (!paths)\n continue;\n for (const p of paths)\n merged.add(p);\n }\n if (merged.size === 0) {\n console.log(`[cdn-purge] purgeByTags: input=${uniqueTags.length} matched=0 (manifest miss, skip)`);\n return;\n }\n const urls = expandPathsToUrls(Array.from(merged), target.hostname);\n console.log(`[cdn-purge] purgeByTags: input=${uniqueTags.length} matched=${merged.size} urls=${urls.length}`);\n await refreshUrls(urls, target.hostname, target.siteId);\n } catch (err) {\n console.warn(`[cdn-purge] purgeByTags error: ${(_a2 = err === null || err === void 0 ? void 0 : err.message) !== null && _a2 !== void 0 ? _a2 : err}`);\n }\n }\n return { purgeByPaths, purgeByTags };\n }\n exports2.createCdnPurgeClient = createCdnPurgeClient;\n }\n});\n\n// dist/overrides/tagCache/gateway.js\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar gateway_auth_1 = require_gateway_auth();\nvar cdn_purge_1 = require_cdn_purge();\nvar QUERY_TIMEOUT = 3e3;\nvar WRITE_TIMEOUT = 5e3;\nvar BATCH_SIZE = 200;\nfunction stripLeadingSlash(s) {\n return s.replace(/^\\/+/, \"\");\n}\nvar GatewayTagCache = class {\n constructor() {\n this.name = \"gateway-tag-cache\";\n this.mode = \"nextMode\";\n this.config = null;\n this.configLoaded = false;\n this.purgeClient = null;\n this.purgeClientLoaded = false;\n }\n getConfig() {\n if (!this.configLoaded) {\n this.config = (0, gateway_auth_1.loadGatewayAuthConfig)();\n this.configLoaded = true;\n }\n return this.config;\n }\n getPurgeClient() {\n if (!this.purgeClientLoaded) {\n const cfg = (0, cdn_purge_1.loadCdnPurgeConfig)();\n this.purgeClient = cfg ? (0, cdn_purge_1.createCdnPurgeClient)(cfg) : null;\n this.purgeClientLoaded = true;\n }\n return this.purgeClient;\n }\n buildTagKey(tag) {\n const config = this.getConfig();\n if (!config)\n return tag;\n return `${config.version}/${stripLeadingSlash(tag)}`;\n }\n async getLastRevalidated(tags) {\n const config = this.getConfig();\n if (!config)\n return 0;\n try {\n const rows = await this.batchGetTags(config, tags);\n let maxRevalidatedAt = 0;\n for (const row of rows) {\n if (row.revalidatedAt && row.revalidatedAt > maxRevalidatedAt) {\n maxRevalidatedAt = row.revalidatedAt;\n }\n }\n return maxRevalidatedAt;\n } catch (err) {\n console.warn(`[tagCache] getLastRevalidated error: ${err.message}`);\n return 0;\n }\n }\n async hasBeenRevalidated(tags, lastModified) {\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const now = Date.now();\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.expire !== void 0) {\n if (row.expire <= now && row.expire > lm) {\n return true;\n }\n }\n if (row.revalidatedAt !== void 0 && row.revalidatedAt > lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] hasBeenRevalidated error: ${err.message}`);\n return false;\n }\n }\n async isStale(tags, lastModified) {\n var _a;\n const config = this.getConfig();\n if (!config)\n return false;\n if (tags.length === 0)\n return false;\n try {\n const rows = await this.batchGetTags(config, tags);\n const lm = lastModified !== null && lastModified !== void 0 ? lastModified : 0;\n for (const row of rows) {\n if (row.stale === void 0)\n continue;\n const revalidatedAt = (_a = row.revalidatedAt) !== null && _a !== void 0 ? _a : 0;\n if (revalidatedAt > lm && row.stale >= lm) {\n return true;\n }\n }\n return false;\n } catch (err) {\n console.warn(`[tagCache] isStale error: ${err.message}`);\n return false;\n }\n }\n async writeTags(tags) {\n if (!tags || tags.length === 0)\n return;\n const config = this.getConfig();\n if (!config)\n return;\n const writeTs = Date.now();\n const rows = tags.map((input) => {\n const tagStr = typeof input === \"string\" ? input : input.tag;\n const stale = typeof input === \"string\" ? void 0 : input.stale;\n const expire = typeof input === \"string\" ? void 0 : input.expire;\n const tagKey = this.buildTagKey(tagStr);\n const columns = [\n { name: \"revalidatedAt\", value: writeTs }\n ];\n if (stale !== void 0) {\n columns.push({ name: \"stale\", value: stale });\n }\n if (expire !== void 0) {\n columns.push({ name: \"expire\", value: expire });\n }\n return {\n primaryKey: [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: tagKey }\n ],\n columns\n };\n });\n await this.batchWrite(config, rows);\n const purgeClient = this.getPurgeClient();\n if (purgeClient) {\n const tagStrs = tags.map((t) => typeof t === \"string\" ? t : t.tag).filter((s) => typeof s === \"string\" && s.length > 0);\n if (tagStrs.length > 0) {\n purgeClient.purgeByTags(tagStrs).catch((err) => {\n var _a;\n console.warn(`[tagCache] purge fan-out failed: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);\n });\n }\n }\n }\n // ---- private methods ----\n async batchGetTags(config, tags) {\n var _a, _b;\n const primaryKeys = tags.map((tag) => [\n { name: \"app_id\", value: `${config.aliuid}/${config.routinename}` },\n { name: \"tag\", value: this.buildTagKey(tag) }\n ]);\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-get-row\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ primaryKeys }),\n timeoutMs: QUERY_TIMEOUT\n });\n if (!res.ok) {\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-get-row rejected (${res.status})`);\n } else {\n console.warn(`[tagCache] batch-get-row failed: status=${res.status}`);\n }\n return [];\n }\n const data = await res.json();\n console.log(`[tagCache] batch-get-row ok: tags=${tags.length} rows=${(_b = (_a = data.rows) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0}`);\n if (!data.rows)\n return [];\n return data.rows.map((row) => {\n var _a2;\n const result = {};\n for (const col of (_a2 = row.columns) !== null && _a2 !== void 0 ? _a2 : []) {\n if (col.name === \"revalidatedAt\" && typeof col.value === \"number\") {\n result.revalidatedAt = col.value;\n } else if (col.name === \"stale\" && typeof col.value === \"number\") {\n result.stale = col.value;\n } else if (col.name === \"expire\" && typeof col.value === \"number\") {\n result.expire = col.value;\n }\n }\n return result;\n });\n }\n async batchWrite(config, rows) {\n if (rows.length === 0)\n return;\n for (let i = 0; i < rows.length; i += BATCH_SIZE) {\n const batch = rows.slice(i, i + BATCH_SIZE);\n try {\n const res = await (0, gateway_auth_1.gatewayFetch)(config, \"/table/batch-write\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ rows: batch }),\n timeoutMs: WRITE_TIMEOUT\n });\n if (res.status === 401 || res.status === 403) {\n console.error(`[tagCache] batch-write rejected (${res.status})`);\n return;\n }\n if (!res.ok) {\n console.warn(`[tagCache] batch-write failed: status=${res.status}`);\n } else {\n console.log(`[tagCache] batch-write ok: rows=${batch.length}`);\n }\n } catch (err) {\n if (err.name === \"AbortError\") {\n console.warn(`[tagCache] batch-write timeout (${WRITE_TIMEOUT}ms)`);\n } else {\n console.warn(`[tagCache] batch-write error: ${err.message}`);\n }\n }\n }\n }\n};\nexports.default = GatewayTagCache;\n",
|
|
7
7
|
};
|
|
@@ -20,6 +20,7 @@ const http = require("http");
|
|
|
20
20
|
const fs = require("fs");
|
|
21
21
|
const path = require("path");
|
|
22
22
|
const image_proxy_1 = require("../../runtime/image-proxy");
|
|
23
|
+
const edge_context_1 = require("../../runtime/edge-context");
|
|
23
24
|
// === 静态资源 MIME(与原 pcg serve 父进程实现保持一致) ===
|
|
24
25
|
const MIME_TYPES = {
|
|
25
26
|
'.js': 'application/javascript',
|
|
@@ -184,7 +185,10 @@ function bridgeOpenNextHandler(handler) {
|
|
|
184
185
|
},
|
|
185
186
|
abortSignal: abortController.signal,
|
|
186
187
|
};
|
|
187
|
-
|
|
188
|
+
// 进入 OpenNext handler 前把请求头 (host / x-alicdn-site-id) 注入
|
|
189
|
+
// AsyncLocalStorage,下游 cdn-purge 即使 fire-and-forget 也能拿到本次
|
|
190
|
+
// 请求的 hostname / siteId(promise 链继承当前 store)。
|
|
191
|
+
await (0, edge_context_1.runWithEdgeContext)(headers, () => handler(event, { streamCreator }));
|
|
188
192
|
}
|
|
189
193
|
catch (err) {
|
|
190
194
|
if (!res.headersSent) {
|
|
@@ -281,4 +285,4 @@ const wrapperDef = {
|
|
|
281
285
|
supportStreaming: true,
|
|
282
286
|
};
|
|
283
287
|
exports.default = wrapperDef;
|
|
284
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYWRhcHRlcnMvd3JhcHBlcnMvbm9kZS1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRzs7QUFFSCw2QkFBNkI7QUFDN0IseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QiwyREFBNkQ7QUErQjdELDRDQUE0QztBQUU1QyxNQUFNLFVBQVUsR0FBMkI7SUFDekMsS0FBSyxFQUFFLHdCQUF3QjtJQUMvQixNQUFNLEVBQUUsd0JBQXdCO0lBQ2hDLE1BQU0sRUFBRSxVQUFVO0lBQ2xCLE9BQU8sRUFBRSxXQUFXO0lBQ3BCLE9BQU8sRUFBRSxrQkFBa0I7SUFDM0IsTUFBTSxFQUFFLFdBQVc7SUFDbkIsTUFBTSxFQUFFLFlBQVk7SUFDcEIsT0FBTyxFQUFFLFlBQVk7SUFDckIsTUFBTSxFQUFFLFdBQVc7SUFDbkIsTUFBTSxFQUFFLGVBQWU7SUFDdkIsTUFBTSxFQUFFLGNBQWM7SUFDdEIsT0FBTyxFQUFFLFdBQVc7SUFDcEIsUUFBUSxFQUFFLFlBQVk7SUFDdEIsTUFBTSxFQUFFLFVBQVU7SUFDbEIsTUFBTSxFQUFFLGtCQUFrQjtJQUMxQixNQUFNLEVBQUUsWUFBWTtJQUNwQixPQUFPLEVBQUUsWUFBWTtDQUN0QixDQUFDO0FBRUYsa0NBQWtDO0FBRWxDLFNBQVMsVUFBVSxDQUFDLEdBQVc7SUFDN0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUMxQixNQUFNLE1BQU0sR0FBc0MsRUFBRSxDQUFDO0lBQ3JELE1BQU0sWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsS0FBSyxN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O0dBRUc7QUFDSCxNQUFNLFVBQVUsR0FBRztJQUNqQixPQUFPO0lBQ1AsSUFBSSxFQUFFLFVBQVU7SUFDaEIsZ0JBQWdCLEVBQUUsSUFBSTtDQUN2QixDQUFDO0FBRUYsa0JBQWUsVUFBVSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBwY2cgTm9kZSBTZXJ2ZXIgV3JhcHBlclxuICpcbiAqIE9wZW5OZXh0IHdyYXBwZXIg55qE6ZW/6L+b56iL5b2i5oCBOuS4jeS+nei1liBGYWFTIHJ1bnRpbWUs6Ieq5bimIEhUVFAgc2VydmVyIOebtOaOpeebkeWQrFxuICogYHByb2Nlc3MuZW52LlBPUlRgKOm7mOiupCAzMDAwKSxgbm9kZSBpbmRleC5tanNgIOWNs+WPr+eLrOeri+i/kOihjOOAglxuICpcbiAqIOWNleS4quivt+axguS8muaMieS7peS4i+mhuuW6j+WIhuWPkTpcbiAqICAgMS4gYC9fX2hlYWx0aGAgICAgICAgICAgICAgICAgICDihpIgMjAwIE9LKOS+myBwY2cgc2VydmUgLyDlrrnlmajlsLHnu6rmjqLpkogpXG4gKiAgIDIuIGAvX25leHQvaW1hZ2VgICAgICAgICAgICAgICDihpIgaW1hZ2UtcHJveHko562+5ZCNIGNsaWVudCDosIMgR2F0ZXdheSlcbiAqICAgMy4gYC5vcGVuLW5leHQvYXNzZXRzLzx1cmxQYXRoPmAg5ZG95LitIOKGkiDnm7TmjqUgcGlwZSDmlofku7bmtYFcbiAqICAgNC4g5YW25LuWICAgICAgICAgICAgICAgICAgICAgICAgICDihpIgT3Blbk5leHQgaGFuZGxlcihOZXh0IFNTUi9BUEkvUlNDKVxuICpcbiAqIOS4ieautemAu+i+keatpOWJjeWIhuaVo+WcqCBwbGF0Zm9ybS1mdW5jdGlvbiB3cmFwcGVyKGltYWdlIHByb3h5ICsgcmVx4oaSZXZlbnQg5qGl5o6lKVxuICog5LiOIGBwY2cgc2VydmVgIOeItui/m+eoiyjpnZnmgIHotYTmupAgKyByZXZlcnNlIHByb3h5KeS4rTvmraTmrKHnu5/kuIDov5sgd3JhcHBlcixcbiAqIOiuqSBgcGNnIHNlcnZlYCDpgIDljJbkuLrnuq/lrZDov5vnqIvnrqHnkIblmajjgIJcbiAqL1xuXG5pbXBvcnQgKiBhcyBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGhhbmRsZUltYWdlUHJveHkgfSBmcm9tICcuLi8uLi9ydW50aW1lL2ltYWdlLXByb3h5JztcblxuLy8gPT09IE9wZW5OZXh0IOaOpeWPo+exu+WeiyjlhoXogZTpgb/lhY3noazkvp3otZYgQG9wZW5uZXh0anMvYXdzKSA9PT1cblxuaW50ZXJmYWNlIEludGVybmFsRXZlbnQge1xuICB0eXBlOiAnY29yZSc7XG4gIG1ldGhvZDogc3RyaW5nO1xuICByYXdQYXRoOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICBib2R5Pzogc3RyaW5nO1xuICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBxdWVyeTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgc3RyaW5nW10+O1xuICBjb29raWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICByZW1vdGVBZGRyZXNzOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBTdHJlYW1DcmVhdG9yIHtcbiAgd3JpdGVIZWFkZXJzKHByZWx1ZGU6IHtcbiAgICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gICAgY29va2llczogc3RyaW5nW107XG4gICAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgfSk6IGltcG9ydCgnc3RyZWFtJykuV3JpdGFibGU7XG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIG9uRmluaXNoPzogKCkgPT4gdm9pZDtcbn1cblxudHlwZSBPcGVuTmV4dEhhbmRsZXIgPSAoXG4gIGV2ZW50OiBJbnRlcm5hbEV2ZW50LFxuICBjdHg6IHsgc3RyZWFtQ3JlYXRvcjogU3RyZWFtQ3JlYXRvciB9XG4pID0+IFByb21pc2U8dm9pZD47XG5cbi8vID09PSDpnZnmgIHotYTmupAgTUlNRSjkuI7ljp8gcGNnIHNlcnZlIOeItui/m+eoi+WunueOsOS/neaMgeS4gOiHtCkgPT09XG5cbmNvbnN0IE1JTUVfVFlQRVM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICcuanMnOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdCcsXG4gICcubWpzJzogJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnLFxuICAnLmNzcyc6ICd0ZXh0L2NzcycsXG4gICcuaHRtbCc6ICd0ZXh0L2h0bWwnLFxuICAnLmpzb24nOiAnYXBwbGljYXRpb24vanNvbicsXG4gICcucG5nJzogJ2ltYWdlL3BuZycsXG4gICcuanBnJzogJ2ltYWdlL2pwZWcnLFxuICAnLmpwZWcnOiAnaW1hZ2UvanBlZycsXG4gICcuZ2lmJzogJ2ltYWdlL2dpZicsXG4gICcuc3ZnJzogJ2ltYWdlL3N2Zyt4bWwnLFxuICAnLmljbyc6ICdpbWFnZS94LWljb24nLFxuICAnLndvZmYnOiAnZm9udC93b2ZmJyxcbiAgJy53b2ZmMic6ICdmb250L3dvZmYyJyxcbiAgJy50dGYnOiAnZm9udC90dGYnLFxuICAnLm1hcCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgJy50eHQnOiAndGV4dC9wbGFpbicsXG4gICcud2VicCc6ICdpbWFnZS93ZWJwJyxcbn07XG5cbi8vID09PSDor7fmsYIg4oaSIEludGVybmFsRXZlbnQg5qGl5o6l5bel5YW3ID09PVxuXG5mdW5jdGlvbiBwYXJzZVF1ZXJ5KHVybDogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgc3RyaW5nW10+IHtcbiAgY29uc3QgaWR4ID0gdXJsLmluZGV4T2YoJz8nKTtcbiAgaWYgKGlkeCA9PT0gLTEpIHJldHVybiB7fTtcbiAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXT4gPSB7fTtcbiAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh1cmwuc2xpY2UoaWR4ICsgMSkpO1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBzZWFyY2hQYXJhbXMpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHBhcmFtc1trZXldO1xuICAgIGlmIChleGlzdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXJhbXNba2V5XSA9IHZhbHVlO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShleGlzdGluZykpIHtcbiAgICAgIGV4aXN0aW5nLnB1c2godmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJhbXNba2V5XSA9IFtleGlzdGluZywgdmFsdWVdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcGFyYW1zO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNvb2tpZXMoXG4gIGNvb2tpZUhlYWRlcjogc3RyaW5nIHwgdW5kZWZpbmVkXG4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgaWYgKCFjb29raWVIZWFkZXIpIHJldHVybiB7fTtcbiAgY29uc3QgY29va2llczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IHBhaXIgb2YgY29va2llSGVhZGVyLnNwbGl0KCc7JykpIHtcbiAgICBjb25zdCBlcUlkeCA9IHBhaXIuaW5kZXhPZignPScpO1xuICAgIGlmIChlcUlkeCA9PT0gLTEpIGNvbnRpbnVlO1xuICAgIGNvbnN0IG5hbWUgPSBwYWlyLnNsaWNlKDAsIGVxSWR4KS50cmltKCk7XG4gICAgY29uc3QgdmFsdWUgPSBwYWlyLnNsaWNlKGVxSWR4ICsgMSkudHJpbSgpO1xuICAgIGlmIChuYW1lKSBjb29raWVzW25hbWVdID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGNvb2tpZXM7XG59XG5cbmZ1bmN0aW9uIGZsYXR0ZW5IZWFkZXJzKFxuICByYXdIZWFkZXJzOiBodHRwLkluY29taW5nSHR0cEhlYWRlcnNcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJhd0hlYWRlcnMpKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgIGhlYWRlcnNba2V5LnRvTG93ZXJDYXNlKCldID0gQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgID8gdmFsdWUuam9pbignLCAnKVxuICAgICAgOiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gaGVhZGVycztcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZEJvZHkoXG4gIHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2Vcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChyZXEubWV0aG9kID09PSAnR0VUJyB8fCByZXEubWV0aG9kID09PSAnSEVBRCcpIHJldHVybiB1bmRlZmluZWQ7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2h1bmtzOiBCdWZmZXJbXSA9IFtdO1xuICAgIHJlcS5vbignZGF0YScsIChjaHVuazogQnVmZmVyKSA9PiBjaHVua3MucHVzaChjaHVuaykpO1xuICAgIHJlcS5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0Zi04JykpKTtcbiAgICByZXEub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbi8vID09PSDpnZnmgIHotYTmupAgPT09XG5cbi8qKlxuICog5pyN5YqhIC5vcGVuLW5leHQvYXNzZXRzLyDkuIvnmoTpnZnmgIHmlofku7bjgIJcbiAqXG4gKiDljLnphY3kuKTnsbs6XG4gKiAgIDEuIGAvX25leHQvc3RhdGljLypgIOKAlOKAlCBOZXh0LmpzIOeUn+aIkOeahOW4piBoYXNoIOi1hOa6kCzplb/nvJPlrZggaW1tdXRhYmxlXG4gKiAgIDIuIGAvPHB1YmxpYy1maWxlPmAg4oCU4oCUIGBwdWJsaWMvYCDmj5Dlj5blh7rmnaXnmoTmoLnnuqfpnZnmgIHmlofku7Ys55+t57yT5a2YXG4gKlxuICog5LiN5a2Y5Zyo55qE6Lev5b6E6L+U5ZueIGZhbHNlIOiuqeS4iuWxgiBmYWxsYmFjayDliLAgT3Blbk5leHQgaGFuZGxlcihBUEkgLyBTU1IgL1xuICogYF9wY2cvKmAg562JKeOAglxuICovXG5mdW5jdGlvbiBzZXJ2ZVN0YXRpY0ZpbGUoXG4gIGFzc2V0c0Rpcjogc3RyaW5nLFxuICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLFxuICByZXM6IGh0dHAuU2VydmVyUmVzcG9uc2Vcbik6IGJvb2xlYW4ge1xuICBjb25zdCB1cmxQYXRoID0gcmVxLnVybD8uc3BsaXQoJz8nKVswXSA/PyAnLyc7XG4gIGlmICh1cmxQYXRoID09PSAnLycgfHwgIXVybFBhdGguc3RhcnRzV2l0aCgnLycpKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oYXNzZXRzRGlyLCB1cmxQYXRoKTtcbiAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBwYXRoLm5vcm1hbGl6ZShmaWxlUGF0aCk7XG4gIGlmICghbm9ybWFsaXplZFBhdGguc3RhcnRzV2l0aChhc3NldHNEaXIpKSB7XG4gICAgcmVzLndyaXRlSGVhZCg0MDMpO1xuICAgIHJlcy5lbmQoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGxldCBzdGF0OiBmcy5TdGF0cztcbiAgdHJ5IHtcbiAgICBzdGF0ID0gZnMuc3RhdFN5bmMobm9ybWFsaXplZFBhdGgpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKCFzdGF0LmlzRmlsZSgpKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgZXh0ID0gcGF0aC5leHRuYW1lKG5vcm1hbGl6ZWRQYXRoKTtcbiAgY29uc3QgY29udGVudFR5cGUgPSBNSU1FX1RZUEVTW2V4dF0gfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7XG4gIGNvbnN0IGlzSGFzaGVkQXNzZXQgPSB1cmxQYXRoLnN0YXJ0c1dpdGgoJy9fbmV4dC9zdGF0aWMvJyk7XG5cbiAgcmVzLndyaXRlSGVhZCgyMDAsIHtcbiAgICAnQ29udGVudC1UeXBlJzogY29udGVudFR5cGUsXG4gICAgJ0NvbnRlbnQtTGVuZ3RoJzogc3RhdC5zaXplLFxuICAgICdDYWNoZS1Db250cm9sJzogaXNIYXNoZWRBc3NldFxuICAgICAgPyAncHVibGljLCBtYXgtYWdlPTMxNTM2MDAwLCBpbW11dGFibGUnXG4gICAgICA6ICdwdWJsaWMsIG1heC1hZ2U9NjAnLFxuICB9KTtcbiAgZnMuY3JlYXRlUmVhZFN0cmVhbShub3JtYWxpemVkUGF0aCkucGlwZShyZXMpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiDmioogT3Blbk5leHQg5o+Q5L6b55qEIGhhbmRsZXIg5YyF5oiQIGh0dHAgKHJlcSwgcmVzKSDlpITnkIblh73mlbDjgIJcbiAqIOi0n+i0ozogYm9keSDor7vlj5bjgIFldmVudCDnu4Too4XjgIHmtYHlvI/lk43lupTjgIE1MDAg5YWc5bqV44CCXG4gKi9cbmZ1bmN0aW9uIGJyaWRnZU9wZW5OZXh0SGFuZGxlcihoYW5kbGVyOiBPcGVuTmV4dEhhbmRsZXIpIHtcbiAgcmV0dXJuIGFzeW5jIChcbiAgICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLFxuICAgIHJlczogaHR0cC5TZXJ2ZXJSZXNwb25zZVxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3VXJsID0gcmVxLnVybCB8fCAnLyc7XG4gICAgICBjb25zdCBoZWFkZXJzID0gZmxhdHRlbkhlYWRlcnMocmVxLmhlYWRlcnMpO1xuICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlYWRCb2R5KHJlcSk7XG5cbiAgICAgIC8vIE9wZW5OZXh0IOWGhemDqOWvuSBldmVudC51cmwg5omn6KGMIGBuZXcgVVJMKC4uLilgLOW/hemhu+aYr+e7neWvuSBVUkwg4oCU4oCUIOeUqFxuICAgICAgLy8gaG9zdCBoZWFkZXIgKyB4LWZvcndhcmRlZC1wcm90byDov5jljp8s6KGM5Li65LiOIE9wZW5OZXh0IOWGhee9riBub2RlXG4gICAgICAvLyBjb252ZXJ0ZXIg5LiA6Ie0IChAb3Blbm5leHRqcy9hd3MvZGlzdC9vdmVycmlkZXMvY29udmVydGVycy9ub2RlLmpzKeOAglxuICAgICAgY29uc3QgaG9zdCA9IGhlYWRlcnNbJ2hvc3QnXSB8fCBgbG9jYWxob3N0OiR7cHJvY2Vzcy5lbnYuUE9SVCA/PyAnMzAwMCd9YDtcbiAgICAgIGNvbnN0IHByb3RvID0gaGVhZGVyc1sneC1mb3J3YXJkZWQtcHJvdG8nXT8uc3BsaXQoJywnKVswXT8udHJpbSgpIHx8ICdodHRwJztcbiAgICAgIGNvbnN0IGFic29sdXRlVXJsID0gbmV3IFVSTChgJHtwcm90b306Ly8ke2hvc3R9JHtyYXdVcmx9YCk7XG5cbiAgICAgIGNvbnN0IGV2ZW50OiBJbnRlcm5hbEV2ZW50ID0ge1xuICAgICAgICB0eXBlOiAnY29yZScsXG4gICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCB8fCAnR0VUJyxcbiAgICAgICAgcmF3UGF0aDogYWJzb2x1dGVVcmwucGF0aG5hbWUsXG4gICAgICAgIHVybDogYWJzb2x1dGVVcmwuaHJlZixcbiAgICAgICAgYm9keSxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgcXVlcnk6IHBhcnNlUXVlcnkocmF3VXJsKSxcbiAgICAgICAgY29va2llczogcGFyc2VDb29raWVzKGhlYWRlcnNbJ2Nvb2tpZSddKSxcbiAgICAgICAgcmVtb3RlQWRkcmVzczpcbiAgICAgICAgICBoZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXT8uc3BsaXQoJywnKVswXT8udHJpbSgpIHx8XG4gICAgICAgICAgaGVhZGVyc1sneC1yZWFsLWlwJ10gfHxcbiAgICAgICAgICByZXEuc29ja2V0Py5yZW1vdGVBZGRyZXNzIHx8XG4gICAgICAgICAgJzEyNy4wLjAuMScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICByZXMub24oJ2Nsb3NlJywgKCkgPT4gYWJvcnRDb250cm9sbGVyLmFib3J0KCkpO1xuXG4gICAgICBjb25zdCBzdHJlYW1DcmVhdG9yOiBTdHJlYW1DcmVhdG9yID0ge1xuICAgICAgICB3cml0ZUhlYWRlcnMocHJlbHVkZSkge1xuICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ1NldC1Db29raWUnLCBwcmVsdWRlLmNvb2tpZXMpO1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQocHJlbHVkZS5zdGF0dXNDb2RlLCBwcmVsdWRlLmhlYWRlcnMpO1xuICAgICAgICAgIHJlcy5mbHVzaEhlYWRlcnMoKTtcbiAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9LFxuICAgICAgICBhYm9ydFNpZ25hbDogYWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGhhbmRsZXIoZXZlbnQsIHsgc3RyZWFtQ3JlYXRvciB9KTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgY29uc3QgaXNEZXYgPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nO1xuICAgICAgICByZXMud3JpdGVIZWFkKDUwMCwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICByZXMuZW5kKFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIGVycm9yOiAnSW50ZXJuYWwgU2VydmVyIEVycm9yJyxcbiAgICAgICAgICAgIC4uLihpc0RldiAmJiB7IG1lc3NhZ2U6IGVyci5tZXNzYWdlLCBzdGFjazogZXJyLnN0YWNrIH0pLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKCFyZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIE9wZW5OZXh0IOWcqOWKoOi9veWujCBzZXJ2ZXIgYnVuZGxlIOWQjuiwg+eUqOatpOWHveaVsCzmiJHku6zlnKjmraTlkK/liqggSFRUUCBzZXJ2ZXLjgIJcbiAqXG4gKiBhc3NldHMg55uu5b2V6Kej5p6Q5Li6IGA8Y3dkPi8uLi8uLi9hc3NldHNgOk9wZW5OZXh0IOm7mOiupOS6p+eJqee7k+aehOaYr1xuICogYC5vcGVuLW5leHQvc2VydmVyLWZ1bmN0aW9ucy9kZWZhdWx0L2luZGV4Lm1qc2As6L+Q6KGM5pe25peg6K665piv55So5oi35omL5YqoXG4gKiBgY2RgIOWQjiBgbm9kZSBpbmRleC5tanNgIOi/mOaYryBgcGNnIHNlcnZlYCBzcGF3bihgY3dkOiBzZXJ2ZXJEaXJgKSxcbiAqIGBwcm9jZXNzLmN3ZCgpYCDpg73nrYnkuo4gYHNlcnZlci1mdW5jdGlvbnMvZGVmYXVsdC9gLGFzc2V0cyDlv4XlnKggYC4uLy4uL2Fzc2V0cy9g44CCXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHdyYXBwZXIoaGFuZGxlcjogT3Blbk5leHRIYW5kbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHBvcnQgPSBwYXJzZUludChwcm9jZXNzLmVudi5QT1JUID8/ICczMDAwJywgMTApO1xuICBjb25zdCBhc3NldHNEaXIgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJy4uJywgJy4uJywgJ2Fzc2V0cycpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMoYXNzZXRzRGlyKSkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGBbcGNnLW5vZGVdIGFzc2V0cyBkaXJlY3Rvcnkgbm90IGZvdW5kIGF0ICR7YXNzZXRzRGlyfSDigJQgc3RhdGljIGZpbGUgcmVxdWVzdHMgd2lsbCBmYWxsIHRocm91Z2ggdG8gTmV4dCBoYW5kbGVyYFxuICAgICk7XG4gIH1cblxuICBjb25zdCBkaXNwYXRjaFRvTmV4dCA9IGJyaWRnZU9wZW5OZXh0SGFuZGxlcihoYW5kbGVyKTtcblxuICBjb25zdCBzZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICBjb25zdCB1cmxQYXRoID0gcmVxLnVybD8uc3BsaXQoJz8nKVswXSA/PyAnLyc7XG5cbiAgICAvLyAxLiBoZWFsdGggY2hlY2tcbiAgICBpZiAodXJsUGF0aCA9PT0gJy9fX2hlYWx0aCcpIHtcbiAgICAgIHJlcy53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbicgfSk7XG4gICAgICByZXMuZW5kKCdPSycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIDIuIOWbvueJh+S8mOWMluS7o+eQhiDigJTigJQg5oum5oiqIE5leHQg6buY6K6k55qEIC9fbmV4dC9pbWFnZT91cmw9Li4uLHNlcnZlciDkvqfku6Plj5FcbiAgICAvLyAgICDnrb7lkI3or7fmsYLliLAgR2F0ZXdheeOAgui/meagt+eUqOaItyBuZXh0LmNvbmZpZyDkuI3pnIDopoHphY0gY3VzdG9tIGxvYWRlcixcbiAgICAvLyAgICA8SW1hZ2U+IOi1sCBOZXh0IOWGhee9riBVUkwg55Sf5oiQ6YC76L6R5Y2z5Y+v44CCXG4gICAgaWYgKHVybFBhdGggPT09ICcvX25leHQvaW1hZ2UnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBoYW5kbGVJbWFnZVByb3h5KHJlcSwgcmVzKTtcbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1twY2ctbm9kZV0gaW1hZ2UtcHJveHkgZXJyb3I6JywgZXJyKTtcbiAgICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDUwMCwgeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICAgIHJlcy5lbmQoSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogJ0ltYWdlIHByb3h5IGZhaWxlZCcgfSkpO1xuICAgICAgICB9IGVsc2UgaWYgKCFyZXMud3JpdGFibGVFbmRlZCkge1xuICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIDMuIOmdmeaAgei1hOa6kCgub3Blbi1uZXh0L2Fzc2V0cy8pXG4gICAgaWYgKHNlcnZlU3RhdGljRmlsZShhc3NldHNEaXIsIHJlcSwgcmVzKSkgcmV0dXJuO1xuXG4gICAgLy8gNC4gZmFsbGJhY2sg4oCU4oCUIE9wZW5OZXh0IE5leHQuanMgaGFuZGxlclxuICAgIGF3YWl0IGRpc3BhdGNoVG9OZXh0KHJlcSwgcmVzKTtcbiAgfSk7XG5cbiAgLy8g5LyY6ZuF5YWz6ZetOuWBnOatouaOpeaUtuaWsOi/nuaOpSznrYkgaW4tZmxpZ2h0IOivt+axguiHqueEtue7k+adnyw1cyDlhZzlupXlvLrliLbpgIDlh7pcbiAgbGV0IHNodXR0aW5nRG93biA9IGZhbHNlO1xuICBjb25zdCBzaHV0ZG93biA9IChzaWduYWw6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIGlmIChzaHV0dGluZ0Rvd24pIHJldHVybjtcbiAgICBzaHV0dGluZ0Rvd24gPSB0cnVlO1xuICAgIGNvbnNvbGUubG9nKGBbcGNnLW5vZGVdICR7c2lnbmFsfSByZWNlaXZlZCwgc2h1dHRpbmcgZG93bi4uLmApO1xuICAgIHNlcnZlci5jbG9zZSgoKSA9PiBwcm9jZXNzLmV4aXQoMCkpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KDApLCA1MDAwKS51bnJlZigpO1xuICB9O1xuICBwcm9jZXNzLm9uKCdTSUdJTlQnLCAoKSA9PiBzaHV0ZG93bignU0lHSU5UJykpO1xuICBwcm9jZXNzLm9uKCdTSUdURVJNJywgKCkgPT4gc2h1dGRvd24oJ1NJR1RFUk0nKSk7XG5cbiAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4ocmVzb2x2ZSA9PiB7XG4gICAgc2VydmVyLmxpc3Rlbihwb3J0LCAoKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhgW3BjZy1ub2RlXSBMaXN0ZW5pbmcgb24gcG9ydCAke3BvcnR9YCk7XG4gICAgICBjb25zb2xlLmxvZyhgW3BjZy1ub2RlXSAgIGFzc2V0czogICR7YXNzZXRzRGlyfWApO1xuICAgICAgY29uc29sZS5sb2coYFtwY2ctbm9kZV0gICByb3V0ZXM6ICAvX19oZWFsdGgsIC9fbmV4dC9pbWFnZSwgL19uZXh0L3N0YXRpYy8qLCA8bmV4dD5gKTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogT3Blbk5leHQg6buY6K6k5a+85Ye65aWR57qmOmB7IHdyYXBwZXIsIG5hbWUsIHN1cHBvcnRTdHJlYW1pbmcgfWDjgIJcbiAqL1xuY29uc3Qgd3JhcHBlckRlZiA9IHtcbiAgd3JhcHBlcixcbiAgbmFtZTogJ3BjZy1ub2RlJyxcbiAgc3VwcG9ydFN0cmVhbWluZzogdHJ1ZSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHdyYXBwZXJEZWY7XG4iXX0=
|
|
288
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYWRhcHRlcnMvd3JhcHBlcnMvbm9kZS1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRzs7QUFFSCw2QkFBNkI7QUFDN0IseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QiwyREFBNkQ7QUFDN0QsNkRBQWdFO0FBK0JoRSw0Q0FBNEM7QUFFNUMsTUFBTSxVQUFVLEdBQTJCO0lBQ3pDLEtBQUssRUFBRSx3QkFBd0I7SUFDL0IsTUFBTSxFQUFFLHdCQUF3QjtJQUNoQyxNQUFNLEVBQUUsVUFBVTtJQUNsQixPQUFPLEVBQUUsV0FBVztJQUNwQixPQUFPLEVBQUUsa0JBQWtCO0lBQzNCLE1BQU0sRUFBRSxXQUFXO0lBQ25CLE1BQU0sRUFBRSxZQUFZO0lBQ3BCLE9BQU8sRUFBRSxZQUFZO0lBQ3JCLE1BQU0sRUFBRSxXQUFXO0lBQ25CLE1BQU0sRUFBRSxlQUFlO0lBQ3ZCLE1BQU0sRUFBRSxjQUFjO0lBQ3RCLE9BQU8sRUFBRSxXQUFXO0lBQ3BCLFFBQVEsRUFBRSxZQUFZO0lBQ3RCLE1BQU0sRUFBRSxVQUFVO0lBQ2xCLE1BQU0sRUFBRSxrQkFBa0I7SUFDMUIsTUFBTSxFQUFFLFlBQVk7SUFDcEIsT0FBTyxFQUFFLFlBQVk7Q0FDdEIsQ0FBQztBQUVGLGtDQUFrQztBQUVsQyxTQUFTLFVBQVUsQ0FBQyxHQUFXO0lBQzdCLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDMUIsTUFBTSxNQUFNLEdBQXNDLEVBQUUsQ0FBQztJQUNyRCxNQUFNLFlBQVksR0FBRyxJQUFJLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFD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LENBQUMsd0VBQXdFLENBQUMsQ0FBQztZQUN0RixPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsR0FBRztJQUNqQixPQUFPO0lBQ1AsSUFBSSxFQUFFLFVBQVU7SUFDaEIsZ0JBQWdCLEVBQUUsSUFBSTtDQUN2QixDQUFDO0FBRUYsa0JBQWUsVUFBVSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBwY2cgTm9kZSBTZXJ2ZXIgV3JhcHBlclxuICpcbiAqIE9wZW5OZXh0IHdyYXBwZXIg55qE6ZW/6L+b56iL5b2i5oCBOuS4jeS+nei1liBGYWFTIHJ1bnRpbWUs6Ieq5bimIEhUVFAgc2VydmVyIOebtOaOpeebkeWQrFxuICogYHByb2Nlc3MuZW52LlBPUlRgKOm7mOiupCAzMDAwKSxgbm9kZSBpbmRleC5tanNgIOWNs+WPr+eLrOeri+i/kOihjOOAglxuICpcbiAqIOWNleS4quivt+axguS8muaMieS7peS4i+mhuuW6j+WIhuWPkTpcbiAqICAgMS4gYC9fX2hlYWx0aGAgICAgICAgICAgICAgICAgICDihpIgMjAwIE9LKOS+myBwY2cgc2VydmUgLyDlrrnlmajlsLHnu6rmjqLpkogpXG4gKiAgIDIuIGAvX25leHQvaW1hZ2VgICAgICAgICAgICAgICDihpIgaW1hZ2UtcHJveHko562+5ZCNIGNsaWVudCDosIMgR2F0ZXdheSlcbiAqICAgMy4gYC5vcGVuLW5leHQvYXNzZXRzLzx1cmxQYXRoPmAg5ZG95LitIOKGkiDnm7TmjqUgcGlwZSDmlofku7bmtYFcbiAqICAgNC4g5YW25LuWICAgICAgICAgICAgICAgICAgICAgICAgICDihpIgT3Blbk5leHQgaGFuZGxlcihOZXh0IFNTUi9BUEkvUlNDKVxuICpcbiAqIOS4ieautemAu+i+keatpOWJjeWIhuaVo+WcqCBwbGF0Zm9ybS1mdW5jdGlvbiB3cmFwcGVyKGltYWdlIHByb3h5ICsgcmVx4oaSZXZlbnQg5qGl5o6lKVxuICog5LiOIGBwY2cgc2VydmVgIOeItui/m+eoiyjpnZnmgIHotYTmupAgKyByZXZlcnNlIHByb3h5KeS4rTvmraTmrKHnu5/kuIDov5sgd3JhcHBlcixcbiAqIOiuqSBgcGNnIHNlcnZlYCDpgIDljJbkuLrnuq/lrZDov5vnqIvnrqHnkIblmajjgIJcbiAqL1xuXG5pbXBvcnQgKiBhcyBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGhhbmRsZUltYWdlUHJveHkgfSBmcm9tICcuLi8uLi9ydW50aW1lL2ltYWdlLXByb3h5JztcbmltcG9ydCB7IHJ1bldpdGhFZGdlQ29udGV4dCB9IGZyb20gJy4uLy4uL3J1bnRpbWUvZWRnZS1jb250ZXh0JztcblxuLy8gPT09IE9wZW5OZXh0IOaOpeWPo+exu+WeiyjlhoXogZTpgb/lhY3noazkvp3otZYgQG9wZW5uZXh0anMvYXdzKSA9PT1cblxuaW50ZXJmYWNlIEludGVybmFsRXZlbnQge1xuICB0eXBlOiAnY29yZSc7XG4gIG1ldGhvZDogc3RyaW5nO1xuICByYXdQYXRoOiBzdHJpbmc7XG4gIHVybDogc3RyaW5nO1xuICBib2R5Pzogc3RyaW5nO1xuICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBxdWVyeTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgc3RyaW5nW10+O1xuICBjb29raWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICByZW1vdGVBZGRyZXNzOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBTdHJlYW1DcmVhdG9yIHtcbiAgd3JpdGVIZWFkZXJzKHByZWx1ZGU6IHtcbiAgICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gICAgY29va2llczogc3RyaW5nW107XG4gICAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgfSk6IGltcG9ydCgnc3RyZWFtJykuV3JpdGFibGU7XG4gIGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIG9uRmluaXNoPzogKCkgPT4gdm9pZDtcbn1cblxudHlwZSBPcGVuTmV4dEhhbmRsZXIgPSAoXG4gIGV2ZW50OiBJbnRlcm5hbEV2ZW50LFxuICBjdHg6IHsgc3RyZWFtQ3JlYXRvcjogU3RyZWFtQ3JlYXRvciB9XG4pID0+IFByb21pc2U8dm9pZD47XG5cbi8vID09PSDpnZnmgIHotYTmupAgTUlNRSjkuI7ljp8gcGNnIHNlcnZlIOeItui/m+eoi+WunueOsOS/neaMgeS4gOiHtCkgPT09XG5cbmNvbnN0IE1JTUVfVFlQRVM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICcuanMnOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdCcsXG4gICcubWpzJzogJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnLFxuICAnLmNzcyc6ICd0ZXh0L2NzcycsXG4gICcuaHRtbCc6ICd0ZXh0L2h0bWwnLFxuICAnLmpzb24nOiAnYXBwbGljYXRpb24vanNvbicsXG4gICcucG5nJzogJ2ltYWdlL3BuZycsXG4gICcuanBnJzogJ2ltYWdlL2pwZWcnLFxuICAnLmpwZWcnOiAnaW1hZ2UvanBlZycsXG4gICcuZ2lmJzogJ2ltYWdlL2dpZicsXG4gICcuc3ZnJzogJ2ltYWdlL3N2Zyt4bWwnLFxuICAnLmljbyc6ICdpbWFnZS94LWljb24nLFxuICAnLndvZmYnOiAnZm9udC93b2ZmJyxcbiAgJy53b2ZmMic6ICdmb250L3dvZmYyJyxcbiAgJy50dGYnOiAnZm9udC90dGYnLFxuICAnLm1hcCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgJy50eHQnOiAndGV4dC9wbGFpbicsXG4gICcud2VicCc6ICdpbWFnZS93ZWJwJyxcbn07XG5cbi8vID09PSDor7fmsYIg4oaSIEludGVybmFsRXZlbnQg5qGl5o6l5bel5YW3ID09PVxuXG5mdW5jdGlvbiBwYXJzZVF1ZXJ5KHVybDogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgc3RyaW5nW10+IHtcbiAgY29uc3QgaWR4ID0gdXJsLmluZGV4T2YoJz8nKTtcbiAgaWYgKGlkeCA9PT0gLTEpIHJldHVybiB7fTtcbiAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXT4gPSB7fTtcbiAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh1cmwuc2xpY2UoaWR4ICsgMSkpO1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBzZWFyY2hQYXJhbXMpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHBhcmFtc1trZXldO1xuICAgIGlmIChleGlzdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXJhbXNba2V5XSA9IHZhbHVlO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShleGlzdGluZykpIHtcbiAgICAgIGV4aXN0aW5nLnB1c2godmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJhbXNba2V5XSA9IFtleGlzdGluZywgdmFsdWVdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcGFyYW1zO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNvb2tpZXMoXG4gIGNvb2tpZUhlYWRlcjogc3RyaW5nIHwgdW5kZWZpbmVkXG4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgaWYgKCFjb29raWVIZWFkZXIpIHJldHVybiB7fTtcbiAgY29uc3QgY29va2llczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IHBhaXIgb2YgY29va2llSGVhZGVyLnNwbGl0KCc7JykpIHtcbiAgICBjb25zdCBlcUlkeCA9IHBhaXIuaW5kZXhPZignPScpO1xuICAgIGlmIChlcUlkeCA9PT0gLTEpIGNvbnRpbnVlO1xuICAgIGNvbnN0IG5hbWUgPSBwYWlyLnNsaWNlKDAsIGVxSWR4KS50cmltKCk7XG4gICAgY29uc3QgdmFsdWUgPSBwYWlyLnNsaWNlKGVxSWR4ICsgMSkudHJpbSgpO1xuICAgIGlmIChuYW1lKSBjb29raWVzW25hbWVdID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGNvb2tpZXM7XG59XG5cbmZ1bmN0aW9uIGZsYXR0ZW5IZWFkZXJzKFxuICByYXdIZWFkZXJzOiBodHRwLkluY29taW5nSHR0cEhlYWRlcnNcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJhd0hlYWRlcnMpKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgIGhlYWRlcnNba2V5LnRvTG93ZXJDYXNlKCldID0gQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgID8gdmFsdWUuam9pbignLCAnKVxuICAgICAgOiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gaGVhZGVycztcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZEJvZHkoXG4gIHJlcTogaHR0cC5JbmNvbWluZ01lc3NhZ2Vcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChyZXEubWV0aG9kID09PSAnR0VUJyB8fCByZXEubWV0aG9kID09PSAnSEVBRCcpIHJldHVybiB1bmRlZmluZWQ7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2h1bmtzOiBCdWZmZXJbXSA9IFtdO1xuICAgIHJlcS5vbignZGF0YScsIChjaHVuazogQnVmZmVyKSA9PiBjaHVua3MucHVzaChjaHVuaykpO1xuICAgIHJlcS5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0Zi04JykpKTtcbiAgICByZXEub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbi8vID09PSDpnZnmgIHotYTmupAgPT09XG5cbi8qKlxuICog5pyN5YqhIC5vcGVuLW5leHQvYXNzZXRzLyDkuIvnmoTpnZnmgIHmlofku7bjgIJcbiAqXG4gKiDljLnphY3kuKTnsbs6XG4gKiAgIDEuIGAvX25leHQvc3RhdGljLypgIOKAlOKAlCBOZXh0LmpzIOeUn+aIkOeahOW4piBoYXNoIOi1hOa6kCzplb/nvJPlrZggaW1tdXRhYmxlXG4gKiAgIDIuIGAvPHB1YmxpYy1maWxlPmAg4oCU4oCUIGBwdWJsaWMvYCDmj5Dlj5blh7rmnaXnmoTmoLnnuqfpnZnmgIHmlofku7Ys55+t57yT5a2YXG4gKlxuICog5LiN5a2Y5Zyo55qE6Lev5b6E6L+U5ZueIGZhbHNlIOiuqeS4iuWxgiBmYWxsYmFjayDliLAgT3Blbk5leHQgaGFuZGxlcihBUEkgLyBTU1IgL1xuICogYF9wY2cvKmAg562JKeOAglxuICovXG5mdW5jdGlvbiBzZXJ2ZVN0YXRpY0ZpbGUoXG4gIGFzc2V0c0Rpcjogc3RyaW5nLFxuICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLFxuICByZXM6IGh0dHAuU2VydmVyUmVzcG9uc2Vcbik6IGJvb2xlYW4ge1xuICBjb25zdCB1cmxQYXRoID0gcmVxLnVybD8uc3BsaXQoJz8nKVswXSA/PyAnLyc7XG4gIGlmICh1cmxQYXRoID09PSAnLycgfHwgIXVybFBhdGguc3RhcnRzV2l0aCgnLycpKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oYXNzZXRzRGlyLCB1cmxQYXRoKTtcbiAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBwYXRoLm5vcm1hbGl6ZShmaWxlUGF0aCk7XG4gIGlmICghbm9ybWFsaXplZFBhdGguc3RhcnRzV2l0aChhc3NldHNEaXIpKSB7XG4gICAgcmVzLndyaXRlSGVhZCg0MDMpO1xuICAgIHJlcy5lbmQoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGxldCBzdGF0OiBmcy5TdGF0cztcbiAgdHJ5IHtcbiAgICBzdGF0ID0gZnMuc3RhdFN5bmMobm9ybWFsaXplZFBhdGgpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKCFzdGF0LmlzRmlsZSgpKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgZXh0ID0gcGF0aC5leHRuYW1lKG5vcm1hbGl6ZWRQYXRoKTtcbiAgY29uc3QgY29udGVudFR5cGUgPSBNSU1FX1RZUEVTW2V4dF0gfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7XG4gIGNvbnN0IGlzSGFzaGVkQXNzZXQgPSB1cmxQYXRoLnN0YXJ0c1dpdGgoJy9fbmV4dC9zdGF0aWMvJyk7XG5cbiAgcmVzLndyaXRlSGVhZCgyMDAsIHtcbiAgICAnQ29udGVudC1UeXBlJzogY29udGVudFR5cGUsXG4gICAgJ0NvbnRlbnQtTGVuZ3RoJzogc3RhdC5zaXplLFxuICAgICdDYWNoZS1Db250cm9sJzogaXNIYXNoZWRBc3NldFxuICAgICAgPyAncHVibGljLCBtYXgtYWdlPTMxNTM2MDAwLCBpbW11dGFibGUnXG4gICAgICA6ICdwdWJsaWMsIG1heC1hZ2U9NjAnLFxuICB9KTtcbiAgZnMuY3JlYXRlUmVhZFN0cmVhbShub3JtYWxpemVkUGF0aCkucGlwZShyZXMpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiDmioogT3Blbk5leHQg5o+Q5L6b55qEIGhhbmRsZXIg5YyF5oiQIGh0dHAgKHJlcSwgcmVzKSDlpITnkIblh73mlbDjgIJcbiAqIOi0n+i0ozogYm9keSDor7vlj5bjgIFldmVudCDnu4Too4XjgIHmtYHlvI/lk43lupTjgIE1MDAg5YWc5bqV44CCXG4gKi9cbmZ1bmN0aW9uIGJyaWRnZU9wZW5OZXh0SGFuZGxlcihoYW5kbGVyOiBPcGVuTmV4dEhhbmRsZXIpIHtcbiAgcmV0dXJuIGFzeW5jIChcbiAgICByZXE6IGh0dHAuSW5jb21pbmdNZXNzYWdlLFxuICAgIHJlczogaHR0cC5TZXJ2ZXJSZXNwb25zZVxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmF3VXJsID0gcmVxLnVybCB8fCAnLyc7XG4gICAgICBjb25zdCBoZWFkZXJzID0gZmxhdHRlbkhlYWRlcnMocmVxLmhlYWRlcnMpO1xuICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlYWRCb2R5KHJlcSk7XG5cbiAgICAgIC8vIE9wZW5OZXh0IOWGhemDqOWvuSBldmVudC51cmwg5omn6KGMIGBuZXcgVVJMKC4uLilgLOW/hemhu+aYr+e7neWvuSBVUkwg4oCU4oCUIOeUqFxuICAgICAgLy8gaG9zdCBoZWFkZXIgKyB4LWZvcndhcmRlZC1wcm90byDov5jljp8s6KGM5Li65LiOIE9wZW5OZXh0IOWGhee9riBub2RlXG4gICAgICAvLyBjb252ZXJ0ZXIg5LiA6Ie0IChAb3Blbm5leHRqcy9hd3MvZGlzdC9vdmVycmlkZXMvY29udmVydGVycy9ub2RlLmpzKeOAglxuICAgICAgY29uc3QgaG9zdCA9IGhlYWRlcnNbJ2hvc3QnXSB8fCBgbG9jYWxob3N0OiR7cHJvY2Vzcy5lbnYuUE9SVCA/PyAnMzAwMCd9YDtcbiAgICAgIGNvbnN0IHByb3RvID0gaGVhZGVyc1sneC1mb3J3YXJkZWQtcHJvdG8nXT8uc3BsaXQoJywnKVswXT8udHJpbSgpIHx8ICdodHRwJztcbiAgICAgIGNvbnN0IGFic29sdXRlVXJsID0gbmV3IFVSTChgJHtwcm90b306Ly8ke2hvc3R9JHtyYXdVcmx9YCk7XG5cbiAgICAgIGNvbnN0IGV2ZW50OiBJbnRlcm5hbEV2ZW50ID0ge1xuICAgICAgICB0eXBlOiAnY29yZScsXG4gICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCB8fCAnR0VUJyxcbiAgICAgICAgcmF3UGF0aDogYWJzb2x1dGVVcmwucGF0aG5hbWUsXG4gICAgICAgIHVybDogYWJzb2x1dGVVcmwuaHJlZixcbiAgICAgICAgYm9keSxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgcXVlcnk6IHBhcnNlUXVlcnkocmF3VXJsKSxcbiAgICAgICAgY29va2llczogcGFyc2VDb29raWVzKGhlYWRlcnNbJ2Nvb2tpZSddKSxcbiAgICAgICAgcmVtb3RlQWRkcmVzczpcbiAgICAgICAgICBoZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXT8uc3BsaXQoJywnKVswXT8udHJpbSgpIHx8XG4gICAgICAgICAgaGVhZGVyc1sneC1yZWFsLWlwJ10gfHxcbiAgICAgICAgICByZXEuc29ja2V0Py5yZW1vdGVBZGRyZXNzIHx8XG4gICAgICAgICAgJzEyNy4wLjAuMScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICByZXMub24oJ2Nsb3NlJywgKCkgPT4gYWJvcnRDb250cm9sbGVyLmFib3J0KCkpO1xuXG4gICAgICBjb25zdCBzdHJlYW1DcmVhdG9yOiBTdHJlYW1DcmVhdG9yID0ge1xuICAgICAgICB3cml0ZUhlYWRlcnMocHJlbHVkZSkge1xuICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ1NldC1Db29raWUnLCBwcmVsdWRlLmNvb2tpZXMpO1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQocHJlbHVkZS5zdGF0dXNDb2RlLCBwcmVsdWRlLmhlYWRlcnMpO1xuICAgICAgICAgIHJlcy5mbHVzaEhlYWRlcnMoKTtcbiAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9LFxuICAgICAgICBhYm9ydFNpZ25hbDogYWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgIH07XG5cbiAgICAgIC8vIOi/m+WFpSBPcGVuTmV4dCBoYW5kbGVyIOWJjeaKiuivt+axguWktCAoaG9zdCAvIHgtYWxpY2RuLXNpdGUtaWQpIOazqOWFpVxuICAgICAgLy8gQXN5bmNMb2NhbFN0b3JhZ2Us5LiL5ri4IGNkbi1wdXJnZSDljbPkvb8gZmlyZS1hbmQtZm9yZ2V0IOS5n+iDveaLv+WIsOacrOasoVxuICAgICAgLy8g6K+35rGC55qEIGhvc3RuYW1lIC8gc2l0ZUlkKHByb21pc2Ug6ZO+57un5om/5b2T5YmNIHN0b3JlKeOAglxuICAgICAgYXdhaXQgcnVuV2l0aEVkZ2VDb250ZXh0KGhlYWRlcnMsICgpID0+IGhhbmRsZXIoZXZlbnQsIHsgc3RyZWFtQ3JlYXRvciB9KSk7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgIGNvbnN0IGlzRGV2ID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJztcbiAgICAgICAgcmVzLndyaXRlSGVhZCg1MDAsIHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTtcbiAgICAgICAgcmVzLmVuZChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBlcnJvcjogJ0ludGVybmFsIFNlcnZlciBFcnJvcicsXG4gICAgICAgICAgICAuLi4oaXNEZXYgJiYgeyBtZXNzYWdlOiBlcnIubWVzc2FnZSwgc3RhY2s6IGVyci5zdGFjayB9KSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmICghcmVzLndyaXRhYmxlRW5kZWQpIHtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBPcGVuTmV4dCDlnKjliqDovb3lrowgc2VydmVyIGJ1bmRsZSDlkI7osIPnlKjmraTlh73mlbAs5oiR5Lus5Zyo5q2k5ZCv5YqoIEhUVFAgc2VydmVy44CCXG4gKlxuICogYXNzZXRzIOebruW9leino+aekOS4uiBgPGN3ZD4vLi4vLi4vYXNzZXRzYDpPcGVuTmV4dCDpu5jorqTkuqfniannu5PmnoTmmK9cbiAqIGAub3Blbi1uZXh0L3NlcnZlci1mdW5jdGlvbnMvZGVmYXVsdC9pbmRleC5tanNgLOi/kOihjOaXtuaXoOiuuuaYr+eUqOaIt+aJi+WKqFxuICogYGNkYCDlkI4gYG5vZGUgaW5kZXgubWpzYCDov5jmmK8gYHBjZyBzZXJ2ZWAgc3Bhd24oYGN3ZDogc2VydmVyRGlyYCksXG4gKiBgcHJvY2Vzcy5jd2QoKWAg6YO9562J5LqOIGBzZXJ2ZXItZnVuY3Rpb25zL2RlZmF1bHQvYCxhc3NldHMg5b+F5ZyoIGAuLi8uLi9hc3NldHMvYOOAglxuICovXG5hc3luYyBmdW5jdGlvbiB3cmFwcGVyKGhhbmRsZXI6IE9wZW5OZXh0SGFuZGxlcik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwb3J0ID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuUE9SVCA/PyAnMzAwMCcsIDEwKTtcbiAgY29uc3QgYXNzZXRzRGlyID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksICcuLicsICcuLicsICdhc3NldHMnKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGFzc2V0c0RpcikpIHtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgW3BjZy1ub2RlXSBhc3NldHMgZGlyZWN0b3J5IG5vdCBmb3VuZCBhdCAke2Fzc2V0c0Rpcn0g4oCUIHN0YXRpYyBmaWxlIHJlcXVlc3RzIHdpbGwgZmFsbCB0aHJvdWdoIHRvIE5leHQgaGFuZGxlcmBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgZGlzcGF0Y2hUb05leHQgPSBicmlkZ2VPcGVuTmV4dEhhbmRsZXIoaGFuZGxlcik7XG5cbiAgY29uc3Qgc2VydmVyID0gaHR0cC5jcmVhdGVTZXJ2ZXIoYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgY29uc3QgdXJsUGF0aCA9IHJlcS51cmw/LnNwbGl0KCc/JylbMF0gPz8gJy8nO1xuXG4gICAgLy8gMS4gaGVhbHRoIGNoZWNrXG4gICAgaWYgKHVybFBhdGggPT09ICcvX19oZWFsdGgnKSB7XG4gICAgICByZXMud3JpdGVIZWFkKDIwMCwgeyAnQ29udGVudC1UeXBlJzogJ3RleHQvcGxhaW4nIH0pO1xuICAgICAgcmVzLmVuZCgnT0snKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAyLiDlm77niYfkvJjljJbku6PnkIYg4oCU4oCUIOaLpuaIqiBOZXh0IOm7mOiupOeahCAvX25leHQvaW1hZ2U/dXJsPS4uLixzZXJ2ZXIg5L6n5Luj5Y+RXG4gICAgLy8gICAg562+5ZCN6K+35rGC5YiwIEdhdGV3YXnjgILov5nmoLfnlKjmiLcgbmV4dC5jb25maWcg5LiN6ZyA6KaB6YWNIGN1c3RvbSBsb2FkZXIsXG4gICAgLy8gICAgPEltYWdlPiDotbAgTmV4dCDlhoXnva4gVVJMIOeUn+aIkOmAu+i+keWNs+WPr+OAglxuICAgIGlmICh1cmxQYXRoID09PSAnL19uZXh0L2ltYWdlJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgaGFuZGxlSW1hZ2VQcm94eShyZXEsIHJlcyk7XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbcGNnLW5vZGVdIGltYWdlLXByb3h5IGVycm9yOicsIGVycik7XG4gICAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgICAgcmVzLndyaXRlSGVhZCg1MDAsIHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTtcbiAgICAgICAgICByZXMuZW5kKEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6ICdJbWFnZSBwcm94eSBmYWlsZWQnIH0pKTtcbiAgICAgICAgfSBlbHNlIGlmICghcmVzLndyaXRhYmxlRW5kZWQpIHtcbiAgICAgICAgICByZXMuZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAzLiDpnZnmgIHotYTmupAoLm9wZW4tbmV4dC9hc3NldHMvKVxuICAgIGlmIChzZXJ2ZVN0YXRpY0ZpbGUoYXNzZXRzRGlyLCByZXEsIHJlcykpIHJldHVybjtcblxuICAgIC8vIDQuIGZhbGxiYWNrIOKAlOKAlCBPcGVuTmV4dCBOZXh0LmpzIGhhbmRsZXJcbiAgICBhd2FpdCBkaXNwYXRjaFRvTmV4dChyZXEsIHJlcyk7XG4gIH0pO1xuXG4gIC8vIOS8mOmbheWFs+mXrTrlgZzmraLmjqXmlLbmlrDov57mjqUs562JIGluLWZsaWdodCDor7fmsYLoh6rnhLbnu5PmnZ8sNXMg5YWc5bqV5by65Yi26YCA5Ye6XG4gIGxldCBzaHV0dGluZ0Rvd24gPSBmYWxzZTtcbiAgY29uc3Qgc2h1dGRvd24gPSAoc2lnbmFsOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBpZiAoc2h1dHRpbmdEb3duKSByZXR1cm47XG4gICAgc2h1dHRpbmdEb3duID0gdHJ1ZTtcbiAgICBjb25zb2xlLmxvZyhgW3BjZy1ub2RlXSAke3NpZ25hbH0gcmVjZWl2ZWQsIHNodXR0aW5nIGRvd24uLi5gKTtcbiAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4gcHJvY2Vzcy5leGl0KDApKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHByb2Nlc3MuZXhpdCgwKSwgNTAwMCkudW5yZWYoKTtcbiAgfTtcbiAgcHJvY2Vzcy5vbignU0lHSU5UJywgKCkgPT4gc2h1dGRvd24oJ1NJR0lOVCcpKTtcbiAgcHJvY2Vzcy5vbignU0lHVEVSTScsICgpID0+IHNodXRkb3duKCdTSUdURVJNJykpO1xuXG4gIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4ge1xuICAgIHNlcnZlci5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuICAgICAgY29uc29sZS5sb2coYFtwY2ctbm9kZV0gTGlzdGVuaW5nIG9uIHBvcnQgJHtwb3J0fWApO1xuICAgICAgY29uc29sZS5sb2coYFtwY2ctbm9kZV0gICBhc3NldHM6ICAke2Fzc2V0c0Rpcn1gKTtcbiAgICAgIGNvbnNvbGUubG9nKGBbcGNnLW5vZGVdICAgcm91dGVzOiAgL19faGVhbHRoLCAvX25leHQvaW1hZ2UsIC9fbmV4dC9zdGF0aWMvKiwgPG5leHQ+YCk7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIE9wZW5OZXh0IOm7mOiupOWvvOWHuuWlkee6pjpgeyB3cmFwcGVyLCBuYW1lLCBzdXBwb3J0U3RyZWFtaW5nIH1g44CCXG4gKi9cbmNvbnN0IHdyYXBwZXJEZWYgPSB7XG4gIHdyYXBwZXIsXG4gIG5hbWU6ICdwY2ctbm9kZScsXG4gIHN1cHBvcnRTdHJlYW1pbmc6IHRydWUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCB3cmFwcGVyRGVmO1xuIl19
|
|
@@ -162,6 +162,7 @@ class GatewayTagCache {
|
|
|
162
162
|
}
|
|
163
163
|
// ---- private methods ----
|
|
164
164
|
async batchGetTags(config, tags) {
|
|
165
|
+
var _a, _b;
|
|
165
166
|
const primaryKeys = tags.map(tag => [
|
|
166
167
|
{ name: 'app_id', value: `${config.aliuid}/${config.routinename}` },
|
|
167
168
|
{ name: 'tag', value: this.buildTagKey(tag) },
|
|
@@ -182,6 +183,7 @@ class GatewayTagCache {
|
|
|
182
183
|
return [];
|
|
183
184
|
}
|
|
184
185
|
const data = (await res.json());
|
|
186
|
+
console.log(`[tagCache] batch-get-row ok: tags=${tags.length} rows=${(_b = (_a = data.rows) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0}`);
|
|
185
187
|
if (!data.rows)
|
|
186
188
|
return [];
|
|
187
189
|
return data.rows.map(row => {
|
|
@@ -220,6 +222,9 @@ class GatewayTagCache {
|
|
|
220
222
|
if (!res.ok) {
|
|
221
223
|
console.warn(`[tagCache] batch-write failed: status=${res.status}`);
|
|
222
224
|
}
|
|
225
|
+
else {
|
|
226
|
+
console.log(`[tagCache] batch-write ok: rows=${batch.length}`);
|
|
227
|
+
}
|
|
223
228
|
}
|
|
224
229
|
catch (err) {
|
|
225
230
|
if (err.name === 'AbortError') {
|
|
@@ -233,4 +238,4 @@ class GatewayTagCache {
|
|
|
233
238
|
}
|
|
234
239
|
}
|
|
235
240
|
exports.default = GatewayTagCache;
|
|
236
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9vdmVycmlkZXMvdGFnQ2FjaGUvZ2F0ZXdheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7O0dBS0c7O0FBRUgsNkRBSW9DO0FBQ3BDLHVEQUlpQztBQUVqQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFDM0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQztBQUV2QixTQUFTLGlCQUFpQixDQUFDLENBQVM7SUFDbEMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBZ0JELE1BQXFCLGVBQWU7SUFBcEM7UUFDRSxTQUFJLEdBQUcsbUJBQTRCLENBQUM7UUFDcEMsU0FBSSxHQUFHLFVBQW1CLENBQUM7UUFFbkIsV0FBTSxHQUE2QixJQUFJLENBQUM7UUFDeEMsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFckIsZ0JBQVcsR0FBMEIsSUFBSSxDQUFDO1FBQzFDLHNCQUFpQixHQUFHLEtBQUssQ0FBQztJQWlQcEMsQ0FBQztJQS9PUyxTQUFTO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFBLG9DQUFxQixHQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDMUI7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUVPLGNBQWM7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMzQixNQUFNLEdBQUcsR0FBRyxJQUFBLDhCQUFrQixHQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUEsZ0NBQW9CLEVBQUMsR0FBRyxDQUFDLENB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QUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO29CQUNYLE9BQU8sQ0FBQyxJQUFJLENBQUMseUNBQXlDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUNyRTthQUNGO1lBQUMsT0FBTyxHQUFRLEVBQUU7Z0JBQ2pCLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUU7b0JBQzdCLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLGFBQWEsS0FBSyxDQUFDLENBQUM7aUJBQ3JFO3FCQUFNO29CQUNMLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2lCQUM5RDthQUNGO1NBQ0Y7SUFDSCxDQUFDO0NBQ0Y7QUF6UEQsa0NBeVBDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHYXRld2F5IFRhZyDnvJPlrZggT3ZlcnJpZGUgKG5leHRNb2RlKVxuICpcbiAqIOS9v+eUqCBPcGVuTmV4dCDnmoQgbmV4dE1vZGUg5o6l5Y+j77yM6YCa6L+HIEdhdGV3YXkg5Luj55CG6K+75YaZIFRhYmxlU3RvcmXjgIJcbiAqIOmJtOadg+e7n+S4gOi1sCBydW50aW1lL2dhdGV3YXktYXV0aO+8iEhNQUMg562+5ZCNICsgNCBoZWFkZXLvvInjgIJcbiAqL1xuXG5pbXBvcnQge1xuICBsb2FkR2F0ZXdheUF1dGhDb25maWcsXG4gIGdhdGV3YXlGZXRjaCxcbiAgR2F0ZXdheUF1dGhDb25maWcsXG59IGZyb20gJy4uLy4uL3J1bnRpbWUvZ2F0ZXdheS1hdXRoJztcbmltcG9ydCB7XG4gIGxvYWRDZG5QdXJnZUNvbmZpZyxcbiAgY3JlYXRlQ2RuUHVyZ2VDbGllbnQsXG4gIENkblB1cmdlQ2xpZW50LFxufSBmcm9tICcuLi8uLi9ydW50aW1lL2Nkbi1wdXJnZSc7XG5cbmNvbnN0IFFVRVJZX1RJTUVPVVQgPSAzMDAwO1xuY29uc3QgV1JJVEVfVElNRU9VVCA9IDUwMDA7XG5jb25zdCBCQVRDSF9TSVpFID0gMjAwO1xuXG5mdW5jdGlvbiBzdHJpcExlYWRpbmdTbGFzaChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKC9eXFwvKy8sICcnKTtcbn1cblxudHlwZSBOZXh0TW9kZVRhZ0NhY2hlV3JpdGVJbnB1dCA9XG4gIHwgc3RyaW5nXG4gIHwge1xuICAgICAgdGFnOiBzdHJpbmc7XG4gICAgICBzdGFsZT86IG51bWJlcjtcbiAgICAgIGV4cGlyZT86IG51bWJlcjtcbiAgICB9O1xuXG5pbnRlcmZhY2UgVGFnUm93IHtcbiAgcmV2YWxpZGF0ZWRBdD86IG51bWJlcjtcbiAgc3RhbGU/OiBudW1iZXI7XG4gIGV4cGlyZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2F0ZXdheVRhZ0NhY2hlIHtcbiAgbmFtZSA9ICdnYXRld2F5LXRhZy1jYWNoZScgYXMgY29uc3Q7XG4gIG1vZGUgPSAnbmV4dE1vZGUnIGFzIGNvbnN0O1xuXG4gIHByaXZhdGUgY29uZmlnOiBHYXRld2F5QXV0aENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbmZpZ0xvYWRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgcHVyZ2VDbGllbnQ6IENkblB1cmdlQ2xpZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcHVyZ2VDbGllbnRMb2FkZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIGdldENvbmZpZygpOiBHYXRld2F5QXV0aENvbmZpZyB8IG51bGwge1xuICAgIGlmICghdGhpcy5jb25maWdMb2FkZWQpIHtcbiAgICAgIHRoaXMuY29uZmlnID0gbG9hZEdhdGV3YXlBdXRoQ29uZmlnKCk7XG4gICAgICB0aGlzLmNvbmZpZ0xvYWRlZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbmZpZztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UHVyZ2VDbGllbnQoKTogQ2RuUHVyZ2VDbGllbnQgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMucHVyZ2VDbGllbnRMb2FkZWQpIHtcbiAgICAgIGNvbnN0IGNmZyA9IGxvYWRDZG5QdXJnZUNvbmZpZygpO1xuICAgICAgdGhpcy5wdXJnZUNsaWVudCA9IGNmZyA/IGNyZWF0ZUNkblB1cmdlQ2xpZW50KGNmZykgOiBudWxsO1xuICAgICAgdGhpcy5wdXJnZUNsaWVudExvYWRlZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnB1cmdlQ2xpZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFRhZ0tleSh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuIHRhZztcbiAgICByZXR1cm4gYCR7Y29uZmlnLnZlcnNpb259LyR7c3RyaXBMZWFkaW5nU2xhc2godGFnKX1gO1xuICB9XG5cbiAgYXN5bmMgZ2V0TGFzdFJldmFsaWRhdGVkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gMDtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGxldCBtYXhSZXZhbGlkYXRlZEF0ID0gMDtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5yZXZhbGlkYXRlZEF0ICYmIHJvdy5yZXZhbGlkYXRlZEF0ID4gbWF4UmV2YWxpZGF0ZWRBdCkge1xuICAgICAgICAgIG1heFJldmFsaWRhdGVkQXQgPSByb3cucmV2YWxpZGF0ZWRBdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1heFJldmFsaWRhdGVkQXQ7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBnZXRMYXN0UmV2YWxpZGF0ZWQgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYXNCZWVuUmV2YWxpZGF0ZWQoXG4gICAgdGFnczogc3RyaW5nW10sXG4gICAgbGFzdE1vZGlmaWVkPzogbnVtYmVyXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0YWdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLmJhdGNoR2V0VGFncyhjb25maWcsIHRhZ3MpO1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5leHBpcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyb3cuZXhwaXJlIDw9IG5vdyAmJiByb3cuZXhwaXJlID4gbG0pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocm93LnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCAmJiByb3cucmV2YWxpZGF0ZWRBdCA+IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGhhc0JlZW5SZXZhbGlkYXRlZCBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpc1N0YWxlKHRhZ3M6IHN0cmluZ1tdLCBsYXN0TW9kaWZpZWQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5zdGFsZSA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgcmV2YWxpZGF0ZWRBdCA9IHJvdy5yZXZhbGlkYXRlZEF0ID8/IDA7XG4gICAgICAgIGlmIChyZXZhbGlkYXRlZEF0ID4gbG0gJiYgcm93LnN0YWxlID49IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGlzU3RhbGUgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgd3JpdGVUYWdzKHRhZ3M6IE5leHRNb2RlVGFnQ2FjaGVXcml0ZUlucHV0W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRhZ3MgfHwgdGFncy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybjtcblxuICAgIGNvbnN0IHdyaXRlVHMgPSBEYXRlLm5vdygpO1xuXG4gICAgY29uc3Qgcm93cyA9IHRhZ3MubWFwKGlucHV0ID0+IHtcbiAgICAgIGNvbnN0IHRhZ1N0ciA9IHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgPyBpbnB1dCA6IGlucHV0LnRhZztcbiAgICAgIGNvbnN0IHN0YWxlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LnN0YWxlO1xuICAgICAgY29uc3QgZXhwaXJlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LmV4cGlyZTtcbiAgICAgIGNvbnN0IHRhZ0tleSA9IHRoaXMuYnVpbGRUYWdLZXkodGFnU3RyKTtcblxuICAgICAgY29uc3QgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBudW1iZXIgfVtdID0gW1xuICAgICAgICB7IG5hbWU6ICdyZXZhbGlkYXRlZEF0JywgdmFsdWU6IHdyaXRlVHMgfSxcbiAgICAgIF07XG4gICAgICBpZiAoc3RhbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb2x1bW5zLnB1c2goeyBuYW1lOiAnc3RhbGUnLCB2YWx1ZTogc3RhbGUgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXhwaXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sdW1ucy5wdXNoKHsgbmFtZTogJ2V4cGlyZScsIHZhbHVlOiBleHBpcmUgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByaW1hcnlLZXk6IFtcbiAgICAgICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgICAgIHsgbmFtZTogJ3RhZycsIHZhbHVlOiB0YWdLZXkgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY29sdW1ucyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0aGlzLmJhdGNoV3JpdGUoY29uZmlnLCByb3dzKTtcblxuICAgIC8vIOWGmeW6k+aIkOWKn+WQjixmaXJlLWFuZC1mb3JnZXQg6Kem5Y+RIEVTQSDovrnnvJjnvJPlrZjlpLHmlYjjgIJcbiAgICAvLyDku7vkvZXlpLHotKXpg73kuI3lupTlm57ngYzliLDosIPnlKjmlrks5omA5LulIGNhdGNoIOebtOaOpSB3YXJuLOS4jSB0aHJvd+OAgeS4jSBhd2FpdOOAglxuICAgIGNvbnN0IHB1cmdlQ2xpZW50ID0gdGhpcy5nZXRQdXJnZUNsaWVudCgpO1xuICAgIGlmIChwdXJnZUNsaWVudCkge1xuICAgICAgY29uc3QgdGFnU3RycyA9IHRhZ3NcbiAgICAgICAgLm1hcCh0ID0+ICh0eXBlb2YgdCA9PT0gJ3N0cmluZycgPyB0IDogdC50YWcpKVxuICAgICAgICAuZmlsdGVyKChzKTogcyBpcyBzdHJpbmcgPT4gdHlwZW9mIHMgPT09ICdzdHJpbmcnICYmIHMubGVuZ3RoID4gMCk7XG4gICAgICBpZiAodGFnU3Rycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHB1cmdlQ2xpZW50LnB1cmdlQnlUYWdzKHRhZ1N0cnMpLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIHB1cmdlIGZhbi1vdXQgZmFpbGVkOiAke2Vycj8ubWVzc2FnZSA/PyBlcnJ9YCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0gcHJpdmF0ZSBtZXRob2RzIC0tLS1cblxuICBwcml2YXRlIGFzeW5jIGJhdGNoR2V0VGFncyhcbiAgICBjb25maWc6IEdhdGV3YXlBdXRoQ29uZmlnLFxuICAgIHRhZ3M6IHN0cmluZ1tdXG4gICk6IFByb21pc2U8VGFnUm93W10+IHtcbiAgICBjb25zdCBwcmltYXJ5S2V5cyA9IHRhZ3MubWFwKHRhZyA9PiBbXG4gICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgeyBuYW1lOiAndGFnJywgdmFsdWU6IHRoaXMuYnVpbGRUYWdLZXkodGFnKSB9LFxuICAgIF0pO1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC1nZXQtcm93Jywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcHJpbWFyeUtleXMgfSksXG4gICAgICB0aW1lb3V0TXM6IFFVRVJZX1RJTUVPVVQsXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlcy5vaykge1xuICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IHJlamVjdGVkICgke3Jlcy5zdGF0dXN9KWBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IGZhaWxlZDogc3RhdHVzPSR7cmVzLnN0YXR1c31gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIHtcbiAgICAgIHJvd3M/OiB7XG4gICAgICAgIHByaW1hcnlLZXk/OiBhbnlbXTtcbiAgICAgICAgY29sdW1ucz86IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIH1bXTtcbiAgICAgIH1bXTtcbiAgICB9O1xuXG4gICAgaWYgKCFkYXRhLnJvd3MpIHJldHVybiBbXTtcblxuICAgIHJldHVybiBkYXRhLnJvd3MubWFwKHJvdyA9PiB7XG4gICAgICBjb25zdCByZXN1bHQ6IFRhZ1JvdyA9IHt9O1xuICAgICAgZm9yIChjb25zdCBjb2wgb2Ygcm93LmNvbHVtbnMgPz8gW10pIHtcbiAgICAgICAgaWYgKGNvbC5uYW1lID09PSAncmV2YWxpZGF0ZWRBdCcgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQucmV2YWxpZGF0ZWRBdCA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ3N0YWxlJyAmJiB0eXBlb2YgY29sLnZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJlc3VsdC5zdGFsZSA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ2V4cGlyZScgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQuZXhwaXJlID0gY29sLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBiYXRjaFdyaXRlKFxuICAgIGNvbmZpZzogR2F0ZXdheUF1dGhDb25maWcsXG4gICAgcm93czoge1xuICAgICAgcHJpbWFyeUtleTogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgICAgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgIH1bXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocm93cy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkgKz0gQkFUQ0hfU0laRSkge1xuICAgICAgY29uc3QgYmF0Y2ggPSByb3dzLnNsaWNlKGksIGkgKyBCQVRDSF9TSVpFKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC13cml0ZScsIHtcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHJvd3M6IGJhdGNoIH0pLFxuICAgICAgICAgIHRpbWVvdXRNczogV1JJVEVfVElNRU9VVCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgcmVqZWN0ZWQgKCR7cmVzLnN0YXR1c30pYFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZXMub2spIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgZmFpbGVkOiBzdGF0dXM9JHtyZXMuc3RhdHVzfWApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBpZiAoZXJyLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC13cml0ZSB0aW1lb3V0ICgke1dSSVRFX1RJTUVPVVR9bXMpYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGJhdGNoLXdyaXRlIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
241
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9vdmVycmlkZXMvdGFnQ2FjaGUvZ2F0ZXdheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7O0dBS0c7O0FBRUgsNkRBSW9DO0FBQ3BDLHVEQUlpQztBQUVqQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFDM0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQztBQUV2QixTQUFTLGlCQUFpQixDQUFDLENBQVM7SUFDbEMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBZ0JELE1BQXFCLGVBQWU7SUFBcEM7UUFDRSxTQUFJLEdBQUcsbUJBQTRCLENBQUM7UUFDcEMsU0FBSSxHQUFHLFVBQW1CLENBQUM7UUFFbkIsV0FBTSxHQUE2QixJQUFJLENBQUM7UUFDeEMsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFckIsZ0JBQVcsR0FBMEIsSUFBSSxDQUFDO1FBQzFDLHNCQUFpQixHQUFHLEtBQUssQ0FBQztJQXVQcEMsQ0FBQztJQXJQUyxTQUFTO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFBLG9DQUFxQixHQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDMUI7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUVPLGNBQWM7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMzQixNQUFNLEdBQUcsR0FBRyxJQUFBLDhCQUFrQixHQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUEsZ0NBQW9CLEVBQUMsR0FBRyxDQUFDLENB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LENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRTtvQkFDNUMsT0FBTyxDQUFDLEtBQUssQ0FDWCxvQ0FBb0MsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUNsRCxDQUFDO29CQUNGLE9BQU87aUJBQ1I7Z0JBRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUU7b0JBQ1gsT0FBTyxDQUFDLElBQUksQ0FBQyx5Q0FBeUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7aUJBQ3JFO3FCQUFNO29CQUNMLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQW1DLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUNoRTthQUNGO1lBQUMsT0FBTyxHQUFRLEVBQUU7Z0JBQ2pCLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUU7b0JBQzdCLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLGFBQWEsS0FBSyxDQUFDLENBQUM7aUJBQ3JFO3FCQUFNO29CQUNMLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2lCQUM5RDthQUNGO1NBQ0Y7SUFDSCxDQUFDO0NBQ0Y7QUEvUEQsa0NBK1BDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHYXRld2F5IFRhZyDnvJPlrZggT3ZlcnJpZGUgKG5leHRNb2RlKVxuICpcbiAqIOS9v+eUqCBPcGVuTmV4dCDnmoQgbmV4dE1vZGUg5o6l5Y+j77yM6YCa6L+HIEdhdGV3YXkg5Luj55CG6K+75YaZIFRhYmxlU3RvcmXjgIJcbiAqIOmJtOadg+e7n+S4gOi1sCBydW50aW1lL2dhdGV3YXktYXV0aO+8iEhNQUMg562+5ZCNICsgNCBoZWFkZXLvvInjgIJcbiAqL1xuXG5pbXBvcnQge1xuICBsb2FkR2F0ZXdheUF1dGhDb25maWcsXG4gIGdhdGV3YXlGZXRjaCxcbiAgR2F0ZXdheUF1dGhDb25maWcsXG59IGZyb20gJy4uLy4uL3J1bnRpbWUvZ2F0ZXdheS1hdXRoJztcbmltcG9ydCB7XG4gIGxvYWRDZG5QdXJnZUNvbmZpZyxcbiAgY3JlYXRlQ2RuUHVyZ2VDbGllbnQsXG4gIENkblB1cmdlQ2xpZW50LFxufSBmcm9tICcuLi8uLi9ydW50aW1lL2Nkbi1wdXJnZSc7XG5cbmNvbnN0IFFVRVJZX1RJTUVPVVQgPSAzMDAwO1xuY29uc3QgV1JJVEVfVElNRU9VVCA9IDUwMDA7XG5jb25zdCBCQVRDSF9TSVpFID0gMjAwO1xuXG5mdW5jdGlvbiBzdHJpcExlYWRpbmdTbGFzaChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKC9eXFwvKy8sICcnKTtcbn1cblxudHlwZSBOZXh0TW9kZVRhZ0NhY2hlV3JpdGVJbnB1dCA9XG4gIHwgc3RyaW5nXG4gIHwge1xuICAgICAgdGFnOiBzdHJpbmc7XG4gICAgICBzdGFsZT86IG51bWJlcjtcbiAgICAgIGV4cGlyZT86IG51bWJlcjtcbiAgICB9O1xuXG5pbnRlcmZhY2UgVGFnUm93IHtcbiAgcmV2YWxpZGF0ZWRBdD86IG51bWJlcjtcbiAgc3RhbGU/OiBudW1iZXI7XG4gIGV4cGlyZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2F0ZXdheVRhZ0NhY2hlIHtcbiAgbmFtZSA9ICdnYXRld2F5LXRhZy1jYWNoZScgYXMgY29uc3Q7XG4gIG1vZGUgPSAnbmV4dE1vZGUnIGFzIGNvbnN0O1xuXG4gIHByaXZhdGUgY29uZmlnOiBHYXRld2F5QXV0aENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbmZpZ0xvYWRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgcHVyZ2VDbGllbnQ6IENkblB1cmdlQ2xpZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcHVyZ2VDbGllbnRMb2FkZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIGdldENvbmZpZygpOiBHYXRld2F5QXV0aENvbmZpZyB8IG51bGwge1xuICAgIGlmICghdGhpcy5jb25maWdMb2FkZWQpIHtcbiAgICAgIHRoaXMuY29uZmlnID0gbG9hZEdhdGV3YXlBdXRoQ29uZmlnKCk7XG4gICAgICB0aGlzLmNvbmZpZ0xvYWRlZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbmZpZztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UHVyZ2VDbGllbnQoKTogQ2RuUHVyZ2VDbGllbnQgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMucHVyZ2VDbGllbnRMb2FkZWQpIHtcbiAgICAgIGNvbnN0IGNmZyA9IGxvYWRDZG5QdXJnZUNvbmZpZygpO1xuICAgICAgdGhpcy5wdXJnZUNsaWVudCA9IGNmZyA/IGNyZWF0ZUNkblB1cmdlQ2xpZW50KGNmZykgOiBudWxsO1xuICAgICAgdGhpcy5wdXJnZUNsaWVudExvYWRlZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnB1cmdlQ2xpZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFRhZ0tleSh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuIHRhZztcbiAgICByZXR1cm4gYCR7Y29uZmlnLnZlcnNpb259LyR7c3RyaXBMZWFkaW5nU2xhc2godGFnKX1gO1xuICB9XG5cbiAgYXN5bmMgZ2V0TGFzdFJldmFsaWRhdGVkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gMDtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGxldCBtYXhSZXZhbGlkYXRlZEF0ID0gMDtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5yZXZhbGlkYXRlZEF0ICYmIHJvdy5yZXZhbGlkYXRlZEF0ID4gbWF4UmV2YWxpZGF0ZWRBdCkge1xuICAgICAgICAgIG1heFJldmFsaWRhdGVkQXQgPSByb3cucmV2YWxpZGF0ZWRBdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1heFJldmFsaWRhdGVkQXQ7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBnZXRMYXN0UmV2YWxpZGF0ZWQgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYXNCZWVuUmV2YWxpZGF0ZWQoXG4gICAgdGFnczogc3RyaW5nW10sXG4gICAgbGFzdE1vZGlmaWVkPzogbnVtYmVyXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0YWdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLmJhdGNoR2V0VGFncyhjb25maWcsIHRhZ3MpO1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5leHBpcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyb3cuZXhwaXJlIDw9IG5vdyAmJiByb3cuZXhwaXJlID4gbG0pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocm93LnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCAmJiByb3cucmV2YWxpZGF0ZWRBdCA+IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGhhc0JlZW5SZXZhbGlkYXRlZCBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpc1N0YWxlKHRhZ3M6IHN0cmluZ1tdLCBsYXN0TW9kaWZpZWQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5iYXRjaEdldFRhZ3MoY29uZmlnLCB0YWdzKTtcbiAgICAgIGNvbnN0IGxtID0gbGFzdE1vZGlmaWVkID8/IDA7XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgaWYgKHJvdy5zdGFsZSA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgcmV2YWxpZGF0ZWRBdCA9IHJvdy5yZXZhbGlkYXRlZEF0ID8/IDA7XG4gICAgICAgIGlmIChyZXZhbGlkYXRlZEF0ID4gbG0gJiYgcm93LnN0YWxlID49IGxtKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGlzU3RhbGUgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgd3JpdGVUYWdzKHRhZ3M6IE5leHRNb2RlVGFnQ2FjaGVXcml0ZUlucHV0W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRhZ3MgfHwgdGFncy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybjtcblxuICAgIGNvbnN0IHdyaXRlVHMgPSBEYXRlLm5vdygpO1xuXG4gICAgY29uc3Qgcm93cyA9IHRhZ3MubWFwKGlucHV0ID0+IHtcbiAgICAgIGNvbnN0IHRhZ1N0ciA9IHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgPyBpbnB1dCA6IGlucHV0LnRhZztcbiAgICAgIGNvbnN0IHN0YWxlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LnN0YWxlO1xuICAgICAgY29uc3QgZXhwaXJlID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/IHVuZGVmaW5lZCA6IGlucHV0LmV4cGlyZTtcbiAgICAgIGNvbnN0IHRhZ0tleSA9IHRoaXMuYnVpbGRUYWdLZXkodGFnU3RyKTtcblxuICAgICAgY29uc3QgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBudW1iZXIgfVtdID0gW1xuICAgICAgICB7IG5hbWU6ICdyZXZhbGlkYXRlZEF0JywgdmFsdWU6IHdyaXRlVHMgfSxcbiAgICAgIF07XG4gICAgICBpZiAoc3RhbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb2x1bW5zLnB1c2goeyBuYW1lOiAnc3RhbGUnLCB2YWx1ZTogc3RhbGUgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXhwaXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29sdW1ucy5wdXNoKHsgbmFtZTogJ2V4cGlyZScsIHZhbHVlOiBleHBpcmUgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByaW1hcnlLZXk6IFtcbiAgICAgICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgICAgIHsgbmFtZTogJ3RhZycsIHZhbHVlOiB0YWdLZXkgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY29sdW1ucyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0aGlzLmJhdGNoV3JpdGUoY29uZmlnLCByb3dzKTtcblxuICAgIC8vIOWGmeW6k+aIkOWKn+WQjixmaXJlLWFuZC1mb3JnZXQg6Kem5Y+RIEVTQSDovrnnvJjnvJPlrZjlpLHmlYjjgIJcbiAgICAvLyDku7vkvZXlpLHotKXpg73kuI3lupTlm57ngYzliLDosIPnlKjmlrks5omA5LulIGNhdGNoIOebtOaOpSB3YXJuLOS4jSB0aHJvd+OAgeS4jSBhd2FpdOOAglxuICAgIGNvbnN0IHB1cmdlQ2xpZW50ID0gdGhpcy5nZXRQdXJnZUNsaWVudCgpO1xuICAgIGlmIChwdXJnZUNsaWVudCkge1xuICAgICAgY29uc3QgdGFnU3RycyA9IHRhZ3NcbiAgICAgICAgLm1hcCh0ID0+ICh0eXBlb2YgdCA9PT0gJ3N0cmluZycgPyB0IDogdC50YWcpKVxuICAgICAgICAuZmlsdGVyKChzKTogcyBpcyBzdHJpbmcgPT4gdHlwZW9mIHMgPT09ICdzdHJpbmcnICYmIHMubGVuZ3RoID4gMCk7XG4gICAgICBpZiAodGFnU3Rycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHB1cmdlQ2xpZW50LnB1cmdlQnlUYWdzKHRhZ1N0cnMpLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIHB1cmdlIGZhbi1vdXQgZmFpbGVkOiAke2Vycj8ubWVzc2FnZSA/PyBlcnJ9YCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0gcHJpdmF0ZSBtZXRob2RzIC0tLS1cblxuICBwcml2YXRlIGFzeW5jIGJhdGNoR2V0VGFncyhcbiAgICBjb25maWc6IEdhdGV3YXlBdXRoQ29uZmlnLFxuICAgIHRhZ3M6IHN0cmluZ1tdXG4gICk6IFByb21pc2U8VGFnUm93W10+IHtcbiAgICBjb25zdCBwcmltYXJ5S2V5cyA9IHRhZ3MubWFwKHRhZyA9PiBbXG4gICAgICB7IG5hbWU6ICdhcHBfaWQnLCB2YWx1ZTogYCR7Y29uZmlnLmFsaXVpZH0vJHtjb25maWcucm91dGluZW5hbWV9YCB9LFxuICAgICAgeyBuYW1lOiAndGFnJywgdmFsdWU6IHRoaXMuYnVpbGRUYWdLZXkodGFnKSB9LFxuICAgIF0pO1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC1nZXQtcm93Jywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcHJpbWFyeUtleXMgfSksXG4gICAgICB0aW1lb3V0TXM6IFFVRVJZX1RJTUVPVVQsXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlcy5vaykge1xuICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IHJlamVjdGVkICgke3Jlcy5zdGF0dXN9KWBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IGZhaWxlZDogc3RhdHVzPSR7cmVzLnN0YXR1c31gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIHtcbiAgICAgIHJvd3M/OiB7XG4gICAgICAgIHByaW1hcnlLZXk/OiBhbnlbXTtcbiAgICAgICAgY29sdW1ucz86IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIH1bXTtcbiAgICAgIH1bXTtcbiAgICB9O1xuXG4gICAgY29uc29sZS5sb2coXG4gICAgICBgW3RhZ0NhY2hlXSBiYXRjaC1nZXQtcm93IG9rOiB0YWdzPSR7dGFncy5sZW5ndGh9IHJvd3M9JHtkYXRhLnJvd3M/Lmxlbmd0aCA/PyAwfWBcbiAgICApO1xuXG4gICAgaWYgKCFkYXRhLnJvd3MpIHJldHVybiBbXTtcblxuICAgIHJldHVybiBkYXRhLnJvd3MubWFwKHJvdyA9PiB7XG4gICAgICBjb25zdCByZXN1bHQ6IFRhZ1JvdyA9IHt9O1xuICAgICAgZm9yIChjb25zdCBjb2wgb2Ygcm93LmNvbHVtbnMgPz8gW10pIHtcbiAgICAgICAgaWYgKGNvbC5uYW1lID09PSAncmV2YWxpZGF0ZWRBdCcgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQucmV2YWxpZGF0ZWRBdCA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ3N0YWxlJyAmJiB0eXBlb2YgY29sLnZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJlc3VsdC5zdGFsZSA9IGNvbC52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2wubmFtZSA9PT0gJ2V4cGlyZScgJiYgdHlwZW9mIGNvbC52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXN1bHQuZXhwaXJlID0gY29sLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBiYXRjaFdyaXRlKFxuICAgIGNvbmZpZzogR2F0ZXdheUF1dGhDb25maWcsXG4gICAgcm93czoge1xuICAgICAgcHJpbWFyeUtleTogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgICAgY29sdW1uczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfVtdO1xuICAgIH1bXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocm93cy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkgKz0gQkFUQ0hfU0laRSkge1xuICAgICAgY29uc3QgYmF0Y2ggPSByb3dzLnNsaWNlKGksIGkgKyBCQVRDSF9TSVpFKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNvbmZpZywgJy90YWJsZS9iYXRjaC13cml0ZScsIHtcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHJvd3M6IGJhdGNoIH0pLFxuICAgICAgICAgIHRpbWVvdXRNczogV1JJVEVfVElNRU9VVCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSB8fCByZXMuc3RhdHVzID09PSA0MDMpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgcmVqZWN0ZWQgKCR7cmVzLnN0YXR1c30pYFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZXMub2spIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFt0YWdDYWNoZV0gYmF0Y2gtd3JpdGUgZmFpbGVkOiBzdGF0dXM9JHtyZXMuc3RhdHVzfWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbdGFnQ2FjaGVdIGJhdGNoLXdyaXRlIG9rOiByb3dzPSR7YmF0Y2gubGVuZ3RofWApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBpZiAoZXJyLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICAgIGNvbnNvbGUud2FybihgW3RhZ0NhY2hlXSBiYXRjaC13cml0ZSB0aW1lb3V0ICgke1dSSVRFX1RJTUVPVVR9bXMpYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbdGFnQ2FjaGVdIGJhdGNoLXdyaXRlIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -9,14 +9,15 @@
|
|
|
9
9
|
* 运行时第一次用到时 lazy 加载到内存 Map,后续 O(1) 查询,无网络往返
|
|
10
10
|
* - /cache/refresh 走 Gateway,沿用现有 HMAC 鉴权 + ESA 分流
|
|
11
11
|
* - 所有失败仅 warn,绝不抛错(purge 是优化,不是正确性)
|
|
12
|
-
* - hostname / siteId
|
|
12
|
+
* - hostname / siteId 走 per-request edge-context(AsyncLocalStorage),
|
|
13
|
+
* 由 node-server wrapper 从入站请求 header 注入;ctx 缺这两项时 skip + warn,
|
|
14
|
+
* 不再静默生效。鉴权(5 env)缺失则 loadCdnPurgeConfig 返回 null,
|
|
15
|
+
* 上游降级 no-op,连 client 都不构造。
|
|
13
16
|
* - 跨 tag 反查结果去重,每 path 追加 /_next/data/{buildId}/{path}.json
|
|
14
17
|
* - 调 /cache/refresh 时按 100 URL/批、batch 内并发上限 4
|
|
15
18
|
*/
|
|
16
19
|
import { GatewayAuthConfig } from './gateway-auth';
|
|
17
20
|
export interface CdnPurgeConfig extends GatewayAuthConfig {
|
|
18
|
-
hostname: string;
|
|
19
|
-
siteId: string | number;
|
|
20
21
|
/**
|
|
21
22
|
* 覆盖默认 manifest 路径,主要给测试用。
|
|
22
23
|
* 默认 = path.join(__dirname, '__pcg_tag_manifest.json'),
|
|
@@ -37,13 +38,16 @@ export interface CdnPurgeClient {
|
|
|
37
38
|
purgeByTags(tags: string[]): Promise<void>;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
|
-
*
|
|
41
|
+
* 加载 purge 配置。
|
|
41
42
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* hostname / siteId 不再从 env 取,改由 node-server wrapper 在入口
|
|
44
|
+
* runWithEdgeContext(headers, …) 把请求头里的 host 与 x-alicdn-site-id 注入
|
|
45
|
+
* AsyncLocalStorage,refreshBatch 时即时读取。原因:
|
|
46
|
+
* - 一个 routine 可能服务多 site / 多 hostname,启动期 env 无法表达
|
|
47
|
+
* - 本地 dev 若没带头,这次 purge 直接 skip + warn,不再静默生效
|
|
45
48
|
*
|
|
46
|
-
*
|
|
49
|
+
* 复用 loadGatewayAuthConfig 的 5 个 env 做 HMAC 鉴权 / endpoint 选取。
|
|
50
|
+
* 缺这五个 env 返回 null,调用方应跳过 purge(不影响 tag 写库)。
|
|
47
51
|
*/
|
|
48
52
|
export declare function loadCdnPurgeConfig(): CdnPurgeConfig | null;
|
|
49
53
|
export declare function createCdnPurgeClient(cfg: CdnPurgeConfig): CdnPurgeClient;
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
* 运行时第一次用到时 lazy 加载到内存 Map,后续 O(1) 查询,无网络往返
|
|
11
11
|
* - /cache/refresh 走 Gateway,沿用现有 HMAC 鉴权 + ESA 分流
|
|
12
12
|
* - 所有失败仅 warn,绝不抛错(purge 是优化,不是正确性)
|
|
13
|
-
* - hostname / siteId
|
|
13
|
+
* - hostname / siteId 走 per-request edge-context(AsyncLocalStorage),
|
|
14
|
+
* 由 node-server wrapper 从入站请求 header 注入;ctx 缺这两项时 skip + warn,
|
|
15
|
+
* 不再静默生效。鉴权(5 env)缺失则 loadCdnPurgeConfig 返回 null,
|
|
16
|
+
* 上游降级 no-op,连 client 都不构造。
|
|
14
17
|
* - 跨 tag 反查结果去重,每 path 追加 /_next/data/{buildId}/{path}.json
|
|
15
18
|
* - 调 /cache/refresh 时按 100 URL/批、batch 内并发上限 4
|
|
16
19
|
*/
|
|
@@ -19,6 +22,7 @@ exports.createCdnPurgeClient = exports.loadCdnPurgeConfig = void 0;
|
|
|
19
22
|
const fs = require("fs");
|
|
20
23
|
const path = require("path");
|
|
21
24
|
const gateway_auth_1 = require("./gateway-auth");
|
|
25
|
+
const edge_context_1 = require("./edge-context");
|
|
22
26
|
const REFRESH_TIMEOUT_MS = 15000;
|
|
23
27
|
const URL_BATCH_SIZE = 100;
|
|
24
28
|
const REFRESH_CONCURRENCY = 4;
|
|
@@ -31,32 +35,22 @@ function ensureLeadingSlash(s) {
|
|
|
31
35
|
return s.startsWith('/') ? s : `/${s}`;
|
|
32
36
|
}
|
|
33
37
|
/**
|
|
34
|
-
*
|
|
38
|
+
* 加载 purge 配置。
|
|
35
39
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
40
|
+
* hostname / siteId 不再从 env 取,改由 node-server wrapper 在入口
|
|
41
|
+
* runWithEdgeContext(headers, …) 把请求头里的 host 与 x-alicdn-site-id 注入
|
|
42
|
+
* AsyncLocalStorage,refreshBatch 时即时读取。原因:
|
|
43
|
+
* - 一个 routine 可能服务多 site / 多 hostname,启动期 env 无法表达
|
|
44
|
+
* - 本地 dev 若没带头,这次 purge 直接 skip + warn,不再静默生效
|
|
39
45
|
*
|
|
40
|
-
*
|
|
46
|
+
* 复用 loadGatewayAuthConfig 的 5 个 env 做 HMAC 鉴权 / endpoint 选取。
|
|
47
|
+
* 缺这五个 env 返回 null,调用方应跳过 purge(不影响 tag 写库)。
|
|
41
48
|
*/
|
|
42
49
|
function loadCdnPurgeConfig() {
|
|
43
50
|
const base = (0, gateway_auth_1.loadGatewayAuthConfig)();
|
|
44
51
|
if (!base)
|
|
45
52
|
return null;
|
|
46
|
-
|
|
47
|
-
const siteIdRaw = process.env.ESA_CACHE_GW_SITE_ID;
|
|
48
|
-
if (!hostname || !siteIdRaw) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
const siteIdNum = Number(siteIdRaw);
|
|
52
|
-
const siteId = Number.isFinite(siteIdNum)
|
|
53
|
-
? siteIdNum
|
|
54
|
-
: siteIdRaw;
|
|
55
|
-
return {
|
|
56
|
-
...base,
|
|
57
|
-
hostname,
|
|
58
|
-
siteId,
|
|
59
|
-
};
|
|
53
|
+
return { ...base };
|
|
60
54
|
}
|
|
61
55
|
exports.loadCdnPurgeConfig = loadCdnPurgeConfig;
|
|
62
56
|
function createCdnPurgeClient(cfg) {
|
|
@@ -114,9 +108,12 @@ function createCdnPurgeClient(cfg) {
|
|
|
114
108
|
bucket.add(p);
|
|
115
109
|
}
|
|
116
110
|
const result = new Map();
|
|
111
|
+
let totalEntries = 0;
|
|
117
112
|
for (const [tag, set] of map) {
|
|
118
113
|
result.set(tag, Array.from(set));
|
|
114
|
+
totalEntries += set.size;
|
|
119
115
|
}
|
|
116
|
+
console.log(`[cdn-purge] manifest loaded: tags=${result.size} entries=${totalEntries} (${manifestPath})`);
|
|
120
117
|
return result;
|
|
121
118
|
})();
|
|
122
119
|
return manifestPromise;
|
|
@@ -127,7 +124,7 @@ function createCdnPurgeClient(cfg) {
|
|
|
127
124
|
* - 对每个 path 追加 /_next/data/{buildId}/{path}.json
|
|
128
125
|
* - 拼上 https://{hostname}
|
|
129
126
|
*/
|
|
130
|
-
function expandPathsToUrls(paths) {
|
|
127
|
+
function expandPathsToUrls(paths, hostname) {
|
|
131
128
|
const normalized = new Set();
|
|
132
129
|
for (const p of paths) {
|
|
133
130
|
if (!p)
|
|
@@ -138,18 +135,18 @@ function createCdnPurgeClient(cfg) {
|
|
|
138
135
|
return [];
|
|
139
136
|
const urls = new Set();
|
|
140
137
|
for (const p of normalized) {
|
|
141
|
-
urls.add(`https://${
|
|
138
|
+
urls.add(`https://${hostname}${p}`);
|
|
142
139
|
const rel = stripLeadingSlash(p);
|
|
143
140
|
// pages router ISR 必需;app router 多打一条无副作用
|
|
144
|
-
urls.add(`https://${
|
|
141
|
+
urls.add(`https://${hostname}/_next/data/${buildId}/${rel || 'index'}.json`);
|
|
145
142
|
}
|
|
146
143
|
return Array.from(urls);
|
|
147
144
|
}
|
|
148
|
-
async function refreshBatch(urls) {
|
|
145
|
+
async function refreshBatch(urls, hostname, siteId) {
|
|
149
146
|
var _a;
|
|
150
147
|
const body = {
|
|
151
|
-
hostname
|
|
152
|
-
siteId
|
|
148
|
+
hostname,
|
|
149
|
+
siteId,
|
|
153
150
|
urls,
|
|
154
151
|
};
|
|
155
152
|
let res;
|
|
@@ -174,9 +171,11 @@ function createCdnPurgeClient(cfg) {
|
|
|
174
171
|
/* ignore */
|
|
175
172
|
}
|
|
176
173
|
console.warn(`[cdn-purge] cache/refresh failed status=${res.status} urls=${urls.length} ${detail}`);
|
|
174
|
+
return;
|
|
177
175
|
}
|
|
176
|
+
console.log(`[cdn-purge] cache/refresh ok: urls=${urls.length}`);
|
|
178
177
|
}
|
|
179
|
-
async function refreshUrls(allUrls) {
|
|
178
|
+
async function refreshUrls(allUrls, hostname, siteId) {
|
|
180
179
|
if (allUrls.length === 0)
|
|
181
180
|
return;
|
|
182
181
|
const batches = [];
|
|
@@ -188,17 +187,34 @@ function createCdnPurgeClient(cfg) {
|
|
|
188
187
|
async function worker() {
|
|
189
188
|
while (cursor < batches.length) {
|
|
190
189
|
const idx = cursor++;
|
|
191
|
-
await refreshBatch(batches[idx]);
|
|
190
|
+
await refreshBatch(batches[idx], hostname, siteId);
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
const workers = Array.from({ length: Math.min(REFRESH_CONCURRENCY, batches.length) }, () => worker());
|
|
195
194
|
await Promise.all(workers);
|
|
196
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* 从当前请求的 AsyncLocalStorage 拿 hostname/siteId。
|
|
198
|
+
* 缺任一即返回 null,调用方 warn 后 skip — 本地无 header 路径就是这条降级。
|
|
199
|
+
*/
|
|
200
|
+
function resolveTarget(action) {
|
|
201
|
+
const { hostname, siteId } = (0, edge_context_1.getEdgeContext)();
|
|
202
|
+
if (!hostname || siteId === undefined || siteId === '') {
|
|
203
|
+
console.warn(`[cdn-purge] ${action} skip: edge context missing (hostname=${hostname !== null && hostname !== void 0 ? hostname : '∅'} siteId=${siteId !== null && siteId !== void 0 ? siteId : '∅'}); ` +
|
|
204
|
+
`要求入站请求带 host 与 x-alicdn-site-id`);
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
return { hostname, siteId };
|
|
208
|
+
}
|
|
197
209
|
async function purgeByPaths(paths) {
|
|
198
210
|
var _a;
|
|
199
211
|
try {
|
|
200
|
-
const
|
|
201
|
-
|
|
212
|
+
const target = resolveTarget('purgeByPaths');
|
|
213
|
+
if (!target)
|
|
214
|
+
return;
|
|
215
|
+
const urls = expandPathsToUrls(paths, target.hostname);
|
|
216
|
+
console.log(`[cdn-purge] purgeByPaths: input=${paths.length} urls=${urls.length}`);
|
|
217
|
+
await refreshUrls(urls, target.hostname, target.siteId);
|
|
202
218
|
}
|
|
203
219
|
catch (err) {
|
|
204
220
|
console.warn(`[cdn-purge] purgeByPaths error: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
@@ -213,6 +229,9 @@ function createCdnPurgeClient(cfg) {
|
|
|
213
229
|
.filter(Boolean)));
|
|
214
230
|
if (uniqueTags.length === 0)
|
|
215
231
|
return;
|
|
232
|
+
const target = resolveTarget('purgeByTags');
|
|
233
|
+
if (!target)
|
|
234
|
+
return;
|
|
216
235
|
const map = await loadManifest();
|
|
217
236
|
const merged = new Set();
|
|
218
237
|
for (const t of uniqueTags) {
|
|
@@ -222,10 +241,13 @@ function createCdnPurgeClient(cfg) {
|
|
|
222
241
|
for (const p of paths)
|
|
223
242
|
merged.add(p);
|
|
224
243
|
}
|
|
225
|
-
if (merged.size === 0)
|
|
244
|
+
if (merged.size === 0) {
|
|
245
|
+
console.log(`[cdn-purge] purgeByTags: input=${uniqueTags.length} matched=0 (manifest miss, skip)`);
|
|
226
246
|
return;
|
|
227
|
-
|
|
228
|
-
|
|
247
|
+
}
|
|
248
|
+
const urls = expandPathsToUrls(Array.from(merged), target.hostname);
|
|
249
|
+
console.log(`[cdn-purge] purgeByTags: input=${uniqueTags.length} matched=${merged.size} urls=${urls.length}`);
|
|
250
|
+
await refreshUrls(urls, target.hostname, target.siteId);
|
|
229
251
|
}
|
|
230
252
|
catch (err) {
|
|
231
253
|
console.warn(`[cdn-purge] purgeByTags error: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}`);
|
|
@@ -234,4 +256,4 @@ function createCdnPurgeClient(cfg) {
|
|
|
234
256
|
return { purgeByPaths, purgeByTags };
|
|
235
257
|
}
|
|
236
258
|
exports.createCdnPurgeClient = createCdnPurgeClient;
|
|
237
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RuLXB1cmdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvY2RuLXB1cmdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7R0FjRzs7O0FBRUgseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUU3QixpREFJd0I7QUFFeEIsTUFBTSxrQkFBa0IsR0FBRyxLQUFNLENBQUM7QUFFbEMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBQzNCLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBRTlCLHVEQUF1RDtBQUN2RCxNQUFNLHFCQUFxQixHQUFHLHlCQUF5QixDQUFDO0FBMkJ4RCxTQUFTLGlCQUFpQixDQUFDLENBQVM7SUFDbEMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxDQUFTO0lBQ25DLE9BQU8sQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO0FBQ3pDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLGtCQUFrQjtJQUNoQyxNQUFNLElBQUksR0FBRyxJQUFBLG9DQUFxQixHQUFFLENBQUM7SUFDckMsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUV2QixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDO0lBQ25ELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7SUFFbkQsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFNBQVMsRUFBRTtRQUMzQixPQUFPLElBQUksQ0FBQztLQUNiO0lBRUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BD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LE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDdEM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQztnQkFBRSxPQUFPO1lBRTlCLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNuRCxNQUFNLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN6QjtRQUFDLE9BQU8sR0FBUSxFQUFFO1lBQ2pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLE1BQUEsR0FBRyxhQUFILEdBQUcsdUJBQUgsR0FBRyxDQUFFLE9BQU8sbUNBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztTQUN2RTtJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUEzTEQsb0RBMkxDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDRE4gUHVyZ2UgUnVudGltZVxuICpcbiAqIOWcqCByZXZhbGlkYXRlVGFnIC8gcmV2YWxpZGF0ZVBhdGgg5ZCOLGZpcmUtYW5kLWZvcmdldCDop6blj5EgRVNBIOi+uee8mOe8k+WtmOWkseaViOOAglxuICpcbiAqIOiuvuiuoeWOn+WImTpcbiAqICAgLSB0YWcg4oaSIHBhdGhzIOWPjeafpei1sCAqKuacrOWcsCoqIG1hbmlmZXN0KGJ1aWxkIOaXtueUsSBwY2cgYnVpbGQg5oqKXG4gKiAgICAgLm9wZW4tbmV4dC9keW5hbW9kYi1wcm92aWRlci9keW5hbW9kYi1jYWNoZS5qc29uIOW1jOWFpSBGQyBidW5kbGUpLFxuICogICAgIOi/kOihjOaXtuesrOS4gOasoeeUqOWIsOaXtiBsYXp5IOWKoOi9veWIsOWGheWtmCBNYXAs5ZCO57utIE8oMSkg5p+l6K+iLOaXoOe9kee7nOW+gOi/lFxuICogICAtIC9jYWNoZS9yZWZyZXNoIOi1sCBHYXRld2F5LOayv+eUqOeOsOaciSBITUFDIOmJtOadgyArIEVTQSDliIbmtYFcbiAqICAgLSDmiYDmnInlpLHotKXku4Ugd2Fybiznu53kuI3mipvplJkocHVyZ2Ug5piv5LyY5YyWLOS4jeaYr+ato+ehruaApylcbiAqICAgLSBob3N0bmFtZSAvIHNpdGVJZCDnvLrlpLHliJkgbG9hZENkblB1cmdlQ29uZmlnIOi/lOWbniBudWxsLOiwg+eUqOaWuemZjee6pyBuby1vcFxuICogICAtIOi3qCB0YWcg5Y+N5p+l57uT5p6c5Y676YeNLOavjyBwYXRoIOi/veWKoCAvX25leHQvZGF0YS97YnVpbGRJZH0ve3BhdGh9Lmpzb25cbiAqICAgLSDosIMgL2NhY2hlL3JlZnJlc2gg5pe25oyJIDEwMCBVUkwv5om544CBYmF0Y2gg5YaF5bm25Y+R5LiK6ZmQIDRcbiAqL1xuXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ2FjaGVSZWZyZXNoUmVxdWVzdCB9IGZyb20gJ0BwY2cvcHJvdG9jb2wnO1xuaW1wb3J0IHtcbiAgbG9hZEdhdGV3YXlBdXRoQ29uZmlnLFxuICBnYXRld2F5RmV0Y2gsXG4gIEdhdGV3YXlBdXRoQ29uZmlnLFxufSBmcm9tICcuL2dhdGV3YXktYXV0aCc7XG5cbmNvbnN0IFJFRlJFU0hfVElNRU9VVF9NUyA9IDE1XzAwMDtcblxuY29uc3QgVVJMX0JBVENIX1NJWkUgPSAxMDA7XG5jb25zdCBSRUZSRVNIX0NPTkNVUlJFTkNZID0gNDtcblxuLy8g5LiOIGJ1aWxkLnRzIOS4rSBUQUdfTUFOSUZFU1RfRklMRU5BTUUg5L+d5oyB5LiA6Ie0KOWvueS+p+aYr+WGmeWFpSzov5nkvqfmmK/or7vlj5YpXG5jb25zdCBUQUdfTUFOSUZFU1RfRklMRU5BTUUgPSAnX19wY2dfdGFnX21hbmlmZXN0Lmpzb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIENkblB1cmdlQ29uZmlnIGV4dGVuZHMgR2F0ZXdheUF1dGhDb25maWcge1xuICBob3N0bmFtZTogc3RyaW5nO1xuICBzaXRlSWQ6IHN0cmluZyB8IG51bWJlcjtcbiAgLyoqXG4gICAqIOimhueblum7mOiupCBtYW5pZmVzdCDot6/lvoQs5Li76KaB57uZ5rWL6K+V55So44CCXG4gICAqIOm7mOiupCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdfX3BjZ190YWdfbWFuaWZlc3QuanNvbicpLFxuICAgKiDljbMgRkMgYnVuZGxlIOWGheS4jiBjYWNoZS5janMg5ZCM57qn44CCXG4gICAqL1xuICBtYW5pZmVzdFBhdGg/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2RuUHVyZ2VDbGllbnQge1xuICAvKipcbiAgICog5byC5q2l6Kem5Y+RIEVTQSDnvJPlrZjlpLHmlYjjgILkuI3pmLvloZ7osIPnlKjmlrks5aSx6LSl5LuFIHdhcm7jgIJcbiAgICog5YaF6YOo5a6M5oiQIHBhdGgg5Y676YeNICsgSVNSIOaVsOaNrui3r+W+hOihpeWFqCArIOmZkOa1geOAglxuICAgKi9cbiAgcHVyZ2VCeVBhdGhzKHBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD47XG5cbiAgLyoqXG4gICAqIHRhZyDihpIgcGF0aHMg5Y+N5p+lICsgcHVyZ2XjgIJcbiAgICog5Y+N5p+l6LWw5pys5Zyw5bWM5YWl55qEIG1hbmlmZXN0IOaWh+S7tizml6DnvZHnu5wgSU/jgIJcbiAgICovXG4gIHB1cmdlQnlUYWdzKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPjtcbn1cblxuZnVuY3Rpb24gc3RyaXBMZWFkaW5nU2xhc2goczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHMucmVwbGFjZSgvXlxcLysvLCAnJyk7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUxlYWRpbmdTbGFzaChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5zdGFydHNXaXRoKCcvJykgPyBzIDogYC8ke3N9YDtcbn1cblxuLyoqXG4gKiDku47njq/looPlj5jph4/liqDovb0gcHVyZ2Ug6YWN572u44CCXG4gKlxuICog5rK/55SoIGxvYWRHYXRld2F5QXV0aENvbmZpZyDnmoQgNSDkuKogZW52LOmineWkluivu+WPljpcbiAqICAgLSBFU0FfQ0FDSEVfR1dfSE9TVE5BTUUg4oCUIOaLvCBwdXJnZSBVUkwg55SoXG4gKiAgIC0gRVNBX0NBQ0hFX0dXX1NJVEVfSUQgIOKAlCDpgI/kvKDnu5kgL2NhY2hlL3JlZnJlc2hcbiAqXG4gKiDnvLrkuIDov5Tlm54gbnVsbCzosIPnlKjmlrnlupTot7Pov4cgcHVyZ2Uo5LiN5b2x5ZONIHRhZyDlhpnlupMp44CCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkQ2RuUHVyZ2VDb25maWcoKTogQ2RuUHVyZ2VDb25maWcgfCBudWxsIHtcbiAgY29uc3QgYmFzZSA9IGxvYWRHYXRld2F5QXV0aENvbmZpZygpO1xuICBpZiAoIWJhc2UpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGhvc3RuYW1lID0gcHJvY2Vzcy5lbnYuRVNBX0NBQ0hFX0dXX0hPU1ROQU1FO1xuICBjb25zdCBzaXRlSWRSYXcgPSBwcm9jZXNzLmVudi5FU0FfQ0FDSEVfR1dfU0lURV9JRDtcblxuICBpZiAoIWhvc3RuYW1lIHx8ICFzaXRlSWRSYXcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHNpdGVJZE51bSA9IE51bWJlcihzaXRlSWRSYXcpO1xuICBjb25zdCBzaXRlSWQ6IHN0cmluZyB8IG51bWJlciA9IE51bWJlci5pc0Zpbml0ZShzaXRlSWROdW0pXG4gICAgPyBzaXRlSWROdW1cbiAgICA6IHNpdGVJZFJhdztcblxuICByZXR1cm4ge1xuICAgIC4uLmJhc2UsXG4gICAgaG9zdG5hbWUsXG4gICAgc2l0ZUlkLFxuICB9O1xufVxuXG4vKipcbiAqIGR5bmFtb2RiLXByb3ZpZGVyL2R5bmFtb2RiLWNhY2hlLmpzb24g55qE6KGM5qC85byPIOKAlOKAlFxuICog55SxIE9wZW5OZXh0IGJ1aWxkIOebtOaOpeS6p+WHuizlrZfmrrXlkI3lm7rlrprkuLogRHluYW1vREIg5bGe5oCn5pig5bCE5qC85byP44CCXG4gKi9cbmludGVyZmFjZSBEeW5hbW9UYWdSb3cge1xuICB0YWc6IHsgUzogc3RyaW5nIH07XG4gIHBhdGg6IHsgUzogc3RyaW5nIH07XG4gIHJldmFsaWRhdGVkQXQ/OiB7IE46IHN0cmluZyB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2RuUHVyZ2VDbGllbnQoY2ZnOiBDZG5QdXJnZUNvbmZpZyk6IENkblB1cmdlQ2xpZW50IHtcbiAgY29uc3QgYnVpbGRJZCA9IGNmZy52ZXJzaW9uO1xuICBjb25zdCBwYXRoUHJlZml4ID0gYCR7YnVpbGRJZH0vYDtcbiAgY29uc3QgbWFuaWZlc3RQYXRoID1cbiAgICBjZmcubWFuaWZlc3RQYXRoID8/IHBhdGguam9pbihfX2Rpcm5hbWUsIFRBR19NQU5JRkVTVF9GSUxFTkFNRSk7XG5cbiAgLy8gbGF6eSDliqDovb07UHJvbWlzZSDnlKjkuo7lubblj5HpppbmrKHosIPnlKjnmoTlkIjmtYFcbiAgbGV0IG1hbmlmZXN0UHJvbWlzZTogUHJvbWlzZTxNYXA8c3RyaW5nLCBzdHJpbmdbXT4+IHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZE1hbmlmZXN0KCk6IFByb21pc2U8TWFwPHN0cmluZywgc3RyaW5nW10+PiB7XG4gICAgaWYgKG1hbmlmZXN0UHJvbWlzZSkgcmV0dXJuIG1hbmlmZXN0UHJvbWlzZTtcbiAgICBtYW5pZmVzdFByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgbWFwID0gbmV3IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PigpO1xuICAgICAgbGV0IHJhdzogc3RyaW5nO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmF3ID0gYXdhaXQgZnMucHJvbWlzZXMucmVhZEZpbGUobWFuaWZlc3RQYXRoLCAndXRmLTgnKTtcbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIC8vIEVOT0VOVCDmmK/luLjop4Hmg4XlhrUo57qv6Z2Z5oCB6aG555uu5pegIHRhZyzmiJbogIHniYggQ0xJIOacquW1jOWFpSks6Z2Z6buY6ZmN57qnXG4gICAgICAgIGlmIChlcnI/LmNvZGUgIT09ICdFTk9FTlQnKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgYFtjZG4tcHVyZ2VdIG1hbmlmZXN0IHJlYWQgZXJyb3IgJHttYW5pZmVzdFBhdGh9OiAke2Vycj8ubWVzc2FnZSA/PyBlcnJ9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcbiAgICAgIH1cbiAgICAgIGxldCByb3dzOiBEeW5hbW9UYWdSb3dbXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UocmF3KTtcbiAgICAgICAgcm93cyA9IEFycmF5LmlzQXJyYXkocGFyc2VkKSA/IHBhcnNlZCA6IFtdO1xuICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBbY2RuLXB1cmdlXSBtYW5pZmVzdCBwYXJzZSBlcnJvciAke21hbmlmZXN0UGF0aH06ICR7ZXJyPy5tZXNzYWdlID8/IGVycn1gXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KCk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgICAgY29uc3QgdGFnUGsgPSByb3c/LnRhZz8uUztcbiAgICAgICAgY29uc3QgcGF0aFBrID0gcm93Py5wYXRoPy5TO1xuICAgICAgICBpZiAodHlwZW9mIHRhZ1BrICE9PSAnc3RyaW5nJyB8fCB0eXBlb2YgcGF0aFBrICE9PSAnc3RyaW5nJykgY29udGludWU7XG4gICAgICAgIC8vIOWPquaOpeWPl+W9k+WJjSBidWlsZElkIOeahOihjDtPcGVuTmV4dCDlt7Lkv53or4EgcHJlZml4LOS9huS4h+S4gOa3t+WFpeaXp+ihjOWwsei3s+i/h1xuICAgICAgICBpZiAoIXRhZ1BrLnN0YXJ0c1dpdGgocGF0aFByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIXBhdGhQay5zdGFydHNXaXRoKHBhdGhQcmVmaXgpKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgdGFnID0gdGFnUGsuc2xpY2UocGF0aFByZWZpeC5sZW5ndGgpO1xuICAgICAgICBjb25zdCBwID0gcGF0aFBrLnNsaWNlKHBhdGhQcmVmaXgubGVuZ3RoKTtcbiAgICAgICAgaWYgKCF0YWcgfHwgIXApIGNvbnRpbnVlO1xuICAgICAgICBsZXQgYnVja2V0ID0gbWFwLmdldCh0YWcpO1xuICAgICAgICBpZiAoIWJ1Y2tldCkge1xuICAgICAgICAgIGJ1Y2tldCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICAgIG1hcC5zZXQodGFnLCBidWNrZXQpO1xuICAgICAgICB9XG4gICAgICAgIGJ1Y2tldC5hZGQocCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcbiAgICAgIGZvciAoY29uc3QgW3RhZywgc2V0XSBvZiBtYXApIHtcbiAgICAgICAgcmVzdWx0LnNldCh0YWcsIEFycmF5LmZyb20oc2V0KSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pKCk7XG4gICAgcmV0dXJuIG1hbmlmZXN0UHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmioroi6XlubIgTmV4dCDot6/nlLEgcGF0aCDlsZXlvIDmiJDpnIAgcHVyZ2Ug55qEIFVSTCDliJfooag6XG4gICAqICAgLSDot7Pov4fnqbrkuLLjgIHljrvph40o5Z+65LqO6KeE6IyD5YyW5ZCO55qEIGxlYWRpbmcgXCIvXCIpXG4gICAqICAgLSDlr7nmr4/kuKogcGF0aCDov73liqAgL19uZXh0L2RhdGEve2J1aWxkSWR9L3twYXRofS5qc29uXG4gICAqICAgLSDmi7zkuIogaHR0cHM6Ly97aG9zdG5hbWV9XG4gICAqL1xuICBmdW5jdGlvbiBleHBhbmRQYXRoc1RvVXJscyhwYXRoczogc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgcCBvZiBwYXRocykge1xuICAgICAgaWYgKCFwKSBjb250aW51ZTtcbiAgICAgIG5vcm1hbGl6ZWQuYWRkKGVuc3VyZUxlYWRpbmdTbGFzaChwKSk7XG4gICAgfVxuICAgIGlmIChub3JtYWxpemVkLnNpemUgPT09IDApIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHVybHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHAgb2Ygbm9ybWFsaXplZCkge1xuICAgICAgdXJscy5hZGQoYGh0dHBzOi8vJHtjZmcuaG9zdG5hbWV9JHtwfWApO1xuICAgICAgY29uc3QgcmVsID0gc3RyaXBMZWFkaW5nU2xhc2gocCk7XG4gICAgICAvLyBwYWdlcyByb3V0ZXIgSVNSIOW/hemcgDthcHAgcm91dGVyIOWkmuaJk+S4gOadoeaXoOWJr+S9nOeUqFxuICAgICAgdXJscy5hZGQoXG4gICAgICAgIGBodHRwczovLyR7Y2ZnLmhvc3RuYW1lfS9fbmV4dC9kYXRhLyR7YnVpbGRJZH0vJHtyZWwgfHwgJ2luZGV4J30uanNvbmBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKHVybHMpO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVmcmVzaEJhdGNoKHVybHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYm9keTogQ2FjaGVSZWZyZXNoUmVxdWVzdCA9IHtcbiAgICAgIGhvc3RuYW1lOiBjZmcuaG9zdG5hbWUsXG4gICAgICBzaXRlSWQ6IGNmZy5zaXRlSWQsXG4gICAgICB1cmxzLFxuICAgIH07XG5cbiAgICBsZXQgcmVzOiBSZXNwb25zZTtcbiAgICB0cnkge1xuICAgICAgcmVzID0gYXdhaXQgZ2F0ZXdheUZldGNoKGNmZywgJy9jYWNoZS9yZWZyZXNoJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICAgICAgICB0aW1lb3V0TXM6IFJFRlJFU0hfVElNRU9VVF9NUyxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbY2RuLXB1cmdlXSBjYWNoZS9yZWZyZXNoIGVycm9yICgke3VybHMubGVuZ3RofSB1cmxzKTogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFyZXMub2spIHtcbiAgICAgIGxldCBkZXRhaWwgPSAnJztcbiAgICAgIHRyeSB7XG4gICAgICAgIGRldGFpbCA9IChhd2FpdCByZXMudGV4dCgpKS5zbGljZSgwLCAyMDApO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGlnbm9yZSAqL1xuICAgICAgfVxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgW2Nkbi1wdXJnZV0gY2FjaGUvcmVmcmVzaCBmYWlsZWQgc3RhdHVzPSR7cmVzLnN0YXR1c30gdXJscz0ke3VybHMubGVuZ3RofSAke2RldGFpbH1gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlZnJlc2hVcmxzKGFsbFVybHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGFsbFVybHMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBjb25zdCBiYXRjaGVzOiBzdHJpbmdbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxVcmxzLmxlbmd0aDsgaSArPSBVUkxfQkFUQ0hfU0laRSkge1xuICAgICAgYmF0Y2hlcy5wdXNoKGFsbFVybHMuc2xpY2UoaSwgaSArIFVSTF9CQVRDSF9TSVpFKSk7XG4gICAgfVxuXG4gICAgLy8g5bm25Y+R5LiK6ZmQIFJFRlJFU0hfQ09OQ1VSUkVOQ1kg55qE5ruR5Yqo56qX5Y+jXG4gICAgbGV0IGN1cnNvciA9IDA7XG4gICAgYXN5bmMgZnVuY3Rpb24gd29ya2VyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgd2hpbGUgKGN1cnNvciA8IGJhdGNoZXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGlkeCA9IGN1cnNvcisrO1xuICAgICAgICBhd2FpdCByZWZyZXNoQmF0Y2goYmF0Y2hlc1tpZHhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB3b3JrZXJzID0gQXJyYXkuZnJvbShcbiAgICAgIHsgbGVuZ3RoOiBNYXRoLm1pbihSRUZSRVNIX0NPTkNVUlJFTkNZLCBiYXRjaGVzLmxlbmd0aCkgfSxcbiAgICAgICgpID0+IHdvcmtlcigpXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbCh3b3JrZXJzKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHB1cmdlQnlQYXRocyhwYXRoczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXJscyA9IGV4cGFuZFBhdGhzVG9VcmxzKHBhdGhzKTtcbiAgICAgIGF3YWl0IHJlZnJlc2hVcmxzKHVybHMpO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLndhcm4oYFtjZG4tcHVyZ2VdIHB1cmdlQnlQYXRocyBlcnJvcjogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHB1cmdlQnlUYWdzKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVuaXF1ZVRhZ3MgPSBBcnJheS5mcm9tKFxuICAgICAgICBuZXcgU2V0KFxuICAgICAgICAgIHRhZ3NcbiAgICAgICAgICAgIC5tYXAodCA9PiAodHlwZW9mIHQgPT09ICdzdHJpbmcnID8gdCA6ICcnKSlcbiAgICAgICAgICAgIC5tYXAodCA9PiB0LnRyaW0oKSlcbiAgICAgICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIGlmICh1bmlxdWVUYWdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICBjb25zdCBtYXAgPSBhd2FpdCBsb2FkTWFuaWZlc3QoKTtcblxuICAgICAgY29uc3QgbWVyZ2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBmb3IgKGNvbnN0IHQgb2YgdW5pcXVlVGFncykge1xuICAgICAgICBjb25zdCBwYXRocyA9IG1hcC5nZXQodCk7XG4gICAgICAgIGlmICghcGF0aHMpIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGNvbnN0IHAgb2YgcGF0aHMpIG1lcmdlZC5hZGQocCk7XG4gICAgICB9XG4gICAgICBpZiAobWVyZ2VkLnNpemUgPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgdXJscyA9IGV4cGFuZFBhdGhzVG9VcmxzKEFycmF5LmZyb20obWVyZ2VkKSk7XG4gICAgICBhd2FpdCByZWZyZXNoVXJscyh1cmxzKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbY2RuLXB1cmdlXSBwdXJnZUJ5VGFncyBlcnJvcjogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IHB1cmdlQnlQYXRocywgcHVyZ2VCeVRhZ3MgfTtcbn1cbiJdfQ==
|
|
259
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RuLXB1cmdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvY2RuLXB1cmdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7OztBQUVILHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFFN0IsaURBSXdCO0FBQ3hCLGlEQUFnRDtBQUVoRCxNQUFNLGtCQUFrQixHQUFHLEtBQU0sQ0FBQztBQUVsQyxNQUFNLGNBQWMsR0FBRyxHQUFHLENBQUM7QUFDM0IsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFFOUIsdURBQXVEO0FBQ3ZELE1BQU0scUJBQXFCLEdBQUcseUJBQXlCLENBQUM7QUF5QnhELFNBQVMsaUJBQWlCLENBQUMsQ0FBUztJQUNsQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLENBQVM7SUFDbkMsT0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDekMsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsU0FBZ0Isa0JBQWtCO0lBQ2hDLE1BQU0sSUFBSSxHQUFHLElBQUEsb0NBQXFCLEdBQUUsQ0FBQztJQUNyQyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3ZCLE9BQU8sRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO0FBQ3JCLENBQUM7QUFKRCxnREFJQztBQVlELFNBQWdCLG9CQUFvQixDQUFDLEdBQW1COztJQUN0RCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDO0lBQzVCLE1BQU0sVUFBVSxHQUFHLEdBQUcsT0FBTyxHQUFHLENBQUM7SUFDakMsTUFBTSxZQUFZLEdBQ2hCLE1BQUEsR0FBRyxD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QWtDLFVBQVUsQ0FBQyxNQUFNLFlBQVksTUFBTSxDQUFDLElBQUksU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQ2pHLENBQUM7WUFDRixNQUFNLFdBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDekQ7UUFBQyxPQUFPLEdBQVEsRUFBRTtZQUNqQixPQUFPLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxNQUFBLEdBQUcsYUFBSCxHQUFHLHVCQUFILEdBQUcsQ0FBRSxPQUFPLG1DQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7U0FDdkU7SUFDSCxDQUFDO0lBRUQsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsQ0FBQztBQUN2QyxDQUFDO0FBNU9ELG9EQTRPQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ0ROIFB1cmdlIFJ1bnRpbWVcbiAqXG4gKiDlnKggcmV2YWxpZGF0ZVRhZyAvIHJldmFsaWRhdGVQYXRoIOWQjixmaXJlLWFuZC1mb3JnZXQg6Kem5Y+RIEVTQSDovrnnvJjnvJPlrZjlpLHmlYjjgIJcbiAqXG4gKiDorr7orqHljp/liJk6XG4gKiAgIC0gdGFnIOKGkiBwYXRocyDlj43mn6XotbAgKirmnKzlnLAqKiBtYW5pZmVzdChidWlsZCDml7bnlLEgcGNnIGJ1aWxkIOaKilxuICogICAgIC5vcGVuLW5leHQvZHluYW1vZGItcHJvdmlkZXIvZHluYW1vZGItY2FjaGUuanNvbiDltYzlhaUgRkMgYnVuZGxlKSxcbiAqICAgICDov5DooYzml7bnrKzkuIDmrKHnlKjliLDml7YgbGF6eSDliqDovb3liLDlhoXlrZggTWFwLOWQjue7rSBPKDEpIOafpeivoizml6DnvZHnu5zlvoDov5RcbiAqICAgLSAvY2FjaGUvcmVmcmVzaCDotbAgR2F0ZXdheSzmsr/nlKjnjrDmnIkgSE1BQyDpibTmnYMgKyBFU0Eg5YiG5rWBXG4gKiAgIC0g5omA5pyJ5aSx6LSl5LuFIHdhcm4s57ud5LiN5oqb6ZSZKHB1cmdlIOaYr+S8mOWMlizkuI3mmK/mraPnoa7mgKcpXG4gKiAgIC0gaG9zdG5hbWUgLyBzaXRlSWQg6LWwIHBlci1yZXF1ZXN0IGVkZ2UtY29udGV4dChBc3luY0xvY2FsU3RvcmFnZSksXG4gKiAgICAg55SxIG5vZGUtc2VydmVyIHdyYXBwZXIg5LuO5YWl56uZ6K+35rGCIGhlYWRlciDms6jlhaU7Y3R4IOe8uui/meS4pOmhueaXtiBza2lwICsgd2FybixcbiAqICAgICDkuI3lho3pnZnpu5jnlJ/mlYjjgILpibTmnYMoNSBlbnYp57y65aSx5YiZIGxvYWRDZG5QdXJnZUNvbmZpZyDov5Tlm54gbnVsbCxcbiAqICAgICDkuIrmuLjpmY3nuqcgbm8tb3As6L+eIGNsaWVudCDpg73kuI3mnoTpgKDjgIJcbiAqICAgLSDot6ggdGFnIOWPjeafpee7k+aenOWOu+mHjSzmr48gcGF0aCDov73liqAgL19uZXh0L2RhdGEve2J1aWxkSWR9L3twYXRofS5qc29uXG4gKiAgIC0g6LCDIC9jYWNoZS9yZWZyZXNoIOaXtuaMiSAxMDAgVVJML+aJueOAgWJhdGNoIOWGheW5tuWPkeS4iumZkCA0XG4gKi9cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IENhY2hlUmVmcmVzaFJlcXVlc3QgfSBmcm9tICdAcGNnL3Byb3RvY29sJztcbmltcG9ydCB7XG4gIGxvYWRHYXRld2F5QXV0aENvbmZpZyxcbiAgZ2F0ZXdheUZldGNoLFxuICBHYXRld2F5QXV0aENvbmZpZyxcbn0gZnJvbSAnLi9nYXRld2F5LWF1dGgnO1xuaW1wb3J0IHsgZ2V0RWRnZUNvbnRleHQgfSBmcm9tICcuL2VkZ2UtY29udGV4dCc7XG5cbmNvbnN0IFJFRlJFU0hfVElNRU9VVF9NUyA9IDE1XzAwMDtcblxuY29uc3QgVVJMX0JBVENIX1NJWkUgPSAxMDA7XG5jb25zdCBSRUZSRVNIX0NPTkNVUlJFTkNZID0gNDtcblxuLy8g5LiOIGJ1aWxkLnRzIOS4rSBUQUdfTUFOSUZFU1RfRklMRU5BTUUg5L+d5oyB5LiA6Ie0KOWvueS+p+aYr+WGmeWFpSzov5nkvqfmmK/or7vlj5YpXG5jb25zdCBUQUdfTUFOSUZFU1RfRklMRU5BTUUgPSAnX19wY2dfdGFnX21hbmlmZXN0Lmpzb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIENkblB1cmdlQ29uZmlnIGV4dGVuZHMgR2F0ZXdheUF1dGhDb25maWcge1xuICAvKipcbiAgICog6KaG55uW6buY6K6kIG1hbmlmZXN0IOi3r+W+hCzkuLvopoHnu5nmtYvor5XnlKjjgIJcbiAgICog6buY6K6kID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ19fcGNnX3RhZ19tYW5pZmVzdC5qc29uJyksXG4gICAqIOWNsyBGQyBidW5kbGUg5YaF5LiOIGNhY2hlLmNqcyDlkIznuqfjgIJcbiAgICovXG4gIG1hbmlmZXN0UGF0aD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDZG5QdXJnZUNsaWVudCB7XG4gIC8qKlxuICAgKiDlvILmraXop6blj5EgRVNBIOe8k+WtmOWkseaViOOAguS4jemYu+Whnuiwg+eUqOaWuSzlpLHotKXku4Ugd2FybuOAglxuICAgKiDlhoXpg6jlrozmiJAgcGF0aCDljrvph40gKyBJU1Ig5pWw5o2u6Lev5b6E6KGl5YWoICsg6ZmQ5rWB44CCXG4gICAqL1xuICBwdXJnZUJ5UGF0aHMocGF0aHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogdGFnIOKGkiBwYXRocyDlj43mn6UgKyBwdXJnZeOAglxuICAgKiDlj43mn6XotbDmnKzlnLDltYzlhaXnmoQgbWFuaWZlc3Qg5paH5Lu2LOaXoOe9kee7nCBJT+OAglxuICAgKi9cbiAgcHVyZ2VCeVRhZ3ModGFnczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5mdW5jdGlvbiBzdHJpcExlYWRpbmdTbGFzaChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKC9eXFwvKy8sICcnKTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlTGVhZGluZ1NsYXNoKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzLnN0YXJ0c1dpdGgoJy8nKSA/IHMgOiBgLyR7c31gO1xufVxuXG4vKipcbiAqIOWKoOi9vSBwdXJnZSDphY3nva7jgIJcbiAqXG4gKiBob3N0bmFtZSAvIHNpdGVJZCDkuI3lho3ku44gZW52IOWPlizmlLnnlLEgbm9kZS1zZXJ2ZXIgd3JhcHBlciDlnKjlhaXlj6NcbiAqIHJ1bldpdGhFZGdlQ29udGV4dChoZWFkZXJzLCDigKYpIOaKiuivt+axguWktOmHjOeahCBob3N0IOS4jiB4LWFsaWNkbi1zaXRlLWlkIOazqOWFpVxuICogQXN5bmNMb2NhbFN0b3JhZ2UscmVmcmVzaEJhdGNoIOaXtuWNs+aXtuivu+WPluOAguWOn+WboDpcbiAqICAgLSDkuIDkuKogcm91dGluZSDlj6/og73mnI3liqHlpJogc2l0ZSAvIOWkmiBob3N0bmFtZSzlkK/liqjmnJ8gZW52IOaXoOazleihqOi+vlxuICogICAtIOacrOWcsCBkZXYg6Iul5rKh5bim5aS0LOi/measoSBwdXJnZSDnm7TmjqUgc2tpcCArIHdhcm4s5LiN5YaN6Z2Z6buY55Sf5pWIXG4gKlxuICog5aSN55SoIGxvYWRHYXRld2F5QXV0aENvbmZpZyDnmoQgNSDkuKogZW52IOWBmiBITUFDIOmJtOadgyAvIGVuZHBvaW50IOmAieWPluOAglxuICog57y66L+Z5LqU5LiqIGVudiDov5Tlm54gbnVsbCzosIPnlKjmlrnlupTot7Pov4cgcHVyZ2Uo5LiN5b2x5ZONIHRhZyDlhpnlupMp44CCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkQ2RuUHVyZ2VDb25maWcoKTogQ2RuUHVyZ2VDb25maWcgfCBudWxsIHtcbiAgY29uc3QgYmFzZSA9IGxvYWRHYXRld2F5QXV0aENvbmZpZygpO1xuICBpZiAoIWJhc2UpIHJldHVybiBudWxsO1xuICByZXR1cm4geyAuLi5iYXNlIH07XG59XG5cbi8qKlxuICogZHluYW1vZGItcHJvdmlkZXIvZHluYW1vZGItY2FjaGUuanNvbiDnmoTooYzmoLzlvI8g4oCU4oCUXG4gKiDnlLEgT3Blbk5leHQgYnVpbGQg55u05o6l5Lqn5Ye6LOWtl+auteWQjeWbuuWumuS4uiBEeW5hbW9EQiDlsZ7mgKfmmKDlsITmoLzlvI/jgIJcbiAqL1xuaW50ZXJmYWNlIER5bmFtb1RhZ1JvdyB7XG4gIHRhZzogeyBTOiBzdHJpbmcgfTtcbiAgcGF0aDogeyBTOiBzdHJpbmcgfTtcbiAgcmV2YWxpZGF0ZWRBdD86IHsgTjogc3RyaW5nIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDZG5QdXJnZUNsaWVudChjZmc6IENkblB1cmdlQ29uZmlnKTogQ2RuUHVyZ2VDbGllbnQge1xuICBjb25zdCBidWlsZElkID0gY2ZnLnZlcnNpb247XG4gIGNvbnN0IHBhdGhQcmVmaXggPSBgJHtidWlsZElkfS9gO1xuICBjb25zdCBtYW5pZmVzdFBhdGggPVxuICAgIGNmZy5tYW5pZmVzdFBhdGggPz8gcGF0aC5qb2luKF9fZGlybmFtZSwgVEFHX01BTklGRVNUX0ZJTEVOQU1FKTtcblxuICAvLyBsYXp5IOWKoOi9vTtQcm9taXNlIOeUqOS6juW5tuWPkemmluasoeiwg+eUqOeahOWQiOa1gVxuICBsZXQgbWFuaWZlc3RQcm9taXNlOiBQcm9taXNlPE1hcDxzdHJpbmcsIHN0cmluZ1tdPj4gfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBmdW5jdGlvbiBsb2FkTWFuaWZlc3QoKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBzdHJpbmdbXT4+IHtcbiAgICBpZiAobWFuaWZlc3RQcm9taXNlKSByZXR1cm4gbWFuaWZlc3RQcm9taXNlO1xuICAgIG1hbmlmZXN0UHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtYXAgPSBuZXcgTWFwPHN0cmluZywgU2V0PHN0cmluZz4+KCk7XG4gICAgICBsZXQgcmF3OiBzdHJpbmc7XG4gICAgICB0cnkge1xuICAgICAgICByYXcgPSBhd2FpdCBmcy5wcm9taXNlcy5yZWFkRmlsZShtYW5pZmVzdFBhdGgsICd1dGYtOCcpO1xuICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgLy8gRU5PRU5UIOaYr+W4uOingeaDheWGtSjnuq/pnZnmgIHpobnnm67ml6AgdGFnLOaIluiAgeeJiCBDTEkg5pyq5bWM5YWlKSzpnZnpu5jpmY3nuqdcbiAgICAgICAgaWYgKGVycj8uY29kZSAhPT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgW2Nkbi1wdXJnZV0gbWFuaWZlc3QgcmVhZCBlcnJvciAke21hbmlmZXN0UGF0aH06ICR7ZXJyPy5tZXNzYWdlID8/IGVycn1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpO1xuICAgICAgfVxuICAgICAgbGV0IHJvd3M6IER5bmFtb1RhZ1Jvd1tdO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgICByb3dzID0gQXJyYXkuaXNBcnJheShwYXJzZWQpID8gcGFyc2VkIDogW107XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFtjZG4tcHVyZ2VdIG1hbmlmZXN0IHBhcnNlIGVycm9yICR7bWFuaWZlc3RQYXRofTogJHtlcnI/Lm1lc3NhZ2UgPz8gZXJyfWBcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgICBjb25zdCB0YWdQayA9IHJvdz8udGFnPy5TO1xuICAgICAgICBjb25zdCBwYXRoUGsgPSByb3c/LnBhdGg/LlM7XG4gICAgICAgIGlmICh0eXBlb2YgdGFnUGsgIT09ICdzdHJpbmcnIHx8IHR5cGVvZiBwYXRoUGsgIT09ICdzdHJpbmcnKSBjb250aW51ZTtcbiAgICAgICAgLy8g5Y+q5o6l5Y+X5b2T5YmNIGJ1aWxkSWQg55qE6KGMO09wZW5OZXh0IOW3suS/neivgSBwcmVmaXgs5L2G5LiH5LiA5re35YWl5pen6KGM5bCx6Lez6L+HXG4gICAgICAgIGlmICghdGFnUGsuc3RhcnRzV2l0aChwYXRoUHJlZml4KSkgY29udGludWU7XG4gICAgICAgIGlmICghcGF0aFBrLnN0YXJ0c1dpdGgocGF0aFByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCB0YWcgPSB0YWdQay5zbGljZShwYXRoUHJlZml4Lmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IHAgPSBwYXRoUGsuc2xpY2UocGF0aFByZWZpeC5sZW5ndGgpO1xuICAgICAgICBpZiAoIXRhZyB8fCAhcCkgY29udGludWU7XG4gICAgICAgIGxldCBidWNrZXQgPSBtYXAuZ2V0KHRhZyk7XG4gICAgICAgIGlmICghYnVja2V0KSB7XG4gICAgICAgICAgYnVja2V0ID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICAgICAgbWFwLnNldCh0YWcsIGJ1Y2tldCk7XG4gICAgICAgIH1cbiAgICAgICAgYnVja2V0LmFkZChwKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpO1xuICAgICAgbGV0IHRvdGFsRW50cmllcyA9IDA7XG4gICAgICBmb3IgKGNvbnN0IFt0YWcsIHNldF0gb2YgbWFwKSB7XG4gICAgICAgIHJlc3VsdC5zZXQodGFnLCBBcnJheS5mcm9tKHNldCkpO1xuICAgICAgICB0b3RhbEVudHJpZXMgKz0gc2V0LnNpemU7XG4gICAgICB9XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYFtjZG4tcHVyZ2VdIG1hbmlmZXN0IGxvYWRlZDogdGFncz0ke3Jlc3VsdC5zaXplfSBlbnRyaWVzPSR7dG90YWxFbnRyaWVzfSAoJHttYW5pZmVzdFBhdGh9KWBcbiAgICAgICk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pKCk7XG4gICAgcmV0dXJuIG1hbmlmZXN0UHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmioroi6XlubIgTmV4dCDot6/nlLEgcGF0aCDlsZXlvIDmiJDpnIAgcHVyZ2Ug55qEIFVSTCDliJfooag6XG4gICAqICAgLSDot7Pov4fnqbrkuLLjgIHljrvph40o5Z+65LqO6KeE6IyD5YyW5ZCO55qEIGxlYWRpbmcgXCIvXCIpXG4gICAqICAgLSDlr7nmr4/kuKogcGF0aCDov73liqAgL19uZXh0L2RhdGEve2J1aWxkSWR9L3twYXRofS5qc29uXG4gICAqICAgLSDmi7zkuIogaHR0cHM6Ly97aG9zdG5hbWV9XG4gICAqL1xuICBmdW5jdGlvbiBleHBhbmRQYXRoc1RvVXJscyhwYXRoczogc3RyaW5nW10sIGhvc3RuYW1lOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgcCBvZiBwYXRocykge1xuICAgICAgaWYgKCFwKSBjb250aW51ZTtcbiAgICAgIG5vcm1hbGl6ZWQuYWRkKGVuc3VyZUxlYWRpbmdTbGFzaChwKSk7XG4gICAgfVxuICAgIGlmIChub3JtYWxpemVkLnNpemUgPT09IDApIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHVybHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHAgb2Ygbm9ybWFsaXplZCkge1xuICAgICAgdXJscy5hZGQoYGh0dHBzOi8vJHtob3N0bmFtZX0ke3B9YCk7XG4gICAgICBjb25zdCByZWwgPSBzdHJpcExlYWRpbmdTbGFzaChwKTtcbiAgICAgIC8vIHBhZ2VzIHJvdXRlciBJU1Ig5b+F6ZyAO2FwcCByb3V0ZXIg5aSa5omT5LiA5p2h5peg5Ymv5L2c55SoXG4gICAgICB1cmxzLmFkZChcbiAgICAgICAgYGh0dHBzOi8vJHtob3N0bmFtZX0vX25leHQvZGF0YS8ke2J1aWxkSWR9LyR7cmVsIHx8ICdpbmRleCd9Lmpzb25gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gQXJyYXkuZnJvbSh1cmxzKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlZnJlc2hCYXRjaChcbiAgICB1cmxzOiBzdHJpbmdbXSxcbiAgICBob3N0bmFtZTogc3RyaW5nLFxuICAgIHNpdGVJZDogc3RyaW5nIHwgbnVtYmVyXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJvZHk6IENhY2hlUmVmcmVzaFJlcXVlc3QgPSB7XG4gICAgICBob3N0bmFtZSxcbiAgICAgIHNpdGVJZCxcbiAgICAgIHVybHMsXG4gICAgfTtcblxuICAgIGxldCByZXM6IFJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICByZXMgPSBhd2FpdCBnYXRld2F5RmV0Y2goY2ZnLCAnL2NhY2hlL3JlZnJlc2gnLCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgICAgIHRpbWVvdXRNczogUkVGUkVTSF9USU1FT1VUX01TLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFtjZG4tcHVyZ2VdIGNhY2hlL3JlZnJlc2ggZXJyb3IgKCR7dXJscy5sZW5ndGh9IHVybHMpOiAke2Vycj8ubWVzc2FnZSA/PyBlcnJ9YFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXJlcy5vaykge1xuICAgICAgbGV0IGRldGFpbCA9ICcnO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZGV0YWlsID0gKGF3YWl0IHJlcy50ZXh0KCkpLnNsaWNlKDAsIDIwMCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogaWdub3JlICovXG4gICAgICB9XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbY2RuLXB1cmdlXSBjYWNoZS9yZWZyZXNoIGZhaWxlZCBzdGF0dXM9JHtyZXMuc3RhdHVzfSB1cmxzPSR7dXJscy5sZW5ndGh9ICR7ZGV0YWlsfWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBbY2RuLXB1cmdlXSBjYWNoZS9yZWZyZXNoIG9rOiB1cmxzPSR7dXJscy5sZW5ndGh9YCk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiByZWZyZXNoVXJscyhcbiAgICBhbGxVcmxzOiBzdHJpbmdbXSxcbiAgICBob3N0bmFtZTogc3RyaW5nLFxuICAgIHNpdGVJZDogc3RyaW5nIHwgbnVtYmVyXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChhbGxVcmxzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgY29uc3QgYmF0Y2hlczogc3RyaW5nW11bXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWxsVXJscy5sZW5ndGg7IGkgKz0gVVJMX0JBVENIX1NJWkUpIHtcbiAgICAgIGJhdGNoZXMucHVzaChhbGxVcmxzLnNsaWNlKGksIGkgKyBVUkxfQkFUQ0hfU0laRSkpO1xuICAgIH1cblxuICAgIC8vIOW5tuWPkeS4iumZkCBSRUZSRVNIX0NPTkNVUlJFTkNZIOeahOa7keWKqOeql+WPo1xuICAgIGxldCBjdXJzb3IgPSAwO1xuICAgIGFzeW5jIGZ1bmN0aW9uIHdvcmtlcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIHdoaWxlIChjdXJzb3IgPCBiYXRjaGVzLmxlbmd0aCkge1xuICAgICAgICBjb25zdCBpZHggPSBjdXJzb3IrKztcbiAgICAgICAgYXdhaXQgcmVmcmVzaEJhdGNoKGJhdGNoZXNbaWR4XSwgaG9zdG5hbWUsIHNpdGVJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgd29ya2VycyA9IEFycmF5LmZyb20oXG4gICAgICB7IGxlbmd0aDogTWF0aC5taW4oUkVGUkVTSF9DT05DVVJSRU5DWSwgYmF0Y2hlcy5sZW5ndGgpIH0sXG4gICAgICAoKSA9PiB3b3JrZXIoKVxuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwod29ya2Vycyk7XG4gIH1cblxuICAvKipcbiAgICog5LuO5b2T5YmN6K+35rGC55qEIEFzeW5jTG9jYWxTdG9yYWdlIOaLvyBob3N0bmFtZS9zaXRlSWTjgIJcbiAgICog57y65Lu75LiA5Y2z6L+U5ZueIG51bGws6LCD55So5pa5IHdhcm4g5ZCOIHNraXAg4oCUIOacrOWcsOaXoCBoZWFkZXIg6Lev5b6E5bCx5piv6L+Z5p2h6ZmN57qn44CCXG4gICAqL1xuICBmdW5jdGlvbiByZXNvbHZlVGFyZ2V0KFxuICAgIGFjdGlvbjogc3RyaW5nXG4gICk6IHsgaG9zdG5hbWU6IHN0cmluZzsgc2l0ZUlkOiBzdHJpbmcgfCBudW1iZXIgfSB8IG51bGwge1xuICAgIGNvbnN0IHsgaG9zdG5hbWUsIHNpdGVJZCB9ID0gZ2V0RWRnZUNvbnRleHQoKTtcbiAgICBpZiAoIWhvc3RuYW1lIHx8IHNpdGVJZCA9PT0gdW5kZWZpbmVkIHx8IHNpdGVJZCA9PT0gJycpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFtjZG4tcHVyZ2VdICR7YWN0aW9ufSBza2lwOiBlZGdlIGNvbnRleHQgbWlzc2luZyAoaG9zdG5hbWU9JHtob3N0bmFtZSA/PyAn4oiFJ30gc2l0ZUlkPSR7c2l0ZUlkID8/ICfiiIUnfSk7IGAgK1xuICAgICAgICAgIGDopoHmsYLlhaXnq5nor7fmsYLluKYgaG9zdCDkuI4geC1hbGljZG4tc2l0ZS1pZGBcbiAgICAgICk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHsgaG9zdG5hbWUsIHNpdGVJZCB9O1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcHVyZ2VCeVBhdGhzKHBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSByZXNvbHZlVGFyZ2V0KCdwdXJnZUJ5UGF0aHMnKTtcbiAgICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgICBjb25zdCB1cmxzID0gZXhwYW5kUGF0aHNUb1VybHMocGF0aHMsIHRhcmdldC5ob3N0bmFtZSk7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYFtjZG4tcHVyZ2VdIHB1cmdlQnlQYXRoczogaW5wdXQ9JHtwYXRocy5sZW5ndGh9IHVybHM9JHt1cmxzLmxlbmd0aH1gXG4gICAgICApO1xuICAgICAgYXdhaXQgcmVmcmVzaFVybHModXJscywgdGFyZ2V0Lmhvc3RuYW1lLCB0YXJnZXQuc2l0ZUlkKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS53YXJuKGBbY2RuLXB1cmdlXSBwdXJnZUJ5UGF0aHMgZXJyb3I6ICR7ZXJyPy5tZXNzYWdlID8/IGVycn1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBwdXJnZUJ5VGFncyh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB1bmlxdWVUYWdzID0gQXJyYXkuZnJvbShcbiAgICAgICAgbmV3IFNldChcbiAgICAgICAgICB0YWdzXG4gICAgICAgICAgICAubWFwKHQgPT4gKHR5cGVvZiB0ID09PSAnc3RyaW5nJyA/IHQgOiAnJykpXG4gICAgICAgICAgICAubWFwKHQgPT4gdC50cmltKCkpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICBpZiAodW5pcXVlVGFncy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgdGFyZ2V0ID0gcmVzb2x2ZVRhcmdldCgncHVyZ2VCeVRhZ3MnKTtcbiAgICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG5cbiAgICAgIGNvbnN0IG1hcCA9IGF3YWl0IGxvYWRNYW5pZmVzdCgpO1xuXG4gICAgICBjb25zdCBtZXJnZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgIGZvciAoY29uc3QgdCBvZiB1bmlxdWVUYWdzKSB7XG4gICAgICAgIGNvbnN0IHBhdGhzID0gbWFwLmdldCh0KTtcbiAgICAgICAgaWYgKCFwYXRocykgY29udGludWU7XG4gICAgICAgIGZvciAoY29uc3QgcCBvZiBwYXRocykgbWVyZ2VkLmFkZChwKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXJnZWQuc2l6ZSA9PT0gMCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICBgW2Nkbi1wdXJnZV0gcHVyZ2VCeVRhZ3M6IGlucHV0PSR7dW5pcXVlVGFncy5sZW5ndGh9IG1hdGNoZWQ9MCAobWFuaWZlc3QgbWlzcywgc2tpcClgXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXJscyA9IGV4cGFuZFBhdGhzVG9VcmxzKEFycmF5LmZyb20obWVyZ2VkKSwgdGFyZ2V0Lmhvc3RuYW1lKTtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBgW2Nkbi1wdXJnZV0gcHVyZ2VCeVRhZ3M6IGlucHV0PSR7dW5pcXVlVGFncy5sZW5ndGh9IG1hdGNoZWQ9JHttZXJnZWQuc2l6ZX0gdXJscz0ke3VybHMubGVuZ3RofWBcbiAgICAgICk7XG4gICAgICBhd2FpdCByZWZyZXNoVXJscyh1cmxzLCB0YXJnZXQuaG9zdG5hbWUsIHRhcmdldC5zaXRlSWQpO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLndhcm4oYFtjZG4tcHVyZ2VdIHB1cmdlQnlUYWdzIGVycm9yOiAke2Vycj8ubWVzc2FnZSA/PyBlcnJ9YCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgcHVyZ2VCeVBhdGhzLCBwdXJnZUJ5VGFncyB9O1xufVxuIl19
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Request Context
|
|
3
|
+
*
|
|
4
|
+
* 在 ESA / 边缘环境,siteId 和 hostname 从入站请求 header 取,不再依赖
|
|
5
|
+
* 启动时 env 注入。原因:
|
|
6
|
+
* - 一个 routine 实例可能服务多个 site / hostname(灰度、多版本、聚合域),
|
|
7
|
+
* 启动时 env 无法表达 per-request 变化
|
|
8
|
+
* - 让 ops 不必再为每个部署额外配两个 env
|
|
9
|
+
*
|
|
10
|
+
* 实现用 AsyncLocalStorage:
|
|
11
|
+
* - node-server wrapper 在 handler 入口处 runWithEdgeContext(headers, fn)
|
|
12
|
+
* - 下游 cdn-purge / 其他模块用 getEdgeContext() 同步读取
|
|
13
|
+
* - 即使 purge 是 fire-and-forget,promise 链也会继承当前 ALS,
|
|
14
|
+
* refreshBatch 内仍能拿到当时请求的 ctx
|
|
15
|
+
*
|
|
16
|
+
* 关键 header:
|
|
17
|
+
* - x-alicdn-site-id → siteId
|
|
18
|
+
* - host / x-forwarded-host → hostname(首选 host,缺失才退 x-forwarded-host)
|
|
19
|
+
*/
|
|
20
|
+
export interface EdgeContext {
|
|
21
|
+
siteId?: string | number;
|
|
22
|
+
hostname?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function buildEdgeContextFromHeaders(headers: Record<string, string | undefined>): EdgeContext;
|
|
25
|
+
export declare function runWithEdgeContext<T>(headers: Record<string, string | undefined>, fn: () => T): T;
|
|
26
|
+
export declare function getEdgeContext(): EdgeContext;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Edge Request Context
|
|
4
|
+
*
|
|
5
|
+
* 在 ESA / 边缘环境,siteId 和 hostname 从入站请求 header 取,不再依赖
|
|
6
|
+
* 启动时 env 注入。原因:
|
|
7
|
+
* - 一个 routine 实例可能服务多个 site / hostname(灰度、多版本、聚合域),
|
|
8
|
+
* 启动时 env 无法表达 per-request 变化
|
|
9
|
+
* - 让 ops 不必再为每个部署额外配两个 env
|
|
10
|
+
*
|
|
11
|
+
* 实现用 AsyncLocalStorage:
|
|
12
|
+
* - node-server wrapper 在 handler 入口处 runWithEdgeContext(headers, fn)
|
|
13
|
+
* - 下游 cdn-purge / 其他模块用 getEdgeContext() 同步读取
|
|
14
|
+
* - 即使 purge 是 fire-and-forget,promise 链也会继承当前 ALS,
|
|
15
|
+
* refreshBatch 内仍能拿到当时请求的 ctx
|
|
16
|
+
*
|
|
17
|
+
* 关键 header:
|
|
18
|
+
* - x-alicdn-site-id → siteId
|
|
19
|
+
* - host / x-forwarded-host → hostname(首选 host,缺失才退 x-forwarded-host)
|
|
20
|
+
*/
|
|
21
|
+
var _a;
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.getEdgeContext = exports.runWithEdgeContext = exports.buildEdgeContextFromHeaders = void 0;
|
|
24
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
25
|
+
// OpenNext build 把 wrapper / tagCache 等分别作为 esbuild 入口打包,即便同一 routine
|
|
26
|
+
// 里 edge-context.ts 也会被复制成多份 —— 每份各自 `new AsyncLocalStorage()`,
|
|
27
|
+
// store 互不可见,wrapper 注入的 ctx 在 cdn-purge 一侧读到永远是 undefined。
|
|
28
|
+
// 用 Symbol.for 把单例挂到 globalThis,所有副本拿到同一个 ALS。
|
|
29
|
+
const ALS_KEY = Symbol.for('pcg.edgeContext.als');
|
|
30
|
+
const globalRef = globalThis;
|
|
31
|
+
const storage = (_a = globalRef[ALS_KEY]) !== null && _a !== void 0 ? _a : (globalRef[ALS_KEY] = new node_async_hooks_1.AsyncLocalStorage());
|
|
32
|
+
const SITE_ID_HEADER = 'x-alicdn-site-id';
|
|
33
|
+
const HOSTNAME_HEADER = 'host';
|
|
34
|
+
const FORWARDED_HOSTNAME_HEADER = 'x-forwarded-host';
|
|
35
|
+
function pickHeader(headers, name) {
|
|
36
|
+
var _a;
|
|
37
|
+
return (_a = headers[name]) !== null && _a !== void 0 ? _a : headers[name.toLowerCase()];
|
|
38
|
+
}
|
|
39
|
+
function parseHostname(raw) {
|
|
40
|
+
var _a;
|
|
41
|
+
if (!raw)
|
|
42
|
+
return undefined;
|
|
43
|
+
const first = (_a = raw.split(',')[0]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
44
|
+
return first || undefined;
|
|
45
|
+
}
|
|
46
|
+
function parseSiteId(raw) {
|
|
47
|
+
if (!raw)
|
|
48
|
+
return undefined;
|
|
49
|
+
const trimmed = raw.trim();
|
|
50
|
+
if (!trimmed)
|
|
51
|
+
return undefined;
|
|
52
|
+
const n = Number(trimmed);
|
|
53
|
+
return Number.isFinite(n) && trimmed === String(n) ? n : trimmed;
|
|
54
|
+
}
|
|
55
|
+
function buildEdgeContextFromHeaders(headers) {
|
|
56
|
+
var _a;
|
|
57
|
+
const ctx = {};
|
|
58
|
+
const siteId = parseSiteId(pickHeader(headers, SITE_ID_HEADER));
|
|
59
|
+
if (siteId !== undefined)
|
|
60
|
+
ctx.siteId = siteId;
|
|
61
|
+
const hostname = (_a = parseHostname(pickHeader(headers, HOSTNAME_HEADER))) !== null && _a !== void 0 ? _a : parseHostname(pickHeader(headers, FORWARDED_HOSTNAME_HEADER));
|
|
62
|
+
if (hostname)
|
|
63
|
+
ctx.hostname = hostname;
|
|
64
|
+
return ctx;
|
|
65
|
+
}
|
|
66
|
+
exports.buildEdgeContextFromHeaders = buildEdgeContextFromHeaders;
|
|
67
|
+
function runWithEdgeContext(headers, fn) {
|
|
68
|
+
const ctx = buildEdgeContextFromHeaders(headers);
|
|
69
|
+
return storage.run(ctx, fn);
|
|
70
|
+
}
|
|
71
|
+
exports.runWithEdgeContext = runWithEdgeContext;
|
|
72
|
+
function getEdgeContext() {
|
|
73
|
+
var _a;
|
|
74
|
+
return (_a = storage.getStore()) !== null && _a !== void 0 ? _a : {};
|
|
75
|
+
}
|
|
76
|
+
exports.getEdgeContext = getEdgeContext;
|
|
77
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRnZS1jb250ZXh0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvZWRnZS1jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHOzs7O0FBRUgsdURBQXFEO0FBT3JELHNFQUFzRTtBQUN0RSxnRUFBZ0U7QUFDaEUsNERBQTREO0FBQzVELCtDQUErQztBQUMvQyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFJbEQsTUFBTSxTQUFTLEdBQUcsVUFBMkIsQ0FBQztBQUM5QyxNQUFNLE9BQU8sR0FDWCxNQUFBLFNBQVMsQ0FBQyxPQUFPLENBQUMsbUNBQ2xCLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksb0NBQWlCLEVBQWUsQ0FBQyxDQUFDO0FBRTlELE1BQU0sY0FBYyxHQUFHLGtCQUFrQixDQUFDO0FBQzFDLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQztBQUMvQixNQUFNLHlCQUF5QixHQUFHLGtCQUFrQixDQUFDO0FBRXJELFNBQVMsVUFBVSxDQUNqQixPQUEyQyxFQUMzQyxJQUFZOztJQUVaLE9BQU8sTUFBQSxPQUFPLENBQUMsSUFBSSxDQUFDLG1DQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsR0FBdUI7O0lBQzVDLElBQUksQ0FBQyxHQUFHO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDM0IsTUFBTSxLQUFLLEdBQUcsTUFBQSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQywwQ0FBRSxJQUFJLEVBQUUsQ0FBQztJQUN4QyxPQUFPLEtBQUssSUFBSSxTQUFTLENBQUM7QUFDNUIsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLEdBQXVCO0lBQzFDLElBQUksQ0FBQyxHQUFHO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDM0IsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzNCLElBQUksQ0FBQyxPQUFPO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDL0IsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFCLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUNuRSxDQUFDO0FBRUQsU0FBZ0IsMkJBQTJCLENBQ3pDLE9BQTJDOztJQUUzQyxNQUFNLEdBQUcsR0FBZ0IsRUFBRSxDQUFDO0lBQzVCLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7SUFDaEUsSUFBSSxNQUFNLEtBQUssU0FBUztRQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQzlDLE1BQU0sUUFBUSxHQUNaLE1BQUEsYUFBYSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUMsbUNBQ25ELGFBQWEsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLHlCQUF5QixDQUFDLENBQUMsQ0FBQztJQUNoRSxJQUFJLFFBQVE7UUFBRSxHQUFHLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUN0QyxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFYRCxrRUFXQztBQUVELFNBQWdCLGtCQUFrQixDQUNoQyxPQUEyQyxFQUMzQyxFQUFXO0lBRVgsTUFBTSxHQUFHLEdBQUcsMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakQsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBTkQsZ0RBTUM7QUFFRCxTQUFnQixjQUFjOztJQUM1QixPQUFPLE1BQUEsT0FBTyxDQUFDLFFBQVEsRUFBRSxtQ0FBSSxFQUFFLENBQUM7QUFDbEMsQ0FBQztBQUZELHdDQUVDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFZGdlIFJlcXVlc3QgQ29udGV4dFxuICpcbiAqIOWcqCBFU0EgLyDovrnnvJjnjq/looMsc2l0ZUlkIOWSjCBob3N0bmFtZSDku47lhaXnq5nor7fmsYIgaGVhZGVyIOWPlizkuI3lho3kvp3otZZcbiAqIOWQr+WKqOaXtiBlbnYg5rOo5YWl44CC5Y6f5ZugOlxuICogICAtIOS4gOS4qiByb3V0aW5lIOWunuS+i+WPr+iDveacjeWKoeWkmuS4qiBzaXRlIC8gaG9zdG5hbWUo54Gw5bqm44CB5aSa54mI5pys44CB6IGa5ZCI5Z+fKSxcbiAqICAgICDlkK/liqjml7YgZW52IOaXoOazleihqOi+viBwZXItcmVxdWVzdCDlj5jljJZcbiAqICAgLSDorqkgb3BzIOS4jeW/heWGjeS4uuavj+S4qumDqOe9sumineWklumFjeS4pOS4qiBlbnZcbiAqXG4gKiDlrp7njrDnlKggQXN5bmNMb2NhbFN0b3JhZ2U6XG4gKiAgIC0gbm9kZS1zZXJ2ZXIgd3JhcHBlciDlnKggaGFuZGxlciDlhaXlj6PlpIQgcnVuV2l0aEVkZ2VDb250ZXh0KGhlYWRlcnMsIGZuKVxuICogICAtIOS4i+a4uCBjZG4tcHVyZ2UgLyDlhbbku5bmqKHlnZfnlKggZ2V0RWRnZUNvbnRleHQoKSDlkIzmraXor7vlj5ZcbiAqICAgLSDljbPkvb8gcHVyZ2Ug5pivIGZpcmUtYW5kLWZvcmdldCxwcm9taXNlIOmTvuS5n+S8mue7p+aJv+W9k+WJjSBBTFMsXG4gKiAgICAgcmVmcmVzaEJhdGNoIOWGheS7jeiDveaLv+WIsOW9k+aXtuivt+axgueahCBjdHhcbiAqXG4gKiDlhbPplK4gaGVhZGVyOlxuICogICAtIHgtYWxpY2RuLXNpdGUtaWQgIOKGkiBzaXRlSWRcbiAqICAgLSBob3N0IC8geC1mb3J3YXJkZWQtaG9zdCDihpIgaG9zdG5hbWUo6aaW6YCJIGhvc3Qs57y65aSx5omN6YCAIHgtZm9yd2FyZGVkLWhvc3QpXG4gKi9cblxuaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tICdub2RlOmFzeW5jX2hvb2tzJztcblxuZXhwb3J0IGludGVyZmFjZSBFZGdlQ29udGV4dCB7XG4gIHNpdGVJZD86IHN0cmluZyB8IG51bWJlcjtcbiAgaG9zdG5hbWU/OiBzdHJpbmc7XG59XG5cbi8vIE9wZW5OZXh0IGJ1aWxkIOaKiiB3cmFwcGVyIC8gdGFnQ2FjaGUg562J5YiG5Yir5L2c5Li6IGVzYnVpbGQg5YWl5Y+j5omT5YyFLOWNs+S+v+WQjOS4gCByb3V0aW5lXG4vLyDph4wgZWRnZS1jb250ZXh0LnRzIOS5n+S8muiiq+WkjeWItuaIkOWkmuS7vSDigJTigJQg5q+P5Lu95ZCE6IeqIGBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKWAsXG4vLyBzdG9yZSDkupLkuI3lj6/op4Esd3JhcHBlciDms6jlhaXnmoQgY3R4IOWcqCBjZG4tcHVyZ2Ug5LiA5L6n6K+75Yiw5rC46L+c5pivIHVuZGVmaW5lZOOAglxuLy8g55SoIFN5bWJvbC5mb3Ig5oqK5Y2V5L6L5oyC5YiwIGdsb2JhbFRoaXMs5omA5pyJ5Ymv5pys5ou/5Yiw5ZCM5LiA5LiqIEFMU+OAglxuY29uc3QgQUxTX0tFWSA9IFN5bWJvbC5mb3IoJ3BjZy5lZGdlQ29udGV4dC5hbHMnKTtcbnR5cGUgR2xvYmFsV2l0aEFscyA9IHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICBbQUxTX0tFWV0/OiBBc3luY0xvY2FsU3RvcmFnZTxFZGdlQ29udGV4dD47XG59O1xuY29uc3QgZ2xvYmFsUmVmID0gZ2xvYmFsVGhpcyBhcyBHbG9iYWxXaXRoQWxzO1xuY29uc3Qgc3RvcmFnZTogQXN5bmNMb2NhbFN0b3JhZ2U8RWRnZUNvbnRleHQ+ID1cbiAgZ2xvYmFsUmVmW0FMU19LRVldID8/XG4gIChnbG9iYWxSZWZbQUxTX0tFWV0gPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2U8RWRnZUNvbnRleHQ+KCkpO1xuXG5jb25zdCBTSVRFX0lEX0hFQURFUiA9ICd4LWFsaWNkbi1zaXRlLWlkJztcbmNvbnN0IEhPU1ROQU1FX0hFQURFUiA9ICdob3N0JztcbmNvbnN0IEZPUldBUkRFRF9IT1NUTkFNRV9IRUFERVIgPSAneC1mb3J3YXJkZWQtaG9zdCc7XG5cbmZ1bmN0aW9uIHBpY2tIZWFkZXIoXG4gIGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4sXG4gIG5hbWU6IHN0cmluZ1xuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIGhlYWRlcnNbbmFtZV0gPz8gaGVhZGVyc1tuYW1lLnRvTG93ZXJDYXNlKCldO1xufVxuXG5mdW5jdGlvbiBwYXJzZUhvc3RuYW1lKHJhdzogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFyYXcpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGZpcnN0ID0gcmF3LnNwbGl0KCcsJylbMF0/LnRyaW0oKTtcbiAgcmV0dXJuIGZpcnN0IHx8IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcGFyc2VTaXRlSWQocmF3OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCBudW1iZXIgfCB1bmRlZmluZWQge1xuICBpZiAoIXJhdykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgdHJpbW1lZCA9IHJhdy50cmltKCk7XG4gIGlmICghdHJpbW1lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgbiA9IE51bWJlcih0cmltbWVkKTtcbiAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShuKSAmJiB0cmltbWVkID09PSBTdHJpbmcobikgPyBuIDogdHJpbW1lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRWRnZUNvbnRleHRGcm9tSGVhZGVycyhcbiAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPlxuKTogRWRnZUNvbnRleHQge1xuICBjb25zdCBjdHg6IEVkZ2VDb250ZXh0ID0ge307XG4gIGNvbnN0IHNpdGVJZCA9IHBhcnNlU2l0ZUlkKHBpY2tIZWFkZXIoaGVhZGVycywgU0lURV9JRF9IRUFERVIpKTtcbiAgaWYgKHNpdGVJZCAhPT0gdW5kZWZpbmVkKSBjdHguc2l0ZUlkID0gc2l0ZUlkO1xuICBjb25zdCBob3N0bmFtZSA9XG4gICAgcGFyc2VIb3N0bmFtZShwaWNrSGVhZGVyKGhlYWRlcnMsIEhPU1ROQU1FX0hFQURFUikpID8/XG4gICAgcGFyc2VIb3N0bmFtZShwaWNrSGVhZGVyKGhlYWRlcnMsIEZPUldBUkRFRF9IT1NUTkFNRV9IRUFERVIpKTtcbiAgaWYgKGhvc3RuYW1lKSBjdHguaG9zdG5hbWUgPSBob3N0bmFtZTtcbiAgcmV0dXJuIGN0eDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bldpdGhFZGdlQ29udGV4dDxUPihcbiAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPixcbiAgZm46ICgpID0+IFRcbik6IFQge1xuICBjb25zdCBjdHggPSBidWlsZEVkZ2VDb250ZXh0RnJvbUhlYWRlcnMoaGVhZGVycyk7XG4gIHJldHVybiBzdG9yYWdlLnJ1bihjdHgsIGZuKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVkZ2VDb250ZXh0KCk6IEVkZ2VDb250ZXh0IHtcbiAgcmV0dXJuIHN0b3JhZ2UuZ2V0U3RvcmUoKSA/PyB7fTtcbn1cbiJdfQ==
|