@wix/himalaya-cli 0.982.0 → 0.984.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 (29) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/notification-preferences/src/index.d.ts +105 -33
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-notification-preferences.mjs +66 -5
  3. package/dist/cli.mjs +3437 -331
  4. package/fixtures/wix-canned.json +36 -29
  5. package/guides/sdk-reference.json +86 -49
  6. package/package.json +3 -2
  7. package/templates/beauty-salon/dev/index.ts +27 -2
  8. package/templates/beauty-salon/tier5-src/himi-branded-lite-order/index.ts +14 -6
  9. package/templates/beauty-salon/tier5-src/himi-store-account/index.ts +59 -20
  10. package/templates/branded-lite/dev/index.ts +27 -2
  11. package/templates/branded-lite/tier5-src/himi-branded-lite-notifsettings/index.ts +42 -14
  12. package/templates/branded-lite/tier5-src/himi-branded-lite-order/index.ts +14 -6
  13. package/templates/branded-lite/tier5-src/himi-store-account/index.ts +59 -20
  14. package/templates/community-club/tier5-src/himi-store-account/index.ts +59 -20
  15. package/templates/events-meetups/tier5-src/himi-store-account/index.ts +59 -20
  16. package/templates/gym-fitness/dev/index.ts +27 -2
  17. package/templates/gym-fitness/tier5-src/himi-branded-lite-order/index.ts +14 -6
  18. package/templates/gym-fitness/tier5-src/himi-store-account/index.ts +59 -20
  19. package/templates/nonprofit-cause/tier5-src/himi-store-account/index.ts +59 -20
  20. package/templates/podcast-creator/tier5-src/himi-store-account/index.ts +59 -20
  21. package/templates/portfolio-creative/dev/index.ts +25 -1
  22. package/templates/portfolio-creative/tier5-src/himi-branded-lite-order/index.ts +14 -6
  23. package/templates/portfolio-creative/tier5-src/himi-store-account/index.ts +59 -20
  24. package/templates/restaurant/tier5-src/himi-store-account/index.ts +59 -20
  25. package/templates/retail-store/dev/index.ts +25 -1
  26. package/templates/retail-store/tier5-src/himi-branded-lite-order/index.ts +14 -6
  27. package/templates/retail-store/tier5-src/himi-store-account/index.ts +59 -20
  28. package/templates/yoga-studio/dev/index.ts +2 -1
  29. package/templates/yoga-studio/tier5-src/himi-store-account/index.ts +59 -20
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) {
@@ -3448,6 +3471,9 @@ var init_build_lib = __esm({
3448
3471
  // as @himalaya/state.
3449
3472
  "@himalaya/time": resolve8(REPO_ROOT4, "core/sdk/time/src/index.ts"),
3450
3473
  "@himalaya/widget": resolve8(REPO_ROOT4, "core/sdk/widget/src/index.ts"),
3474
+ // RFC 0036. The app-level nav workers consume its pure `readNotificationEvent`
3475
+ // parser + `setBadge`; demo-app-push has its own build.mjs and predates this entry.
3476
+ "@himalaya/push": resolve8(REPO_ROOT4, "core/sdk/push/src/index.ts"),
3451
3477
  "@himalaya/dispatch": resolve8(REPO_ROOT4, "core/sdk/dispatch/src/index.ts"),
3452
3478
  // stdlib/flows/* — composed flow modules (auth, checkout). Not capabilities:
3453
3479
  // they wrap capabilities + native dispatch actions that already exist. See
@@ -4200,7 +4226,7 @@ var init_build = __esm({
4200
4226
 
4201
4227
  // ../../core/dev-server/src/quickjs-intl.ts
4202
4228
  function installIntl(ctx) {
4203
- const parse = (s) => {
4229
+ const parse2 = (s) => {
4204
4230
  if (!s) return void 0;
4205
4231
  try {
4206
4232
  return JSON.parse(
@@ -4216,8 +4242,8 @@ function installIntl(ctx) {
4216
4242
  "__himiIntlDate",
4217
4243
  (l, o, t) => {
4218
4244
  const fmt = new Intl.DateTimeFormat(
4219
- parse(ctx.getString(l)),
4220
- parse(ctx.getString(o))
4245
+ parse2(ctx.getString(l)),
4246
+ parse2(ctx.getString(o))
4221
4247
  );
4222
4248
  return ctx.newString(fmt.format(new Date(ctx.getNumber(t))));
4223
4249
  }
@@ -4244,8 +4270,8 @@ function installIntl(ctx) {
4244
4270
  (k, t, l, o) => {
4245
4271
  const kind = ctx.getString(k);
4246
4272
  const date = new Date(ctx.getNumber(t));
4247
- const locales = parse(ctx.getString(l));
4248
- const options = parse(ctx.getString(o));
4273
+ const locales = parse2(ctx.getString(l));
4274
+ const options = parse2(ctx.getString(o));
4249
4275
  const out = kind === "d" ? date.toLocaleDateString(locales, options) : kind === "t" ? date.toLocaleTimeString(locales, options) : date.toLocaleString(locales, options);
4250
4276
  return ctx.newString(out);
4251
4277
  }
@@ -4254,8 +4280,8 @@ function installIntl(ctx) {
4254
4280
  "__himiIntlNumber",
4255
4281
  (l, o, v, k) => {
4256
4282
  const fmt = new Intl.NumberFormat(
4257
- parse(ctx.getString(l)),
4258
- parse(ctx.getString(o))
4283
+ parse2(ctx.getString(l)),
4284
+ parse2(ctx.getString(o))
4259
4285
  );
4260
4286
  const raw = ctx.getString(v);
4261
4287
  const kind = k === void 0 ? "n" : ctx.getString(k);
@@ -4267,8 +4293,8 @@ function installIntl(ctx) {
4267
4293
  "__himiIntlCompare",
4268
4294
  (a, b, l, o) => {
4269
4295
  const collator = new Intl.Collator(
4270
- parse(ctx.getString(l)),
4271
- parse(o === void 0 ? "" : ctx.getString(o))
4296
+ parse2(ctx.getString(l)),
4297
+ parse2(o === void 0 ? "" : ctx.getString(o))
4272
4298
  );
4273
4299
  return ctx.newNumber(collator.compare(ctx.getString(a), ctx.getString(b)));
4274
4300
  }
@@ -4280,8 +4306,8 @@ function installIntl(ctx) {
4280
4306
  // crawled path may never reach.
4281
4307
  "__himiIntlValidate",
4282
4308
  (k, l, o) => {
4283
- const locales = parse(ctx.getString(l));
4284
- const options = parse(ctx.getString(o));
4309
+ const locales = parse2(ctx.getString(l));
4310
+ const options = parse2(ctx.getString(o));
4285
4311
  switch (ctx.getString(k)) {
4286
4312
  case "DateTimeFormat":
4287
4313
  new Intl.DateTimeFormat(locales, options);
@@ -4771,7 +4797,7 @@ function installWebGlobals(ctx) {
4771
4797
  });
4772
4798
  ctx.setProp(ctx.global, "__himiQueryEncode", queryEncode);
4773
4799
  queryEncode.dispose();
4774
- const parse = ctx.newFunction("__himiParseUrl", (hrefH, baseH) => {
4800
+ const parse2 = ctx.newFunction("__himiParseUrl", (hrefH, baseH) => {
4775
4801
  const href = ctx.getString(hrefH);
4776
4802
  const base = ctx.getString(baseH);
4777
4803
  try {
@@ -4781,8 +4807,8 @@ function installWebGlobals(ctx) {
4781
4807
  return ctx.newString(JSON.stringify({ error: err?.message ?? "Invalid URL" }));
4782
4808
  }
4783
4809
  });
4784
- ctx.setProp(ctx.global, "__himiParseUrl", parse);
4785
- parse.dispose();
4810
+ ctx.setProp(ctx.global, "__himiParseUrl", parse2);
4811
+ parse2.dispose();
4786
4812
  const res = ctx.evalCode(WEB_GLOBALS_SHIM, "himi-web-globals.js");
4787
4813
  if (res.error) {
4788
4814
  const detail = ctx.dump(res.error);
@@ -5450,9 +5476,9 @@ function scanWidgetPayload(node, family, path, bindings, disallowed, timeRefs, i
5450
5476
  }
5451
5477
  }
5452
5478
  function validateWidget(snapshot2) {
5453
- const validate2 = compileWidgetSchema();
5454
- const schemaOk = validate2(snapshot2);
5455
- const schemaErrors = schemaOk ? [] : validate2.errors ?? [];
5479
+ const validate3 = compileWidgetSchema();
5480
+ const schemaOk = validate3(snapshot2);
5481
+ const schemaErrors = schemaOk ? [] : validate3.errors ?? [];
5456
5482
  const bindingViolations = [];
5457
5483
  const disallowedComponents = [];
5458
5484
  const timeRefViolations = [];
@@ -18831,7 +18857,6 @@ function shouldRevealError(args) {
18831
18857
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
18832
18858
  var init_validation = __esm({
18833
18859
  "../../core/ts/src/validation.ts"() {
18834
- "use strict";
18835
18860
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
18836
18861
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
18837
18862
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -22256,7 +22281,6 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
22256
22281
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
22257
22282
  var init_worker_subtree = __esm({
22258
22283
  "../../core/ts/src/worker-subtree.ts"() {
22259
- "use strict";
22260
22284
  init_worker_subtree_safe_types_generated();
22261
22285
  WORKER_SUBTREE_CEILINGS = Object.freeze({
22262
22286
  maxEncodedBytes: 65536,
@@ -22533,7 +22557,7 @@ function ensureMeasureRuntime() {
22533
22557
  if (measureRuntimeInjected || typeof document === "undefined") return;
22534
22558
  measureRuntimeInjected = true;
22535
22559
  const store = {};
22536
- const parse = (s) => {
22560
+ const parse2 = (s) => {
22537
22561
  if (!s) return {};
22538
22562
  try {
22539
22563
  const o = JSON.parse(s);
@@ -22544,13 +22568,13 @@ function ensureMeasureRuntime() {
22544
22568
  };
22545
22569
  const applyConsumers = () => {
22546
22570
  document.querySelectorAll("[data-hm-measure-bind]").forEach((el) => {
22547
- const patch = measureConsumerStyle(parse(el.getAttribute("data-hm-measure-bind")), store);
22571
+ const patch = measureConsumerStyle(parse2(el.getAttribute("data-hm-measure-bind")), store);
22548
22572
  const style = el.style;
22549
22573
  for (const k of Object.keys(patch)) style[k] = patch[k];
22550
22574
  });
22551
22575
  };
22552
22576
  const measure = (el) => {
22553
- const cfg = parse(el.getAttribute("data-hm-measure"));
22577
+ const cfg = parse2(el.getAttribute("data-hm-measure"));
22554
22578
  const rect = el.getBoundingClientRect();
22555
22579
  let changed = false;
22556
22580
  if (cfg.h) {
@@ -35626,7 +35650,7 @@ var init_dependencies = __esm({
35626
35650
  // ../../core/functions-build/src/sbom.ts
35627
35651
  import { createHash as createHash16 } from "node:crypto";
35628
35652
  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 }));
35653
+ 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
35654
  const body = JSON.stringify({ format: "himalaya-sbom-v1", components: components2 });
35631
35655
  return { format: "himalaya-sbom-v1", components: components2, hash: createHash16("sha256").update(body).digest("hex") };
35632
35656
  }
@@ -39723,7 +39747,7 @@ function ipv6Private(address) {
39723
39747
  const value = address.toLowerCase().replace(/^\[|\]$/g, "");
39724
39748
  const sections = value.split("::");
39725
39749
  if (sections.length > 2) return true;
39726
- const parse = (section2) => {
39750
+ const parse2 = (section2) => {
39727
39751
  if (!section2) return [];
39728
39752
  const parts = section2.split(":");
39729
39753
  const last = parts.at(-1) ?? "";
@@ -39733,8 +39757,8 @@ function ipv6Private(address) {
39733
39757
  if (octets.length !== 4 || octets.some((octet) => !Number.isInteger(octet) || octet < 0 || octet > 255)) return [Number.NaN];
39734
39758
  return [...parts.map((part) => Number.parseInt(part, 16)), octets[0] * 256 + octets[1], octets[2] * 256 + octets[3]];
39735
39759
  };
39736
- const head = parse(sections[0]);
39737
- const tail = parse(sections[1] ?? "");
39760
+ const head = parse2(sections[0]);
39761
+ const tail = parse2(sections[1] ?? "");
39738
39762
  const words = sections.length === 2 ? [...head, ...Array.from({ length: Math.max(0, 8 - head.length - tail.length) }, () => 0), ...tail] : [...head];
39739
39763
  if (words.length !== 8 || words.some((word) => !Number.isInteger(word) || word < 0 || word > 65535)) return true;
39740
39764
  const mappedOrCompatible = words.slice(0, 5).every((word) => word === 0) && (words[5] === 0 || words[5] === 65535);
@@ -39747,8 +39771,8 @@ function ipv6Private(address) {
39747
39771
  return value.startsWith("fe8") || value.startsWith("fe9") || value.startsWith("fea") || value.startsWith("feb") || Number.isFinite(firstWord) && (firstWord & 65024) === 64512;
39748
39772
  }
39749
39773
  function privateAddress(address) {
39750
- const version = isIP(address);
39751
- return version === 4 ? ipv4Private(address) : version === 6 ? ipv6Private(address) : true;
39774
+ const version2 = isIP(address);
39775
+ return version2 === 4 ? ipv4Private(address) : version2 === 6 ? ipv6Private(address) : true;
39752
39776
  }
39753
39777
  async function checkDestination(url, options) {
39754
39778
  if (!/^https?:$/.test(url.protocol) || url.username || url.password) throw new Error("only credential-free HTTP(S) URLs are allowed");
@@ -40481,8 +40505,8 @@ function planResourceChange(input) {
40481
40505
  const reusable = versions.filter((candidate) => candidate.status === "retired" && candidate.type === field.type).toSorted((left, right) => right.version - left.version)[0];
40482
40506
  if (!current && reusable) operations.push({ kind: "restore-field", collection: request.name, field: field.key, version: reusable.version });
40483
40507
  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 } });
40508
+ const version2 = (latest?.version ?? 0) + 1;
40509
+ 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
40510
  } else if (current.type !== field.type && reusable) operations.push({ kind: "restore-field", collection: request.name, field: field.key, version: reusable.version });
40487
40511
  else if (current.type !== field.type) operations.push({ kind: "replace-field", collection: request.name, logicalName: field.key, type: field.type, displayName: field.displayName });
40488
40512
  }
@@ -44185,9 +44209,9 @@ async function runWixMobileRelease(pos, flags, io, deps) {
44185
44209
  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
44210
  if (on(flags["no-wait"])) return fail2("--no-wait is not supported for Himi Player TestFlight releases; wait for MRE processing to complete");
44187
44211
  const release = str(flags.release);
44188
- const version = str(flags.version);
44212
+ const version2 = str(flags.version);
44189
44213
  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)");
44214
+ if (!version2 || !/^\d+(?:\.\d+){0,2}$/.test(version2)) return fail2("--version needs the Player marketing version (for example 1.0.0)");
44191
44215
  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
44216
  const plan = {
44193
44217
  ok: true,
@@ -44195,7 +44219,7 @@ async function runWixMobileRelease(pos, flags, io, deps) {
44195
44219
  provider: "wix-mobile-release",
44196
44220
  app,
44197
44221
  release,
44198
- version,
44222
+ version: version2,
44199
44223
  destination: "TestFlight \xB7 Wix-owned Himi Player \xB7 internal upload",
44200
44224
  steps: ["Himi Job Service iOS build", "approved-bucket validation", "POCO MRE provisioning and re-sign", "MRE TestFlight upload", "MRE status poll"]
44201
44225
  };
@@ -44206,13 +44230,13 @@ async function runWixMobileRelease(pos, flags, io, deps) {
44206
44230
  if (!deps.releasePlayerJob) return fail2("this Himi CLI cannot create a service-side Himi Player TestFlight job; target deployed serve");
44207
44231
  if (!on(flags.yes)) {
44208
44232
  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?`)) {
44233
+ if (!await deps.confirm(` Dispatch Himi Player ${version2} to Wix TestFlight?`)) {
44210
44234
  io.log(" aborted \u2014 no release was dispatched.");
44211
44235
  return 1;
44212
44236
  }
44213
44237
  }
44214
44238
  try {
44215
- const released = await deps.releasePlayerJob(release, version);
44239
+ const released = await deps.releasePlayerJob(release, version2);
44216
44240
  const status = released.status.toUpperCase();
44217
44241
  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
44242
  print({ ok: true, provider: "wix-mobile-release", app, jobId: released.jobId, ...released.requestId ? { requestId: released.requestId } : {}, status, ...released.url ? { url: released.url } : {} });
@@ -44245,11 +44269,11 @@ function pad(label2, width = 12) {
44245
44269
  return label2.length >= width ? label2 : label2 + " ".repeat(width - label2.length);
44246
44270
  }
44247
44271
  function accountHeader(args) {
44248
- const { app, bundleId, version, nextBuild, creds, track } = args;
44272
+ const { app, bundleId, version: version2, nextBuild, creds, track } = args;
44249
44273
  const issuer = creds.ascIssuerId.length <= 8 ? creds.ascIssuerId : `${creds.ascIssuerId.slice(0, 8)}\u2026`;
44250
44274
  const account = creds.source === "env" ? "from ASC_* environment" : `profile "${creds.profile}" (${creds.source === "flag" ? "--profile" : "store.config.yaml"})`;
44251
44275
  return [
44252
- ` ${pad("app")}${app} ios ${version.marketing} (${version.build} \u2192 ${nextBuild})`,
44276
+ ` ${pad("app")}${app} ios ${version2.marketing} (${version2.build} \u2192 ${nextBuild})`,
44253
44277
  ` ${pad("bundle")}${bundleId}`,
44254
44278
  ` ${pad("team")}${creds.team} key ${creds.ascKeyId} \xB7 issuer ${issuer}`,
44255
44279
  ` ${pad("account")}${account}`,
@@ -44352,25 +44376,25 @@ async function runStore(pos, flags, io, deps) {
44352
44376
  }
44353
44377
  const bundleId = cfg.ios?.bundleId ?? "(unset)";
44354
44378
  let creds;
44355
- let version;
44379
+ let version2;
44356
44380
  try {
44357
44381
  creds = deps.resolveCredentials({ app, cfg, profileFlag: str2(flags.profile) });
44358
- version = deps.readVersion(app);
44382
+ version2 = deps.readVersion(app);
44359
44383
  } catch (e) {
44360
44384
  return fail2(e.message);
44361
44385
  }
44362
- if (!Number.isInteger(version.build)) {
44386
+ if (!Number.isInteger(version2.build)) {
44363
44387
  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 }
44388
+ `${app} has a non-integer CFBundleVersion (${JSON.stringify(version2.build)}) \u2014 this command bumps and matches build numbers arithmetically. Use an integer CFBundleVersion.`,
44389
+ { app, marketing: version2.marketing }
44366
44390
  );
44367
44391
  }
44368
44392
  const reuseExisting = on2(flags["skip-build"]);
44369
- const nextBuild = reuseExisting ? version.build : version.build + 1;
44393
+ const nextBuild = reuseExisting ? version2.build : version2.build + 1;
44370
44394
  const plannedSteps = UPLOAD_STEPS.filter((s) => !(reuseExisting && BUILD_STEPS.has(s)));
44371
44395
  if (!json5) {
44372
44396
  io.log("");
44373
- for (const line of accountHeader({ app, bundleId, version, nextBuild, creds, track })) io.log(line);
44397
+ for (const line of accountHeader({ app, bundleId, version: version2, nextBuild, creds, track })) io.log(line);
44374
44398
  io.log("");
44375
44399
  for (const f of findings) io.log(` ${f.level === "error" ? "\u2717" : "!"} ${f.message}`);
44376
44400
  }
@@ -44392,7 +44416,7 @@ async function runStore(pos, flags, io, deps) {
44392
44416
  ascKeyId: creds.ascKeyId,
44393
44417
  credentialSource: creds.source,
44394
44418
  ...creds.profile ? { credentialProfile: creds.profile } : {},
44395
- version: { marketing: version.marketing, build: version.build, next: nextBuild },
44419
+ version: { marketing: version2.marketing, build: version2.build, next: nextBuild },
44396
44420
  steps: [...plannedSteps],
44397
44421
  warnings: warnings.map((w) => w.message)
44398
44422
  };
@@ -44411,7 +44435,7 @@ async function runStore(pos, flags, io, deps) {
44411
44435
  { app, track, team: creds.team }
44412
44436
  );
44413
44437
  }
44414
- const okToGo = await deps.confirm(` Upload ${app} ${version.marketing} (${nextBuild}) to App Store Connect team ${creds.team}?`);
44438
+ const okToGo = await deps.confirm(` Upload ${app} ${version2.marketing} (${nextBuild}) to App Store Connect team ${creds.team}?`);
44415
44439
  if (!okToGo) {
44416
44440
  io.log(" aborted \u2014 nothing was built or uploaded.");
44417
44441
  return 1;
@@ -44419,16 +44443,16 @@ async function runStore(pos, flags, io, deps) {
44419
44443
  }
44420
44444
  let uploaded;
44421
44445
  try {
44422
- uploaded = reuseExisting ? version : deps.bumpBuild(app);
44446
+ uploaded = reuseExisting ? version2 : deps.bumpBuild(app);
44423
44447
  } catch (e) {
44424
44448
  return fail2(`could not bump the build number: ${e.message}`);
44425
44449
  }
44426
44450
  const rollback = () => {
44427
44451
  if (reuseExisting) return;
44428
44452
  try {
44429
- deps.setVersion(app, version);
44453
+ deps.setVersion(app, version2);
44430
44454
  } catch (e) {
44431
- io.error(JSON.stringify({ warning: `could not restore the build number to ${version.build}: ${e.message}` }));
44455
+ io.error(JSON.stringify({ warning: `could not restore the build number to ${version2.build}: ${e.message}` }));
44432
44456
  }
44433
44457
  };
44434
44458
  for (const step of plannedSteps) {
@@ -47635,7 +47659,297 @@ var init_permissions = __esm({
47635
47659
  }
47636
47660
  });
47637
47661
 
47662
+ // src/site-analyze/net-guard.ts
47663
+ import { lookup as dnsLookup } from "node:dns";
47664
+ import { request as httpsRequest2 } from "node:https";
47665
+ import { Readable as Readable2 } from "node:stream";
47666
+ import { createBrotliDecompress, createGunzip, createInflate } from "node:zlib";
47667
+ function ipv4Octets(host) {
47668
+ const m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
47669
+ if (!m) return null;
47670
+ const octets = m.slice(1).map(Number);
47671
+ return octets.every((o) => o <= 255) ? octets : null;
47672
+ }
47673
+ function isPrivateV4([a, b, c]) {
47674
+ if (a === 0 || a === 127) return true;
47675
+ if (a === 10) return true;
47676
+ if (a === 192 && b === 168) return true;
47677
+ if (a === 172 && b >= 16 && b <= 31) return true;
47678
+ if (a === 169 && b === 254) return true;
47679
+ if (a === 100 && b >= 64 && b <= 127) return true;
47680
+ if (a === 192 && b === 0 && c === 0) return true;
47681
+ if (a === 192 && b === 0 && c === 2) return true;
47682
+ if (a === 198 && b === 51 && c === 100) return true;
47683
+ if (a === 203 && b === 0 && c === 113) return true;
47684
+ if (a === 198 && (b === 18 || b === 19)) return true;
47685
+ if (a === 192 && b === 88 && c === 99) return true;
47686
+ return a >= 224;
47687
+ }
47688
+ function v6Groups(host) {
47689
+ let text2 = host;
47690
+ const dotted = /:((?:\d{1,3}\.){3}\d{1,3})$/.exec(text2);
47691
+ if (dotted) {
47692
+ const octets = ipv4Octets(dotted[1]);
47693
+ if (!octets) return null;
47694
+ const hi = (octets[0] << 8 | octets[1]).toString(16);
47695
+ const lo = (octets[2] << 8 | octets[3]).toString(16);
47696
+ text2 = `${text2.slice(0, dotted.index)}:${hi}:${lo}`;
47697
+ }
47698
+ const halves = text2.split("::");
47699
+ if (halves.length > 2) return null;
47700
+ const parts = (part) => part ? part.split(":") : [];
47701
+ const head = parts(halves[0]);
47702
+ const tail = halves.length === 2 ? parts(halves[1]) : [];
47703
+ const fill = 8 - head.length - tail.length;
47704
+ if (halves.length === 2 && fill < 0) return null;
47705
+ const groups = halves.length === 2 ? [...head, ...new Array(fill).fill("0"), ...tail] : head;
47706
+ if (groups.length !== 8) return null;
47707
+ const out = groups.map((g) => /^[0-9a-f]{1,4}$/i.test(g) ? parseInt(g, 16) : NaN);
47708
+ return out.every((g) => Number.isInteger(g)) ? out : null;
47709
+ }
47710
+ function isPrivateV6(host) {
47711
+ const g = v6Groups(host);
47712
+ if (!g) return true;
47713
+ const embedded = (hi, lo) => isPrivateV4([hi >> 8, hi & 255, lo >> 8, lo & 255]);
47714
+ const leadingZeros = g.slice(0, 5).every((x) => x === 0);
47715
+ if (leadingZeros && g[5] === 0) return true;
47716
+ if (leadingZeros && g[5] === 65535) return embedded(g[6], g[7]);
47717
+ if ((g[0] & 65280) === 0) return true;
47718
+ if ((g[0] & 65024) === 64512) return true;
47719
+ if ((g[0] & 65472) === 65152) return true;
47720
+ if ((g[0] & 65472) === 65216) return true;
47721
+ if ((g[0] & 65280) === 65280) return true;
47722
+ if (g[0] === 100 && g[1] === 65435) return true;
47723
+ if (g[0] === 256 && g[1] === 0 && g[2] === 0 && g[3] === 0) return true;
47724
+ if (g[0] === 8193 && g[1] <= 511) return true;
47725
+ if (g[0] === 8193 && g[1] === 3512) return true;
47726
+ if (g[0] === 16383 && (g[1] & 61440) === 0) return true;
47727
+ if (g[0] === 24320) return true;
47728
+ if (g[0] === 8194) return embedded(g[1], g[2]);
47729
+ return false;
47730
+ }
47731
+ function isBlockedAddress(address) {
47732
+ const host = address.toLowerCase().replace(/^\[|\]$/g, "");
47733
+ if (!host) return true;
47734
+ const v4 = ipv4Octets(host);
47735
+ if (v4) return isPrivateV4(v4);
47736
+ if (host.includes(":")) return isPrivateV6(host);
47737
+ return true;
47738
+ }
47739
+ function isFetchableFontUrl(raw) {
47740
+ let url;
47741
+ try {
47742
+ url = new URL(raw);
47743
+ } catch {
47744
+ return false;
47745
+ }
47746
+ if (url.protocol !== "https:") return false;
47747
+ const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.+$/, "");
47748
+ if (!host) return false;
47749
+ if (host === "localhost" || host.endsWith(".localhost")) return false;
47750
+ if (host.endsWith(".internal") || host.endsWith(".local")) return false;
47751
+ const v4 = ipv4Octets(host);
47752
+ if (v4) return !isPrivateV4(v4);
47753
+ if (host.includes(":")) return !isPrivateV6(host);
47754
+ return true;
47755
+ }
47756
+ function siteUrlRefusal(raw) {
47757
+ const shown2 = JSON.stringify(raw.length > 200 ? `${raw.slice(0, 200)}\u2026` : raw);
47758
+ let url;
47759
+ try {
47760
+ url = new URL(raw);
47761
+ } catch {
47762
+ return `refusing to fetch ${shown2}: it is not a URL \u2014 a scheme is required. Allowed: ${PUBLIC_SITE_RULE}.`;
47763
+ }
47764
+ if (url.protocol !== "https:") {
47765
+ return `refusing to fetch ${shown2}: scheme "${url.protocol}" is not https. Allowed: ${PUBLIC_SITE_RULE}.`;
47766
+ }
47767
+ if (url.port && url.port !== "443") {
47768
+ return `refusing to fetch ${shown2}: port ${url.port} is not the default 443. Allowed: ${PUBLIC_SITE_RULE}.`;
47769
+ }
47770
+ if (!isFetchableFontUrl(url.href)) {
47771
+ return `refusing to fetch ${shown2}: host "${url.hostname}" is not a public host. Allowed: ${PUBLIC_SITE_RULE}.`;
47772
+ }
47773
+ return null;
47774
+ }
47775
+ function assertPublicSiteUrl(raw) {
47776
+ const refusal = siteUrlRefusal(raw);
47777
+ if (refusal) throw new Error(refusal);
47778
+ }
47779
+ function resolveAll(hostname2) {
47780
+ return new Promise((resolve43, reject) => {
47781
+ dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
47782
+ if (err) reject(err);
47783
+ else resolve43(addresses);
47784
+ });
47785
+ });
47786
+ }
47787
+ function withAbort(start, signal, what) {
47788
+ if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
47789
+ const work = start();
47790
+ if (!signal) return work;
47791
+ return new Promise((resolve43, reject) => {
47792
+ const onAbort = () => reject(new Error(`${what} aborted`));
47793
+ signal.addEventListener("abort", onAbort, { once: true });
47794
+ work.then(resolve43, reject).finally(() => signal.removeEventListener("abort", onAbort));
47795
+ });
47796
+ }
47797
+ async function pinAddress(url, resolve43 = resolveAll, signal) {
47798
+ const host = url.hostname.replace(/^\[|\]$/g, "");
47799
+ if (ipv4Octets(host)) {
47800
+ if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
47801
+ return { address: host, family: 4 };
47802
+ }
47803
+ if (host.includes(":")) {
47804
+ if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
47805
+ return { address: host, family: 6 };
47806
+ }
47807
+ const addresses = await withAbort(() => resolve43(host), signal, `${host} lookup`);
47808
+ if (!addresses.length) throw new Error(`${host} resolved to no address`);
47809
+ const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
47810
+ if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
47811
+ return { address: addresses[0].address, family: addresses[0].family };
47812
+ }
47813
+ function realPin(url, signal) {
47814
+ return pinAddress(url, resolveAll, signal);
47815
+ }
47816
+ function decodedBody(res, hasBody) {
47817
+ if (!hasBody) return res;
47818
+ const codings = (res.headers["content-encoding"] ?? "").split(",").map((c) => c.trim().toLowerCase()).filter((c) => c && c !== "identity");
47819
+ const makers = codings.reverse().map((coding) => {
47820
+ const make = DECODERS.get(coding);
47821
+ if (!make) throw new Error(`unsupported content-encoding "${coding}"`);
47822
+ return make;
47823
+ });
47824
+ let out = res;
47825
+ for (const make of makers) {
47826
+ const next = make();
47827
+ out.on("error", (err) => next.emit("error", err));
47828
+ out = out.pipe(next);
47829
+ }
47830
+ return out;
47831
+ }
47832
+ function copyIncomingHeaders(headers2) {
47833
+ const out = new Headers();
47834
+ for (const [k, v] of Object.entries(headers2)) {
47835
+ if (typeof v === "string") out.set(k, v);
47836
+ else if (Array.isArray(v)) {
47837
+ if (k.toLowerCase() === "set-cookie") {
47838
+ for (const one of v) out.append(k, one);
47839
+ } else {
47840
+ out.set(k, v.join(", "));
47841
+ }
47842
+ }
47843
+ }
47844
+ return out;
47845
+ }
47846
+ function requestOnce(url, pinned, init) {
47847
+ return new Promise((resolve43, reject) => {
47848
+ const headers2 = { host: url.host, "accept-encoding": "identity" };
47849
+ new Headers(init.headers ?? {}).forEach((value, key2) => {
47850
+ if (key2.toLowerCase() !== "host") headers2[key2] = value;
47851
+ });
47852
+ const req = httpsRequest2(
47853
+ {
47854
+ // The ADDRESS is what we connect to; `servername` and the Host header keep the NAME, so
47855
+ // SNI and certificate validation are exactly what they would have been. Pinning by
47856
+ // rewriting the url to an IP would have broken both.
47857
+ host: pinned.address,
47858
+ servername: url.hostname.replace(/^\[|\]$/g, ""),
47859
+ port: url.port ? Number(url.port) : 443,
47860
+ path: `${url.pathname}${url.search}`,
47861
+ method: (init.method ?? "GET").toUpperCase(),
47862
+ headers: headers2,
47863
+ family: pinned.family
47864
+ },
47865
+ (res) => {
47866
+ const status = res.statusCode ?? 0;
47867
+ const out = copyIncomingHeaders(res.headers);
47868
+ const hasBody = status !== 204 && status !== 304 && (init.method ?? "GET").toUpperCase() !== "HEAD";
47869
+ let body = null;
47870
+ try {
47871
+ body = hasBody ? Readable2.toWeb(decodedBody(res, hasBody)) : null;
47872
+ } catch (err) {
47873
+ res.resume();
47874
+ reject(err);
47875
+ return;
47876
+ }
47877
+ resolve43(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
47878
+ }
47879
+ );
47880
+ req.on("error", reject);
47881
+ const signal = init.signal;
47882
+ if (signal) {
47883
+ if (signal.aborted) req.destroy(new Error("aborted"));
47884
+ else signal.addEventListener("abort", () => req.destroy(new Error("aborted")), { once: true });
47885
+ }
47886
+ req.end();
47887
+ });
47888
+ }
47889
+ async function discardBody(res) {
47890
+ try {
47891
+ await res?.body?.cancel();
47892
+ } catch {
47893
+ }
47894
+ }
47895
+ async function followPinned(href, init, perform, pin = (u, s) => pinAddress(u, resolveAll, s), allow = ASSET_HOP) {
47896
+ let url = new URL(href);
47897
+ for (let hop = 0; ; hop += 1) {
47898
+ const refusal = allow(url);
47899
+ if (refusal) throw new Error(refusal);
47900
+ const pinned = await pin(url, init.signal);
47901
+ const res = await perform(url, pinned, init);
47902
+ const location = res.headers.get("location");
47903
+ if (!REDIRECT_STATUS.has(res.status) || !location) return res;
47904
+ const mode = init.redirect ?? "follow";
47905
+ if (mode === "manual") return res;
47906
+ await discardBody(res);
47907
+ if (mode === "error") throw new Error(`redirect refused by redirect:"error" at ${url.href}`);
47908
+ if (hop >= MAX_REDIRECTS) throw new Error(`too many redirects from ${url.href}`);
47909
+ url = new URL(location, url);
47910
+ }
47911
+ }
47912
+ function makePinnedFetch(allow, label2, pin = realPin, perform = requestOnce) {
47913
+ const transport = (async (input, init) => {
47914
+ if (typeof input !== "string" && !(input instanceof URL)) {
47915
+ throw new TypeError(`${label2} takes a url \u2014 the analyzer's Request-shaped calls use the API transport`);
47916
+ }
47917
+ if (init?.body != null) {
47918
+ throw new TypeError(`${label2} is GET-only \u2014 a request with a body belongs on the API transport`);
47919
+ }
47920
+ const method = (init?.method ?? "GET").toUpperCase();
47921
+ if (method !== "GET" && method !== "HEAD") {
47922
+ throw new TypeError(`${label2} is GET-only, refusing ${method}`);
47923
+ }
47924
+ return followPinned(input instanceof URL ? input.href : input, init ?? {}, perform, pin, allow);
47925
+ });
47926
+ transport.pin = pin;
47927
+ transport.perform = perform;
47928
+ return transport;
47929
+ }
47930
+ var PUBLIC_SITE_RULE, DECODERS, MAX_REDIRECTS, REDIRECT_STATUS, ASSET_HOP, SITE_HOP, pinnedFetch2, guardedSiteFetch;
47931
+ var init_net_guard = __esm({
47932
+ "src/site-analyze/net-guard.ts"() {
47933
+ 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";
47934
+ DECODERS = /* @__PURE__ */ new Map([
47935
+ ["gzip", createGunzip],
47936
+ ["x-gzip", createGunzip],
47937
+ ["deflate", createInflate],
47938
+ ["br", createBrotliDecompress]
47939
+ ]);
47940
+ MAX_REDIRECTS = 5;
47941
+ REDIRECT_STATUS = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
47942
+ ASSET_HOP = (url) => isFetchableFontUrl(url.href) ? null : `refusing to fetch ${url.href}`;
47943
+ SITE_HOP = (url) => siteUrlRefusal(url.href);
47944
+ pinnedFetch2 = makePinnedFetch(ASSET_HOP, "pinnedFetch");
47945
+ guardedSiteFetch = makePinnedFetch(SITE_HOP, "guardedSiteFetch");
47946
+ }
47947
+ });
47948
+
47638
47949
  // src/site-analyze/analyze.ts
47950
+ function siteFetchFor(ports) {
47951
+ return ports.siteFetch ?? guardedSiteFetch;
47952
+ }
47639
47953
  function localeFromSiteLanguage(languageCode) {
47640
47954
  const tag = languageCode.trim().toLowerCase().split(/[-_]/)[0] ?? "";
47641
47955
  if (tag === "he" || tag === "es") return { default: tag, pin: true };
@@ -47646,6 +47960,7 @@ async function analyzeSite(input, ports) {
47646
47960
  const siteUrl = input.siteUrl.trim();
47647
47961
  if (!clientId) throw new Error("clientId is required");
47648
47962
  if (!siteUrl) throw new Error("siteUrl is required");
47963
+ assertPublicSiteUrl(siteUrl);
47649
47964
  const redirectUri = input.redirectUri?.trim() ? assertRedirectUri(input.redirectUri) : void 0;
47650
47965
  const visitorToken = await mintVisitorToken(ports.fetch, clientId);
47651
47966
  const visitor = visitorTransportFrom(ports.fetch, visitorToken, input.msid ?? ports.ownerAuth?.msid);
@@ -47662,7 +47977,7 @@ async function analyzeSite(input, ports) {
47662
47977
  theme: null
47663
47978
  }));
47664
47979
  const probesP = runDualProbes(owner, visitor);
47665
- const publishedP = readPublishedHtml(ports.fetch, siteUrl);
47980
+ const publishedP = readPublishedHtml(siteFetchFor(ports), siteUrl);
47666
47981
  const catsP = Promise.all([
47667
47982
  readStoreCategories(owner ?? visitor),
47668
47983
  readBlogCategories(owner ?? visitor),
@@ -47969,6 +48284,7 @@ var init_analyze = __esm({
47969
48284
  init_copy();
47970
48285
  init_permissions();
47971
48286
  init_published_html();
48287
+ init_net_guard();
47972
48288
  SCREENSHOT_NAME = /^(home|shop|book|menu|blog|about|contact|events|gallery|plans|faq|library|members|other)-\d+\.png$/i;
47973
48289
  }
47974
48290
  });
@@ -48314,246 +48630,6 @@ var init_book = __esm({
48314
48630
  }
48315
48631
  });
48316
48632
 
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
48633
  // ../native-config/brand-font.ts
48558
48634
  import { create as createFont } from "fontkit";
48559
48635
  import { decompress } from "wawoff2";
@@ -49520,6 +49596,2907 @@ var init_apply2 = __esm({
49520
49596
  }
49521
49597
  });
49522
49598
 
49599
+ // ../../node_modules/tldts/dist/cjs/index.js
49600
+ var require_cjs = __commonJS({
49601
+ "../../node_modules/tldts/dist/cjs/index.js"(exports) {
49602
+ "use strict";
49603
+ function shareSameDomainSuffix(hostname2, vhost) {
49604
+ if (hostname2.endsWith(vhost)) {
49605
+ return hostname2.length === vhost.length || hostname2[hostname2.length - vhost.length - 1] === ".";
49606
+ }
49607
+ return false;
49608
+ }
49609
+ function extractDomainWithSuffix(hostname2, publicSuffix) {
49610
+ const publicSuffixIndex = hostname2.length - publicSuffix.length - 2;
49611
+ const lastDotBeforeSuffixIndex = hostname2.lastIndexOf(".", publicSuffixIndex);
49612
+ if (lastDotBeforeSuffixIndex === -1) {
49613
+ return hostname2;
49614
+ }
49615
+ return hostname2.slice(lastDotBeforeSuffixIndex + 1);
49616
+ }
49617
+ function getDomain$1(suffix, hostname2, options) {
49618
+ if (options.validHosts !== null) {
49619
+ const validHosts = options.validHosts;
49620
+ for (const vhost of validHosts) {
49621
+ if (
49622
+ /*@__INLINE__*/
49623
+ shareSameDomainSuffix(hostname2, vhost)
49624
+ ) {
49625
+ return vhost;
49626
+ }
49627
+ }
49628
+ }
49629
+ let numberOfLeadingDots = 0;
49630
+ if (hostname2.startsWith(".")) {
49631
+ while (numberOfLeadingDots < hostname2.length && hostname2[numberOfLeadingDots] === ".") {
49632
+ numberOfLeadingDots += 1;
49633
+ }
49634
+ }
49635
+ if (suffix.length === hostname2.length - numberOfLeadingDots) {
49636
+ return null;
49637
+ }
49638
+ return (
49639
+ /*@__INLINE__*/
49640
+ extractDomainWithSuffix(hostname2, suffix)
49641
+ );
49642
+ }
49643
+ function getDomainWithoutSuffix$1(domain, suffix) {
49644
+ return domain.slice(0, -suffix.length - 1);
49645
+ }
49646
+ var CONTROL_CHARS3 = /[\t\n\r]/g;
49647
+ var extractedHostnameValidated = false;
49648
+ function isValidHostnameChar(code) {
49649
+ return code >= 97 && code <= 122 || // a-z
49650
+ code >= 48 && code <= 57 || // 0-9
49651
+ code > 127 || // non-ASCII (accepted, not punycode-checked)
49652
+ code >= 65 && code <= 90 || // A-Z (becomes valid once lowercased)
49653
+ code === 45 || // '-'
49654
+ code === 95;
49655
+ }
49656
+ function getSpecialScheme(url, schemeStart, colonIndex) {
49657
+ const length = colonIndex - schemeStart;
49658
+ const c0 = url.charCodeAt(schemeStart) | 32;
49659
+ if (length === 2) {
49660
+ return c0 === 119 && (url.charCodeAt(schemeStart + 1) | 32) === 115 ? 1 : 0;
49661
+ } else if (length === 3) {
49662
+ const c1 = url.charCodeAt(schemeStart + 1) | 32;
49663
+ const c2 = url.charCodeAt(schemeStart + 2) | 32;
49664
+ if (c0 === 119 && c1 === 115 && c2 === 115)
49665
+ return 1;
49666
+ if (c0 === 102 && c1 === 116 && c2 === 112)
49667
+ return 1;
49668
+ return 0;
49669
+ } else if (length === 4) {
49670
+ const c1 = url.charCodeAt(schemeStart + 1) | 32;
49671
+ const c2 = url.charCodeAt(schemeStart + 2) | 32;
49672
+ const c3 = url.charCodeAt(schemeStart + 3) | 32;
49673
+ if (c0 === 104 && c1 === 116 && c2 === 116 && c3 === 112)
49674
+ return 1;
49675
+ if (c0 === 102 && c1 === 105 && c2 === 108 && c3 === 101)
49676
+ return 2;
49677
+ return 0;
49678
+ } else if (length === 5) {
49679
+ 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;
49680
+ }
49681
+ return 0;
49682
+ }
49683
+ function extractHostname(url, urlIsValidHostname, validate3 = false) {
49684
+ let start = 0;
49685
+ let end = url.length;
49686
+ let hasUpper = false;
49687
+ let isSpecial = false;
49688
+ extractedHostnameValidated = false;
49689
+ if (!urlIsValidHostname) {
49690
+ if (url.startsWith("data:")) {
49691
+ return null;
49692
+ }
49693
+ while (start < url.length && url.charCodeAt(start) <= 32) {
49694
+ start += 1;
49695
+ }
49696
+ while (end > start + 1 && url.charCodeAt(end - 1) <= 32) {
49697
+ end -= 1;
49698
+ }
49699
+ if (url.charCodeAt(start) === 47 && url.charCodeAt(start + 1) === 47) {
49700
+ start += 2;
49701
+ } else {
49702
+ const indexOfProtocol = url.indexOf(":/", start);
49703
+ if (indexOfProtocol !== -1) {
49704
+ const special = getSpecialScheme(url, start, indexOfProtocol);
49705
+ if (special === 1) {
49706
+ isSpecial = true;
49707
+ start = indexOfProtocol + 2;
49708
+ while (url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) {
49709
+ start += 1;
49710
+ }
49711
+ } else if (special === 2) {
49712
+ isSpecial = true;
49713
+ start = indexOfProtocol + 1;
49714
+ let slashes = 0;
49715
+ while ((url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) && slashes < 2) {
49716
+ start += 1;
49717
+ slashes += 1;
49718
+ }
49719
+ if (slashes < 2) {
49720
+ return null;
49721
+ }
49722
+ } else {
49723
+ for (let i = start; i < indexOfProtocol; i += 1) {
49724
+ const code = url.charCodeAt(i) | 32;
49725
+ if (!(code >= 97 && code <= 122 || // [a, z]
49726
+ code >= 48 && code <= 57 || // [0, 9]
49727
+ code === 46 || // '.'
49728
+ code === 45 || // '-'
49729
+ code === 43)) {
49730
+ const raw = url.charCodeAt(i);
49731
+ if (raw === 9 || raw === 10 || raw === 13) {
49732
+ return extractHostname(url.replace(CONTROL_CHARS3, ""), urlIsValidHostname, validate3);
49733
+ }
49734
+ return null;
49735
+ }
49736
+ }
49737
+ if (url.charCodeAt(indexOfProtocol + 2) === 47) {
49738
+ start = indexOfProtocol + 3;
49739
+ } else {
49740
+ return null;
49741
+ }
49742
+ }
49743
+ } else if (url.charCodeAt(start) !== 91) {
49744
+ let indexOfColon = -1;
49745
+ for (let i = start; i < end; i += 1) {
49746
+ const code = url.charCodeAt(i);
49747
+ if (code === 9 || code === 10 || code === 13) {
49748
+ return extractHostname(url.replace(CONTROL_CHARS3, ""), urlIsValidHostname, validate3);
49749
+ }
49750
+ if (code === 58) {
49751
+ indexOfColon = i;
49752
+ break;
49753
+ }
49754
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49755
+ break;
49756
+ }
49757
+ }
49758
+ if (indexOfColon !== -1) {
49759
+ let hasIdentifier = false;
49760
+ for (let i = indexOfColon + 1; i < end; i += 1) {
49761
+ const code = url.charCodeAt(i);
49762
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49763
+ break;
49764
+ }
49765
+ if (code === 64) {
49766
+ hasIdentifier = true;
49767
+ break;
49768
+ }
49769
+ }
49770
+ if (!hasIdentifier) {
49771
+ let allDigits = true;
49772
+ let i = indexOfColon + 1;
49773
+ for (; i < end; i += 1) {
49774
+ const code = url.charCodeAt(i);
49775
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49776
+ break;
49777
+ }
49778
+ if (code < 48 || code > 57) {
49779
+ allDigits = false;
49780
+ break;
49781
+ }
49782
+ }
49783
+ if (i === indexOfColon + 1) {
49784
+ allDigits = false;
49785
+ }
49786
+ if (!allDigits) {
49787
+ const special = getSpecialScheme(url, start, indexOfColon);
49788
+ if (special === 0) {
49789
+ let isBareIpv6 = false;
49790
+ for (let j = indexOfColon + 1; j < end; j += 1) {
49791
+ const code = url.charCodeAt(j);
49792
+ if (code === 47 || code === 92 || code === 63 || code === 35) {
49793
+ break;
49794
+ }
49795
+ if (code === 58) {
49796
+ isBareIpv6 = true;
49797
+ break;
49798
+ }
49799
+ }
49800
+ if (!isBareIpv6) {
49801
+ return null;
49802
+ }
49803
+ } else {
49804
+ isSpecial = true;
49805
+ start = indexOfColon + 1;
49806
+ if (special === 2) {
49807
+ let slashes = 0;
49808
+ while ((url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) && slashes < 2) {
49809
+ start += 1;
49810
+ slashes += 1;
49811
+ }
49812
+ if (slashes < 2) {
49813
+ return null;
49814
+ }
49815
+ } else {
49816
+ while (url.charCodeAt(start) === 47 || url.charCodeAt(start) === 92) {
49817
+ start += 1;
49818
+ }
49819
+ }
49820
+ }
49821
+ }
49822
+ }
49823
+ }
49824
+ }
49825
+ }
49826
+ let indexOfIdentifier = -1;
49827
+ let indexOfClosingBracket = -1;
49828
+ let indexOfPort = -1;
49829
+ let indexOfFirstColon = -1;
49830
+ let hasControl = false;
49831
+ let vValid = validate3;
49832
+ let vLastDot = start - 1;
49833
+ let vLastCode = -1;
49834
+ if (validate3 && start < end) {
49835
+ const c0 = url.charCodeAt(start);
49836
+ if (!/*@__INLINE__*/
49837
+ (isValidHostnameChar(c0) || c0 === 46 || c0 === 95) || c0 === 45) {
49838
+ vValid = false;
49839
+ }
49840
+ }
49841
+ for (let i = start; i < end; i += 1) {
49842
+ const code = url.charCodeAt(i);
49843
+ if (code < 64) {
49844
+ if (code === 47 || code === 35 || code === 63) {
49845
+ end = i;
49846
+ break;
49847
+ } else if (code === 58) {
49848
+ if (indexOfFirstColon === -1) {
49849
+ indexOfFirstColon = i;
49850
+ }
49851
+ indexOfPort = i;
49852
+ } else if (code === 9 || code === 10 || code === 13) {
49853
+ hasControl = true;
49854
+ } else if (validate3) {
49855
+ if (code === 46) {
49856
+ if (i - vLastDot > 64 || vLastCode === 46 || vLastCode === 45) {
49857
+ vValid = false;
49858
+ }
49859
+ vLastDot = i;
49860
+ } else if (code < 48 || code > 57) {
49861
+ if (code !== 45 || vLastCode === 46) {
49862
+ vValid = false;
49863
+ }
49864
+ }
49865
+ }
49866
+ } else if (isSpecial && code === 92) {
49867
+ end = i;
49868
+ break;
49869
+ } else if (code === 64) {
49870
+ indexOfIdentifier = i;
49871
+ indexOfFirstColon = -1;
49872
+ } else if (code === 93) {
49873
+ indexOfClosingBracket = i;
49874
+ } else if (code >= 65 && code <= 90) {
49875
+ hasUpper = true;
49876
+ } else if (validate3 && !/*@__INLINE__*/
49877
+ isValidHostnameChar(code)) {
49878
+ vValid = false;
49879
+ }
49880
+ if (validate3) {
49881
+ vLastCode = code;
49882
+ }
49883
+ }
49884
+ if (hasControl) {
49885
+ return extractHostname(url.replace(CONTROL_CHARS3, ""), urlIsValidHostname, validate3);
49886
+ }
49887
+ if (indexOfIdentifier !== -1 && indexOfIdentifier >= start && indexOfIdentifier < end) {
49888
+ start = indexOfIdentifier + 1;
49889
+ }
49890
+ if (url.charCodeAt(start) === 91) {
49891
+ if (indexOfClosingBracket !== -1) {
49892
+ return url.slice(start + 1, indexOfClosingBracket).toLowerCase();
49893
+ }
49894
+ return null;
49895
+ } else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end && // A host:port has exactly one ':' in the host (so its first ':' is its
49896
+ // last); a bare, unbracketed IPv6 literal ("2a01:e35::1") has >= 2, so
49897
+ // its first ':' precedes the last. Only the former has a ':port' to trim.
49898
+ indexOfFirstColon === indexOfPort) {
49899
+ end = indexOfPort;
49900
+ }
49901
+ if (start >= end) {
49902
+ return null;
49903
+ }
49904
+ if (validate3 && vValid && indexOfIdentifier === -1 && indexOfPort === -1 && indexOfClosingBracket === -1 && url.charCodeAt(end - 1) !== 46 && end - start <= 255 && // total length
49905
+ end - vLastDot - 1 <= 63 && // last label length
49906
+ vLastCode !== 45) {
49907
+ extractedHostnameValidated = true;
49908
+ }
49909
+ }
49910
+ while (end > start + 1 && url.charCodeAt(end - 1) === 46) {
49911
+ end -= 1;
49912
+ }
49913
+ const hostname2 = start !== 0 || end !== url.length ? url.slice(start, end) : url;
49914
+ if (hasUpper) {
49915
+ return hostname2.toLowerCase();
49916
+ }
49917
+ return hostname2;
49918
+ }
49919
+ function isProbablyIpv4(hostname2) {
49920
+ if (hostname2.length < 7) {
49921
+ return false;
49922
+ }
49923
+ if (hostname2.length > 15) {
49924
+ return false;
49925
+ }
49926
+ let numberOfDots = 0;
49927
+ for (let i = 0; i < hostname2.length; i += 1) {
49928
+ const code = hostname2.charCodeAt(i);
49929
+ if (code === 46) {
49930
+ numberOfDots += 1;
49931
+ } else if (code < 48 || code > 57) {
49932
+ return false;
49933
+ }
49934
+ }
49935
+ return numberOfDots === 3 && hostname2.charCodeAt(0) !== 46 && hostname2.charCodeAt(hostname2.length - 1) !== 46;
49936
+ }
49937
+ function isProbablyIpv6(hostname2) {
49938
+ if (hostname2.length < 3) {
49939
+ return false;
49940
+ }
49941
+ let start = hostname2.startsWith("[") ? 1 : 0;
49942
+ let end = hostname2.length;
49943
+ if (hostname2[end - 1] === "]") {
49944
+ end -= 1;
49945
+ }
49946
+ if (end - start > 39) {
49947
+ return false;
49948
+ }
49949
+ let hasColon = false;
49950
+ for (; start < end; start += 1) {
49951
+ const code = hostname2.charCodeAt(start);
49952
+ if (code === 58) {
49953
+ hasColon = true;
49954
+ } else if (!(code >= 48 && code <= 57 || // 0-9
49955
+ code >= 97 && code <= 102 || // a-f
49956
+ code >= 65 && code <= 70)) {
49957
+ return false;
49958
+ }
49959
+ }
49960
+ return hasColon;
49961
+ }
49962
+ function isIp(hostname2) {
49963
+ return isProbablyIpv6(hostname2) || isProbablyIpv4(hostname2);
49964
+ }
49965
+ var SPECIAL_USE_DOMAINS2 = [
49966
+ "test",
49967
+ // RFC 6761
49968
+ "localhost",
49969
+ // RFC 6761
49970
+ "invalid",
49971
+ // RFC 6761
49972
+ "example",
49973
+ // RFC 6761
49974
+ "example.com",
49975
+ // RFC 6761
49976
+ "example.net",
49977
+ // RFC 6761
49978
+ "example.org",
49979
+ // RFC 6761
49980
+ "local",
49981
+ // RFC 6762 (mDNS)
49982
+ "onion",
49983
+ // RFC 7686 (Tor)
49984
+ "alt",
49985
+ // RFC 9476
49986
+ "home.arpa",
49987
+ // RFC 8375
49988
+ "ipv4only.arpa",
49989
+ // RFC 8880
49990
+ "resolver.arpa",
49991
+ // RFC 9462
49992
+ "service.arpa",
49993
+ // RFC 9665
49994
+ "6tisch.arpa",
49995
+ // RFC 9031
49996
+ "eap.arpa"
49997
+ // RFC 9965
49998
+ ];
49999
+ function isSpecialUse(hostname2) {
50000
+ for (const name of SPECIAL_USE_DOMAINS2) {
50001
+ if (hostname2.endsWith(name) && (hostname2.length === name.length || hostname2.charCodeAt(hostname2.length - name.length - 1) === 46)) {
50002
+ return true;
50003
+ }
50004
+ }
50005
+ return false;
50006
+ }
50007
+ function isValidAscii(code) {
50008
+ return code >= 97 && code <= 122 || code >= 48 && code <= 57 || code > 127;
50009
+ }
50010
+ function isValidHostname(hostname2) {
50011
+ if (hostname2.length > 255) {
50012
+ return false;
50013
+ }
50014
+ if (hostname2.length === 0) {
50015
+ return false;
50016
+ }
50017
+ if (
50018
+ /*@__INLINE__*/
50019
+ !isValidAscii(hostname2.charCodeAt(0)) && hostname2.charCodeAt(0) !== 46 && // '.' (dot)
50020
+ hostname2.charCodeAt(0) !== 95
50021
+ ) {
50022
+ return false;
50023
+ }
50024
+ let lastDotIndex = -1;
50025
+ let lastCharCode = -1;
50026
+ const len = hostname2.length;
50027
+ for (let i = 0; i < len; i += 1) {
50028
+ const code = hostname2.charCodeAt(i);
50029
+ if (code === 46) {
50030
+ if (
50031
+ // Check that previous label is < 63 bytes long (64 = 63 + '.')
50032
+ i - lastDotIndex > 64 || // Check that previous character was not already a '.'
50033
+ lastCharCode === 46 || // Check that the previous label does not end with '-' (RFC 1035 §2.3.1 LDH).
50034
+ // '_' is intentionally NOT restricted: DNS allows any octet (RFC 2181 §11) and
50035
+ // WHATWG URL does not treat '_' as a forbidden host code point.
50036
+ lastCharCode === 45
50037
+ ) {
50038
+ return false;
50039
+ }
50040
+ lastDotIndex = i;
50041
+ } else if (
50042
+ // A forbidden character in the label...
50043
+ !/*@__INLINE__*/
50044
+ (isValidAscii(code) || code === 45 || code === 95) || // ...or a '-' starting a label (the byte right after a '.'). A label must
50045
+ // not begin with a hyphen (RFC 1034 §3.5 / RFC 1035 §2.3.1 LDH, as amended
50046
+ // by RFC 1123 §2.1; cf. UTS #46 CheckHyphens). The first label is covered by
50047
+ // the leading-character guard above; mirrors the trailing-'-' rule below.
50048
+ code === 45 && lastCharCode === 46
50049
+ ) {
50050
+ return false;
50051
+ }
50052
+ lastCharCode = code;
50053
+ }
50054
+ return (
50055
+ // Check that last label is shorter than 63 chars
50056
+ len - lastDotIndex - 1 <= 63 && // Check that the last character is an allowed trailing label character.
50057
+ // Since we already checked that the char is a valid hostname character,
50058
+ // we only need to check that it's different from '-'.
50059
+ lastCharCode !== 45
50060
+ );
50061
+ }
50062
+ function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, detectSpecialUse = false, extractHostname: extractHostname2 = true, mixedInputs = true, validHosts = null, validateHostname = true }) {
50063
+ return {
50064
+ allowIcannDomains,
50065
+ allowPrivateDomains,
50066
+ detectIp,
50067
+ detectSpecialUse,
50068
+ extractHostname: extractHostname2,
50069
+ mixedInputs,
50070
+ validHosts,
50071
+ validateHostname
50072
+ };
50073
+ }
50074
+ var DEFAULT_OPTIONS = (
50075
+ /*@__INLINE__*/
50076
+ setDefaultsImpl({})
50077
+ );
50078
+ function setDefaults(options) {
50079
+ if (options === void 0) {
50080
+ return DEFAULT_OPTIONS;
50081
+ }
50082
+ return (
50083
+ /*@__INLINE__*/
50084
+ setDefaultsImpl(options)
50085
+ );
50086
+ }
50087
+ function getSubdomain$1(hostname2, domain) {
50088
+ if (domain.length === hostname2.length) {
50089
+ return "";
50090
+ }
50091
+ return hostname2.slice(0, -domain.length - 1);
50092
+ }
50093
+ function getEmptyResult() {
50094
+ return {
50095
+ domain: null,
50096
+ domainWithoutSuffix: null,
50097
+ hostname: null,
50098
+ isIcann: null,
50099
+ isIp: null,
50100
+ isPrivate: null,
50101
+ isSpecialUse: null,
50102
+ publicSuffix: null,
50103
+ subdomain: null
50104
+ };
50105
+ }
50106
+ function resetResult(result) {
50107
+ result.domain = null;
50108
+ result.domainWithoutSuffix = null;
50109
+ result.hostname = null;
50110
+ result.isIcann = null;
50111
+ result.isIp = null;
50112
+ result.isPrivate = null;
50113
+ result.isSpecialUse = null;
50114
+ result.publicSuffix = null;
50115
+ result.subdomain = null;
50116
+ }
50117
+ function parseImpl(url, step, suffixLookup2, partialOptions, result) {
50118
+ const options = (
50119
+ /*@__INLINE__*/
50120
+ setDefaults(partialOptions)
50121
+ );
50122
+ if (typeof url !== "string") {
50123
+ return result;
50124
+ }
50125
+ let urlIsValid = false;
50126
+ if (!options.extractHostname) {
50127
+ result.hostname = url;
50128
+ } else if (options.mixedInputs) {
50129
+ urlIsValid = isValidHostname(url);
50130
+ result.hostname = extractHostname(url, urlIsValid, options.validateHostname);
50131
+ } else {
50132
+ result.hostname = extractHostname(url, false, options.validateHostname);
50133
+ }
50134
+ if (options.detectIp && result.hostname !== null) {
50135
+ result.isIp = isIp(result.hostname);
50136
+ if (result.isIp) {
50137
+ return result;
50138
+ }
50139
+ }
50140
+ if (options.validateHostname && options.extractHostname && result.hostname !== null && // Skip the re-scan when `url` was already validated and extractHostname
50141
+ // returned it unchanged (same reference => identical string, still valid).
50142
+ !(urlIsValid && result.hostname === url) && // Skip the re-scan when extractHostname already validated the host inline
50143
+ // (a confirmed-valid simple authority — see extract-hostname.ts).
50144
+ !extractedHostnameValidated && !isValidHostname(result.hostname)) {
50145
+ result.hostname = null;
50146
+ return result;
50147
+ }
50148
+ if (step === 0 || result.hostname === null) {
50149
+ return result;
50150
+ }
50151
+ if (step === 5 && options.detectSpecialUse) {
50152
+ result.isSpecialUse = isSpecialUse(result.hostname);
50153
+ }
50154
+ suffixLookup2(result.hostname, options, result);
50155
+ if (step === 2 || result.publicSuffix === null) {
50156
+ return result;
50157
+ }
50158
+ result.domain = getDomain$1(result.publicSuffix, result.hostname, options);
50159
+ if (step === 3 || result.domain === null) {
50160
+ return result;
50161
+ }
50162
+ result.subdomain = getSubdomain$1(result.hostname, result.domain);
50163
+ if (step === 4) {
50164
+ return result;
50165
+ }
50166
+ result.domainWithoutSuffix = getDomainWithoutSuffix$1(result.domain, result.publicSuffix);
50167
+ return result;
50168
+ }
50169
+ function fastPathLookup(hostname2, options, out) {
50170
+ if (!options.allowPrivateDomains && hostname2.length > 3) {
50171
+ const last = hostname2.length - 1;
50172
+ const c3 = hostname2.charCodeAt(last);
50173
+ const c2 = hostname2.charCodeAt(last - 1);
50174
+ const c1 = hostname2.charCodeAt(last - 2);
50175
+ const c0 = hostname2.charCodeAt(last - 3);
50176
+ if (c3 === 109 && c2 === 111 && c1 === 99 && c0 === 46) {
50177
+ out.isIcann = true;
50178
+ out.isPrivate = false;
50179
+ out.publicSuffix = "com";
50180
+ return true;
50181
+ } else if (c3 === 103 && c2 === 114 && c1 === 111 && c0 === 46) {
50182
+ out.isIcann = true;
50183
+ out.isPrivate = false;
50184
+ out.publicSuffix = "org";
50185
+ return true;
50186
+ } else if (c3 === 117 && c2 === 100 && c1 === 101 && c0 === 46) {
50187
+ out.isIcann = true;
50188
+ out.isPrivate = false;
50189
+ out.publicSuffix = "edu";
50190
+ return true;
50191
+ } else if (c3 === 118 && c2 === 111 && c1 === 103 && c0 === 46) {
50192
+ out.isIcann = true;
50193
+ out.isPrivate = false;
50194
+ out.publicSuffix = "gov";
50195
+ return true;
50196
+ } else if (c3 === 116 && c2 === 101 && c1 === 110 && c0 === 46) {
50197
+ out.isIcann = true;
50198
+ out.isPrivate = false;
50199
+ out.publicSuffix = "net";
50200
+ return true;
50201
+ } else if (c3 === 101 && c2 === 100 && c1 === 46) {
50202
+ out.isIcann = true;
50203
+ out.isPrivate = false;
50204
+ out.publicSuffix = "de";
50205
+ return true;
50206
+ }
50207
+ }
50208
+ return false;
50209
+ }
50210
+ 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]);
50211
+ 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]);
50212
+ 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]);
50213
+ 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]);
50214
+ 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";
50215
+ var rulesRoot = 617;
50216
+ var exceptionsRoot = 621;
50217
+ var numberOfNodes = nodeFlags.length;
50218
+ var numberOfEdges = edgeLength.length;
50219
+ var edgeOffset = new Uint32Array(numberOfEdges);
50220
+ var edgeHash = new Uint32Array(numberOfEdges);
50221
+ var wildcardEdge = new Int32Array(numberOfNodes).fill(-1);
50222
+ for (let node = 0, offset = 0; node < numberOfNodes; node += 1) {
50223
+ for (let edge = edgeStart[node]; edge < edgeStart[node + 1]; edge += 1) {
50224
+ edgeOffset[edge] = offset;
50225
+ const end = offset + edgeLength[edge];
50226
+ let hash = 5381;
50227
+ for (let i = end - 1; i >= offset; i -= 1) {
50228
+ hash = hash * 33 ^ labelText.charCodeAt(i);
50229
+ }
50230
+ edgeHash[edge] = hash >>> 0;
50231
+ if (edgeLength[edge] === 1 && labelText.charCodeAt(offset) === 42) {
50232
+ wildcardEdge[node] = edge;
50233
+ }
50234
+ offset = end;
50235
+ }
50236
+ }
50237
+ var matchNode = -1;
50238
+ var matchStart = 0;
50239
+ var matchEnd = 0;
50240
+ function labelEquals(edge, hostname2, start, length) {
50241
+ if (edgeLength[edge] !== length) {
50242
+ return false;
50243
+ }
50244
+ const offset = edgeOffset[edge];
50245
+ for (let i = 0; i < length; i += 1) {
50246
+ if (labelText.charCodeAt(offset + i) !== hostname2.charCodeAt(start + i)) {
50247
+ return false;
50248
+ }
50249
+ }
50250
+ return true;
50251
+ }
50252
+ function findEdge(node, hash, hostname2, start, length) {
50253
+ let lo = edgeStart[node];
50254
+ let hi = edgeStart[node + 1];
50255
+ while (lo < hi) {
50256
+ const mid = lo + hi >>> 1;
50257
+ const value = edgeHash[mid];
50258
+ if (value < hash) {
50259
+ lo = mid + 1;
50260
+ } else if (value > hash) {
50261
+ hi = mid;
50262
+ } else {
50263
+ for (let e = mid; e >= lo && edgeHash[e] === hash; e -= 1) {
50264
+ if (labelEquals(e, hostname2, start, length))
50265
+ return e;
50266
+ }
50267
+ for (let e = mid + 1; e < hi && edgeHash[e] === hash; e += 1) {
50268
+ if (labelEquals(e, hostname2, start, length))
50269
+ return e;
50270
+ }
50271
+ return -1;
50272
+ }
50273
+ }
50274
+ return -1;
50275
+ }
50276
+ function walk2(hostname2, root, allowedMask) {
50277
+ let node = root;
50278
+ let end = hostname2.length;
50279
+ let hash = 5381;
50280
+ matchNode = -1;
50281
+ for (let i = hostname2.length - 1; i >= 0; i -= 1) {
50282
+ const code = hostname2.charCodeAt(i);
50283
+ if (code === 46) {
50284
+ const start = i + 1;
50285
+ let edge2 = findEdge(node, hash >>> 0, hostname2, start, end - start);
50286
+ if (edge2 === -1) {
50287
+ edge2 = wildcardEdge[node];
50288
+ }
50289
+ if (edge2 === -1) {
50290
+ return matchNode !== -1;
50291
+ }
50292
+ node = edgeChild[edge2];
50293
+ if ((nodeFlags[node] & allowedMask) !== 0) {
50294
+ matchNode = node;
50295
+ matchStart = start;
50296
+ matchEnd = end;
50297
+ }
50298
+ end = i;
50299
+ hash = 5381;
50300
+ } else {
50301
+ hash = hash * 33 ^ code;
50302
+ }
50303
+ }
50304
+ let edge = findEdge(node, hash >>> 0, hostname2, 0, end);
50305
+ if (edge === -1) {
50306
+ edge = wildcardEdge[node];
50307
+ }
50308
+ if (edge !== -1) {
50309
+ node = edgeChild[edge];
50310
+ if ((nodeFlags[node] & allowedMask) !== 0) {
50311
+ matchNode = node;
50312
+ matchStart = 0;
50313
+ matchEnd = end;
50314
+ }
50315
+ }
50316
+ return matchNode !== -1;
50317
+ }
50318
+ function suffixLookup(hostname2, options, out) {
50319
+ if (fastPathLookup(hostname2, options, out)) {
50320
+ return;
50321
+ }
50322
+ const allowedMask = (options.allowPrivateDomains ? 2 : 0) | (options.allowIcannDomains ? 1 : 0);
50323
+ if (walk2(hostname2, exceptionsRoot, allowedMask)) {
50324
+ out.isIcann = (nodeFlags[matchNode] & 1) !== 0;
50325
+ out.isPrivate = (nodeFlags[matchNode] & 2) !== 0;
50326
+ out.publicSuffix = hostname2.slice(matchEnd + 1);
50327
+ return;
50328
+ }
50329
+ if (walk2(hostname2, rulesRoot, allowedMask)) {
50330
+ out.isIcann = (nodeFlags[matchNode] & 1) !== 0;
50331
+ out.isPrivate = (nodeFlags[matchNode] & 2) !== 0;
50332
+ out.publicSuffix = hostname2.slice(matchStart);
50333
+ return;
50334
+ }
50335
+ out.isIcann = false;
50336
+ out.isPrivate = false;
50337
+ const lastDot = hostname2.lastIndexOf(".");
50338
+ out.publicSuffix = lastDot === -1 ? hostname2 : hostname2.slice(lastDot + 1);
50339
+ }
50340
+ var RESULT = getEmptyResult();
50341
+ function parse2(url, options) {
50342
+ return parseImpl(url, 5, suffixLookup, options, getEmptyResult());
50343
+ }
50344
+ function getHostname(url, options) {
50345
+ resetResult(RESULT);
50346
+ return parseImpl(url, 0, suffixLookup, options, RESULT).hostname;
50347
+ }
50348
+ function getPublicSuffix2(url, options) {
50349
+ resetResult(RESULT);
50350
+ return parseImpl(url, 2, suffixLookup, options, RESULT).publicSuffix;
50351
+ }
50352
+ function getDomain2(url, options) {
50353
+ resetResult(RESULT);
50354
+ return parseImpl(url, 3, suffixLookup, options, RESULT).domain;
50355
+ }
50356
+ function getFullDomain(url, options) {
50357
+ resetResult(RESULT);
50358
+ const result = parseImpl(url, 3, suffixLookup, options, RESULT);
50359
+ return result.domain === null ? null : result.hostname;
50360
+ }
50361
+ function getSubdomain(url, options) {
50362
+ resetResult(RESULT);
50363
+ return parseImpl(url, 4, suffixLookup, options, RESULT).subdomain;
50364
+ }
50365
+ function getDomainWithoutSuffix(url, options) {
50366
+ resetResult(RESULT);
50367
+ return parseImpl(url, 5, suffixLookup, options, RESULT).domainWithoutSuffix;
50368
+ }
50369
+ exports.getDomain = getDomain2;
50370
+ exports.getDomainWithoutSuffix = getDomainWithoutSuffix;
50371
+ exports.getFullDomain = getFullDomain;
50372
+ exports.getHostname = getHostname;
50373
+ exports.getPublicSuffix = getPublicSuffix2;
50374
+ exports.getSubdomain = getSubdomain;
50375
+ exports.parse = parse2;
50376
+ }
50377
+ });
50378
+
50379
+ // ../../node_modules/tough-cookie/dist/index.js
50380
+ function pathMatch(reqPath, cookiePath) {
50381
+ if (cookiePath === reqPath) {
50382
+ return true;
50383
+ }
50384
+ const idx = reqPath.indexOf(cookiePath);
50385
+ if (idx === 0) {
50386
+ if (cookiePath[cookiePath.length - 1] === "/") {
50387
+ return true;
50388
+ }
50389
+ if (reqPath.startsWith(cookiePath) && reqPath[cookiePath.length] === "/") {
50390
+ return true;
50391
+ }
50392
+ }
50393
+ return false;
50394
+ }
50395
+ function getPublicSuffix(domain, options = {}) {
50396
+ options = { ...defaultGetPublicSuffixOptions, ...options };
50397
+ const domainParts = domain.split(".");
50398
+ const topLevelDomain = domainParts[domainParts.length - 1];
50399
+ const allowSpecialUseDomain = !!options.allowSpecialUseDomain;
50400
+ const ignoreError = !!options.ignoreError;
50401
+ if (allowSpecialUseDomain && topLevelDomain !== void 0 && SPECIAL_USE_DOMAINS.includes(topLevelDomain)) {
50402
+ if (domainParts.length > 1) {
50403
+ const secondLevelDomain = domainParts[domainParts.length - 2];
50404
+ return `${secondLevelDomain}.${topLevelDomain}`;
50405
+ } else if (SPECIAL_TREATMENT_DOMAINS.includes(topLevelDomain)) {
50406
+ return topLevelDomain;
50407
+ }
50408
+ }
50409
+ if (!ignoreError && topLevelDomain !== void 0 && SPECIAL_USE_DOMAINS.includes(topLevelDomain)) {
50410
+ throw new Error(
50411
+ `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}.`
50412
+ );
50413
+ }
50414
+ const publicSuffix = (0, import_tldts.getDomain)(domain, {
50415
+ allowIcannDomains: true,
50416
+ allowPrivateDomains: true
50417
+ });
50418
+ if (publicSuffix) return publicSuffix;
50419
+ }
50420
+ function permuteDomain(domain, allowSpecialUseDomain) {
50421
+ const pubSuf = getPublicSuffix(domain, {
50422
+ allowSpecialUseDomain
50423
+ });
50424
+ if (!pubSuf) {
50425
+ return void 0;
50426
+ }
50427
+ if (pubSuf == domain) {
50428
+ return [domain];
50429
+ }
50430
+ if (domain.slice(-1) == ".") {
50431
+ domain = domain.slice(0, -1);
50432
+ }
50433
+ const prefix = domain.slice(0, -(pubSuf.length + 1));
50434
+ const parts = prefix.split(".").reverse();
50435
+ let cur = pubSuf;
50436
+ const permutations = [cur];
50437
+ while (parts.length) {
50438
+ const part = parts.shift();
50439
+ cur = `${part}.${cur}`;
50440
+ permutations.push(cur);
50441
+ }
50442
+ return permutations;
50443
+ }
50444
+ function createPromiseCallback(cb) {
50445
+ let callback;
50446
+ let resolve43;
50447
+ let reject;
50448
+ const promise = new Promise((_resolve, _reject) => {
50449
+ resolve43 = _resolve;
50450
+ reject = _reject;
50451
+ });
50452
+ if (typeof cb === "function") {
50453
+ callback = (err, result) => {
50454
+ try {
50455
+ if (err) cb(err);
50456
+ else cb(null, result);
50457
+ } catch (e) {
50458
+ reject(e instanceof Error ? e : new Error());
50459
+ }
50460
+ };
50461
+ } else {
50462
+ callback = (err, result) => {
50463
+ try {
50464
+ if (err) reject(err);
50465
+ else resolve43(result);
50466
+ } catch (e) {
50467
+ reject(e instanceof Error ? e : new Error());
50468
+ }
50469
+ };
50470
+ }
50471
+ return {
50472
+ promise,
50473
+ callback,
50474
+ resolve: (value) => {
50475
+ callback(null, value);
50476
+ return promise;
50477
+ },
50478
+ reject: (error) => {
50479
+ callback(error);
50480
+ return promise;
50481
+ }
50482
+ };
50483
+ }
50484
+ function inOperator(k, o) {
50485
+ return k in o;
50486
+ }
50487
+ function isNonEmptyString(data) {
50488
+ return isString(data) && data !== "";
50489
+ }
50490
+ function isEmptyString(data) {
50491
+ return data === "" || data instanceof String && data.toString() === "";
50492
+ }
50493
+ function isString(data) {
50494
+ return typeof data === "string" || data instanceof String;
50495
+ }
50496
+ function isObject(data) {
50497
+ return objectToString(data) === "[object Object]";
50498
+ }
50499
+ function validate2(bool, cbOrMessage, message) {
50500
+ if (bool) return;
50501
+ const cb = typeof cbOrMessage === "function" ? cbOrMessage : void 0;
50502
+ let options = typeof cbOrMessage === "function" ? message : cbOrMessage;
50503
+ if (!isObject(options)) options = "[object Object]";
50504
+ const err = new ParameterError(safeToString(options));
50505
+ if (cb) cb(err);
50506
+ else throw err;
50507
+ }
50508
+ function domainToASCII(domain) {
50509
+ return new URL(`http://${domain}`).hostname;
50510
+ }
50511
+ function canonicalDomain(domainName) {
50512
+ if (domainName == null) {
50513
+ return void 0;
50514
+ }
50515
+ let str6 = domainName.trim().replace(/^\./, "");
50516
+ if (IP_V6_REGEX_OBJECT.test(str6)) {
50517
+ if (!str6.startsWith("[")) {
50518
+ str6 = "[" + str6;
50519
+ }
50520
+ if (!str6.endsWith("]")) {
50521
+ str6 = str6 + "]";
50522
+ }
50523
+ return domainToASCII(str6).slice(1, -1);
50524
+ }
50525
+ if (/[^\u0001-\u007f]/.test(str6)) {
50526
+ return domainToASCII(str6);
50527
+ }
50528
+ return str6.toLowerCase();
50529
+ }
50530
+ function formatDate(date) {
50531
+ return date.toUTCString();
50532
+ }
50533
+ function parseDate(cookieDate) {
50534
+ if (!cookieDate) {
50535
+ return void 0;
50536
+ }
50537
+ const flags = {
50538
+ foundTime: void 0,
50539
+ foundDayOfMonth: void 0,
50540
+ foundMonth: void 0,
50541
+ foundYear: void 0
50542
+ };
50543
+ const dateTokens = cookieDate.split(DELIMITER).filter((token) => token.length > 0);
50544
+ for (const dateToken of dateTokens) {
50545
+ if (flags.foundTime === void 0) {
50546
+ const [, hours, minutes, seconds] = TIME.exec(dateToken) || [];
50547
+ if (hours != void 0 && minutes != void 0 && seconds != void 0) {
50548
+ const parsedHours = parseInt(hours, 10);
50549
+ const parsedMinutes = parseInt(minutes, 10);
50550
+ const parsedSeconds = parseInt(seconds, 10);
50551
+ if (!isNaN(parsedHours) && !isNaN(parsedMinutes) && !isNaN(parsedSeconds)) {
50552
+ flags.foundTime = {
50553
+ hours: parsedHours,
50554
+ minutes: parsedMinutes,
50555
+ seconds: parsedSeconds
50556
+ };
50557
+ continue;
50558
+ }
50559
+ }
50560
+ }
50561
+ if (flags.foundDayOfMonth === void 0 && DAY_OF_MONTH.test(dateToken)) {
50562
+ const dayOfMonth = parseInt(dateToken, 10);
50563
+ if (!isNaN(dayOfMonth)) {
50564
+ flags.foundDayOfMonth = dayOfMonth;
50565
+ continue;
50566
+ }
50567
+ }
50568
+ if (flags.foundMonth === void 0 && MONTH.test(dateToken)) {
50569
+ const month = months.indexOf(dateToken.substring(0, 3).toLowerCase());
50570
+ if (month >= 0 && month <= 11) {
50571
+ flags.foundMonth = month;
50572
+ continue;
50573
+ }
50574
+ }
50575
+ if (flags.foundYear === void 0 && YEAR2.test(dateToken)) {
50576
+ const parsedYear = parseInt(dateToken, 10);
50577
+ if (!isNaN(parsedYear)) {
50578
+ flags.foundYear = parsedYear;
50579
+ continue;
50580
+ }
50581
+ }
50582
+ }
50583
+ if (flags.foundYear !== void 0 && flags.foundYear >= 70 && flags.foundYear <= 99) {
50584
+ flags.foundYear += 1900;
50585
+ }
50586
+ if (flags.foundYear !== void 0 && flags.foundYear >= 0 && flags.foundYear <= 69) {
50587
+ flags.foundYear += 2e3;
50588
+ }
50589
+ if (flags.foundDayOfMonth === void 0 || flags.foundMonth === void 0 || flags.foundYear === void 0 || flags.foundTime === void 0) {
50590
+ return void 0;
50591
+ }
50592
+ if (flags.foundDayOfMonth < 1 || flags.foundDayOfMonth > 31) {
50593
+ return void 0;
50594
+ }
50595
+ if (flags.foundYear < 1601) {
50596
+ return void 0;
50597
+ }
50598
+ if (flags.foundTime.hours > 23) {
50599
+ return void 0;
50600
+ }
50601
+ if (flags.foundTime.minutes > 59) {
50602
+ return void 0;
50603
+ }
50604
+ if (flags.foundTime.seconds > 59) {
50605
+ return void 0;
50606
+ }
50607
+ const date = new Date(
50608
+ Date.UTC(
50609
+ flags.foundYear,
50610
+ flags.foundMonth,
50611
+ flags.foundDayOfMonth,
50612
+ flags.foundTime.hours,
50613
+ flags.foundTime.minutes,
50614
+ flags.foundTime.seconds
50615
+ )
50616
+ );
50617
+ if (date.getUTCFullYear() !== flags.foundYear || date.getUTCMonth() !== flags.foundMonth || date.getUTCDate() !== flags.foundDayOfMonth) {
50618
+ return void 0;
50619
+ }
50620
+ return date;
50621
+ }
50622
+ function trimTerminator(str6) {
50623
+ if (isEmptyString(str6)) return str6;
50624
+ for (let t = 0; t < TERMINATORS.length; t++) {
50625
+ const terminator = TERMINATORS[t];
50626
+ const terminatorIdx = terminator ? str6.indexOf(terminator) : -1;
50627
+ if (terminatorIdx !== -1) {
50628
+ str6 = str6.slice(0, terminatorIdx);
50629
+ }
50630
+ }
50631
+ return str6;
50632
+ }
50633
+ function parseCookiePair(cookiePair, looseMode) {
50634
+ cookiePair = trimTerminator(cookiePair);
50635
+ let firstEq = cookiePair.indexOf("=");
50636
+ if (looseMode) {
50637
+ if (firstEq === 0) {
50638
+ cookiePair = cookiePair.substring(1);
50639
+ firstEq = cookiePair.indexOf("=");
50640
+ }
50641
+ } else {
50642
+ if (firstEq <= 0) {
50643
+ return void 0;
50644
+ }
50645
+ }
50646
+ let cookieName, cookieValue;
50647
+ if (firstEq <= 0) {
50648
+ cookieName = "";
50649
+ cookieValue = cookiePair.trim();
50650
+ } else {
50651
+ cookieName = cookiePair.slice(0, firstEq).trim();
50652
+ cookieValue = cookiePair.slice(firstEq + 1).trim();
50653
+ }
50654
+ if (CONTROL_CHARS2.test(cookieName) || CONTROL_CHARS2.test(cookieValue)) {
50655
+ return void 0;
50656
+ }
50657
+ const c = new Cookie();
50658
+ c.key = cookieName;
50659
+ c.value = cookieValue;
50660
+ return c;
50661
+ }
50662
+ function parse(str6, options) {
50663
+ if (isEmptyString(str6) || !isString(str6)) {
50664
+ return void 0;
50665
+ }
50666
+ str6 = str6.trim();
50667
+ const firstSemi = str6.indexOf(";");
50668
+ const cookiePair = firstSemi === -1 ? str6 : str6.slice(0, firstSemi);
50669
+ const c = parseCookiePair(cookiePair, options?.loose ?? false);
50670
+ if (!c) {
50671
+ return void 0;
50672
+ }
50673
+ if (firstSemi === -1) {
50674
+ return c;
50675
+ }
50676
+ const unparsed = str6.slice(firstSemi + 1).trim();
50677
+ if (unparsed.length === 0) {
50678
+ return c;
50679
+ }
50680
+ const cookie_avs = unparsed.split(";");
50681
+ while (cookie_avs.length) {
50682
+ const av = (cookie_avs.shift() ?? "").trim();
50683
+ if (av.length === 0) {
50684
+ continue;
50685
+ }
50686
+ const av_sep = av.indexOf("=");
50687
+ let av_key, av_value;
50688
+ if (av_sep === -1) {
50689
+ av_key = av;
50690
+ av_value = null;
50691
+ } else {
50692
+ av_key = av.slice(0, av_sep);
50693
+ av_value = av.slice(av_sep + 1);
50694
+ }
50695
+ av_key = av_key.trim().toLowerCase();
50696
+ if (av_value) {
50697
+ av_value = av_value.trim();
50698
+ }
50699
+ switch (av_key) {
50700
+ case "expires":
50701
+ if (av_value) {
50702
+ const exp = parseDate(av_value);
50703
+ if (exp) {
50704
+ c.expires = exp;
50705
+ }
50706
+ }
50707
+ break;
50708
+ case "max-age":
50709
+ if (av_value) {
50710
+ if (/^-?[0-9]+$/.test(av_value)) {
50711
+ const delta = parseInt(av_value, 10);
50712
+ c.setMaxAge(delta);
50713
+ }
50714
+ }
50715
+ break;
50716
+ case "domain":
50717
+ if (av_value) {
50718
+ const domain = av_value.trim().replace(/^\./, "");
50719
+ if (domain) {
50720
+ c.domain = domain.toLowerCase();
50721
+ }
50722
+ }
50723
+ break;
50724
+ case "path":
50725
+ c.path = av_value && av_value[0] === "/" ? av_value : null;
50726
+ break;
50727
+ case "secure":
50728
+ c.secure = true;
50729
+ break;
50730
+ case "httponly":
50731
+ c.httpOnly = true;
50732
+ break;
50733
+ case "samesite":
50734
+ switch (av_value ? av_value.toLowerCase() : "") {
50735
+ case "strict":
50736
+ c.sameSite = "strict";
50737
+ break;
50738
+ case "lax":
50739
+ c.sameSite = "lax";
50740
+ break;
50741
+ case "none":
50742
+ c.sameSite = "none";
50743
+ break;
50744
+ default:
50745
+ c.sameSite = void 0;
50746
+ break;
50747
+ }
50748
+ break;
50749
+ default:
50750
+ c.extensions = c.extensions || [];
50751
+ c.extensions.push(av);
50752
+ break;
50753
+ }
50754
+ }
50755
+ return c;
50756
+ }
50757
+ function fromJSON(str6) {
50758
+ if (!str6 || isEmptyString(str6)) {
50759
+ return void 0;
50760
+ }
50761
+ let obj;
50762
+ if (typeof str6 === "string") {
50763
+ try {
50764
+ obj = JSON.parse(str6);
50765
+ } catch {
50766
+ return void 0;
50767
+ }
50768
+ } else {
50769
+ obj = str6;
50770
+ }
50771
+ const c = new Cookie();
50772
+ Cookie.serializableProperties.forEach((prop) => {
50773
+ if (obj && typeof obj === "object" && inOperator(prop, obj)) {
50774
+ const val = obj[prop];
50775
+ if (val === void 0) {
50776
+ return;
50777
+ }
50778
+ if (inOperator(prop, cookieDefaults) && val === cookieDefaults[prop]) {
50779
+ return;
50780
+ }
50781
+ switch (prop) {
50782
+ case "key":
50783
+ case "value":
50784
+ case "sameSite":
50785
+ if (typeof val === "string") {
50786
+ c[prop] = val;
50787
+ }
50788
+ break;
50789
+ case "expires":
50790
+ case "creation":
50791
+ case "lastAccessed":
50792
+ if (typeof val === "number" || typeof val === "string" || val instanceof Date) {
50793
+ c[prop] = obj[prop] == "Infinity" ? "Infinity" : new Date(val);
50794
+ } else if (val === null) {
50795
+ c[prop] = null;
50796
+ }
50797
+ break;
50798
+ case "maxAge":
50799
+ if (typeof val === "number" || val === "Infinity" || val === "-Infinity") {
50800
+ c[prop] = val;
50801
+ }
50802
+ break;
50803
+ case "domain":
50804
+ case "path":
50805
+ if (typeof val === "string" || val === null) {
50806
+ c[prop] = val;
50807
+ }
50808
+ break;
50809
+ case "secure":
50810
+ case "httpOnly":
50811
+ if (typeof val === "boolean") {
50812
+ c[prop] = val;
50813
+ }
50814
+ break;
50815
+ case "extensions":
50816
+ if (Array.isArray(val) && val.every((item) => typeof item === "string")) {
50817
+ c[prop] = val;
50818
+ }
50819
+ break;
50820
+ case "hostOnly":
50821
+ case "pathIsDefault":
50822
+ if (typeof val === "boolean" || val === null) {
50823
+ c[prop] = val;
50824
+ }
50825
+ break;
50826
+ }
50827
+ }
50828
+ });
50829
+ return c;
50830
+ }
50831
+ function cookieCompare(a, b) {
50832
+ let cmp;
50833
+ const aPathLen = a.path ? a.path.length : 0;
50834
+ const bPathLen = b.path ? b.path.length : 0;
50835
+ cmp = bPathLen - aPathLen;
50836
+ if (cmp !== 0) {
50837
+ return cmp;
50838
+ }
50839
+ const aTime = a.creation && a.creation instanceof Date ? a.creation.getTime() : MAX_TIME;
50840
+ const bTime = b.creation && b.creation instanceof Date ? b.creation.getTime() : MAX_TIME;
50841
+ cmp = aTime - bTime;
50842
+ if (cmp !== 0) {
50843
+ return cmp;
50844
+ }
50845
+ cmp = (a.creationIndex || 0) - (b.creationIndex || 0);
50846
+ return cmp;
50847
+ }
50848
+ function defaultPath(path) {
50849
+ if (!path || path.slice(0, 1) !== "/") {
50850
+ return "/";
50851
+ }
50852
+ if (path === "/") {
50853
+ return path;
50854
+ }
50855
+ const rightSlash = path.lastIndexOf("/");
50856
+ if (rightSlash === 0) {
50857
+ return "/";
50858
+ }
50859
+ return path.slice(0, rightSlash);
50860
+ }
50861
+ function domainMatch(domain, cookieDomain, canonicalize) {
50862
+ if (domain == null || cookieDomain == null) {
50863
+ return void 0;
50864
+ }
50865
+ let _str;
50866
+ let _domStr;
50867
+ if (canonicalize !== false) {
50868
+ _str = canonicalDomain(domain);
50869
+ _domStr = canonicalDomain(cookieDomain);
50870
+ } else {
50871
+ _str = domain;
50872
+ _domStr = cookieDomain;
50873
+ }
50874
+ if (_str == null || _domStr == null) {
50875
+ return void 0;
50876
+ }
50877
+ if (_str == _domStr) {
50878
+ return true;
50879
+ }
50880
+ const idx = _str.lastIndexOf(_domStr);
50881
+ if (idx <= 0) {
50882
+ return false;
50883
+ }
50884
+ if (_str.length !== _domStr.length + idx) {
50885
+ return false;
50886
+ }
50887
+ if (_str.substring(idx - 1, idx) !== ".") {
50888
+ return false;
50889
+ }
50890
+ return !IP_REGEX_LOWERCASE.test(_str);
50891
+ }
50892
+ function isLoopbackV4(address) {
50893
+ const octets = address.split(".");
50894
+ return octets.length === 4 && octets[0] !== void 0 && parseInt(octets[0], 10) === 127;
50895
+ }
50896
+ function isLoopbackV6(address) {
50897
+ return address === "::1";
50898
+ }
50899
+ function isNormalizedLocalhostTLD(lowerHost) {
50900
+ return lowerHost.endsWith(".localhost");
50901
+ }
50902
+ function isLocalHostname(host) {
50903
+ const lowerHost = host.toLowerCase();
50904
+ return lowerHost === "localhost" || isNormalizedLocalhostTLD(lowerHost);
50905
+ }
50906
+ function hostNoBrackets(host) {
50907
+ if (host.length >= 2 && host.startsWith("[") && host.endsWith("]")) {
50908
+ return host.substring(1, host.length - 1);
50909
+ }
50910
+ return host;
50911
+ }
50912
+ function isPotentiallyTrustworthy(inputUrl, allowSecureOnLocal = true) {
50913
+ let url;
50914
+ if (typeof inputUrl === "string") {
50915
+ try {
50916
+ url = new URL(inputUrl);
50917
+ } catch {
50918
+ return false;
50919
+ }
50920
+ } else {
50921
+ url = inputUrl;
50922
+ }
50923
+ const scheme = url.protocol.replace(":", "").toLowerCase();
50924
+ const hostname2 = hostNoBrackets(url.hostname).replace(/\.+$/, "");
50925
+ if (scheme === "https" || scheme === "wss") {
50926
+ return true;
50927
+ }
50928
+ if (!allowSecureOnLocal) {
50929
+ return false;
50930
+ }
50931
+ if (IP_V4_REGEX_OBJECT.test(hostname2)) {
50932
+ return isLoopbackV4(hostname2);
50933
+ }
50934
+ if (IP_V6_REGEX_OBJECT.test(hostname2)) {
50935
+ return isLoopbackV6(hostname2);
50936
+ }
50937
+ return isLocalHostname(hostname2);
50938
+ }
50939
+ function getCookieContext(url) {
50940
+ 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") {
50941
+ return {
50942
+ hostname: url.hostname,
50943
+ pathname: url.pathname,
50944
+ protocol: url.protocol
50945
+ };
50946
+ } else if (typeof url === "string") {
50947
+ try {
50948
+ return new URL(decodeURI(url));
50949
+ } catch {
50950
+ return new URL(url);
50951
+ }
50952
+ } else {
50953
+ throw new ParameterError("`url` argument is not a string or URL.");
50954
+ }
50955
+ }
50956
+ function checkSameSiteContext(value) {
50957
+ const context = String(value).toLowerCase();
50958
+ if (context === "none" || context === "lax" || context === "strict") {
50959
+ return context;
50960
+ } else {
50961
+ return void 0;
50962
+ }
50963
+ }
50964
+ function isSecurePrefixConditionMet(cookie) {
50965
+ const startsWithSecurePrefix = typeof cookie.key === "string" && cookie.key.startsWith("__Secure-");
50966
+ return !startsWithSecurePrefix || cookie.secure;
50967
+ }
50968
+ function isHostPrefixConditionMet(cookie) {
50969
+ const startsWithHostPrefix = typeof cookie.key === "string" && cookie.key.startsWith("__Host-");
50970
+ return !startsWithHostPrefix || Boolean(
50971
+ cookie.secure && cookie.hostOnly && cookie.path != null && cookie.path === "/"
50972
+ );
50973
+ }
50974
+ function getNormalizedPrefixSecurity(prefixSecurity) {
50975
+ const normalizedPrefixSecurity = prefixSecurity.toLowerCase();
50976
+ switch (normalizedPrefixSecurity) {
50977
+ case PrefixSecurityEnum.STRICT:
50978
+ case PrefixSecurityEnum.SILENT:
50979
+ case PrefixSecurityEnum.DISABLED:
50980
+ return normalizedPrefixSecurity;
50981
+ default:
50982
+ return PrefixSecurityEnum.SILENT;
50983
+ }
50984
+ }
50985
+ 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;
50986
+ var init_dist = __esm({
50987
+ "../../node_modules/tough-cookie/dist/index.js"() {
50988
+ import_tldts = __toESM(require_cjs(), 1);
50989
+ SPECIAL_USE_DOMAINS = ["local", "example", "invalid", "localhost", "test"];
50990
+ SPECIAL_TREATMENT_DOMAINS = ["localhost", "invalid"];
50991
+ defaultGetPublicSuffixOptions = {
50992
+ allowSpecialUseDomain: false,
50993
+ ignoreError: false
50994
+ };
50995
+ Store2 = class {
50996
+ constructor() {
50997
+ this.synchronous = false;
50998
+ }
50999
+ /**
51000
+ * @internal No doc because this is an overload that supports the implementation
51001
+ */
51002
+ findCookie(_domain, _path, _key, _callback) {
51003
+ throw new Error("findCookie is not implemented");
51004
+ }
51005
+ /**
51006
+ * @internal No doc because this is an overload that supports the implementation
51007
+ */
51008
+ findCookies(_domain, _path, _allowSpecialUseDomain = false, _callback) {
51009
+ throw new Error("findCookies is not implemented");
51010
+ }
51011
+ /**
51012
+ * @internal No doc because this is an overload that supports the implementation
51013
+ */
51014
+ putCookie(_cookie, _callback) {
51015
+ throw new Error("putCookie is not implemented");
51016
+ }
51017
+ /**
51018
+ * @internal No doc because this is an overload that supports the implementation
51019
+ */
51020
+ updateCookie(_oldCookie, _newCookie, _callback) {
51021
+ throw new Error("updateCookie is not implemented");
51022
+ }
51023
+ /**
51024
+ * @internal No doc because this is an overload that supports the implementation
51025
+ */
51026
+ removeCookie(_domain, _path, _key, _callback) {
51027
+ throw new Error("removeCookie is not implemented");
51028
+ }
51029
+ /**
51030
+ * @internal No doc because this is an overload that supports the implementation
51031
+ */
51032
+ removeCookies(_domain, _path, _callback) {
51033
+ throw new Error("removeCookies is not implemented");
51034
+ }
51035
+ /**
51036
+ * @internal No doc because this is an overload that supports the implementation
51037
+ */
51038
+ removeAllCookies(_callback) {
51039
+ throw new Error("removeAllCookies is not implemented");
51040
+ }
51041
+ /**
51042
+ * @internal No doc because this is an overload that supports the implementation
51043
+ */
51044
+ getAllCookies(_callback) {
51045
+ throw new Error(
51046
+ "getAllCookies is not implemented (therefore jar cannot be serialized)"
51047
+ );
51048
+ }
51049
+ };
51050
+ objectToString = (obj) => Object.prototype.toString.call(obj);
51051
+ safeArrayToString = (arr, seenArrays) => {
51052
+ if (typeof arr.join !== "function") return objectToString(arr);
51053
+ seenArrays.add(arr);
51054
+ const mapped = arr.map(
51055
+ (val) => val === null || val === void 0 || seenArrays.has(val) ? "" : safeToStringImpl(val, seenArrays)
51056
+ );
51057
+ return mapped.join();
51058
+ };
51059
+ safeToStringImpl = (val, seenArrays = /* @__PURE__ */ new WeakSet()) => {
51060
+ if (typeof val !== "object" || val === null) {
51061
+ return String(val);
51062
+ } else if (typeof val.toString === "function") {
51063
+ return Array.isArray(val) ? (
51064
+ // Arrays have a weird custom toString that we need to replicate
51065
+ safeArrayToString(val, seenArrays)
51066
+ ) : (
51067
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
51068
+ String(val)
51069
+ );
51070
+ } else {
51071
+ return objectToString(val);
51072
+ }
51073
+ };
51074
+ safeToString = (val) => safeToStringImpl(val);
51075
+ MemoryCookieStore = class extends Store2 {
51076
+ /**
51077
+ * Create a new {@link MemoryCookieStore}.
51078
+ */
51079
+ constructor() {
51080
+ super();
51081
+ this.synchronous = true;
51082
+ this.idx = /* @__PURE__ */ Object.create(null);
51083
+ }
51084
+ /**
51085
+ * @internal No doc because this is an overload that supports the implementation
51086
+ */
51087
+ findCookie(domain, path, key2, callback) {
51088
+ const promiseCallback = createPromiseCallback(callback);
51089
+ if (domain == null || path == null || key2 == null) {
51090
+ return promiseCallback.resolve(void 0);
51091
+ }
51092
+ const result = this.idx[domain]?.[path]?.[key2];
51093
+ return promiseCallback.resolve(result);
51094
+ }
51095
+ /**
51096
+ * @internal No doc because this is an overload that supports the implementation
51097
+ */
51098
+ findCookies(domain, path, allowSpecialUseDomain = false, callback) {
51099
+ if (typeof allowSpecialUseDomain === "function") {
51100
+ callback = allowSpecialUseDomain;
51101
+ allowSpecialUseDomain = true;
51102
+ }
51103
+ const results = [];
51104
+ const promiseCallback = createPromiseCallback(callback);
51105
+ if (!domain) {
51106
+ return promiseCallback.resolve([]);
51107
+ }
51108
+ let pathMatcher;
51109
+ if (!path) {
51110
+ pathMatcher = function matchAll(domainIndex) {
51111
+ for (const curPath in domainIndex) {
51112
+ const pathIndex = domainIndex[curPath];
51113
+ for (const key2 in pathIndex) {
51114
+ const value = pathIndex[key2];
51115
+ if (value) {
51116
+ results.push(value);
51117
+ }
51118
+ }
51119
+ }
51120
+ };
51121
+ } else {
51122
+ pathMatcher = function matchRFC(domainIndex) {
51123
+ for (const cookiePath in domainIndex) {
51124
+ if (pathMatch(path, cookiePath)) {
51125
+ const pathIndex = domainIndex[cookiePath];
51126
+ for (const key2 in pathIndex) {
51127
+ const value = pathIndex[key2];
51128
+ if (value) {
51129
+ results.push(value);
51130
+ }
51131
+ }
51132
+ }
51133
+ }
51134
+ };
51135
+ }
51136
+ const domains = permuteDomain(domain, allowSpecialUseDomain) || [domain];
51137
+ const idx = this.idx;
51138
+ domains.forEach((curDomain) => {
51139
+ const domainIndex = idx[curDomain];
51140
+ if (!domainIndex) {
51141
+ return;
51142
+ }
51143
+ pathMatcher(domainIndex);
51144
+ });
51145
+ return promiseCallback.resolve(results);
51146
+ }
51147
+ /**
51148
+ * @internal No doc because this is an overload that supports the implementation
51149
+ */
51150
+ putCookie(cookie, callback) {
51151
+ const promiseCallback = createPromiseCallback(callback);
51152
+ const { domain, path, key: key2 } = cookie;
51153
+ if (domain == null || path == null || key2 == null) {
51154
+ return promiseCallback.resolve(void 0);
51155
+ }
51156
+ const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null);
51157
+ this.idx[domain] = domainEntry;
51158
+ const pathEntry = domainEntry[path] ?? /* @__PURE__ */ Object.create(null);
51159
+ domainEntry[path] = pathEntry;
51160
+ pathEntry[key2] = cookie;
51161
+ return promiseCallback.resolve(void 0);
51162
+ }
51163
+ /**
51164
+ * @internal No doc because this is an overload that supports the implementation
51165
+ */
51166
+ updateCookie(_oldCookie, newCookie, callback) {
51167
+ if (callback) this.putCookie(newCookie, callback);
51168
+ else return this.putCookie(newCookie);
51169
+ }
51170
+ /**
51171
+ * @internal No doc because this is an overload that supports the implementation
51172
+ */
51173
+ removeCookie(domain, path, key2, callback) {
51174
+ const promiseCallback = createPromiseCallback(callback);
51175
+ delete this.idx[domain]?.[path]?.[key2];
51176
+ return promiseCallback.resolve(void 0);
51177
+ }
51178
+ /**
51179
+ * @internal No doc because this is an overload that supports the implementation
51180
+ */
51181
+ removeCookies(domain, path, callback) {
51182
+ const promiseCallback = createPromiseCallback(callback);
51183
+ const domainEntry = this.idx[domain];
51184
+ if (domainEntry) {
51185
+ if (path) {
51186
+ delete domainEntry[path];
51187
+ } else {
51188
+ delete this.idx[domain];
51189
+ }
51190
+ }
51191
+ return promiseCallback.resolve(void 0);
51192
+ }
51193
+ /**
51194
+ * @internal No doc because this is an overload that supports the implementation
51195
+ */
51196
+ removeAllCookies(callback) {
51197
+ const promiseCallback = createPromiseCallback(callback);
51198
+ this.idx = /* @__PURE__ */ Object.create(null);
51199
+ return promiseCallback.resolve(void 0);
51200
+ }
51201
+ /**
51202
+ * @internal No doc because this is an overload that supports the implementation
51203
+ */
51204
+ getAllCookies(callback) {
51205
+ const promiseCallback = createPromiseCallback(callback);
51206
+ const cookies = [];
51207
+ const idx = this.idx;
51208
+ const domains = Object.keys(idx);
51209
+ domains.forEach((domain) => {
51210
+ const domainEntry = idx[domain] ?? {};
51211
+ const paths = Object.keys(domainEntry);
51212
+ paths.forEach((path) => {
51213
+ const pathEntry = domainEntry[path] ?? {};
51214
+ const keys = Object.keys(pathEntry);
51215
+ keys.forEach((key2) => {
51216
+ const keyEntry = pathEntry[key2];
51217
+ if (keyEntry != null) {
51218
+ cookies.push(keyEntry);
51219
+ }
51220
+ });
51221
+ });
51222
+ });
51223
+ cookies.sort((a, b) => {
51224
+ return (a.creationIndex || 0) - (b.creationIndex || 0);
51225
+ });
51226
+ return promiseCallback.resolve(cookies);
51227
+ }
51228
+ };
51229
+ ParameterError = class extends Error {
51230
+ };
51231
+ version = "6.0.1";
51232
+ PrefixSecurityEnum = {
51233
+ SILENT: "silent",
51234
+ STRICT: "strict",
51235
+ DISABLED: "unsafe-disabled"
51236
+ };
51237
+ Object.freeze(PrefixSecurityEnum);
51238
+ IP_V6_REGEX = `
51239
+ \\[?(?:
51240
+ (?:[a-fA-F\\d]{1,4}:){7}(?:[a-fA-F\\d]{1,4}|:)|
51241
+ (?:[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}|:)|
51242
+ (?:[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}|:)|
51243
+ (?:[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}|:)|
51244
+ (?:[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}|:)|
51245
+ (?:[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}|:)|
51246
+ (?:[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}|:)|
51247
+ (?::(?:(?::[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}|:))
51248
+ )(?:%[0-9a-zA-Z]{1,})?\\]?
51249
+ `.replace(/\s*\/\/.*$/gm, "").replace(/\n/g, "").trim();
51250
+ IP_V6_REGEX_OBJECT = new RegExp(`^${IP_V6_REGEX}$`);
51251
+ 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])`;
51252
+ IP_V4_REGEX_OBJECT = new RegExp(`^${IP_V4_REGEX}$`);
51253
+ months = [
51254
+ "jan",
51255
+ "feb",
51256
+ "mar",
51257
+ "apr",
51258
+ "may",
51259
+ "jun",
51260
+ "jul",
51261
+ "aug",
51262
+ "sep",
51263
+ "oct",
51264
+ "nov",
51265
+ "dec"
51266
+ ];
51267
+ DELIMITER = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/;
51268
+ TIME = /^(\d{1,2}):(\d{1,2}):(\d{1,2})(?:[\x00-\x2F\x3A-\xFF][\x00-\xFF]*)?$/;
51269
+ DAY_OF_MONTH = /^[0-9]{1,2}(?:[\x00-\x2F\x3A-\xFF][\x00-\xFF]*)?$/;
51270
+ MONTH = /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[\x00-\xFF]*$/i;
51271
+ YEAR2 = /^[\x30-\x39]{2,4}(?:[\x00-\x2F\x3A-\xFF][\x00-\xFF]*)?$/;
51272
+ COOKIE_OCTETS = /^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+$/;
51273
+ PATH_VALUE = /[\x20-\x3A\x3C-\x7E]+/;
51274
+ CONTROL_CHARS2 = /[\x00-\x1F]/;
51275
+ TERMINATORS = ["\n", "\r", "\0"];
51276
+ cookieDefaults = {
51277
+ // the order in which the RFC has them:
51278
+ key: "",
51279
+ value: "",
51280
+ expires: "Infinity",
51281
+ maxAge: null,
51282
+ domain: null,
51283
+ path: null,
51284
+ secure: false,
51285
+ httpOnly: false,
51286
+ extensions: null,
51287
+ // set by the CookieJar:
51288
+ hostOnly: null,
51289
+ pathIsDefault: null,
51290
+ creation: null,
51291
+ lastAccessed: null,
51292
+ sameSite: void 0
51293
+ };
51294
+ _Cookie = class _Cookie2 {
51295
+ /**
51296
+ * Create a new Cookie instance.
51297
+ * @public
51298
+ * @param options - The attributes to set on the cookie
51299
+ */
51300
+ constructor(options = {}) {
51301
+ this.key = options.key ?? cookieDefaults.key;
51302
+ this.value = options.value ?? cookieDefaults.value;
51303
+ this.expires = options.expires ?? cookieDefaults.expires;
51304
+ this.maxAge = options.maxAge ?? cookieDefaults.maxAge;
51305
+ this.domain = options.domain ?? cookieDefaults.domain;
51306
+ this.path = options.path ?? cookieDefaults.path;
51307
+ this.secure = options.secure ?? cookieDefaults.secure;
51308
+ this.httpOnly = options.httpOnly ?? cookieDefaults.httpOnly;
51309
+ this.extensions = options.extensions ?? cookieDefaults.extensions;
51310
+ this.creation = options.creation ?? cookieDefaults.creation;
51311
+ this.hostOnly = options.hostOnly ?? cookieDefaults.hostOnly;
51312
+ this.pathIsDefault = options.pathIsDefault ?? cookieDefaults.pathIsDefault;
51313
+ this.lastAccessed = options.lastAccessed ?? cookieDefaults.lastAccessed;
51314
+ this.sameSite = options.sameSite ?? cookieDefaults.sameSite;
51315
+ this.creation = options.creation ?? /* @__PURE__ */ new Date();
51316
+ Object.defineProperty(this, "creationIndex", {
51317
+ configurable: false,
51318
+ enumerable: false,
51319
+ // important for assert.deepEqual checks
51320
+ writable: true,
51321
+ value: ++_Cookie2.cookiesCreated
51322
+ });
51323
+ this.creationIndex = _Cookie2.cookiesCreated;
51324
+ }
51325
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
51326
+ const now = Date.now();
51327
+ const hostOnly = this.hostOnly != null ? this.hostOnly.toString() : "?";
51328
+ const createAge = this.creation && this.creation !== "Infinity" ? `${String(now - this.creation.getTime())}ms` : "?";
51329
+ const accessAge = this.lastAccessed && this.lastAccessed !== "Infinity" ? `${String(now - this.lastAccessed.getTime())}ms` : "?";
51330
+ return `Cookie="${this.toString()}; hostOnly=${hostOnly}; aAge=${accessAge}; cAge=${createAge}"`;
51331
+ }
51332
+ /**
51333
+ * For convenience in using `JSON.stringify(cookie)`. Returns a plain-old Object that can be JSON-serialized.
51334
+ *
51335
+ * @remarks
51336
+ * - Any `Date` properties (such as {@link Cookie.expires}, {@link Cookie.creation}, and {@link Cookie.lastAccessed}) are exported in ISO format (`Date.toISOString()`).
51337
+ *
51338
+ * - 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.
51339
+ * If you want a property to be serialized, add the property name to {@link Cookie.serializableProperties}.
51340
+ */
51341
+ toJSON() {
51342
+ const obj = {};
51343
+ for (const prop of _Cookie2.serializableProperties) {
51344
+ const val = this[prop];
51345
+ if (val === cookieDefaults[prop]) {
51346
+ continue;
51347
+ }
51348
+ switch (prop) {
51349
+ case "key":
51350
+ case "value":
51351
+ case "sameSite":
51352
+ if (typeof val === "string") {
51353
+ obj[prop] = val;
51354
+ }
51355
+ break;
51356
+ case "expires":
51357
+ case "creation":
51358
+ case "lastAccessed":
51359
+ if (typeof val === "number" || typeof val === "string" || val instanceof Date) {
51360
+ obj[prop] = val == "Infinity" ? "Infinity" : new Date(val).toISOString();
51361
+ } else if (val === null) {
51362
+ obj[prop] = null;
51363
+ }
51364
+ break;
51365
+ case "maxAge":
51366
+ if (typeof val === "number" || val === "Infinity" || val === "-Infinity") {
51367
+ obj[prop] = val;
51368
+ }
51369
+ break;
51370
+ case "domain":
51371
+ case "path":
51372
+ if (typeof val === "string" || val === null) {
51373
+ obj[prop] = val;
51374
+ }
51375
+ break;
51376
+ case "secure":
51377
+ case "httpOnly":
51378
+ if (typeof val === "boolean") {
51379
+ obj[prop] = val;
51380
+ }
51381
+ break;
51382
+ case "extensions":
51383
+ if (Array.isArray(val)) {
51384
+ obj[prop] = val;
51385
+ }
51386
+ break;
51387
+ case "hostOnly":
51388
+ case "pathIsDefault":
51389
+ if (typeof val === "boolean" || val === null) {
51390
+ obj[prop] = val;
51391
+ }
51392
+ break;
51393
+ }
51394
+ }
51395
+ return obj;
51396
+ }
51397
+ /**
51398
+ * Does a deep clone of this cookie, implemented exactly as `Cookie.fromJSON(cookie.toJSON())`.
51399
+ * @public
51400
+ */
51401
+ clone() {
51402
+ return fromJSON(this.toJSON());
51403
+ }
51404
+ /**
51405
+ * Validates cookie attributes for semantic correctness. Useful for "lint" checking any `Set-Cookie` headers you generate.
51406
+ * For now, it returns a boolean, but eventually could return a reason string.
51407
+ *
51408
+ * @remarks
51409
+ * Works for a few things, but is by no means comprehensive.
51410
+ *
51411
+ * @beta
51412
+ */
51413
+ validate() {
51414
+ if (!this.value || !COOKIE_OCTETS.test(this.value)) {
51415
+ return false;
51416
+ }
51417
+ if (this.expires != "Infinity" && !(this.expires instanceof Date) && !parseDate(this.expires)) {
51418
+ return false;
51419
+ }
51420
+ if (this.maxAge != null && this.maxAge !== "Infinity" && (this.maxAge === "-Infinity" || this.maxAge <= 0)) {
51421
+ return false;
51422
+ }
51423
+ if (this.path != null && !PATH_VALUE.test(this.path)) {
51424
+ return false;
51425
+ }
51426
+ const cdomain = this.cdomain();
51427
+ if (cdomain) {
51428
+ if (cdomain.match(/\.$/)) {
51429
+ return false;
51430
+ }
51431
+ const suffix = getPublicSuffix(cdomain);
51432
+ if (suffix == null) {
51433
+ return false;
51434
+ }
51435
+ }
51436
+ return true;
51437
+ }
51438
+ /**
51439
+ * Sets the 'Expires' attribute on a cookie.
51440
+ *
51441
+ * @remarks
51442
+ * When given a `string` value it will be parsed with {@link parseDate}. If the value can't be parsed as a cookie date
51443
+ * then the 'Expires' attribute will be set to `"Infinity"`.
51444
+ *
51445
+ * @param exp - the new value for the 'Expires' attribute of the cookie.
51446
+ */
51447
+ setExpires(exp) {
51448
+ if (exp instanceof Date) {
51449
+ this.expires = exp;
51450
+ } else {
51451
+ this.expires = parseDate(exp) || "Infinity";
51452
+ }
51453
+ }
51454
+ /**
51455
+ * Sets the 'Max-Age' attribute (in seconds) on a cookie.
51456
+ *
51457
+ * @remarks
51458
+ * Coerces `-Infinity` to `"-Infinity"` and `Infinity` to `"Infinity"` so it can be serialized to JSON.
51459
+ *
51460
+ * @param age - the new value for the 'Max-Age' attribute (in seconds).
51461
+ */
51462
+ setMaxAge(age) {
51463
+ if (age === Infinity) {
51464
+ this.maxAge = "Infinity";
51465
+ } else if (age === -Infinity) {
51466
+ this.maxAge = "-Infinity";
51467
+ } else {
51468
+ this.maxAge = age;
51469
+ }
51470
+ }
51471
+ /**
51472
+ * Encodes to a `Cookie` header value (specifically, the {@link Cookie.key} and {@link Cookie.value} properties joined with "=").
51473
+ * @public
51474
+ */
51475
+ cookieString() {
51476
+ const val = this.value || "";
51477
+ if (this.key) {
51478
+ return `${this.key}=${val}`;
51479
+ }
51480
+ return val;
51481
+ }
51482
+ /**
51483
+ * Encodes to a `Set-Cookie header` value.
51484
+ * @public
51485
+ */
51486
+ toString() {
51487
+ let str6 = this.cookieString();
51488
+ if (this.expires != "Infinity") {
51489
+ if (this.expires instanceof Date) {
51490
+ str6 += `; Expires=${formatDate(this.expires)}`;
51491
+ }
51492
+ }
51493
+ if (this.maxAge != null && this.maxAge != Infinity) {
51494
+ str6 += `; Max-Age=${String(this.maxAge)}`;
51495
+ }
51496
+ if (this.domain && !this.hostOnly) {
51497
+ str6 += `; Domain=${this.domain}`;
51498
+ }
51499
+ if (this.path) {
51500
+ str6 += `; Path=${this.path}`;
51501
+ }
51502
+ if (this.secure) {
51503
+ str6 += "; Secure";
51504
+ }
51505
+ if (this.httpOnly) {
51506
+ str6 += "; HttpOnly";
51507
+ }
51508
+ if (this.sameSite && this.sameSite !== "none") {
51509
+ if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.lax.toLowerCase()) {
51510
+ str6 += `; SameSite=${_Cookie2.sameSiteCanonical.lax}`;
51511
+ } else if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.strict.toLowerCase()) {
51512
+ str6 += `; SameSite=${_Cookie2.sameSiteCanonical.strict}`;
51513
+ } else {
51514
+ str6 += `; SameSite=${this.sameSite}`;
51515
+ }
51516
+ }
51517
+ if (this.extensions) {
51518
+ this.extensions.forEach((ext) => {
51519
+ str6 += `; ${ext}`;
51520
+ });
51521
+ }
51522
+ return str6;
51523
+ }
51524
+ /**
51525
+ * Computes the TTL relative to now (milliseconds).
51526
+ *
51527
+ * @remarks
51528
+ * - `Infinity` is returned for cookies without an explicit expiry
51529
+ *
51530
+ * - `0` is returned if the cookie is expired.
51531
+ *
51532
+ * - Otherwise a time-to-live in milliseconds is returned.
51533
+ *
51534
+ * @param now - passing an explicit value is mostly used for testing purposes since this defaults to the `Date.now()`
51535
+ * @public
51536
+ */
51537
+ TTL(now = Date.now()) {
51538
+ if (this.maxAge != null && typeof this.maxAge === "number") {
51539
+ return this.maxAge <= 0 ? 0 : this.maxAge * 1e3;
51540
+ }
51541
+ const expires = this.expires;
51542
+ if (expires === "Infinity") {
51543
+ return Infinity;
51544
+ }
51545
+ return (expires?.getTime() ?? now) - (now || Date.now());
51546
+ }
51547
+ /**
51548
+ * Computes the absolute unix-epoch milliseconds that this cookie expires.
51549
+ *
51550
+ * The "Max-Age" attribute takes precedence over "Expires" (as per the RFC). The {@link Cookie.lastAccessed} attribute
51551
+ * (or the `now` parameter if given) is used to offset the {@link Cookie.maxAge} attribute.
51552
+ *
51553
+ * If Expires ({@link Cookie.expires}) is set, that's returned.
51554
+ *
51555
+ * @param now - can be used to provide a time offset (instead of {@link Cookie.lastAccessed}) to use when calculating the "Max-Age" value
51556
+ */
51557
+ expiryTime(now) {
51558
+ if (this.maxAge != null) {
51559
+ const relativeTo = now || this.lastAccessed || /* @__PURE__ */ new Date();
51560
+ const maxAge = typeof this.maxAge === "number" ? this.maxAge : -Infinity;
51561
+ const age = maxAge <= 0 ? -Infinity : maxAge * 1e3;
51562
+ if (relativeTo === "Infinity") {
51563
+ return Infinity;
51564
+ }
51565
+ return relativeTo.getTime() + age;
51566
+ }
51567
+ if (this.expires == "Infinity") {
51568
+ return Infinity;
51569
+ }
51570
+ return this.expires ? this.expires.getTime() : void 0;
51571
+ }
51572
+ /**
51573
+ * Similar to {@link Cookie.expiryTime}, computes the absolute unix-epoch milliseconds that this cookie expires and returns it as a Date.
51574
+ *
51575
+ * The "Max-Age" attribute takes precedence over "Expires" (as per the RFC). The {@link Cookie.lastAccessed} attribute
51576
+ * (or the `now` parameter if given) is used to offset the {@link Cookie.maxAge} attribute.
51577
+ *
51578
+ * If Expires ({@link Cookie.expires}) is set, that's returned.
51579
+ *
51580
+ * @param now - can be used to provide a time offset (instead of {@link Cookie.lastAccessed}) to use when calculating the "Max-Age" value
51581
+ */
51582
+ expiryDate(now) {
51583
+ const millisec = this.expiryTime(now);
51584
+ if (millisec == Infinity) {
51585
+ return /* @__PURE__ */ new Date(2147483647e3);
51586
+ } else if (millisec == -Infinity) {
51587
+ return /* @__PURE__ */ new Date(0);
51588
+ } else {
51589
+ return millisec == void 0 ? void 0 : new Date(millisec);
51590
+ }
51591
+ }
51592
+ /**
51593
+ * Indicates if the cookie has been persisted to a store or not.
51594
+ * @public
51595
+ */
51596
+ isPersistent() {
51597
+ return this.maxAge != null || this.expires != "Infinity";
51598
+ }
51599
+ /**
51600
+ * Calls {@link canonicalDomain} with the {@link Cookie.domain} property.
51601
+ * @public
51602
+ */
51603
+ canonicalizedDomain() {
51604
+ return canonicalDomain(this.domain);
51605
+ }
51606
+ /**
51607
+ * Alias for {@link Cookie.canonicalizedDomain}
51608
+ * @public
51609
+ */
51610
+ cdomain() {
51611
+ return canonicalDomain(this.domain);
51612
+ }
51613
+ /**
51614
+ * Parses a string into a Cookie object.
51615
+ *
51616
+ * @remarks
51617
+ * Note: when parsing a `Cookie` header it must be split by ';' before each Cookie string can be parsed.
51618
+ *
51619
+ * @example
51620
+ * ```
51621
+ * // parse a `Set-Cookie` header
51622
+ * const setCookieHeader = 'a=bcd; Expires=Tue, 18 Oct 2011 07:05:03 GMT'
51623
+ * const cookie = Cookie.parse(setCookieHeader)
51624
+ * cookie.key === 'a'
51625
+ * cookie.value === 'bcd'
51626
+ * cookie.expires === new Date(Date.parse('Tue, 18 Oct 2011 07:05:03 GMT'))
51627
+ * ```
51628
+ *
51629
+ * @example
51630
+ * ```
51631
+ * // parse a `Cookie` header
51632
+ * const cookieHeader = 'name=value; name2=value2; name3=value3'
51633
+ * const cookies = cookieHeader.split(';').map(Cookie.parse)
51634
+ * cookies[0].name === 'name'
51635
+ * cookies[0].value === 'value'
51636
+ * cookies[1].name === 'name2'
51637
+ * cookies[1].value === 'value2'
51638
+ * cookies[2].name === 'name3'
51639
+ * cookies[2].value === 'value3'
51640
+ * ```
51641
+ *
51642
+ * @param str - The `Set-Cookie` header or a Cookie string to parse.
51643
+ * @param options - Configures `strict` or `loose` mode for cookie parsing
51644
+ */
51645
+ static parse(str6, options) {
51646
+ return parse(str6, options);
51647
+ }
51648
+ /**
51649
+ * Does the reverse of {@link Cookie.toJSON}.
51650
+ *
51651
+ * @remarks
51652
+ * 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.
51653
+ *
51654
+ * @example
51655
+ * ```
51656
+ * const json = JSON.stringify({
51657
+ * key: 'alpha',
51658
+ * value: 'beta',
51659
+ * domain: 'example.com',
51660
+ * path: '/foo',
51661
+ * expires: '2038-01-19T03:14:07.000Z',
51662
+ * })
51663
+ * const cookie = Cookie.fromJSON(json)
51664
+ * cookie.key === 'alpha'
51665
+ * cookie.value === 'beta'
51666
+ * cookie.domain === 'example.com'
51667
+ * cookie.path === '/foo'
51668
+ * cookie.expires === new Date(Date.parse('2038-01-19T03:14:07.000Z'))
51669
+ * ```
51670
+ *
51671
+ * @param str - An unparsed JSON string or a value that has already been parsed as JSON
51672
+ */
51673
+ static fromJSON(str6) {
51674
+ return fromJSON(str6);
51675
+ }
51676
+ };
51677
+ _Cookie.cookiesCreated = 0;
51678
+ _Cookie.sameSiteLevel = {
51679
+ strict: 3,
51680
+ lax: 2,
51681
+ none: 1
51682
+ };
51683
+ _Cookie.sameSiteCanonical = {
51684
+ strict: "Strict",
51685
+ lax: "Lax"
51686
+ };
51687
+ _Cookie.serializableProperties = [
51688
+ "key",
51689
+ "value",
51690
+ "expires",
51691
+ "maxAge",
51692
+ "domain",
51693
+ "path",
51694
+ "secure",
51695
+ "httpOnly",
51696
+ "extensions",
51697
+ "hostOnly",
51698
+ "pathIsDefault",
51699
+ "creation",
51700
+ "lastAccessed",
51701
+ "sameSite"
51702
+ ];
51703
+ Cookie = _Cookie;
51704
+ MAX_TIME = 2147483647e3;
51705
+ 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}|:)))$)/;
51706
+ defaultSetCookieOptions = {
51707
+ loose: false,
51708
+ sameSiteContext: void 0,
51709
+ ignoreError: false,
51710
+ http: true
51711
+ };
51712
+ defaultGetCookieOptions = {
51713
+ http: true,
51714
+ expire: true,
51715
+ allPaths: false,
51716
+ sameSiteContext: void 0,
51717
+ sort: void 0
51718
+ };
51719
+ SAME_SITE_CONTEXT_VAL_ERR = 'Invalid sameSiteContext option for getCookies(); expected one of "strict", "lax", or "none"';
51720
+ CookieJar = class _CookieJar {
51721
+ /**
51722
+ * Creates a new `CookieJar` instance.
51723
+ *
51724
+ * @remarks
51725
+ * - If a custom store is not passed to the constructor, an in-memory store ({@link MemoryCookieStore} will be created and used.
51726
+ * - If a boolean value is passed as the `options` parameter, this is equivalent to passing `{ rejectPublicSuffixes: <value> }`
51727
+ *
51728
+ * @param store - a custom {@link Store} implementation (defaults to {@link MemoryCookieStore})
51729
+ * @param options - configures how cookies are processed by the cookie jar
51730
+ */
51731
+ constructor(store, options) {
51732
+ if (typeof options === "boolean") {
51733
+ options = { rejectPublicSuffixes: options };
51734
+ }
51735
+ this.rejectPublicSuffixes = options?.rejectPublicSuffixes ?? true;
51736
+ this.enableLooseMode = options?.looseMode ?? false;
51737
+ this.allowSpecialUseDomain = options?.allowSpecialUseDomain ?? true;
51738
+ this.allowSecureOnLocal = options?.allowSecureOnLocal ?? true;
51739
+ this.prefixSecurity = getNormalizedPrefixSecurity(
51740
+ options?.prefixSecurity ?? "silent"
51741
+ );
51742
+ this.store = store ?? new MemoryCookieStore();
51743
+ }
51744
+ callSync(fn) {
51745
+ if (!this.store.synchronous) {
51746
+ throw new Error(
51747
+ "CookieJar store is not synchronous; use async API instead."
51748
+ );
51749
+ }
51750
+ let syncErr = null;
51751
+ let syncResult = void 0;
51752
+ try {
51753
+ fn.call(this, (error, result) => {
51754
+ syncErr = error;
51755
+ syncResult = result;
51756
+ });
51757
+ } catch (err) {
51758
+ syncErr = err;
51759
+ }
51760
+ if (syncErr) throw syncErr;
51761
+ return syncResult;
51762
+ }
51763
+ /**
51764
+ * @internal No doc because this is the overload implementation
51765
+ */
51766
+ setCookie(cookie, url, options, callback) {
51767
+ if (typeof options === "function") {
51768
+ callback = options;
51769
+ options = void 0;
51770
+ }
51771
+ const promiseCallback = createPromiseCallback(callback);
51772
+ const cb = promiseCallback.callback;
51773
+ let context;
51774
+ try {
51775
+ if (typeof url === "string") {
51776
+ validate2(
51777
+ isNonEmptyString(url),
51778
+ callback,
51779
+ safeToString(options)
51780
+ );
51781
+ }
51782
+ context = getCookieContext(url);
51783
+ if (typeof url === "function") {
51784
+ return promiseCallback.reject(new Error("No URL was specified"));
51785
+ }
51786
+ if (typeof options === "function") {
51787
+ options = defaultSetCookieOptions;
51788
+ }
51789
+ validate2(typeof cb === "function", cb);
51790
+ if (!isNonEmptyString(cookie) && !isObject(cookie) && cookie instanceof String && cookie.length == 0) {
51791
+ return promiseCallback.resolve(void 0);
51792
+ }
51793
+ } catch (err) {
51794
+ return promiseCallback.reject(err);
51795
+ }
51796
+ const host = canonicalDomain(context.hostname) ?? null;
51797
+ const loose = options?.loose || this.enableLooseMode;
51798
+ let sameSiteContext = null;
51799
+ if (options?.sameSiteContext) {
51800
+ sameSiteContext = checkSameSiteContext(options.sameSiteContext);
51801
+ if (!sameSiteContext) {
51802
+ return promiseCallback.reject(new Error(SAME_SITE_CONTEXT_VAL_ERR));
51803
+ }
51804
+ }
51805
+ if (typeof cookie === "string" || cookie instanceof String) {
51806
+ const parsedCookie = Cookie.parse(cookie.toString(), { loose });
51807
+ if (!parsedCookie) {
51808
+ const err = new Error("Cookie failed to parse");
51809
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51810
+ }
51811
+ cookie = parsedCookie;
51812
+ } else if (!(cookie instanceof Cookie)) {
51813
+ const err = new Error(
51814
+ "First argument to setCookie must be a Cookie object or string"
51815
+ );
51816
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51817
+ }
51818
+ const now = options?.now || /* @__PURE__ */ new Date();
51819
+ if (this.rejectPublicSuffixes && cookie.domain) {
51820
+ try {
51821
+ const cdomain = cookie.cdomain();
51822
+ const suffix = typeof cdomain === "string" ? getPublicSuffix(cdomain, {
51823
+ allowSpecialUseDomain: this.allowSpecialUseDomain,
51824
+ ignoreError: options?.ignoreError
51825
+ }) : null;
51826
+ if (suffix == null && !IP_V6_REGEX_OBJECT.test(cookie.domain)) {
51827
+ const err = new Error("Cookie has domain set to a public suffix");
51828
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51829
+ }
51830
+ } catch (err) {
51831
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : (
51832
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
51833
+ promiseCallback.reject(err)
51834
+ );
51835
+ }
51836
+ }
51837
+ if (cookie.domain) {
51838
+ if (!domainMatch(host ?? void 0, cookie.cdomain() ?? void 0, false)) {
51839
+ const err = new Error(
51840
+ `Cookie not in this host's domain. Cookie:${cookie.cdomain() ?? "null"} Request:${host ?? "null"}`
51841
+ );
51842
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51843
+ }
51844
+ if (cookie.hostOnly == null) {
51845
+ cookie.hostOnly = false;
51846
+ }
51847
+ } else {
51848
+ cookie.hostOnly = true;
51849
+ cookie.domain = host;
51850
+ }
51851
+ if (!cookie.path || cookie.path[0] !== "/") {
51852
+ cookie.path = defaultPath(context.pathname);
51853
+ cookie.pathIsDefault = true;
51854
+ }
51855
+ if (options?.http === false && cookie.httpOnly) {
51856
+ const err = new Error("Cookie is HttpOnly and this isn't an HTTP API");
51857
+ return options.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51858
+ }
51859
+ if (cookie.sameSite !== "none" && cookie.sameSite !== void 0 && sameSiteContext) {
51860
+ if (sameSiteContext === "none") {
51861
+ const err = new Error(
51862
+ "Cookie is SameSite but this is a cross-origin request"
51863
+ );
51864
+ return options?.ignoreError ? promiseCallback.resolve(void 0) : promiseCallback.reject(err);
51865
+ }
51866
+ }
51867
+ const ignoreErrorForPrefixSecurity = this.prefixSecurity === PrefixSecurityEnum.SILENT;
51868
+ const prefixSecurityDisabled = this.prefixSecurity === PrefixSecurityEnum.DISABLED;
51869
+ if (!prefixSecurityDisabled) {
51870
+ let errorFound = false;
51871
+ let errorMsg;
51872
+ if (!isSecurePrefixConditionMet(cookie)) {
51873
+ errorFound = true;
51874
+ errorMsg = "Cookie has __Secure prefix but Secure attribute is not set";
51875
+ } else if (!isHostPrefixConditionMet(cookie)) {
51876
+ errorFound = true;
51877
+ errorMsg = "Cookie has __Host prefix but either Secure or HostOnly attribute is not set or Path is not '/'";
51878
+ }
51879
+ if (errorFound) {
51880
+ return options?.ignoreError || ignoreErrorForPrefixSecurity ? promiseCallback.resolve(void 0) : promiseCallback.reject(new Error(errorMsg));
51881
+ }
51882
+ }
51883
+ const store = this.store;
51884
+ if (!store.updateCookie) {
51885
+ store.updateCookie = async function(_oldCookie, newCookie, cb2) {
51886
+ return this.putCookie(newCookie).then(
51887
+ () => cb2?.(null),
51888
+ (error) => cb2?.(error)
51889
+ );
51890
+ };
51891
+ }
51892
+ const withCookie = function withCookie2(err, oldCookie) {
51893
+ if (err) {
51894
+ cb(err);
51895
+ return;
51896
+ }
51897
+ const next = function(err2) {
51898
+ if (err2) {
51899
+ cb(err2);
51900
+ } else if (typeof cookie === "string") {
51901
+ cb(null, void 0);
51902
+ } else {
51903
+ cb(null, cookie);
51904
+ }
51905
+ };
51906
+ if (oldCookie) {
51907
+ if (options && "http" in options && options.http === false && oldCookie.httpOnly) {
51908
+ err = new Error("old Cookie is HttpOnly and this isn't an HTTP API");
51909
+ if (options.ignoreError) cb(null, void 0);
51910
+ else cb(err);
51911
+ return;
51912
+ }
51913
+ if (cookie instanceof Cookie) {
51914
+ cookie.creation = oldCookie.creation;
51915
+ cookie.creationIndex = oldCookie.creationIndex;
51916
+ cookie.lastAccessed = now;
51917
+ store.updateCookie(oldCookie, cookie, next);
51918
+ }
51919
+ } else {
51920
+ if (cookie instanceof Cookie) {
51921
+ cookie.creation = cookie.lastAccessed = now;
51922
+ store.putCookie(cookie, next);
51923
+ }
51924
+ }
51925
+ };
51926
+ store.findCookie(cookie.domain, cookie.path, cookie.key, withCookie);
51927
+ return promiseCallback.promise;
51928
+ }
51929
+ /**
51930
+ * Synchronously attempt to set the {@link Cookie} in the {@link CookieJar}.
51931
+ *
51932
+ * <strong>Note:</strong> Only works if the configured {@link Store} is also synchronous.
51933
+ *
51934
+ * @remarks
51935
+ * - If successfully persisted, the {@link Cookie} will have updated
51936
+ * {@link Cookie.creation}, {@link Cookie.lastAccessed} and {@link Cookie.hostOnly}
51937
+ * properties.
51938
+ *
51939
+ * - As per the RFC, the {@link Cookie.hostOnly} flag is set if there was no `Domain={value}`
51940
+ * attribute on the cookie string. The {@link Cookie.domain} property is set to the
51941
+ * fully-qualified hostname of `currentUrl` in this case. Matching this cookie requires an
51942
+ * exact hostname match (not a {@link domainMatch} as per usual)
51943
+ *
51944
+ * @param cookie - The cookie object or cookie string to store. A string value will be parsed into a cookie using {@link Cookie.parse}.
51945
+ * @param url - The domain to store the cookie with.
51946
+ * @param options - Configuration settings to use when storing the cookie.
51947
+ * @public
51948
+ */
51949
+ setCookieSync(cookie, url, options) {
51950
+ const setCookieFn = options ? this.setCookie.bind(this, cookie, url, options) : this.setCookie.bind(this, cookie, url);
51951
+ return this.callSync(setCookieFn);
51952
+ }
51953
+ /**
51954
+ * @internal No doc because this is the overload implementation
51955
+ */
51956
+ getCookies(url, options, callback) {
51957
+ if (typeof options === "function") {
51958
+ callback = options;
51959
+ options = defaultGetCookieOptions;
51960
+ } else if (options === void 0) {
51961
+ options = defaultGetCookieOptions;
51962
+ }
51963
+ const promiseCallback = createPromiseCallback(callback);
51964
+ const cb = promiseCallback.callback;
51965
+ let context;
51966
+ try {
51967
+ if (typeof url === "string") {
51968
+ validate2(isNonEmptyString(url), cb, url);
51969
+ }
51970
+ context = getCookieContext(url);
51971
+ validate2(
51972
+ isObject(options),
51973
+ cb,
51974
+ safeToString(options)
51975
+ );
51976
+ validate2(typeof cb === "function", cb);
51977
+ } catch (parameterError) {
51978
+ return promiseCallback.reject(parameterError);
51979
+ }
51980
+ const host = canonicalDomain(context.hostname);
51981
+ const path = context.pathname || "/";
51982
+ const potentiallyTrustworthy = isPotentiallyTrustworthy(
51983
+ url,
51984
+ this.allowSecureOnLocal
51985
+ );
51986
+ let sameSiteLevel = 0;
51987
+ if (options.sameSiteContext) {
51988
+ const sameSiteContext = checkSameSiteContext(options.sameSiteContext);
51989
+ if (sameSiteContext == null) {
51990
+ return promiseCallback.reject(new Error(SAME_SITE_CONTEXT_VAL_ERR));
51991
+ }
51992
+ sameSiteLevel = Cookie.sameSiteLevel[sameSiteContext];
51993
+ if (!sameSiteLevel) {
51994
+ return promiseCallback.reject(new Error(SAME_SITE_CONTEXT_VAL_ERR));
51995
+ }
51996
+ }
51997
+ const http = options.http ?? true;
51998
+ const now = Date.now();
51999
+ const expireCheck = options.expire ?? true;
52000
+ const allPaths = options.allPaths ?? false;
52001
+ const store = this.store;
52002
+ function matchingCookie(c) {
52003
+ if (c.hostOnly) {
52004
+ if (c.domain != host) {
52005
+ return false;
52006
+ }
52007
+ } else {
52008
+ if (!domainMatch(host ?? void 0, c.domain ?? void 0, false)) {
52009
+ return false;
52010
+ }
52011
+ }
52012
+ if (!allPaths && typeof c.path === "string" && !pathMatch(path, c.path)) {
52013
+ return false;
52014
+ }
52015
+ if (c.secure && !potentiallyTrustworthy) {
52016
+ return false;
52017
+ }
52018
+ if (c.httpOnly && !http) {
52019
+ return false;
52020
+ }
52021
+ if (sameSiteLevel) {
52022
+ let cookieLevel;
52023
+ if (c.sameSite === "lax") {
52024
+ cookieLevel = Cookie.sameSiteLevel.lax;
52025
+ } else if (c.sameSite === "strict") {
52026
+ cookieLevel = Cookie.sameSiteLevel.strict;
52027
+ } else {
52028
+ cookieLevel = Cookie.sameSiteLevel.none;
52029
+ }
52030
+ if (cookieLevel > sameSiteLevel) {
52031
+ return false;
52032
+ }
52033
+ }
52034
+ const expiryTime = c.expiryTime();
52035
+ if (expireCheck && expiryTime != void 0 && expiryTime <= now) {
52036
+ store.removeCookie(c.domain, c.path, c.key, () => {
52037
+ });
52038
+ return false;
52039
+ }
52040
+ return true;
52041
+ }
52042
+ store.findCookies(
52043
+ host,
52044
+ allPaths ? null : path,
52045
+ this.allowSpecialUseDomain,
52046
+ (err, cookies) => {
52047
+ if (err) {
52048
+ cb(err);
52049
+ return;
52050
+ }
52051
+ if (cookies == null) {
52052
+ cb(null, []);
52053
+ return;
52054
+ }
52055
+ cookies = cookies.filter(matchingCookie);
52056
+ if ("sort" in options && options.sort !== false) {
52057
+ cookies = cookies.sort(cookieCompare);
52058
+ }
52059
+ const now2 = /* @__PURE__ */ new Date();
52060
+ for (const cookie of cookies) {
52061
+ cookie.lastAccessed = now2;
52062
+ }
52063
+ cb(null, cookies);
52064
+ }
52065
+ );
52066
+ return promiseCallback.promise;
52067
+ }
52068
+ /**
52069
+ * Synchronously retrieve the list of cookies that can be sent in a Cookie header for the
52070
+ * current URL.
52071
+ *
52072
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52073
+ *
52074
+ * @remarks
52075
+ * - The array of cookies returned will be sorted according to {@link cookieCompare}.
52076
+ *
52077
+ * - The {@link Cookie.lastAccessed} property will be updated on all returned cookies.
52078
+ *
52079
+ * @param url - The domain to store the cookie with.
52080
+ * @param options - Configuration settings to use when retrieving the cookies.
52081
+ */
52082
+ getCookiesSync(url, options) {
52083
+ return this.callSync(this.getCookies.bind(this, url, options)) ?? [];
52084
+ }
52085
+ /**
52086
+ * @internal No doc because this is the overload implementation
52087
+ */
52088
+ getCookieString(url, options, callback) {
52089
+ if (typeof options === "function") {
52090
+ callback = options;
52091
+ options = void 0;
52092
+ }
52093
+ const promiseCallback = createPromiseCallback(callback);
52094
+ const next = function(err, cookies) {
52095
+ if (err) {
52096
+ promiseCallback.callback(err);
52097
+ } else {
52098
+ promiseCallback.callback(
52099
+ null,
52100
+ cookies?.sort(cookieCompare).map((c) => c.cookieString()).join("; ")
52101
+ );
52102
+ }
52103
+ };
52104
+ this.getCookies(url, options, next);
52105
+ return promiseCallback.promise;
52106
+ }
52107
+ /**
52108
+ * Synchronous version of `.getCookieString()`. Accepts the same options as `.getCookies()` but returns a string suitable for a
52109
+ * `Cookie` header rather than an Array.
52110
+ *
52111
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52112
+ *
52113
+ * @param url - The domain to store the cookie with.
52114
+ * @param options - Configuration settings to use when retrieving the cookies.
52115
+ */
52116
+ getCookieStringSync(url, options) {
52117
+ return this.callSync(
52118
+ options ? this.getCookieString.bind(this, url, options) : this.getCookieString.bind(this, url)
52119
+ ) ?? "";
52120
+ }
52121
+ /**
52122
+ * @internal No doc because this is the overload implementation
52123
+ */
52124
+ getSetCookieStrings(url, options, callback) {
52125
+ if (typeof options === "function") {
52126
+ callback = options;
52127
+ options = void 0;
52128
+ }
52129
+ const promiseCallback = createPromiseCallback(
52130
+ callback
52131
+ );
52132
+ const next = function(err, cookies) {
52133
+ if (err) {
52134
+ promiseCallback.callback(err);
52135
+ } else {
52136
+ promiseCallback.callback(
52137
+ null,
52138
+ cookies?.map((c) => {
52139
+ return c.toString();
52140
+ })
52141
+ );
52142
+ }
52143
+ };
52144
+ this.getCookies(url, options, next);
52145
+ return promiseCallback.promise;
52146
+ }
52147
+ /**
52148
+ * Synchronous version of `.getSetCookieStrings()`. Returns an array of strings suitable for `Set-Cookie` headers.
52149
+ * Accepts the same options as `.getCookies()`.
52150
+ *
52151
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52152
+ *
52153
+ * @param url - The domain to store the cookie with.
52154
+ * @param options - Configuration settings to use when retrieving the cookies.
52155
+ */
52156
+ getSetCookieStringsSync(url, options = {}) {
52157
+ return this.callSync(this.getSetCookieStrings.bind(this, url, options)) ?? [];
52158
+ }
52159
+ /**
52160
+ * @internal No doc because this is the overload implementation
52161
+ */
52162
+ serialize(callback) {
52163
+ const promiseCallback = createPromiseCallback(callback);
52164
+ let type = this.store.constructor.name;
52165
+ if (isObject(type)) {
52166
+ type = null;
52167
+ }
52168
+ const serialized = {
52169
+ // The version of tough-cookie that serialized this jar. Generally a good
52170
+ // practice since future versions can make data import decisions based on
52171
+ // known past behavior. When/if this matters, use `semver`.
52172
+ version: `tough-cookie@${version}`,
52173
+ // add the store type, to make humans happy:
52174
+ storeType: type,
52175
+ // CookieJar configuration:
52176
+ rejectPublicSuffixes: this.rejectPublicSuffixes,
52177
+ enableLooseMode: this.enableLooseMode,
52178
+ allowSpecialUseDomain: this.allowSpecialUseDomain,
52179
+ prefixSecurity: getNormalizedPrefixSecurity(this.prefixSecurity),
52180
+ // this gets filled from getAllCookies:
52181
+ cookies: []
52182
+ };
52183
+ if (typeof this.store.getAllCookies !== "function") {
52184
+ return promiseCallback.reject(
52185
+ new Error(
52186
+ "store does not support getAllCookies and cannot be serialized"
52187
+ )
52188
+ );
52189
+ }
52190
+ this.store.getAllCookies((err, cookies) => {
52191
+ if (err) {
52192
+ promiseCallback.callback(err);
52193
+ return;
52194
+ }
52195
+ if (cookies == null) {
52196
+ promiseCallback.callback(null, serialized);
52197
+ return;
52198
+ }
52199
+ serialized.cookies = cookies.map((cookie) => {
52200
+ const serializedCookie = cookie.toJSON();
52201
+ delete serializedCookie.creationIndex;
52202
+ return serializedCookie;
52203
+ });
52204
+ promiseCallback.callback(null, serialized);
52205
+ });
52206
+ return promiseCallback.promise;
52207
+ }
52208
+ /**
52209
+ * Serialize the CookieJar if the underlying store supports `.getAllCookies`.
52210
+ *
52211
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52212
+ */
52213
+ serializeSync() {
52214
+ return this.callSync((callback) => {
52215
+ this.serialize(callback);
52216
+ });
52217
+ }
52218
+ /**
52219
+ * Alias of {@link CookieJar.serializeSync}. Allows the cookie to be serialized
52220
+ * with `JSON.stringify(cookieJar)`.
52221
+ */
52222
+ toJSON() {
52223
+ return this.serializeSync();
52224
+ }
52225
+ /**
52226
+ * Use the class method CookieJar.deserialize instead of calling this directly
52227
+ * @internal
52228
+ */
52229
+ _importCookies(serialized, callback) {
52230
+ let cookies = void 0;
52231
+ if (serialized && typeof serialized === "object" && inOperator("cookies", serialized) && Array.isArray(serialized.cookies)) {
52232
+ cookies = serialized.cookies;
52233
+ }
52234
+ if (!cookies) {
52235
+ callback(new Error("serialized jar has no cookies array"), void 0);
52236
+ return;
52237
+ }
52238
+ cookies = cookies.slice();
52239
+ const putNext = (err) => {
52240
+ if (err) {
52241
+ callback(err, void 0);
52242
+ return;
52243
+ }
52244
+ if (Array.isArray(cookies)) {
52245
+ if (!cookies.length) {
52246
+ callback(err, this);
52247
+ return;
52248
+ }
52249
+ let cookie;
52250
+ try {
52251
+ cookie = Cookie.fromJSON(cookies.shift());
52252
+ } catch (e) {
52253
+ callback(e instanceof Error ? e : new Error(), void 0);
52254
+ return;
52255
+ }
52256
+ if (cookie === void 0) {
52257
+ putNext(null);
52258
+ return;
52259
+ }
52260
+ this.store.putCookie(cookie, putNext);
52261
+ }
52262
+ };
52263
+ putNext(null);
52264
+ }
52265
+ /**
52266
+ * @internal
52267
+ */
52268
+ _importCookiesSync(serialized) {
52269
+ this.callSync(this._importCookies.bind(this, serialized));
52270
+ }
52271
+ /**
52272
+ * @internal No doc because this is the overload implementation
52273
+ */
52274
+ clone(newStore, callback) {
52275
+ if (typeof newStore === "function") {
52276
+ callback = newStore;
52277
+ newStore = void 0;
52278
+ }
52279
+ const promiseCallback = createPromiseCallback(callback);
52280
+ const cb = promiseCallback.callback;
52281
+ this.serialize((err, serialized) => {
52282
+ if (err) {
52283
+ return promiseCallback.reject(err);
52284
+ }
52285
+ return _CookieJar.deserialize(serialized ?? "", newStore, cb);
52286
+ });
52287
+ return promiseCallback.promise;
52288
+ }
52289
+ /**
52290
+ * @internal
52291
+ */
52292
+ _cloneSync(newStore) {
52293
+ const cloneFn = newStore && typeof newStore !== "function" ? this.clone.bind(this, newStore) : this.clone.bind(this);
52294
+ return this.callSync((callback) => {
52295
+ cloneFn(callback);
52296
+ });
52297
+ }
52298
+ /**
52299
+ * Produces a deep clone of this CookieJar. Modifications to the original do
52300
+ * not affect the clone, and vice versa.
52301
+ *
52302
+ * <strong>Note</strong>: Only works if both the configured Store and destination
52303
+ * Store are synchronous.
52304
+ *
52305
+ * @remarks
52306
+ * - When no {@link Store} is provided, a new {@link MemoryCookieStore} will be used.
52307
+ *
52308
+ * - Transferring between store types is supported so long as the source
52309
+ * implements `.getAllCookies()` and the destination implements `.putCookie()`.
52310
+ *
52311
+ * @param newStore - The target {@link Store} to clone cookies into.
52312
+ */
52313
+ cloneSync(newStore) {
52314
+ if (!newStore) {
52315
+ return this._cloneSync();
52316
+ }
52317
+ if (!newStore.synchronous) {
52318
+ throw new Error(
52319
+ "CookieJar clone destination store is not synchronous; use async API instead."
52320
+ );
52321
+ }
52322
+ return this._cloneSync(newStore);
52323
+ }
52324
+ /**
52325
+ * @internal No doc because this is the overload implementation
52326
+ */
52327
+ removeAllCookies(callback) {
52328
+ const promiseCallback = createPromiseCallback(callback);
52329
+ const cb = promiseCallback.callback;
52330
+ const store = this.store;
52331
+ if (typeof store.removeAllCookies === "function" && store.removeAllCookies !== Store2.prototype.removeAllCookies) {
52332
+ store.removeAllCookies(cb);
52333
+ return promiseCallback.promise;
52334
+ }
52335
+ store.getAllCookies((err, cookies) => {
52336
+ if (err) {
52337
+ cb(err);
52338
+ return;
52339
+ }
52340
+ if (!cookies) {
52341
+ cookies = [];
52342
+ }
52343
+ if (cookies.length === 0) {
52344
+ cb(null, void 0);
52345
+ return;
52346
+ }
52347
+ let completedCount = 0;
52348
+ const removeErrors = [];
52349
+ const removeCookieCb = function removeCookieCb2(removeErr) {
52350
+ if (removeErr) {
52351
+ removeErrors.push(removeErr);
52352
+ }
52353
+ completedCount++;
52354
+ if (completedCount === cookies.length) {
52355
+ if (removeErrors[0]) cb(removeErrors[0]);
52356
+ else cb(null, void 0);
52357
+ return;
52358
+ }
52359
+ };
52360
+ cookies.forEach((cookie) => {
52361
+ store.removeCookie(
52362
+ cookie.domain,
52363
+ cookie.path,
52364
+ cookie.key,
52365
+ removeCookieCb
52366
+ );
52367
+ });
52368
+ });
52369
+ return promiseCallback.promise;
52370
+ }
52371
+ /**
52372
+ * Removes all cookies from the CookieJar.
52373
+ *
52374
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52375
+ *
52376
+ * @remarks
52377
+ * - This is a new backwards-compatible feature of tough-cookie version 2.5,
52378
+ * so not all Stores will implement it efficiently. For Stores that do not
52379
+ * implement `removeAllCookies`, the fallback is to call `removeCookie` after
52380
+ * `getAllCookies`.
52381
+ *
52382
+ * - If `getAllCookies` fails or isn't implemented in the Store, an error is returned.
52383
+ *
52384
+ * - If one or more of the `removeCookie` calls fail, only the first error is returned.
52385
+ */
52386
+ removeAllCookiesSync() {
52387
+ this.callSync((callback) => {
52388
+ this.removeAllCookies(callback);
52389
+ });
52390
+ }
52391
+ /**
52392
+ * @internal No doc because this is the overload implementation
52393
+ */
52394
+ static deserialize(strOrObj, store, callback) {
52395
+ if (typeof store === "function") {
52396
+ callback = store;
52397
+ store = void 0;
52398
+ }
52399
+ const promiseCallback = createPromiseCallback(callback);
52400
+ let serialized;
52401
+ if (typeof strOrObj === "string") {
52402
+ try {
52403
+ serialized = JSON.parse(strOrObj);
52404
+ } catch (e) {
52405
+ return promiseCallback.reject(e instanceof Error ? e : new Error());
52406
+ }
52407
+ } else {
52408
+ serialized = strOrObj;
52409
+ }
52410
+ const readSerializedProperty = (property) => {
52411
+ return serialized && typeof serialized === "object" && inOperator(property, serialized) ? serialized[property] : void 0;
52412
+ };
52413
+ const readSerializedBoolean = (property) => {
52414
+ const value = readSerializedProperty(property);
52415
+ return typeof value === "boolean" ? value : void 0;
52416
+ };
52417
+ const readSerializedString = (property) => {
52418
+ const value = readSerializedProperty(property);
52419
+ return typeof value === "string" ? value : void 0;
52420
+ };
52421
+ const jar = new _CookieJar(store, {
52422
+ rejectPublicSuffixes: readSerializedBoolean("rejectPublicSuffixes"),
52423
+ looseMode: readSerializedBoolean("enableLooseMode"),
52424
+ allowSpecialUseDomain: readSerializedBoolean("allowSpecialUseDomain"),
52425
+ prefixSecurity: getNormalizedPrefixSecurity(
52426
+ readSerializedString("prefixSecurity") ?? "silent"
52427
+ )
52428
+ });
52429
+ jar._importCookies(serialized, (err) => {
52430
+ if (err) {
52431
+ promiseCallback.callback(err);
52432
+ return;
52433
+ }
52434
+ promiseCallback.callback(null, jar);
52435
+ });
52436
+ return promiseCallback.promise;
52437
+ }
52438
+ /**
52439
+ * A new CookieJar is created and the serialized {@link Cookie} values are added to
52440
+ * the underlying store. Each {@link Cookie} is added via `store.putCookie(...)` in
52441
+ * the order in which they appear in the serialization.
52442
+ *
52443
+ * <strong>Note</strong>: Only works if the configured Store is also synchronous.
52444
+ *
52445
+ * @remarks
52446
+ * - When no {@link Store} is provided, a new {@link MemoryCookieStore} will be used.
52447
+ *
52448
+ * - As a convenience, if `strOrObj` is a string, it is passed through `JSON.parse` first.
52449
+ *
52450
+ * @param strOrObj - A JSON string or object representing the deserialized cookies.
52451
+ * @param store - The underlying store to persist the deserialized cookies into.
52452
+ */
52453
+ static deserializeSync(strOrObj, store) {
52454
+ const serialized = typeof strOrObj === "string" ? JSON.parse(strOrObj) : strOrObj;
52455
+ const readSerializedProperty = (property) => {
52456
+ return serialized && typeof serialized === "object" && inOperator(property, serialized) ? serialized[property] : void 0;
52457
+ };
52458
+ const readSerializedBoolean = (property) => {
52459
+ const value = readSerializedProperty(property);
52460
+ return typeof value === "boolean" ? value : void 0;
52461
+ };
52462
+ const readSerializedString = (property) => {
52463
+ const value = readSerializedProperty(property);
52464
+ return typeof value === "string" ? value : void 0;
52465
+ };
52466
+ const jar = new _CookieJar(store, {
52467
+ rejectPublicSuffixes: readSerializedBoolean("rejectPublicSuffixes"),
52468
+ looseMode: readSerializedBoolean("enableLooseMode"),
52469
+ allowSpecialUseDomain: readSerializedBoolean("allowSpecialUseDomain"),
52470
+ prefixSecurity: getNormalizedPrefixSecurity(
52471
+ readSerializedString("prefixSecurity") ?? "silent"
52472
+ )
52473
+ });
52474
+ if (!jar.store.synchronous) {
52475
+ throw new Error(
52476
+ "CookieJar store is not synchronous; use async API instead."
52477
+ );
52478
+ }
52479
+ jar._importCookiesSync(serialized);
52480
+ return jar;
52481
+ }
52482
+ /**
52483
+ * Alias of {@link CookieJar.deserializeSync}.
52484
+ *
52485
+ * @remarks
52486
+ * - When no {@link Store} is provided, a new {@link MemoryCookieStore} will be used.
52487
+ *
52488
+ * - As a convenience, if `strOrObj` is a string, it is passed through `JSON.parse` first.
52489
+ *
52490
+ * @param jsonString - A JSON string or object representing the deserialized cookies.
52491
+ * @param store - The underlying store to persist the deserialized cookies into.
52492
+ */
52493
+ static fromJSON(jsonString, store) {
52494
+ return _CookieJar.deserializeSync(jsonString, store);
52495
+ }
52496
+ };
52497
+ }
52498
+ });
52499
+
49523
52500
  // src/site-analyze/crawl-look.ts
49524
52501
  function patternOf(hay) {
49525
52502
  const h = hay.toLowerCase();
@@ -49578,20 +52555,57 @@ function copyFromEval(evaled) {
49578
52555
  ...Object.keys(meta).length ? { meta } : {}
49579
52556
  };
49580
52557
  }
49581
- async function createPlaywrightBrowser() {
52558
+ function forwardedRequestHeaders(all) {
52559
+ const out = {};
52560
+ for (const name of FORWARDED_REQUEST_HEADERS) {
52561
+ const value = all[name];
52562
+ if (value !== void 0) out[name] = value;
52563
+ }
52564
+ return out;
52565
+ }
52566
+ async function toPlaywrightCookies(setCookies, url) {
52567
+ const jar = new CookieJar();
52568
+ const out = [];
52569
+ for (const raw of setCookies) {
52570
+ let cookie;
52571
+ try {
52572
+ cookie = await jar.setCookie(raw, url.toString());
52573
+ } catch {
52574
+ continue;
52575
+ }
52576
+ if (!cookie || !cookie.path) continue;
52577
+ const expiresMs = cookie.expiryTime();
52578
+ const expiresSeconds = expiresMs === -Infinity ? 0 : Number.isFinite(expiresMs) ? expiresMs / 1e3 : void 0;
52579
+ const sameSite = cookie.sameSite === "strict" || cookie.sameSite === "lax" || cookie.sameSite === "none" ? cookie.sameSite[0].toUpperCase() + cookie.sameSite.slice(1) : void 0;
52580
+ out.push({
52581
+ name: cookie.key,
52582
+ value: cookie.value,
52583
+ domain: cookie.hostOnly ? url.hostname : `.${cookie.domain}`,
52584
+ path: cookie.path,
52585
+ ...expiresSeconds !== void 0 ? { expires: expiresSeconds } : {},
52586
+ ...cookie.httpOnly ? { httpOnly: true } : {},
52587
+ ...cookie.secure ? { secure: true } : {},
52588
+ ...sameSite ? { sameSite } : {}
52589
+ });
52590
+ }
52591
+ return out;
52592
+ }
52593
+ async function createPlaywrightBrowser(load = () => import("playwright"), siteFetch = guardedSiteFetch) {
49582
52594
  const screenshots = [];
49583
52595
  let pw;
49584
52596
  try {
49585
- pw = await import("playwright");
52597
+ pw = await load();
49586
52598
  } catch {
49587
52599
  return {
49588
52600
  port: { crawl: async () => ({ unavailable: `playwright_not_installed: ${PLAYWRIGHT_HINT}`, pages: [], navLabels: [], theme: null }) },
49589
52601
  screenshots,
49590
- unavailable: `playwright_not_installed: ${PLAYWRIGHT_HINT}`
52602
+ unavailable: `playwright_not_installed: ${PLAYWRIGHT_HINT}`,
52603
+ siteFetch
49591
52604
  };
49592
52605
  }
49593
52606
  const port = {
49594
52607
  async crawl({ siteUrl, budget = 12 }) {
52608
+ assertPublicSiteUrl(siteUrl);
49595
52609
  let browser;
49596
52610
  try {
49597
52611
  browser = await pw.chromium.launch({ headless: true });
@@ -49600,6 +52614,52 @@ async function createPlaywrightBrowser() {
49600
52614
  }
49601
52615
  try {
49602
52616
  const page = await browser.newPage();
52617
+ await page.route("**/*", async (route) => {
52618
+ const request = route.request();
52619
+ if (request.resourceType() !== "document") {
52620
+ await route.continue();
52621
+ return;
52622
+ }
52623
+ try {
52624
+ const headers2 = forwardedRequestHeaders(await request.allHeaders());
52625
+ const res = await siteFetch(request.url(), {
52626
+ redirect: "manual",
52627
+ headers: headers2,
52628
+ signal: AbortSignal.timeout(DOCUMENT_FETCH_TIMEOUT_MS)
52629
+ });
52630
+ const target = new URL(request.url());
52631
+ const location = res.headers.get("location");
52632
+ if (REDIRECT_STATUS.has(res.status) && location) {
52633
+ await discardBody(res);
52634
+ const setCookies2 = res.headers.getSetCookie();
52635
+ if (setCookies2.length) {
52636
+ const cookies = await toPlaywrightCookies(setCookies2, target);
52637
+ if (cookies.length) await page.context().addCookies(cookies);
52638
+ }
52639
+ await route.fulfill({ status: res.status, headers: { location }, body: Buffer.alloc(0) });
52640
+ return;
52641
+ }
52642
+ const capped = await readCapped(res, MAX_DOCUMENT_BYTES);
52643
+ if (!capped) {
52644
+ await route.abort();
52645
+ return;
52646
+ }
52647
+ const setCookies = res.headers.getSetCookie();
52648
+ if (setCookies.length) {
52649
+ const cookies = await toPlaywrightCookies(setCookies, target);
52650
+ if (cookies.length) await page.context().addCookies(cookies);
52651
+ }
52652
+ const headersOut = {};
52653
+ res.headers.forEach((value, key2) => {
52654
+ const k = key2.toLowerCase();
52655
+ if (k === "content-encoding" || k === "content-length" || k === "transfer-encoding" || k === "set-cookie") return;
52656
+ headersOut[key2] = value;
52657
+ });
52658
+ await route.fulfill({ status: res.status, headers: headersOut, body: capped });
52659
+ } catch {
52660
+ await route.abort();
52661
+ }
52662
+ });
49603
52663
  const fontFaceUrls = [];
49604
52664
  page.on("response", (response) => {
49605
52665
  try {
@@ -49728,16 +52788,19 @@ async function createPlaywrightBrowser() {
49728
52788
  }
49729
52789
  }
49730
52790
  };
49731
- return { port, screenshots };
52791
+ return { port, screenshots, siteFetch };
49732
52792
  }
49733
- var PLAYWRIGHT_HINT, PAGE_EVAL, CAP2;
52793
+ var PLAYWRIGHT_HINT, PAGE_EVAL, CAP2, DOCUMENT_FETCH_TIMEOUT_MS, MAX_DOCUMENT_BYTES, FORWARDED_REQUEST_HEADERS;
49734
52794
  var init_crawl_look = __esm({
49735
52795
  "src/site-analyze/crawl-look.ts"() {
52796
+ init_dist();
49736
52797
  init_copy_clean();
49737
52798
  init_traits();
49738
52799
  init_velo();
49739
52800
  init_published_html();
49740
52801
  init_rest();
52802
+ init_net_guard();
52803
+ init_write_artifacts();
49741
52804
  PLAYWRIGHT_HINT = "npx playwright install chromium";
49742
52805
  PAGE_EVAL = `(() => {
49743
52806
  const wst = {};
@@ -49936,6 +52999,9 @@ var init_crawl_look = __esm({
49936
52999
  meta: 300,
49937
53000
  sections: 40
49938
53001
  };
53002
+ DOCUMENT_FETCH_TIMEOUT_MS = 12e3;
53003
+ MAX_DOCUMENT_BYTES = 15e6;
53004
+ FORWARDED_REQUEST_HEADERS = ["user-agent", "accept-language", "accept", "cookie", "referer"];
49939
53005
  }
49940
53006
  });
49941
53007
 
@@ -50561,15 +53627,20 @@ var init_site_function = __esm({
50561
53627
  var cli_exports = {};
50562
53628
  __export(cli_exports, {
50563
53629
  SITE_FUNCTION_USAGE: () => SITE_FUNCTION_USAGE,
53630
+ assetFetchFor: () => assetFetchFor,
50564
53631
  noteWithWarnings: () => noteWithWarnings,
50565
53632
  runSiteAnalyze: () => runSiteAnalyze,
50566
53633
  runSiteFunctionCli: () => runSiteFunctionCli
50567
53634
  });
50568
53635
  import { readFileSync as readFileSync63 } from "node:fs";
50569
53636
  import { resolve as resolve41 } from "node:path";
53637
+ function assetFetchFor(_opts) {
53638
+ return pinnedFetch2;
53639
+ }
50570
53640
  async function runSiteAnalyze(opts) {
50571
53641
  const fetchImpl = opts.fetchImpl ?? fetch;
50572
- const assetFetch = opts.fetchImpl ?? pinnedFetch2;
53642
+ const assetFetch = assetFetchFor(opts);
53643
+ const siteFetch = guardedSiteFetch;
50573
53644
  const cwd = opts.cwd ?? process.cwd();
50574
53645
  const outDir = resolve41(cwd, opts.outDir ?? ".himi/business-book");
50575
53646
  let ownerAuth;
@@ -50584,6 +53655,7 @@ async function runSiteAnalyze(opts) {
50584
53655
  const pw = await createPlaywrightBrowser();
50585
53656
  const ports = {
50586
53657
  fetch: fetchImpl,
53658
+ siteFetch,
50587
53659
  ownerAuth,
50588
53660
  browser: pw.unavailable ? void 0 : pw.port,
50589
53661
  lookUnavailableReason: pw.unavailable
@@ -52349,8 +55421,8 @@ var DEFAULT_MAX_RUNS = 20;
52349
55421
  var ATTESTATION_VERSION = 2;
52350
55422
  function attestationVersionOf(value) {
52351
55423
  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;
55424
+ const version2 = value.attestation;
55425
+ return typeof version2 === "number" && Number.isInteger(version2) && version2 > 0 ? version2 : null;
52354
55426
  }
52355
55427
  function classifyRetainedRun(dir, name) {
52356
55428
  let value;
@@ -52360,9 +55432,9 @@ function classifyRetainedRun(dir, name) {
52360
55432
  return { kind: "unreadable" };
52361
55433
  }
52362
55434
  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" };
55435
+ const version2 = attestationVersionOf(value);
55436
+ if (version2 === null || version2 === ATTESTATION_VERSION) return { kind: "malformed" };
55437
+ return { kind: version2 < ATTESTATION_VERSION ? "legacy" : "future" };
52366
55438
  }
52367
55439
  function screenshotArtifactPath(contentDir2, hash) {
52368
55440
  return join6(resolve6(contentDir2), ".himi", "attestations", "artifacts", `${hash}.png`);
@@ -52862,12 +55934,12 @@ function penalty(m, size) {
52862
55934
  }
52863
55935
  function encodeQr(text2) {
52864
55936
  const bytes2 = [...new TextEncoder().encode(text2)];
52865
- const version = fitVersion(bytes2.length);
52866
- if (!version) {
55937
+ const version2 = fitVersion(bytes2.length);
55938
+ if (!version2) {
52867
55939
  throw new RangeError(`QR payload too long: ${bytes2.length} bytes exceeds version ${QR_MAX_VERSION} at EC level L`);
52868
55940
  }
52869
- const codewords = interleave(encodeData(bytes2, version), version);
52870
- const size = version * 4 + 17;
55941
+ const codewords = interleave(encodeData(bytes2, version2), version2);
55942
+ const size = version2 * 4 + 17;
52871
55943
  const modules = Array.from({ length: size }, () => new Array(size).fill(false));
52872
55944
  const reserved = Array.from({ length: size }, () => new Array(size).fill(false));
52873
55945
  const set = (x, y, dark) => {
@@ -52890,8 +55962,8 @@ function encodeQr(text2) {
52890
55962
  set(i, 6, i % 2 === 0);
52891
55963
  set(6, i, i % 2 === 0);
52892
55964
  }
52893
- for (const ay of alignmentPositions(version))
52894
- for (const ax of alignmentPositions(version)) {
55965
+ for (const ay of alignmentPositions(version2))
55966
+ for (const ax of alignmentPositions(version2)) {
52895
55967
  if (ax === 6 && ay === 6 || ax === 6 && ay === size - 7 || ax === size - 7 && ay === 6) continue;
52896
55968
  for (let dy = -2; dy <= 2; dy++)
52897
55969
  for (let dx = -2; dx <= 2; dx++) set(ax + dx, ay + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);
@@ -52905,7 +55977,7 @@ function encodeQr(text2) {
52905
55977
  reserved[8][size - 1 - i] = true;
52906
55978
  }
52907
55979
  set(8, size - 8, true);
52908
- if (version >= 7)
55980
+ if (version2 >= 7)
52909
55981
  for (let i = 0; i < 18; i++) {
52910
55982
  const a = size - 11 + i % 3, b = Math.floor(i / 3);
52911
55983
  reserved[a][b] = true;
@@ -52932,7 +56004,7 @@ function encodeQr(text2) {
52932
56004
  for (let y = 0; y < size; y++)
52933
56005
  for (let x = 0; x < size; x++) if (!reserved[y][x] && MASKS[mask](x, y)) cand[y][x] = !cand[y][x];
52934
56006
  applyFormat(cand, size, mask);
52935
- if (version >= 7) applyVersion(cand, size, version);
56007
+ if (version2 >= 7) applyVersion(cand, size, version2);
52936
56008
  const s = penalty(cand, size);
52937
56009
  if (s < bestScore) {
52938
56010
  bestScore = s;
@@ -52940,7 +56012,7 @@ function encodeQr(text2) {
52940
56012
  bestMask = mask;
52941
56013
  }
52942
56014
  }
52943
- return { size, version, mask: bestMask, modules: best };
56015
+ return { size, version: version2, mask: bestMask, modules: best };
52944
56016
  }
52945
56017
  function applyFormat(m, size, mask) {
52946
56018
  const bits = bchFormat(1 << 3 | mask);
@@ -52957,8 +56029,8 @@ function applyFormat(m, size, mask) {
52957
56029
  for (let i = 8; i < 15; i++) put(8, size - 15 + i, on3(i));
52958
56030
  put(8, size - 8, true);
52959
56031
  }
52960
- function applyVersion(m, size, version) {
52961
- const bits = bchVersion(version);
56032
+ function applyVersion(m, size, version2) {
56033
+ const bits = bchVersion(version2);
52962
56034
  for (let i = 0; i < 18; i++) {
52963
56035
  const on3 = (bits >>> i & 1) === 1;
52964
56036
  const a = size - 11 + i % 3, b = Math.floor(i / 3);
@@ -55747,7 +58819,7 @@ async function fetchPackumentFrom(registry, fetchImpl, timeoutMs) {
55747
58819
  const json5 = await response.json();
55748
58820
  const latest = typeof json5?.["dist-tags"]?.latest === "string" ? json5["dist-tags"].latest : void 0;
55749
58821
  const time = {};
55750
- for (const [version, when] of Object.entries(json5?.time ?? {})) if (typeof when === "string") time[version] = when;
58822
+ for (const [version2, when] of Object.entries(json5?.time ?? {})) if (typeof when === "string") time[version2] = when;
55751
58823
  return latest ? { latest, time, registry: normalizeRegistry(registry) ?? registry } : void 0;
55752
58824
  } catch {
55753
58825
  return void 0;
@@ -55770,8 +58842,8 @@ function ageInDays(publishedAt, now = Date.now()) {
55770
58842
  }
55771
58843
  function packageVersion(path) {
55772
58844
  try {
55773
- const version = JSON.parse(readFileSync65(path, "utf8")).version;
55774
- return typeof version === "string" && version ? version : void 0;
58845
+ const version2 = JSON.parse(readFileSync65(path, "utf8")).version;
58846
+ return typeof version2 === "string" && version2 ? version2 : void 0;
55775
58847
  } catch {
55776
58848
  return void 0;
55777
58849
  }
@@ -55779,8 +58851,8 @@ function packageVersion(path) {
55779
58851
  function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
55780
58852
  let dir = resolve42(fromDir);
55781
58853
  for (; ; ) {
55782
- const version = packageVersion(join51(dir, "node_modules", "@wix", "himalaya", "package.json"));
55783
- if (version) return { version, source: "local" };
58854
+ const version2 = packageVersion(join51(dir, "node_modules", "@wix", "himalaya", "package.json"));
58855
+ if (version2) return { version: version2, source: "local" };
55784
58856
  const parent = dirname30(dir);
55785
58857
  if (parent === dir) break;
55786
58858
  dir = parent;
@@ -55789,8 +58861,8 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
55789
58861
  if (bundled) return { version: bundled, source: "bundled" };
55790
58862
  try {
55791
58863
  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" } : {};
58864
+ const version2 = root ? packageVersion(join51(root, "@wix", "himalaya", "package.json")) : void 0;
58865
+ return version2 ? { version: version2, source: "global" } : {};
55794
58866
  } catch {
55795
58867
  return {};
55796
58868
  }
@@ -55881,17 +58953,17 @@ function globalPrefixWritable() {
55881
58953
  return false;
55882
58954
  }
55883
58955
  }
55884
- function npmInstallArgs(registry, version) {
58956
+ function npmInstallArgs(registry, version2) {
55885
58957
  const pinned = `${normalizeRegistry(registry) ?? registry}/`;
55886
- return ["i", "-g", `${CLI_PACKAGE}@${version}`, `--registry=${pinned}`, `--@wix:registry=${pinned}`];
58958
+ return ["i", "-g", `${CLI_PACKAGE}@${version2}`, `--registry=${pinned}`, `--@wix:registry=${pinned}`];
55887
58959
  }
55888
58960
  var INSTALLABLE_SPEC = /^(?:latest|\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/;
55889
58961
  function createUpdateRunner(spawn5 = spawnSync5) {
55890
58962
  return {
55891
- install: async (registry, version) => {
58963
+ install: async (registry, version2) => {
55892
58964
  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), {
58965
+ if (!INSTALLABLE_SPEC.test(version2)) return { ok: false, detail: `refusing install spec ${JSON.stringify(version2)}` };
58966
+ const result = spawn5("npm", npmInstallArgs(registry, version2), {
55895
58967
  // npm's stdout goes to OUR stderr: in `himi <cmd> --json | jq` (and `himi upgrade --json`) its
55896
58968
  // "added 212 packages" would otherwise land in stdout ahead of the envelope and break the
55897
58969
  // parse — the agent case this whole feature exists for (#2985 review). And no stdin: an
@@ -56559,7 +59631,7 @@ function loginModeMark(m) {
56559
59631
  return /NOT checked/.test(m.detail) ? "unchecked" : "yes";
56560
59632
  }
56561
59633
  function buildDoctorReport(input) {
56562
- const { target, version, data, serve, auth, loginModes, dpxStatus, versions } = input;
59634
+ const { target, version: version2, data, serve, auth, loginModes, dpxStatus, versions } = input;
56563
59635
  const serveCode = serve.reachable ? void 0 : target === "local" ? "no_local_serve" : "needs_vpn";
56564
59636
  const sdkSkew = versions?.sdk.status === "outdated" && versions?.sdk.source !== "bundled";
56565
59637
  const versionSkew = versions?.cli.status === "outdated" || sdkSkew;
@@ -56568,7 +59640,7 @@ function buildDoctorReport(input) {
56568
59640
  return {
56569
59641
  ok,
56570
59642
  target,
56571
- version,
59643
+ version: version2,
56572
59644
  dataPlane: { ...data, note: "public Wix APIs \u2014 reachable off-VPN" },
56573
59645
  servePlane: {
56574
59646
  ...serve,
@@ -60806,9 +63878,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
60806
63878
  input.close();
60807
63879
  }
60808
63880
  },
60809
- releasePlayerJob: async (release, version) => {
63881
+ releasePlayerJob: async (release, version2) => {
60810
63882
  const c = new ServeCliClient(resolveTarget({ target: playerTarget }));
60811
- const created = await c.distCreate({ app: "himi-player", platform: "ios", shell: "player", release, destination: "testflight", version });
63883
+ const created = await c.distCreate({ app: "himi-player", platform: "ios", shell: "player", release, destination: "testflight", version: version2 });
60812
63884
  if (!created.ok) throw new Error(`Job Service refused the Player TestFlight build (HTTP ${created.status})`);
60813
63885
  const jobs = created.json?.jobs ?? [];
60814
63886
  const jobId = jobs.find((candidate) => candidate.platform === "ios")?.jobId;
@@ -61619,9 +64691,9 @@ ${label2}`);
61619
64691
  else io.log(`himi ${before} (unchanged \u2014 ${registry} has nothing newer; its latest is ${answered.latest})`);
61620
64692
  return 0;
61621
64693
  }
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);
64694
+ const version2 = answered?.latest ?? "latest";
64695
+ io.error(`upgrading ${CLI_PACKAGE} (running v${before}) to ${version2} from ${registry}\u2026`);
64696
+ const installed = await runner2.install(registry, version2);
61625
64697
  if (!installed.ok) {
61626
64698
  const detail = installed.detail ?? "unknown error";
61627
64699
  if (flags.json) print({ ok: false, error: "upgrade_failed", running: before, registry, detail });
@@ -62183,3 +65255,37 @@ export {
62183
65255
  writePngFile,
62184
65256
  writeUpdateCache
62185
65257
  };
65258
+ /*! Bundled license information:
65259
+
65260
+ tough-cookie/dist/index.js:
65261
+ (*!
65262
+ * Copyright (c) 2015-2020, Salesforce.com, Inc.
65263
+ * All rights reserved.
65264
+ *
65265
+ * Redistribution and use in source and binary forms, with or without
65266
+ * modification, are permitted provided that the following conditions are met:
65267
+ *
65268
+ * 1. Redistributions of source code must retain the above copyright notice,
65269
+ * this list of conditions and the following disclaimer.
65270
+ *
65271
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
65272
+ * this list of conditions and the following disclaimer in the documentation
65273
+ * and/or other materials provided with the distribution.
65274
+ *
65275
+ * 3. Neither the name of Salesforce.com nor the names of its contributors may
65276
+ * be used to endorse or promote products derived from this software without
65277
+ * specific prior written permission.
65278
+ *
65279
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
65280
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65281
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65282
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
65283
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65284
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
65285
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65286
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
65287
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65288
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
65289
+ * POSSIBILITY OF SUCH DAMAGE.
65290
+ *)
65291
+ */