@wix/himalaya-cli 0.982.0 → 0.983.0

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +3434 -331
  2. package/package.json +3 -2
package/dist/cli.mjs CHANGED
@@ -1,13 +1,36 @@
1
1
  // AUTO-GENERATED self-contained bundle — DO NOT EDIT. Source: tools/himi-cli/src/. Regenerate: node scripts/bundle.mjs
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
8
  var __esm = (fn, res) => function __init() {
5
9
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
10
  };
11
+ var __commonJS = (cb, mod) => function __require() {
12
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13
+ };
7
14
  var __export = (target, all) => {
8
15
  for (var name in all)
9
16
  __defProp(target, name, { get: all[name], enumerable: true });
10
17
  };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key2 of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key2) && key2 !== except)
22
+ __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ // If the importer is in node compatibility mode or this is not an ESM
28
+ // file that has been converted to a CommonJS file using a Babel-
29
+ // compatible transform (i.e. "__esModule" has not been set), then set
30
+ // "default" to the CommonJS "module.exports" for node compatibility.
31
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
+ mod
33
+ ));
11
34
 
12
35
  // ../../core/ts/src/serve-origins.ts
13
36
  function isPublicServeOrigin(url) {
@@ -4200,7 +4223,7 @@ var init_build = __esm({
4200
4223
 
4201
4224
  // ../../core/dev-server/src/quickjs-intl.ts
4202
4225
  function installIntl(ctx) {
4203
- const parse = (s) => {
4226
+ const parse2 = (s) => {
4204
4227
  if (!s) return void 0;
4205
4228
  try {
4206
4229
  return JSON.parse(
@@ -4216,8 +4239,8 @@ function installIntl(ctx) {
4216
4239
  "__himiIntlDate",
4217
4240
  (l, o, t) => {
4218
4241
  const fmt = new Intl.DateTimeFormat(
4219
- parse(ctx.getString(l)),
4220
- parse(ctx.getString(o))
4242
+ parse2(ctx.getString(l)),
4243
+ parse2(ctx.getString(o))
4221
4244
  );
4222
4245
  return ctx.newString(fmt.format(new Date(ctx.getNumber(t))));
4223
4246
  }
@@ -4244,8 +4267,8 @@ function installIntl(ctx) {
4244
4267
  (k, t, l, o) => {
4245
4268
  const kind = ctx.getString(k);
4246
4269
  const date = new Date(ctx.getNumber(t));
4247
- const locales = parse(ctx.getString(l));
4248
- const options = parse(ctx.getString(o));
4270
+ const locales = parse2(ctx.getString(l));
4271
+ const options = parse2(ctx.getString(o));
4249
4272
  const out = kind === "d" ? date.toLocaleDateString(locales, options) : kind === "t" ? date.toLocaleTimeString(locales, options) : date.toLocaleString(locales, options);
4250
4273
  return ctx.newString(out);
4251
4274
  }
@@ -4254,8 +4277,8 @@ function installIntl(ctx) {
4254
4277
  "__himiIntlNumber",
4255
4278
  (l, o, v, k) => {
4256
4279
  const fmt = new Intl.NumberFormat(
4257
- parse(ctx.getString(l)),
4258
- parse(ctx.getString(o))
4280
+ parse2(ctx.getString(l)),
4281
+ parse2(ctx.getString(o))
4259
4282
  );
4260
4283
  const raw = ctx.getString(v);
4261
4284
  const kind = k === void 0 ? "n" : ctx.getString(k);
@@ -4267,8 +4290,8 @@ function installIntl(ctx) {
4267
4290
  "__himiIntlCompare",
4268
4291
  (a, b, l, o) => {
4269
4292
  const collator = new Intl.Collator(
4270
- parse(ctx.getString(l)),
4271
- parse(o === void 0 ? "" : ctx.getString(o))
4293
+ parse2(ctx.getString(l)),
4294
+ parse2(o === void 0 ? "" : ctx.getString(o))
4272
4295
  );
4273
4296
  return ctx.newNumber(collator.compare(ctx.getString(a), ctx.getString(b)));
4274
4297
  }
@@ -4280,8 +4303,8 @@ function installIntl(ctx) {
4280
4303
  // crawled path may never reach.
4281
4304
  "__himiIntlValidate",
4282
4305
  (k, l, o) => {
4283
- const locales = parse(ctx.getString(l));
4284
- const options = parse(ctx.getString(o));
4306
+ const locales = parse2(ctx.getString(l));
4307
+ const options = parse2(ctx.getString(o));
4285
4308
  switch (ctx.getString(k)) {
4286
4309
  case "DateTimeFormat":
4287
4310
  new Intl.DateTimeFormat(locales, options);
@@ -4771,7 +4794,7 @@ function installWebGlobals(ctx) {
4771
4794
  });
4772
4795
  ctx.setProp(ctx.global, "__himiQueryEncode", queryEncode);
4773
4796
  queryEncode.dispose();
4774
- const parse = ctx.newFunction("__himiParseUrl", (hrefH, baseH) => {
4797
+ const parse2 = ctx.newFunction("__himiParseUrl", (hrefH, baseH) => {
4775
4798
  const href = ctx.getString(hrefH);
4776
4799
  const base = ctx.getString(baseH);
4777
4800
  try {
@@ -4781,8 +4804,8 @@ function installWebGlobals(ctx) {
4781
4804
  return ctx.newString(JSON.stringify({ error: err?.message ?? "Invalid URL" }));
4782
4805
  }
4783
4806
  });
4784
- ctx.setProp(ctx.global, "__himiParseUrl", parse);
4785
- parse.dispose();
4807
+ ctx.setProp(ctx.global, "__himiParseUrl", parse2);
4808
+ parse2.dispose();
4786
4809
  const res = ctx.evalCode(WEB_GLOBALS_SHIM, "himi-web-globals.js");
4787
4810
  if (res.error) {
4788
4811
  const detail = ctx.dump(res.error);
@@ -5450,9 +5473,9 @@ function scanWidgetPayload(node, family, path, bindings, disallowed, timeRefs, i
5450
5473
  }
5451
5474
  }
5452
5475
  function validateWidget(snapshot2) {
5453
- const validate2 = compileWidgetSchema();
5454
- const schemaOk = validate2(snapshot2);
5455
- const schemaErrors = schemaOk ? [] : validate2.errors ?? [];
5476
+ const validate3 = compileWidgetSchema();
5477
+ const schemaOk = validate3(snapshot2);
5478
+ const schemaErrors = schemaOk ? [] : validate3.errors ?? [];
5456
5479
  const bindingViolations = [];
5457
5480
  const disallowedComponents = [];
5458
5481
  const timeRefViolations = [];
@@ -18831,7 +18854,6 @@ function shouldRevealError(args) {
18831
18854
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
18832
18855
  var init_validation = __esm({
18833
18856
  "../../core/ts/src/validation.ts"() {
18834
- "use strict";
18835
18857
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
18836
18858
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
18837
18859
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -22256,7 +22278,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
22256
22278
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
22257
22279
  var init_worker_subtree = __esm({
22258
22280
  "../../core/ts/src/worker-subtree.ts"() {
22259
- "use strict";
22260
22281
  init_worker_subtree_safe_types_generated();
22261
22282
  WORKER_SUBTREE_CEILINGS = Object.freeze({
22262
22283
  maxEncodedBytes: 65536,
@@ -22533,7 +22554,7 @@ function ensureMeasureRuntime() {
22533
22554
  if (measureRuntimeInjected || typeof document === "undefined") return;
22534
22555
  measureRuntimeInjected = true;
22535
22556
  const store = {};
22536
- const parse = (s) => {
22557
+ const parse2 = (s) => {
22537
22558
  if (!s) return {};
22538
22559
  try {
22539
22560
  const o = JSON.parse(s);
@@ -22544,13 +22565,13 @@ function ensureMeasureRuntime() {
22544
22565
  };
22545
22566
  const applyConsumers = () => {
22546
22567
  document.querySelectorAll("[data-hm-measure-bind]").forEach((el) => {
22547
- const patch = measureConsumerStyle(parse(el.getAttribute("data-hm-measure-bind")), store);
22568
+ const patch = measureConsumerStyle(parse2(el.getAttribute("data-hm-measure-bind")), store);
22548
22569
  const style = el.style;
22549
22570
  for (const k of Object.keys(patch)) style[k] = patch[k];
22550
22571
  });
22551
22572
  };
22552
22573
  const measure = (el) => {
22553
- const cfg = parse(el.getAttribute("data-hm-measure"));
22574
+ const cfg = parse2(el.getAttribute("data-hm-measure"));
22554
22575
  const rect = el.getBoundingClientRect();
22555
22576
  let changed = false;
22556
22577
  if (cfg.h) {
@@ -35626,7 +35647,7 @@ var init_dependencies = __esm({
35626
35647
  // ../../core/functions-build/src/sbom.ts
35627
35648
  import { createHash as createHash16 } from "node:crypto";
35628
35649
  function createFunctionSbom(packages) {
35629
- const components2 = [...packages].sort((a, b) => a.name.localeCompare(b.name)).map(({ name, version, integrity: integrity2, license }) => ({ name, version, integrity: integrity2, license }));
35650
+ const components2 = [...packages].sort((a, b) => a.name.localeCompare(b.name)).map(({ name, version: version2, integrity: integrity2, license }) => ({ name, version: version2, integrity: integrity2, license }));
35630
35651
  const body = JSON.stringify({ format: "himalaya-sbom-v1", components: components2 });
35631
35652
  return { format: "himalaya-sbom-v1", components: components2, hash: createHash16("sha256").update(body).digest("hex") };
35632
35653
  }
@@ -39723,7 +39744,7 @@ function ipv6Private(address) {
39723
39744
  const value = address.toLowerCase().replace(/^\[|\]$/g, "");
39724
39745
  const sections = value.split("::");
39725
39746
  if (sections.length > 2) return true;
39726
- const parse = (section2) => {
39747
+ const parse2 = (section2) => {
39727
39748
  if (!section2) return [];
39728
39749
  const parts = section2.split(":");
39729
39750
  const last = parts.at(-1) ?? "";
@@ -39733,8 +39754,8 @@ function ipv6Private(address) {
39733
39754
  if (octets.length !== 4 || octets.some((octet) => !Number.isInteger(octet) || octet < 0 || octet > 255)) return [Number.NaN];
39734
39755
  return [...parts.map((part) => Number.parseInt(part, 16)), octets[0] * 256 + octets[1], octets[2] * 256 + octets[3]];
39735
39756
  };
39736
- const head = parse(sections[0]);
39737
- const tail = parse(sections[1] ?? "");
39757
+ const head = parse2(sections[0]);
39758
+ const tail = parse2(sections[1] ?? "");
39738
39759
  const words = sections.length === 2 ? [...head, ...Array.from({ length: Math.max(0, 8 - head.length - tail.length) }, () => 0), ...tail] : [...head];
39739
39760
  if (words.length !== 8 || words.some((word) => !Number.isInteger(word) || word < 0 || word > 65535)) return true;
39740
39761
  const mappedOrCompatible = words.slice(0, 5).every((word) => word === 0) && (words[5] === 0 || words[5] === 65535);
@@ -39747,8 +39768,8 @@ function ipv6Private(address) {
39747
39768
  return value.startsWith("fe8") || value.startsWith("fe9") || value.startsWith("fea") || value.startsWith("feb") || Number.isFinite(firstWord) && (firstWord & 65024) === 64512;
39748
39769
  }
39749
39770
  function privateAddress(address) {
39750
- const version = isIP(address);
39751
- return version === 4 ? ipv4Private(address) : version === 6 ? ipv6Private(address) : true;
39771
+ const version2 = isIP(address);
39772
+ return version2 === 4 ? ipv4Private(address) : version2 === 6 ? ipv6Private(address) : true;
39752
39773
  }
39753
39774
  async function checkDestination(url, options) {
39754
39775
  if (!/^https?:$/.test(url.protocol) || url.username || url.password) throw new Error("only credential-free HTTP(S) URLs are allowed");
@@ -40481,8 +40502,8 @@ function planResourceChange(input) {
40481
40502
  const reusable = versions.filter((candidate) => candidate.status === "retired" && candidate.type === field.type).toSorted((left, right) => right.version - left.version)[0];
40482
40503
  if (!current && reusable) operations.push({ kind: "restore-field", collection: request.name, field: field.key, version: reusable.version });
40483
40504
  else if (!current) {
40484
- const version = (latest?.version ?? 0) + 1;
40485
- operations.push({ kind: "add-field", collection: request.name, field: { logicalName: field.key, physicalName: version === 1 ? field.key : `${field.key}__v${version}`, type: field.type, displayName: field.displayName, status: "active", version } });
40505
+ const version2 = (latest?.version ?? 0) + 1;
40506
+ operations.push({ kind: "add-field", collection: request.name, field: { logicalName: field.key, physicalName: version2 === 1 ? field.key : `${field.key}__v${version2}`, type: field.type, displayName: field.displayName, status: "active", version: version2 } });
40486
40507
  } else if (current.type !== field.type && reusable) operations.push({ kind: "restore-field", collection: request.name, field: field.key, version: reusable.version });
40487
40508
  else if (current.type !== field.type) operations.push({ kind: "replace-field", collection: request.name, logicalName: field.key, type: field.type, displayName: field.displayName });
40488
40509
  }
@@ -44185,9 +44206,9 @@ async function runWixMobileRelease(pos, flags, io, deps) {
44185
44206
  if (str(flags.artifact)) return fail2("--artifact is not accepted for Himi Player; pass --release so deployed serve can validate the Job Service IPA and call MRE with its service identity");
44186
44207
  if (on(flags["no-wait"])) return fail2("--no-wait is not supported for Himi Player TestFlight releases; wait for MRE processing to complete");
44187
44208
  const release = str(flags.release);
44188
- const version = str(flags.version);
44209
+ const version2 = str(flags.version);
44189
44210
  if (!release) return fail2("--release is required for a Himi Player TestFlight release");
44190
- if (!version || !/^\d+(?:\.\d+){0,2}$/.test(version)) return fail2("--version needs the Player marketing version (for example 1.0.0)");
44211
+ if (!version2 || !/^\d+(?:\.\d+){0,2}$/.test(version2)) return fail2("--version needs the Player marketing version (for example 1.0.0)");
44191
44212
  if (str(flags.track) && str(flags.track) !== "testflight" && str(flags.track) !== "internal") return fail2("Wix Mobile Release only supports TestFlight upload; public App Store release remains a separate human step");
44192
44213
  const plan = {
44193
44214
  ok: true,
@@ -44195,7 +44216,7 @@ async function runWixMobileRelease(pos, flags, io, deps) {
44195
44216
  provider: "wix-mobile-release",
44196
44217
  app,
44197
44218
  release,
44198
- version,
44219
+ version: version2,
44199
44220
  destination: "TestFlight \xB7 Wix-owned Himi Player \xB7 internal upload",
44200
44221
  steps: ["Himi Job Service iOS build", "approved-bucket validation", "POCO MRE provisioning and re-sign", "MRE TestFlight upload", "MRE status poll"]
44201
44222
  };
@@ -44206,13 +44227,13 @@ async function runWixMobileRelease(pos, flags, io, deps) {
44206
44227
  if (!deps.releasePlayerJob) return fail2("this Himi CLI cannot create a service-side Himi Player TestFlight job; target deployed serve");
44207
44228
  if (!on(flags.yes)) {
44208
44229
  if (io.isTTY !== true) return fail2("refusing to dispatch a Wix TestFlight release without --yes in a non-interactive shell");
44209
- if (!await deps.confirm(` Dispatch Himi Player ${version} to Wix TestFlight?`)) {
44230
+ if (!await deps.confirm(` Dispatch Himi Player ${version2} to Wix TestFlight?`)) {
44210
44231
  io.log(" aborted \u2014 no release was dispatched.");
44211
44232
  return 1;
44212
44233
  }
44213
44234
  }
44214
44235
  try {
44215
- const released = await deps.releasePlayerJob(release, version);
44236
+ const released = await deps.releasePlayerJob(release, version2);
44216
44237
  const status = released.status.toUpperCase();
44217
44238
  if (mreStatusKind(status) !== "completed") return fail2(`Himi Player TestFlight job ${status || "FAILED"}`, { jobId: released.jobId, ...released.requestId ? { requestId: released.requestId } : {}, ...released.error ? { error: released.error } : {} });
44218
44239
  print({ ok: true, provider: "wix-mobile-release", app, jobId: released.jobId, ...released.requestId ? { requestId: released.requestId } : {}, status, ...released.url ? { url: released.url } : {} });
@@ -44245,11 +44266,11 @@ function pad(label2, width = 12) {
44245
44266
  return label2.length >= width ? label2 : label2 + " ".repeat(width - label2.length);
44246
44267
  }
44247
44268
  function accountHeader(args) {
44248
- const { app, bundleId, version, nextBuild, creds, track } = args;
44269
+ const { app, bundleId, version: version2, nextBuild, creds, track } = args;
44249
44270
  const issuer = creds.ascIssuerId.length <= 8 ? creds.ascIssuerId : `${creds.ascIssuerId.slice(0, 8)}\u2026`;
44250
44271
  const account = creds.source === "env" ? "from ASC_* environment" : `profile "${creds.profile}" (${creds.source === "flag" ? "--profile" : "store.config.yaml"})`;
44251
44272
  return [
44252
- ` ${pad("app")}${app} ios ${version.marketing} (${version.build} \u2192 ${nextBuild})`,
44273
+ ` ${pad("app")}${app} ios ${version2.marketing} (${version2.build} \u2192 ${nextBuild})`,
44253
44274
  ` ${pad("bundle")}${bundleId}`,
44254
44275
  ` ${pad("team")}${creds.team} key ${creds.ascKeyId} \xB7 issuer ${issuer}`,
44255
44276
  ` ${pad("account")}${account}`,
@@ -44352,25 +44373,25 @@ async function runStore(pos, flags, io, deps) {
44352
44373
  }
44353
44374
  const bundleId = cfg.ios?.bundleId ?? "(unset)";
44354
44375
  let creds;
44355
- let version;
44376
+ let version2;
44356
44377
  try {
44357
44378
  creds = deps.resolveCredentials({ app, cfg, profileFlag: str2(flags.profile) });
44358
- version = deps.readVersion(app);
44379
+ version2 = deps.readVersion(app);
44359
44380
  } catch (e) {
44360
44381
  return fail2(e.message);
44361
44382
  }
44362
- if (!Number.isInteger(version.build)) {
44383
+ if (!Number.isInteger(version2.build)) {
44363
44384
  return fail2(
44364
- `${app} has a non-integer CFBundleVersion (${JSON.stringify(version.build)}) \u2014 this command bumps and matches build numbers arithmetically. Use an integer CFBundleVersion.`,
44365
- { app, marketing: version.marketing }
44385
+ `${app} has a non-integer CFBundleVersion (${JSON.stringify(version2.build)}) \u2014 this command bumps and matches build numbers arithmetically. Use an integer CFBundleVersion.`,
44386
+ { app, marketing: version2.marketing }
44366
44387
  );
44367
44388
  }
44368
44389
  const reuseExisting = on2(flags["skip-build"]);
44369
- const nextBuild = reuseExisting ? version.build : version.build + 1;
44390
+ const nextBuild = reuseExisting ? version2.build : version2.build + 1;
44370
44391
  const plannedSteps = UPLOAD_STEPS.filter((s) => !(reuseExisting && BUILD_STEPS.has(s)));
44371
44392
  if (!json5) {
44372
44393
  io.log("");
44373
- for (const line of accountHeader({ app, bundleId, version, nextBuild, creds, track })) io.log(line);
44394
+ for (const line of accountHeader({ app, bundleId, version: version2, nextBuild, creds, track })) io.log(line);
44374
44395
  io.log("");
44375
44396
  for (const f of findings) io.log(` ${f.level === "error" ? "\u2717" : "!"} ${f.message}`);
44376
44397
  }
@@ -44392,7 +44413,7 @@ async function runStore(pos, flags, io, deps) {
44392
44413
  ascKeyId: creds.ascKeyId,
44393
44414
  credentialSource: creds.source,
44394
44415
  ...creds.profile ? { credentialProfile: creds.profile } : {},
44395
- version: { marketing: version.marketing, build: version.build, next: nextBuild },
44416
+ version: { marketing: version2.marketing, build: version2.build, next: nextBuild },
44396
44417
  steps: [...plannedSteps],
44397
44418
  warnings: warnings.map((w) => w.message)
44398
44419
  };
@@ -44411,7 +44432,7 @@ async function runStore(pos, flags, io, deps) {
44411
44432
  { app, track, team: creds.team }
44412
44433
  );
44413
44434
  }
44414
- const okToGo = await deps.confirm(` Upload ${app} ${version.marketing} (${nextBuild}) to App Store Connect team ${creds.team}?`);
44435
+ const okToGo = await deps.confirm(` Upload ${app} ${version2.marketing} (${nextBuild}) to App Store Connect team ${creds.team}?`);
44415
44436
  if (!okToGo) {
44416
44437
  io.log(" aborted \u2014 nothing was built or uploaded.");
44417
44438
  return 1;
@@ -44419,16 +44440,16 @@ async function runStore(pos, flags, io, deps) {
44419
44440
  }
44420
44441
  let uploaded;
44421
44442
  try {
44422
- uploaded = reuseExisting ? version : deps.bumpBuild(app);
44443
+ uploaded = reuseExisting ? version2 : deps.bumpBuild(app);
44423
44444
  } catch (e) {
44424
44445
  return fail2(`could not bump the build number: ${e.message}`);
44425
44446
  }
44426
44447
  const rollback = () => {
44427
44448
  if (reuseExisting) return;
44428
44449
  try {
44429
- deps.setVersion(app, version);
44450
+ deps.setVersion(app, version2);
44430
44451
  } catch (e) {
44431
- io.error(JSON.stringify({ warning: `could not restore the build number to ${version.build}: ${e.message}` }));
44452
+ io.error(JSON.stringify({ warning: `could not restore the build number to ${version2.build}: ${e.message}` }));
44432
44453
  }
44433
44454
  };
44434
44455
  for (const step of plannedSteps) {
@@ -47635,7 +47656,297 @@ var init_permissions = __esm({
47635
47656
  }
47636
47657
  });
47637
47658
 
47659
+ // src/site-analyze/net-guard.ts
47660
+ import { lookup as dnsLookup } from "node:dns";
47661
+ import { request as httpsRequest2 } from "node:https";
47662
+ import { Readable as Readable2 } from "node:stream";
47663
+ import { createBrotliDecompress, createGunzip, createInflate } from "node:zlib";
47664
+ function ipv4Octets(host) {
47665
+ const m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
47666
+ if (!m) return null;
47667
+ const octets = m.slice(1).map(Number);
47668
+ return octets.every((o) => o <= 255) ? octets : null;
47669
+ }
47670
+ function isPrivateV4([a, b, c]) {
47671
+ if (a === 0 || a === 127) return true;
47672
+ if (a === 10) return true;
47673
+ if (a === 192 && b === 168) return true;
47674
+ if (a === 172 && b >= 16 && b <= 31) return true;
47675
+ if (a === 169 && b === 254) return true;
47676
+ if (a === 100 && b >= 64 && b <= 127) return true;
47677
+ if (a === 192 && b === 0 && c === 0) return true;
47678
+ if (a === 192 && b === 0 && c === 2) return true;
47679
+ if (a === 198 && b === 51 && c === 100) return true;
47680
+ if (a === 203 && b === 0 && c === 113) return true;
47681
+ if (a === 198 && (b === 18 || b === 19)) return true;
47682
+ if (a === 192 && b === 88 && c === 99) return true;
47683
+ return a >= 224;
47684
+ }
47685
+ function v6Groups(host) {
47686
+ let text2 = host;
47687
+ const dotted = /:((?:\d{1,3}\.){3}\d{1,3})$/.exec(text2);
47688
+ if (dotted) {
47689
+ const octets = ipv4Octets(dotted[1]);
47690
+ if (!octets) return null;
47691
+ const hi = (octets[0] << 8 | octets[1]).toString(16);
47692
+ const lo = (octets[2] << 8 | octets[3]).toString(16);
47693
+ text2 = `${text2.slice(0, dotted.index)}:${hi}:${lo}`;
47694
+ }
47695
+ const halves = text2.split("::");
47696
+ if (halves.length > 2) return null;
47697
+ const parts = (part) => part ? part.split(":") : [];
47698
+ const head = parts(halves[0]);
47699
+ const tail = halves.length === 2 ? parts(halves[1]) : [];
47700
+ const fill = 8 - head.length - tail.length;
47701
+ if (halves.length === 2 && fill < 0) return null;
47702
+ const groups = halves.length === 2 ? [...head, ...new Array(fill).fill("0"), ...tail] : head;
47703
+ if (groups.length !== 8) return null;
47704
+ const out = groups.map((g) => /^[0-9a-f]{1,4}$/i.test(g) ? parseInt(g, 16) : NaN);
47705
+ return out.every((g) => Number.isInteger(g)) ? out : null;
47706
+ }
47707
+ function isPrivateV6(host) {
47708
+ const g = v6Groups(host);
47709
+ if (!g) return true;
47710
+ const embedded = (hi, lo) => isPrivateV4([hi >> 8, hi & 255, lo >> 8, lo & 255]);
47711
+ const leadingZeros = g.slice(0, 5).every((x) => x === 0);
47712
+ if (leadingZeros && g[5] === 0) return true;
47713
+ if (leadingZeros && g[5] === 65535) return embedded(g[6], g[7]);
47714
+ if ((g[0] & 65280) === 0) return true;
47715
+ if ((g[0] & 65024) === 64512) return true;
47716
+ if ((g[0] & 65472) === 65152) return true;
47717
+ if ((g[0] & 65472) === 65216) return true;
47718
+ if ((g[0] & 65280) === 65280) return true;
47719
+ if (g[0] === 100 && g[1] === 65435) return true;
47720
+ if (g[0] === 256 && g[1] === 0 && g[2] === 0 && g[3] === 0) return true;
47721
+ if (g[0] === 8193 && g[1] <= 511) return true;
47722
+ if (g[0] === 8193 && g[1] === 3512) return true;
47723
+ if (g[0] === 16383 && (g[1] & 61440) === 0) return true;
47724
+ if (g[0] === 24320) return true;
47725
+ if (g[0] === 8194) return embedded(g[1], g[2]);
47726
+ return false;
47727
+ }
47728
+ function isBlockedAddress(address) {
47729
+ const host = address.toLowerCase().replace(/^\[|\]$/g, "");
47730
+ if (!host) return true;
47731
+ const v4 = ipv4Octets(host);
47732
+ if (v4) return isPrivateV4(v4);
47733
+ if (host.includes(":")) return isPrivateV6(host);
47734
+ return true;
47735
+ }
47736
+ function isFetchableFontUrl(raw) {
47737
+ let url;
47738
+ try {
47739
+ url = new URL(raw);
47740
+ } catch {
47741
+ return false;
47742
+ }
47743
+ if (url.protocol !== "https:") return false;
47744
+ const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.+$/, "");
47745
+ if (!host) return false;
47746
+ if (host === "localhost" || host.endsWith(".localhost")) return false;
47747
+ if (host.endsWith(".internal") || host.endsWith(".local")) return false;
47748
+ const v4 = ipv4Octets(host);
47749
+ if (v4) return !isPrivateV4(v4);
47750
+ if (host.includes(":")) return !isPrivateV6(host);
47751
+ return true;
47752
+ }
47753
+ function siteUrlRefusal(raw) {
47754
+ const shown2 = JSON.stringify(raw.length > 200 ? `${raw.slice(0, 200)}\u2026` : raw);
47755
+ let url;
47756
+ try {
47757
+ url = new URL(raw);
47758
+ } catch {
47759
+ return `refusing to fetch ${shown2}: it is not a URL \u2014 a scheme is required. Allowed: ${PUBLIC_SITE_RULE}.`;
47760
+ }
47761
+ if (url.protocol !== "https:") {
47762
+ return `refusing to fetch ${shown2}: scheme "${url.protocol}" is not https. Allowed: ${PUBLIC_SITE_RULE}.`;
47763
+ }
47764
+ if (url.port && url.port !== "443") {
47765
+ return `refusing to fetch ${shown2}: port ${url.port} is not the default 443. Allowed: ${PUBLIC_SITE_RULE}.`;
47766
+ }
47767
+ if (!isFetchableFontUrl(url.href)) {
47768
+ return `refusing to fetch ${shown2}: host "${url.hostname}" is not a public host. Allowed: ${PUBLIC_SITE_RULE}.`;
47769
+ }
47770
+ return null;
47771
+ }
47772
+ function assertPublicSiteUrl(raw) {
47773
+ const refusal = siteUrlRefusal(raw);
47774
+ if (refusal) throw new Error(refusal);
47775
+ }
47776
+ function resolveAll(hostname2) {
47777
+ return new Promise((resolve43, reject) => {
47778
+ dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
47779
+ if (err) reject(err);
47780
+ else resolve43(addresses);
47781
+ });
47782
+ });
47783
+ }
47784
+ function withAbort(start, signal, what) {
47785
+ if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
47786
+ const work = start();
47787
+ if (!signal) return work;
47788
+ return new Promise((resolve43, reject) => {
47789
+ const onAbort = () => reject(new Error(`${what} aborted`));
47790
+ signal.addEventListener("abort", onAbort, { once: true });
47791
+ work.then(resolve43, reject).finally(() => signal.removeEventListener("abort", onAbort));
47792
+ });
47793
+ }
47794
+ async function pinAddress(url, resolve43 = resolveAll, signal) {
47795
+ const host = url.hostname.replace(/^\[|\]$/g, "");
47796
+ if (ipv4Octets(host)) {
47797
+ if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
47798
+ return { address: host, family: 4 };
47799
+ }
47800
+ if (host.includes(":")) {
47801
+ if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
47802
+ return { address: host, family: 6 };
47803
+ }
47804
+ const addresses = await withAbort(() => resolve43(host), signal, `${host} lookup`);
47805
+ if (!addresses.length) throw new Error(`${host} resolved to no address`);
47806
+ const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
47807
+ if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
47808
+ return { address: addresses[0].address, family: addresses[0].family };
47809
+ }
47810
+ function realPin(url, signal) {
47811
+ return pinAddress(url, resolveAll, signal);
47812
+ }
47813
+ function decodedBody(res, hasBody) {
47814
+ if (!hasBody) return res;
47815
+ const codings = (res.headers["content-encoding"] ?? "").split(",").map((c) => c.trim().toLowerCase()).filter((c) => c && c !== "identity");
47816
+ const makers = codings.reverse().map((coding) => {
47817
+ const make = DECODERS.get(coding);
47818
+ if (!make) throw new Error(`unsupported content-encoding "${coding}"`);
47819
+ return make;
47820
+ });
47821
+ let out = res;
47822
+ for (const make of makers) {
47823
+ const next = make();
47824
+ out.on("error", (err) => next.emit("error", err));
47825
+ out = out.pipe(next);
47826
+ }
47827
+ return out;
47828
+ }
47829
+ function copyIncomingHeaders(headers2) {
47830
+ const out = new Headers();
47831
+ for (const [k, v] of Object.entries(headers2)) {
47832
+ if (typeof v === "string") out.set(k, v);
47833
+ else if (Array.isArray(v)) {
47834
+ if (k.toLowerCase() === "set-cookie") {
47835
+ for (const one of v) out.append(k, one);
47836
+ } else {
47837
+ out.set(k, v.join(", "));
47838
+ }
47839
+ }
47840
+ }
47841
+ return out;
47842
+ }
47843
+ function requestOnce(url, pinned, init) {
47844
+ return new Promise((resolve43, reject) => {
47845
+ const headers2 = { host: url.host, "accept-encoding": "identity" };
47846
+ new Headers(init.headers ?? {}).forEach((value, key2) => {
47847
+ if (key2.toLowerCase() !== "host") headers2[key2] = value;
47848
+ });
47849
+ const req = httpsRequest2(
47850
+ {
47851
+ // The ADDRESS is what we connect to; `servername` and the Host header keep the NAME, so
47852
+ // SNI and certificate validation are exactly what they would have been. Pinning by
47853
+ // rewriting the url to an IP would have broken both.
47854
+ host: pinned.address,
47855
+ servername: url.hostname.replace(/^\[|\]$/g, ""),
47856
+ port: url.port ? Number(url.port) : 443,
47857
+ path: `${url.pathname}${url.search}`,
47858
+ method: (init.method ?? "GET").toUpperCase(),
47859
+ headers: headers2,
47860
+ family: pinned.family
47861
+ },
47862
+ (res) => {
47863
+ const status = res.statusCode ?? 0;
47864
+ const out = copyIncomingHeaders(res.headers);
47865
+ const hasBody = status !== 204 && status !== 304 && (init.method ?? "GET").toUpperCase() !== "HEAD";
47866
+ let body = null;
47867
+ try {
47868
+ body = hasBody ? Readable2.toWeb(decodedBody(res, hasBody)) : null;
47869
+ } catch (err) {
47870
+ res.resume();
47871
+ reject(err);
47872
+ return;
47873
+ }
47874
+ resolve43(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
47875
+ }
47876
+ );
47877
+ req.on("error", reject);
47878
+ const signal = init.signal;
47879
+ if (signal) {
47880
+ if (signal.aborted) req.destroy(new Error("aborted"));
47881
+ else signal.addEventListener("abort", () => req.destroy(new Error("aborted")), { once: true });
47882
+ }
47883
+ req.end();
47884
+ });
47885
+ }
47886
+ async function discardBody(res) {
47887
+ try {
47888
+ await res?.body?.cancel();
47889
+ } catch {
47890
+ }
47891
+ }
47892
+ async function followPinned(href, init, perform, pin = (u, s) => pinAddress(u, resolveAll, s), allow = ASSET_HOP) {
47893
+ let url = new URL(href);
47894
+ for (let hop = 0; ; hop += 1) {
47895
+ const refusal = allow(url);
47896
+ if (refusal) throw new Error(refusal);
47897
+ const pinned = await pin(url, init.signal);
47898
+ const res = await perform(url, pinned, init);
47899
+ const location = res.headers.get("location");
47900
+ if (!REDIRECT_STATUS.has(res.status) || !location) return res;
47901
+ const mode = init.redirect ?? "follow";
47902
+ if (mode === "manual") return res;
47903
+ await discardBody(res);
47904
+ if (mode === "error") throw new Error(`redirect refused by redirect:"error" at ${url.href}`);
47905
+ if (hop >= MAX_REDIRECTS) throw new Error(`too many redirects from ${url.href}`);
47906
+ url = new URL(location, url);
47907
+ }
47908
+ }
47909
+ function makePinnedFetch(allow, label2, pin = realPin, perform = requestOnce) {
47910
+ const transport = (async (input, init) => {
47911
+ if (typeof input !== "string" && !(input instanceof URL)) {
47912
+ throw new TypeError(`${label2} takes a url \u2014 the analyzer's Request-shaped calls use the API transport`);
47913
+ }
47914
+ if (init?.body != null) {
47915
+ throw new TypeError(`${label2} is GET-only \u2014 a request with a body belongs on the API transport`);
47916
+ }
47917
+ const method = (init?.method ?? "GET").toUpperCase();
47918
+ if (method !== "GET" && method !== "HEAD") {
47919
+ throw new TypeError(`${label2} is GET-only, refusing ${method}`);
47920
+ }
47921
+ return followPinned(input instanceof URL ? input.href : input, init ?? {}, perform, pin, allow);
47922
+ });
47923
+ transport.pin = pin;
47924
+ transport.perform = perform;
47925
+ return transport;
47926
+ }
47927
+ var PUBLIC_SITE_RULE, DECODERS, MAX_REDIRECTS, REDIRECT_STATUS, ASSET_HOP, SITE_HOP, pinnedFetch2, guardedSiteFetch;
47928
+ var init_net_guard = __esm({
47929
+ "src/site-analyze/net-guard.ts"() {
47930
+ PUBLIC_SITE_RULE = "the analyzer reads a PUBLIC site: an https:// URL on the default port (443) whose host is not localhost, not an .internal/.local name, and not a loopback, link-local, private or otherwise non-globally-reachable address";
47931
+ DECODERS = /* @__PURE__ */ new Map([
47932
+ ["gzip", createGunzip],
47933
+ ["x-gzip", createGunzip],
47934
+ ["deflate", createInflate],
47935
+ ["br", createBrotliDecompress]
47936
+ ]);
47937
+ MAX_REDIRECTS = 5;
47938
+ REDIRECT_STATUS = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
47939
+ ASSET_HOP = (url) => isFetchableFontUrl(url.href) ? null : `refusing to fetch ${url.href}`;
47940
+ SITE_HOP = (url) => siteUrlRefusal(url.href);
47941
+ pinnedFetch2 = makePinnedFetch(ASSET_HOP, "pinnedFetch");
47942
+ guardedSiteFetch = makePinnedFetch(SITE_HOP, "guardedSiteFetch");
47943
+ }
47944
+ });
47945
+
47638
47946
  // src/site-analyze/analyze.ts
47947
+ function siteFetchFor(ports) {
47948
+ return ports.siteFetch ?? guardedSiteFetch;
47949
+ }
47639
47950
  function localeFromSiteLanguage(languageCode) {
47640
47951
  const tag = languageCode.trim().toLowerCase().split(/[-_]/)[0] ?? "";
47641
47952
  if (tag === "he" || tag === "es") return { default: tag, pin: true };
@@ -47646,6 +47957,7 @@ async function analyzeSite(input, ports) {
47646
47957
  const siteUrl = input.siteUrl.trim();
47647
47958
  if (!clientId) throw new Error("clientId is required");
47648
47959
  if (!siteUrl) throw new Error("siteUrl is required");
47960
+ assertPublicSiteUrl(siteUrl);
47649
47961
  const redirectUri = input.redirectUri?.trim() ? assertRedirectUri(input.redirectUri) : void 0;
47650
47962
  const visitorToken = await mintVisitorToken(ports.fetch, clientId);
47651
47963
  const visitor = visitorTransportFrom(ports.fetch, visitorToken, input.msid ?? ports.ownerAuth?.msid);
@@ -47662,7 +47974,7 @@ async function analyzeSite(input, ports) {
47662
47974
  theme: null
47663
47975
  }));
47664
47976
  const probesP = runDualProbes(owner, visitor);
47665
- const publishedP = readPublishedHtml(ports.fetch, siteUrl);
47977
+ const publishedP = readPublishedHtml(siteFetchFor(ports), siteUrl);
47666
47978
  const catsP = Promise.all([
47667
47979
  readStoreCategories(owner ?? visitor),
47668
47980
  readBlogCategories(owner ?? visitor),
@@ -47969,6 +48281,7 @@ var init_analyze = __esm({
47969
48281
  init_copy();
47970
48282
  init_permissions();
47971
48283
  init_published_html();
48284
+ init_net_guard();
47972
48285
  SCREENSHOT_NAME = /^(home|shop|book|menu|blog|about|contact|events|gallery|plans|faq|library|members|other)-\d+\.png$/i;
47973
48286
  }
47974
48287
  });
@@ -48314,246 +48627,6 @@ var init_book = __esm({
48314
48627
  }
48315
48628
  });
48316
48629
 
48317
- // src/site-analyze/net-guard.ts
48318
- import { lookup as dnsLookup } from "node:dns";
48319
- import { request as httpsRequest2 } from "node:https";
48320
- import { Readable as Readable2 } from "node:stream";
48321
- import { createBrotliDecompress, createGunzip, createInflate } from "node:zlib";
48322
- function ipv4Octets(host) {
48323
- const m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
48324
- if (!m) return null;
48325
- const octets = m.slice(1).map(Number);
48326
- return octets.every((o) => o <= 255) ? octets : null;
48327
- }
48328
- function isPrivateV4([a, b, c]) {
48329
- if (a === 0 || a === 127) return true;
48330
- if (a === 10) return true;
48331
- if (a === 192 && b === 168) return true;
48332
- if (a === 172 && b >= 16 && b <= 31) return true;
48333
- if (a === 169 && b === 254) return true;
48334
- if (a === 100 && b >= 64 && b <= 127) return true;
48335
- if (a === 192 && b === 0 && c === 0) return true;
48336
- if (a === 192 && b === 0 && c === 2) return true;
48337
- if (a === 198 && b === 51 && c === 100) return true;
48338
- if (a === 203 && b === 0 && c === 113) return true;
48339
- if (a === 198 && (b === 18 || b === 19)) return true;
48340
- if (a === 192 && b === 88 && c === 99) return true;
48341
- return a >= 224;
48342
- }
48343
- function v6Groups(host) {
48344
- let text2 = host;
48345
- const dotted = /:((?:\d{1,3}\.){3}\d{1,3})$/.exec(text2);
48346
- if (dotted) {
48347
- const octets = ipv4Octets(dotted[1]);
48348
- if (!octets) return null;
48349
- const hi = (octets[0] << 8 | octets[1]).toString(16);
48350
- const lo = (octets[2] << 8 | octets[3]).toString(16);
48351
- text2 = `${text2.slice(0, dotted.index)}:${hi}:${lo}`;
48352
- }
48353
- const halves = text2.split("::");
48354
- if (halves.length > 2) return null;
48355
- const parts = (part) => part ? part.split(":") : [];
48356
- const head = parts(halves[0]);
48357
- const tail = halves.length === 2 ? parts(halves[1]) : [];
48358
- const fill = 8 - head.length - tail.length;
48359
- if (halves.length === 2 && fill < 0) return null;
48360
- const groups = halves.length === 2 ? [...head, ...new Array(fill).fill("0"), ...tail] : head;
48361
- if (groups.length !== 8) return null;
48362
- const out = groups.map((g) => /^[0-9a-f]{1,4}$/i.test(g) ? parseInt(g, 16) : NaN);
48363
- return out.every((g) => Number.isInteger(g)) ? out : null;
48364
- }
48365
- function isPrivateV6(host) {
48366
- const g = v6Groups(host);
48367
- if (!g) return true;
48368
- const embedded = (hi, lo) => isPrivateV4([hi >> 8, hi & 255, lo >> 8, lo & 255]);
48369
- const leadingZeros = g.slice(0, 5).every((x) => x === 0);
48370
- if (leadingZeros && g[5] === 0) return true;
48371
- if (leadingZeros && g[5] === 65535) return embedded(g[6], g[7]);
48372
- if ((g[0] & 65280) === 0) return true;
48373
- if ((g[0] & 65024) === 64512) return true;
48374
- if ((g[0] & 65472) === 65152) return true;
48375
- if ((g[0] & 65472) === 65216) return true;
48376
- if ((g[0] & 65280) === 65280) return true;
48377
- if (g[0] === 100 && g[1] === 65435) return true;
48378
- if (g[0] === 256 && g[1] === 0 && g[2] === 0 && g[3] === 0) return true;
48379
- if (g[0] === 8193 && g[1] <= 511) return true;
48380
- if (g[0] === 8193 && g[1] === 3512) return true;
48381
- if (g[0] === 16383 && (g[1] & 61440) === 0) return true;
48382
- if (g[0] === 24320) return true;
48383
- if (g[0] === 8194) return embedded(g[1], g[2]);
48384
- return false;
48385
- }
48386
- function isBlockedAddress(address) {
48387
- const host = address.toLowerCase().replace(/^\[|\]$/g, "");
48388
- if (!host) return true;
48389
- const v4 = ipv4Octets(host);
48390
- if (v4) return isPrivateV4(v4);
48391
- if (host.includes(":")) return isPrivateV6(host);
48392
- return true;
48393
- }
48394
- function isFetchableFontUrl(raw) {
48395
- let url;
48396
- try {
48397
- url = new URL(raw);
48398
- } catch {
48399
- return false;
48400
- }
48401
- if (url.protocol !== "https:") return false;
48402
- const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.+$/, "");
48403
- if (!host) return false;
48404
- if (host === "localhost" || host.endsWith(".localhost")) return false;
48405
- if (host.endsWith(".internal") || host.endsWith(".local")) return false;
48406
- const v4 = ipv4Octets(host);
48407
- if (v4) return !isPrivateV4(v4);
48408
- if (host.includes(":")) return !isPrivateV6(host);
48409
- return true;
48410
- }
48411
- function resolveAll(hostname2) {
48412
- return new Promise((resolve43, reject) => {
48413
- dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
48414
- if (err) reject(err);
48415
- else resolve43(addresses);
48416
- });
48417
- });
48418
- }
48419
- function withAbort(start, signal, what) {
48420
- if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
48421
- const work = start();
48422
- if (!signal) return work;
48423
- return new Promise((resolve43, reject) => {
48424
- const onAbort = () => reject(new Error(`${what} aborted`));
48425
- signal.addEventListener("abort", onAbort, { once: true });
48426
- work.then(resolve43, reject).finally(() => signal.removeEventListener("abort", onAbort));
48427
- });
48428
- }
48429
- async function pinAddress(url, resolve43 = resolveAll, signal) {
48430
- const host = url.hostname.replace(/^\[|\]$/g, "");
48431
- if (ipv4Octets(host)) {
48432
- if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
48433
- return { address: host, family: 4 };
48434
- }
48435
- if (host.includes(":")) {
48436
- if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
48437
- return { address: host, family: 6 };
48438
- }
48439
- const addresses = await withAbort(() => resolve43(host), signal, `${host} lookup`);
48440
- if (!addresses.length) throw new Error(`${host} resolved to no address`);
48441
- const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
48442
- if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
48443
- return { address: addresses[0].address, family: addresses[0].family };
48444
- }
48445
- function decodedBody(res, hasBody) {
48446
- if (!hasBody) return res;
48447
- const codings = (res.headers["content-encoding"] ?? "").split(",").map((c) => c.trim().toLowerCase()).filter((c) => c && c !== "identity");
48448
- const makers = codings.reverse().map((coding) => {
48449
- const make = DECODERS.get(coding);
48450
- if (!make) throw new Error(`unsupported content-encoding "${coding}"`);
48451
- return make;
48452
- });
48453
- let out = res;
48454
- for (const make of makers) {
48455
- const next = make();
48456
- out.on("error", (err) => next.emit("error", err));
48457
- out = out.pipe(next);
48458
- }
48459
- return out;
48460
- }
48461
- function requestOnce(url, pinned, init) {
48462
- return new Promise((resolve43, reject) => {
48463
- const headers2 = { host: url.host, "accept-encoding": "identity" };
48464
- new Headers(init.headers ?? {}).forEach((value, key2) => {
48465
- if (key2.toLowerCase() !== "host") headers2[key2] = value;
48466
- });
48467
- const req = httpsRequest2(
48468
- {
48469
- // The ADDRESS is what we connect to; `servername` and the Host header keep the NAME, so
48470
- // SNI and certificate validation are exactly what they would have been. Pinning by
48471
- // rewriting the url to an IP would have broken both.
48472
- host: pinned.address,
48473
- servername: url.hostname.replace(/^\[|\]$/g, ""),
48474
- port: url.port ? Number(url.port) : 443,
48475
- path: `${url.pathname}${url.search}`,
48476
- method: (init.method ?? "GET").toUpperCase(),
48477
- headers: headers2,
48478
- family: pinned.family
48479
- },
48480
- (res) => {
48481
- const status = res.statusCode ?? 0;
48482
- const out = new Headers();
48483
- for (const [k, v] of Object.entries(res.headers)) {
48484
- if (typeof v === "string") out.set(k, v);
48485
- else if (Array.isArray(v)) out.set(k, v.join(", "));
48486
- }
48487
- const hasBody = status !== 204 && status !== 304 && (init.method ?? "GET").toUpperCase() !== "HEAD";
48488
- let body = null;
48489
- try {
48490
- body = hasBody ? Readable2.toWeb(decodedBody(res, hasBody)) : null;
48491
- } catch (err) {
48492
- res.resume();
48493
- reject(err);
48494
- return;
48495
- }
48496
- resolve43(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
48497
- }
48498
- );
48499
- req.on("error", reject);
48500
- const signal = init.signal;
48501
- if (signal) {
48502
- if (signal.aborted) req.destroy(new Error("aborted"));
48503
- else signal.addEventListener("abort", () => req.destroy(new Error("aborted")), { once: true });
48504
- }
48505
- req.end();
48506
- });
48507
- }
48508
- async function discardBody(res) {
48509
- try {
48510
- await res?.body?.cancel();
48511
- } catch {
48512
- }
48513
- }
48514
- async function followPinned(href, init, perform, pin = (u, s) => pinAddress(u, resolveAll, s)) {
48515
- let url = new URL(href);
48516
- for (let hop = 0; ; hop += 1) {
48517
- if (!isFetchableFontUrl(url.href)) throw new Error(`refusing to fetch ${url.href}`);
48518
- const pinned = await pin(url, init.signal);
48519
- const res = await perform(url, pinned, init);
48520
- const location = res.headers.get("location");
48521
- if (!REDIRECT_STATUS.has(res.status) || !location) return res;
48522
- const mode = init.redirect ?? "follow";
48523
- if (mode === "manual") return res;
48524
- await discardBody(res);
48525
- if (mode === "error") throw new Error(`redirect refused by redirect:"error" at ${url.href}`);
48526
- if (hop >= MAX_REDIRECTS) throw new Error(`too many redirects from ${url.href}`);
48527
- url = new URL(location, url);
48528
- }
48529
- }
48530
- var DECODERS, MAX_REDIRECTS, REDIRECT_STATUS, pinnedFetch2;
48531
- var init_net_guard = __esm({
48532
- "src/site-analyze/net-guard.ts"() {
48533
- DECODERS = /* @__PURE__ */ new Map([
48534
- ["gzip", createGunzip],
48535
- ["x-gzip", createGunzip],
48536
- ["deflate", createInflate],
48537
- ["br", createBrotliDecompress]
48538
- ]);
48539
- MAX_REDIRECTS = 5;
48540
- REDIRECT_STATUS = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
48541
- pinnedFetch2 = async (input, init) => {
48542
- if (typeof input !== "string" && !(input instanceof URL)) {
48543
- throw new TypeError("pinnedFetch takes a url \u2014 the analyzer's Request-shaped calls use the API transport");
48544
- }
48545
- if (init?.body != null) {
48546
- throw new TypeError("pinnedFetch is GET-only \u2014 a request with a body belongs on the API transport");
48547
- }
48548
- const method = (init?.method ?? "GET").toUpperCase();
48549
- if (method !== "GET" && method !== "HEAD") {
48550
- throw new TypeError(`pinnedFetch is GET-only, refusing ${method}`);
48551
- }
48552
- return followPinned(input instanceof URL ? input.href : input, init ?? {}, requestOnce);
48553
- };
48554
- }
48555
- });
48556
-
48557
48630
  // ../native-config/brand-font.ts
48558
48631
  import { create as createFont } from "fontkit";
48559
48632
  import { decompress } from "wawoff2";
@@ -49520,6 +49593,2907 @@ var init_apply2 = __esm({
49520
49593
  }
49521
49594
  });
49522
49595
 
49596
+ // ../../node_modules/tldts/dist/cjs/index.js
49597
+ var require_cjs = __commonJS({
49598
+ "../../node_modules/tldts/dist/cjs/index.js"(exports) {
49599
+ "use strict";
49600
+ function shareSameDomainSuffix(hostname2, vhost) {
49601
+ if (hostname2.endsWith(vhost)) {
49602
+ return hostname2.length === vhost.length || hostname2[hostname2.length - vhost.length - 1] === ".";
49603
+ }
49604
+ return false;
49605
+ }
49606
+ function extractDomainWithSuffix(hostname2, publicSuffix) {
49607
+ const publicSuffixIndex = hostname2.length - publicSuffix.length - 2;
49608
+ const lastDotBeforeSuffixIndex = hostname2.lastIndexOf(".", publicSuffixIndex);
49609
+ if (lastDotBeforeSuffixIndex === -1) {
49610
+ return hostname2;
49611
+ }
49612
+ return hostname2.slice(lastDotBeforeSuffixIndex + 1);
49613
+ }
49614
+ function getDomain$1(suffix, hostname2, options) {
49615
+ if (options.validHosts !== null) {
49616
+ const validHosts = options.validHosts;
49617
+ for (const vhost of validHosts) {
49618
+ if (
49619
+ /*@__INLINE__*/
49620
+ shareSameDomainSuffix(hostname2, vhost)
49621
+ ) {
49622
+ return vhost;
49623
+ }
49624
+ }
49625
+ }
49626
+ let numberOfLeadingDots = 0;
49627
+ if (hostname2.startsWith(".")) {
49628
+ while (numberOfLeadingDots < hostname2.length && hostname2[numberOfLeadingDots] === ".") {
49629
+ numberOfLeadingDots += 1;
49630
+ }
49631
+ }
49632
+ if (suffix.length === hostname2.length - numberOfLeadingDots) {
49633
+ return null;
49634
+ }
49635
+ return (
49636
+ /*@__INLINE__*/
49637
+ extractDomainWithSuffix(hostname2, suffix)
49638
+ );
49639
+ }
49640
+ function getDomainWithoutSuffix$1(domain, suffix) {
49641
+ return domain.slice(0, -suffix.length - 1);
49642
+ }
49643
+ var CONTROL_CHARS3 = /[\t\n\r]/g;
49644
+ var extractedHostnameValidated = false;
49645
+ function isValidHostnameChar(code) {
49646
+ return code >= 97 && code <= 122 || // a-z
49647
+ code >= 48 && code <= 57 || // 0-9
49648
+ code > 127 || // non-ASCII (accepted, not punycode-checked)
49649
+ code >= 65 && code <= 90 || // A-Z (becomes valid once lowercased)
49650
+ code === 45 || // '-'
49651
+ code === 95;
49652
+ }
49653
+ function getSpecialScheme(url, schemeStart, colonIndex) {
49654
+ const length = colonIndex - schemeStart;
49655
+ const c0 = url.charCodeAt(schemeStart) | 32;
49656
+ if (length === 2) {
49657
+ return c0 === 119 && (url.charCodeAt(schemeStart + 1) | 32) === 115 ? 1 : 0;
49658
+ } else if (length === 3) {
49659
+ const c1 = url.charCodeAt(schemeStart + 1) | 32;
49660
+ const c2 = url.charCodeAt(schemeStart + 2) | 32;
49661
+ if (c0 === 119 && c1 === 115 && c2 === 115)
49662
+ return 1;
49663
+ if (c0 === 102 && c1 === 116 && c2 === 112)
49664
+ return 1;
49665
+ return 0;
49666
+ } else if (length === 4) {
49667
+ const c1 = url.charCodeAt(schemeStart + 1) | 32;
49668
+ const c2 = url.charCodeAt(schemeStart + 2) | 32;
49669
+ const c3 = url.charCodeAt(schemeStart + 3) | 32;
49670
+ if (c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112)
49671
+ return 1;
49672
+ if (c0 === 102 && c1 === 105 && c2 === 108 && c3 === 101)
49673
+ return 2;
49674
+ return 0;
49675
+ } else if (length === 5) {
49676
+ return c0 === 104 && (url.charCodeAt(schemeStart + 1) | 32) === 116 && (url.charCodeAt(schemeStart + 2) | 32) === 116 && (url.charCodeAt(schemeStart + 3) | 32) === 112 && (url.charCodeAt(schemeStart + 4) | 32) === 115 ? 1 : 0;
49677
+ }
49678
+ return 0;
49679
+ }
49680
+ function extractHostname(url, urlIsValidHostname, validate3 = false) {
49681
+ let start = 0;
49682
+ let end = url.length;
49683
+ let hasUpper = false;
49684
+ let isSpecial = false;
49685
+ extractedHostnameValidated = false;
49686
+ if (!urlIsValidHostname) {
49687
+ if (url.startsWith("data:")) {
49688
+ return null;
49689
+ }
49690
+ while (start < url.length && url.charCodeAt(start) <= 32) {
49691
+ start += 1;
49692
+ }
49693
+ while (end > start + 1 && url.charCodeAt(end - 1) <= 32) {
49694
+ end -= 1;
49695
+ }
49696
+ if (url.charCodeAt(start) === 47 && url.charCodeAt(start + 1) === 47) {
49697
+ start += 2;
49698
+ } else {
49699
+ const indexOfProtocol = url.indexOf(":/", start);
49700
+ if (indexOfProtocol !== -1) {
49701
+ const special = getSpecialScheme(url, start, indexOfProtocol);
49702
+ if (special === 1) {
49703
+ isSpecial = true;
49704
+ start = indexOfProtocol + 2;
49705
+ while (url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) {
49706
+ start += 1;
49707
+ }
49708
+ } else if (special === 2) {
49709
+ isSpecial = true;
49710
+ start = indexOfProtocol + 1;
49711
+ let slashes = 0;
49712
+ while ((url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) && slashes < 2) {
49713
+ start += 1;
49714
+ slashes += 1;
49715
+ }
49716
+ if (slashes < 2) {
49717
+ return null;
49718
+ }
49719
+ } else {
49720
+ for (let i = start; i < indexOfProtocol; i += 1) {
49721
+ const code = url.charCodeAt(i) | 32;
49722
+ if (!(code >= 97 && code <= 122 || // [a, z]
49723
+ code >= 48 && code <= 57 || // [0, 9]
49724
+ code === 46 || // '.'
49725
+ code === 45 || // '-'
49726
+ code === 43)) {
49727
+ const raw = url.charCodeAt(i);
49728
+ if (raw === 9 || raw === 10 || raw === 13) {
49729
+ return extractHostname(url.replace(CONTROL_CHARS3, ""), urlIsValidHostname, validate3);
49730
+ }
49731
+ return null;
49732
+ }
49733
+ }
49734
+ if (url.charCodeAt(indexOfProtocol + 2) === 47) {
49735
+ start = indexOfProtocol + 3;
49736
+ } else {
49737
+ return null;
49738
+ }
49739
+ }
49740
+ } else if (url.charCodeAt(start) !== 91) {
49741
+ let indexOfColon = -1;
49742
+ for (let i = start; i < end; i += 1) {
49743
+ const code = url.charCodeAt(i);
49744
+ if (code === 9 || code === 10 || code === 13) {
49745
+ return extractHostname(url.replace(CONTROL_CHARS3, ""), urlIsValidHostname, validate3);
49746
+ }
49747
+ if (code === 58) {
49748
+ indexOfColon = i;
49749
+ break;
49750
+ }
49751
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49752
+ break;
49753
+ }
49754
+ }
49755
+ if (indexOfColon !== -1) {
49756
+ let hasIdentifier = false;
49757
+ for (let i = indexOfColon + 1; i < end; i += 1) {
49758
+ const code = url.charCodeAt(i);
49759
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49760
+ break;
49761
+ }
49762
+ if (code === 64) {
49763
+ hasIdentifier = true;
49764
+ break;
49765
+ }
49766
+ }
49767
+ if (!hasIdentifier) {
49768
+ let allDigits = true;
49769
+ let i = indexOfColon + 1;
49770
+ for (; i < end; i += 1) {
49771
+ const code = url.charCodeAt(i);
49772
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49773
+ break;
49774
+ }
49775
+ if (code < 48 || code > 57) {
49776
+ allDigits = false;
49777
+ break;
49778
+ }
49779
+ }
49780
+ if (i === indexOfColon + 1) {
49781
+ allDigits = false;
49782
+ }
49783
+ if (!allDigits) {
49784
+ const special = getSpecialScheme(url, start, indexOfColon);
49785
+ if (special === 0) {
49786
+ let isBareIpv6 = false;
49787
+ for (let j = indexOfColon + 1; j < end; j += 1) {
49788
+ const code = url.charCodeAt(j);
49789
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49790
+ break;
49791
+ }
49792
+ if (code === 58) {
49793
+ isBareIpv6 = true;
49794
+ break;
49795
+ }
49796
+ }
49797
+ if (!isBareIpv6) {
49798
+ return null;
49799
+ }
49800
+ } else {
49801
+ isSpecial = true;
49802
+ start = indexOfColon + 1;
49803
+ if (special === 2) {
49804
+ let slashes = 0;
49805
+ while ((url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) && slashes < 2) {
49806
+ start += 1;
49807
+ slashes += 1;
49808
+ }
49809
+ if (slashes < 2) {
49810
+ return null;
49811
+ }
49812
+ } else {
49813
+ while (url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) {
49814
+ start += 1;
49815
+ }
49816
+ }
49817
+ }
49818
+ }
49819
+ }
49820
+ }
49821
+ }
49822
+ }
49823
+ let indexOfIdentifier = -1;
49824
+ let indexOfClosingBracket = -1;
49825
+ let indexOfPort = -1;
49826
+ let indexOfFirstColon = -1;
49827
+ let hasControl = false;
49828
+ let vValid = validate3;
49829
+ let vLastDot = start - 1;
49830
+ let vLastCode = -1;
49831
+ if (validate3 && start < end) {
49832
+ const c0 = url.charCodeAt(start);
49833
+ if (!/*@__INLINE__*/
49834
+ (isValidHostnameChar(c0) || c0 === 46 || c0 === 95) || c0 === 45) {
49835
+ vValid = false;
49836
+ }
49837
+ }
49838
+ for (let i = start; i < end; i += 1) {
49839
+ const code = url.charCodeAt(i);
49840
+ if (code < 64) {
49841
+ if (code === 47 || code === 35 || code === 63) {
49842
+ end = i;
49843
+ break;
49844
+ } else if (code === 58) {
49845
+ if (indexOfFirstColon === -1) {
49846
+ indexOfFirstColon = i;
49847
+ }
49848
+ indexOfPort = i;
49849
+ } else if (code === 9 || code === 10 || code === 13) {
49850
+ hasControl = true;
49851
+ } else if (validate3) {
49852
+ if (code === 46) {
49853
+ if (i - vLastDot > 64 || vLastCode === 46 || vLastCode === 45) {
49854
+ vValid = false;
49855
+ }
49856
+ vLastDot = i;
49857
+ } else if (code < 48 || code > 57) {
49858
+ if (code !== 45 || vLastCode === 46) {
49859
+ vValid = false;
49860
+ }
49861
+ }
49862
+ }
49863
+ } else if (isSpecial && code === 92) {
49864
+ end = i;
49865
+ break;
49866
+ } else if (code === 64) {
49867
+ indexOfIdentifier = i;
49868
+ indexOfFirstColon = -1;
49869
+ } else if (code === 93) {
49870
+ indexOfClosingBracket = i;
49871
+ } else if (code >= 65 && code <= 90) {
49872
+ hasUpper = true;
49873
+ } else if (validate3 && !/*@__INLINE__*/
49874
+ isValidHostnameChar(code)) {
49875
+ vValid = false;
49876
+ }
49877
+ if (validate3) {
49878
+ vLastCode = code;
49879
+ }
49880
+ }
49881
+ if (hasControl) {
49882
+ return extractHostname(url.replace(CONTROL_CHARS3, ""), urlIsValidHostname, validate3);
49883
+ }
49884
+ if (indexOfIdentifier !== -1 && indexOfIdentifier >= start && indexOfIdentifier < end) {
49885
+ start = indexOfIdentifier + 1;
49886
+ }
49887
+ if (url.charCodeAt(start) === 91) {
49888
+ if (indexOfClosingBracket !== -1) {
49889
+ return url.slice(start + 1, indexOfClosingBracket).toLowerCase();
49890
+ }
49891
+ return null;
49892
+ } else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end && // A host:port has exactly one ':' in the host (so its first ':' is its
49893
+ // last); a bare, unbracketed IPv6 literal ("2a01:e35::1") has >= 2, so
49894
+ // its first ':' precedes the last. Only the former has a ':port' to trim.
49895
+ indexOfFirstColon === indexOfPort) {
49896
+ end = indexOfPort;
49897
+ }
49898
+ if (start >= end) {
49899
+ return null;
49900
+ }
49901
+ if (validate3 && vValid && indexOfIdentifier === -1 && indexOfPort === -1 && indexOfClosingBracket === -1 && url.charCodeAt(end - 1) !== 46 && end - start <= 255 && // total length
49902
+ end - vLastDot - 1 <= 63 && // last label length
49903
+ vLastCode !== 45) {
49904
+ extractedHostnameValidated = true;
49905
+ }
49906
+ }
49907
+ while (end > start + 1 && url.charCodeAt(end - 1) === 46) {
49908
+ end -= 1;
49909
+ }
49910
+ const hostname2 = start !== 0 || end !== url.length ? url.slice(start, end) : url;
49911
+ if (hasUpper) {
49912
+ return hostname2.toLowerCase();
49913
+ }
49914
+ return hostname2;
49915
+ }
49916
+ function isProbablyIpv4(hostname2) {
49917
+ if (hostname2.length < 7) {
49918
+ return false;
49919
+ }
49920
+ if (hostname2.length > 15) {
49921
+ return false;
49922
+ }
49923
+ let numberOfDots = 0;
49924
+ for (let i = 0; i < hostname2.length; i += 1) {
49925
+ const code = hostname2.charCodeAt(i);
49926
+ if (code === 46) {
49927
+ numberOfDots += 1;
49928
+ } else if (code < 48 || code > 57) {
49929
+ return false;
49930
+ }
49931
+ }
49932
+ return numberOfDots === 3 && hostname2.charCodeAt(0) !== 46 && hostname2.charCodeAt(hostname2.length - 1) !== 46;
49933
+ }
49934
+ function isProbablyIpv6(hostname2) {
49935
+ if (hostname2.length < 3) {
49936
+ return false;
49937
+ }
49938
+ let start = hostname2.startsWith("[") ? 1 : 0;
49939
+ let end = hostname2.length;
49940
+ if (hostname2[end - 1] === "]") {
49941
+ end -= 1;
49942
+ }
49943
+ if (end - start > 39) {
49944
+ return false;
49945
+ }
49946
+ let hasColon = false;
49947
+ for (; start < end; start += 1) {
49948
+ const code = hostname2.charCodeAt(start);
49949
+ if (code === 58) {
49950
+ hasColon = true;
49951
+ } else if (!(code >= 48 && code <= 57 || // 0-9
49952
+ code >= 97 && code <= 102 || // a-f
49953
+ code >= 65 && code <= 70)) {
49954
+ return false;
49955
+ }
49956
+ }
49957
+ return hasColon;
49958
+ }
49959
+ function isIp(hostname2) {
49960
+ return isProbablyIpv6(hostname2) || isProbablyIpv4(hostname2);
49961
+ }
49962
+ var SPECIAL_USE_DOMAINS2 = [
49963
+ "test",
49964
+ // RFC 6761
49965
+ "localhost",
49966
+ // RFC 6761
49967
+ "invalid",
49968
+ // RFC 6761
49969
+ "example",
49970
+ // RFC 6761
49971
+ "example.com",
49972
+ // RFC 6761
49973
+ "example.net",
49974
+ // RFC 6761
49975
+ "example.org",
49976
+ // RFC 6761
49977
+ "local",
49978
+ // RFC 6762 (mDNS)
49979
+ "onion",
49980
+ // RFC 7686 (Tor)
49981
+ "alt",
49982
+ // RFC 9476
49983
+ "home.arpa",
49984
+ // RFC 8375
49985
+ "ipv4only.arpa",
49986
+ // RFC 8880
49987
+ "resolver.arpa",
49988
+ // RFC 9462
49989
+ "service.arpa",
49990
+ // RFC 9665
49991
+ "6tisch.arpa",
49992
+ // RFC 9031
49993
+ "eap.arpa"
49994
+ // RFC 9965
49995
+ ];
49996
+ function isSpecialUse(hostname2) {
49997
+ for (const name of SPECIAL_USE_DOMAINS2) {
49998
+ if (hostname2.endsWith(name) && (hostname2.length === name.length || hostname2.charCodeAt(hostname2.length - name.length - 1) === 46)) {
49999
+ return true;
50000
+ }
50001
+ }
50002
+ return false;
50003
+ }
50004
+ function isValidAscii(code) {
50005
+ return code >= 97 && code <= 122 || code >= 48 && code <= 57 || code > 127;
50006
+ }
50007
+ function isValidHostname(hostname2) {
50008
+ if (hostname2.length > 255) {
50009
+ return false;
50010
+ }
50011
+ if (hostname2.length === 0) {
50012
+ return false;
50013
+ }
50014
+ if (
50015
+ /*@__INLINE__*/
50016
+ !isValidAscii(hostname2.charCodeAt(0)) && hostname2.charCodeAt(0) !== 46 && // '.' (dot)
50017
+ hostname2.charCodeAt(0) !== 95
50018
+ ) {
50019
+ return false;
50020
+ }
50021
+ let lastDotIndex = -1;
50022
+ let lastCharCode = -1;
50023
+ const len = hostname2.length;
50024
+ for (let i = 0; i < len; i += 1) {
50025
+ const code = hostname2.charCodeAt(i);
50026
+ if (code === 46) {
50027
+ if (
50028
+ // Check that previous label is < 63 bytes long (64 = 63 + '.')
50029
+ i - lastDotIndex > 64 || // Check that previous character was not already a '.'
50030
+ lastCharCode === 46 || // Check that the previous label does not end with '-' (RFC 1035 §2.3.1 LDH).
50031
+ // '_' is intentionally NOT restricted: DNS allows any octet (RFC 2181 §11) and
50032
+ // WHATWG URL does not treat '_' as a forbidden host code point.
50033
+ lastCharCode === 45
50034
+ ) {
50035
+ return false;
50036
+ }
50037
+ lastDotIndex = i;
50038
+ } else if (
50039
+ // A forbidden character in the label...
50040
+ !/*@__INLINE__*/
50041
+ (isValidAscii(code) || code === 45 || code === 95) || // ...or a '-' starting a label (the byte right after a '.'). A label must
50042
+ // not begin with a hyphen (RFC 1034 §3.5 / RFC 1035 §2.3.1 LDH, as amended
50043
+ // by RFC 1123 §2.1; cf. UTS #46 CheckHyphens). The first label is covered by
50044
+ // the leading-character guard above; mirrors the trailing-'-' rule below.
50045
+ code === 45 && lastCharCode === 46
50046
+ ) {
50047
+ return false;
50048
+ }
50049
+ lastCharCode = code;
50050
+ }
50051
+ return (
50052
+ // Check that last label is shorter than 63 chars
50053
+ len - lastDotIndex - 1 <= 63 && // Check that the last character is an allowed trailing label character.
50054
+ // Since we already checked that the char is a valid hostname character,
50055
+ // we only need to check that it's different from '-'.
50056
+ lastCharCode !== 45
50057
+ );
50058
+ }
50059
+ function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, detectSpecialUse = false, extractHostname: extractHostname2 = true, mixedInputs = true, validHosts = null, validateHostname = true }) {
50060
+ return {
50061
+ allowIcannDomains,
50062
+ allowPrivateDomains,
50063
+ detectIp,
50064
+ detectSpecialUse,
50065
+ extractHostname: extractHostname2,
50066
+ mixedInputs,
50067
+ validHosts,
50068
+ validateHostname
50069
+ };
50070
+ }
50071
+ var DEFAULT_OPTIONS = (
50072
+ /*@__INLINE__*/
50073
+ setDefaultsImpl({})
50074
+ );
50075
+ function setDefaults(options) {
50076
+ if (options === void 0) {
50077
+ return DEFAULT_OPTIONS;
50078
+ }
50079
+ return (
50080
+ /*@__INLINE__*/
50081
+ setDefaultsImpl(options)
50082
+ );
50083
+ }
50084
+ function getSubdomain$1(hostname2, domain) {
50085
+ if (domain.length === hostname2.length) {
50086
+ return "";
50087
+ }
50088
+ return hostname2.slice(0, -domain.length - 1);
50089
+ }
50090
+ function getEmptyResult() {
50091
+ return {
50092
+ domain: null,
50093
+ domainWithoutSuffix: null,
50094
+ hostname: null,
50095
+ isIcann: null,
50096
+ isIp: null,
50097
+ isPrivate: null,
50098
+ isSpecialUse: null,
50099
+ publicSuffix: null,
50100
+ subdomain: null
50101
+ };
50102
+ }
50103
+ function resetResult(result) {
50104
+ result.domain = null;
50105
+ result.domainWithoutSuffix = null;
50106
+ result.hostname = null;
50107
+ result.isIcann = null;
50108
+ result.isIp = null;
50109
+ result.isPrivate = null;
50110
+ result.isSpecialUse = null;
50111
+ result.publicSuffix = null;
50112
+ result.subdomain = null;
50113
+ }
50114
+ function parseImpl(url, step, suffixLookup2, partialOptions, result) {
50115
+ const options = (
50116
+ /*@__INLINE__*/
50117
+ setDefaults(partialOptions)
50118
+ );
50119
+ if (typeof url !== "string") {
50120
+ return result;
50121
+ }
50122
+ let urlIsValid = false;
50123
+ if (!options.extractHostname) {
50124
+ result.hostname = url;
50125
+ } else if (options.mixedInputs) {
50126
+ urlIsValid = isValidHostname(url);
50127
+ result.hostname = extractHostname(url, urlIsValid, options.validateHostname);
50128
+ } else {
50129
+ result.hostname = extractHostname(url, false, options.validateHostname);
50130
+ }
50131
+ if (options.detectIp && result.hostname !== null) {
50132
+ result.isIp = isIp(result.hostname);
50133
+ if (result.isIp) {
50134
+ return result;
50135
+ }
50136
+ }
50137
+ if (options.validateHostname && options.extractHostname && result.hostname !== null && // Skip the re-scan when `url` was already validated and extractHostname
50138
+ // returned it unchanged (same reference => identical string, still valid).
50139
+ !(urlIsValid && result.hostname === url) && // Skip the re-scan when extractHostname already validated the host inline
50140
+ // (a confirmed-valid simple authority — see extract-hostname.ts).
50141
+ !extractedHostnameValidated && !isValidHostname(result.hostname)) {
50142
+ result.hostname = null;
50143
+ return result;
50144
+ }
50145
+ if (step === 0 || result.hostname === null) {
50146
+ return result;
50147
+ }
50148
+ if (step === 5 && options.detectSpecialUse) {
50149
+ result.isSpecialUse = isSpecialUse(result.hostname);
50150
+ }
50151
+ suffixLookup2(result.hostname, options, result);
50152
+ if (step === 2 || result.publicSuffix === null) {
50153
+ return result;
50154
+ }
50155
+ result.domain = getDomain$1(result.publicSuffix, result.hostname, options);
50156
+ if (step === 3 || result.domain === null) {
50157
+ return result;
50158
+ }
50159
+ result.subdomain = getSubdomain$1(result.hostname, result.domain);
50160
+ if (step === 4) {
50161
+ return result;
50162
+ }
50163
+ result.domainWithoutSuffix = getDomainWithoutSuffix$1(result.domain, result.publicSuffix);
50164
+ return result;
50165
+ }
50166
+ function fastPathLookup(hostname2, options, out) {
50167
+ if (!options.allowPrivateDomains && hostname2.length > 3) {
50168
+ const last = hostname2.length - 1;
50169
+ const c3 = hostname2.charCodeAt(last);
50170
+ const c2 = hostname2.charCodeAt(last - 1);
50171
+ const c1 = hostname2.charCodeAt(last - 2);
50172
+ const c0 = hostname2.charCodeAt(last - 3);
50173
+ if (c3 === 109 && c2 === 111 && c1 === 99 && c0 === 46) {
50174
+ out.isIcann = true;
50175
+ out.isPrivate = false;
50176
+ out.publicSuffix = "com";
50177
+ return true;
50178
+ } else if (c3 === 103 && c2 === 114 && c1 === 111 && c0 === 46) {
50179
+ out.isIcann = true;
50180
+ out.isPrivate = false;
50181
+ out.publicSuffix = "org";
50182
+ return true;
50183
+ } else if (c3 === 117 && c2 === 100 && c1 === 101 && c0 === 46) {
50184
+ out.isIcann = true;
50185
+ out.isPrivate = false;
50186
+ out.publicSuffix = "edu";
50187
+ return true;
50188
+ } else if (c3 === 118 && c2 === 111 && c1 === 103 && c0 === 46) {
50189
+ out.isIcann = true;
50190
+ out.isPrivate = false;
50191
+ out.publicSuffix = "gov";
50192
+ return true;
50193
+ } else if (c3 === 116 && c2 === 101 && c1 === 110 && c0 === 46) {
50194
+ out.isIcann = true;
50195
+ out.isPrivate = false;
50196
+ out.publicSuffix = "net";
50197
+ return true;
50198
+ } else if (c3 === 101 && c2 === 100 && c1 === 46) {
50199
+ out.isIcann = true;
50200
+ out.isPrivate = false;
50201
+ out.publicSuffix = "de";
50202
+ return true;
50203
+ }
50204
+ }
50205
+ return false;
50206
+ }
50207
+ var nodeFlags = /* @__PURE__ */ new Uint8Array([1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 0, 2, 0, 0, 1, 0, 0, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 2, 2, 0, 0, 0, 2, 0, 1, 1, 0, 2, 0, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 2, 0, 2, 2, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]);
50208
+ var edgeStart = /* @__PURE__ */ new Uint16Array([0, 0, 0, 9, 10, 17, 105, 110, 116, 123, 129, 135, 144, 145, 146, 147, 148, 149, 150, 152, 153, 154, 156, 158, 224, 237, 239, 240, 241, 256, 263, 264, 267, 268, 269, 272, 274, 294, 295, 297, 306, 311, 312, 330, 331, 334, 336, 337, 339, 373, 374, 376, 379, 380, 384, 386, 390, 393, 425, 428, 441, 442, 450, 452, 462, 476, 477, 478, 487, 524, 529, 545, 565, 571, 612, 613, 640, 667, 668, 816, 822, 825, 826, 827, 832, 837, 846, 868, 869, 870, 871, 872, 873, 874, 892, 894, 895, 898, 900, 901, 903, 905, 920, 935, 940, 941, 943, 944, 945, 946, 947, 949, 952, 957, 958, 959, 961, 962, 965, 968, 969, 970, 983, 985, 997, 1008, 1016, 1018, 1057, 1060, 1064, 1065, 1067, 1070, 1081, 1083, 1093, 1095, 1101, 1103, 1104, 1106, 1109, 1110, 1111, 1163, 1165, 1167, 1187, 1188, 1189, 1190, 1192, 1203, 1234, 1245, 1257, 1266, 1273, 1278, 1291, 1302, 1315, 1316, 1327, 1361, 1362, 1363, 1378, 1393, 1465, 1466, 1468, 1469, 1503, 1504, 1505, 1508, 1512, 1514, 1543, 1544, 1552, 1553, 1554, 1556, 1558, 1559, 1561, 1562, 1563, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1590, 1591, 1592, 1594, 2049, 2052, 2053, 2055, 2062, 2069, 2077, 2081, 2092, 2093, 2094, 2106, 2107, 2109, 2111, 2112, 2119, 2120, 2122, 2123, 2125, 2126, 2127, 2128, 2129, 2197, 2199, 2220, 2221, 2222, 2224, 2250, 2251, 2302, 2303, 2305, 2312, 2318, 2328, 2338, 2391, 2392, 2393, 2403, 2417, 2418, 2421, 2428, 2429, 2437, 2438, 2439, 2440, 2441, 2451, 2452, 2453, 2455, 2456, 2457, 2459, 2469, 2481, 2487, 2519, 2523, 2525, 2526, 2528, 2529, 2536, 2537, 2539, 2547, 2554, 2560, 2565, 2566, 2572, 2575, 2581, 2588, 2589, 2596, 2604, 2605, 2606, 2644, 2650, 2665, 2666, 2671, 2689, 2720, 2738, 2740, 2743, 2751, 2753, 2760, 2808, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2846, 2847, 2848, 2849, 2850, 2851, 2853, 2854, 2858, 2942, 2955, 2956, 3391, 3395, 3409, 3461, 3489, 3511, 3569, 3591, 3606, 3669, 3720, 3758, 3794, 3819, 3961, 4007, 4058, 4077, 4111, 4126, 4146, 4176, 4207, 4230, 4261, 4291, 4323, 4350, 4425, 4447, 4485, 4495, 4529, 4548, 4574, 4616, 4666, 4692, 4761, 4762, 4764, 4787, 4810, 4846, 4877, 4894, 4951, 4964, 4988, 5017, 5019, 5053, 5069, 5097, 5402, 5411, 5420, 5427, 5444, 5448, 5454, 5493, 5495, 5502, 5509, 5518, 5525, 5526, 5537, 5540, 5555, 5556, 5565, 5566, 5575, 5584, 5590, 5592, 5593, 5594, 5629, 5630, 5632, 5640, 5647, 5660, 5664, 5666, 5667, 5673, 5680, 5694, 5704, 5709, 5717, 5725, 5731, 5732, 5736, 5738, 5739, 5751, 5752, 5753, 5754, 5756, 5757, 5760, 5762, 5765, 5769, 5770, 5776, 5777, 5778, 5780, 5782, 5784, 5785, 5786, 5789, 5791, 5794, 5795, 5797, 5994, 6001, 6002, 6012, 6017, 6034, 6048, 6057, 6058, 6059, 6063, 6064, 6066, 6068, 6074, 6075, 6078, 6079, 6081, 6082, 6083, 6974, 6978, 6996, 7005, 7008, 7014, 7015, 7017, 7018, 7019, 7021, 7073, 7074, 7077, 7078, 7196, 7197, 7208, 7219, 7226, 7229, 7238, 7239, 7240, 7255, 7310, 7501, 7503, 7504, 7506, 7511, 7524, 7539, 7546, 7555, 7558, 7561, 7568, 7576, 7580, 7581, 7582, 7596, 7600, 7609, 7610, 7611, 7615, 7650, 7651, 7668, 7675, 7683, 7684, 7688, 7696, 7740, 7741, 7747, 7750, 7761, 7766, 7767, 7770, 7802, 7803, 7809, 7816, 7817, 7826, 7835, 7850, 7854, 7906, 7907, 7912, 7914, 7917, 7919, 7920, 7921, 7930, 7945, 7953, 7967, 7979, 7980, 7982, 7984, 8006, 8017, 8023, 8024, 8036, 8048, 8135, 8147, 8149, 8158, 8161, 8167, 8192, 8195, 8196, 8197, 8199, 8202, 8205, 8216, 8218, 8220, 8248, 8322, 8329, 8333, 8334, 8343, 8365, 8366, 8371, 8372, 8451, 8453, 8454, 8463, 8467, 8473, 8479, 8485, 8495, 8500, 8501, 8519, 8530, 8535, 8540, 8550, 8556, 8560, 8566, 8572, 10180, 10181, 10182, 10189, 10191]);
50209
+ var edgeLength = /* @__PURE__ */ new Uint8Array([3, 3, 3, 3, 3, 3, 3, 5, 8, 8, 2, 2, 3, 3, 3, 3, 3, 8, 5, 5, 5, 5, 5, 3, 3, 5, 5, 9, 12, 19, 8, 19, 8, 11, 9, 9, 8, 7, 7, 6, 8, 9, 16, 10, 7, 7, 11, 8, 6, 6, 9, 7, 11, 7, 14, 4, 4, 4, 4, 4, 4, 10, 7, 6, 6, 6, 6, 10, 10, 6, 10, 10, 22, 11, 9, 10, 10, 10, 9, 10, 8, 7, 7, 7, 8, 21, 13, 11, 11, 9, 10, 9, 13, 10, 8, 8, 9, 12, 9, 7, 10, 7, 7, 13, 7, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 6, 3, 3, 3, 3, 3, 3, 2, 5, 3, 3, 3, 7, 2, 2, 2, 2, 2, 2, 3, 3, 3, 1, 1, 7, 8, 5, 2, 2, 7, 2, 2, 1, 4, 1, 11, 9, 9, 5, 5, 8, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 11, 9, 9, 13, 7, 14, 7, 6, 6, 6, 7, 6, 6, 6, 6, 6, 10, 7, 11, 9, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 8, 7, 10, 9, 9, 9, 8, 9, 8, 10, 6, 9, 9, 8, 10, 10, 7, 8, 1, 9, 10, 12, 12, 12, 10, 9, 9, 10, 10, 9, 9, 1, 1, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 4, 3, 3, 3, 7, 4, 4, 4, 3, 3, 6, 7, 3, 4, 1, 2, 2, 2, 6, 1, 2, 2, 2, 2, 2, 12, 5, 3, 3, 8, 9, 13, 4, 4, 4, 13, 9, 9, 11, 3, 12, 9, 2, 2, 2, 3, 3, 3, 3, 3, 8, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 7, 10, 15, 7, 15, 15, 20, 15, 9, 10, 10, 12, 14, 14, 14, 12, 12, 12, 12, 12, 14, 14, 10, 10, 10, 10, 14, 9, 9, 9, 10, 14, 14, 14, 13, 13, 9, 9, 9, 9, 9, 9, 7, 8, 6, 8, 8, 6, 8, 13, 8, 8, 6, 13, 8, 11, 13, 8, 6, 13, 8, 6, 9, 10, 10, 12, 14, 14, 14, 12, 12, 12, 12, 14, 14, 10, 10, 10, 10, 9, 9, 9, 10, 14, 14, 11, 13, 13, 9, 9, 9, 9, 9, 9, 2, 6, 9, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 2, 3, 3, 3, 3, 3, 3, 7, 2, 3, 2, 2, 5, 3, 3, 3, 3, 3, 3, 4, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 5, 7, 2, 2, 12, 8, 10, 8, 10, 7, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 2, 2, 3, 3, 3, 5, 5, 3, 8, 8, 6, 8, 6, 6, 4, 6, 7, 7, 7, 10, 11, 2, 5, 5, 3, 3, 3, 3, 3, 3, 5, 5, 6, 11, 10, 7, 7, 7, 4, 4, 4, 2, 3, 3, 3, 3, 3, 2, 7, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 11, 7, 6, 9, 6, 6, 8, 10, 8, 6, 8, 13, 4, 4, 4, 4, 4, 10, 8, 11, 8, 8, 8, 10, 10, 7, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 10, 13, 7, 8, 7, 11, 8, 8, 6, 9, 8, 8, 6, 6, 6, 8, 8, 6, 6, 6, 6, 6, 9, 7, 6, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 9, 7, 8, 10, 8, 8, 2, 3, 3, 3, 3, 3, 2, 8, 9, 9, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 9, 2, 2, 3, 3, 3, 3, 3, 3, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 5, 3, 5, 4, 2, 3, 2, 4, 3, 9, 2, 2, 2, 2, 2, 5, 5, 3, 8, 8, 13, 6, 10, 9, 4, 7, 9, 11, 2, 3, 7, 3, 3, 4, 1, 3, 4, 2, 9, 3, 3, 12, 5, 3, 7, 10, 10, 7, 4, 4, 6, 14, 7, 9, 7, 13, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 8, 15, 4, 4, 2, 3, 3, 3, 7, 4, 9, 9, 2, 3, 3, 3, 5, 3, 2, 2, 7, 2, 7, 6, 6, 7, 2, 4, 2, 2, 2, 2, 2, 2, 8, 8, 8, 9, 5, 2, 3, 3, 3, 3, 3, 3, 10, 7, 4, 4, 4, 4, 3, 4, 2, 3, 3, 3, 3, 3, 10, 7, 4, 4, 4, 4, 2, 3, 3, 3, 3, 10, 7, 4, 4, 4, 4, 3, 9, 6, 6, 6, 9, 13, 9, 2, 2, 2, 8, 7, 9, 5, 3, 3, 3, 5, 5, 12, 9, 10, 7, 8, 7, 6, 8, 6, 11, 12, 7, 9, 10, 4, 4, 7, 8, 11, 6, 7, 9, 8, 7, 10, 8, 9, 15, 8, 5, 4, 7, 2, 3, 3, 3, 2, 14, 10, 2, 14, 10, 2, 14, 3, 9, 13, 13, 10, 14, 16, 17, 11, 2, 14, 2, 14, 3, 9, 13, 10, 14, 16, 17, 11, 14, 10, 14, 2, 7, 3, 10, 7, 14, 10, 2, 14, 10, 9, 9, 17, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 10, 10, 10, 12, 9, 4, 10, 11, 8, 8, 8, 7, 9, 5, 3, 3, 3, 3, 3, 3, 3, 3, 5, 8, 4, 4, 4, 4, 4, 4, 6, 16, 3, 3, 14, 3, 14, 2, 14, 9, 13, 10, 10, 14, 16, 17, 11, 6, 9, 10, 10, 12, 14, 14, 14, 12, 12, 12, 12, 14, 14, 10, 10, 10, 10, 14, 9, 9, 9, 10, 14, 14, 14, 9, 9, 9, 9, 9, 9, 2, 14, 9, 13, 10, 10, 14, 16, 17, 11, 6, 2, 14, 9, 17, 13, 10, 10, 14, 16, 17, 11, 6, 2, 14, 9, 13, 10, 14, 16, 17, 11, 2, 14, 9, 13, 10, 16, 11, 2, 14, 10, 19, 7, 2, 14, 9, 13, 10, 19, 10, 7, 14, 16, 17, 11, 6, 2, 14, 9, 13, 10, 19, 7, 14, 16, 17, 11, 2, 14, 9, 13, 17, 13, 10, 10, 14, 16, 17, 11, 6, 3, 2, 14, 9, 13, 10, 10, 14, 16, 17, 11, 6, 9, 10, 12, 14, 14, 14, 12, 12, 12, 12, 12, 14, 14, 14, 10, 10, 10, 14, 9, 9, 9, 9, 14, 14, 14, 13, 13, 14, 9, 9, 9, 9, 9, 9, 4, 11, 2, 14, 9, 13, 17, 13, 10, 19, 10, 7, 14, 16, 17, 11, 6, 2, 14, 9, 13, 17, 13, 10, 19, 10, 7, 14, 16, 17, 11, 6, 2, 9, 10, 10, 7, 17, 3, 3, 12, 12, 16, 15, 15, 12, 14, 14, 14, 20, 20, 13, 12, 12, 12, 12, 12, 12, 20, 25, 14, 14, 12, 12, 10, 10, 10, 10, 9, 9, 9, 25, 4, 9, 17, 10, 7, 14, 16, 21, 13, 13, 14, 20, 14, 13, 17, 24, 9, 12, 13, 25, 13, 21, 20, 17, 9, 9, 9, 9, 9, 9, 12, 17, 4, 4, 9, 9, 9, 10, 10, 12, 14, 14, 14, 12, 12, 12, 12, 12, 14, 14, 10, 10, 10, 10, 14, 9, 9, 9, 10, 14, 14, 14, 13, 13, 9, 9, 9, 9, 9, 9, 1, 8, 7, 11, 11, 1, 3, 3, 3, 4, 8, 9, 10, 14, 14, 12, 12, 12, 12, 14, 14, 10, 10, 10, 10, 14, 9, 9, 9, 10, 14, 14, 14, 13, 13, 9, 9, 9, 9, 9, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 12, 6, 14, 4, 12, 7, 2, 2, 1, 2, 7, 6, 4, 4, 4, 6, 8, 8, 7, 4, 5, 6, 3, 3, 3, 3, 4, 16, 8, 3, 5, 4, 3, 3, 3, 5, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 11, 12, 7, 7, 13, 9, 10, 12, 8, 9, 7, 8, 5, 12, 10, 13, 14, 5, 5, 5, 13, 5, 5, 5, 3, 3, 3, 5, 16, 5, 5, 5, 5, 5, 7, 12, 14, 8, 12, 8, 10, 12, 9, 11, 7, 9, 7, 10, 7, 13, 9, 7, 12, 8, 17, 7, 7, 16, 10, 13, 13, 8, 10, 10, 14, 17, 7, 16, 16, 15, 8, 10, 10, 12, 17, 7, 17, 14, 7, 10, 17, 8, 7, 7, 7, 8, 15, 15, 7, 14, 10, 10, 10, 11, 11, 7, 7, 13, 8, 10, 7, 16, 7, 8, 7, 14, 17, 12, 10, 11, 21, 8, 9, 7, 13, 9, 8, 13, 6, 12, 7, 6, 13, 10, 10, 10, 8, 18, 9, 17, 13, 10, 12, 6, 13, 6, 11, 8, 13, 10, 13, 18, 13, 11, 13, 8, 16, 7, 10, 8, 16, 12, 10, 8, 8, 6, 14, 11, 8, 15, 8, 8, 7, 7, 12, 7, 8, 9, 14, 15, 8, 9, 10, 9, 15, 7, 8, 8, 12, 13, 9, 10, 15, 15, 13, 7, 10, 10, 20, 7, 6, 9, 6, 6, 14, 11, 14, 11, 12, 9, 10, 16, 16, 12, 7, 11, 28, 8, 11, 10, 7, 21, 8, 7, 9, 4, 4, 4, 17, 7, 8, 6, 9, 6, 6, 13, 6, 6, 6, 6, 18, 20, 14, 8, 11, 12, 9, 10, 13, 15, 19, 8, 9, 12, 7, 10, 16, 12, 9, 9, 9, 14, 12, 11, 9, 12, 11, 18, 9, 9, 9, 10, 7, 7, 16, 8, 9, 7, 13, 12, 10, 18, 7, 8, 11, 7, 7, 8, 8, 13, 7, 7, 7, 11, 15, 13, 11, 7, 8, 15, 11, 7, 8, 18, 14, 13, 18, 15, 10, 12, 12, 9, 7, 11, 11, 8, 7, 10, 8, 14, 12, 10, 18, 7, 10, 9, 7, 8, 13, 10, 14, 9, 10, 8, 8, 23, 7, 7, 11, 12, 12, 17, 7, 7, 11, 11, 17, 16, 16, 7, 8, 11, 14, 14, 8, 10, 7, 7, 16, 16, 13, 9, 11, 9, 15, 15, 11, 11, 7, 7, 14, 7, 9, 7, 7, 16, 10, 13, 10, 11, 14, 7, 11, 10, 11, 7, 11, 10, 11, 15, 11, 15, 10, 12, 17, 10, 14, 13, 11, 11, 12, 13, 10, 7, 13, 10, 16, 12, 21, 9, 10, 10, 7, 11, 14, 17, 7, 7, 8, 11, 12, 8, 15, 14, 14, 8, 17, 12, 10, 10, 7, 9, 11, 7, 10, 7, 11, 18, 7, 11, 7, 12, 11, 8, 8, 14, 12, 7, 8, 15, 3, 7, 7, 5, 2, 9, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 5, 11, 6, 4, 7, 10, 7, 7, 11, 1, 10, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 3, 5, 6, 3, 3, 5, 2, 2, 5, 3, 4, 13, 11, 3, 3, 6, 3, 5, 14, 2, 2, 3, 8, 2, 2, 12, 18, 5, 3, 3, 3, 16, 5, 5, 5, 10, 7, 13, 12, 13, 9, 12, 14, 19, 9, 21, 9, 9, 10, 6, 9, 6, 15, 10, 6, 12, 8, 6, 10, 15, 4, 4, 6, 9, 9, 12, 16, 14, 23, 7, 7, 14, 9, 7, 7, 11, 14, 10, 10, 10, 10, 12, 11, 10, 13, 11, 15, 11, 7, 12, 10, 3, 7, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 3, 7, 2, 5, 5, 3, 3, 5, 5, 5, 5, 7, 6, 6, 6, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 7, 10, 2, 2, 2, 5, 5, 5, 5, 3, 3, 3, 3, 3, 5, 5, 10, 9, 11, 8, 7, 12, 8, 9, 7, 6, 13, 11, 6, 13, 7, 9, 9, 4, 4, 4, 4, 4, 4, 6, 10, 7, 8, 13, 8, 8, 9, 14, 8, 10, 7, 7, 7, 9, 6, 9, 7, 2, 12, 5, 3, 3, 13, 4, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 2, 2, 2, 5, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 1, 7, 6, 4, 12, 3, 3, 3, 3, 3, 8, 7, 3, 3, 3, 3, 3, 3, 4, 4, 11, 14, 2, 8, 3, 5, 5, 8, 10, 8, 6, 4, 7, 17, 4, 5, 2, 6, 5, 2, 4, 4, 2, 12, 5, 5, 3, 15, 13, 10, 8, 11, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 3, 3, 3, 3, 4, 18, 2, 12, 5, 3, 3, 3, 3, 3, 5, 16, 8, 8, 9, 6, 6, 4, 4, 4, 4, 31, 6, 6, 10, 11, 21, 10, 9, 7, 10, 7, 7, 2, 4, 4, 4, 4, 6, 5, 3, 3, 4, 3, 3, 3, 3, 3, 3, 6, 6, 2, 2, 2, 5, 3, 3, 3, 7, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 8, 2, 3, 3, 3, 3, 3, 5, 9, 11, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 5, 10, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 11, 10, 10, 10, 10, 10, 11, 10, 11, 10, 11, 10, 9, 9, 11, 3, 3, 3, 3, 3, 3, 5, 3, 7, 8, 8, 7, 6, 6, 11, 4, 4, 4, 7, 8, 9, 9, 2, 3, 7, 4, 4, 2, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 2, 2, 5, 5, 5, 5, 5, 3, 3, 5, 5, 5, 7, 7, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 6, 9, 12, 3, 7, 10, 7, 2, 2, 3, 3, 3, 3, 3, 4, 3, 3, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 8, 8, 6, 8, 7, 4, 4, 4, 4, 4, 6, 7, 5, 5, 20, 19, 8, 10, 9, 7, 10, 6, 8, 11, 6, 6, 6, 6, 13, 12, 8, 6, 7, 14, 11, 9, 2, 5, 3, 3, 6, 2, 3, 2, 2, 2, 2, 2, 2, 2, 5, 4, 3, 7, 6, 4, 7, 4, 3, 6, 4, 7, 2, 7, 7, 7, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 9, 10, 10, 8, 11, 7, 8, 20, 7, 8, 9, 8, 12, 6, 6, 6, 8, 9, 8, 12, 6, 6, 8, 13, 10, 12, 6, 6, 7, 7, 8, 9, 6, 4, 4, 4, 4, 4, 4, 4, 10, 6, 6, 6, 7, 14, 11, 10, 7, 8, 10, 8, 11, 14, 11, 11, 9, 7, 9, 8, 11, 9, 17, 10, 9, 2, 2, 2, 9, 3, 3, 3, 3, 15, 14, 9, 5, 5, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 12, 22, 19, 17, 18, 18, 19, 21, 7, 16, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 16, 11, 11, 7, 7, 7, 7, 17, 7, 8, 12, 15, 9, 19, 7, 19, 8, 16, 21, 11, 12, 19, 14, 22, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 16, 16, 19, 24, 12, 7, 14, 7, 12, 7, 8, 10, 10, 13, 7, 12, 12, 7, 7, 10, 18, 15, 12, 16, 7, 14, 12, 17, 10, 16, 17, 12, 17, 25, 7, 7, 7, 13, 6, 9, 6, 9, 18, 6, 6, 11, 20, 10, 6, 6, 6, 6, 6, 6, 6, 17, 6, 6, 6, 15, 6, 6, 6, 6, 6, 8, 14, 11, 12, 15, 13, 19, 17, 21, 7, 18, 8, 13, 13, 8, 12, 8, 6, 6, 13, 6, 15, 15, 16, 6, 6, 16, 6, 6, 6, 14, 6, 18, 6, 6, 6, 17, 18, 9, 13, 15, 8, 19, 8, 15, 15, 18, 14, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 11, 10, 11, 6, 21, 23, 12, 17, 12, 11, 14, 13, 22, 15, 15, 11, 12, 14, 12, 7, 12, 8, 14, 12, 18, 10, 8, 16, 19, 17, 12, 14, 15, 8, 9, 19, 17, 12, 13, 13, 15, 18, 13, 23, 24, 23, 21, 17, 24, 8, 21, 8, 14, 14, 16, 14, 8, 8, 15, 20, 8, 19, 21, 9, 8, 13, 12, 13, 15, 11, 8, 11, 9, 9, 8, 11, 8, 21, 14, 21, 15, 15, 13, 7, 19, 7, 7, 7, 7, 7, 16, 12, 17, 18, 7, 7, 11, 11, 7, 9, 9, 2, 2, 3, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 10, 10, 7, 9, 7, 7, 7, 6, 8, 6, 6, 6, 6, 6, 6, 6, 7, 6, 8, 6, 6, 9, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 8, 9, 8, 7, 8, 7, 8, 10, 7, 5, 5, 5, 5, 5, 5, 3, 9, 7, 7, 8, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 9, 11, 13, 7, 8, 9, 9, 5, 5, 5, 7, 8, 6, 6, 6, 6, 6, 6, 6, 7, 8, 9, 7, 10, 9, 10, 7, 8, 5, 5, 5, 5, 5, 5, 7, 7, 9, 8, 7, 7, 6, 6, 6, 6, 6, 6, 10, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 10, 4, 4, 4, 4, 8, 7, 7, 10, 10, 9, 8, 8, 15, 9, 8, 8, 8, 8, 8, 9, 10, 9, 10, 7, 8, 13, 5, 5, 5, 5, 5, 3, 3, 7, 7, 8, 6, 6, 6, 4, 4, 11, 9, 7, 8, 9, 10, 7, 5, 5, 5, 5, 5, 3, 3, 7, 6, 6, 13, 7, 9, 8, 7, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 7, 8, 7, 8, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 6, 6, 6, 6, 7, 6, 7, 6, 6, 9, 7, 4, 4, 4, 4, 4, 4, 4, 7, 8, 7, 8, 9, 8, 8, 8, 7, 10, 7, 8, 5, 5, 5, 5, 5, 5, 5, 5, 3, 7, 7, 7, 7, 9, 7, 10, 9, 6, 6, 6, 6, 6, 8, 8, 6, 6, 6, 7, 6, 6, 6, 9, 9, 4, 4, 13, 7, 10, 9, 9, 12, 7, 8, 8, 10, 8, 8, 8, 8, 8, 8, 5, 5, 5, 5, 3, 7, 7, 11, 7, 9, 8, 8, 6, 6, 10, 6, 8, 8, 8, 6, 7, 6, 6, 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 8, 8, 16, 8, 9, 8, 7, 5, 5, 5, 5, 5, 3, 3, 7, 7, 7, 10, 15, 8, 9, 8, 9, 9, 6, 6, 6, 6, 6, 6, 7, 4, 8, 7, 8, 8, 7, 8, 11, 8, 5, 5, 5, 5, 5, 3, 7, 7, 6, 11, 16, 7, 6, 4, 4, 4, 4, 9, 9, 8, 8, 8, 13, 12, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 11, 7, 8, 8, 9, 13, 7, 7, 7, 9, 8, 8, 9, 12, 7, 12, 7, 12, 8, 7, 10, 12, 9, 9, 6, 6, 8, 8, 6, 6, 6, 6, 6, 6, 6, 9, 8, 9, 11, 8, 6, 6, 6, 6, 6, 12, 7, 6, 6, 6, 9, 7, 7, 6, 6, 6, 6, 6, 11, 9, 6, 6, 6, 6, 6, 7, 9, 4, 4, 4, 4, 4, 4, 4, 4, 9, 9, 9, 9, 7, 7, 7, 7, 7, 11, 7, 7, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 7, 7, 11, 11, 7, 12, 8, 8, 8, 8, 8, 7, 8, 8, 8, 8, 8, 13, 12, 8, 8, 8, 8, 7, 7, 7, 9, 5, 5, 5, 5, 5, 5, 5, 3, 3, 7, 7, 11, 7, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 11, 6, 7, 9, 4, 4, 4, 4, 4, 4, 9, 9, 8, 9, 8, 8, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 11, 7, 7, 7, 9, 6, 6, 11, 8, 10, 6, 6, 6, 12, 8, 8, 7, 6, 6, 8, 7, 4, 4, 4, 4, 4, 4, 4, 4, 9, 10, 9, 9, 8, 10, 9, 11, 8, 5, 5, 5, 7, 6, 6, 8, 7, 4, 4, 4, 4, 8, 7, 7, 8, 7, 8, 8, 5, 5, 5, 5, 7, 7, 8, 8, 8, 6, 6, 6, 6, 6, 10, 8, 9, 13, 6, 7, 6, 6, 8, 7, 8, 4, 4, 4, 4, 11, 8, 8, 8, 10, 5, 5, 8, 7, 8, 13, 8, 7, 6, 8, 6, 9, 7, 8, 7, 5, 5, 5, 5, 5, 5, 3, 3, 7, 8, 9, 6, 4, 8, 10, 10, 8, 12, 9, 13, 2, 7, 5, 5, 5, 5, 5, 7, 7, 10, 6, 6, 6, 6, 6, 6, 6, 8, 4, 4, 9, 8, 8, 8, 14, 8, 8, 8, 9, 8, 5, 5, 5, 5, 5, 3, 3, 9, 6, 6, 6, 6, 10, 12, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 11, 8, 7, 8, 8, 8, 5, 5, 3, 3, 3, 3, 7, 7, 6, 8, 6, 8, 11, 7, 6, 6, 6, 7, 4, 8, 11, 9, 10, 5, 5, 5, 3, 3, 3, 7, 7, 8, 9, 8, 15, 9, 6, 6, 6, 6, 6, 6, 11, 11, 4, 4, 4, 4, 4, 7, 9, 9, 10, 8, 7, 5, 5, 5, 5, 5, 5, 3, 3, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 7, 4, 4, 4, 4, 4, 9, 9, 8, 8, 10, 13, 5, 5, 5, 3, 17, 7, 7, 7, 7, 7, 8, 6, 8, 13, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 9, 10, 8, 8, 8, 5, 5, 5, 5, 3, 7, 7, 7, 8, 8, 6, 6, 6, 8, 8, 8, 9, 10, 8, 4, 8, 10, 9, 8, 8, 8, 9, 13, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 7, 8, 9, 9, 7, 7, 7, 10, 9, 9, 8, 9, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 11, 8, 8, 9, 9, 10, 8, 9, 7, 7, 5, 5, 5, 5, 5, 5, 3, 7, 8, 7, 6, 6, 8, 6, 6, 10, 4, 7, 8, 9, 12, 8, 7, 7, 5, 5, 5, 5, 5, 5, 3, 3, 7, 14, 7, 9, 8, 8, 6, 6, 8, 12, 12, 6, 6, 7, 7, 10, 4, 4, 4, 4, 4, 9, 9, 14, 9, 13, 8, 7, 5, 5, 5, 6, 6, 6, 7, 4, 8, 7, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 7, 7, 7, 8, 6, 6, 6, 6, 6, 6, 12, 6, 6, 6, 6, 4, 4, 9, 9, 8, 8, 11, 7, 7, 7, 5, 5, 5, 3, 9, 8, 6, 6, 7, 4, 4, 4, 4, 4, 4, 8, 8, 11, 5, 5, 5, 7, 7, 7, 9, 6, 6, 6, 6, 6, 6, 9, 8, 4, 4, 4, 4, 7, 12, 9, 8, 8, 8, 7, 10, 10, 5, 5, 5, 5, 5, 5, 5, 3, 11, 14, 8, 7, 8, 8, 6, 6, 6, 6, 6, 8, 7, 6, 6, 6, 7, 6, 8, 9, 4, 4, 4, 7, 8, 9, 7, 9, 7, 7, 9, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 11, 3, 9, 7, 7, 12, 14, 8, 6, 6, 12, 11, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 15, 7, 4, 4, 4, 16, 9, 9, 9, 8, 9, 9, 9, 9, 9, 8, 8, 8, 13, 11, 8, 5, 5, 5, 5, 3, 7, 6, 6, 8, 8, 8, 6, 6, 7, 10, 7, 4, 4, 4, 4, 9, 7, 8, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 7, 7, 7, 9, 6, 6, 6, 6, 6, 8, 8, 7, 7, 9, 6, 6, 6, 7, 6, 6, 6, 6, 6, 15, 4, 4, 4, 4, 4, 8, 8, 7, 8, 12, 9, 8, 8, 8, 8, 8, 9, 8, 8, 10, 8, 8, 8, 8, 16, 9, 10, 2, 5, 5, 5, 5, 5, 5, 5, 9, 7, 6, 8, 9, 4, 4, 4, 4, 4, 7, 8, 8, 8, 9, 8, 11, 10, 5, 5, 5, 5, 3, 7, 8, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 4, 12, 10, 12, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 3, 3, 7, 7, 10, 8, 9, 7, 6, 10, 7, 6, 6, 4, 4, 8, 9, 7, 9, 9, 9, 9, 8, 8, 8, 8, 10, 5, 5, 5, 5, 5, 5, 8, 7, 6, 6, 6, 10, 6, 7, 10, 7, 4, 4, 4, 4, 4, 4, 4, 12, 9, 10, 7, 7, 10, 8, 10, 5, 12, 9, 6, 6, 6, 6, 6, 7, 6, 4, 4, 4, 10, 9, 9, 8, 7, 7, 5, 5, 5, 5, 5, 5, 3, 3, 13, 7, 7, 9, 7, 7, 7, 8, 9, 9, 7, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 13, 9, 15, 15, 4, 4, 4, 4, 4, 10, 10, 9, 8, 9, 8, 8, 9, 7, 8, 7, 8, 5, 5, 7, 6, 6, 6, 4, 4, 4, 7, 8, 11, 8, 5, 5, 5, 5, 5, 5, 5, 7, 6, 6, 6, 6, 6, 6, 9, 11, 10, 7, 4, 4, 4, 9, 8, 8, 5, 5, 5, 5, 5, 9, 9, 6, 6, 6, 6, 6, 6, 6, 9, 9, 4, 4, 4, 4, 8, 8, 8, 9, 9, 8, 8, 8, 13, 2, 4, 2, 7, 5, 5, 5, 5, 5, 5, 9, 9, 6, 6, 6, 6, 10, 8, 8, 8, 6, 6, 6, 4, 4, 9, 8, 10, 8, 9, 8, 8, 8, 9, 8, 8, 5, 3, 3, 3, 11, 6, 6, 6, 7, 6, 6, 6, 4, 4, 9, 8, 5, 5, 5, 5, 5, 3, 11, 8, 6, 6, 6, 6, 6, 9, 7, 4, 4, 14, 10, 9, 8, 12, 8, 8, 8, 11, 15, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 10, 10, 7, 7, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 7, 11, 7, 7, 11, 11, 7, 8, 9, 10, 7, 7, 9, 9, 9, 9, 7, 7, 10, 8, 13, 8, 8, 8, 8, 11, 10, 6, 6, 8, 10, 11, 14, 14, 6, 6, 6, 6, 6, 6, 9, 11, 7, 7, 6, 8, 12, 11, 11, 6, 6, 10, 6, 6, 6, 6, 6, 10, 7, 7, 6, 6, 11, 6, 6, 6, 11, 8, 9, 7, 6, 10, 11, 9, 10, 11, 7, 11, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 6, 6, 8, 9, 10, 9, 6, 6, 6, 10, 6, 6, 6, 6, 11, 10, 11, 10, 9, 8, 7, 7, 7, 7, 11, 14, 8, 10, 9, 9, 8, 8, 7, 11, 8, 8, 8, 11, 11, 10, 10, 9, 10, 8, 11, 10, 8, 11, 9, 12, 8, 10, 8, 11, 8, 9, 9, 11, 11, 10, 11, 13, 8, 7, 8, 8, 9, 7, 8, 8, 8, 8, 7, 8, 2, 2, 2, 2, 2, 2, 2, 4, 4, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 2, 3, 3, 3, 3, 3, 3, 3, 3, 8, 6, 4, 4, 4, 11, 7, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 3, 3, 3, 3, 8, 7, 7, 8, 8, 4, 8, 7, 7, 7, 9, 7, 8, 9, 8, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 4, 2, 2, 3, 3, 3, 3, 3, 4, 5, 5, 3, 8, 8, 6, 9, 4, 4, 10, 7, 3, 3, 3, 2, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 2, 2, 2, 3, 3, 3, 3, 3, 4, 10, 2, 3, 3, 3, 3, 3, 3, 3, 4, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 5, 2, 4, 2, 6, 2, 2, 9, 5, 5, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 8, 7, 6, 6, 11, 4, 4, 4, 4, 4, 4, 4, 6, 6, 7, 7, 11, 8, 8, 6, 5, 11, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 2, 2, 3, 3, 3, 3, 3, 3, 6, 4, 4, 4, 4, 3, 3, 3, 3, 5, 7, 2, 3, 3, 3, 3, 3, 8, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 4, 4, 4, 4, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 2, 2, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 6, 3, 3, 8, 10, 3, 4, 4, 1, 1, 1, 1, 1, 1, 1, 8, 9, 10, 7, 7, 1, 1, 3, 8, 7, 7, 8, 8, 8, 1, 6, 1, 1, 6, 3, 3, 4, 7, 3, 5, 5, 4, 4, 4, 4, 4, 2, 7, 7, 8, 12, 3, 4, 5, 1, 3, 4, 4, 10, 4, 3, 3, 3, 8, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 9, 20, 7, 5, 5, 9, 13, 5, 5, 5, 5, 5, 3, 3, 3, 16, 5, 5, 5, 13, 7, 8, 8, 11, 8, 7, 9, 7, 11, 12, 9, 9, 8, 8, 11, 10, 14, 7, 12, 10, 11, 13, 7, 9, 11, 17, 17, 14, 13, 7, 8, 7, 10, 10, 7, 16, 13, 7, 8, 17, 12, 9, 8, 6, 7, 10, 6, 6, 12, 6, 8, 10, 8, 8, 8, 6, 8, 6, 14, 6, 6, 6, 13, 6, 10, 6, 6, 7, 14, 8, 6, 6, 10, 11, 10, 9, 9, 7, 7, 6, 6, 6, 9, 9, 7, 9, 10, 9, 13, 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 6, 8, 9, 10, 9, 7, 10, 10, 8, 7, 8, 7, 10, 12, 9, 8, 15, 8, 7, 8, 8, 7, 7, 15, 13, 7, 10, 9, 14, 18, 16, 7, 24, 7, 8, 10, 11, 16, 8, 14, 7, 9, 9, 9, 11, 13, 19, 14, 15, 14, 11, 7, 13, 9, 10, 7, 13, 9, 10, 11, 12, 8, 9, 2, 3, 5, 8, 7, 4, 4, 10, 5, 3, 3, 3, 3, 3, 5, 4, 4, 4, 2, 2, 2, 2, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 2, 12, 5, 3, 8, 10, 15, 6, 7, 2, 3, 2, 5, 5, 12, 2, 5, 5, 5, 5, 2, 2, 5, 5, 12, 9, 5, 2, 2, 9, 5, 5, 12, 12, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 12, 5, 8, 8, 9, 5, 5, 5, 8, 19, 7, 16, 15, 14, 9, 9, 9, 9, 7, 11, 11, 11, 14, 10, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 14, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 12, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 12, 9, 9, 12, 12, 12, 15, 7, 11, 7, 11, 18, 13, 8, 18, 15, 18, 12, 14, 12, 8, 8, 8, 8, 9, 9, 9, 12, 7, 10, 10, 8, 8, 12, 12, 12, 7, 12, 12, 9, 7, 7, 7, 7, 7, 8, 15, 12, 9, 10, 10, 7, 10, 10, 13, 11, 10, 9, 22, 11, 9, 8, 8, 8, 8, 8, 13, 18, 13, 9, 15, 19, 9, 7, 7, 10, 7, 7, 7, 11, 8, 13, 17, 7, 7, 10, 10, 10, 7, 20, 16, 7, 7, 7, 7, 11, 21, 12, 12, 13, 11, 14, 16, 8, 8, 13, 11, 9, 7, 7, 13, 7, 7, 14, 15, 15, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 10, 18, 6, 6, 6, 6, 6, 6, 6, 6, 6, 11, 8, 8, 12, 12, 11, 11, 8, 12, 9, 9, 9, 13, 13, 9, 9, 9, 9, 9, 9, 10, 12, 6, 6, 6, 6, 17, 11, 7, 7, 7, 7, 14, 14, 12, 6, 7, 7, 6, 6, 15, 10, 13, 10, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 13, 9, 9, 15, 13, 6, 12, 12, 6, 19, 11, 10, 7, 7, 16, 8, 19, 17, 9, 9, 9, 9, 9, 6, 6, 6, 10, 8, 16, 8, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 14, 6, 6, 6, 6, 20, 6, 9, 6, 9, 9, 9, 6, 9, 8, 8, 12, 9, 8, 8, 8, 7, 8, 12, 7, 8, 8, 8, 6, 8, 6, 6, 6, 6, 6, 6, 6, 9, 8, 8, 6, 6, 13, 9, 12, 13, 12, 14, 13, 12, 11, 11, 6, 8, 8, 8, 6, 13, 12, 11, 11, 12, 6, 11, 12, 11, 13, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 15, 6, 6, 6, 6, 6, 6, 6, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 6, 18, 6, 12, 13, 13, 13, 9, 10, 15, 9, 12, 6, 6, 6, 6, 6, 6, 6, 6, 9, 15, 10, 9, 10, 13, 9, 19, 8, 18, 17, 10, 10, 8, 8, 6, 6, 6, 6, 6, 6, 10, 14, 8, 16, 16, 9, 8, 15, 8, 8, 10, 12, 14, 7, 7, 8, 8, 7, 7, 7, 7, 8, 13, 13, 11, 9, 9, 9, 12, 10, 17, 8, 11, 9, 7, 7, 14, 8, 14, 14, 7, 7, 7, 7, 7, 7, 14, 7, 7, 7, 7, 7, 10, 10, 8, 14, 7, 7, 7, 7, 8, 8, 8, 8, 8, 17, 9, 15, 7, 8, 12, 7, 9, 14, 7, 7, 7, 9, 13, 8, 14, 7, 16, 18, 13, 15, 14, 12, 13, 10, 15, 9, 7, 7, 7, 10, 13, 15, 15, 9, 9, 9, 9, 19, 11, 11, 11, 13, 8, 8, 8, 8, 7, 12, 19, 17, 9, 9, 13, 7, 7, 7, 9, 7, 7, 7, 12, 13, 15, 10, 8, 8, 14, 15, 12, 13, 13, 8, 12, 14, 7, 11, 7, 14, 15, 13, 12, 8, 8, 8, 8, 11, 13, 15, 15, 8, 13, 12, 8, 8, 8, 13, 10, 16, 14, 11, 8, 8, 12, 12, 9, 15, 15, 12, 12, 13, 8, 8, 9, 12, 13, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 11, 12, 11, 14, 7, 13, 13, 13, 12, 18, 16, 7, 12, 11, 10, 10, 15, 9, 9, 9, 21, 7, 7, 7, 11, 16, 8, 8, 11, 11, 7, 7, 7, 7, 7, 19, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 8, 9, 12, 14, 11, 9, 9, 9, 22, 12, 8, 8, 15, 4, 2, 2, 5, 5, 3, 3, 3, 3, 3, 3, 6, 6, 4, 4, 4, 12, 7, 10, 2, 3, 3, 3, 3, 3, 3, 3, 6, 7, 3, 7, 5, 14, 4, 4, 8, 10, 4, 1, 3, 3, 6, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 2, 2, 5, 3, 4, 2, 2, 2, 2, 2, 2, 11, 5, 5, 5, 11, 5, 5, 3, 5, 5, 5, 5, 11, 14, 13, 9, 11, 9, 12, 8, 11, 11, 8, 11, 16, 9, 9, 7, 10, 9, 12, 8, 15, 6, 7, 6, 6, 13, 10, 8, 11, 8, 6, 6, 6, 12, 16, 6, 11, 7, 8, 9, 18, 6, 6, 9, 4, 4, 6, 13, 6, 6, 6, 6, 8, 8, 9, 16, 8, 7, 7, 14, 7, 8, 8, 8, 7, 7, 7, 7, 7, 7, 15, 13, 7, 10, 7, 7, 10, 12, 16, 15, 7, 9, 9, 14, 11, 11, 10, 9, 10, 8, 12, 7, 8, 7, 7, 10, 12, 7, 12, 8, 7, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 5, 5, 5, 10, 4, 8, 7, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 7, 4, 5, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 8, 2, 2, 2, 8, 12, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11, 9, 8, 8, 8, 7, 8, 9, 7, 7, 9, 7, 7, 7, 10, 7, 7, 10, 9, 10, 6, 6, 6, 6, 6, 6, 15, 7, 8, 9, 9, 8, 6, 6, 10, 9, 6, 8, 13, 9, 7, 6, 6, 6, 6, 6, 6, 12, 6, 6, 7, 6, 7, 6, 6, 6, 10, 10, 7, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 14, 6, 6, 7, 7, 9, 6, 6, 6, 6, 9, 9, 8, 9, 10, 9, 8, 9, 12, 7, 7, 7, 8, 7, 10, 12, 11, 9, 10, 7, 7, 7, 9, 10, 10, 8, 12, 9, 7, 7, 9, 8, 8, 8, 10, 7, 7, 8, 9, 9, 7, 7, 7, 8, 2, 4, 6, 3, 4, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 5, 8, 6, 4, 7, 3, 3, 3, 3, 3, 3, 3, 12, 3, 3, 3, 3, 3, 3, 4, 4, 2, 3, 5, 3, 4, 7, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 6, 4, 3, 4, 2, 2, 2, 5, 3, 3, 3, 3, 3, 5, 4, 4, 4, 4, 7, 6, 8, 9, 2, 2, 2, 2, 3, 3, 3, 5, 7, 2, 3, 3, 8, 7, 7, 2, 2, 8, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 8, 8, 7, 7, 6, 10, 6, 9, 7, 11, 4, 6, 8, 8, 7, 8, 4, 5, 5, 5, 3, 3, 11, 8, 9, 6, 6, 8, 7, 4, 4, 7, 8, 7, 2, 2, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 2, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 12, 5, 5, 3, 3, 3, 5, 10, 12, 6, 15, 4, 6, 6, 7, 14, 9, 3, 3, 3, 3, 3, 8, 2, 2, 3, 5, 3, 3, 3, 3, 3, 3, 8, 8, 8, 7, 5, 8, 4, 6, 11, 2, 2, 6, 7, 2, 9, 8, 5, 5, 3, 3, 5, 7, 7, 6, 6, 10, 6, 6, 8, 9, 7, 4, 4, 4, 4, 7, 6, 6, 7, 7, 10, 9, 8, 11, 8, 3, 3, 3, 3, 3, 4, 4, 2, 3, 3, 3, 3, 3, 7, 6, 2, 5, 6, 7, 6, 4, 8, 9, 11, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 5, 3, 3, 3, 3, 3, 9, 9, 6, 4, 8, 7, 7, 5, 9, 8, 6, 8, 7, 8, 5, 5, 5, 5, 5, 3, 3, 3, 16, 8, 7, 7, 7, 8, 7, 7, 7, 7, 9, 6, 9, 6, 10, 7, 7, 7, 6, 10, 8, 9, 11, 11, 8, 4, 4, 10, 8, 8, 6, 9, 6, 11, 8, 8, 8, 15, 7, 8, 9, 5, 3, 3, 3, 3, 3, 5, 11, 2, 2, 3, 8, 9, 10, 3, 2, 2, 2, 2, 2, 2, 3, 6, 4, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 2, 3, 3, 3, 3, 3, 3, 3, 11, 5, 3, 3, 3, 3, 3, 3, 3, 3, 6, 7, 4, 4, 2, 3, 3, 3, 3, 3, 3, 3, 3, 12, 7, 4, 12, 4, 6, 5, 4, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 11, 10, 6, 4, 6, 10, 8, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 5, 3, 4, 4, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 7, 8, 8, 7, 13, 12, 10, 10, 8, 8, 7, 7, 9, 12, 11, 6, 6, 8, 8, 9, 7, 7, 7, 10, 15, 10, 4, 4, 4, 4, 4, 11, 8, 8, 9, 7, 9, 14, 14, 12, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 12, 5, 5, 5, 8, 11, 10, 7, 9, 3, 8, 7, 3, 15, 13, 11, 4, 4, 2, 2, 2, 19, 7, 5, 5, 3, 3, 3, 3, 3, 3, 3, 5, 22, 18, 6, 14, 17, 4, 4, 19, 16, 18, 2, 3, 3, 2, 3, 2, 3, 3, 6, 4, 2, 3, 3, 2, 5, 3, 3, 3, 3, 3, 3, 3, 9, 9, 2, 3, 2, 2, 2, 3, 3, 3, 5, 7, 14, 7, 7, 12, 9, 13, 6, 11, 6, 10, 9, 7, 7, 8, 12, 12, 8, 8, 8, 10, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 5, 8, 10, 7, 8, 11, 8, 12, 9, 4, 7, 7, 9, 13, 2, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 3, 3, 3, 3, 3, 3, 5, 2, 2, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 4, 4, 4, 3, 2, 3, 3, 3, 3, 5, 2, 2, 2, 2, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 12, 9, 8, 8, 9, 8, 6, 17, 6, 6, 6, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 4, 4, 8, 8, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 7, 8, 8, 8, 10, 7, 13, 10, 8, 9, 3, 3, 13, 3, 3, 3, 3, 3, 7, 7, 6, 6, 10, 13, 11, 11, 8, 8, 9, 8, 9, 9, 10, 10, 10, 11, 10, 10, 13, 13, 16, 15, 11, 12, 9, 9, 10, 9, 11, 10, 9, 9, 14, 7, 8, 3, 10, 7, 7, 3, 2, 2, 2, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 7, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 11, 6, 7, 4, 6, 2, 2, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 6, 4, 4, 2, 2, 2, 3, 3, 3, 3, 4, 4, 6, 6, 6, 6, 5, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 11, 6, 10, 9, 12, 7, 7, 11, 14, 9, 7, 12, 3, 3, 7, 12, 11, 12, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 11, 5, 5, 5, 5, 5, 5, 5, 5, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 10, 3, 3, 3, 11, 3, 5, 9, 11, 8, 12, 14, 9, 7, 8, 7, 7, 11, 11, 7, 7, 10, 9, 8, 10, 9, 7, 7, 7, 7, 7, 7, 8, 8, 7, 11, 8, 8, 8, 7, 7, 10, 8, 7, 13, 12, 7, 17, 10, 8, 8, 11, 7, 11, 11, 14, 7, 11, 7, 8, 6, 9, 20, 8, 7, 9, 16, 7, 10, 6, 11, 10, 8, 9, 7, 16, 11, 11, 9, 8, 9, 8, 8, 8, 11, 8, 15, 8, 8, 9, 7, 8, 8, 11, 10, 7, 5, 7, 10, 10, 15, 7, 7, 7, 8, 7, 8, 8, 10, 11, 10, 10, 10, 11, 11, 7, 8, 6, 8, 8, 8, 10, 6, 8, 6, 6, 7, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16, 6, 15, 6, 7, 11, 11, 7, 9, 10, 11, 13, 10, 6, 16, 8, 10, 12, 11, 6, 6, 6, 6, 6, 6, 6, 10, 6, 10, 7, 7, 7, 7, 11, 7, 11, 6, 6, 6, 6, 6, 6, 17, 7, 7, 6, 6, 12, 22, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 7, 6, 6, 5, 6, 6, 8, 11, 6, 9, 14, 11, 9, 11, 7, 7, 8, 6, 6, 6, 8, 10, 9, 6, 6, 6, 6, 9, 7, 6, 6, 6, 6, 6, 15, 6, 4, 4, 4, 6, 4, 17, 8, 11, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 10, 6, 10, 6, 6, 6, 6, 12, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 18, 6, 6, 6, 8, 9, 10, 7, 8, 9, 10, 11, 7, 13, 6, 8, 8, 6, 6, 14, 7, 7, 7, 7, 10, 7, 14, 9, 6, 6, 9, 15, 9, 7, 14, 6, 11, 14, 13, 7, 12, 8, 7, 7, 7, 7, 7, 12, 7, 10, 9, 16, 6, 8, 6, 5, 17, 6, 8, 10, 4, 6, 4, 10, 15, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 11, 7, 4, 4, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 19, 17, 6, 10, 11, 6, 6, 6, 6, 18, 6, 6, 11, 4, 4, 4, 5, 6, 6, 6, 9, 5, 6, 4, 6, 6, 4, 6, 6, 6, 6, 10, 6, 6, 4, 6, 6, 10, 6, 10, 6, 6, 6, 6, 11, 6, 6, 10, 6, 6, 8, 6, 6, 6, 8, 6, 11, 4, 11, 9, 10, 9, 11, 4, 8, 4, 11, 12, 7, 9, 8, 6, 7, 7, 8, 12, 12, 11, 13, 10, 11, 7, 7, 7, 9, 7, 11, 10, 7, 7, 7, 16, 11, 10, 11, 17, 9, 9, 8, 8, 7, 7, 7, 9, 7, 7, 7, 14, 7, 13, 9, 11, 10, 14, 10, 10, 12, 11, 10, 7, 10, 5, 14, 8, 8, 8, 9, 7, 8, 7, 7, 9, 8, 7, 8, 7, 7, 7, 7, 7, 7, 7, 11, 8, 10, 8, 7, 8, 14, 11, 8, 9, 9, 9, 8, 24, 10, 10, 12, 7, 7, 15, 11, 8, 8, 12, 11, 8, 9, 9, 7, 8, 9, 10, 11, 10, 11, 7, 12, 7, 7, 11, 9, 8, 14, 13, 12, 8, 11, 10, 8, 8, 7, 7, 14, 9, 10, 8, 9, 11, 7, 14, 8, 8, 13, 8, 8, 12, 7, 10, 14, 14, 11, 9, 10, 9, 9, 7, 7, 11, 11, 13, 9, 13, 5, 5, 5, 7, 9, 5, 11, 12, 14, 8, 7, 7, 11, 10, 9, 7, 8, 8, 7, 10, 11, 11, 5, 5, 7, 5, 5, 5, 7, 7, 15, 7, 7, 8, 7, 15, 12, 12, 10, 7, 8, 7, 11, 7, 7, 7, 23, 11, 8, 8, 11, 10, 7, 8, 11, 7, 19, 7, 7, 6, 9, 9, 9, 11, 3, 4, 7, 8, 6, 6, 4, 10, 8, 2, 2]);
50210
+ var edgeChild = /* @__PURE__ */ new Uint16Array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 1, 1, 1, 1, 1, 17, 1, 1, 1, 12, 1, 12, 1, 12, 13, 1, 1, 1, 1, 12, 1, 12, 1, 1, 1, 1, 1, 14, 21, 1, 1, 1, 1, 1, 1, 19, 12, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 16, 1, 18, 1, 1, 15, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 22, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 24, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 12, 12, 12, 12, 1, 32, 0, 0, 0, 1, 1, 1, 1, 1, 35, 34, 1, 1, 1, 1, 1, 1, 33, 1, 1, 1, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 39, 40, 0, 0, 0, 41, 0, 12, 1, 1, 12, 1, 1, 1, 1, 44, 45, 45, 45, 44, 45, 44, 44, 46, 45, 44, 45, 44, 44, 44, 44, 44, 44, 46, 44, 44, 44, 44, 44, 44, 45, 47, 47, 45, 44, 44, 44, 44, 44, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 52, 50, 50, 50, 52, 50, 51, 50, 53, 50, 51, 51, 50, 50, 50, 51, 53, 51, 53, 50, 51, 51, 12, 55, 55, 54, 56, 51, 53, 50, 50, 48, 49, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 60, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 66, 1, 12, 1, 1, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 12, 1, 1, 1, 1, 87, 1, 89, 1, 1, 1, 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 95, 95, 1, 1, 12, 1, 98, 1, 1, 1, 1, 1, 1, 1, 96, 1, 97, 1, 99, 1, 1, 1, 1, 1, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 108, 109, 1, 1, 1, 1, 1, 1, 111, 111, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 119, 120, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 120, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 120, 1, 1, 1, 1, 1, 1, 1, 1, 1, 124, 121, 123, 118, 1, 122, 1, 1, 112, 1, 1, 1, 1, 115, 1, 125, 1, 1, 1, 1, 1, 117, 1, 106, 1, 107, 1, 12, 126, 104, 1, 110, 1, 1, 1, 1, 1, 105, 113, 1, 12, 12, 12, 116, 114, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 12, 12, 1, 1, 1, 1, 1, 12, 132, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 134, 1, 1, 1, 1, 1, 1, 1, 1, 135, 136, 12, 12, 133, 131, 45, 45, 138, 50, 50, 137, 140, 139, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 1, 0, 142, 130, 1, 0, 1, 12, 12, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 146, 145, 20, 1, 1, 12, 12, 1, 20, 12, 12, 1, 1, 1, 1, 1, 132, 1, 1, 150, 1, 1, 1, 1, 151, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 1, 134, 1, 1, 150, 1, 1, 1, 1, 151, 1, 1, 132, 1, 1, 1, 150, 1, 1, 1, 1, 151, 1, 1, 132, 1, 1, 1, 1, 1, 1, 1, 1, 132, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 158, 1, 1, 1, 150, 1, 1, 1, 1, 1, 151, 1, 1, 158, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 132, 1, 1, 1, 1, 150, 1, 1, 1, 1, 151, 1, 1, 1, 132, 1, 1, 150, 1, 1, 1, 1, 162, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 165, 1, 1, 158, 1, 1, 1, 1, 1, 150, 1, 1, 1, 1, 1, 151, 1, 1, 158, 1, 1, 1, 1, 1, 150, 1, 1, 1, 1, 1, 151, 1, 152, 156, 156, 12, 1, 12, 164, 1, 1, 1, 1, 1, 156, 156, 156, 152, 1, 1, 1, 155, 156, 159, 163, 1, 1, 1, 1, 155, 155, 1, 1, 154, 152, 152, 155, 168, 154, 168, 1, 1, 166, 1, 154, 153, 155, 1, 1, 1, 1, 155, 1, 157, 1, 1, 1, 12, 1, 160, 1, 160, 1, 1, 1, 160, 159, 161, 167, 154, 152, 1, 1, 1, 1, 1, 1, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 170, 171, 170, 170, 170, 170, 172, 172, 170, 171, 170, 171, 170, 170, 12, 12, 12, 12, 12, 1, 12, 12, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 191, 1, 1, 1, 1, 12, 197, 198, 199, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 149, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 194, 1, 1, 1, 182, 1, 208, 1, 1, 1, 206, 1, 1, 203, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 188, 1, 1, 1, 184, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 180, 1, 1, 1, 1, 1, 1, 1, 189, 1, 1, 1, 1, 193, 1, 1, 1, 1, 169, 1, 1, 187, 1, 1, 1, 190, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 178, 1, 12, 1, 1, 12, 1, 1, 1, 1, 181, 1, 1, 1, 186, 1, 201, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 207, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 192, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 174, 12, 1, 1, 1, 176, 12, 1, 1, 1, 1, 1, 1, 1, 196, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 175, 1, 1, 1, 1, 1, 1, 202, 1, 1, 1, 179, 1, 1, 1, 185, 1, 12, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 189, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 173, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 183, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 204, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 205, 1, 1, 12, 1, 1, 1, 1, 177, 1, 1, 1, 183, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 195, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 200, 1, 1, 12, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 218, 0, 0, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 1, 12, 1, 1, 1, 223, 1, 1, 1, 0, 224, 221, 222, 1, 1, 1, 1, 1, 1, 229, 1, 231, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 227, 1, 1, 1, 1, 1, 233, 1, 1, 12, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 232, 1, 1, 12, 1, 1, 1, 1, 228, 1, 1, 226, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 230, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 239, 13, 1, 1, 1, 12, 12, 236, 237, 1, 1, 1, 1, 238, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 240, 1, 1, 12, 16, 1, 1, 1, 1, 1, 1, 1, 241, 1, 1, 1, 12, 12, 1, 1, 1, 1, 1, 241, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 254, 254, 1, 0, 0, 0, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 0, 0, 170, 259, 260, 1, 12, 1, 1, 1, 1, 12, 262, 1, 1, 261, 1, 264, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 268, 269, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 12, 0, 280, 0, 0, 281, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 324, 324, 325, 324, 0, 183, 1, 1, 13, 320, 1, 318, 0, 0, 0, 0, 1, 0, 0, 0, 321, 1, 1, 326, 1, 203, 1, 1, 1, 1, 1, 319, 1, 316, 1, 322, 1, 314, 1, 323, 1, 315, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 12, 1, 12, 317, 317, 1, 1, 1, 313, 182, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 12, 1, 1, 1, 1, 312, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 329, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 264, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 369, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 337, 348, 1, 1, 336, 371, 1, 342, 1, 1, 334, 366, 1, 1, 352, 333, 338, 1, 1, 1, 345, 376, 354, 1, 1, 1, 1, 1, 1, 355, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 364, 368, 0, 0, 77, 1, 1, 0, 362, 339, 375, 340, 343, 350, 1, 365, 0, 1, 0, 77, 359, 357, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 378, 1, 1, 349, 1, 77, 1, 0, 1, 1, 1, 381, 1, 0, 0, 77, 356, 0, 1, 335, 1, 1, 1, 0, 1, 1, 358, 1, 0, 1, 1, 1, 0, 1, 383, 346, 1, 1, 0, 1, 0, 0, 374, 0, 1, 1, 1, 77, 367, 1, 1, 363, 360, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 341, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 373, 0, 77, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 377, 1, 1, 1, 0, 0, 380, 0, 0, 0, 1, 353, 1, 0, 77, 379, 1, 0, 0, 0, 0, 382, 1, 1, 0, 0, 1, 0, 1, 0, 351, 0, 347, 0, 1, 1, 1, 0, 1, 1, 0, 370, 344, 372, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 397, 397, 1, 1, 12, 12, 1, 397, 1, 1, 12, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 409, 1, 0, 1, 1, 1, 1, 203, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 427, 427, 1, 1, 0, 0, 314, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 439, 1, 438, 1, 1, 1, 1, 1, 1, 1, 1, 442, 1, 12, 12, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 450, 1, 1, 1, 452, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 449, 1, 444, 1, 1, 1, 432, 1, 1, 1, 1, 1, 1, 1, 1, 445, 12, 1, 1, 1, 1, 451, 1, 1, 1, 446, 441, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 314, 1, 430, 1, 1, 12, 448, 1, 1, 314, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 434, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 451, 1, 1, 1, 1, 314, 1, 447, 1, 1, 1, 436, 1, 1, 1, 1, 1, 437, 1, 453, 440, 1, 1, 1, 1, 1, 435, 1, 1, 1, 1, 1, 1, 1, 1, 1, 431, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 443, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 433, 1, 1, 1, 1, 1, 1, 1, 218, 454, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 459, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 12, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 463, 463, 463, 463, 463, 463, 463, 0, 463, 463, 463, 463, 463, 1, 463, 463, 463, 0, 463, 463, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 468, 467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, 0, 0, 475, 470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 473, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 484, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 196, 196, 1, 488, 1, 1, 1, 487, 1, 1, 1, 1, 483, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 485, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 489, 1, 1, 486, 1, 1, 1, 1, 1, 1, 1, 1, 1, 369, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 490, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 12, 1, 503, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 60, 1, 1, 12, 12, 12, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 522, 1, 1, 1, 1, 1, 1, 1, 523, 1, 1, 1, 1, 1, 1, 1, 521, 1, 1, 12, 1, 525, 237, 1, 1, 12, 12, 1, 1, 12, 1, 12, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 535, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 130, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 105, 1, 1, 12, 1, 1, 1, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 544, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 142, 1, 1, 1, 226, 1, 1, 12, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 568, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 573, 1, 218, 1, 325, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 574, 1, 1, 1, 1, 0, 576, 0, 77, 0, 575, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 12, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 578, 578, 0, 581, 579, 578, 578, 578, 578, 578, 583, 578, 578, 587, 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, 584, 581, 578, 578, 581, 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, 579, 578, 578, 578, 578, 578, 585, 578, 578, 578, 578, 578, 578, 0, 0, 0, 1, 586, 1, 1, 1, 1, 580, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 591, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 12, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 1, 1, 12, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 64, 277, 303, 408, 531, 0, 4, 67, 234, 252, 279, 304, 331, 385, 410, 0, 495, 515, 532, 593, 9, 0, 61, 86, 395, 406, 426, 571, 0, 493, 514, 528, 608, 0, 30, 6, 0, 458, 496, 598, 556, 68, 0, 7, 282, 253, 386, 460, 413, 534, 77, 594, 0, 572, 306, 415, 462, 9, 103, 285, 502, 6, 30, 0, 308, 77, 388, 77, 479, 10, 6, 129, 246, 272, 0, 609, 505, 0, 559, 0, 63, 6, 6, 249, 93, 2, 429, 396, 407, 592, 0, 6, 0, 6, 283, 101, 6, 557, 497, 536, 0, 461, 387, 270, 284, 8, 69, 102, 595, 539, 389, 309, 297, 416, 144, 72, 287, 542, 506, 597, 560, 332, 327, 476, 6, 73, 147, 11, 0, 247, 518, 543, 561, 510, 547, 566, 607, 36, 6, 258, 292, 330, 301, 216, 30, 524, 549, 216, 42, 214, 263, 293, 302, 403, 420, 477, 271, 0, 71, 558, 0, 400, 414, 296, 77, 245, 77, 0, 577, 541, 500, 289, 418, 77, 390, 384, 0, 0, 0, 9, 551, 567, 215, 0, 421, 404, 527, 512, 569, 611, 83, 216, 43, 294, 393, 422, 565, 0, 507, 290, 273, 77, 213, 78, 28, 387, 30, 6, 391, 328, 300, 600, 588, 520, 546, 509, 0, 256, 79, 30, 402, 419, 0, 30, 423, 0, 217, 589, 513, 9, 405, 424, 216, 246, 84, 220, 590, 570, 553, 478, 425, 394, 248, 225, 85, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 127, 0, 0, 82, 545, 0, 0, 0, 0, 0, 0, 0, 27, 0, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 499, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 613, 0, 0, 0, 0, 0, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 392, 0, 0, 0, 480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 0, 0, 0, 0, 0, 526, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455, 0, 0, 0, 311, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 564, 0, 0, 0, 0, 596, 517, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 265, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 0, 0, 276, 606, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 0, 275, 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 498, 0, 0, 0, 0, 0, 550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 482, 0, 481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 494, 0, 610, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 0, 0, 0, 540, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 29, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 554, 0, 267, 0, 0, 128, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 411, 417, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 530, 0, 0, 0, 412, 0, 0, 398, 0, 0, 0, 0, 0, 0, 599, 0, 0, 0, 537, 0, 0, 88, 0, 538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504, 457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 614, 0, 0, 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 619, 619, 619, 619, 619, 619, 619, 618, 620]);
50211
+ var labelText = "orgmilcomnetedugovdrrformsfeedbackofficialaccoorgmilschnetgovmagazinemediaunioncargopilotgroupcaarespressworksaerodromeworkinggroupair-traffic-controlaircraftaccident-preventioneducatormarketplaceambulanceinsurancecateringairportrepbodyenginesoftwaremodellingair-surveillanceconsultingchartertrainermaintenanceservicesdesignflightskydivingfreightassociationstudentgroundhandlingdgcafuelclubtaxicrewshowballooningexpresstraderbrokerauthoragentsairtrafficjournalistsafetyconsultantmicrolightaccident-investigationparachutingequipmentproductionfederationrecreationscientistnavigationengineertradingglidingleasingresearchpassenger-associationentertainmentparaglidinghangglidingaerobaticrotorcraftemergencycertificationgovernmentaeroclubexchangelogisticschampionshiphomebuiltcouncilconferencecontrolairlinecivilaviationjournalorgcomnetedugovcoorgcomnomnetobjofforgcomnetuwukiloappsframerorgmilcomnetedugovcoradioorgcomnetcommuneedogpbcoitgvorgedugov*spreviewfrontendrelayononstagingupid*mtls*privatelinktypedreamdeveloperbravemochawindsurfaivenmirenupsunwnextbegetngrokclerkwale2bwebcsbrunflutterflowspawnbaseshiptodaymagicpatternsnetlifyondigitaloceanrailwayhostedclaudehasurabotdashvercelgithubluyanigadgetreplitcloudflaretelebitedgecomputeevervaultdetaexponyatnoopencrpplxzeaburwasmerframerzeropsconvexmedusajsspritesonherculeseasypanelstreamlitsnowflakemesserliloginlinehackclubnorthflankbase44corespeedadaptableleapcellngrok-freeclerkstagelovableon-fleek*us-west-3ap-south-2us-central-2us-central-1eu-central-1ap-south-1us-west-2us-east-2eu-north-1ap-north-1us-west-1us-east-1*rcloudintsegorgmilcomgobbetnetintedugovturmusicasenasamutualcoopip6uriurnin-addre164homeirisgovdixdaemoncloudnssthwien*inexexkunden4accogvormymyspreadshop4lima2ixbizortsinfofuturecmsfuturehostinginfo12hpprivfuturemailinglima-cityfunkfeuer123webseitemelmyspreadshopcloudletswasantqldvicactnswtascatholicwasaqldvictasvpsidwasantozqldorgcomvicasnactnetedugovnswtasconfhrsncomairflowlambda-urltransfer-webappairflowtransfer-webapptransfer-webapptransfer-webapp-fipstransfer-webappeu-west-3ap-south-2eu-south-2eu-central-2ap-southeast-3ap-southeast-4ap-northeast-3eu-central-1mx-central-1me-central-1ca-central-1il-central-1ap-northeast-1ap-southeast-1me-south-1af-south-1eu-south-1ap-south-1ap-southeast-7us-west-2eu-west-2us-east-2eu-north-1ap-southeast-2ap-northeast-2ap-southeast-5us-gov-west-1us-gov-east-1ca-west-1us-west-1eu-west-1us-east-1ap-east-1sa-east-1privatenotebookstudiolabelingnotebookstudionotebooknotebook-fipslabelingnotebookstudionotebook-fipsnotebookstudio-fipsnotebook-fipsnotebookstudionotebook-fipsnotebookstudioeu-west-3ap-south-2eu-south-2eu-central-2ap-southeast-3ap-southeast-4ap-northeast-3eu-central-1me-central-1ca-central-1il-central-1ap-northeast-1ap-southeast-1me-south-1af-south-1eu-south-1ap-south-1us-west-2eu-west-2us-east-2eu-north-1ap-southeast-2ap-northeast-2experimentsus-gov-west-1us-gov-east-1ca-west-1us-west-1eu-west-1us-east-1ap-east-1sa-east-1onrepostsagemakercopporgmilcompronetintedugovbiznameinfoshoprsorgmilcomnetedugovbrendlynzauscotvstoreorgcomnetedugovbizinfoidacaicoittvorgmilcomschnetedugovinfocloudezproxyacmymyspreadshopkuleuvenwebhostingtransurl123websitecloudnsinterhostsolutions5476103298edgfacbmlonihkjutwvqpsryxzbarsycoororgcomedumyftpno-iporxcloud-ipfor-somemmafanfor-morewebhopselfipjozidyndnscloudnsdscloudfor-thefor-betteractivetrailcoeconorestooteorgcomeconeteduassurmoneyafricaarchitectesrestaurantloisirstourismavocatsinfoagrounivcoorgcomnetedugovtvdeportesaludtksatorgmilcomwebgobnetinteducienciaboliviarevistacooperativaempresanombreindustriamusicapatriamedicinademocraciapoliticapuebloindigenaplurinacionalarteblogwikiinfoagrotransportenoticiasprofesionalacademiaeconomiaecologiamovimientotecnologianaturalsimplesitecepesebamapadfmgalampbacscpirngorotomtrjspaprrprrsesmscepesebamapadfmgalampbacscpirngorotomtrjspaprrprrsesms*biaamfmtcmptvfeirasampajampanatalbelemananiradiog12medindfndbmdtrdthepoaggfjdfdefinfenflegsegongengcngorgzlgslglogppgmillelqslcimcomnomadmjabimbbibbsbabcrectecsjcetcpscpvhudieticriapipsiecnbiorioecogeoteoodoproatoartfstmatvetdetbetnetcntnotfotgrueduajuespappreptmpemparqsrvadvdevgovntrturagrjorfarjusmusdesvixxyzcozfozslzbhzmaringasantamariacampinagrandegoianiasorocabafloripasaobernardocuritibaboavistarecifeaparecidasaogoncasalvadorcuiabamorenamacapalondrinacontagemsocialfortalmaceioleilaoosascoriobranconiteroi9guacutcheblogflogvlogwikitaxicoopmanauspalmascaxiasjoinvillebaruericampinassantoandreribeiraoriopretoweorgcomnetedugovv0windsurfshiptodaycloudsitecoaccoorgnetgovofmilcomgovmediatechzacoorgcomnetedugsjgovmydnspenfnlabnbmbgcbcqconcontnuyksknsmyspreadshopno-ipawdevboxbarsyonidatemfuinabusavinstanceseceuguukussryzespawncsxcloud-ipmyphotosfantasyleaguetwmailcleverappsscrappingccwucloudnsftpaccessgame-serverccgovobjectsrmalpgcust*svcalp1aeappenginermalpgmyspreadshop4lima2ixsquare7cloudscale123websitefirenet12hpflowgotdnslinkyard-cloudcloudnslima-citydnskingobjectstorageedaccogoorusorgcomnetintedua\xE9roportxn--aroport-byaassogouvcomilgobgovcloudnses-1eu-west-1us-east-1euvipit1eurarubait1s3lbwebsites3websiteru-spbru-mskelasticcsrunstnukukcaukusnl-ams-1fr-par-1fr-par-2functionsnodess3ddlwhmrdbfnck8sifrs3-websitecockpitscblmgdbdtwhkafkpubprivs3ddlwhmrdbk8sifrs3-websitecockpitscblmgdbdtwhkafks3ddlrdbk8sifrs3-websitecockpitscblmgdbdtwhkafkk8sscalebookpl-wawfr-parnl-amsbaremetalsmartlabelinginstancesdechk2kuleuvenlaravelvoorloperurownoxazapscwhstgrvaporobservablehqelementorantagonistreclaimjoteluluencowaydiademjelasticmatlabmagentositetrendhostingaxarnetperspectajenv-arubajelejoteravendbemergenttrafficplexconvexkeliwebserveboltbegetcdnstaticson-rancherprimetelonstackitunison-serviceslinkyardbarsyjelecloudnscocomnetgovmycn-northwest-1cn-north-1s3s3-accesspoints3-websites3s3-accesspointrdsdualstacks3-deprecatedemrappui-prods3-websiteemrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apis3s3-accesspoints3s3-accesspointrdsdualstackemrappui-prods3-websiteemrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicn-northwest-1cn-north-1cn-northwest-1ebcomputeelbcn-north-1airflowcn-northwest-1cn-north-1oncn-northwest-1cn-north-1amazonawssagemakeramazonwebservicesdirectasgdsdhehahljlnmhbacscahqhshhihnlnynsnmofjbjzjxjtjhkcqtwgsjssxnxjxgxxzgz\u7DB2\u7D61\u7F51\u7EDC\u516C\u53F8orgmilcomnetedugovxn--55qx5dcanva-appsxn--io0a7iquickconnectcanvasitekhsjxn--od0algmyqnapcloudsrvrlessclustersrealtimestorageleadpagescarrdcrdorgmilcomnomnetedugovhidnssupabaserdpareplmypiumsoxmitotaplpagesfirewalledreplitowodevwebview-assetsvfswebview-assetss3s3-accesspointdualstackemrappui-prods3-websiteaws-cloud9emrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9eu-west-3ap-south-2eu-south-2eu-central-2ap-southeast-3ap-southeast-4ap-northeast-3eu-central-1me-central-1ca-central-1il-central-1ap-northeast-1ap-southeast-1me-south-1af-south-1eu-south-1ap-south-1ap-southeast-7us-west-2eu-west-2us-east-2eu-north-1ap-southeast-2ap-northeast-2ap-southeast-5ca-west-1us-west-1eu-west-1us-east-1ap-east-1sa-east-1s3s3-accesspointdualstackemrappui-prods3-websiteaws-cloud9emrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9s3s3-accesspointdualstackanalytics-gatewayemrappui-prods3-websiteaws-cloud9emrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9s3s3-accesspointdualstackemrappui-prods3-websiteemrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apis3s3-accesspointdualstacks3-deprecateds3-websites3-object-lambdaexecute-apis3s3-accesspoints3-websites3-accesspoint-fipss3-fipss3s3-accesspointdualstackemrappui-prods3-websites3-accesspoint-fipsaws-cloud9s3-fipsemrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9s3s3-accesspointdualstackemrappui-prods3-websites3-accesspoint-fipss3-fipsemrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apis3s3-accesspointdualstacks3-deprecatedanalytics-gatewayemrappui-prods3-websiteaws-cloud9emrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9vfss3s3-accesspointdualstackemrappui-prods3-websiteaws-cloud9emrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9eu-west-3ap-south-2eu-central-2ap-southeast-3ap-southeast-4ap-northeast-3eu-central-1mx-central-1me-central-1ca-central-1il-central-1ap-northeast-1us-northeast-1ap-southeast-1me-south-1af-south-1ap-south-1ap-southeast-7us-west-2eu-west-2ap-east-2us-east-2ap-southeast-2ap-northeast-2ap-southeast-5us-gov-west-1us-gov-east-1ap-southeast-6ca-west-1us-west-1eu-west-1us-east-1ap-east-1sa-east-1mrapaccesspoints3s3-accesspointdualstacks3-deprecatedanalytics-gatewayemrappui-prods3-websites3-accesspoint-fipsaws-cloud9s3-fipsemrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9s3s3-accesspointdualstacks3-deprecatedanalytics-gatewayemrappui-prods3-websites3-accesspoint-fipsaws-cloud9s3-fipsemrstudio-prods3-object-lambdaemrnotebooks-prodexecute-apicloud9s3eu-west-3ap-south-2eu-south-2computes3-ap-northeast-2elbrdss3-ap-east-1s3-sa-east-1s3-us-gov-west-1s3-eu-central-1s3-ca-central-1eu-central-2ap-southeast-3ap-southeast-4ap-northeast-3s3-website-us-west-2s3-website-eu-west-1s3-external-1eu-central-1me-central-1ca-central-1il-central-1s3-us-west-1s3-eu-west-1s3-website-sa-east-1s3-website-ap-southeast-2ap-northeast-1ap-southeast-1s3-us-west-2s3-eu-west-2me-south-1af-south-1eu-south-1ap-south-1us-west-2eu-west-2us-east-2s3-website-ap-southeast-1s3-1s3-globals3-ap-northeast-3eu-north-1airflowap-southeast-2s3-us-gov-east-1s3-fips-us-gov-east-1s3-me-south-1s3-ap-south-1ap-northeast-2s3-website-us-west-1ap-southeast-5s3-eu-north-1s3-ap-southeast-1s3-website-us-gov-west-1compute-1s3-eu-west-3us-gov-west-1s3-website-ap-northeast-1us-gov-east-1s3-fips-us-gov-west-1s3-website-us-east-1s3-ap-southeast-2ca-west-1us-west-1eu-west-1us-east-1ap-east-1sa-east-1s3-us-east-2s3-ap-northeast-1authauthauth-fipsauth-fipseu-west-3ap-south-2eu-south-2eu-central-2ap-southeast-3ap-southeast-4ap-northeast-3eu-central-1mx-central-1me-central-1ca-central-1il-central-1ap-northeast-1ap-southeast-1me-south-1af-south-1eu-south-1ap-south-1ap-southeast-7us-west-2eu-west-2us-east-2eu-north-1ap-southeast-2ap-northeast-2ap-southeast-5us-gov-west-1us-gov-east-1ca-west-1us-west-1eu-west-1us-east-1ap-east-1sa-east-1rservicesbuilderstg-builderdev-builder*ociocpocsdemoinstanceeu-west-3eu-south-2ap-southeast-3ap-northeast-3eu-central-1me-central-1ca-central-1il-central-1ap-northeast-1ap-southeast-1me-south-1af-south-1eu-south-1ap-south-1ap-southeast-7us-west-2eu-west-2us-east-2eu-north-1ap-southeast-2ap-northeast-2ap-southeast-5us-gov-west-1us-gov-east-1us-west-1eu-west-1us-east-1ap-east-1sa-east-1previeweu-4us-4us-1eu-1us-2eu-2us-3eu-3appspaasrag-cloudrag-cloud-chjcloudjcloud-ver-jpcdemonodebalancermembersipeuxvsoncillaocelotonzayalilynxsphinxfentigercustomercaracalo365cloudstaticxendevapp001testcode-builder-stgplatformapimediasiteprojedrydpagesjsu2u2-localx0desazacncoitrueu4uhkukgrbrushatenadiarymyspreadshopfrom-flfrom-wvwebspace-hosttheworkpchatenablogservesarcasmapplinzisakuratanwixsiteappchizigiizeis-into-carsdnsiskinkyadobeaemcloudis-a-therapistpgfogmyvncdojinis-an-actress1kappfldrvkozowqa2jpnmexprgmrfirewall-gatewaydynnscafjsfbsbxooguyxnbayfrom-gawoltlab-demois-a-anarchistwiardwebteaches-yogadattowebtb-hostinglive-websiteservegamegotpantheonfrom-nhsubsc-payfrom-ohvipsinaappfrom-cadyndns-officehomelinuxfrom-mahercules-appservebbsstreakusercontentfrom-okfrom-wyfastly-terrariumis-a-llamaqualyhqportalserveexchangeon-vaporvivenushopciscofreakgrayjayleaguesmetaaiusercontentfrom-iais-a-libertariansaves-the-whalestaveusercontentyolasiteoperaunitepoint2thisis-a-catererlinodeusercontentfrom-vagithubusercontentsells-for-lesshosteurcanva-appsplaystation-cloudddnsfreefrom-pafrom-prfrom-waddnskingoutsystemscloudhotelwithflightmydattois-a-nascarfanmydbserverminiserverdamnserverservehumouris-a-playerfrom-nvfrom-nmemergentagentgentappsamplifyappfrom-kyis-an-accountantnfshostserveircfrom-akpythonanywherestackhero-networkpostman-echolikescandydyndns-mailobservableusercontentserveftpfreeboxosfrom-utcdn77-storageamazonawsneat-urldyndns-serverlinodeis-a-teacherfrom-vtgleezemythic-beastsus1-pleniteu1-plenitla1-plenitpaywhirlservecounterstrikejdevcloudhealth-carereformis-into-animegoogleapisis-a-painterafricaisa-hockeynutatmetais-an-actora2hostedis-a-democratdatadetectest-le-patrondigitaloceanspacesis-a-designeris-a-hunterlinodeobjectstemp-dnsissmarterthanyoufrom-arsimplesiteevennodetownnews-stagingis-a-liberalgooglecodejelasticservemp3stdlibqualyhqpartnerdyndns-free1cooldnsest-a-la-masiondrayddnsdynuddnsfrom-orfrom-miis-a-bloggerfrom-himydobisscanvacodeis-an-engineerest-a-la-maisonupsunappdevinappswafflecellmyasustorwpenginepoweredfrom-ctservep2psame-appmyshopblocksthingdustdatalikes-piediscordsezis-with-thebanddev-myqnapcloudlpusercontentis-leetshopitsite3utilitiesis-a-personaltrainersinaappladeskis-a-cheflogoipselfipbase44-sandboxnospamproxyalibabacloudcsmesswithdnsauthgearappsiamallamawithgooglelutrausercontentmochausercontentframercanvasmytabitdyndns-homew-credentialless-staticblitzcpserverdiscordsaysis-a-nurseappspotatlassian-isolated-3premotewdfrom-mtwixstudiocode0emm180rmyactivedirectoryawsappsmytuleapdnsabrpolyspaceqbuserrenderbuiltwithdarkboutirgotdnsabrdnsdopaascanva-hosted-embedawsglobalacceleratorhomesecuritypcmyiphostditchyouripclever-clouddyndns-ipon-aptibleis-a-musiciansecuritytacticsappspaceusercontenthomeunixstrapiappsame-previewcf-ipfsmycloudnaselasticbeanstalkis-certifieddontexistkasserverik-serverdrive-platformatlassian-3pfirebaseappherokuappawsapprunnerbarsycenteris-a-cubicle-slaveservehttpmyshopifyis-a-guruquicksytessiiitesorsitesmagicpatternsappis-a-cpameteorappfrom-wiis-a-rockstarbumbleshrimpdattolocalreadthedocs-hostedfrom-rifamilydsdyndns-picsplesknsbplaceddnsaliasdynaliasdyndns-remotedoomdnsip-ddnsblogdnsis-a-doctorroutingthecloudamazoncognitobarsyonlinedsmynasddnsgurucloudflare-ipfsdeus-canvasfrom-idsmushcdnpagespeedmobilizerdyndns-at-homeunusualpersonhosted-by-previderis-a-republicandyn-o-saurstreamlitappworkisboringonthewificprapidqualifioappis-uberleetis-slickgetmyipwpdevcloudtypeformdyndns-at-workgentlentapismynascloudw-corp-staticblitzfrom-ingeekgalaxyservebeerfrom-mdonrenderspace-to-rentaivencloudappspacehostedonfabricawafaicloudcodespotblogspotatlassian-3p-us-gov-modfrom-ndfrom-msis-a-techieis-a-studentcustomer-ociis-a-photographerdurumisfrom-ksmassivegriddyndns-wikiis-an-entertaineris-a-hard-workermysecuritycamerafrom-mnrackmazedyndns-blogis-a-bulls-fanwritesthisblogfreemyipsimple-urlfrom-sdreservdauthgear-stagingest-mon-blogueuris-into-gamesrice-labsxtooldevicesakurawebis-an-anarchistoraclecloudappsdyndns-worksells-for-urhcloudfrom-dcfastvps-serverwpmucdnis-a-geekscrysecfrom-txis-into-cartoonsmodelscapetrycloudflarelocaltonetstreak-linkbalena-devicesfrom-njforgeblocksfreebox-oswebadorsitefrom-ncdoesntexisthobby-sitestreaklinkshomesecuritymacownprovidertuleap-partnersdattorelaywphostedmailalpha-myqnapcloudservequakeis-a-socialistservehalflifepivohostingdynuhostingquipelementsw-staticblitzdyndns-webfrom-deproject-studyaliases121is-not-certifiedhercules-devis-a-financialadvisorservepicsis-a-greenloseyouripfrom-ilwithyoutubemwcloudnonprodwiredbladehostingdnsdojofrom-tnpixolinomyqnapcloudis-an-artisthostedpiis-a-landscaperauiusercontentoaiusercontenton-forgeis-a-conservativedreamhostersnet-freaksapps-1and1is-goneencoreapifastly-edgefrom-nesalesforcefrom-scdeployagentoraclegovcloudappsfrom-alis-a-lawyercechirevultrobjectsstufftoreadisa-geekddnsgeeklovableprojecttry-snowplowfrom-moblogsyteis-a-bookkeepernogmyforumravendbmyboxdeelementoredsaacficogoorinforgcomgobnatneteduidorgcomnetintedunomepublorgcomneteduathgovtestscalculatorspaynowinfoquizzesresearchedcloudnsfunnelsassessmentsjscaleforcetmacltdorgmilcompronetgovbizpresseklogesrsccloudcustomfltusrcloude4corealmgovmunicontentproxy9metacentrumdyndyndyndnsdynpagespages-researchitionoccustomercomymyspreadshopdiskussionsbereich4limacomrub2ixfirewall-gatewayddnssspdnsbarsykeymachinesquare7myhome-serverspeedpartnercommunity-proschuldockxenonconnectg\xFCnstigliefernbwcloud-os-instancemy-routerxn--gnstigliefern-wobin-butterl-o-g-i-nisteingeekin-dslin-berlinin-brbfuettertdasnetzleitungsenin-vpnlcube-serverdyn-ip24logoipdyn-berlinruhr-uni-bochum12hpgoipfruskygit-repossvn-reposinternet-dnsg\xFCnstigbestellenhome-webserverxn--gnstigbestellen-zvbbplacedcosidnswebspaceconfiglima-citydyndns1istmeinvirtualuserschulplattformmy-gatewaylebtimnetztest-iservmein-iservvirtual-useriservschuletaifun-dnstraeumtgeradeschulserverdynamisches-dns123webseitednshomehs-heilbronndnsupdaterbssgraphicdwadpdwdaepeweaawapaafpfwfabwbpbacwcpcciwebuserapiobjectsidsiskospockkimodorikerbonesteamsparisjanewaypicardglobaltarpitreedpikekiraworfsulukirkarchertuckerhackercanarywesleystagingprereleaset3r2lpbravepanelngrokiservstglclcrmerpflypagesbarsyvivenushoplocalcertlocalplayerbearbloggatewaydeno-stagingis-not-ais-a-goodbotdashvercelmocha-sandboxplatter-appreplitgithubpreviewworkersinbrowserevervaultdetais-ahrsndenoxmitmodxmyaddrstorageapipayloadgrebedocruncontainersstgstagelclstageloginlineis-a-fullstackleapcellngrok-freeis-coolstoragewebharemediatechlibp2pdiscourseimaginecomyspreadshopstoreregbiz123hjemmesidefirmcoorgcomnetedugovsldorgmilcomwebgobartnetedugovtmorgpolcomsocartnetedugovassoagrondiscoodontk12medcuegyecpaabgengorgmilgalsaltulcomadmesmgobpubdocmonfindgnriouioproartlatvetnetfotedulojgovntrturibrbarxxxofficialbasechefprofmktgpsictechinfoarqtcontdentrrpppsiqgit-pagesritmedfieorgcomlibprieduaipgovriikmeactvsportorgmilcomscieunnetedugovnameinfopintouchtawktotawkmyspreadshoporgcomnomgobedu123miwebcomputeorgcomnetedugovbiznameinfocognito-idpeusc-de-east-1onjelasticnxaspdnsbarsydirectwpdeuxfleurstransurldogadoprvwcloudnsamazonwebservicesuserpartycokoobinstorjfidemopaasdymyspreadshopalandkapsiikixn--hkkinen-5wacloudplatformdatacenterh\xE4kkinen123kotisivuidacorgmilcompronetedugovbiznameinforadioorgcomneteduuserexperts-comptablestmmyspreadshopgretaprdcomnomynhccifbxoshuissier-justicenotairesaeroportfreeboxoson-webavocatassoportgouvkdnschirurgiens-dentistes-en-franceavouesfbx-os123sitewebveterinairechirurgiens-dentistespharmacienchambagrimedecinfreebox-osdediboxgoupilemszicpyicpvicppleysheezypagesedugovcnpyorgcompvtnetedugovschooldaemond6atcopanelorgnetplybotdashstackitkaasorgmilcomnetedugovbizmodltdorgcomedugovcoorgcomneteduappwriteacorgcomnetedugovcloudtranslateusercontentorgcomnetedumobiassoorgcomnetedugovbarsysimplesitediscourseindorgmilcomgobneteduorgcomwebnetedugovguaminfonxhra\u6559\u80B2\u654E\u80B2\u7DB2\u7D61\u7F51\u7D61\u7EC4\u7E54\u7D44\u7E54\u7F51\u7EDC\u7DB2\u7EDC\u7EC4\u7EC7\u7D44\u7EC7\u516C\u53F8\u653F\u5E9C\u500B\u4EBA\u4E2A\u4EBA\u7B87\u4EBAltdorgcomincneteduidvgovxn--uc0ay4axn--55qx5dxn--mk0axixn--io0a7ixn--uc0atvxn--zf0avxxn--lcvr32dxn--od0algxn--wcvs22dxn--gmqw5axn--od0aq3bxn--mxtq1mxn--ciqpnxn--tn0agxn--gmq050iorgmilcomgobneteduiservwp2tempurlmircloudfreesitewpmudevmyfastgadgetcloudaccessjelehalfboltfastvpsemergenteasypanelopencraftizcombrendlynamefromrtpersoadultmedorgpolrelcomproartnetedufirminfoassoshopcoopgouvtmcomediahotelforumvideosportorgsexagrargameslakaseroticaerotikatozsdereklamcasino2000filmsuliinfoboltshopprivnewsszexcityutazasjogaszkonyveloingatlaneacaicogoormy\u1B29\u1B2E\u1B36milwebschnetkopbizzonedesaponpesxn--9tfkymyspreadshopgovmytabittabitorderravpageaccok12idforgnetgovmuniltdplcaccotttvorgcomnetmeca6g5gpgamacaicniocoukuptverdruscsdelhiindorgmilcomwebnicfingenpronetintedugovresbizbiharbarsyinternetbusinesstravelsupabasegujaratfirminfopostbankcoopindevscloudnsno-ipbarsybarrell-of-knowledgebarrel-of-knowledgensupdategroks-thisdnsupdatefor-ourknowsitalldvrcammittwalddynamic-dnsv-infowebhopselfipdyndnshere-for-moreilovecollegemayfirstforumzcloudnsmittwaldservertypo3servergroks-theeusekd1uk0cdndyndnsidrawsainaueuapjpusstagemocksysdevicesclientcustreservdcustdevdisrecprodtestingcobeebyteutwenteboxfusebravepstmndedynngrokorgmilcomnomhzcnetedugovqcxqzzbarsythingdustmo-siemensrb-hostingprotonetfh-muenstergitbookbluebitecloudbeesusercontentnodeartkiloappsforgerockdarklangresinstagingapigeebubbleb-datascryptedhypernodedappnodepantheonsitegitlabgithubkeeneticvirtualservercleverappshostyhostingon-rioedugitticketstelebiton-acornwixstudioon-k3sicp0icp12038jeleqotobigvlairbubbleappsmyaddrstolosmyrdbxwebflowdrive-platformbeagleboardhasura-applolipopdefinimavaporcloudmusicianwebflowtestazurecontainerresindevicereadthedocsloginlineeditorxmoonscalesandcatsbasicserverwebthingsbrowsersafetymarkbeebyteappbitbucketidaccovistablogorgschnetgovxn--mgba3a4f16axn--mgba3a4fraarvanedge\u0627\u064A\u0631\u0627\u0646\u0627\u06CC\u0631\u0627\u0646jclaspeziapdudcefegelemeperetevebacanatavaparasabgagfgogrgpgalclblimfmrmcbmbvbfclcmcvcrcpcchlimifibicivipirisimncnbnanenrnpntnnolomobocoaogorosopotoptvtatctbtmtltotpulunutpspapaqsvpvvvtvavvrtrsrprgrfrcrbrarorkrvstsssbscsmsispzczbzbozen-suedtirolmyspreadshopxn--bulsan-sdtirol-nsbxn--valledaoste-ebbtrentinoaltoadigetrentin-sued-tirolxn--forlcesena-c8axn--forl-cesena-fcbxn--bozen-sdtirol-2obtriestetrentinsuedtiroltrentino-s-tirollecceudineaostesienaparmaluccapaviagenoapaduaaostamonzaabruzzoternirietiturinmilanbozenlaziofermoleccocuneonuoropratola-speziavdataaligfvgpugmolcalcamlomumbsicpmnvenvaoedugovabrsarmaremrbastoslazibxosfirenzetrentinos\xFCdtirolval-d-aostavalle-aostamessinacremonaravennatoscanatrentin-suedtirolbolognacalabriaurbinopesarofriuli-v-giuliaogliastraxn--valle-aoste-ebblaquilaandriatranibarlettasyncloudtrentinosudtirolxn--valle-d-aoste-ehbaostavalleyvalled-aostatrentino-alto-adigevallee-d-aostexn--balsan-sdtirol-nsbpistoiasicilialucaniacataniaiserniaperugiabresciaveneziagorizialiguriaimperiabulsan-suedtirolbalsan-suedtirolbarlettatraniandriaxn--trentino-sdtirol-szbforl\xEC-cesenatuscanyvall\xE9e-d-aostemantovavall\xE9e-aostecasertapiemontevalleaostaval-daostafriulivgiuliatrevisoforli-cesenavall\xE9edaosteferrarapescaravald-aostatrentino-altoadigefriuli-vegiuliavallee-aostecarboniaiglesiastarantomediocampidanovalleedaostetrentinosud-tirolcampobassotrentins\xFCd-tiroltrentinos\xFCd-tirolmonzabrianzatrentino-s\xFCdtirolxn--trentino-sd-tirol-c3bpotenzacosenzavicenzaemiliaromagnavenicefrosinonemarchepordenonetrentinosued-tirolvaresemolisevall\xE9eaostefriuli-veneziagiuliabasilicatalatinaanconasavonaveronamodenaaquilabiellabolzano-altoadigepugliafoggiaumbriatrentino-stirolgenovapadovamateranovararagusapiacenzatrentinostirolvalleeaostetempio-olbiatrentinsudtirolmassa-carrarafriuliveneziagiuliatrentinosuedtirolandria-barletta-tranitrapanixn--cesenaforl-i8amaceratacaltanissettaascoli-picenobrindisicarraramassacagliaririmininapolivibo-valentiachietibulsan-sudtirolbalsan-sudtiroltrentino-a-adigebulsanbalsaniglesiascarboniamilanotorinoteramodell-ogliastraarezzotrentinoalto-adigerovigotrentovenetoiglesias-carboniatrentino-sud-tirolaltoadigereggio-emiliareggio-calabriasardegnatranibarlettaandriapiedmontxn--sdtirol-n2amedio-campidanotrentino-s\xFCd-tirolfriuli-vgiuliafriuli-ve-giuliaromeennaromapisa32-b16-b64-blodiastibarineencomonaplesforlicesenailiadboxosalessandriasicilytrani-barletta-andriaxn--trentin-sdtirol-7vbpesarourbinotrentinsued-tirolcesena-forliforl\xECcesenaemilia-romagnamonzaebrianzaxn--trentinsdtirol-nsbtrentinos-tiroltrentins\xFCdtirolvalledaostaolbia-tempiocampidanomediovibovalentiasassarivalle-daostalombardyfriulivegiuliareggioemiliamonzaedellabrianzaalto-adigevercellitrentin-sudtiroltraniandriabarlettatrentino-sudtirolascolipicenobozen-s\xFCdtirolfriulive-giuliaflorencevaldaostaxn--cesena-forl-mcbcarbonia-iglesiasaosta-valleycarrara-massadellogliastratrentinoa-adigexn--valleaoste-e7apesaro-urbinoxn--trentinosdtirol-7vbxn--trentin-sd-tirol-rzbxn--trentinsd-tirol-6vbtrani-andria-barlettatrentin-s\xFCd-tirolxn--trentinosd-tirol-rzbgrossetomonza-e-della-brianzas\xFCdtirolreggiocalabriatrentinoaadigetrentin-s\xFCdtirolfriuliv-giuliaverbaniacampaniatrentino-aadigefriulivenezia-giuliasardiniaandriabarlettatranibarletta-trani-andriacatanzarooristanourbino-pesarocesena-forl\xECvalle-d-aostacampidano-medio123homepagesiracusatempioolbiasuedtirollombardiaavellinocesenaforl\xECtrentinofriuli-venezia-giuliabozen-sudtirolandria-trani-barlettabulsan-s\xFCdtirolbalsan-s\xFCdtirolmonza-brianzabolzanotrentino-sued-tirolbellunosalernolivornocrotonesondriotrentinsud-tirolmassacarraratrentin-sud-tiroltrentino-suedtirolviterbobergamocesenaforliolbiatempiopalermobeneventoagrigentoofcoorgnetfmaitvphdengorgmilcomschnetedugovperagrikanieasukehandachitatokaiaisaikonanoharuamaobuhigashiuraowariasahiinuyamatobishimaiwakurashitarainazawatoyonegamagorimihamatoyotataharakariyayatomioguchikomakimiyoshinishiotokonamekiyosuchiryutoyohashiokazakiisshikikasugaikotakiratoeianjotogofusosetohazutsushimashinshirotakahamanisshinshikatsuhekinantoyokawaichinomiyatoyoakeodateogataakitaikawakyowahonjoogayurihonjonoshirokamiokakatagamimitanegojomeyokotekosakadaisenkazunonikahohonjyomoriyoshimisatohappoukamikoanihachirogatahigashinarusesembokufujisatokitaakitaitayanagiowanitakkomutsutsurutahirosakigonoheoirasetowadamisawanohejiaomorishingohiranairokunohehashikamitsugarushichinohehachinohenakadomarisannohekuroishisakaeisumiasahiotakiinzaiabikomatsudoyachiyomutsuzawakujukuriomigawakashiwatoganemihamanaritasakuranagaramobarahanamigawachoshishiroichoseikozakishisuikatorimidorichonankyonanfuttsuonjukufunabashinagareyamanodasosatakochuotohnoshourayasukimitsuyokaichibayotsukaidosodegauratateyamakamagayayokoshibahikariyachimatakatsuuratomisatokisarazukamogawaichikawanarashinoichinomiyashimofusaminamibososhirakoichiharaoamishirasatoikatahonaiainansaijoseiyoiyoozuuwajimaniihamanamikatamasakiuchikokihokutobetoonshikokuchuomatsuyamaimabarikamijimakumakogenyawatahamamatsunosabaeikedaobamasakaifukuiohionotsurugamihamawakasaminamiechizeneiheijikatsuyamatakahamaechizensoedaukihaomutaokawanishiogoribuzenonojosueumiokiotochikugosasagurisaigawamizumakishinyoshitomikurumekurateyamadakasuganakamamiyamanogatatakatahakataiizukakawaratagawakasuyaashiyainatsukimunakataminamitsuikishonaikurogifukuchikeisenhigashimiyakoshinguyukuhashiokagakiyamekogaongausuikahotohochuotoyotsumiyawakadazaifuhisayamatachiaraiyanagawanakagawahirokawachikujochikushinochikuhochikuzennamieotamaokumashowateneiiwakikoorinangoononishigoshimogoomotegomishimafukushimaasakawakagamiishishirakawaiitatefutabahiratayugawahanawakitakatakawamatakunimiyabukibandaihigashihironoyamatomiharuyamatsuriaizubangedatesomaaizuwakamatsuyanaizuaizumisatonishiaizuizumizakikitashiobarataishinkaneyamakoriyamainawashirotanagurafurudonosamegawasukagawaishikawatamakawaikedaogakitaruiginanenahashimahichisonakatsugawaibigawashirakawamizunamiminokamomitakekawauesekigaharatomikasakahogikitagatayamagatatajimianpachimotosuyaotsukakamigaharahidakanisekitokigujominogodoyorogifukasamatsutakayamawanouchihigashishirakawakasaharashimonitatsumagoichiyodakannakanrashowameiwakiryuotaoratomiokafujiokaitakuranaganoharahigashiagatsumatakasakishibukawaminakamikatashinatsukiyonokawabanumataannakaoizumimidorishintoisesakiuenoyoshiokakusatsutakayamanakanojonanmokutamamuratatebayashimaebashiotakekaitadaiwahongofuchukuietajimashobaramiharahatsukaichihigashihiroshimamiyoshikumanokurenakasakaseraseranishiasaminamifukuyamashinichionomichiosakikamijimajinsekikogentakeharaotobenanaeikedatohmaozoraobiraabirakyowaeniwataikibibaisharirebunerimohiroooketootarupippunishiokoppechitosefurubirahakodateshiranukakitahiroshimakushiroobihironanporoiwamizawaniikappukunneppufukushimanakasatsunaitoyourakuromatsunaiakabirakamisunagawashibechaurakawakamifuranonakatombetsuasahikawashimokawakayabeokoppebiratoriabashirisaromaatsumanumatahidakabifukamukawamikasahorokanaitoyotomisarufutsuhigashikawaishikarikitamiyoichiesashiiwanaitomariminamifuranoakkeshifuranotoyakoyakumootoineppushikaoishiraoinemuronayorohaboroashorobihororishirifujiutashinaihokutotakasuebetsuurausuassabukikonaishimamakinaiedatetoyabieinikiesanuryuoumuteshikagarikubetsuashibetsukimobetsuaibetsutobetsusobetsuembetsushimizuchippubetsurishirihokuryuhoronobeshintokutsubetsushibetsuhonbetsumombetsutsukigatakuriyamakoshimizushiriuchikutchanmurorannoboribetsukamishihorowassamushinshinotsukembuchiwakkanaikamoenaikiyosatotakinoueshikabesunagawafukagawanakagawatakikawakamikawahigashikagurahamatonbetsumatsumaemoseushirankoshishakotanimakanemashikeotofuketomakomaisandatambaitamiawajikasaiasagoshisoonoakoyashirotoyookaminamiawajiinagawafukusakitakasagokamigorikasugaharimayokawaashiyahimejiakashitaishiaogakisannantakinosumototakarazukanishinomiyashingugoshikinishiwakiyokatakaaioimikisayoyabukawanishiamagasakisasayamashinonsenkakogawaichikawakamikawatatsunotsukubaiwamaogawaasahisakaitokaioaraiitakobandodaigosuifuinaamikasumigaurakashimaomitamayachiyoshimodatetomobetoridehitachinakainashikisakuragawakasamayawaramoriyahitachiomiyanamegatayamagatahitachikamisuushikutakahagiibarakitonekoganakasowayukimihojosomitoryugasakishimotsumafujishirotsuchiurachikuseihitachiotashirosatotamatsukuriuchiharashikahakuinanaotsubatawajimakahokukawakitatsurugikaganominotosuzuuchinadakomatsuanamizunakanotohakusannonoichikanazawaiwateshiwafudaikawaimoriokaofunatohanamakikuzumakikitakamininohekunoheyamadayahabasumitaichinosekitanohatahiraizumirikuzentakatajobojiotsuchihironomiyakoiwaizumikarumaiichinohenodakujitonooshushizukuishifujisawamizusawakamaishikanegasakimannoutazukotohiraayagawazentsujihigashikagawauchinomikanonjisanukimarugamemitoyotakamatsutadotsunaoshimatonoshoakuneamamiizumihiokiyusuikinkoisasookouyamanakatanekagoshimakanoyaisenkawanabeminamitanemakurazakitarumizunishinoomotematsumotosatsumasendaioimatsudaayaseebinamiurazushinakaiodawaraiseharasagamiharahakoneaikawakaiseiatsugitsukuihadanoyamatoyamakitazamaoisochigasakininomiyayokosukakamakuraminamiashigarafujisawasamukawakiyokawahiratsukayugawaraokawaumajikochitsunootoyoakiinonishitosayasudahidakamiharasakawaniyodogawahigashitsunokagamigeiseisusakiotsukinaharisukumomurototosakamiochitoyotosashimizumotoyamanankokunakamurakitagawayusuharaogunichoyoukiasoutoozugyokutoamakusamifunetakamoriyamagaminamataminamiogunikikuchisumotoyamatonagasumashikiaraokumamotokamiamakusanishiharayatsushiroayabeseikasakyoideineujinakagyokameokakyotangokyotanabekyotambaminamiyamashiroyamashinatanabeyawatawazukaminaminantanmiyazuhigashiyamafukuchiyamakitamukokamojoyokizumaizuruujitawaraoyamazakinagaokakyokumiyamakawagoeinabeshimameiwaasahitaikiudonoisetsukisosakikuwanamihamamiyamasuzukatamakimisuginabarikumanokomonominamiisewataraitobakiwatakikihotadomatsusakayokkaichikameyamaureshinoishinomakishichikashukuohirataiwaosakizaohigashimatsushimashikamaiwanumashibataogawaraonagawakawasakiseminemarumoriminamisanrikukakudamuratawakuyatomiyanatoriwataritagajomisatotomekamirifushiroishimatsushimayamamotoshiogamafurukawahyugaebinotsunosaitoayakushimanobeokakitauramiyazakitakazakigokaseshiibamimatashintomikunitomikitakatakobayashikawaminamitakaharukijotakanabemiyakonojonishimeranichinankitagawakadogawamorotsukakisofukushimaminamimakisakaeobuseikedaogawamiasaokayaasahiotakiotarichinoinaomichikumakomaganechikuhokukaruizawayasuokaooshikaikusakaminamiaikitogakushimatsukawakawakamitateshinatakamorikitaaikishiojirimiyadahakubaiizunaiijimaiiyamamiyotasuzakayasakatoguraookuwanagawaminowahirayayamagataminamiminowafujimiomachisakakitakaginaganonakanosakuhokomoronagisoshinanomachiwadauedaiidaharasuwatomiachiaokianankisosakunozawaonsenagematsutakayamashimosuwamatsumotoyamanouchinakagawamochizukiazuminotatsunoobamaomuraseihiunzenosetofutsuikichijiwanagasakiisahayahasamisaikaikawatanasasebohiradokuchinotsugototogitsutsushimashimabarashinkamigotomatsuurayamazoekashibaikomakawaitenrioyodosangokoryoudaojiikarugayamatokoriyamatenkawakatsuragikurotakikawakamimiyakemitsuetakatorikamikitayamayamatotakadahegurishinjokanmakisakuraitawaramotogoseoudanarasoniandokawanishishimoichihigashiyoshinokashiharashimokitayamanosegawayoshinomintsivorytopazsakuragehirnsumomoaseinetopalmail-boxmokurenyoitamuikaojiyagosensanjoaganomyokoseiroagaomishibataniigatanagaokamurakamiuonumayuzawakariwatagamitainaitsunanminamiuonumatochioyahikojoetsuseiroukamosadoizumozakitokamachiitoigawasekikawakashiwazakitsubamemitsukekokonoesaikiusukibeppuusahimeshimakunisakihasamataketatsukumihitaoitahijikusuyufukujukamitsuebungoonobungotakadaibaraniimibizentsuyamaokayamakasaokahayashimayakagemaniwaakaiwamisakishinjotamanotakahashikibichuowakesojanagishookumenannishiawakurakurashikiasakuchisetouchikagaminosatoshotomigusukunakagusukuyaeseizenaurumaiheyaaguniogiminanjokinminamidaitokitanakagusukuyonaguniokinawaishigakikunigamiurasoekadenataramahiraraginozataketomishimojizamamitonakiitomanhigashimotobuyonabarugushikamionnanahanagohaebarukumejimakitadaitonakijinnishiharayomitanginowantokashikiishikawaikedasuitaminohizuminishisakaikananabenodaitoosakasayamayaokishiwadatadaokakaizukatondabayashichihayaakasakakumatorikadomasayamahigashiosakashijonawatehirakatataishimisakitajirihannansennankatanotoyonominatosettsuhigashiyodogawaibarakinosekitachuohigashisumiyoshifujiiderakashiwaraizumiotsutoyonakamatsubaramoriguchiizumisanoshimamototakatsukineyagawahabikinotakaishikawachinaganoyoshinogarikamiminearitaouchiimarihizenogikashimaariakekiyamafukudomikitagatakitahataomachigenkaikanzakinishiaritakyuragisagataratosutakushiroishikaratsuhamatamakouhokukawagoeyoshidasatteogoseirumaasakaurawaogawaniizaomiyayoriiotakishikihonjooganohannohanyuinasaitamaokegawaarakawayoshikawayokozehasudasayamahidakafukayachichibuiwatsukiryokamiyoshimikamiizumifujimiwarabiranzanmiyoshiminanoyashiosakadosugitomisatohigashichichibutodasokakukiyonokazoshiraokakasukabekounosukawajimatsurugashimamiyashirokitamotohatoyamamoroyamahatogayakumagayakawaguchinagatorokamisatomatsubushinamegawatokigawakamikawafujiminohigashimatsuyamakoshigayatokorozawas3isk01isk02ryuohkoseikonanaishorittotakashimamaibarahikonetorahimenishiazaikokagamokotoyasuotsukusatsunagahamamoriyamatoyosatotakatsukinotogawaomihachimanhigashiomiakagiunnanizumogotsuamayatsukakakinokimatsuehamadamasudahikawahikimiokuizumoyasugiyakumomisatotamayuohdahigashiizumookinoshimanishinoshimatsuwanoshimaneshimadafujiedayoshidashimodagotembaiwataatamikosaiyaizuitoizumishimahaibaramakinoharaomaezakikawanehonkannamisusonohigashiizufukuroinumazukawazufujiaraishizuokahamamatsushimizuizunokunimatsuzakimorimachiminamiizunishiizukikugawakakegawafujikawafujinomiyaujiietsugaoyamayaitaohiranikkoashikagakuroisokanumasakurashioyakarasuyamamotegiichikaikaminokawatochigihagamokanogisanobatonasumibunasushiobaranishikatautsunomiyaiwafunemashikoshimotsukeohtawaratakanezawaitanokomatsushimatokushimaichibaminamiaizumiwajikikainanmiyoshinarutomimamugiananmatsushigesanagochishishikuinakagawamachidachiyodakomaefussainagitaitochofufuchuomeotahigashiyamatotoshimaokutamaaogashimakodairaedogawaarakawahachiojishinagawatachikawashibuyasuginamihinodekiyosesumidaoshimanerimamitakahamuraadachinakanomizuhobunkyomegurominatokoganeihigashikurumekokubunjihigashimurayamamusashimurayamatamakitahinochuokotokatsushikakouzushimaogasawaraakishimakunitachishinjukusetagayamusashinohachijoitabashiakirunohinoharachizunanbukotouramisasawakasayonagokogehinoyazutottorinichinansakaiminatokawaharaoyabetairainamiasahinantoimizufuchutakaokakurobeyamadajohanatoyamatonaminyuzenfunahashinakaniikawanamerikawaunazukitogahimiuozufukumitsutateyamakamiichiiwadearidayuasainamitaijikatsuragiaridagawatanabemihamahidakakainankiminomisatoshingushirahamakamitondayurakozakoyagobokitayamawakayamakudoyamahashimotokushimotokozagawahirogawakinokawanachikatsuurarsuseroeoishidasagaeoguniasahinagaitendonanyoobanazawanishikawasakataohkuratozawamikawamamurogawayamagatafunagatatakahatashonaishinjokahokuiideyuzakawanishitsuruokakaminoyamayamanobeshiratakamurayamanakayamakaneyamahigashineyonezawasakegawamitouubeyuuabushimonosekitabuseoshimatoyotaiwakunihikarishunannagatohagihofukudamatsutokuyamashowadoshitsurunanbukoshukaiminami-alpsnirasakikosugeotsukioshinohokutominobuyamanashifuefukichuokofuichikawamisatoyamanakakonakamichitabayamanishikatsuranarusawafujikawahayakawafujiyoshidafujikawaguchikouenohara\u9577\u91CE\u4EAC\u90FD\u5C90\u961C\u5927\u962A\u4E09\u91CD\u7FA4\u99AC\u5343\u8449\u6ECB\u8CC0\u4F50\u8CC0\u5948\u826Fadednelgaccogogror\u79CB\u7530\u611B\u77E5\u9AD8\u77E5\u57FC\u7389\u6C96\u7E04\u6803\u6728\u718A\u672C\u5CA9\u624B\u9752\u68EE\u5C71\u68A8\u65B0\u6F5F\u5CF6\u6839\u9CE5\u53D6\u9577\u5D0E\u9999\u5DDD\u5BAE\u57CE\u77F3\u5DDD\u5927\u5206\u5BAE\u5D0E\u8328\u57CE\u5C71\u53E3\u5175\u5EAB\u5C71\u5F62\u5FB3\u5CF6\u5E83\u5CF6\u798F\u5CF6\u798F\u5CA1\u5CA1\u5C71\u5BCC\u5C71\u9759\u5CA1\u611B\u5A9B\u798F\u4E95\u6771\u4EACxn--4it168dhatenadiaryxn--vgu402ckawaiishophatenablogcocottenamaste\u5317\u6D77\u9053penneehimeiwateversestabachibashigagonnagunmapermahaccaakitaosakauh-ohblushkochiaichifukuikuroncapooitigohyogotokyokyotopunyuthickcheap0t00g00j0mie2-ddaapyawjg0amfemsubxiiboomoobutchueekpgwrgrherskrboyrdyupperunderflierchipsmydnsheavyangryhippygirlyrulez\u795E\u5948\u5DDD\u9E7F\u5150\u5CF6\u548C\u6B4C\u5C71bambinaxn--nit225kokayamasaitamaxn--k7yn95exn--1lqs03nsapporoparasitelolipopmcxn--efvn9sniigatafukuokatokushimafukushimahiroshimakagoshimafakefurokinawaxn--8pvr4ucoolblogxn--0trq7p7nnkawasakinagasakimiyazakichilloutxn--8ltr62kxn--klty5xpeeweezombiecutegirlxn--rny31hxn--uuwu58axn--ntso0iqx3axn--djrs72d6uytoyamanikitanyantakagawamimozanagoyaboyfriendxn--2m4a15egreaterchowderegoismyamagatafashionstorexn--elqq16hxn--pssu33lsendaimiyagixn--rht27zpecoriaomorisaloonwatsonvivianxn--djty4knobushipigboatnaganopinokoxn--f6qx53asadistvelvetsecretxn--5js045dchicappayamanashiibarakidigickgirlfriendxn--1lqs71dmongolianxn--c3s14mxn--qqqt11mtochigixn--5rtq34kparallelo0o0mondkobesagabonadecaoitanarafoolkilldecimainhiholomosblokilociaoundopupugifutankcrapflopnooroopsmodsholyjeezstripperpepperbittershizuokaxn--rht3dkitakyushureadymadeicurusversusmatrixxn--rht61ehungryfloppygloomycrankyhandcraftedlittlestarxn--klt787dxn--kltx9awhitesnowsunnydaytottorilovepoptheshopbuyshopxn--5rtp49cxn--d5qv7z876cwebaccelxn--kbrq7oxn--4pvxsxn--1ctwolovesickkumamotocatfoodxn--tor131oyokohamawakayamatonkotsuxn--ehqz56nxn--uist22hxn--6btw5axn--kltp7dyamaguchifrenchkisspussycatxn--4it797kxn--uisz3gbabybluexn--zbx025dnetgamersxn--7t0a264ckanagawaxn--6orx2rishikawaxn--ntsq17ghalfmoonschoolbusjellybeanxn--mkru45iusercontentlolitapunkxn--32vp30hsakurastoragehokkaidoshimanecandypopbabymilksupersaleweblikeraindropbackdropwebsozaikikirarahateblodaynightmeneacsccogoormobiinfoaeusxxorgmilcomnetedugovorgcomnetedugovbizinfotmprdorgmilcomnomedugovassnotairespresseassocoopgouvveterinairemedecinpharmaciensorgnetedugovtraorgcomedurepgovmeneperekgacscaiiocogoitoresmshsseoulbusanulsandaeguc01milvkimmvchungnamjeonnamjeonbukeliv-dnsgyeonggijejueliv-cdnincheondaejeongangwongyeongbukgwangjuchungbukgyeongnameliv-apicoeduindorgcomembnetedugovorgmilcomnetedugovjcloudorgcomnetintedugovperbnrinfocooyorgcomnetedugovipfscanvamypepw3sstorachakeeneticjoinmcinbrowserdwebcyonnftstoragemyfritzaemewphlxachotelltdorgcomwebsocschngonetintedugrpgovassnomgacsccoorgnetedugovbizinfo123websiteidorgmilcomasnnetedugovconfidmedorgcomplcschnetedugovaccoorgnetgovpresstmassoirseproxaccosoundcasthoptocraftvp4c66orgnetedugovitsmcdirmyboxbarsyedgestacksynologylogintonohostwebhopdiskstationi234tcp4hoocnoipprivmydsddnsdnsforlohmustransipdscloudfilegear-sgbrasiliafilegearframerbarsybarsyonlinecoprdorgmilcomnomedugovinforgcomnetedugovnameacprorgcomartnetedugovpresseinfoassoinstgouvorgnycedugovbarsydscloudjuorgcomnetedugovminisiteaccoororgcomnetgovorgmilcompronetintedugovbizmuseumnameinfoaerocoopaccoorgcomnetintedugovbizcooporgcomgobneteduorgmilcomnetedugovbiznameaccoorgmilneteduadvgovcoorgcomnetaltgovforgotherhiskeeneticispmanagernomassoprod5476132eastasiacentraluswesteuropewestus2eastus2rucdnwest1-usfra1-desandboxjls-sto1jls-sto3jls-sto2aglobalabglobalsslmapprodfreetlsmaplon-1lon-2ny-1fr-1sg-1ny-2paassnwebpaashostingjelasticnordeste-idcsocuserpagescwebfileblobservicebuscoreatlricnjsjelasticwebsitestoragesezagbinruhuukjptsmyspreadshopmynetnameakamaiorigin-stagingfrom-codynv6cdn77serveblogadobeaemcloudhicamsprytdnsupno-ipownipde5ovhicpfirewall-gatewaysytesmypsxbarsyusgovcloudapimyamazemyradwebakamaihdsaveincloudfastlylbfrom-lasubsc-paysquare7in-the-bandblackbaudcdnhomelinuxoninfernoctfcloudservebbsdns-dynamiccloudfrontakamai-stagingipifonyham-radio-opsenseeringclickrisingcommunity-profrom-nylocalcertgrafana-devedgesuite-stagingcloudflareanycasteating-organicatlassian-devmydattofeste-iplocaltotorprojectknx-serveredgekeycloudflareglobalcloudyclustercasacamserveftpakamaized-stagingakamaiorigindns-cloudmyeffectboomlabotdashbuyshousestwmailhetemlazure-mobilein-dslthruhereredirectmedynuddnsbouncemesupabaseluyanicloudappakamaicloudfunctionsdebiannhlfanpgafanstatic-accessin-vpnmysynologymafeloappudohomeftptrafficmanagersiteleafseidatmemsetcloudflarecloudaccesskeyword-onazure-apiis-a-chefdoes-itgets-itwebhopselfiphomeipkicks-assedgesuitewindowsserver-ontunnelmolemydissentscrapper-sitecloudflarecnuni5srcfggffiobbzabcdenodynuopikddnsvpndnsakadnselastxkinghostvps-hostfastlyhomeunixazureedgeshopselectdontexistmyfritzcloudjiffyalwaysdatasells-itsquaresbroke-itazurefddattolocalat-band-campmeinforumfamilydsazurestaticappsdefinimabplaceddnsaliasdynaliasnow-dnsblogdnsroutingthecloudendofinternetdsmynasakamaiedgemymediapcadobeio-staticakamaiedge-stagingakamaihd-stagingddns-ipprivatizehealthinsurancelive-onkrellianschokokeksmassivegridmysecuritycamerarackmazeserveminecraftfrom-azis-a-geekakamaizedmoonscalecryptonomicoffice-on-theusgovtrafficmanageradobeioruntimeedgekey-stagingreserve-onlinechannelsdvrdnsdojousgovcloudappcdn77-sslapps-1and1podzoneazurewebsitesdynathomescaleforceyandexcloudvusercontentisa-geekcdn-edgescoaemalcesappwriteazimuthtlonarvonoticeablestorecomwebrecnetperotherfirminfoartslgdloncogoiltdorgmilcolcomplcschgenngonetedugovbiznamefirmmobiacincoorgmilcomnomwebgobnetintedubizinfocomyspreadshopdemongovtransurl123websitehosting-clusterkhplaycistrongsnesosvalerv\xE5lerxn--vler-qoaossandeheroysandeher\xF8yb\xF8boheroyher\xF8yxn--hery-iraxn--b-5gavalerb\xF8boxn--b-5gasandesandexn--hery-iraxn--vler-qoav\xE5lerh\xE5\xE5laahavaofsfvfhlolnlalrlhmfmtmahcostntbu\xE5strmreigersundmyspreadshopg\xE1ls\xE1eidsvolltingvollgildeskalflor\xF8vads\xF8vard\xF8vanylvenxn--bhccavuotna-k7astrandaxn--kvnangen-k0axn--sknland-fxaxn--mosjen-eyarakkestadhyllestadnannestadvevelstadvaapstenordre-landsondre-lands\xF8ndre-landxn--vrggt-xqads\xF8r-aurdalsor-aurdalheradstordmoldefordef\xF8rdeseljefedjeryggehemnexn--krehamn-dxasognegranes\xF8gnebrynetjomevallebykletokkegiskedovretj\xF8mehob\xF8lvoldasaudatolgas\xF8mnaviknad\xF8nnasomnadonnatranafrananesnaraumasmolatr\xE6nafr\xE6nalesjasm\xF8la\xF8rstaorstahitrafloraaukraloppafr\xF8yarissasnasahalsagalsaromsaraisar\xE1isafroyasn\xE5sagronghobolfjelltydal\xE5rdalardalaskimharamkraanghkekr\xE5anghkesorumbarumhurumb\xE6rums\xF8rummodums\xE1l\xE1tb\xE1l\xE1tfrognbjugnv\xE5ganvagangulenskienl\xF8tenlotenstrynvefsnxn--merker-kuaskaunsveiob\xF8mlobomloskj\xE5kvardoflorovadsosalatbalats\xE1latkl\xE6buklabuselbubarduulvikskjakkleppris\xF8rxn--nttery-byaefl\xE5eidflahofmilgolholsellomskifetvikdepvgsfhsaskerrisorhamarasnes\xE5snesr\xF8rosrorosxn--slat-5namasoynaroyvaroyluroydyroyaskoyradoyandoyrodoymeloyrad\xF8yand\xF8yr\xF8d\xF8ymel\xF8yask\xF8ylur\xF8ydyr\xF8ym\xE5s\xF8yv\xE6r\xF8yn\xE6r\xF8yhoylandeth\xF8ylandetdivtasvuodnal\xF8renskoglorenskognesoddtangenxn--tjme-hraxn--smla-hraxn--stjrdal-s1aunjargalillehammerunj\xE1rgadavvenjargaxn--bearalvhki-y4a123hjemmesidegjerdrumxn--brnnysund-m8acxn--tnsberg-q1axn--mlatvuopmi-s4axn--snsa-roaxn--skierv-utaxn--brum-voatysfjordkvafjordeidfjordkv\xE6fjordsongdalenmjondalenmj\xF8ndalenxn--gls-elackragerog\xE1\u014Bgaviikagangaviikas\xF8rreisasorreisas\xF8r-varangersor-varangerxn--risr-iraskiervaxn--frna-woaxn--trna-woakvinesdalleksvikleirvikr\xF8yrvikroyrviksvelvikvenneslaevje-og-hornnessandnessj\xF8enmarnardalvindafjordsandefjordenebakksnillfjordullensvangxn--trany-yuabr\xF8nn\xF8ysundnamsskoganaustevollxn--stjrdalshalsen-sqbnord-aurdalnord-frontr\xF8gstadtrogstadgrimstadflakstadgjerstadxn--sandy-yuaxn--leagaviika-52bnore-og-uvdalvegarsheixn--rlingen-mxaxn--ggaviika-8ya47hveg\xE5rsheikarlsoykvitsoymasfjordenhamaroyinderoyosteroydavvenj\xE1rgasauheradguovdageaidnuxn--vre-eiker-k8abronnoysiellakkr\xF8dsheradkrodsheradkvinnheradbr\xF8nn\xF8yxn--mtta-vrjjat-k7afxn--lrenskog-54akvits\xF8yv\xE1rgg\xE1toster\xF8yinder\xF8ybronnoysundxn--aurskog-hland-jnbbahccavuotnab\xE1hccavuotnagiehtavuoatnastor-elvdalmidtre-gauldalxn--gildeskl-g0akarasjokevenassixn--bievt-0qaxn--yer-znaaudnedalnlebesbynessebyxn--hbmer-xqamalselvm\xE5lselvxn--unjrga-rtam\xF8re-og-romsdalmore-og-romsdalhareidmeland\xF8rlandorlandstrand\xE5lg\xE5rdsolundalgardafjord\xE5fjorddielddanuorrikautokeinoxn--stre-toten-zcbskodjeaejriestangeliernebamblestokkefauskesn\xE5asesnaasekongsvingerlangevagberlevagxn--flor-jrahattfjelldalostre-toten\xF8stre-totenvestfoldxn--mely-ira\xE1laheadjualaheadjunordreisaxn--troms-zuaxn--lgrd-poacporsangerflatangerstavangerleikangerbremangersamnangerkarasjohkaxn--rdy-0nabfrostautsirasnoasatromsaxn--sr-aurdal-l8aflekkefjordj\xF8lsterjolsteraremarkhedmarkn\xE5\xE5mesjevuemienaamesjevuemiexn--vard-jrarollagmer\xE5kermerakerorskog\xF8rskogxn--bdddj-mrabd\xE1k\u014Boluoktaxn--osyro-wuaaknoluoktatrysilskjerv\xF8ymandaljondalbindalrindalmeldalsuldalorkdalsigdalalvdall\xE6rdalhurdalsirdalverdallerdallardaloppdal\xE5seralaseralhadselkrager\xF8divttasvuotnaoverhallasteinkjerxn--hnefoss-q1askedsmokorsettroms\xF8xn--dyry-iravestre-totenmuseumxn--sandnessjen-ogbrahkkeravjufylkesbiblb\xE1jddarbajddarxn--laheadju-7yarennes\xF8yxn--koluokta-7ya57hxn--hgebostad-g3aleirfjordstorfjordbalsfjordb\xE5tsfjordbatsfjordmuos\xE1tbiev\xE1tloab\xE1tk\xE1r\xE1\u0161johkan\xF8tter\xF8yxn--mjndalen-64anordkappl\xE1hppilahppialstahaugsiljanverranr\xF8ykenroykenhaldenlyngenbergenhortenh\xF8nefosshonefosstroandinbeiarnvarggatosoyroos\xF8yrotromsoidrettmuosatbievatruovatloabatvoagattynsetnessetxn--indery-fyask\xE1nitskanitraholtr\xE5holtxn--ystre-slidre-ujbandebusarpsborgbearduhordalandjorpelandj\xF8rpelanddeatnuringsakers\xF8r-odalsor-odalxn--slt-elabringerikenittedalnissedalhemsedalslattumsurnadalxn--blt-elabelverumstj\xF8rdalnaustdalhjartdalgj\xF8vikfyresdalhasviknarviklarvikgjovikmalvikgamviklenvikporsgrunnstjordalengerdaldrobakdr\xF8bakxn--msy-ula0hvestvagoyxn--vgan-qoaxn--ryken-vuaxn--lten-graxn--stfold-9xaxn--hpmir-xqaxn--lury-iram\xE1latvuopmimalatvuopmitysv\xE6rkirkenesbirkenesmoskenesb\xE1id\xE1rxn--fjord-lraxn--rdal-poabahcavuotnab\xE1hcavuotnaxn--frde-gralind\xE5sbearalvahkixn--hobl-irar\xE1hkker\xE1vjuxn--loabt-0qav\xE5g\xE5\xE1lt\xE1bod\xF8sundlundrader\xE5deetnetimeholeauregrueoddavagavegaranatanaarnasolasulaaltalekafusavangbergkvam\xE5mliamlifreibokntinnroangranosenoslobodor\xF8stroststat\xE5motamotivgupriv\xF8yeroyerliermossvossxn--nvuotna-hwalusterlunnermarkerh\xE1bmerhabmerhvalerfjalerxn--rholt-mratysvarbaidarfitjargaularh\xE1pmirhapmirmelhusfosnes\xF8ksnesoksnestysneshemnesevenesflesbergeidsbergtonsbergt\xF8nsberglindasxn--sndre-land-0cbnamsosxn--srum-gra\xF8ystre-slidreoystre-slidrevestre-slidretrondheimbalestrandxn--langevg-jxaaustrheimxn--skjk-soavagsoyaveroysandoykarmoyfinnoytranoyvestbytranbysykkylvenxn--hyanger-q1aspjelkavikandasuoloxn--fl-ziaxn--drbak-wuastathellexn--sr-varanger-ggbtelemarkxn--bhcavuotna-s4axn--porsgu-sta26f\u010D\xE1hcesuolocahcesuoloakrehamn\xE5krehamnsand\xF8ykarm\xF8yfinn\xF8ytran\xF8yv\xE5gs\xF8yaver\xF8ynamdalseidxn--lesund-huabadaddjaxn--vegrshei-c0axn--btsfjord-9zagildesk\xE5lporsanguxn--trgstad-r1an\xE1vuotnanavuotnahammerfestxn--sgne-graxn--brnny-wuacibestadharstadnarviikaeven\xE1\u0161\u0161ivestnesgjemnessandnesagdenesrennesoyxn--avery-yuaxn--tysvr-vrabearalv\xE1hkikongsbergspydebergrandabergxn--andy-iradavvesiidaxn--krdsherad-m8apors\xE1\u014Bgufredrikstadbjerkreimringeburennebuaurskog-holandnotteroyxn--vgsy-qoa0jxn--rmskog-byaskierv\xE1ivelandbyglandfrolandaurlandforsandxn--bjddar-ptamidsund\xE5lesundalesundfetsundfarsundovre-eiker\xF8vre-eikerakershusxn--moreke-juas\xF8rfold\xF8stfoldostfoldsorfoldh\xF8yangerhoyangerlevangerorkangertanangerxn--vestvgy-ixa6olillesandxn--rennesy-v1agranvinskjervoyxn--klbu-woalavagisxn--h-2faxn--ryrvik-byakafjordk\xE5fjordseljordfolkebiblxn--gjvik-wuajevnakerxn--kfjord-iuabudejjuxn--kranghke-b0axn--davvenjrga-y4axn--rland-uuaxn--ldingen-q1axn--mlselv-iuaxn--rady-iraxn--linds-prabrumunddalxn--ygarden-p1amo-i-ranaeidskogr\xF8mskogromskoghjelmelandxn--finny-yuaxn--sr-odal-q1axn--skjervy-v1aballangenkvanangenkv\xE6nangengratangenxn--hmmrfeasta-s4acvossevangenxn--rde-ulaxn--mli-tlaxn--ksnes-uuanordlandskanlandsk\xE5nlandsortlandfuoiskuxn--rros-graxn--hcesuolo-7ya35bxn--eveni-0qa01gagaivuotnag\xE1ivuotnaxn--seral-lradrammenmodalenmosjoenjan-mayentorskensteigengloppenxn--snes-poamatta-varjjatxn--sr-fron-q1aomasvuotnajessheimb\xE5d\xE5ddj\xE5xn--krager-gyaxn--kvfjord-nxaxn--asky-iraxn--snase-nraxn--bidr-5nacholt\xE5lenxn--vads-jraxn--jlster-byamosj\xF8enxn--rst-0nastavernxn--ostery-fyaxn--oppegrd-ixaxn--sknit-yqaxn--risa-5naoppeg\xE5rdskiptvetrendalenholtalenxn--mot-tlaxn--lhppi-xqaxn--holtlen-hxaxn--srreisa-q1akopervikxn--muost-0qaxn--bmlo-grahokksundkvalsundegersundxn--karmy-yuaullensakerxn--hylandet-54axn--kvitsy-fyaxn--bod-2nalangev\xE5gberlev\xE5gkristiansandxn--rsta-frahornindalstj\xF8rdalshalsenstjordalshalsensandnessjoenh\xE1mm\xE1rfeastaxn--lrdal-sras\xF8r-fronsor-fronnord-odalkristiansundm\xE1tta-v\xE1rjjatvestv\xE5g\xF8ynesoddennotoddenbuskerud\xF8ygardenoygardensalangenlavangenralingenr\xE6lingenlodingenl\xF8dingenlea\u014Bgaviikalaakesvuemieleangaviikaxn--srfold-byaaskvollxn--rskog-uuaxn--nry-yla5gxn--vry-yla5ghammarfeastaxn--rhkkervju-01afxn--givuotna-8yakommunekrokstadelvanedre-eikerhagebostadh\xE6gebostadxn--berlevg-jxakviteseidxn--s-1faxn--l-1faxn--nmesjevuemie-tcbafuosskomo\xE5rekemoarekexn--lt-liacxn--jrpeland-54asvalbardoppegardholmestrandtvedestrandsogndalsokndalarendalsunndalfolldalxn--krjohka-hwab49jlyngdaletnedalnorddalsaltdalgausdalskedsmovaksdalgjesdalstordalxn--frya-hraaarbortedrangedalxn--smna-graaurskog-h\xF8landxn--vg-yiabtjeldsundhaugesundlindesnesxn--mre-og-romsdal-qqbxn--dnna-gramerseineshacknetenterprisecloudmineaccomaorim\u0101oriorgmilcriiwigennetschoolhealthkiwigovtgeekxn--mori-qsacloudnsparliamentcomedorgcompronetedugovmuseumwebsitekinservicebarsywebsitebuildereerobookleapcelleero-stagetechcrscsslorigingohomecdbedeeeiemesecabgngilnlalplchfisiincnnoroptatitmtltruauhulumkdkukskjplvtrgrfrkrhrusesismycynzcznetinteduassoososcloudstgbetaaezaeuhkusjshatenadiarycdn77hoptozaptois-a-knightmyftpno-ipjpnddnssdpdnsspdnsbarsysweetpepperis-a-bruinsfanis-very-sweetservegameis-a-soxfanhomelinuxcdn77-secureservebbsmisconfusedwebredirectblogsitefreedesktopcouchpotatofriestoolforgeaccesscamis-lostreadmyblogsmall-webfedorapeopleserveftpis-a-celticsfanmywirepotagertwmailin-dslsellsyourhomeread-booksfreeddnscable-modemis-savednflfanufcfanmlbfanstuff-4-saleendoftheinternetin-vpnmy-firewallhomeftpis-localis-a-chefboldlygoingnowherewebhopselfipkicks-assroxatunkcamdvrfedoraprojectgotdnsdvrdnsdyndnspubtlspimientahomeunixdontexistfedorainfracloudmayfirstwmflabsfspagesbmoattachmentsteckidsfamilydsdnsaliasdynaliasnow-dnscloudnsdoomdnsduckdnsblogdnshomednsroutingthecloudendofinternetdsmynasip-dynamicpoivronhttpbinmyfirewallis-very-evilmysecuritycamerais-a-linux-userwmcloudis-a-geektuxfamilyis-a-candidatedoesntexistis-very-badhobby-sitegame-hostaltervistais-foundis-a-patsfandnsdojohepforgepodzonedynservcollegefanis-very-goodfrom-meis-very-niceisa-geeknerdpolacmedsldingorgcomnomgobabonetedupleskaemhlxmyboxrockyprvcydeuxfleurspdnscodebergheyflowstatichostorgmilcomnomgobneteduorgcomeduiorgmilcomngonetedugovcloudns1337ngrokacorggogfamcomwebgobnetedugokgopgkpgovgosbizpasaugumicsopozpapuwmwsrprusiskwpspkppspkmpspokeoiawsawifoumsdnskokwpmuppuppsppiwwiwoowuzswkzoschrzpisdnwzmiuwwitdpssewsseumigugimoirmpinbwinbwiihupporzgwgriwupowwskrwioswuozstarostwokonsulattmpccopruszkowmyspreadshopostrodakartuzyopolegminamediaustkazgorajgoraolawailawalomzawloclradombytomjaworznotargilubinkoninzagantorunkutnokepnonakloczestsopotsanokturekplockslasksklepzarowlukowmedaidgdaorgmilrelcomnomatmgsmartneteduelkgovwawsossexbiztgorysejnytychypomorzeboleslawiechomesklepsdscloudunicloudzakopanelegnicarawa-mazbydgoszczswidnikkrasnikwloclawekbielawamragowograjeworealestatebeskidykaszubymalopolskaprzeworskswiebodzinlecznadfirmaszkolawarmiagdyniamiastakazimierz-dolnymalborkswidnicadlugolekaostrolekapodlasieelblagtravelsimplesitezachpomormielecszczecinnieruchomosciwalbrzychlezajsklublinbedzinpoznanwielunmielnooleckostarachowicedkontopowiatwroclawrybniksuwalkileborkslupskgdanskostrowwlkptarnobrzegtourismwegrowkrakowglogowyou2pilanysamailwrocinfoagroautobeepshopprivlapypiszlodzcfolksecommerce-shopmazurypulawyskoczowrzeszowpomorskiezgierzkaliszolkuszlowiczostrowiecsosnowiecmazowszewodzislawbialowiezazgorzeleckatowicepabianicejelenia-gorawolominkarpaczsieradznowarudaczeladzkonskowolaskierniewiceswinoujscieturystykabieszczadycieszynketrzynolsztynbialystokbabia-goraprochowicewarszawastalowa-wolapolkowicegorlicegliwiceponiatowalimanowalubartowaugustowkobierzyceopocznognieznoszczytnokolobrzegshoparenapodhalebielskoklodzkostargardatwithplayitownnamecoorgnetedugovacorgcomproestnetedugovbiznameislaprofinforechtngrokmedaaaacacpaenglawjurbarbarsykeeneticavocatacctcloudnsorgcomsecplonetedugov123paginaweborgcomnetintedugovnomepublidkinbarsygovx443cloudnsorgmilcomnetedugovcooporgmilcomschnetedugovnamecomcannetlibassoaemclantmcontstoreorgcomnomrecwwwbarsyfirminfoshopartsstackitmyddnswebspacelima-cityacincooxorgedugovbarsybrendlyhbvpsvpsspectrumlandinghostingacppmordoviamcprecbgorgmilcomspbnetintedumsknovgovbirrasmcdirmytismircloudvladimirnalchikadygeyamarinepyatigorskmyjinobashkiriaeurodirvladikavkazna4ugroznykustanaikalmykiacldmaildagestaniranbuildcanvaliaravalwixdevelopmentappwritemigrationneedleverceldatabasestackitcodereplravendbonporterlovableaccoorgmilnetgovcoopmedorgcompubschnetedugovservicemecoorggovtvmedorgcomnetedugovinfoedgfacbmlonihkutwpsryxzbdtmacfhppmyspreadshopbrandpartiorgcomfhvpress123minsidaitcouldbeworlanbibkommunalforbundfhskiopsyskomvuxkomforbnaturbruksgymnloginlineorgcomnetedugovenscaledeuusentbotdaorgmilcomnetgovnowteleporthashbangplatformlovablebarsyshopwarebasehoplixbarsyonlinemsf5gitappgitpagecofigma-govcaffeinefigmacanvasoltstbarsysupportchatgptsquareomniweopensocialcpanelnotionnovecorewpsquaredpreviewjelecyonbyensrhtfastvpspieboxconvexjouwwebheyflowplatformshloginlinemadethissourcecraftclouderaorgorgcomartedugouvunivmeorgcomnetedugovsurveysstatichfheiyuxs4allprojectmyfastubervibehostapp-ionosdeployagentmecoorgcomschnetedugovbizcncostoreorgmilcomneteduembaixadaconsuladokiraranohoprincipesaotomeheliohobarsystorebaseshopwaresellfyabkhaziavologdamordoviapenzalenugsochinavoiexnetspbmsknovnorth-kazakhstanashgabadkareliaarmeniageorgiavladimirnalchikivanovobukharaadygeyakhakassiakalugakrasnodarjambylaktyubinsktroitskbryanskobninskkurganazerbaijanpokrovskbashkiriatselinogradvladikavkazmurmansktulatuvamangyshlaktashkentchimkentgroznykaragandatermezarkhangelskkustanaikalmykiabalashoveast-kazakhstankaracoldagestantogliattibarsyredorgcomgobedumirenknightpointaccoorgjelasticdiscoursecleverappsschacmiincogoornetonlineshopaccogoorgmilcomwebnicnetintedugovbiznametestcoorgmilcomnomnetedugovorangecloudpersoindorgcomfinnatnetgovensmincomtourismintlinfox0611oyaorgmilcomnetedugovquickconnectvpnplusnettprequalifymeaddrmyaddrntdllwadlnctvavdrk12orgmilpolbeltelcomwebgennetedutskkepgovbbsbiznameinfocoorgmilcompronetedugovbiznameinfobetter-thanworse-thansakurafromdyndnson-the-webmymailerorgmilurlcomneteduidvgovmydnsgameclubebizmeneacsccogotvorhotelmilmobiinfovodteiflgplkmsmsbcckhincndnvncoztltmkckppzpdprvcvkvlvcrkrkscxuzchernovtsyrivneyaltaodesavolynrovnolutskltdinforgcomnetedugovbizvinnicazhitomirternopilpoltavakropyvnytskyizaporizhzhiasevastopolsebastopoluzhgoroduzhhorodkharkovkharkivvinnytsiakhmelnytskyizaporizhzhecrimeaodessazhytomyrnikolaevcherkassydonetskluganskluhanskkirovogradivano-frankivskchernivtsikrymkievkyivlvivsumyzakarpattiamykolaivcherkasychernigovkhersonchernihivdnipropetrovskdnepropetrovskkhmelnitskiyneacsccogoorusorgmilcomedugovvmdhmyspreadshopadimono-ipbarsybytemarkbarsyonlinelayershiftnh-servretrosnubapicampaignservicelugaffinitylotteryweeklylotteryraffleentrygluglugsmeaccoindependent-inquestnimsitecopropymntltdorgplcschnetgovnhsbarsyindependent-commissionindependent-reviewpolicepublic-inquiryindependent-panelconnhospindependent-inquiryroyal-commissionoraclegovcloudappscck12libccphxcclibpvtparochchtrcck12libcceatonk12coglibtecgendstmusann-arborwashtenawcck12glghcck12sealibforksolympiabainbridge-islkeyporthoquiamyarrow-pointcentraliaport-townsendsequimport-ludlowrentonsilverdalebremertonredmondsheltonbellevueport-orchardport-angeleskingstonchehalisaberdeengig-harborseattlepoulsboidmdndsddemenegacalamaiavawapailalflnmdcncscohnhmihiviwiriinmntnmocoutvtctmtgunjokakwvnvprarorasmskstxwynykyazisadninsnngosrvis-bymircloudservernamepointtoenscaledland-4-salefreeddnsstuff-4-saleazure-apinoipcloudnsgolffanheliohostazurewebsitesgvorgmilcomgubneteducoorgcomnetd0egvorgmilcomnetedugovmydnsiacostoree12orgmilcomnomwebgobbibrectecnetintedugovraremprendefirminfoartseducok12orgcomnethidnsidacaiiosonlahanamhanoicamauhueorgcompronetintedugovbizbacninhtayninhhoabinhnamdinhtravinhhaiphongvinhlonghaiduongquangnamquangtrithuathienhuequangninhbacgianghaugiangquangbinhsoctrangbentrethanhphohochiminhdanangkontumhatinhkhanhhoathanhhoahealthgialailaocaiyenbaibackanngheanlonganphuyenphuthocanthodaklakdongnainameinfovinhphucdongthapkiengiangtiengiangquangngailaichaulangsonlamdongdaknonghagiangangiangcaobangbinhduongninhthuanbinhthuanbaclieuthaibinhninhbinhbinhdinhtuyenquanghungyenbaria-vungtauthainguyendienbienbinhphuocschbizimagine-proxyorgcomnetedugovcloud66advisormypetsdyndnsxn--8dbq2axn--4dbgdty6cxn--5dbhl8dxn--hebda8bxn--80auxn--d1atxn--c1avgxn--o1acxn--o1achxn--90azhxn--55qx5dxn--uc0atvxn--od0algxn--wcvs22dxn--gmqw5axn--mxtq1mxn--12c1fe0brxn--h3cuzk1dixn--12co0c3b4evaxn--12cfi8ixb8lxn--o3cyx2axn--m3ch0j3axn--j1adpxn--90amcxn--90a1afxn--h1ahnxn--j1ael8bxn--h1alizxn--c1avgxn--j1aefxn--80aaa0cvacxn--41acaffeineexeopentunnelbotdashtelebitorgtmaccoagricorgmilnomwebnicngonetaltedugovlawnisschoolgrondaraccoorgmilcomschnetedugovbizinfoprg1-zeropstritonstackitlimazeropsaccoorgmilgov\u044F\u0441\u043F\u0431\u043E\u0440\u0433\u043A\u043E\u043C\u043C\u0441\u043A\u0431\u0438\u0437\u043C\u0438\u0440\u0441\u0430\u043C\u0430\u0440\u0430\u043A\u0440\u044B\u043C\u0441\u043E\u0447\u0438\u0430\u043A\u043E\u0434\u043F\u0440\u043E\u0440\u0433\u043E\u0431\u0440\u0443\u043F\u0440\u05E6\u05D4\u05DC\u05DE\u05DE\u05E9\u05DC\u05D9\u05E9\u05D5\u05D1\u05D0\u05E7\u05D3\u05DE\u05D9\u05D4\u0E2D\u0E07\u0E04\u0E4C\u0E01\u0E23\u0E18\u0E38\u0E23\u0E01\u0E34\u0E08\u0E23\u0E31\u0E10\u0E1A\u0E32\u0E25\u0E28\u0E36\u0E01\u0E29\u0E32\u0E17\u0E2B\u0E32\u0E23\u0E40\u0E19\u0E47\u0E15\u6559\u80B2\u7DB2\u7D61\u7D44\u7E54\u516C\u53F8\u653F\u5E9C\u500B\u4EBA\uB2F7\uB137\uD55C\uAD6D\u6FB3\u95E8\u65B0\u95FB\u6FB3\u9580\u8054\u901A\u5BB6\u96FB\u5609\u91CC\u62DB\u8058\u901A\u8CA9\uB2F7\uCEF4\uC0BC\uC131\u30B3\u30E0\u10D2\u10D4\u0431\u0433\u0440\u0444\u0435\u044Eadcdbdgdidmdsdtdaebedeeegeiejekemenepereseveyegabacalamanauavapaqasazacfbfafgfnfpfwftfbgcgagggegkgngmgsgpgvgtgugilmlnlalclglplsltlhmimjmkmmmomambmcmdmfmgmzmpmsmtmgbbblbsbecccacnclcmcvctcscmhkhghchbhthphshlinikifigiaibicivisikninhnmncnbngnsnpnvntnjoionomobocoaofodorosotoptstttytatbtetgtithtmtltrusuvuaucueuguhulumunufjdjbjtjsjlkmkhkfkdkcktkukskpkgpmpnpkpjpgqaqmqiqsvtvcvbvmvlvrwpwtwzwbwcwawgwkwmwtrsrprgrfrercrbrarnrmrlrkrirhrwsusrssspsgsesbsaslsmsissxmxaxcxuypysylymykygybycyuztzsznzmzkzdzczbzaz\u03B5\u03BB\u03B5\u03C5\u4E16\u754C\u53F0\u7063\u8D2D\u7269\u516C\u76CA\u70B9\u770B\u81FA\u7063\u7F51\u7EDC\u66F8\u7C4D\u5728\u7EBF\u7F51\u7AD9\u624B\u673A\u673A\u6784\u5927\u62FF\u6E38\u620F\u4FE1\u606F\u53F0\u6E7E\u8C37\u6B4C\u6148\u5584\u5546\u6807\u9999\u6E2F\u4E2D\u56FD\u9910\u5385\u7F51\u5740\u4E2D\u570B\u5546\u57CE\u98DF\u54C1\u5FAE\u535A\u653F\u52A1\u79FB\u52A8\u96C6\u56E2\u516C\u53F8\u516B\u5366\u5546\u5E97\u5065\u5EB7\u7F51\u5E97\u653F\u5E9C\u65F6\u5C1A\u4F5B\u5C71\u4E2D\u4FE1\u5A31\u4E50\u5E7F\u4E1C\u4F01\u4E1Ahomedepotengineering\u0627\u0645\u0627\u0631\u0627\u062Arepublicankuokgroupversicherungchannelcitadelxn--pgbs0dhxn--b4w605ferdstatebankwebsitexn--mgb9awbf\u4E9A\u9A6C\u900A\u6DE1\u9A6C\u9521alibabaxn--ngbc5azdxn--mgbbh1axn--45br5cyltoshibabuildworldcloudtradeguideplacespacedancemoviephoneprimesmilebiblestyleappleazurestoreskypegripexn--l1accdrivelottehorsehouseleasechasereisestadahondaomegaaetnaamicaninjanokiamediadeltavodkaedekaosakapizzaslingemailgmailtirolshelltmallfinallegaltotalhotelamfamforumrehabmusicciticricohcoachwatchboschearthfaithirishmiamiarchidubaiguccipraxi\u307F\u3093\u306A\u30B9\u30C8\u30A2\u30BB\u30FC\u30EBcanonsalononionnikonepsonkoelngreensevencrownikanoradioaudioweiboglobopromogalloyahoociscorodeovideomangobingotokyovolvolottokyotophotosmartsportquesttrusthyattjetztadultcymrubaidutushuxn--kprw13dubankclickblackmerckgroupsharpcheapnowtvxn--h2brj9c\u05E7\u05D5\u05DD\u0570\u0561\u0575\u043E\u0440\u0433\u0441\u0440\u0431\u043C\u043E\u043D\u043A\u043E\u043C\u0431\u0435\u043B\u043C\u043A\u0434\u049B\u0430\u0437\u0440\u0443\u0441\u0443\u043A\u0440\u0645\u0635\u0631\u0642\u0637\u0631\u0639\u0631\u0628\u0643\u0648\u0645dadcfdmedwedredphdthdbidpidkrdmsdltdiceonewmeglemoerwecfageacbanbambaaaammakianraspacpaaxawtfbcgaegongingaigvigorgdogdhlmilrilonlaolloluoljllcalgalnflafltelsrlfrllplkimibmcamcombommomifmabbjcbscbcabnabtabmlbpubabcbbcnecincpncllcstcwtcpwcnyckfhbzhovhmoiskiobisbitcifyituipinvinwinxincbnbcnmanfangdnmenrenkpnmtnyunrunfununobiojioriohbogmofooboooooacoecoceongoproartistottnttbbtcateatlatvetpetbetnethktmitfitintjothotgotdotbotprueduicujnjyouinknhktdkappsapgapmapdnptopgopllpjmpzipvipripesqtrvdtvitvdevmovgovhivnrwlawsewnewbmwwownowhowdvrftrmtrsfrbarcartvscrseusawsupsubssbsadsddsldssasbmsmlsxxxboxfoxgmxtjxsextaxbuyflydiysoyjoyskypaydaygayxyzanzbizwebersenerpokerlameractortatarsolar\u0EA5\u0EB2\u0EA7\u0E04\u0E2D\u0E21\u0E44\u0E17\u0E22tourslocusnexuslexusgiftsbeatsboatspartspressglassswiss\u0915\u0949\u092E\u0928\u0947\u091Ftiresgivescodeshomesgamestunesshoescardswalesloansvegastoolsdealsautosparis\u30D5\u30A1\u30C3\u30B7\u30E7\u30F3workssucksrocksxeroxforexfedexpartylillymoneystudyrugbytoraytoday\u4E2D\u6587\u7F51xn--unup4y\u5929\u4E3B\u6559\u98DE\u5229\u6D66\u65B0\u52A0\u5761enterprises\u6211\u7231\u4F60\u5609\u91CC\u5927\u9152\u5E97christmasxn--fct429kholdingsxn--8y0a063axn--mgbx4cd0ablifestyleabogadoallstatenetbank\u0643\u0627\u062B\u0648\u0644\u064A\u0643xn--s9brj9cxn--gk3at1ebestbuycharityxn--55qx5dmicrosoftpropertybasketballhomegoodscorsicajewelrygallerygrocerysurgerycountrybrusselsverisignferreroxn--czr694bhdfcbankcommbanksoftbank\u067E\u0627\u0643\u0633\u062A\u0627\u0646\u067E\u0627\u06A9\u0633\u062A\u0627\u0646nextdirect\u0627\u0644\u0633\u0639\u0648\u062F\u064A\u0647\u0627\u0644\u0639\u0644\u064A\u0627\u0646xn--h2brj9c8cxn--80adxhksshikshaxn--mgbai9azgqp6jcuisinellabarclayscatholicxn--kpry57dcompanyxn--xhq521bblackfridayxn--mgba3a3ejtsandvikxn--d1acj3bacademydownload\u0645\u0644\u064A\u0633\u064A\u0627xn--j1amhxn--w4r85el8fhu5dnraipirangaathletaxn--fhbeixn--mgbqly7cvafrzuerichxn--c2br7g\u0B87\u0BB2\u0B99\u0BCD\u0B95\u0BC8contractorsxn--io0a7igraphicsinsurancetemasekxn--xkc2al3hye2amotorcyclesphotographydirectoryplumbingxn--vhquvclothingtrainingcleaningwilliamhilllightingxn--mgba3a4f16ashoppingcateringeducationokinawapicturesventuresproductionsxn--9et52uwalmart\u0D2D\u0D3E\u0D30\u0D24\u0D02supportrealestatecapitalonexn--nqv7fs00emaauspostfloristdentistxn--qxamgodaddybradescobargainsmitsubishikerryhotelsxn--9dbq2axn--3pxu8kimmobilienxn--fjq720axn--mgbtx2bholidaymckinseymadridbusinessbuildershelsinkixn--4gbrim\u043C\u043E\u0441\u043A\u0432\u0430\u0627\u0644\u0633\u0639\u0648\u062F\u06CC\u0629coffeedegreelacaixapartnersalsaceofficeabbvievoyageorangegeorgeonlinechromemobilekindlegoogleoraclecircleschulesecureinsurexn--mgba7c0bbn0aestatexn--mgbc0a9azcgcruisehangoutxn--vuq861bxn--42c2d9arexrothfirestoneuniversityxn--nnx388alifeinsuranceextraspace\u043E\u043D\u043B\u0430\u0439\u043Dverm\xF6gensberatersoftwarexn--fiqs8sxn--mgbab2bdxn--w4rs40ltienda\u092D\u093E\u0930\u0924\u092E\u094Dafricatoyotaotsukasakuracameracreditcardnagoyaconsultingnetworkjunipertheatermonsterprogressivepioneerxn--55qw42gracingdatingvotingvikinglivinggivingxn--bck1b9a5dre4cbrotherweatherjoburg\u0641\u0644\u0633\u0637\u064A\u0646lplfinancialxn--clchc0ea0b2g2a9gcdfutbolschoolsocialglobaldentalwoodsidechanelairtelmatteltravelrealtorwebcamstream\u0C2D\u0C3E\u0C30\u0C24\u0C4Dunicomalstomxn--nodexn--6frz82gmuseumfurniturexn--rvc1e0am3exn--mix891faccenturexn--11b4c3dismailineustardiscountquebeccomsecclinicservicesxn--y9a3aqxn--c1avgswatchchurchsearch\u0627\u0644\u0627\u0631\u062F\u0646marketingcontacthealthmonashshoujisanofitaipeiamericanexpresssuzuki\u30A2\u30DE\u30BE\u30F3\u30AF\u30E9\u30A6\u30C9\u30DD\u30A4\u30F3\u30C8bharti\u30B0\u30FC\u30B0\u30EBxn--mgberp4a5d4armemorialxn--1qqw23alondonmormoninstitutevisionbostonnortoncouponmaisonamazonvirginberlindesigndurbanolayannissananquanxihuanhitachikaufengardenreisenbayerntechnologydatsunxn--90a3aclatinocasinostudiophysioxn--ngbe9e0apharmacytattootaobaoaramcoexpertreportabbottdirectselectimamatfairwindspictettargetmarketintuittravelersinsurancecreditdupontryukyusuppliesxn--tckwebnpparibasschmidtmerckmsdyodobashirestaurantbridgestonecricketxn--fpcrj9c3dbostikbroadwayattorneylefrakemerckxn--fiq228c5hscareersfarmerswinnersflowersxn--wgbh1cguitarsxn--54b7fta0ccxn--p1acfmakeupgalluplandroverxn--kcrx77d1x4agoldpointbauhausxn--mgbayh7gpahiphopplaystationxn--mgba3a4fraxn--eckvdtc9dhyundaixn--gckr3f0fistanbulticketsmarketsflightschintaireviewsxn--3e0b707ewindowsxn--fiqz9sfinancialxn--fzys8d69uvgm\u0627\u0628\u0648\u0638\u0628\u064Adiscoverreview\u09AC\u09BE\u0982\u09B2\u09BExn--5su34j936bgsgmoscowobserverapartments\u0434\u0435\u0442\u0438\u0627\u0631\u0627\u0645\u0643\u0648\u0441\u0430\u0439\u0442eurovisionxn--i1b6b1a6a2exn--xkc2dl3a5ee0h\u062A\u0648\u0646\u0633\u0645\u0648\u0642\u0639\u0628\u0627\u0631\u062A\u0680\u0627\u0631\u062A\u0634\u0628\u0643\u0629\u0639\u0645\u0627\u0646\u0628\u064A\u062A\u0643\u0639\u0631\u0627\u0642readkredbondlandbandfundfoodprodgoldfordtubecafesafelifeggeeieeefreefagepagegugezonewinememenamegamesaleablebikenikelikecarecbreherefiresaveloveliveblueartedatesitevotecaseluxebofamodaltdaasdatiaayogasinavanashiaasiajavabbvatevavivadatazaraarpacasavisasncfprofmaifsurfgolfdvagsongbingpingwangkpmggoogblogpohlfailcooldellcalldeallidlsarlfilmteamroomfarmimdbarabclubhdfcicbchsbcgmbhrichtechfishdishcashminiernikddiaudiwikimobitaxicitikiwidesiqponskinloanakdnwienopenporncerntownimmolimoolloinfonicofidolegosaxozeroaerovivoautovotomotofastbestresthostpostnextlgbtchatseatgiftmeetdietreitmintrentgentspotscotguruitausohumenucyoubanklinkpinkdclktalksilkbookseekworkrsvpaarpjeepshopcoophelpcamppccwshowbeerstarruhrflirweirhaircarsparsjprshausplusnewstipstoysjobskidsfanspicsdocsxboxamexsexynavycitysonyarmyallybabyplaydeliverybuzzgbizlamborghiniphilips\u0DBD\u0D82\u0D9A\u0DCF\u0CAD\u0CBE\u0CB0\u0CA4fitnessexpresslanxesspfizercenterwalterlawyersoccercareerkosherbrokerlockerdealerdoctorauthorxn--mgbqly7c0a67fbcverm\xF6gensberatungjaguarxn--pssy2uxn--hxt814eflickrrepairrogersairbusxn--mgbai9a5eva00beventsyachtsxn--t60b56a\u09AD\u09BE\u09F0\u09A4\u09AD\u09BE\u09B0\u09A4\u092D\u093E\u0930\u0924\u092D\u093E\u0930\u094B\u0924viajeshermeshughesxn--j1aef\u0938\u0902\u0917\u0920\u0928villas\u0B2D\u0B3E\u0B30\u0B24claimshotels\u0AAD\u0ABE\u0AB0\u0AA4zapposphotosjuegoscondostatamotorsgratistennis\u0A2D\u0A3E\u0A30\u0A24tkmaxxtjmaxxschaeffleryandexxn--80aswgrealtysafetybeautyluxuryxn--3ds443gsupplyfamilyxn--o3cw4hhockeysydneyxn--90aenissayalipayenergycomputeragencyxn--rovu88b\u96FB\u8A0A\u76C8\u79D1xn--gecrj9cstatefarmaccountantaquarelleolayangroup\u9999\u683C\u91CC\u62C9xn--p1ai\u7EC4\u7EC7\u673A\u6784xn--1ck2e1bxn--mgbt3dhdschwarz\u0645\u0648\u0631\u064A\u062A\u0627\u0646\u064A\u0627abudhabinowruzkomatsufujitsuhospitalxn--80asehdbxn--mgbtf8flxn--j6w193gxn--yfro4i67oprudentialxn--flw351ecruisescoursesrecipesxn--e1a4cferrarixn--ses554gxn--wgbl6awatchesstaplessinglesxn--mgbcpq6gpa1axn--otu796dpropertiescreditunionxn--mgbah1a3hjkrdstockholmhisamitsu\u0627\u0644\u0633\u0639\u0648\u062F\u064A\u0629stcgroupdomainsoriginscouponsbloombergclubmedfroganslimitedxn--80aqecdr1aexposedinternationalequipmentbarclaycardxn--q7ce6axn--mgbi4ecexpprotectionassociatesconstructionxn--cck2b3bxn--45q11candroidfoundation\u05D9\u05E9\u05E8\u05D0\u05DCxn--mgbca7dzdocliniqueboutiqueengineerxn--qxa6asystemsfirmdalefashionauctionxn--nqv7finfinitirentalsreliancetradingweddingfishinghostinggentingbookingcookingxn--3hcrj9cgraingerxn--czrs0tdemocratsamsungyokohamaxn--h2breg3evexn--nyqy26alundbeckmelbournevacationssolutionsfrontierxn--vermgensberatung-pwbmanagementxn--cg4bkixn--mgb2ddeslincolnhamburgsandvikcoromantblockbusterairforcebarefootxn--4dbrk0ceinvestmentsfeedbackcommunityxn--ngbrx\u0627\u0644\u0628\u062D\u0631\u064A\u0646diamondsamsterdamhealthcareredumbrellaxn--mxtq1mxn--2scrj9cagakhanxn--mgbpl2fh\u043A\u0430\u0442\u043E\u043B\u0438\u043Acaravan\u0B9A\u0BBF\u0B99\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0BC2\u0BB0\u0BCDrichardlimortgageamericanfamilyxn--fzc2c9e2cscholarshipssaarlandxn--imr513nvlaanderensamsclubgoodyearkitchen\u0B87\u0BA8\u0BCD\u0BA4\u0BBF\u0BAF\u0BBEweatherchannelallfinanzxn--kput3i\u0627\u0644\u0633\u0639\u0648\u062F\u06CC\u06C3xn--90aisxn--efvy88h\u0627\u0644\u062C\u0632\u0627\u0626\u0631xn--mgbaam7a8hexchangejpmorganxn--tiq49xqyjfidelitysecurityxn--mk1bu44cwanggouxn--fiq64bxn--6qq986b3xlxn--mgbbh1a71exn--80ao21amarshallsxn--5tzm5gtravelerspanasoniclatrobeyoutubeaccountantsxn--rhqv96gxn--cckwcxetdanalyticsxn--ygbi2ammx\u0628\u0627\u0632\u0627\u0631\u0628\u06BE\u0627\u0631\u062A\u0633\u0648\u0631\u064A\u0629organicfresenius\u0633\u0648\u0631\u064A\u0627xn--9krt00axn--qcka1pmcxn--jlq480n2rgdeloittesciencefinancexn--jvr189mxn--30rr7yhomesensehotmailbaseballfootballleclercboehringerxn--q9jyb4cxn--mix082f\u0627\u0644\u064A\u0645\u0646\u0647\u0645\u0631\u0627\u0647politie\u0633\u0648\u062F\u0627\u0646\u0627\u064A\u0631\u0627\u0646\u0627\u06CC\u0631\u0627\u0646netflixyamaxunxn--lgbbat1ad8jcollegestoragecapetowncolognekerrypropertiesxn--mgbgu82axn--ogbpf8flxn--czru2dwhoswhociprianilasallexn--g2xx48cforsalebanamexaudiblexn--vermgensberater-ctbxn--zfr164bericssonvanguardxn--45brj9cindustriestheatremarriottxn--3bst00mcomparexn--mgberp4a5d4a87gcapitaldigital\u0627\u0644\u0645\u063A\u0631\u0628barcelonashangrilaxn--d1alfcalvinkleinwwwcitysapporokawasakinagoyasendaikobekitakyushuyokohamackjp";
50212
+ var rulesRoot = 617;
50213
+ var exceptionsRoot = 621;
50214
+ var numberOfNodes = nodeFlags.length;
50215
+ var numberOfEdges = edgeLength.length;
50216
+ var edgeOffset = new Uint32Array(numberOfEdges);
50217
+ var edgeHash = new Uint32Array(numberOfEdges);
50218
+ var wildcardEdge = new Int32Array(numberOfNodes).fill(-1);
50219
+ for (let node = 0, offset = 0; node < numberOfNodes; node += 1) {
50220
+ for (let edge = edgeStart[node]; edge < edgeStart[node + 1]; edge += 1) {
50221
+ edgeOffset[edge] = offset;
50222
+ const end = offset + edgeLength[edge];
50223
+ let hash = 5381;
50224
+ for (let i = end - 1; i >= offset; i -= 1) {
50225
+ hash = hash * 33 ^ labelText.charCodeAt(i);
50226
+ }
50227
+ edgeHash[edge] = hash >>> 0;
50228
+ if (edgeLength[edge] === 1 && labelText.charCodeAt(offset) === 42) {
50229
+ wildcardEdge[node] = edge;
50230
+ }
50231
+ offset = end;
50232
+ }
50233
+ }
50234
+ var matchNode = -1;
50235
+ var matchStart = 0;
50236
+ var matchEnd = 0;
50237
+ function labelEquals(edge, hostname2, start, length) {
50238
+ if (edgeLength[edge] !== length) {
50239
+ return false;
50240
+ }
50241
+ const offset = edgeOffset[edge];
50242
+ for (let i = 0; i < length; i += 1) {
50243
+ if (labelText.charCodeAt(offset + i) !== hostname2.charCodeAt(start + i)) {
50244
+ return false;
50245
+ }
50246
+ }
50247
+ return true;
50248
+ }
50249
+ function findEdge(node, hash, hostname2, start, length) {
50250
+ let lo = edgeStart[node];
50251
+ let hi = edgeStart[node + 1];
50252
+ while (lo < hi) {
50253
+ const mid = lo + hi >>> 1;
50254
+ const value = edgeHash[mid];
50255
+ if (value < hash) {
50256
+ lo = mid + 1;
50257
+ } else if (value > hash) {
50258
+ hi = mid;
50259
+ } else {
50260
+ for (let e = mid; e >= lo && edgeHash[e] === hash; e -= 1) {
50261
+ if (labelEquals(e, hostname2, start, length))
50262
+ return e;
50263
+ }
50264
+ for (let e = mid + 1; e < hi && edgeHash[e] === hash; e += 1) {
50265
+ if (labelEquals(e, hostname2, start, length))
50266
+ return e;
50267
+ }
50268
+ return -1;
50269
+ }
50270
+ }
50271
+ return -1;
50272
+ }
50273
+ function walk2(hostname2, root, allowedMask) {
50274
+ let node = root;
50275
+ let end = hostname2.length;
50276
+ let hash = 5381;
50277
+ matchNode = -1;
50278
+ for (let i = hostname2.length - 1; i >= 0; i -= 1) {
50279
+ const code = hostname2.charCodeAt(i);
50280
+ if (code === 46) {
50281
+ const start = i + 1;
50282
+ let edge2 = findEdge(node, hash >>> 0, hostname2, start, end - start);
50283
+ if (edge2 === -1) {
50284
+ edge2 = wildcardEdge[node];
50285
+ }
50286
+ if (edge2 === -1) {
50287
+ return matchNode !== -1;
50288
+ }
50289
+ node = edgeChild[edge2];
50290
+ if ((nodeFlags[node] & allowedMask) !== 0) {
50291
+ matchNode = node;
50292
+ matchStart = start;
50293
+ matchEnd = end;
50294
+ }
50295
+ end = i;
50296
+ hash = 5381;
50297
+ } else {
50298
+ hash = hash * 33 ^ code;
50299
+ }
50300
+ }
50301
+ let edge = findEdge(node, hash >>> 0, hostname2, 0, end);
50302
+ if (edge === -1) {
50303
+ edge = wildcardEdge[node];
50304
+ }
50305
+ if (edge !== -1) {
50306
+ node = edgeChild[edge];
50307
+ if ((nodeFlags[node] & allowedMask) !== 0) {
50308
+ matchNode = node;
50309
+ matchStart = 0;
50310
+ matchEnd = end;
50311
+ }
50312
+ }
50313
+ return matchNode !== -1;
50314
+ }
50315
+ function suffixLookup(hostname2, options, out) {
50316
+ if (fastPathLookup(hostname2, options, out)) {
50317
+ return;
50318
+ }
50319
+ const allowedMask = (options.allowPrivateDomains ? 2 : 0) | (options.allowIcannDomains ? 1 : 0);
50320
+ if (walk2(hostname2, exceptionsRoot, allowedMask)) {
50321
+ out.isIcann = (nodeFlags[matchNode] & 1) !== 0;
50322
+ out.isPrivate = (nodeFlags[matchNode] & 2) !== 0;
50323
+ out.publicSuffix = hostname2.slice(matchEnd + 1);
50324
+ return;
50325
+ }
50326
+ if (walk2(hostname2, rulesRoot, allowedMask)) {
50327
+ out.isIcann = (nodeFlags[matchNode] & 1) !== 0;
50328
+ out.isPrivate = (nodeFlags[matchNode] & 2) !== 0;
50329
+ out.publicSuffix = hostname2.slice(matchStart);
50330
+ return;
50331
+ }
50332
+ out.isIcann = false;
50333
+ out.isPrivate = false;
50334
+ const lastDot = hostname2.lastIndexOf(".");
50335
+ out.publicSuffix = lastDot === -1 ? hostname2 : hostname2.slice(lastDot + 1);
50336
+ }
50337
+ var RESULT = getEmptyResult();
50338
+ function parse2(url, options) {
50339
+ return parseImpl(url, 5, suffixLookup, options, getEmptyResult());
50340
+ }
50341
+ function getHostname(url, options) {
50342
+ resetResult(RESULT);
50343
+ return parseImpl(url, 0, suffixLookup, options, RESULT).hostname;
50344
+ }
50345
+ function getPublicSuffix2(url, options) {
50346
+ resetResult(RESULT);
50347
+ return parseImpl(url, 2, suffixLookup, options, RESULT).publicSuffix;
50348
+ }
50349
+ function getDomain2(url, options) {
50350
+ resetResult(RESULT);
50351
+ return parseImpl(url, 3, suffixLookup, options, RESULT).domain;
50352
+ }
50353
+ function getFullDomain(url, options) {
50354
+ resetResult(RESULT);
50355
+ const result = parseImpl(url, 3, suffixLookup, options, RESULT);
50356
+ return result.domain === null ? null : result.hostname;
50357
+ }
50358
+ function getSubdomain(url, options) {
50359
+ resetResult(RESULT);
50360
+ return parseImpl(url, 4, suffixLookup, options, RESULT).subdomain;
50361
+ }
50362
+ function getDomainWithoutSuffix(url, options) {
50363
+ resetResult(RESULT);
50364
+ return parseImpl(url, 5, suffixLookup, options, RESULT).domainWithoutSuffix;
50365
+ }
50366
+ exports.getDomain = getDomain2;
50367
+ exports.getDomainWithoutSuffix = getDomainWithoutSuffix;
50368
+ exports.getFullDomain = getFullDomain;
50369
+ exports.getHostname = getHostname;
50370
+ exports.getPublicSuffix = getPublicSuffix2;
50371
+ exports.getSubdomain = getSubdomain;
50372
+ exports.parse = parse2;
50373
+ }
50374
+ });
50375
+
50376
+ // ../../node_modules/tough-cookie/dist/index.js
50377
+ function pathMatch(reqPath, cookiePath) {
50378
+ if (cookiePath === reqPath) {
50379
+ return true;
50380
+ }
50381
+ const idx = reqPath.indexOf(cookiePath);
50382
+ if (idx === 0) {
50383
+ if (cookiePath[cookiePath.length - 1] === "/") {
50384
+ return true;
50385
+ }
50386
+ if (reqPath.startsWith(cookiePath) && reqPath[cookiePath.length] === "/") {
50387
+ return true;
50388
+ }
50389
+ }
50390
+ return false;
50391
+ }
50392
+ function getPublicSuffix(domain, options = {}) {
50393
+ options = { ...defaultGetPublicSuffixOptions, ...options };
50394
+ const domainParts = domain.split(".");
50395
+ const topLevelDomain = domainParts[domainParts.length - 1];
50396
+ const allowSpecialUseDomain = !!options.allowSpecialUseDomain;
50397
+ const ignoreError = !!options.ignoreError;
50398
+ if (allowSpecialUseDomain && topLevelDomain !== void 0 && SPECIAL_USE_DOMAINS.includes(topLevelDomain)) {
50399
+ if (domainParts.length > 1) {
50400
+ const secondLevelDomain = domainParts[domainParts.length - 2];
50401
+ return `${secondLevelDomain}.${topLevelDomain}`;
50402
+ } else if (SPECIAL_TREATMENT_DOMAINS.includes(topLevelDomain)) {
50403
+ return topLevelDomain;
50404
+ }
50405
+ }
50406
+ if (!ignoreError && topLevelDomain !== void 0 && SPECIAL_USE_DOMAINS.includes(topLevelDomain)) {
50407
+ throw new Error(
50408
+ `Cookie has domain set to the public suffix "${topLevelDomain}" which is a special use domain. To allow this, configure your CookieJar with {allowSpecialUseDomain: true, rejectPublicSuffixes: false}.`
50409
+ );
50410
+ }
50411
+ const publicSuffix = (0, import_tldts.getDomain)(domain, {
50412
+ allowIcannDomains: true,
50413
+ allowPrivateDomains: true
50414
+ });
50415
+ if (publicSuffix) return publicSuffix;
50416
+ }
50417
+ function permuteDomain(domain, allowSpecialUseDomain) {
50418
+ const pubSuf = getPublicSuffix(domain, {
50419
+ allowSpecialUseDomain
50420
+ });
50421
+ if (!pubSuf) {
50422
+ return void 0;
50423
+ }
50424
+ if (pubSuf == domain) {
50425
+ return [domain];
50426
+ }
50427
+ if (domain.slice(-1) == ".") {
50428
+ domain = domain.slice(0, -1);
50429
+ }
50430
+ const prefix = domain.slice(0, -(pubSuf.length + 1));
50431
+ const parts = prefix.split(".").reverse();
50432
+ let cur = pubSuf;
50433
+ const permutations = [cur];
50434
+ while (parts.length) {
50435
+ const part = parts.shift();
50436
+ cur = `${part}.${cur}`;
50437
+ permutations.push(cur);
50438
+ }
50439
+ return permutations;
50440
+ }
50441
+ function createPromiseCallback(cb) {
50442
+ let callback;
50443
+ let resolve43;
50444
+ let reject;
50445
+ const promise = new Promise((_resolve, _reject) => {
50446
+ resolve43 = _resolve;
50447
+ reject = _reject;
50448
+ });
50449
+ if (typeof cb === "function") {
50450
+ callback = (err, result) => {
50451
+ try {
50452
+ if (err) cb(err);
50453
+ else cb(null, result);
50454
+ } catch (e) {
50455
+ reject(e instanceof Error ? e : new Error());
50456
+ }
50457
+ };
50458
+ } else {
50459
+ callback = (err, result) => {
50460
+ try {
50461
+ if (err) reject(err);
50462
+ else resolve43(result);
50463
+ } catch (e) {
50464
+ reject(e instanceof Error ? e : new Error());
50465
+ }
50466
+ };
50467
+ }
50468
+ return {
50469
+ promise,
50470
+ callback,
50471
+ resolve: (value) => {
50472
+ callback(null, value);
50473
+ return promise;
50474
+ },
50475
+ reject: (error) => {
50476
+ callback(error);
50477
+ return promise;
50478
+ }
50479
+ };
50480
+ }
50481
+ function inOperator(k, o) {
50482
+ return k in o;
50483
+ }
50484
+ function isNonEmptyString(data) {
50485
+ return isString(data) && data !== "";
50486
+ }
50487
+ function isEmptyString(data) {
50488
+ return data === "" || data instanceof String && data.toString() === "";
50489
+ }
50490
+ function isString(data) {
50491
+ return typeof data === "string" || data instanceof String;
50492
+ }
50493
+ function isObject(data) {
50494
+ return objectToString(data) === "[object Object]";
50495
+ }
50496
+ function validate2(bool, cbOrMessage, message) {
50497
+ if (bool) return;
50498
+ const cb = typeof cbOrMessage === "function" ? cbOrMessage : void 0;
50499
+ let options = typeof cbOrMessage === "function" ? message : cbOrMessage;
50500
+ if (!isObject(options)) options = "[object Object]";
50501
+ const err = new ParameterError(safeToString(options));
50502
+ if (cb) cb(err);
50503
+ else throw err;
50504
+ }
50505
+ function domainToASCII(domain) {
50506
+ return new URL(`http://${domain}`).hostname;
50507
+ }
50508
+ function canonicalDomain(domainName) {
50509
+ if (domainName == null) {
50510
+ return void 0;
50511
+ }
50512
+ let str6 = domainName.trim().replace(/^\./, "");
50513
+ if (IP_V6_REGEX_OBJECT.test(str6)) {
50514
+ if (!str6.startsWith("[")) {
50515
+ str6 = "[" + str6;
50516
+ }
50517
+ if (!str6.endsWith("]")) {
50518
+ str6 = str6 + "]";
50519
+ }
50520
+ return domainToASCII(str6).slice(1, -1);
50521
+ }
50522
+ if (/[^\u0001-\u007f]/.test(str6)) {
50523
+ return domainToASCII(str6);
50524
+ }
50525
+ return str6.toLowerCase();
50526
+ }
50527
+ function formatDate(date) {
50528
+ return date.toUTCString();
50529
+ }
50530
+ function parseDate(cookieDate) {
50531
+ if (!cookieDate) {
50532
+ return void 0;
50533
+ }
50534
+ const flags = {
50535
+ foundTime: void 0,
50536
+ foundDayOfMonth: void 0,
50537
+ foundMonth: void 0,
50538
+ foundYear: void 0
50539
+ };
50540
+ const dateTokens = cookieDate.split(DELIMITER).filter((token) => token.length > 0);
50541
+ for (const dateToken of dateTokens) {
50542
+ if (flags.foundTime === void 0) {
50543
+ const [, hours, minutes, seconds] = TIME.exec(dateToken) || [];
50544
+ if (hours != void 0 && minutes != void 0 && seconds != void 0) {
50545
+ const parsedHours = parseInt(hours, 10);
50546
+ const parsedMinutes = parseInt(minutes, 10);
50547
+ const parsedSeconds = parseInt(seconds, 10);
50548
+ if (!isNaN(parsedHours) && !isNaN(parsedMinutes) && !isNaN(parsedSeconds)) {
50549
+ flags.foundTime = {
50550
+ hours: parsedHours,
50551
+ minutes: parsedMinutes,
50552
+ seconds: parsedSeconds
50553
+ };
50554
+ continue;
50555
+ }
50556
+ }
50557
+ }
50558
+ if (flags.foundDayOfMonth === void 0 && DAY_OF_MONTH.test(dateToken)) {
50559
+ const dayOfMonth = parseInt(dateToken, 10);
50560
+ if (!isNaN(dayOfMonth)) {
50561
+ flags.foundDayOfMonth = dayOfMonth;
50562
+ continue;
50563
+ }
50564
+ }
50565
+ if (flags.foundMonth === void 0 && MONTH.test(dateToken)) {
50566
+ const month = months.indexOf(dateToken.substring(0, 3).toLowerCase());
50567
+ if (month >= 0 && month <= 11) {
50568
+ flags.foundMonth = month;
50569
+ continue;
50570
+ }
50571
+ }
50572
+ if (flags.foundYear === void 0 && YEAR2.test(dateToken)) {
50573
+ const parsedYear = parseInt(dateToken, 10);
50574
+ if (!isNaN(parsedYear)) {
50575
+ flags.foundYear = parsedYear;
50576
+ continue;
50577
+ }
50578
+ }
50579
+ }
50580
+ if (flags.foundYear !== void 0 && flags.foundYear >= 70 && flags.foundYear <= 99) {
50581
+ flags.foundYear += 1900;
50582
+ }
50583
+ if (flags.foundYear !== void 0 && flags.foundYear >= 0 && flags.foundYear <= 69) {
50584
+ flags.foundYear += 2e3;
50585
+ }
50586
+ if (flags.foundDayOfMonth === void 0 || flags.foundMonth === void 0 || flags.foundYear === void 0 || flags.foundTime === void 0) {
50587
+ return void 0;
50588
+ }
50589
+ if (flags.foundDayOfMonth < 1 || flags.foundDayOfMonth > 31) {
50590
+ return void 0;
50591
+ }
50592
+ if (flags.foundYear < 1601) {
50593
+ return void 0;
50594
+ }
50595
+ if (flags.foundTime.hours > 23) {
50596
+ return void 0;
50597
+ }
50598
+ if (flags.foundTime.minutes > 59) {
50599
+ return void 0;
50600
+ }
50601
+ if (flags.foundTime.seconds > 59) {
50602
+ return void 0;
50603
+ }
50604
+ const date = new Date(
50605
+ Date.UTC(
50606
+ flags.foundYear,
50607
+ flags.foundMonth,
50608
+ flags.foundDayOfMonth,
50609
+ flags.foundTime.hours,
50610
+ flags.foundTime.minutes,
50611
+ flags.foundTime.seconds
50612
+ )
50613
+ );
50614
+ if (date.getUTCFullYear() !== flags.foundYear || date.getUTCMonth() !== flags.foundMonth || date.getUTCDate() !== flags.foundDayOfMonth) {
50615
+ return void 0;
50616
+ }
50617
+ return date;
50618
+ }
50619
+ function trimTerminator(str6) {
50620
+ if (isEmptyString(str6)) return str6;
50621
+ for (let t = 0; t < TERMINATORS.length; t++) {
50622
+ const terminator = TERMINATORS[t];
50623
+ const terminatorIdx = terminator ? str6.indexOf(terminator) : -1;
50624
+ if (terminatorIdx !== -1) {
50625
+ str6 = str6.slice(0, terminatorIdx);
50626
+ }
50627
+ }
50628
+ return str6;
50629
+ }
50630
+ function parseCookiePair(cookiePair, looseMode) {
50631
+ cookiePair = trimTerminator(cookiePair);
50632
+ let firstEq = cookiePair.indexOf("=");
50633
+ if (looseMode) {
50634
+ if (firstEq === 0) {
50635
+ cookiePair = cookiePair.substring(1);
50636
+ firstEq = cookiePair.indexOf("=");
50637
+ }
50638
+ } else {
50639
+ if (firstEq <= 0) {
50640
+ return void 0;
50641
+ }
50642
+ }
50643
+ let cookieName, cookieValue;
50644
+ if (firstEq <= 0) {
50645
+ cookieName = "";
50646
+ cookieValue = cookiePair.trim();
50647
+ } else {
50648
+ cookieName = cookiePair.slice(0, firstEq).trim();
50649
+ cookieValue = cookiePair.slice(firstEq + 1).trim();
50650
+ }
50651
+ if (CONTROL_CHARS2.test(cookieName) || CONTROL_CHARS2.test(cookieValue)) {
50652
+ return void 0;
50653
+ }
50654
+ const c = new Cookie();
50655
+ c.key = cookieName;
50656
+ c.value = cookieValue;
50657
+ return c;
50658
+ }
50659
+ function parse(str6, options) {
50660
+ if (isEmptyString(str6) || !isString(str6)) {
50661
+ return void 0;
50662
+ }
50663
+ str6 = str6.trim();
50664
+ const firstSemi = str6.indexOf(";");
50665
+ const cookiePair = firstSemi === -1 ? str6 : str6.slice(0, firstSemi);
50666
+ const c = parseCookiePair(cookiePair, options?.loose ?? false);
50667
+ if (!c) {
50668
+ return void 0;
50669
+ }
50670
+ if (firstSemi === -1) {
50671
+ return c;
50672
+ }
50673
+ const unparsed = str6.slice(firstSemi + 1).trim();
50674
+ if (unparsed.length === 0) {
50675
+ return c;
50676
+ }
50677
+ const cookie_avs = unparsed.split(";");
50678
+ while (cookie_avs.length) {
50679
+ const av = (cookie_avs.shift() ?? "").trim();
50680
+ if (av.length === 0) {
50681
+ continue;
50682
+ }
50683
+ const av_sep = av.indexOf("=");
50684
+ let av_key, av_value;
50685
+ if (av_sep === -1) {
50686
+ av_key = av;
50687
+ av_value = null;
50688
+ } else {
50689
+ av_key = av.slice(0, av_sep);
50690
+ av_value = av.slice(av_sep + 1);
50691
+ }
50692
+ av_key = av_key.trim().toLowerCase();
50693
+ if (av_value) {
50694
+ av_value = av_value.trim();
50695
+ }
50696
+ switch (av_key) {
50697
+ case "expires":
50698
+ if (av_value) {
50699
+ const exp = parseDate(av_value);
50700
+ if (exp) {
50701
+ c.expires = exp;
50702
+ }
50703
+ }
50704
+ break;
50705
+ case "max-age":
50706
+ if (av_value) {
50707
+ if (/^-?[0-9]+$/.test(av_value)) {
50708
+ const delta = parseInt(av_value, 10);
50709
+ c.setMaxAge(delta);
50710
+ }
50711
+ }
50712
+ break;
50713
+ case "domain":
50714
+ if (av_value) {
50715
+ const domain = av_value.trim().replace(/^\./, "");
50716
+ if (domain) {
50717
+ c.domain = domain.toLowerCase();
50718
+ }
50719
+ }
50720
+ break;
50721
+ case "path":
50722
+ c.path = av_value && av_value[0] === "/" ? av_value : null;
50723
+ break;
50724
+ case "secure":
50725
+ c.secure = true;
50726
+ break;
50727
+ case "httponly":
50728
+ c.httpOnly = true;
50729
+ break;
50730
+ case "samesite":
50731
+ switch (av_value ? av_value.toLowerCase() : "") {
50732
+ case "strict":
50733
+ c.sameSite = "strict";
50734
+ break;
50735
+ case "lax":
50736
+ c.sameSite = "lax";
50737
+ break;
50738
+ case "none":
50739
+ c.sameSite = "none";
50740
+ break;
50741
+ default:
50742
+ c.sameSite = void 0;
50743
+ break;
50744
+ }
50745
+ break;
50746
+ default:
50747
+ c.extensions = c.extensions || [];
50748
+ c.extensions.push(av);
50749
+ break;
50750
+ }
50751
+ }
50752
+ return c;
50753
+ }
50754
+ function fromJSON(str6) {
50755
+ if (!str6 || isEmptyString(str6)) {
50756
+ return void 0;
50757
+ }
50758
+ let obj;
50759
+ if (typeof str6 === "string") {
50760
+ try {
50761
+ obj = JSON.parse(str6);
50762
+ } catch {
50763
+ return void 0;
50764
+ }
50765
+ } else {
50766
+ obj = str6;
50767
+ }
50768
+ const c = new Cookie();
50769
+ Cookie.serializableProperties.forEach((prop) => {
50770
+ if (obj && typeof obj === "object" && inOperator(prop, obj)) {
50771
+ const val = obj[prop];
50772
+ if (val === void 0) {
50773
+ return;
50774
+ }
50775
+ if (inOperator(prop, cookieDefaults) && val === cookieDefaults[prop]) {
50776
+ return;
50777
+ }
50778
+ switch (prop) {
50779
+ case "key":
50780
+ case "value":
50781
+ case "sameSite":
50782
+ if (typeof val === "string") {
50783
+ c[prop] = val;
50784
+ }
50785
+ break;
50786
+ case "expires":
50787
+ case "creation":
50788
+ case "lastAccessed":
50789
+ if (typeof val === "number" || typeof val === "string" || val instanceof Date) {
50790
+ c[prop] = obj[prop] == "Infinity" ? "Infinity" : new Date(val);
50791
+ } else if (val === null) {
50792
+ c[prop] = null;
50793
+ }
50794
+ break;
50795
+ case "maxAge":
50796
+ if (typeof val === "number" || val === "Infinity" || val === "-Infinity") {
50797
+ c[prop] = val;
50798
+ }
50799
+ break;
50800
+ case "domain":
50801
+ case "path":
50802
+ if (typeof val === "string" || val === null) {
50803
+ c[prop] = val;
50804
+ }
50805
+ break;
50806
+ case "secure":
50807
+ case "httpOnly":
50808
+ if (typeof val === "boolean") {
50809
+ c[prop] = val;
50810
+ }
50811
+ break;
50812
+ case "extensions":
50813
+ if (Array.isArray(val) && val.every((item) => typeof item === "string")) {
50814
+ c[prop] = val;
50815
+ }
50816
+ break;
50817
+ case "hostOnly":
50818
+ case "pathIsDefault":
50819
+ if (typeof val === "boolean" || val === null) {
50820
+ c[prop] = val;
50821
+ }
50822
+ break;
50823
+ }
50824
+ }
50825
+ });
50826
+ return c;
50827
+ }
50828
+ function cookieCompare(a, b) {
50829
+ let cmp;
50830
+ const aPathLen = a.path ? a.path.length : 0;
50831
+ const bPathLen = b.path ? b.path.length : 0;
50832
+ cmp = bPathLen - aPathLen;
50833
+ if (cmp !== 0) {
50834
+ return cmp;
50835
+ }
50836
+ const aTime = a.creation && a.creation instanceof Date ? a.creation.getTime() : MAX_TIME;
50837
+ const bTime = b.creation && b.creation instanceof Date ? b.creation.getTime() : MAX_TIME;
50838
+ cmp = aTime - bTime;
50839
+ if (cmp !== 0) {
50840
+ return cmp;
50841
+ }
50842
+ cmp = (a.creationIndex || 0) - (b.creationIndex || 0);
50843
+ return cmp;
50844
+ }
50845
+ function defaultPath(path) {
50846
+ if (!path || path.slice(0, 1) !== "/") {
50847
+ return "/";
50848
+ }
50849
+ if (path === "/") {
50850
+ return path;
50851
+ }
50852
+ const rightSlash = path.lastIndexOf("/");
50853
+ if (rightSlash === 0) {
50854
+ return "/";
50855
+ }
50856
+ return path.slice(0, rightSlash);
50857
+ }
50858
+ function domainMatch(domain, cookieDomain, canonicalize) {
50859
+ if (domain == null || cookieDomain == null) {
50860
+ return void 0;
50861
+ }
50862
+ let _str;
50863
+ let _domStr;
50864
+ if (canonicalize !== false) {
50865
+ _str = canonicalDomain(domain);
50866
+ _domStr = canonicalDomain(cookieDomain);
50867
+ } else {
50868
+ _str = domain;
50869
+ _domStr = cookieDomain;
50870
+ }
50871
+ if (_str == null || _domStr == null) {
50872
+ return void 0;
50873
+ }
50874
+ if (_str == _domStr) {
50875
+ return true;
50876
+ }
50877
+ const idx = _str.lastIndexOf(_domStr);
50878
+ if (idx <= 0) {
50879
+ return false;
50880
+ }
50881
+ if (_str.length !== _domStr.length + idx) {
50882
+ return false;
50883
+ }
50884
+ if (_str.substring(idx - 1, idx) !== ".") {
50885
+ return false;
50886
+ }
50887
+ return !IP_REGEX_LOWERCASE.test(_str);
50888
+ }
50889
+ function isLoopbackV4(address) {
50890
+ const octets = address.split(".");
50891
+ return octets.length === 4 && octets[0] !== void 0 && parseInt(octets[0], 10) === 127;
50892
+ }
50893
+ function isLoopbackV6(address) {
50894
+ return address === "::1";
50895
+ }
50896
+ function isNormalizedLocalhostTLD(lowerHost) {
50897
+ return lowerHost.endsWith(".localhost");
50898
+ }
50899
+ function isLocalHostname(host) {
50900
+ const lowerHost = host.toLowerCase();
50901
+ return lowerHost === "localhost" || isNormalizedLocalhostTLD(lowerHost);
50902
+ }
50903
+ function hostNoBrackets(host) {
50904
+ if (host.length >= 2 && host.startsWith("[") && host.endsWith("]")) {
50905
+ return host.substring(1, host.length - 1);
50906
+ }
50907
+ return host;
50908
+ }
50909
+ function isPotentiallyTrustworthy(inputUrl, allowSecureOnLocal = true) {
50910
+ let url;
50911
+ if (typeof inputUrl === "string") {
50912
+ try {
50913
+ url = new URL(inputUrl);
50914
+ } catch {
50915
+ return false;
50916
+ }
50917
+ } else {
50918
+ url = inputUrl;
50919
+ }
50920
+ const scheme = url.protocol.replace(":", "").toLowerCase();
50921
+ const hostname2 = hostNoBrackets(url.hostname).replace(/\.+$/, "");
50922
+ if (scheme === "https" || scheme === "wss") {
50923
+ return true;
50924
+ }
50925
+ if (!allowSecureOnLocal) {
50926
+ return false;
50927
+ }
50928
+ if (IP_V4_REGEX_OBJECT.test(hostname2)) {
50929
+ return isLoopbackV4(hostname2);
50930
+ }
50931
+ if (IP_V6_REGEX_OBJECT.test(hostname2)) {
50932
+ return isLoopbackV6(hostname2);
50933
+ }
50934
+ return isLocalHostname(hostname2);
50935
+ }
50936
+ function getCookieContext(url) {
50937
+ if (url && typeof url === "object" && "hostname" in url && typeof url.hostname === "string" && "pathname" in url && typeof url.pathname === "string" && "protocol" in url && typeof url.protocol === "string") {
50938
+ return {
50939
+ hostname: url.hostname,
50940
+ pathname: url.pathname,
50941
+ protocol: url.protocol
50942
+ };
50943
+ } else if (typeof url === "string") {
50944
+ try {
50945
+ return new URL(decodeURI(url));
50946
+ } catch {
50947
+ return new URL(url);
50948
+ }
50949
+ } else {
50950
+ throw new ParameterError("`url` argument is not a string or URL.");
50951
+ }
50952
+ }
50953
+ function checkSameSiteContext(value) {
50954
+ const context = String(value).toLowerCase();
50955
+ if (context === "none" || context === "lax" || context === "strict") {
50956
+ return context;
50957
+ } else {
50958
+ return void 0;
50959
+ }
50960
+ }
50961
+ function isSecurePrefixConditionMet(cookie) {
50962
+ const startsWithSecurePrefix = typeof cookie.key === "string" && cookie.key.startsWith("__Secure-");
50963
+ return !startsWithSecurePrefix || cookie.secure;
50964
+ }
50965
+ function isHostPrefixConditionMet(cookie) {
50966
+ const startsWithHostPrefix = typeof cookie.key === "string" && cookie.key.startsWith("__Host-");
50967
+ return !startsWithHostPrefix || Boolean(
50968
+ cookie.secure && cookie.hostOnly && cookie.path != null && cookie.path === "/"
50969
+ );
50970
+ }
50971
+ function getNormalizedPrefixSecurity(prefixSecurity) {
50972
+ const normalizedPrefixSecurity = prefixSecurity.toLowerCase();
50973
+ switch (normalizedPrefixSecurity) {
50974
+ case PrefixSecurityEnum.STRICT:
50975
+ case PrefixSecurityEnum.SILENT:
50976
+ case PrefixSecurityEnum.DISABLED:
50977
+ return normalizedPrefixSecurity;
50978
+ default:
50979
+ return PrefixSecurityEnum.SILENT;
50980
+ }
50981
+ }
50982
+ var import_tldts, SPECIAL_USE_DOMAINS, SPECIAL_TREATMENT_DOMAINS, defaultGetPublicSuffixOptions, Store2, objectToString, safeArrayToString, safeToStringImpl, safeToString, MemoryCookieStore, ParameterError, version, PrefixSecurityEnum, IP_V6_REGEX, IP_V6_REGEX_OBJECT, IP_V4_REGEX, IP_V4_REGEX_OBJECT, months, DELIMITER, TIME, DAY_OF_MONTH, MONTH, YEAR2, COOKIE_OCTETS, PATH_VALUE, CONTROL_CHARS2, TERMINATORS, cookieDefaults, _Cookie, Cookie, MAX_TIME, IP_REGEX_LOWERCASE, defaultSetCookieOptions, defaultGetCookieOptions, SAME_SITE_CONTEXT_VAL_ERR, CookieJar;
50983
+ var init_dist = __esm({
50984
+ "../../node_modules/tough-cookie/dist/index.js"() {
50985
+ import_tldts = __toESM(require_cjs(), 1);
50986
+ SPECIAL_USE_DOMAINS = ["local", "example", "invalid", "localhost", "test"];
50987
+ SPECIAL_TREATMENT_DOMAINS = ["localhost", "invalid"];
50988
+ defaultGetPublicSuffixOptions = {
50989
+ allowSpecialUseDomain: false,
50990
+ ignoreError: false
50991
+ };
50992
+ Store2 = class {
50993
+ constructor() {
50994
+ this.synchronous = false;
50995
+ }
50996
+ /**
50997
+ * @internal No doc because this is an overload that supports the implementation
50998
+ */
50999
+ findCookie(_domain, _path, _key, _callback) {
51000
+ throw new Error("findCookie is not implemented");
51001
+ }
51002
+ /**
51003
+ * @internal No doc because this is an overload that supports the implementation
51004
+ */
51005
+ findCookies(_domain, _path, _allowSpecialUseDomain = false, _callback) {
51006
+ throw new Error("findCookies is not implemented");
51007
+ }
51008
+ /**
51009
+ * @internal No doc because this is an overload that supports the implementation
51010
+ */
51011
+ putCookie(_cookie, _callback) {
51012
+ throw new Error("putCookie is not implemented");
51013
+ }
51014
+ /**
51015
+ * @internal No doc because this is an overload that supports the implementation
51016
+ */
51017
+ updateCookie(_oldCookie, _newCookie, _callback) {
51018
+ throw new Error("updateCookie is not implemented");
51019
+ }
51020
+ /**
51021
+ * @internal No doc because this is an overload that supports the implementation
51022
+ */
51023
+ removeCookie(_domain, _path, _key, _callback) {
51024
+ throw new Error("removeCookie is not implemented");
51025
+ }
51026
+ /**
51027
+ * @internal No doc because this is an overload that supports the implementation
51028
+ */
51029
+ removeCookies(_domain, _path, _callback) {
51030
+ throw new Error("removeCookies is not implemented");
51031
+ }
51032
+ /**
51033
+ * @internal No doc because this is an overload that supports the implementation
51034
+ */
51035
+ removeAllCookies(_callback) {
51036
+ throw new Error("removeAllCookies is not implemented");
51037
+ }
51038
+ /**
51039
+ * @internal No doc because this is an overload that supports the implementation
51040
+ */
51041
+ getAllCookies(_callback) {
51042
+ throw new Error(
51043
+ "getAllCookies is not implemented (therefore jar cannot be serialized)"
51044
+ );
51045
+ }
51046
+ };
51047
+ objectToString = (obj) => Object.prototype.toString.call(obj);
51048
+ safeArrayToString = (arr, seenArrays) => {
51049
+ if (typeof arr.join !== "function") return objectToString(arr);
51050
+ seenArrays.add(arr);
51051
+ const mapped = arr.map(
51052
+ (val) => val === null || val === void 0 || seenArrays.has(val) ? "" : safeToStringImpl(val, seenArrays)
51053
+ );
51054
+ return mapped.join();
51055
+ };
51056
+ safeToStringImpl = (val, seenArrays = /* @__PURE__ */ new WeakSet()) => {
51057
+ if (typeof val !== "object" || val === null) {
51058
+ return String(val);
51059
+ } else if (typeof val.toString === "function") {
51060
+ return Array.isArray(val) ? (
51061
+ // Arrays have a weird custom toString that we need to replicate
51062
+ safeArrayToString(val, seenArrays)
51063
+ ) : (
51064
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
51065
+ String(val)
51066
+ );
51067
+ } else {
51068
+ return objectToString(val);
51069
+ }
51070
+ };
51071
+ safeToString = (val) => safeToStringImpl(val);
51072
+ MemoryCookieStore = class extends Store2 {
51073
+ /**
51074
+ * Create a new {@link MemoryCookieStore}.
51075
+ */
51076
+ constructor() {
51077
+ super();
51078
+ this.synchronous = true;
51079
+ this.idx = /* @__PURE__ */ Object.create(null);
51080
+ }
51081
+ /**
51082
+ * @internal No doc because this is an overload that supports the implementation
51083
+ */
51084
+ findCookie(domain, path, key2, callback) {
51085
+ const promiseCallback = createPromiseCallback(callback);
51086
+ if (domain == null || path == null || key2 == null) {
51087
+ return promiseCallback.resolve(void 0);
51088
+ }
51089
+ const result = this.idx[domain]?.[path]?.[key2];
51090
+ return promiseCallback.resolve(result);
51091
+ }
51092
+ /**
51093
+ * @internal No doc because this is an overload that supports the implementation
51094
+ */
51095
+ findCookies(domain, path, allowSpecialUseDomain = false, callback) {
51096
+ if (typeof allowSpecialUseDomain === "function") {
51097
+ callback = allowSpecialUseDomain;
51098
+ allowSpecialUseDomain = true;
51099
+ }
51100
+ const results = [];
51101
+ const promiseCallback = createPromiseCallback(callback);
51102
+ if (!domain) {
51103
+ return promiseCallback.resolve([]);
51104
+ }
51105
+ let pathMatcher;
51106
+ if (!path) {
51107
+ pathMatcher = function matchAll(domainIndex) {
51108
+ for (const curPath in domainIndex) {
51109
+ const pathIndex = domainIndex[curPath];
51110
+ for (const key2 in pathIndex) {
51111
+ const value = pathIndex[key2];
51112
+ if (value) {
51113
+ results.push(value);
51114
+ }
51115
+ }
51116
+ }
51117
+ };
51118
+ } else {
51119
+ pathMatcher = function matchRFC(domainIndex) {
51120
+ for (const cookiePath in domainIndex) {
51121
+ if (pathMatch(path, cookiePath)) {
51122
+ const pathIndex = domainIndex[cookiePath];
51123
+ for (const key2 in pathIndex) {
51124
+ const value = pathIndex[key2];
51125
+ if (value) {
51126
+ results.push(value);
51127
+ }
51128
+ }
51129
+ }
51130
+ }
51131
+ };
51132
+ }
51133
+ const domains = permuteDomain(domain, allowSpecialUseDomain) || [domain];
51134
+ const idx = this.idx;
51135
+ domains.forEach((curDomain) => {
51136
+ const domainIndex = idx[curDomain];
51137
+ if (!domainIndex) {
51138
+ return;
51139
+ }
51140
+ pathMatcher(domainIndex);
51141
+ });
51142
+ return promiseCallback.resolve(results);
51143
+ }
51144
+ /**
51145
+ * @internal No doc because this is an overload that supports the implementation
51146
+ */
51147
+ putCookie(cookie, callback) {
51148
+ const promiseCallback = createPromiseCallback(callback);
51149
+ const { domain, path, key: key2 } = cookie;
51150
+ if (domain == null || path == null || key2 == null) {
51151
+ return promiseCallback.resolve(void 0);
51152
+ }
51153
+ const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null);
51154
+ this.idx[domain] = domainEntry;
51155
+ const pathEntry = domainEntry[path] ?? /* @__PURE__ */ Object.create(null);
51156
+ domainEntry[path] = pathEntry;
51157
+ pathEntry[key2] = cookie;
51158
+ return promiseCallback.resolve(void 0);
51159
+ }
51160
+ /**
51161
+ * @internal No doc because this is an overload that supports the implementation
51162
+ */
51163
+ updateCookie(_oldCookie, newCookie, callback) {
51164
+ if (callback) this.putCookie(newCookie, callback);
51165
+ else return this.putCookie(newCookie);
51166
+ }
51167
+ /**
51168
+ * @internal No doc because this is an overload that supports the implementation
51169
+ */
51170
+ removeCookie(domain, path, key2, callback) {
51171
+ const promiseCallback = createPromiseCallback(callback);
51172
+ delete this.idx[domain]?.[path]?.[key2];
51173
+ return promiseCallback.resolve(void 0);
51174
+ }
51175
+ /**
51176
+ * @internal No doc because this is an overload that supports the implementation
51177
+ */
51178
+ removeCookies(domain, path, callback) {
51179
+ const promiseCallback = createPromiseCallback(callback);
51180
+ const domainEntry = this.idx[domain];
51181
+ if (domainEntry) {
51182
+ if (path) {
51183
+ delete domainEntry[path];
51184
+ } else {
51185
+ delete this.idx[domain];
51186
+ }
51187
+ }
51188
+ return promiseCallback.resolve(void 0);
51189
+ }
51190
+ /**
51191
+ * @internal No doc because this is an overload that supports the implementation
51192
+ */
51193
+ removeAllCookies(callback) {
51194
+ const promiseCallback = createPromiseCallback(callback);
51195
+ this.idx = /* @__PURE__ */ Object.create(null);
51196
+ return promiseCallback.resolve(void 0);
51197
+ }
51198
+ /**
51199
+ * @internal No doc because this is an overload that supports the implementation
51200
+ */
51201
+ getAllCookies(callback) {
51202
+ const promiseCallback = createPromiseCallback(callback);
51203
+ const cookies = [];
51204
+ const idx = this.idx;
51205
+ const domains = Object.keys(idx);
51206
+ domains.forEach((domain) => {
51207
+ const domainEntry = idx[domain] ?? {};
51208
+ const paths = Object.keys(domainEntry);
51209
+ paths.forEach((path) => {
51210
+ const pathEntry = domainEntry[path] ?? {};
51211
+ const keys = Object.keys(pathEntry);
51212
+ keys.forEach((key2) => {
51213
+ const keyEntry = pathEntry[key2];
51214
+ if (keyEntry != null) {
51215
+ cookies.push(keyEntry);
51216
+ }
51217
+ });
51218
+ });
51219
+ });
51220
+ cookies.sort((a, b) => {
51221
+ return (a.creationIndex || 0) - (b.creationIndex || 0);
51222
+ });
51223
+ return promiseCallback.resolve(cookies);
51224
+ }
51225
+ };
51226
+ ParameterError = class extends Error {
51227
+ };
51228
+ version = "6.0.1";
51229
+ PrefixSecurityEnum = {
51230
+ SILENT: "silent",
51231
+ STRICT: "strict",
51232
+ DISABLED: "unsafe-disabled"
51233
+ };
51234
+ Object.freeze(PrefixSecurityEnum);
51235
+ IP_V6_REGEX = `
51236
+ \\[?(?:
51237
+ (?:[a-fA-F\\d]{1,4}:){7}(?:[a-fA-F\\d]{1,4}|:)|
51238
+ (?:[a-fA-F\\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|:[a-fA-F\\d]{1,4}|:)|
51239
+ (?:[a-fA-F\\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?::[a-fA-F\\d]{1,4}){1,2}|:)|
51240
+ (?:[a-fA-F\\d]{1,4}:){4}(?:(?::[a-fA-F\\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?::[a-fA-F\\d]{1,4}){1,3}|:)|
51241
+ (?:[a-fA-F\\d]{1,4}:){3}(?:(?::[a-fA-F\\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?::[a-fA-F\\d]{1,4}){1,4}|:)|
51242
+ (?:[a-fA-F\\d]{1,4}:){2}(?:(?::[a-fA-F\\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?::[a-fA-F\\d]{1,4}){1,5}|:)|
51243
+ (?:[a-fA-F\\d]{1,4}:){1}(?:(?::[a-fA-F\\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?::[a-fA-F\\d]{1,4}){1,6}|:)|
51244
+ (?::(?:(?::[a-fA-F\\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}|(?::[a-fA-F\\d]{1,4}){1,7}|:))
51245
+ )(?:%[0-9a-zA-Z]{1,})?\\]?
51246
+ `.replace(/\s*\/\/.*$/gm, "").replace(/\n/g, "").trim();
51247
+ IP_V6_REGEX_OBJECT = new RegExp(`^${IP_V6_REGEX}$`);
51248
+ IP_V4_REGEX = `(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])`;
51249
+ IP_V4_REGEX_OBJECT = new RegExp(`^${IP_V4_REGEX}$`);
51250
+ months = [
51251
+ "jan",
51252
+ "feb",
51253
+ "mar",
51254
+ "apr",
51255
+ "may",
51256
+ "jun",
51257
+ "jul",
51258
+ "aug",
51259
+ "sep",
51260
+ "oct",
51261
+ "nov",
51262
+ "dec"
51263
+ ];
51264
+ DELIMITER = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/;
51265
+ TIME = /^(\d{1,2}):(\d{1,2}):(\d{1,2})(?:[\x00-\x2F\x3A-\xFF][\x00-\xFF]*)?$/;
51266
+ DAY_OF_MONTH = /^[0-9]{1,2}(?:[\x00-\x2F\x3A-\xFF][\x00-\xFF]*)?$/;
51267
+ MONTH = /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[\x00-\xFF]*$/i;
51268
+ YEAR2 = /^[\x30-\x39]{2,4}(?:[\x00-\x2F\x3A-\xFF][\x00-\xFF]*)?$/;
51269
+ COOKIE_OCTETS = /^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+$/;
51270
+ PATH_VALUE = /[\x20-\x3A\x3C-\x7E]+/;
51271
+ CONTROL_CHARS2 = /[\x00-\x1F]/;
51272
+ TERMINATORS = ["\n", "\r", "\0"];
51273
+ cookieDefaults = {
51274
+ // the order in which the RFC has them:
51275
+ key: "",
51276
+ value: "",
51277
+ expires: "Infinity",
51278
+ maxAge: null,
51279
+ domain: null,
51280
+ path: null,
51281
+ secure: false,
51282
+ httpOnly: false,
51283
+ extensions: null,
51284
+ // set by the CookieJar:
51285
+ hostOnly: null,
51286
+ pathIsDefault: null,
51287
+ creation: null,
51288
+ lastAccessed: null,
51289
+ sameSite: void 0
51290
+ };
51291
+ _Cookie = class _Cookie2 {
51292
+ /**
51293
+ * Create a new Cookie instance.
51294
+ * @public
51295
+ * @param options - The attributes to set on the cookie
51296
+ */
51297
+ constructor(options = {}) {
51298
+ this.key = options.key ?? cookieDefaults.key;
51299
+ this.value = options.value ?? cookieDefaults.value;
51300
+ this.expires = options.expires ?? cookieDefaults.expires;
51301
+ this.maxAge = options.maxAge ?? cookieDefaults.maxAge;
51302
+ this.domain = options.domain ?? cookieDefaults.domain;
51303
+ this.path = options.path ?? cookieDefaults.path;
51304
+ this.secure = options.secure ?? cookieDefaults.secure;
51305
+ this.httpOnly = options.httpOnly ?? cookieDefaults.httpOnly;
51306
+ this.extensions = options.extensions ?? cookieDefaults.extensions;
51307
+ this.creation = options.creation ?? cookieDefaults.creation;
51308
+ this.hostOnly = options.hostOnly ?? cookieDefaults.hostOnly;
51309
+ this.pathIsDefault = options.pathIsDefault ?? cookieDefaults.pathIsDefault;
51310
+ this.lastAccessed = options.lastAccessed ?? cookieDefaults.lastAccessed;
51311
+ this.sameSite = options.sameSite ?? cookieDefaults.sameSite;
51312
+ this.creation = options.creation ?? /* @__PURE__ */ new Date();
51313
+ Object.defineProperty(this, "creationIndex", {
51314
+ configurable: false,
51315
+ enumerable: false,
51316
+ // important for assert.deepEqual checks
51317
+ writable: true,
51318
+ value: ++_Cookie2.cookiesCreated
51319
+ });
51320
+ this.creationIndex = _Cookie2.cookiesCreated;
51321
+ }
51322
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
51323
+ const now = Date.now();
51324
+ const hostOnly = this.hostOnly != null ? this.hostOnly.toString() : "?";
51325
+ const createAge = this.creation && this.creation !== "Infinity" ? `${String(now - this.creation.getTime())}ms` : "?";
51326
+ const accessAge = this.lastAccessed && this.lastAccessed !== "Infinity" ? `${String(now - this.lastAccessed.getTime())}ms` : "?";
51327
+ return `Cookie="${this.toString()}; hostOnly=${hostOnly}; aAge=${accessAge}; cAge=${createAge}"`;
51328
+ }
51329
+ /**
51330
+ * For convenience in using `JSON.stringify(cookie)`. Returns a plain-old Object that can be JSON-serialized.
51331
+ *
51332
+ * @remarks
51333
+ * - Any `Date` properties (such as {@link Cookie.expires}, {@link Cookie.creation}, and {@link Cookie.lastAccessed}) are exported in ISO format (`Date.toISOString()`).
51334
+ *
51335
+ * - Custom Cookie properties are discarded. In tough-cookie 1.x, since there was no {@link Cookie.toJSON} method explicitly defined, all enumerable properties were captured.
51336
+ * If you want a property to be serialized, add the property name to {@link Cookie.serializableProperties}.
51337
+ */
51338
+ toJSON() {
51339
+ const obj = {};
51340
+ for (const prop of _Cookie2.serializableProperties) {
51341
+ const val = this[prop];
51342
+ if (val === cookieDefaults[prop]) {
51343
+ continue;
51344
+ }
51345
+ switch (prop) {
51346
+ case "key":
51347
+ case "value":
51348
+ case "sameSite":
51349
+ if (typeof val === "string") {
51350
+ obj[prop] = val;
51351
+ }
51352
+ break;
51353
+ case "expires":
51354
+ case "creation":
51355
+ case "lastAccessed":
51356
+ if (typeof val === "number" || typeof val === "string" || val instanceof Date) {
51357
+ obj[prop] = val == "Infinity" ? "Infinity" : new Date(val).toISOString();
51358
+ } else if (val === null) {
51359
+ obj[prop] = null;
51360
+ }
51361
+ break;
51362
+ case "maxAge":
51363
+ if (typeof val === "number" || val === "Infinity" || val === "-Infinity") {
51364
+ obj[prop] = val;
51365
+ }
51366
+ break;
51367
+ case "domain":
51368
+ case "path":
51369
+ if (typeof val === "string" || val === null) {
51370
+ obj[prop] = val;
51371
+ }
51372
+ break;
51373
+ case "secure":
51374
+ case "httpOnly":
51375
+ if (typeof val === "boolean") {
51376
+ obj[prop] = val;
51377
+ }
51378
+ break;
51379
+ case "extensions":
51380
+ if (Array.isArray(val)) {
51381
+ obj[prop] = val;
51382
+ }
51383
+ break;
51384
+ case "hostOnly":
51385
+ case "pathIsDefault":
51386
+ if (typeof val === "boolean" || val === null) {
51387
+ obj[prop] = val;
51388
+ }
51389
+ break;
51390
+ }
51391
+ }
51392
+ return obj;
51393
+ }
51394
+ /**
51395
+ * Does a deep clone of this cookie, implemented exactly as `Cookie.fromJSON(cookie.toJSON())`.
51396
+ * @public
51397
+ */
51398
+ clone() {
51399
+ return fromJSON(this.toJSON());
51400
+ }
51401
+ /**
51402
+ * Validates cookie attributes for semantic correctness. Useful for "lint" checking any `Set-Cookie` headers you generate.
51403
+ * For now, it returns a boolean, but eventually could return a reason string.
51404
+ *
51405
+ * @remarks
51406
+ * Works for a few things, but is by no means comprehensive.
51407
+ *
51408
+ * @beta
51409
+ */
51410
+ validate() {
51411
+ if (!this.value || !COOKIE_OCTETS.test(this.value)) {
51412
+ return false;
51413
+ }
51414
+ if (this.expires != "Infinity" && !(this.expires instanceof Date) && !parseDate(this.expires)) {
51415
+ return false;
51416
+ }
51417
+ if (this.maxAge != null && this.maxAge !== "Infinity" && (this.maxAge === "-Infinity" || this.maxAge <= 0)) {
51418
+ return false;
51419
+ }
51420
+ if (this.path != null && !PATH_VALUE.test(this.path)) {
51421
+ return false;
51422
+ }
51423
+ const cdomain = this.cdomain();
51424
+ if (cdomain) {
51425
+ if (cdomain.match(/\.$/)) {
51426
+ return false;
51427
+ }
51428
+ const suffix = getPublicSuffix(cdomain);
51429
+ if (suffix == null) {
51430
+ return false;
51431
+ }
51432
+ }
51433
+ return true;
51434
+ }
51435
+ /**
51436
+ * Sets the 'Expires' attribute on a cookie.
51437
+ *
51438
+ * @remarks
51439
+ * When given a `string` value it will be parsed with {@link parseDate}. If the value can't be parsed as a cookie date
51440
+ * then the 'Expires' attribute will be set to `"Infinity"`.
51441
+ *
51442
+ * @param exp - the new value for the 'Expires' attribute of the cookie.
51443
+ */
51444
+ setExpires(exp) {
51445
+ if (exp instanceof Date) {
51446
+ this.expires = exp;
51447
+ } else {
51448
+ this.expires = parseDate(exp) || "Infinity";
51449
+ }
51450
+ }
51451
+ /**
51452
+ * Sets the 'Max-Age' attribute (in seconds) on a cookie.
51453
+ *
51454
+ * @remarks
51455
+ * Coerces `-Infinity` to `"-Infinity"` and `Infinity` to `"Infinity"` so it can be serialized to JSON.
51456
+ *
51457
+ * @param age - the new value for the 'Max-Age' attribute (in seconds).
51458
+ */
51459
+ setMaxAge(age) {
51460
+ if (age === Infinity) {
51461
+ this.maxAge = "Infinity";
51462
+ } else if (age === -Infinity) {
51463
+ this.maxAge = "-Infinity";
51464
+ } else {
51465
+ this.maxAge = age;
51466
+ }
51467
+ }
51468
+ /**
51469
+ * Encodes to a `Cookie` header value (specifically, the {@link Cookie.key} and {@link Cookie.value} properties joined with "=").
51470
+ * @public
51471
+ */
51472
+ cookieString() {
51473
+ const val = this.value || "";
51474
+ if (this.key) {
51475
+ return `${this.key}=${val}`;
51476
+ }
51477
+ return val;
51478
+ }
51479
+ /**
51480
+ * Encodes to a `Set-Cookie header` value.
51481
+ * @public
51482
+ */
51483
+ toString() {
51484
+ let str6 = this.cookieString();
51485
+ if (this.expires != "Infinity") {
51486
+ if (this.expires instanceof Date) {
51487
+ str6 += `; Expires=${formatDate(this.expires)}`;
51488
+ }
51489
+ }
51490
+ if (this.maxAge != null && this.maxAge != Infinity) {
51491
+ str6 += `; Max-Age=${String(this.maxAge)}`;
51492
+ }
51493
+ if (this.domain && !this.hostOnly) {
51494
+ str6 += `; Domain=${this.domain}`;
51495
+ }
51496
+ if (this.path) {
51497
+ str6 += `; Path=${this.path}`;
51498
+ }
51499
+ if (this.secure) {
51500
+ str6 += "; Secure";
51501
+ }
51502
+ if (this.httpOnly) {
51503
+ str6 += "; HttpOnly";
51504
+ }
51505
+ if (this.sameSite && this.sameSite !== "none") {
51506
+ if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.lax.toLowerCase()) {
51507
+ str6 += `; SameSite=${_Cookie2.sameSiteCanonical.lax}`;
51508
+ } else if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.strict.toLowerCase()) {
51509
+ str6 += `; SameSite=${_Cookie2.sameSiteCanonical.strict}`;
51510
+ } else {
51511
+ str6 += `; SameSite=${this.sameSite}`;
51512
+ }
51513
+ }
51514
+ if (this.extensions) {
51515
+ this.extensions.forEach((ext) => {
51516
+ str6 += `; ${ext}`;
51517
+ });
51518
+ }
51519
+ return str6;
51520
+ }
51521
+ /**
51522
+ * Computes the TTL relative to now (milliseconds).
51523
+ *
51524
+ * @remarks
51525
+ * - `Infinity` is returned for cookies without an explicit expiry
51526
+ *
51527
+ * - `0` is returned if the cookie is expired.
51528
+ *
51529
+ * - Otherwise a time-to-live in milliseconds is returned.
51530
+ *
51531
+ * @param now - passing an explicit value is mostly used for testing purposes since this defaults to the `Date.now()`
51532
+ * @public
51533
+ */
51534
+ TTL(now = Date.now()) {
51535
+ if (this.maxAge != null && typeof this.maxAge === "number") {
51536
+ return this.maxAge <= 0 ? 0 : this.maxAge * 1e3;
51537
+ }
51538
+ const expires = this.expires;
51539
+ if (expires === "Infinity") {
51540
+ return Infinity;
51541
+ }
51542
+ return (expires?.getTime() ?? now) - (now || Date.now());
51543
+ }
51544
+ /**
51545
+ * Computes the absolute unix-epoch milliseconds that this cookie expires.
51546
+ *
51547
+ * The "Max-Age" attribute takes precedence over "Expires" (as per the RFC). The {@link Cookie.lastAccessed} attribute
51548
+ * (or the `now` parameter if given) is used to offset the {@link Cookie.maxAge} attribute.
51549
+ *
51550
+ * If Expires ({@link Cookie.expires}) is set, that's returned.
51551
+ *
51552
+ * @param now - can be used to provide a time offset (instead of {@link Cookie.lastAccessed}) to use when calculating the "Max-Age" value
51553
+ */
51554
+ expiryTime(now) {
51555
+ if (this.maxAge != null) {
51556
+ const relativeTo = now || this.lastAccessed || /* @__PURE__ */ new Date();
51557
+ const maxAge = typeof this.maxAge === "number" ? this.maxAge : -Infinity;
51558
+ const age = maxAge <= 0 ? -Infinity : maxAge * 1e3;
51559
+ if (relativeTo === "Infinity") {
51560
+ return Infinity;
51561
+ }
51562
+ return relativeTo.getTime() + age;
51563
+ }
51564
+ if (this.expires == "Infinity") {
51565
+ return Infinity;
51566
+ }
51567
+ return this.expires ? this.expires.getTime() : void 0;
51568
+ }
51569
+ /**
51570
+ * Similar to {@link Cookie.expiryTime}, computes the absolute unix-epoch milliseconds that this cookie expires and returns it as a Date.
51571
+ *
51572
+ * The "Max-Age" attribute takes precedence over "Expires" (as per the RFC). The {@link Cookie.lastAccessed} attribute
51573
+ * (or the `now` parameter if given) is used to offset the {@link Cookie.maxAge} attribute.
51574
+ *
51575
+ * If Expires ({@link Cookie.expires}) is set, that's returned.
51576
+ *
51577
+ * @param now - can be used to provide a time offset (instead of {@link Cookie.lastAccessed}) to use when calculating the "Max-Age" value
51578
+ */
51579
+ expiryDate(now) {
51580
+ const millisec = this.expiryTime(now);
51581
+ if (millisec == Infinity) {
51582
+ return /* @__PURE__ */ new Date(2147483647e3);
51583
+ } else if (millisec == -Infinity) {
51584
+ return /* @__PURE__ */ new Date(0);
51585
+ } else {
51586
+ return millisec == void 0 ? void 0 : new Date(millisec);
51587
+ }
51588
+ }
51589
+ /**
51590
+ * Indicates if the cookie has been persisted to a store or not.
51591
+ * @public
51592
+ */
51593
+ isPersistent() {
51594
+ return this.maxAge != null || this.expires != "Infinity";
51595
+ }
51596
+ /**
51597
+ * Calls {@link canonicalDomain} with the {@link Cookie.domain} property.
51598
+ * @public
51599
+ */
51600
+ canonicalizedDomain() {
51601
+ return canonicalDomain(this.domain);
51602
+ }
51603
+ /**
51604
+ * Alias for {@link Cookie.canonicalizedDomain}
51605
+ * @public
51606
+ */
51607
+ cdomain() {
51608
+ return canonicalDomain(this.domain);
51609
+ }
51610
+ /**
51611
+ * Parses a string into a Cookie object.
51612
+ *
51613
+ * @remarks
51614
+ * Note: when parsing a `Cookie` header it must be split by ';' before each Cookie string can be parsed.
51615
+ *
51616
+ * @example
51617
+ * ```
51618
+ * // parse a `Set-Cookie` header
51619
+ * const setCookieHeader = 'a=bcd; Expires=Tue, 18 Oct 2011 07:05:03 GMT'
51620
+ * const cookie = Cookie.parse(setCookieHeader)
51621
+ * cookie.key === 'a'
51622
+ * cookie.value === 'bcd'
51623
+ * cookie.expires === new Date(Date.parse('Tue, 18 Oct 2011 07:05:03 GMT'))
51624
+ * ```
51625
+ *
51626
+ * @example
51627
+ * ```
51628
+ * // parse a `Cookie` header
51629
+ * const cookieHeader = 'name=value; name2=value2; name3=value3'
51630
+ * const cookies = cookieHeader.split(';').map(Cookie.parse)
51631
+ * cookies[0].name === 'name'
51632
+ * cookies[0].value === 'value'
51633
+ * cookies[1].name === 'name2'
51634
+ * cookies[1].value === 'value2'
51635
+ * cookies[2].name === 'name3'
51636
+ * cookies[2].value === 'value3'
51637
+ * ```
51638
+ *
51639
+ * @param str - The `Set-Cookie` header or a Cookie string to parse.
51640
+ * @param options - Configures `strict` or `loose` mode for cookie parsing
51641
+ */
51642
+ static parse(str6, options) {
51643
+ return parse(str6, options);
51644
+ }
51645
+ /**
51646
+ * Does the reverse of {@link Cookie.toJSON}.
51647
+ *
51648
+ * @remarks
51649
+ * Any Date properties (such as .expires, .creation, and .lastAccessed) are parsed via Date.parse, not tough-cookie's parseDate, since ISO timestamps are being handled at this layer.
51650
+ *
51651
+ * @example
51652
+ * ```
51653
+ * const json = JSON.stringify({
51654
+ * key: 'alpha',
51655
+ * value: 'beta',
51656
+ * domain: 'example.com',
51657
+ * path: '/foo',
51658
+ * expires: '2038-01-19T03:14:07.000Z',
51659
+ * })
51660
+ * const cookie = Cookie.fromJSON(json)
51661
+ * cookie.key === 'alpha'
51662
+ * cookie.value === 'beta'
51663
+ * cookie.domain === 'example.com'
51664
+ * cookie.path === '/foo'
51665
+ * cookie.expires === new Date(Date.parse('2038-01-19T03:14:07.000Z'))
51666
+ * ```
51667
+ *
51668
+ * @param str - An unparsed JSON string or a value that has already been parsed as JSON
51669
+ */
51670
+ static fromJSON(str6) {
51671
+ return fromJSON(str6);
51672
+ }
51673
+ };
51674
+ _Cookie.cookiesCreated = 0;
51675
+ _Cookie.sameSiteLevel = {
51676
+ strict: 3,
51677
+ lax: 2,
51678
+ none: 1
51679
+ };
51680
+ _Cookie.sameSiteCanonical = {
51681
+ strict: "Strict",
51682
+ lax: "Lax"
51683
+ };
51684
+ _Cookie.serializableProperties = [
51685
+ "key",
51686
+ "value",
51687
+ "expires",
51688
+ "maxAge",
51689
+ "domain",
51690
+ "path",
51691
+ "secure",
51692
+ "httpOnly",
51693
+ "extensions",
51694
+ "hostOnly",
51695
+ "pathIsDefault",
51696
+ "creation",
51697
+ "lastAccessed",
51698
+ "sameSite"
51699
+ ];
51700
+ Cookie = _Cookie;
51701
+ MAX_TIME = 2147483647e3;
51702
+ IP_REGEX_LOWERCASE = /(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-f\d]{1,4}:){7}(?:[a-f\d]{1,4}|:)|(?:[a-f\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-f\d]{1,4}|:)|(?:[a-f\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,2}|:)|(?:[a-f\d]{1,4}:){4}(?:(?::[a-f\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,3}|:)|(?:[a-f\d]{1,4}:){3}(?:(?::[a-f\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,4}|:)|(?:[a-f\d]{1,4}:){2}(?:(?::[a-f\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,5}|:)|(?:[a-f\d]{1,4}:){1}(?:(?::[a-f\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,6}|:)|(?::(?:(?::[a-f\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-f\d]{1,4}){1,7}|:)))$)/;
51703
+ defaultSetCookieOptions = {
51704
+ loose: false,
51705
+ sameSiteContext: void 0,
51706
+ ignoreError: false,
51707
+ http: true
51708
+ };
51709
+ defaultGetCookieOptions = {
51710
+ http: true,
51711
+ expire: true,
51712
+ allPaths: false,
51713
+ sameSiteContext: void 0,
51714
+ sort: void 0
51715
+ };
51716
+ SAME_SITE_CONTEXT_VAL_ERR = 'Invalid sameSiteContext option for getCookies(); expected one of "strict", "lax", or "none"';
51717
+ CookieJar = class _CookieJar {
51718
+ /**
51719
+ * Creates a new `CookieJar` instance.
51720
+ *
51721
+ * @remarks
51722
+ * - If a custom store is not passed to the constructor, an in-memory store ({@link MemoryCookieStore} will be created and used.
51723
+ * - If a boolean value is passed as the `options` parameter, this is equivalent to passing `{ rejectPublicSuffixes: <value> }`
51724
+ *
51725
+ * @param store - a custom {@link Store} implementation (defaults to {@link MemoryCookieStore})
51726
+ * @param options - configures how cookies are processed by the cookie jar
51727
+ */
51728
+ constructor(store, options) {
51729
+ if (typeof options === "boolean") {
51730
+ options = { rejectPublicSuffixes: options };
51731
+ }
51732
+ this.rejectPublicSuffixes = options?.rejectPublicSuffixes ?? true;
51733
+ this.enableLooseMode = options?.looseMode ?? false;
51734
+ this.allowSpecialUseDomain = options?.allowSpecialUseDomain ?? true;
51735
+ this.allowSecureOnLocal = options?.allowSecureOnLocal ?? true;
51736
+ this.prefixSecurity = getNormalizedPrefixSecurity(
51737
+ options?.prefixSecurity ?? "silent"
51738
+ );
51739
+ this.store = store ?? new MemoryCookieStore();
51740
+ }
51741
+ callSync(fn) {
51742
+ if (!this.store.synchronous) {
51743
+ throw new Error(
51744
+ "CookieJar store is not synchronous; use async API instead."
51745
+ );
51746
+ }
51747
+ let syncErr = null;
51748
+ let syncResult = void 0;
51749
+ try {
51750
+ fn.call(this, (error, result) => {
51751
+ syncErr = error;
51752
+ syncResult = result;
51753
+ });
51754
+ } catch (err) {
51755
+ syncErr = err;
51756
+ }
51757
+ if (syncErr) throw syncErr;
51758
+ return syncResult;
51759
+ }
51760
+ /**
51761
+ * @internal No doc because this is the overload implementation
51762
+ */
51763
+ setCookie(cookie, url, options, callback) {
51764
+ if (typeof options === "function") {
51765
+ callback = options;
51766
+ options = void 0;
51767
+ }
51768
+ const promiseCallback = createPromiseCallback(callback);
51769
+ const cb = promiseCallback.callback;
51770
+ let context;
51771
+ try {
51772
+ if (typeof url === "string") {
51773
+ validate2(
51774
+ isNonEmptyString(url),
51775
+ callback,
51776
+ safeToString(options)
51777
+ );
51778
+ }
51779
+ context = getCookieContext(url);
51780
+ if (typeof url === "function") {
51781
+ return promiseCallback.reject(new Error("No URL was specified"));
51782
+ }
51783
+ if (typeof options === "function") {
51784
+ options = defaultSetCookieOptions;
51785
+ }
51786
+ validate2(typeof cb === "function", cb);
51787
+ if (!isNonEmptyString(cookie) && !isObject(cookie) && cookie instanceof String && cookie.length == 0) {
51788
+ return promiseCallback.resolve(void 0);
51789
+ }
51790
+ } catch (err) {
51791
+ return promiseCallback.reject(err);
51792
+ }
51793
+ const host = canonicalDomain(context.hostname) ?? null;
51794
+ const loose = options?.loose || this.enableLooseMode;
51795
+ let sameSiteContext = null;
51796
+ if (options?.sameSiteContext) {
51797
+ sameSiteContext = checkSameSiteContext(options.sameSiteContext);
51798
+ if (!sameSiteContext) {
51799
+ return promiseCallback.reject(new Error(SAME_SITE_CONTEXT_VAL_ERR));
51800
+ }
51801
+ }
51802
+ if (typeof cookie === "string" || cookie instanceof String) {
51803
+ const parsedCookie = Cookie.parse(cookie.toString(), { loose });
51804
+ if (!parsedCookie) {
51805
+ const err = new Error("Cookie failed to parse");
51806
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51807
+ }
51808
+ cookie = parsedCookie;
51809
+ } else if (!(cookie instanceof Cookie)) {
51810
+ const err = new Error(
51811
+ "First argument to setCookie must be a Cookie object or string"
51812
+ );
51813
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51814
+ }
51815
+ const now = options?.now || /* @__PURE__ */ new Date();
51816
+ if (this.rejectPublicSuffixes && cookie.domain) {
51817
+ try {
51818
+ const cdomain = cookie.cdomain();
51819
+ const suffix = typeof cdomain === "string" ? getPublicSuffix(cdomain, {
51820
+ allowSpecialUseDomain: this.allowSpecialUseDomain,
51821
+ ignoreError: options?.ignoreError
51822
+ }) : null;
51823
+ if (suffix == null && !IP_V6_REGEX_OBJECT.test(cookie.domain)) {
51824
+ const err = new Error("Cookie has domain set to a public suffix");
51825
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51826
+ }
51827
+ } catch (err) {
51828
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : (
51829
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
51830
+ promiseCallback.reject(err)
51831
+ );
51832
+ }
51833
+ }
51834
+ if (cookie.domain) {
51835
+ if (!domainMatch(host ?? void 0, cookie.cdomain() ?? void 0, false)) {
51836
+ const err = new Error(
51837
+ `Cookie not in this host's domain. Cookie:${cookie.cdomain() ?? "null"} Request:${host ?? "null"}`
51838
+ );
51839
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51840
+ }
51841
+ if (cookie.hostOnly == null) {
51842
+ cookie.hostOnly = false;
51843
+ }
51844
+ } else {
51845
+ cookie.hostOnly = true;
51846
+ cookie.domain = host;
51847
+ }
51848
+ if (!cookie.path || cookie.path[0] !== "/") {
51849
+ cookie.path = defaultPath(context.pathname);
51850
+ cookie.pathIsDefault = true;
51851
+ }
51852
+ if (options?.http === false && cookie.httpOnly) {
51853
+ const err = new Error("Cookie is HttpOnly and this isn't an HTTP API");
51854
+ return options.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51855
+ }
51856
+ if (cookie.sameSite !== "none" && cookie.sameSite !== void 0 && sameSiteContext) {
51857
+ if (sameSiteContext === "none") {
51858
+ const err = new Error(
51859
+ "Cookie is SameSite but this is a cross-origin request"
51860
+ );
51861
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51862
+ }
51863
+ }
51864
+ const ignoreErrorForPrefixSecurity = this.prefixSecurity === PrefixSecurityEnum.SILENT;
51865
+ const prefixSecurityDisabled = this.prefixSecurity === PrefixSecurityEnum.DISABLED;
51866
+ if (!prefixSecurityDisabled) {
51867
+ let errorFound = false;
51868
+ let errorMsg;
51869
+ if (!isSecurePrefixConditionMet(cookie)) {
51870
+ errorFound = true;
51871
+ errorMsg = "Cookie has __Secure prefix but Secure attribute is not set";
51872
+ } else if (!isHostPrefixConditionMet(cookie)) {
51873
+ errorFound = true;
51874
+ errorMsg = "Cookie has __Host prefix but either Secure or HostOnly attribute is not set or Path is not '/'";
51875
+ }
51876
+ if (errorFound) {
51877
+ return options?.ignoreError || ignoreErrorForPrefixSecurity ? promiseCallback.resolve(void 0) : promiseCallback.reject(new Error(errorMsg));
51878
+ }
51879
+ }
51880
+ const store = this.store;
51881
+ if (!store.updateCookie) {
51882
+ store.updateCookie = async function(_oldCookie, newCookie, cb2) {
51883
+ return this.putCookie(newCookie).then(
51884
+ () => cb2?.(null),
51885
+ (error) => cb2?.(error)
51886
+ );
51887
+ };
51888
+ }
51889
+ const withCookie = function withCookie2(err, oldCookie) {
51890
+ if (err) {
51891
+ cb(err);
51892
+ return;
51893
+ }
51894
+ const next = function(err2) {
51895
+ if (err2) {
51896
+ cb(err2);
51897
+ } else if (typeof cookie === "string") {
51898
+ cb(null, void 0);
51899
+ } else {
51900
+ cb(null, cookie);
51901
+ }
51902
+ };
51903
+ if (oldCookie) {
51904
+ if (options && "http" in options && options.http === false && oldCookie.httpOnly) {
51905
+ err = new Error("old Cookie is HttpOnly and this isn't an HTTP API");
51906
+ if (options.ignoreError) cb(null, void 0);
51907
+ else cb(err);
51908
+ return;
51909
+ }
51910
+ if (cookie instanceof Cookie) {
51911
+ cookie.creation = oldCookie.creation;
51912
+ cookie.creationIndex = oldCookie.creationIndex;
51913
+ cookie.lastAccessed = now;
51914
+ store.updateCookie(oldCookie, cookie, next);
51915
+ }
51916
+ } else {
51917
+ if (cookie instanceof Cookie) {
51918
+ cookie.creation = cookie.lastAccessed = now;
51919
+ store.putCookie(cookie, next);
51920
+ }
51921
+ }
51922
+ };
51923
+ store.findCookie(cookie.domain, cookie.path, cookie.key, withCookie);
51924
+ return promiseCallback.promise;
51925
+ }
51926
+ /**
51927
+ * Synchronously attempt to set the {@link Cookie} in the {@link CookieJar}.
51928
+ *
51929
+ * <strong>Note:</strong> Only works if the configured {@link Store} is also synchronous.
51930
+ *
51931
+ * @remarks
51932
+ * - If successfully persisted, the {@link Cookie} will have updated
51933
+ * {@link Cookie.creation}, {@link Cookie.lastAccessed} and {@link Cookie.hostOnly}
51934
+ * properties.
51935
+ *
51936
+ * - As per the RFC, the {@link Cookie.hostOnly} flag is set if there was no `Domain={value}`
51937
+ * attribute on the cookie string. The {@link Cookie.domain} property is set to the
51938
+ * fully-qualified hostname of `currentUrl` in this case. Matching this cookie requires an
51939
+ * exact hostname match (not a {@link domainMatch} as per usual)
51940
+ *
51941
+ * @param cookie - The cookie object or cookie string to store. A string value will be parsed into a cookie using {@link Cookie.parse}.
51942
+ * @param url - The domain to store the cookie with.
51943
+ * @param options - Configuration settings to use when storing the cookie.
51944
+ * @public
51945
+ */
51946
+ setCookieSync(cookie, url, options) {
51947
+ const setCookieFn = options ? this.setCookie.bind(this, cookie, url, options) : this.setCookie.bind(this, cookie, url);
51948
+ return this.callSync(setCookieFn);
51949
+ }
51950
+ /**
51951
+ * @internal No doc because this is the overload implementation
51952
+ */
51953
+ getCookies(url, options, callback) {
51954
+ if (typeof options === "function") {
51955
+ callback = options;
51956
+ options = defaultGetCookieOptions;
51957
+ } else if (options === void 0) {
51958
+ options = defaultGetCookieOptions;
51959
+ }
51960
+ const promiseCallback = createPromiseCallback(callback);
51961
+ const cb = promiseCallback.callback;
51962
+ let context;
51963
+ try {
51964
+ if (typeof url === "string") {
51965
+ validate2(isNonEmptyString(url), cb, url);
51966
+ }
51967
+ context = getCookieContext(url);
51968
+ validate2(
51969
+ isObject(options),
51970
+ cb,
51971
+ safeToString(options)
51972
+ );
51973
+ validate2(typeof cb === "function", cb);
51974
+ } catch (parameterError) {
51975
+ return promiseCallback.reject(parameterError);
51976
+ }
51977
+ const host = canonicalDomain(context.hostname);
51978
+ const path = context.pathname || "/";
51979
+ const potentiallyTrustworthy = isPotentiallyTrustworthy(
51980
+ url,
51981
+ this.allowSecureOnLocal
51982
+ );
51983
+ let sameSiteLevel = 0;
51984
+ if (options.sameSiteContext) {
51985
+ const sameSiteContext = checkSameSiteContext(options.sameSiteContext);
51986
+ if (sameSiteContext == null) {
51987
+ return promiseCallback.reject(new Error(SAME_SITE_CONTEXT_VAL_ERR));
51988
+ }
51989
+ sameSiteLevel = Cookie.sameSiteLevel[sameSiteContext];
51990
+ if (!sameSiteLevel) {
51991
+ return promiseCallback.reject(new Error(SAME_SITE_CONTEXT_VAL_ERR));
51992
+ }
51993
+ }
51994
+ const http = options.http ?? true;
51995
+ const now = Date.now();
51996
+ const expireCheck = options.expire ?? true;
51997
+ const allPaths = options.allPaths ?? false;
51998
+ const store = this.store;
51999
+ function matchingCookie(c) {
52000
+ if (c.hostOnly) {
52001
+ if (c.domain != host) {
52002
+ return false;
52003
+ }
52004
+ } else {
52005
+ if (!domainMatch(host ?? void 0, c.domain ?? void 0, false)) {
52006
+ return false;
52007
+ }
52008
+ }
52009
+ if (!allPaths && typeof c.path === "string" && !pathMatch(path, c.path)) {
52010
+ return false;
52011
+ }
52012
+ if (c.secure && !potentiallyTrustworthy) {
52013
+ return false;
52014
+ }
52015
+ if (c.httpOnly && !http) {
52016
+ return false;
52017
+ }
52018
+ if (sameSiteLevel) {
52019
+ let cookieLevel;
52020
+ if (c.sameSite === "lax") {
52021
+ cookieLevel = Cookie.sameSiteLevel.lax;
52022
+ } else if (c.sameSite === "strict") {
52023
+ cookieLevel = Cookie.sameSiteLevel.strict;
52024
+ } else {
52025
+ cookieLevel = Cookie.sameSiteLevel.none;
52026
+ }
52027
+ if (cookieLevel > sameSiteLevel) {
52028
+ return false;
52029
+ }
52030
+ }
52031
+ const expiryTime = c.expiryTime();
52032
+ if (expireCheck && expiryTime != void 0 && expiryTime <= now) {
52033
+ store.removeCookie(c.domain, c.path, c.key, () => {
52034
+ });
52035
+ return false;
52036
+ }
52037
+ return true;
52038
+ }
52039
+ store.findCookies(
52040
+ host,
52041
+ allPaths ? null : path,
52042
+ this.allowSpecialUseDomain,
52043
+ (err, cookies) => {
52044
+ if (err) {
52045
+ cb(err);
52046
+ return;
52047
+ }
52048
+ if (cookies == null) {
52049
+ cb(null, []);
52050
+ return;
52051
+ }
52052
+ cookies = cookies.filter(matchingCookie);
52053
+ if ("sort" in options && options.sort !== false) {
52054
+ cookies = cookies.sort(cookieCompare);
52055
+ }
52056
+ const now2 = /* @__PURE__ */ new Date();
52057
+ for (const cookie of cookies) {
52058
+ cookie.lastAccessed = now2;
52059
+ }
52060
+ cb(null, cookies);
52061
+ }
52062
+ );
52063
+ return promiseCallback.promise;
52064
+ }
52065
+ /**
52066
+ * Synchronously retrieve the list of cookies that can be sent in a Cookie header for the
52067
+ * current URL.
52068
+ *
52069
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52070
+ *
52071
+ * @remarks
52072
+ * - The array of cookies returned will be sorted according to {@link cookieCompare}.
52073
+ *
52074
+ * - The {@link Cookie.lastAccessed} property will be updated on all returned cookies.
52075
+ *
52076
+ * @param url - The domain to store the cookie with.
52077
+ * @param options - Configuration settings to use when retrieving the cookies.
52078
+ */
52079
+ getCookiesSync(url, options) {
52080
+ return this.callSync(this.getCookies.bind(this, url, options)) ?? [];
52081
+ }
52082
+ /**
52083
+ * @internal No doc because this is the overload implementation
52084
+ */
52085
+ getCookieString(url, options, callback) {
52086
+ if (typeof options === "function") {
52087
+ callback = options;
52088
+ options = void 0;
52089
+ }
52090
+ const promiseCallback = createPromiseCallback(callback);
52091
+ const next = function(err, cookies) {
52092
+ if (err) {
52093
+ promiseCallback.callback(err);
52094
+ } else {
52095
+ promiseCallback.callback(
52096
+ null,
52097
+ cookies?.sort(cookieCompare).map((c) => c.cookieString()).join("; ")
52098
+ );
52099
+ }
52100
+ };
52101
+ this.getCookies(url, options, next);
52102
+ return promiseCallback.promise;
52103
+ }
52104
+ /**
52105
+ * Synchronous version of `.getCookieString()`. Accepts the same options as `.getCookies()` but returns a string suitable for a
52106
+ * `Cookie` header rather than an Array.
52107
+ *
52108
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52109
+ *
52110
+ * @param url - The domain to store the cookie with.
52111
+ * @param options - Configuration settings to use when retrieving the cookies.
52112
+ */
52113
+ getCookieStringSync(url, options) {
52114
+ return this.callSync(
52115
+ options ? this.getCookieString.bind(this, url, options) : this.getCookieString.bind(this, url)
52116
+ ) ?? "";
52117
+ }
52118
+ /**
52119
+ * @internal No doc because this is the overload implementation
52120
+ */
52121
+ getSetCookieStrings(url, options, callback) {
52122
+ if (typeof options === "function") {
52123
+ callback = options;
52124
+ options = void 0;
52125
+ }
52126
+ const promiseCallback = createPromiseCallback(
52127
+ callback
52128
+ );
52129
+ const next = function(err, cookies) {
52130
+ if (err) {
52131
+ promiseCallback.callback(err);
52132
+ } else {
52133
+ promiseCallback.callback(
52134
+ null,
52135
+ cookies?.map((c) => {
52136
+ return c.toString();
52137
+ })
52138
+ );
52139
+ }
52140
+ };
52141
+ this.getCookies(url, options, next);
52142
+ return promiseCallback.promise;
52143
+ }
52144
+ /**
52145
+ * Synchronous version of `.getSetCookieStrings()`. Returns an array of strings suitable for `Set-Cookie` headers.
52146
+ * Accepts the same options as `.getCookies()`.
52147
+ *
52148
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52149
+ *
52150
+ * @param url - The domain to store the cookie with.
52151
+ * @param options - Configuration settings to use when retrieving the cookies.
52152
+ */
52153
+ getSetCookieStringsSync(url, options = {}) {
52154
+ return this.callSync(this.getSetCookieStrings.bind(this, url, options)) ?? [];
52155
+ }
52156
+ /**
52157
+ * @internal No doc because this is the overload implementation
52158
+ */
52159
+ serialize(callback) {
52160
+ const promiseCallback = createPromiseCallback(callback);
52161
+ let type = this.store.constructor.name;
52162
+ if (isObject(type)) {
52163
+ type = null;
52164
+ }
52165
+ const serialized = {
52166
+ // The version of tough-cookie that serialized this jar. Generally a good
52167
+ // practice since future versions can make data import decisions based on
52168
+ // known past behavior. When/if this matters, use `semver`.
52169
+ version: `tough-cookie@${version}`,
52170
+ // add the store type, to make humans happy:
52171
+ storeType: type,
52172
+ // CookieJar configuration:
52173
+ rejectPublicSuffixes: this.rejectPublicSuffixes,
52174
+ enableLooseMode: this.enableLooseMode,
52175
+ allowSpecialUseDomain: this.allowSpecialUseDomain,
52176
+ prefixSecurity: getNormalizedPrefixSecurity(this.prefixSecurity),
52177
+ // this gets filled from getAllCookies:
52178
+ cookies: []
52179
+ };
52180
+ if (typeof this.store.getAllCookies !== "function") {
52181
+ return promiseCallback.reject(
52182
+ new Error(
52183
+ "store does not support getAllCookies and cannot be serialized"
52184
+ )
52185
+ );
52186
+ }
52187
+ this.store.getAllCookies((err, cookies) => {
52188
+ if (err) {
52189
+ promiseCallback.callback(err);
52190
+ return;
52191
+ }
52192
+ if (cookies == null) {
52193
+ promiseCallback.callback(null, serialized);
52194
+ return;
52195
+ }
52196
+ serialized.cookies = cookies.map((cookie) => {
52197
+ const serializedCookie = cookie.toJSON();
52198
+ delete serializedCookie.creationIndex;
52199
+ return serializedCookie;
52200
+ });
52201
+ promiseCallback.callback(null, serialized);
52202
+ });
52203
+ return promiseCallback.promise;
52204
+ }
52205
+ /**
52206
+ * Serialize the CookieJar if the underlying store supports `.getAllCookies`.
52207
+ *
52208
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52209
+ */
52210
+ serializeSync() {
52211
+ return this.callSync((callback) => {
52212
+ this.serialize(callback);
52213
+ });
52214
+ }
52215
+ /**
52216
+ * Alias of {@link CookieJar.serializeSync}. Allows the cookie to be serialized
52217
+ * with `JSON.stringify(cookieJar)`.
52218
+ */
52219
+ toJSON() {
52220
+ return this.serializeSync();
52221
+ }
52222
+ /**
52223
+ * Use the class method CookieJar.deserialize instead of calling this directly
52224
+ * @internal
52225
+ */
52226
+ _importCookies(serialized, callback) {
52227
+ let cookies = void 0;
52228
+ if (serialized && typeof serialized === "object" && inOperator("cookies", serialized) && Array.isArray(serialized.cookies)) {
52229
+ cookies = serialized.cookies;
52230
+ }
52231
+ if (!cookies) {
52232
+ callback(new Error("serialized jar has no cookies array"), void 0);
52233
+ return;
52234
+ }
52235
+ cookies = cookies.slice();
52236
+ const putNext = (err) => {
52237
+ if (err) {
52238
+ callback(err, void 0);
52239
+ return;
52240
+ }
52241
+ if (Array.isArray(cookies)) {
52242
+ if (!cookies.length) {
52243
+ callback(err, this);
52244
+ return;
52245
+ }
52246
+ let cookie;
52247
+ try {
52248
+ cookie = Cookie.fromJSON(cookies.shift());
52249
+ } catch (e) {
52250
+ callback(e instanceof Error ? e : new Error(), void 0);
52251
+ return;
52252
+ }
52253
+ if (cookie === void 0) {
52254
+ putNext(null);
52255
+ return;
52256
+ }
52257
+ this.store.putCookie(cookie, putNext);
52258
+ }
52259
+ };
52260
+ putNext(null);
52261
+ }
52262
+ /**
52263
+ * @internal
52264
+ */
52265
+ _importCookiesSync(serialized) {
52266
+ this.callSync(this._importCookies.bind(this, serialized));
52267
+ }
52268
+ /**
52269
+ * @internal No doc because this is the overload implementation
52270
+ */
52271
+ clone(newStore, callback) {
52272
+ if (typeof newStore === "function") {
52273
+ callback = newStore;
52274
+ newStore = void 0;
52275
+ }
52276
+ const promiseCallback = createPromiseCallback(callback);
52277
+ const cb = promiseCallback.callback;
52278
+ this.serialize((err, serialized) => {
52279
+ if (err) {
52280
+ return promiseCallback.reject(err);
52281
+ }
52282
+ return _CookieJar.deserialize(serialized ?? "", newStore, cb);
52283
+ });
52284
+ return promiseCallback.promise;
52285
+ }
52286
+ /**
52287
+ * @internal
52288
+ */
52289
+ _cloneSync(newStore) {
52290
+ const cloneFn = newStore && typeof newStore !== "function" ? this.clone.bind(this, newStore) : this.clone.bind(this);
52291
+ return this.callSync((callback) => {
52292
+ cloneFn(callback);
52293
+ });
52294
+ }
52295
+ /**
52296
+ * Produces a deep clone of this CookieJar. Modifications to the original do
52297
+ * not affect the clone, and vice versa.
52298
+ *
52299
+ * <strong>Note</strong>: Only works if both the configured Store and destination
52300
+ * Store are synchronous.
52301
+ *
52302
+ * @remarks
52303
+ * - When no {@link Store} is provided, a new {@link MemoryCookieStore} will be used.
52304
+ *
52305
+ * - Transferring between store types is supported so long as the source
52306
+ * implements `.getAllCookies()` and the destination implements `.putCookie()`.
52307
+ *
52308
+ * @param newStore - The target {@link Store} to clone cookies into.
52309
+ */
52310
+ cloneSync(newStore) {
52311
+ if (!newStore) {
52312
+ return this._cloneSync();
52313
+ }
52314
+ if (!newStore.synchronous) {
52315
+ throw new Error(
52316
+ "CookieJar clone destination store is not synchronous; use async API instead."
52317
+ );
52318
+ }
52319
+ return this._cloneSync(newStore);
52320
+ }
52321
+ /**
52322
+ * @internal No doc because this is the overload implementation
52323
+ */
52324
+ removeAllCookies(callback) {
52325
+ const promiseCallback = createPromiseCallback(callback);
52326
+ const cb = promiseCallback.callback;
52327
+ const store = this.store;
52328
+ if (typeof store.removeAllCookies === "function" && store.removeAllCookies !== Store2.prototype.removeAllCookies) {
52329
+ store.removeAllCookies(cb);
52330
+ return promiseCallback.promise;
52331
+ }
52332
+ store.getAllCookies((err, cookies) => {
52333
+ if (err) {
52334
+ cb(err);
52335
+ return;
52336
+ }
52337
+ if (!cookies) {
52338
+ cookies = [];
52339
+ }
52340
+ if (cookies.length === 0) {
52341
+ cb(null, void 0);
52342
+ return;
52343
+ }
52344
+ let completedCount = 0;
52345
+ const removeErrors = [];
52346
+ const removeCookieCb = function removeCookieCb2(removeErr) {
52347
+ if (removeErr) {
52348
+ removeErrors.push(removeErr);
52349
+ }
52350
+ completedCount++;
52351
+ if (completedCount === cookies.length) {
52352
+ if (removeErrors[0]) cb(removeErrors[0]);
52353
+ else cb(null, void 0);
52354
+ return;
52355
+ }
52356
+ };
52357
+ cookies.forEach((cookie) => {
52358
+ store.removeCookie(
52359
+ cookie.domain,
52360
+ cookie.path,
52361
+ cookie.key,
52362
+ removeCookieCb
52363
+ );
52364
+ });
52365
+ });
52366
+ return promiseCallback.promise;
52367
+ }
52368
+ /**
52369
+ * Removes all cookies from the CookieJar.
52370
+ *
52371
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52372
+ *
52373
+ * @remarks
52374
+ * - This is a new backwards-compatible feature of tough-cookie version 2.5,
52375
+ * so not all Stores will implement it efficiently. For Stores that do not
52376
+ * implement `removeAllCookies`, the fallback is to call `removeCookie` after
52377
+ * `getAllCookies`.
52378
+ *
52379
+ * - If `getAllCookies` fails or isn't implemented in the Store, an error is returned.
52380
+ *
52381
+ * - If one or more of the `removeCookie` calls fail, only the first error is returned.
52382
+ */
52383
+ removeAllCookiesSync() {
52384
+ this.callSync((callback) => {
52385
+ this.removeAllCookies(callback);
52386
+ });
52387
+ }
52388
+ /**
52389
+ * @internal No doc because this is the overload implementation
52390
+ */
52391
+ static deserialize(strOrObj, store, callback) {
52392
+ if (typeof store === "function") {
52393
+ callback = store;
52394
+ store = void 0;
52395
+ }
52396
+ const promiseCallback = createPromiseCallback(callback);
52397
+ let serialized;
52398
+ if (typeof strOrObj === "string") {
52399
+ try {
52400
+ serialized = JSON.parse(strOrObj);
52401
+ } catch (e) {
52402
+ return promiseCallback.reject(e instanceof Error ? e : new Error());
52403
+ }
52404
+ } else {
52405
+ serialized = strOrObj;
52406
+ }
52407
+ const readSerializedProperty = (property) => {
52408
+ return serialized && typeof serialized === "object" && inOperator(property, serialized) ? serialized[property] : void 0;
52409
+ };
52410
+ const readSerializedBoolean = (property) => {
52411
+ const value = readSerializedProperty(property);
52412
+ return typeof value === "boolean" ? value : void 0;
52413
+ };
52414
+ const readSerializedString = (property) => {
52415
+ const value = readSerializedProperty(property);
52416
+ return typeof value === "string" ? value : void 0;
52417
+ };
52418
+ const jar = new _CookieJar(store, {
52419
+ rejectPublicSuffixes: readSerializedBoolean("rejectPublicSuffixes"),
52420
+ looseMode: readSerializedBoolean("enableLooseMode"),
52421
+ allowSpecialUseDomain: readSerializedBoolean("allowSpecialUseDomain"),
52422
+ prefixSecurity: getNormalizedPrefixSecurity(
52423
+ readSerializedString("prefixSecurity") ?? "silent"
52424
+ )
52425
+ });
52426
+ jar._importCookies(serialized, (err) => {
52427
+ if (err) {
52428
+ promiseCallback.callback(err);
52429
+ return;
52430
+ }
52431
+ promiseCallback.callback(null, jar);
52432
+ });
52433
+ return promiseCallback.promise;
52434
+ }
52435
+ /**
52436
+ * A new CookieJar is created and the serialized {@link Cookie} values are added to
52437
+ * the underlying store. Each {@link Cookie} is added via `store.putCookie(...)` in
52438
+ * the order in which they appear in the serialization.
52439
+ *
52440
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52441
+ *
52442
+ * @remarks
52443
+ * - When no {@link Store} is provided, a new {@link MemoryCookieStore} will be used.
52444
+ *
52445
+ * - As a convenience, if `strOrObj` is a string, it is passed through `JSON.parse` first.
52446
+ *
52447
+ * @param strOrObj - A JSON string or object representing the deserialized cookies.
52448
+ * @param store - The underlying store to persist the deserialized cookies into.
52449
+ */
52450
+ static deserializeSync(strOrObj, store) {
52451
+ const serialized = typeof strOrObj === "string" ? JSON.parse(strOrObj) : strOrObj;
52452
+ const readSerializedProperty = (property) => {
52453
+ return serialized && typeof serialized === "object" && inOperator(property, serialized) ? serialized[property] : void 0;
52454
+ };
52455
+ const readSerializedBoolean = (property) => {
52456
+ const value = readSerializedProperty(property);
52457
+ return typeof value === "boolean" ? value : void 0;
52458
+ };
52459
+ const readSerializedString = (property) => {
52460
+ const value = readSerializedProperty(property);
52461
+ return typeof value === "string" ? value : void 0;
52462
+ };
52463
+ const jar = new _CookieJar(store, {
52464
+ rejectPublicSuffixes: readSerializedBoolean("rejectPublicSuffixes"),
52465
+ looseMode: readSerializedBoolean("enableLooseMode"),
52466
+ allowSpecialUseDomain: readSerializedBoolean("allowSpecialUseDomain"),
52467
+ prefixSecurity: getNormalizedPrefixSecurity(
52468
+ readSerializedString("prefixSecurity") ?? "silent"
52469
+ )
52470
+ });
52471
+ if (!jar.store.synchronous) {
52472
+ throw new Error(
52473
+ "CookieJar store is not synchronous; use async API instead."
52474
+ );
52475
+ }
52476
+ jar._importCookiesSync(serialized);
52477
+ return jar;
52478
+ }
52479
+ /**
52480
+ * Alias of {@link CookieJar.deserializeSync}.
52481
+ *
52482
+ * @remarks
52483
+ * - When no {@link Store} is provided, a new {@link MemoryCookieStore} will be used.
52484
+ *
52485
+ * - As a convenience, if `strOrObj` is a string, it is passed through `JSON.parse` first.
52486
+ *
52487
+ * @param jsonString - A JSON string or object representing the deserialized cookies.
52488
+ * @param store - The underlying store to persist the deserialized cookies into.
52489
+ */
52490
+ static fromJSON(jsonString, store) {
52491
+ return _CookieJar.deserializeSync(jsonString, store);
52492
+ }
52493
+ };
52494
+ }
52495
+ });
52496
+
49523
52497
  // src/site-analyze/crawl-look.ts
49524
52498
  function patternOf(hay) {
49525
52499
  const h = hay.toLowerCase();
@@ -49578,20 +52552,57 @@ function copyFromEval(evaled) {
49578
52552
  ...Object.keys(meta).length ? { meta } : {}
49579
52553
  };
49580
52554
  }
49581
- async function createPlaywrightBrowser() {
52555
+ function forwardedRequestHeaders(all) {
52556
+ const out = {};
52557
+ for (const name of FORWARDED_REQUEST_HEADERS) {
52558
+ const value = all[name];
52559
+ if (value !== void 0) out[name] = value;
52560
+ }
52561
+ return out;
52562
+ }
52563
+ async function toPlaywrightCookies(setCookies, url) {
52564
+ const jar = new CookieJar();
52565
+ const out = [];
52566
+ for (const raw of setCookies) {
52567
+ let cookie;
52568
+ try {
52569
+ cookie = await jar.setCookie(raw, url.toString());
52570
+ } catch {
52571
+ continue;
52572
+ }
52573
+ if (!cookie || !cookie.path) continue;
52574
+ const expiresMs = cookie.expiryTime();
52575
+ const expiresSeconds = expiresMs === -Infinity ? 0 : Number.isFinite(expiresMs) ? expiresMs / 1e3 : void 0;
52576
+ const sameSite = cookie.sameSite === "strict" || cookie.sameSite === "lax" || cookie.sameSite === "none" ? cookie.sameSite[0].toUpperCase() + cookie.sameSite.slice(1) : void 0;
52577
+ out.push({
52578
+ name: cookie.key,
52579
+ value: cookie.value,
52580
+ domain: cookie.hostOnly ? url.hostname : `.${cookie.domain}`,
52581
+ path: cookie.path,
52582
+ ...expiresSeconds !== void 0 ? { expires: expiresSeconds } : {},
52583
+ ...cookie.httpOnly ? { httpOnly: true } : {},
52584
+ ...cookie.secure ? { secure: true } : {},
52585
+ ...sameSite ? { sameSite } : {}
52586
+ });
52587
+ }
52588
+ return out;
52589
+ }
52590
+ async function createPlaywrightBrowser(load = () => import("playwright"), siteFetch = guardedSiteFetch) {
49582
52591
  const screenshots = [];
49583
52592
  let pw;
49584
52593
  try {
49585
- pw = await import("playwright");
52594
+ pw = await load();
49586
52595
  } catch {
49587
52596
  return {
49588
52597
  port: { crawl: async () => ({ unavailable: `playwright_not_installed: ${PLAYWRIGHT_HINT}`, pages: [], navLabels: [], theme: null }) },
49589
52598
  screenshots,
49590
- unavailable: `playwright_not_installed: ${PLAYWRIGHT_HINT}`
52599
+ unavailable: `playwright_not_installed: ${PLAYWRIGHT_HINT}`,
52600
+ siteFetch
49591
52601
  };
49592
52602
  }
49593
52603
  const port = {
49594
52604
  async crawl({ siteUrl, budget = 12 }) {
52605
+ assertPublicSiteUrl(siteUrl);
49595
52606
  let browser;
49596
52607
  try {
49597
52608
  browser = await pw.chromium.launch({ headless: true });
@@ -49600,6 +52611,52 @@ async function createPlaywrightBrowser() {
49600
52611
  }
49601
52612
  try {
49602
52613
  const page = await browser.newPage();
52614
+ await page.route("**/*", async (route) => {
52615
+ const request = route.request();
52616
+ if (request.resourceType() !== "document") {
52617
+ await route.continue();
52618
+ return;
52619
+ }
52620
+ try {
52621
+ const headers2 = forwardedRequestHeaders(await request.allHeaders());
52622
+ const res = await siteFetch(request.url(), {
52623
+ redirect: "manual",
52624
+ headers: headers2,
52625
+ signal: AbortSignal.timeout(DOCUMENT_FETCH_TIMEOUT_MS)
52626
+ });
52627
+ const target = new URL(request.url());
52628
+ const location = res.headers.get("location");
52629
+ if (REDIRECT_STATUS.has(res.status) && location) {
52630
+ await discardBody(res);
52631
+ const setCookies2 = res.headers.getSetCookie();
52632
+ if (setCookies2.length) {
52633
+ const cookies = await toPlaywrightCookies(setCookies2, target);
52634
+ if (cookies.length) await page.context().addCookies(cookies);
52635
+ }
52636
+ await route.fulfill({ status: res.status, headers: { location }, body: Buffer.alloc(0) });
52637
+ return;
52638
+ }
52639
+ const capped = await readCapped(res, MAX_DOCUMENT_BYTES);
52640
+ if (!capped) {
52641
+ await route.abort();
52642
+ return;
52643
+ }
52644
+ const setCookies = res.headers.getSetCookie();
52645
+ if (setCookies.length) {
52646
+ const cookies = await toPlaywrightCookies(setCookies, target);
52647
+ if (cookies.length) await page.context().addCookies(cookies);
52648
+ }
52649
+ const headersOut = {};
52650
+ res.headers.forEach((value, key2) => {
52651
+ const k = key2.toLowerCase();
52652
+ if (k === "content-encoding" || k === "content-length" || k === "transfer-encoding" || k === "set-cookie") return;
52653
+ headersOut[key2] = value;
52654
+ });
52655
+ await route.fulfill({ status: res.status, headers: headersOut, body: capped });
52656
+ } catch {
52657
+ await route.abort();
52658
+ }
52659
+ });
49603
52660
  const fontFaceUrls = [];
49604
52661
  page.on("response", (response) => {
49605
52662
  try {
@@ -49728,16 +52785,19 @@ async function createPlaywrightBrowser() {
49728
52785
  }
49729
52786
  }
49730
52787
  };
49731
- return { port, screenshots };
52788
+ return { port, screenshots, siteFetch };
49732
52789
  }
49733
- var PLAYWRIGHT_HINT, PAGE_EVAL, CAP2;
52790
+ var PLAYWRIGHT_HINT, PAGE_EVAL, CAP2, DOCUMENT_FETCH_TIMEOUT_MS, MAX_DOCUMENT_BYTES, FORWARDED_REQUEST_HEADERS;
49734
52791
  var init_crawl_look = __esm({
49735
52792
  "src/site-analyze/crawl-look.ts"() {
52793
+ init_dist();
49736
52794
  init_copy_clean();
49737
52795
  init_traits();
49738
52796
  init_velo();
49739
52797
  init_published_html();
49740
52798
  init_rest();
52799
+ init_net_guard();
52800
+ init_write_artifacts();
49741
52801
  PLAYWRIGHT_HINT = "npx playwright install chromium";
49742
52802
  PAGE_EVAL = `(() => {
49743
52803
  const wst = {};
@@ -49936,6 +52996,9 @@ var init_crawl_look = __esm({
49936
52996
  meta: 300,
49937
52997
  sections: 40
49938
52998
  };
52999
+ DOCUMENT_FETCH_TIMEOUT_MS = 12e3;
53000
+ MAX_DOCUMENT_BYTES = 15e6;
53001
+ FORWARDED_REQUEST_HEADERS = ["user-agent", "accept-language", "accept", "cookie", "referer"];
49939
53002
  }
49940
53003
  });
49941
53004
 
@@ -50561,15 +53624,20 @@ var init_site_function = __esm({
50561
53624
  var cli_exports = {};
50562
53625
  __export(cli_exports, {
50563
53626
  SITE_FUNCTION_USAGE: () => SITE_FUNCTION_USAGE,
53627
+ assetFetchFor: () => assetFetchFor,
50564
53628
  noteWithWarnings: () => noteWithWarnings,
50565
53629
  runSiteAnalyze: () => runSiteAnalyze,
50566
53630
  runSiteFunctionCli: () => runSiteFunctionCli
50567
53631
  });
50568
53632
  import { readFileSync as readFileSync63 } from "node:fs";
50569
53633
  import { resolve as resolve41 } from "node:path";
53634
+ function assetFetchFor(_opts) {
53635
+ return pinnedFetch2;
53636
+ }
50570
53637
  async function runSiteAnalyze(opts) {
50571
53638
  const fetchImpl = opts.fetchImpl ?? fetch;
50572
- const assetFetch = opts.fetchImpl ?? pinnedFetch2;
53639
+ const assetFetch = assetFetchFor(opts);
53640
+ const siteFetch = guardedSiteFetch;
50573
53641
  const cwd = opts.cwd ?? process.cwd();
50574
53642
  const outDir = resolve41(cwd, opts.outDir ?? ".himi/business-book");
50575
53643
  let ownerAuth;
@@ -50584,6 +53652,7 @@ async function runSiteAnalyze(opts) {
50584
53652
  const pw = await createPlaywrightBrowser();
50585
53653
  const ports = {
50586
53654
  fetch: fetchImpl,
53655
+ siteFetch,
50587
53656
  ownerAuth,
50588
53657
  browser: pw.unavailable ? void 0 : pw.port,
50589
53658
  lookUnavailableReason: pw.unavailable
@@ -52349,8 +55418,8 @@ var DEFAULT_MAX_RUNS = 20;
52349
55418
  var ATTESTATION_VERSION = 2;
52350
55419
  function attestationVersionOf(value) {
52351
55420
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
52352
- const version = value.attestation;
52353
- return typeof version === "number" && Number.isInteger(version) && version > 0 ? version : null;
55421
+ const version2 = value.attestation;
55422
+ return typeof version2 === "number" && Number.isInteger(version2) && version2 > 0 ? version2 : null;
52354
55423
  }
52355
55424
  function classifyRetainedRun(dir, name) {
52356
55425
  let value;
@@ -52360,9 +55429,9 @@ function classifyRetainedRun(dir, name) {
52360
55429
  return { kind: "unreadable" };
52361
55430
  }
52362
55431
  if (isAttestationV2(value)) return { kind: "current", run: value };
52363
- const version = attestationVersionOf(value);
52364
- if (version === null || version === ATTESTATION_VERSION) return { kind: "malformed" };
52365
- return { kind: version < ATTESTATION_VERSION ? "legacy" : "future" };
55432
+ const version2 = attestationVersionOf(value);
55433
+ if (version2 === null || version2 === ATTESTATION_VERSION) return { kind: "malformed" };
55434
+ return { kind: version2 < ATTESTATION_VERSION ? "legacy" : "future" };
52366
55435
  }
52367
55436
  function screenshotArtifactPath(contentDir2, hash) {
52368
55437
  return join6(resolve6(contentDir2), ".himi", "attestations", "artifacts", `${hash}.png`);
@@ -52862,12 +55931,12 @@ function penalty(m, size) {
52862
55931
  }
52863
55932
  function encodeQr(text2) {
52864
55933
  const bytes2 = [...new TextEncoder().encode(text2)];
52865
- const version = fitVersion(bytes2.length);
52866
- if (!version) {
55934
+ const version2 = fitVersion(bytes2.length);
55935
+ if (!version2) {
52867
55936
  throw new RangeError(`QR payload too long: ${bytes2.length} bytes exceeds version ${QR_MAX_VERSION} at EC level L`);
52868
55937
  }
52869
- const codewords = interleave(encodeData(bytes2, version), version);
52870
- const size = version * 4 + 17;
55938
+ const codewords = interleave(encodeData(bytes2, version2), version2);
55939
+ const size = version2 * 4 + 17;
52871
55940
  const modules = Array.from({ length: size }, () => new Array(size).fill(false));
52872
55941
  const reserved = Array.from({ length: size }, () => new Array(size).fill(false));
52873
55942
  const set = (x, y, dark) => {
@@ -52890,8 +55959,8 @@ function encodeQr(text2) {
52890
55959
  set(i, 6, i % 2 === 0);
52891
55960
  set(6, i, i % 2 === 0);
52892
55961
  }
52893
- for (const ay of alignmentPositions(version))
52894
- for (const ax of alignmentPositions(version)) {
55962
+ for (const ay of alignmentPositions(version2))
55963
+ for (const ax of alignmentPositions(version2)) {
52895
55964
  if (ax === 6 && ay === 6 || ax === 6 && ay === size - 7 || ax === size - 7 && ay === 6) continue;
52896
55965
  for (let dy = -2; dy <= 2; dy++)
52897
55966
  for (let dx = -2; dx <= 2; dx++) set(ax + dx, ay + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);
@@ -52905,7 +55974,7 @@ function encodeQr(text2) {
52905
55974
  reserved[8][size - 1 - i] = true;
52906
55975
  }
52907
55976
  set(8, size - 8, true);
52908
- if (version >= 7)
55977
+ if (version2 >= 7)
52909
55978
  for (let i = 0; i < 18; i++) {
52910
55979
  const a = size - 11 + i % 3, b = Math.floor(i / 3);
52911
55980
  reserved[a][b] = true;
@@ -52932,7 +56001,7 @@ function encodeQr(text2) {
52932
56001
  for (let y = 0; y < size; y++)
52933
56002
  for (let x = 0; x < size; x++) if (!reserved[y][x] && MASKS[mask](x, y)) cand[y][x] = !cand[y][x];
52934
56003
  applyFormat(cand, size, mask);
52935
- if (version >= 7) applyVersion(cand, size, version);
56004
+ if (version2 >= 7) applyVersion(cand, size, version2);
52936
56005
  const s = penalty(cand, size);
52937
56006
  if (s < bestScore) {
52938
56007
  bestScore = s;
@@ -52940,7 +56009,7 @@ function encodeQr(text2) {
52940
56009
  bestMask = mask;
52941
56010
  }
52942
56011
  }
52943
- return { size, version, mask: bestMask, modules: best };
56012
+ return { size, version: version2, mask: bestMask, modules: best };
52944
56013
  }
52945
56014
  function applyFormat(m, size, mask) {
52946
56015
  const bits = bchFormat(1 << 3 | mask);
@@ -52957,8 +56026,8 @@ function applyFormat(m, size, mask) {
52957
56026
  for (let i = 8; i < 15; i++) put(8, size - 15 + i, on3(i));
52958
56027
  put(8, size - 8, true);
52959
56028
  }
52960
- function applyVersion(m, size, version) {
52961
- const bits = bchVersion(version);
56029
+ function applyVersion(m, size, version2) {
56030
+ const bits = bchVersion(version2);
52962
56031
  for (let i = 0; i < 18; i++) {
52963
56032
  const on3 = (bits >>> i & 1) === 1;
52964
56033
  const a = size - 11 + i % 3, b = Math.floor(i / 3);
@@ -55747,7 +58816,7 @@ async function fetchPackumentFrom(registry, fetchImpl, timeoutMs) {
55747
58816
  const json5 = await response.json();
55748
58817
  const latest = typeof json5?.["dist-tags"]?.latest === "string" ? json5["dist-tags"].latest : void 0;
55749
58818
  const time = {};
55750
- for (const [version, when] of Object.entries(json5?.time ?? {})) if (typeof when === "string") time[version] = when;
58819
+ for (const [version2, when] of Object.entries(json5?.time ?? {})) if (typeof when === "string") time[version2] = when;
55751
58820
  return latest ? { latest, time, registry: normalizeRegistry(registry) ?? registry } : void 0;
55752
58821
  } catch {
55753
58822
  return void 0;
@@ -55770,8 +58839,8 @@ function ageInDays(publishedAt, now = Date.now()) {
55770
58839
  }
55771
58840
  function packageVersion(path) {
55772
58841
  try {
55773
- const version = JSON.parse(readFileSync65(path, "utf8")).version;
55774
- return typeof version === "string" && version ? version : void 0;
58842
+ const version2 = JSON.parse(readFileSync65(path, "utf8")).version;
58843
+ return typeof version2 === "string" && version2 ? version2 : void 0;
55775
58844
  } catch {
55776
58845
  return void 0;
55777
58846
  }
@@ -55779,8 +58848,8 @@ function packageVersion(path) {
55779
58848
  function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
55780
58849
  let dir = resolve42(fromDir);
55781
58850
  for (; ; ) {
55782
- const version = packageVersion(join51(dir, "node_modules", "@wix", "himalaya", "package.json"));
55783
- if (version) return { version, source: "local" };
58851
+ const version2 = packageVersion(join51(dir, "node_modules", "@wix", "himalaya", "package.json"));
58852
+ if (version2) return { version: version2, source: "local" };
55784
58853
  const parent = dirname30(dir);
55785
58854
  if (parent === dir) break;
55786
58855
  dir = parent;
@@ -55789,8 +58858,8 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
55789
58858
  if (bundled) return { version: bundled, source: "bundled" };
55790
58859
  try {
55791
58860
  const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
55792
- const version = root ? packageVersion(join51(root, "@wix", "himalaya", "package.json")) : void 0;
55793
- return version ? { version, source: "global" } : {};
58861
+ const version2 = root ? packageVersion(join51(root, "@wix", "himalaya", "package.json")) : void 0;
58862
+ return version2 ? { version: version2, source: "global" } : {};
55794
58863
  } catch {
55795
58864
  return {};
55796
58865
  }
@@ -55881,17 +58950,17 @@ function globalPrefixWritable() {
55881
58950
  return false;
55882
58951
  }
55883
58952
  }
55884
- function npmInstallArgs(registry, version) {
58953
+ function npmInstallArgs(registry, version2) {
55885
58954
  const pinned = `${normalizeRegistry(registry) ?? registry}/`;
55886
- return ["i", "-g", `${CLI_PACKAGE}@${version}`, `--registry=${pinned}`, `--@wix:registry=${pinned}`];
58955
+ return ["i", "-g", `${CLI_PACKAGE}@${version2}`, `--registry=${pinned}`, `--@wix:registry=${pinned}`];
55887
58956
  }
55888
58957
  var INSTALLABLE_SPEC = /^(?:latest|\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/;
55889
58958
  function createUpdateRunner(spawn5 = spawnSync5) {
55890
58959
  return {
55891
- install: async (registry, version) => {
58960
+ install: async (registry, version2) => {
55892
58961
  if (!isTrustedRegistry(registry)) return { ok: false, detail: `refusing untrusted registry ${registry}` };
55893
- if (!INSTALLABLE_SPEC.test(version)) return { ok: false, detail: `refusing install spec ${JSON.stringify(version)}` };
55894
- const result = spawn5("npm", npmInstallArgs(registry, version), {
58962
+ if (!INSTALLABLE_SPEC.test(version2)) return { ok: false, detail: `refusing install spec ${JSON.stringify(version2)}` };
58963
+ const result = spawn5("npm", npmInstallArgs(registry, version2), {
55895
58964
  // npm's stdout goes to OUR stderr: in `himi <cmd> --json | jq` (and `himi upgrade --json`) its
55896
58965
  // "added 212 packages" would otherwise land in stdout ahead of the envelope and break the
55897
58966
  // parse — the agent case this whole feature exists for (#2985 review). And no stdin: an
@@ -56559,7 +59628,7 @@ function loginModeMark(m) {
56559
59628
  return /NOT checked/.test(m.detail) ? "unchecked" : "yes";
56560
59629
  }
56561
59630
  function buildDoctorReport(input) {
56562
- const { target, version, data, serve, auth, loginModes, dpxStatus, versions } = input;
59631
+ const { target, version: version2, data, serve, auth, loginModes, dpxStatus, versions } = input;
56563
59632
  const serveCode = serve.reachable ? void 0 : target === "local" ? "no_local_serve" : "needs_vpn";
56564
59633
  const sdkSkew = versions?.sdk.status === "outdated" && versions?.sdk.source !== "bundled";
56565
59634
  const versionSkew = versions?.cli.status === "outdated" || sdkSkew;
@@ -56568,7 +59637,7 @@ function buildDoctorReport(input) {
56568
59637
  return {
56569
59638
  ok,
56570
59639
  target,
56571
- version,
59640
+ version: version2,
56572
59641
  dataPlane: { ...data, note: "public Wix APIs \u2014 reachable off-VPN" },
56573
59642
  servePlane: {
56574
59643
  ...serve,
@@ -60806,9 +63875,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
60806
63875
  input.close();
60807
63876
  }
60808
63877
  },
60809
- releasePlayerJob: async (release, version) => {
63878
+ releasePlayerJob: async (release, version2) => {
60810
63879
  const c = new ServeCliClient(resolveTarget({ target: playerTarget }));
60811
- const created = await c.distCreate({ app: "himi-player", platform: "ios", shell: "player", release, destination: "testflight", version });
63880
+ const created = await c.distCreate({ app: "himi-player", platform: "ios", shell: "player", release, destination: "testflight", version: version2 });
60812
63881
  if (!created.ok) throw new Error(`Job Service refused the Player TestFlight build (HTTP ${created.status})`);
60813
63882
  const jobs = created.json?.jobs ?? [];
60814
63883
  const jobId = jobs.find((candidate) => candidate.platform === "ios")?.jobId;
@@ -61619,9 +64688,9 @@ ${label2}`);
61619
64688
  else io.log(`himi ${before} (unchanged \u2014 ${registry} has nothing newer; its latest is ${answered.latest})`);
61620
64689
  return 0;
61621
64690
  }
61622
- const version = answered?.latest ?? "latest";
61623
- io.error(`upgrading ${CLI_PACKAGE} (running v${before}) to ${version} from ${registry}\u2026`);
61624
- const installed = await runner2.install(registry, version);
64691
+ const version2 = answered?.latest ?? "latest";
64692
+ io.error(`upgrading ${CLI_PACKAGE} (running v${before}) to ${version2} from ${registry}\u2026`);
64693
+ const installed = await runner2.install(registry, version2);
61625
64694
  if (!installed.ok) {
61626
64695
  const detail = installed.detail ?? "unknown error";
61627
64696
  if (flags.json) print({ ok: false, error: "upgrade_failed", running: before, registry, detail });
@@ -62183,3 +65252,37 @@ export {
62183
65252
  writePngFile,
62184
65253
  writeUpdateCache
62185
65254
  };
65255
+ /*! Bundled license information:
65256
+
65257
+ tough-cookie/dist/index.js:
65258
+ (*!
65259
+ * Copyright (c) 2015-2020, Salesforce.com, Inc.
65260
+ * All rights reserved.
65261
+ *
65262
+ * Redistribution and use in source and binary forms, with or without
65263
+ * modification, are permitted provided that the following conditions are met:
65264
+ *
65265
+ * 1. Redistributions of source code must retain the above copyright notice,
65266
+ * this list of conditions and the following disclaimer.
65267
+ *
65268
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
65269
+ * this list of conditions and the following disclaimer in the documentation
65270
+ * and/or other materials provided with the distribution.
65271
+ *
65272
+ * 3. Neither the name of Salesforce.com nor the names of its contributors may
65273
+ * be used to endorse or promote products derived from this software without
65274
+ * specific prior written permission.
65275
+ *
65276
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
65277
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65278
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65279
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
65280
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65281
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
65282
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65283
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
65284
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65285
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
65286
+ * POSSIBILITY OF SUCH DAMAGE.
65287
+ *)
65288
+ */