openship 0.6.9 → 0.7.1

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 (62) hide show
  1. package/dist/bare-AB4SMTNJ.js +29 -0
  2. package/dist/{chunk-P7RCYELG.js → chunk-2BAKEGGF.js} +1 -1
  3. package/dist/{chunk-VAI5VOOI.js → chunk-2YAY5XHK.js} +1 -1
  4. package/dist/{chunk-X53JXRS4.js → chunk-37XZTLBJ.js} +3 -3
  5. package/dist/{chunk-R5DC5PEF.js → chunk-3K65MMYV.js} +39 -10
  6. package/dist/{chunk-D3OEMXYP.js → chunk-3WBKLDGC.js} +12 -7
  7. package/dist/{chunk-ENKJ7XIF.js → chunk-3YSSXSC2.js} +12 -12
  8. package/dist/{chunk-3MP6ACKM.js → chunk-7MCPDYKP.js} +799 -165
  9. package/dist/{chunk-D6HU4VUZ.js → chunk-7TQP6723.js} +2 -2
  10. package/dist/{chunk-SK4FFCFR.js → chunk-AMADTKC6.js} +1 -1
  11. package/dist/{chunk-NPSRGIHV.js → chunk-B2BQX6JX.js} +6 -5
  12. package/dist/{chunk-MUWVC5R4.js → chunk-BBPKAQ54.js} +12 -9
  13. package/dist/{chunk-WEZFTL4V.js → chunk-COI4VFRW.js} +217 -2
  14. package/dist/{chunk-5DJOB7IX.js → chunk-CQ2JOXEQ.js} +3 -3
  15. package/dist/{chunk-7PEXM2UI.js → chunk-DQR5TPFB.js} +6 -6
  16. package/dist/{chunk-IAMOUDHY.js → chunk-ETK6IBCH.js} +24 -15
  17. package/dist/{chunk-T46BQOLY.js → chunk-FNWNUYS3.js} +3 -3
  18. package/dist/{chunk-UAWY6X7V.js → chunk-GPTBEPUE.js} +485 -67
  19. package/dist/{chunk-634DDFT5.js → chunk-H36ASAYI.js} +8 -8
  20. package/dist/{chunk-AHJYP7DG.js → chunk-IVMPA6RC.js} +74 -17
  21. package/dist/{chunk-5UXHT6ED.js → chunk-IXBOV7BE.js} +113 -20
  22. package/dist/{chunk-GNOMEMNI.js → chunk-KATXZ5AB.js} +1 -1
  23. package/dist/{chunk-T6DVUX4F.js → chunk-KCMEWNP7.js} +14 -3
  24. package/dist/{chunk-N5YZMO33.js → chunk-L4DRH6ZA.js} +12 -1
  25. package/dist/{chunk-BO6CY4V2.js → chunk-NF7NQOAP.js} +47 -4
  26. package/dist/{chunk-FCGJN5Q5.js → chunk-NIOLZENU.js} +9 -9
  27. package/dist/{chunk-7YBWXEM6.js → chunk-OEYXXSAM.js} +4 -4
  28. package/dist/{chunk-6GU6JSK6.js → chunk-S5GU345P.js} +3 -3
  29. package/dist/{chunk-TAZZZKYO.js → chunk-TKK5NPDQ.js} +2 -2
  30. package/dist/{chunk-NUT6HKK6.js → chunk-WG5PDWZ3.js} +5 -5
  31. package/dist/{chunk-NIYD7MD2.js → chunk-XJSLJLNY.js} +90 -46
  32. package/dist/{cloud-REV3DPJH.js → cloud-T2JOFEQL.js} +20 -20
  33. package/dist/{detect-BBFT5GEU.js → detect-SWLZURYX.js} +5 -5
  34. package/dist/{docker-EG3QSE6I.js → docker-SQNZRZXN.js} +11 -11
  35. package/dist/{docker-edge-executor-E5TOTLMR.js → docker-edge-executor-BSSQQS76.js} +8 -8
  36. package/dist/{edge-import-YJVJUGYC.js → edge-import-LUDX77C2.js} +27 -27
  37. package/dist/{edge-preflight-QUW4BM7N.js → edge-preflight-JAEFWBRI.js} +14 -14
  38. package/dist/{ensure-container-edge-FOEFQ3PI.js → ensure-container-edge-U7FTLFVJ.js} +12 -12
  39. package/dist/{executor-NTWDJ3DB.js → executor-GYRZ7RIU.js} +7 -7
  40. package/dist/host-channel-preflight-U4IZCRXR.js +54 -0
  41. package/dist/index.js +72 -50
  42. package/dist/{local-executor-OQ2GRN7K.js → local-executor-JCR46VAP.js} +3 -3
  43. package/dist/{nginx-4U4C2XUS.js → nginx-YA6IRPJT.js} +10 -10
  44. package/dist/{openresty-lua-LLWT5XQW.js → openresty-lua-DUOB64TP.js} +8 -8
  45. package/dist/{privilege-MNDVMDST.js → privilege-4B2TMVW2.js} +6 -6
  46. package/dist/server/index.js +13286 -5381
  47. package/dist/server/lua/site_logger.lua +18 -1
  48. package/dist/server/migrations/0117_github_installation_workspace_scope.sql +24 -0
  49. package/dist/server/migrations/0118_git_sources.sql +66 -0
  50. package/dist/server/migrations/0119_backup_run_batch.sql +8 -0
  51. package/dist/server/migrations/0120_domain_primary_unique.sql +24 -0
  52. package/dist/server/migrations/0121_host_port_claim_overlap.sql +14 -0
  53. package/dist/server/migrations/0122_data_transfer_staging.sql +45 -0
  54. package/dist/server/migrations/meta/_journal.json +42 -0
  55. package/dist/setup-T3WN3HRS.js +25 -0
  56. package/dist/{ssh-client-2XWZCMGI.js → ssh-client-FZDWP5PQ.js} +3 -3
  57. package/dist/up-U73RUN5R.js +61 -0
  58. package/package.json +1 -1
  59. package/dist/bare-FA66N7GC.js +0 -29
  60. package/dist/host-channel-preflight-OI2TRHSG.js +0 -54
  61. package/dist/setup-IFIMPQZJ.js +0 -25
  62. package/dist/up-RC5ZQIAD.js +0 -61
@@ -6,11 +6,11 @@ import {
6
6
  formatDuration,
7
7
  isRemoteConnectionError,
8
8
  systemDebug
9
- } from "./chunk-N5YZMO33.js";
9
+ } from "./chunk-L4DRH6ZA.js";
10
10
  import {
11
11
  safeErrorMessage,
12
12
  shellQuote
13
- } from "./chunk-WEZFTL4V.js";
13
+ } from "./chunk-COI4VFRW.js";
14
14
 
15
15
  // ../../packages/adapters/src/system/probe-exec.ts
16
16
  async function tryExec(executor, command, opts) {
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  sq
7
- } from "./chunk-P7RCYELG.js";
7
+ } from "./chunk-2BAKEGGF.js";
8
8
 
9
9
  // ../../packages/adapters/src/runtime/managed-artifact.ts
10
10
  var MANAGED_ARTIFACT_BASE = "/opt/openship";
@@ -4,12 +4,12 @@ import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  sq
7
- } from "./chunk-P7RCYELG.js";
7
+ } from "./chunk-2BAKEGGF.js";
8
8
  import {
9
9
  formatDuration,
10
10
  isRemoteConnectionError,
11
11
  systemDebug
12
- } from "./chunk-N5YZMO33.js";
12
+ } from "./chunk-L4DRH6ZA.js";
13
13
  import {
14
14
  assessHostSupport,
15
15
  classifyDistro,
@@ -17,7 +17,7 @@ import {
17
17
  parseSystemArch,
18
18
  parseSystemOs,
19
19
  safeErrorMessage
20
- } from "./chunk-WEZFTL4V.js";
20
+ } from "./chunk-COI4VFRW.js";
21
21
 
22
22
  // ../../packages/adapters/src/system/elevated-executor.ts
23
23
  import { randomBytes } from "crypto";
@@ -47,12 +47,13 @@ function elevatedExecutor(inner) {
47
47
  if (await inner.exists(path).catch(() => false)) return true;
48
48
  return await inner.exec(elevateCommand(`test -e ${sq(path)}`)).then(() => true).catch(() => false);
49
49
  };
50
- const writeFileElevated = async (path, content) => {
50
+ const writeFileElevated = async (path, content, opts) => {
51
51
  const stage = `/tmp/.openship-elev-${randomBytes(12).toString("hex")}`;
52
52
  await inner.exec(`mkdir -m 700 ${sq(stage)}`);
53
53
  try {
54
54
  const staged = `${stage}/payload`;
55
- await inner.writeFile(staged, content);
55
+ if (opts === void 0) await inner.writeFile(staged, content);
56
+ else await inner.writeFile(staged, content, opts);
56
57
  await inner.exec(
57
58
  elevateCommand(
58
59
  `mkdir -p ${sq(dirOf(path))} && chown 0:0 ${sq(staged)} && mv -f ${sq(staged)} ${sq(path)}`
@@ -5,17 +5,17 @@ const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  checkGit,
7
7
  installGit
8
- } from "./chunk-NIYD7MD2.js";
8
+ } from "./chunk-XJSLJLNY.js";
9
9
  import {
10
10
  createDockerBuildContext,
11
11
  resolveDockerBuildArgs
12
- } from "./chunk-6GU6JSK6.js";
12
+ } from "./chunk-S5GU345P.js";
13
13
  import {
14
14
  prepareStackOutput,
15
15
  resolveProjectDir,
16
16
  resolveStaticOutputPath,
17
17
  runLocalBuild
18
- } from "./chunk-5DJOB7IX.js";
18
+ } from "./chunk-CQ2JOXEQ.js";
19
19
  import {
20
20
  BuildLogger,
21
21
  dockerBuildContextDirectory,
@@ -29,10 +29,10 @@ import {
29
29
  splitRuntimeEnv,
30
30
  sq,
31
31
  transferLocalDirectory
32
- } from "./chunk-AHJYP7DG.js";
32
+ } from "./chunk-IVMPA6RC.js";
33
33
  import {
34
34
  isRuntimeNotFoundError
35
- } from "./chunk-N5YZMO33.js";
35
+ } from "./chunk-L4DRH6ZA.js";
36
36
  import {
37
37
  PRICING,
38
38
  STACKS,
@@ -44,7 +44,7 @@ import {
44
44
  packageManagerEnsureCommand,
45
45
  safeErrorMessage,
46
46
  shellSplitWords
47
- } from "./chunk-WEZFTL4V.js";
47
+ } from "./chunk-COI4VFRW.js";
48
48
 
49
49
  // ../../packages/adapters/src/runtime/cloud.ts
50
50
  import { readFile } from "fs/promises";
@@ -801,6 +801,11 @@ var CloudComposeSupport = class {
801
801
  this.groups.set(group.id, groupState);
802
802
  const builtArtifact = this.deps.builtArtifacts.get(config.image);
803
803
  let workspaceId;
804
+ if (config.forcePull && config.previousWorkspaceId && !builtArtifact) {
805
+ throw new Error(
806
+ `Cannot refresh image "${config.image}" for cloud service "${config.serviceName}" without replacing its persistent workspace. Use a self-hosted Docker target for forced image refreshes.`
807
+ );
808
+ }
804
809
  try {
805
810
  workspaceId = builtArtifact?.workspaceId ?? await this.createImageServiceWorkspace(config, log);
806
811
  const ws = this.deps.workspace(workspaceId);
@@ -1178,9 +1183,7 @@ rm -f "$tmp"`;
1178
1183
  if (!group) return;
1179
1184
  for (const service of group.services.values()) {
1180
1185
  if (service.ip) continue;
1181
- const ip = await this.resolveWorkspaceIpWithRetry(
1182
- this.deps.workspace(service.workspaceId)
1183
- );
1186
+ const ip = await this.resolveWorkspaceIpWithRetry(this.deps.workspace(service.workspaceId));
1184
1187
  if (ip) {
1185
1188
  service.ip = ip;
1186
1189
  } else {
@@ -1418,6 +1418,26 @@ function parseEnv(ctx, v, path) {
1418
1418
  }
1419
1419
  return out;
1420
1420
  }
1421
+ function parseBuildArgs(ctx, v, path) {
1422
+ if (v === void 0) return void 0;
1423
+ if (!ctx.isObj(v)) {
1424
+ ctx.err(path, "must be an object of string or null build arguments");
1425
+ return void 0;
1426
+ }
1427
+ const out = {};
1428
+ for (const [key, value] of Object.entries(v)) {
1429
+ if (!isValidEnvKey(key)) {
1430
+ ctx.err(`${path}.${key}`, "has an invalid build argument name");
1431
+ continue;
1432
+ }
1433
+ if (value === null || typeof value === "string") {
1434
+ out[key] = value;
1435
+ } else {
1436
+ ctx.err(`${path}.${key}`, "must be a string or null");
1437
+ }
1438
+ }
1439
+ return out;
1440
+ }
1421
1441
  function parseDomains(ctx, v, path) {
1422
1442
  if (v === void 0) return void 0;
1423
1443
  if (!Array.isArray(v)) {
@@ -1488,7 +1508,10 @@ function parseRoutes(ctx, v, path) {
1488
1508
  const source = ctx.str(h.source, `${p}.source`);
1489
1509
  const list = Array.isArray(h.headers) ? h.headers.map((kv, j) => {
1490
1510
  const key = ctx.str(kv?.key, `${p}.headers[${j}].key`);
1491
- const value = ctx.str(kv?.value, `${p}.headers[${j}].value`);
1511
+ const value = ctx.str(
1512
+ kv?.value,
1513
+ `${p}.headers[${j}].value`
1514
+ );
1492
1515
  return key && value !== void 0 ? { key, value } : null;
1493
1516
  }).filter(Boolean) : [];
1494
1517
  return source ? { source, headers: list } : null;
@@ -1569,6 +1592,7 @@ function parseServices(ctx, v, path) {
1569
1592
  image: ctx.str(item.image, `${p}.image`),
1570
1593
  build: ctx.str(item.build, `${p}.build`),
1571
1594
  dockerfile: ctx.str(item.dockerfile, `${p}.dockerfile`),
1595
+ buildArgs: parseBuildArgs(ctx, item.buildArgs, `${p}.buildArgs`),
1572
1596
  ports: ctx.strArray(item.ports, `${p}.ports`),
1573
1597
  volumes: ctx.strArray(item.volumes, `${p}.volumes`),
1574
1598
  dependsOn: ctx.strArray(item.dependsOn, `${p}.dependsOn`),
@@ -4070,6 +4094,7 @@ var catalog_default = {
4070
4094
  GOTRUE_API_HOST: "0.0.0.0",
4071
4095
  GOTRUE_API_PORT: "9999",
4072
4096
  API_EXTERNAL_URL: "{{publicUrl:kong}}",
4097
+ GOTRUE_SAML_EXTERNAL_URL: "{{publicUrl:kong}}/auth/v1",
4073
4098
  GOTRUE_DB_DRIVER: "postgres",
4074
4099
  GOTRUE_DB_DATABASE_URL: "postgres://supabase_auth_admin:{{config:POSTGRES_PASSWORD}}@db:5432/postgres",
4075
4100
  GOTRUE_SITE_URL: "{{publicUrl:kong}}",
@@ -4326,7 +4351,7 @@ var catalog_default = {
4326
4351
  {
4327
4352
  service: "kong",
4328
4353
  path: "/usr/local/kong/kong.yml",
4329
- content: '_format_version: "3.0"\n_transform: true\n\nconsumers:\n - username: DASHBOARD\n - username: anon\n keyauth_credentials:\n - key: {{config:ANON_KEY}}\n - username: service_role\n keyauth_credentials:\n - key: {{config:SERVICE_ROLE_KEY}}\n\nacls:\n - consumer: anon\n group: anon\n - consumer: service_role\n group: admin\n\nbasicauth_credentials:\n - consumer: DASHBOARD\n username: {{config:DASHBOARD_USERNAME}}\n password: {{config:DASHBOARD_PASSWORD}}\n\nservices:\n - name: auth-v1-open\n url: http://auth:9999/verify\n routes:\n - name: auth-v1-open\n strip_path: true\n paths:\n - /auth/v1/verify\n plugins:\n - name: cors\n - name: auth-v1-open-callback\n url: http://auth:9999/callback\n routes:\n - name: auth-v1-open-callback\n strip_path: true\n paths:\n - /auth/v1/callback\n plugins:\n - name: cors\n - name: auth-v1-open-authorize\n url: http://auth:9999/authorize\n routes:\n - name: auth-v1-open-authorize\n strip_path: true\n paths:\n - /auth/v1/authorize\n plugins:\n - name: cors\n - name: auth-v1\n url: http://auth:9999/\n routes:\n - name: auth-v1-all\n strip_path: true\n paths:\n - /auth/v1/\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: false\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: rest-v1\n url: http://rest:3000/\n routes:\n - name: rest-v1-all\n strip_path: true\n paths:\n - /rest/v1/\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: true\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: graphql-v1\n url: http://rest:3000/rpc/graphql\n routes:\n - name: graphql-v1-all\n strip_path: true\n paths:\n - /graphql/v1\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: true\n - name: request-transformer\n config:\n add:\n headers:\n - Content-Profile:graphql_public\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: realtime-v1-ws\n url: http://realtime-dev.supabase-realtime:4000/socket/\n routes:\n - name: realtime-v1-ws\n strip_path: true\n paths:\n - /realtime/v1/\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: false\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: storage-v1\n url: http://storage:5000/\n routes:\n - name: storage-v1-all\n strip_path: true\n paths:\n - /storage/v1/\n plugins:\n - name: cors\n - name: meta\n url: http://meta:8080/\n routes:\n - name: meta-all\n strip_path: true\n paths:\n - /pg/\n plugins:\n - name: key-auth\n config:\n hide_credentials: false\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - name: dashboard\n url: http://studio:3000/\n routes:\n - name: dashboard-all\n strip_path: true\n paths:\n - /\n plugins:\n - name: cors\n - name: basic-auth\n config:\n hide_credentials: true\n'
4354
+ content: '_format_version: "3.0"\n_transform: true\n\nconsumers:\n - username: DASHBOARD\n - username: anon\n keyauth_credentials:\n - key: {{config:ANON_KEY}}\n - username: service_role\n keyauth_credentials:\n - key: {{config:SERVICE_ROLE_KEY}}\n\nacls:\n - consumer: anon\n group: anon\n - consumer: service_role\n group: admin\n\nbasicauth_credentials:\n - consumer: DASHBOARD\n username: {{config:DASHBOARD_USERNAME}}\n password: {{config:DASHBOARD_PASSWORD}}\n\nservices:\n - name: auth-v1-open\n url: http://auth:9999/verify\n routes:\n - name: auth-v1-open\n strip_path: true\n paths:\n - /auth/v1/verify\n plugins:\n - name: cors\n - name: auth-v1-open-callback\n url: http://auth:9999/callback\n routes:\n - name: auth-v1-open-callback\n strip_path: true\n paths:\n - /auth/v1/callback\n plugins:\n - name: cors\n - name: auth-v1-open-authorize\n url: http://auth:9999/authorize\n routes:\n - name: auth-v1-open-authorize\n strip_path: true\n paths:\n - /auth/v1/authorize\n plugins:\n - name: cors\n - name: auth-v1-open-sso-acs\n url: http://auth:9999/sso/saml/acs\n routes:\n - name: auth-v1-open-sso-acs\n strip_path: true\n paths:\n - /auth/v1/sso/saml/acs\n plugins:\n - name: cors\n - name: auth-v1-open-sso-metadata\n url: http://auth:9999/sso/saml/metadata\n routes:\n - name: auth-v1-open-sso-metadata\n strip_path: true\n paths:\n - /auth/v1/sso/saml/metadata\n plugins:\n - name: cors\n - name: auth-v1\n url: http://auth:9999/\n routes:\n - name: auth-v1-all\n strip_path: true\n paths:\n - /auth/v1/\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: false\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: rest-v1\n url: http://rest:3000/\n routes:\n - name: rest-v1-all\n strip_path: true\n paths:\n - /rest/v1/\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: true\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: graphql-v1\n url: http://rest:3000/rpc/graphql\n routes:\n - name: graphql-v1-all\n strip_path: true\n paths:\n - /graphql/v1\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: true\n - name: request-transformer\n config:\n add:\n headers:\n - Content-Profile:graphql_public\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: realtime-v1-ws\n url: http://realtime-dev.supabase-realtime:4000/socket/\n routes:\n - name: realtime-v1-ws\n strip_path: true\n paths:\n - /realtime/v1/\n plugins:\n - name: cors\n - name: key-auth\n config:\n hide_credentials: false\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - anon\n - name: storage-v1\n url: http://storage:5000/\n routes:\n - name: storage-v1-all\n strip_path: true\n paths:\n - /storage/v1/\n plugins:\n - name: cors\n - name: meta\n url: http://meta:8080/\n routes:\n - name: meta-all\n strip_path: true\n paths:\n - /pg/\n plugins:\n - name: key-auth\n config:\n hide_credentials: false\n - name: acl\n config:\n hide_groups_header: true\n allow:\n - admin\n - name: dashboard\n url: http://studio:3000/\n routes:\n - name: dashboard-all\n strip_path: true\n paths:\n - /\n plugins:\n - name: cors\n - name: basic-auth\n config:\n hide_credentials: true\n'
4330
4355
  },
4331
4356
  {
4332
4357
  service: "db",
@@ -8621,6 +8646,156 @@ Two things worth knowing, both upstream behaviour: if the console shows a branch
8621
8646
  defaultMode: "domain"
8622
8647
  }
8623
8648
  ]
8649
+ },
8650
+ {
8651
+ $schema: "https://openship.io/app.schema.json",
8652
+ available: true,
8653
+ minEngine: "0.6.6",
8654
+ id: "pocketbase",
8655
+ name: "PocketBase",
8656
+ description: "Self-hosted PocketBase with auth, a realtime SQLite database, file storage, and an admin dashboard in one small service.",
8657
+ repository: "https://github.com/pocketbase/pocketbase",
8658
+ kind: "template",
8659
+ logo: "pocketbase",
8660
+ category: "backend",
8661
+ tags: [
8662
+ "auth",
8663
+ "database",
8664
+ "sqlite",
8665
+ "realtime"
8666
+ ],
8667
+ framework: "docker-compose",
8668
+ services: [
8669
+ {
8670
+ name: "pocketbase",
8671
+ build: {
8672
+ dockerfile: 'FROM alpine:3.24.1 AS downloader\nARG PB_VERSION=0.40.1\nRUN apk add --no-cache ca-certificates unzip wget \\\n && ARCH=$(uname -m) \\\n && case "$ARCH" in x86_64) ARCH=amd64 ;; aarch64) ARCH=arm64 ;; *) echo "Unsupported architecture: $ARCH" >&2; exit 1 ;; esac \\\n && wget -q https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/checksums.txt -O /tmp/checksums.txt \\\n && wget -q https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_${ARCH}.zip -O /tmp/pocketbase_${PB_VERSION}_linux_${ARCH}.zip \\\n && cd /tmp \\\n && grep " pocketbase_${PB_VERSION}_linux_${ARCH}.zip$" checksums.txt | sha256sum -c - \\\n && unzip pocketbase_${PB_VERSION}_linux_${ARCH}.zip -d /pb\nFROM alpine:3.24.1\nRUN apk add --no-cache ca-certificates su-exec \\\n && addgroup -S pocketbase \\\n && adduser -S -G pocketbase -h /pb pocketbase\nCOPY --chown=pocketbase:pocketbase --from=downloader /pb/pocketbase /pb/pocketbase\nCOPY --chown=pocketbase:pocketbase pocketbase/entrypoint.sh /pb/entrypoint.sh\nRUN chmod 755 /pb/entrypoint.sh\nWORKDIR /pb\nENTRYPOINT ["/pb/entrypoint.sh"]\nCMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8090", "--encryptionEnv=PB_ENCRYPTION_KEY"]\n',
8673
+ files: [
8674
+ {
8675
+ path: "entrypoint.sh",
8676
+ content: `#!/bin/sh
8677
+ set -eu
8678
+ mkdir -p /pb/pb_data
8679
+ chown pocketbase:pocketbase /pb/pb_data
8680
+ export PB_ENCRYPTION_KEY="$(printf '%.32s' "$PB_ENCRYPTION_SEED")"
8681
+ if [ ! -e /pb/pb_data/.openship-superuser ]; then
8682
+ su-exec pocketbase /pb/pocketbase superuser upsert "$POCKETBASE_SUPERUSER_EMAIL" "$POCKETBASE_SUPERUSER_PASSWORD" --dir=/pb/pb_data --encryptionEnv=PB_ENCRYPTION_KEY >/dev/null
8683
+ su-exec pocketbase touch /pb/pb_data/.openship-superuser
8684
+ fi
8685
+ exec su-exec pocketbase "$@"
8686
+ `
8687
+ }
8688
+ ]
8689
+ },
8690
+ environment: {
8691
+ GOMEMLIMIT: "512MiB"
8692
+ },
8693
+ secretEnv: [
8694
+ "PB_ENCRYPTION_SEED",
8695
+ "POCKETBASE_SUPERUSER_PASSWORD"
8696
+ ],
8697
+ ports: [
8698
+ "8090:8090"
8699
+ ],
8700
+ exposedPort: 8090,
8701
+ exposed: true,
8702
+ volumes: [
8703
+ "pocketbase_data:/pb/pb_data"
8704
+ ],
8705
+ healthcheck: {
8706
+ test: [
8707
+ "CMD",
8708
+ "wget",
8709
+ "-qO-",
8710
+ "http://127.0.0.1:8090/api/health"
8711
+ ],
8712
+ interval: "5s",
8713
+ timeout: "3s",
8714
+ retries: 20,
8715
+ startPeriod: "10s"
8716
+ },
8717
+ stopGracePeriod: "30s",
8718
+ restart: "unless-stopped"
8719
+ }
8720
+ ],
8721
+ configFields: [
8722
+ {
8723
+ key: "PB_ENCRYPTION_SEED",
8724
+ service: "pocketbase",
8725
+ label: "Settings encryption seed",
8726
+ help: "Derives the stable 32-character key that encrypts PocketBase settings in the data volume.",
8727
+ generate: "secret",
8728
+ secret: true
8729
+ },
8730
+ {
8731
+ key: "POCKETBASE_SUPERUSER_PASSWORD",
8732
+ service: "pocketbase",
8733
+ label: "Initial superuser password",
8734
+ help: "Auto-generated for the first deployment and shown in the connection card.",
8735
+ generate: "secret",
8736
+ secret: true
8737
+ },
8738
+ {
8739
+ key: "POCKETBASE_SUPERUSER_EMAIL",
8740
+ service: "pocketbase",
8741
+ label: "Superuser email",
8742
+ help: "Email for the superuser created during the first deployment.",
8743
+ type: "text",
8744
+ default: "admin@openship.local",
8745
+ required: true
8746
+ }
8747
+ ],
8748
+ connection: {
8749
+ title: "Connect to PocketBase",
8750
+ description: "Use the public URL from browsers and other projects. The admin dashboard is available at /_/.",
8751
+ guide: {
8752
+ intro: "PocketBase stores auth, records, and files in one persistent SQLite-backed volume.",
8753
+ useHint: "Create scoped credentials for automation, configure off-host backups, and point each app at this URL.",
8754
+ defaultMode: "public"
8755
+ },
8756
+ outputs: [
8757
+ {
8758
+ id: "url",
8759
+ label: "PocketBase URL",
8760
+ source: "publicUrl:pocketbase",
8761
+ kind: "url",
8762
+ envKey: "POCKETBASE_URL",
8763
+ recommended: true
8764
+ },
8765
+ {
8766
+ id: "email",
8767
+ label: "Superuser email",
8768
+ source: "env:pocketbase:POCKETBASE_SUPERUSER_EMAIL",
8769
+ envKey: "POCKETBASE_SUPERUSER_EMAIL"
8770
+ },
8771
+ {
8772
+ id: "password",
8773
+ label: "Initial superuser password",
8774
+ help: "Use this installation credential until you change the password in PocketBase.",
8775
+ source: "env:pocketbase:POCKETBASE_SUPERUSER_PASSWORD",
8776
+ envKey: "POCKETBASE_SUPERUSER_PASSWORD",
8777
+ secret: true
8778
+ }
8779
+ ]
8780
+ },
8781
+ provides: [
8782
+ {
8783
+ id: "pocketbase",
8784
+ outputRefs: [
8785
+ "url"
8786
+ ],
8787
+ category: "database"
8788
+ }
8789
+ ],
8790
+ endpoints: [
8791
+ {
8792
+ service: "pocketbase",
8793
+ port: 8090,
8794
+ label: "PocketBase API and dashboard",
8795
+ kind: "http",
8796
+ defaultMode: "domain"
8797
+ }
8798
+ ]
8624
8799
  }
8625
8800
  ]
8626
8801
  };
@@ -25291,6 +25466,13 @@ var AUDIT_EVENTS = {
25291
25466
  tone: "warning",
25292
25467
  description: "Cleanup did not complete, so the app record was kept for a safe retry."
25293
25468
  },
25469
+ "project.build_cache.cleared": {
25470
+ category: "apps",
25471
+ action: "cleared the Docker build cache for",
25472
+ label: "Build cache cleared",
25473
+ tone: "warning",
25474
+ description: "Unused build cache was removed from the app's Docker host."
25475
+ },
25294
25476
  "project:write": {
25295
25477
  category: "apps",
25296
25478
  action: "changed",
@@ -25919,6 +26101,39 @@ var AUDIT_EVENTS = {
25919
26101
  label: "GitHub app installed",
25920
26102
  tone: "info"
25921
26103
  },
26104
+ "github.source.created": {
26105
+ category: "system",
26106
+ action: "registered the GitHub App source",
26107
+ label: "GitHub App source registered",
26108
+ tone: "info",
26109
+ description: "An organization-owned GitHub App was verified and stored. Secret values are never recorded."
26110
+ },
26111
+ "github.source.updated": {
26112
+ category: "system",
26113
+ action: "updated the GitHub App source",
26114
+ label: "GitHub App source updated",
26115
+ tone: "info",
26116
+ description: "A GitHub App's identity, endpoint, or encrypted credentials changed."
26117
+ },
26118
+ "github.source.verified": {
26119
+ category: "system",
26120
+ action: "verified the GitHub App source",
26121
+ label: "GitHub App source verified",
26122
+ tone: "info"
26123
+ },
26124
+ "github.source.defaulted": {
26125
+ category: "system",
26126
+ action: "made the default GitHub App source",
26127
+ label: "Default GitHub App source changed",
26128
+ tone: "info"
26129
+ },
26130
+ "github.source.deleted": {
26131
+ category: "system",
26132
+ action: "deleted the GitHub App source",
26133
+ label: "GitHub App source deleted",
26134
+ tone: "warning",
26135
+ description: "The local App credentials and installation bindings were removed; the GitHub App itself was not uninstalled on GitHub."
26136
+ },
25922
26137
  "github.disconnect": {
25923
26138
  category: "system",
25924
26139
  action: "disconnected GitHub from",
@@ -6,13 +6,13 @@ import {
6
6
  detectBuildKillHint,
7
7
  runBuildPipeline,
8
8
  transferLocalDirectory
9
- } from "./chunk-AHJYP7DG.js";
9
+ } from "./chunk-IVMPA6RC.js";
10
10
  import {
11
11
  LocalExecutor
12
- } from "./chunk-T6DVUX4F.js";
12
+ } from "./chunk-KCMEWNP7.js";
13
13
  import {
14
14
  wrapLocalBuildCommand
15
- } from "./chunk-P7RCYELG.js";
15
+ } from "./chunk-2BAKEGGF.js";
16
16
 
17
17
  // ../../packages/adapters/src/runtime/local-build.ts
18
18
  var LOCAL_BUILD_DIR = "/tmp/openship/.builds";
@@ -5,23 +5,23 @@ const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  envOps,
7
7
  opScript
8
- } from "./chunk-GNOMEMNI.js";
8
+ } from "./chunk-KATXZ5AB.js";
9
9
  import {
10
10
  resolveEnvironment
11
- } from "./chunk-NPSRGIHV.js";
11
+ } from "./chunk-B2BQX6JX.js";
12
12
  import {
13
13
  sq
14
- } from "./chunk-P7RCYELG.js";
14
+ } from "./chunk-2BAKEGGF.js";
15
15
  import {
16
16
  describeProcess,
17
17
  probeListeningPortOwners
18
- } from "./chunk-BO6CY4V2.js";
18
+ } from "./chunk-NF7NQOAP.js";
19
19
  import {
20
20
  SYSTEM,
21
21
  answered,
22
22
  refused,
23
23
  safeErrorMessage
24
- } from "./chunk-WEZFTL4V.js";
24
+ } from "./chunk-COI4VFRW.js";
25
25
 
26
26
  // ../../packages/adapters/src/infra/openresty-lua.ts
27
27
  import { createHash, randomBytes } from "crypto";
@@ -37,7 +37,7 @@ var EMBEDDED_LUA = {
37
37
  "pipe_stream.lua": "LS0gcGlwZV9zdHJlYW0ubHVhCi0tIGNvbnRlbnRfYnlfbHVhOiBTU0UgZW5kcG9pbnQgZm9yIHJlYWwtdGltZSByZXF1ZXN0IGxvZyBzdHJlYW1pbmcuCi0tIEdFVCAvbG9ncy9zdHJlYW0/ZG9tYWluPWV4YW1wbGUuY29tCi0tIEludGVybmFsIG9ubHkgLSAxMjcuMC4wLjE6OTE0NQotLQotLSBSZWFkcyB0aGUgU0FNRSByaW5nIGJ1ZmZlciBzaXRlX2xvZ2dlci5sdWEgd3JpdGVzIChybG9nOntkb21haW59OnNlcSArCi0tIHJsb2c6e2RvbWFpbn06e3Nsb3R9KSwgYnkgYSBQRVItQ09OTkVDVElPTiBjdXJzb3IuIE5vdGhpbmcgaXMgY29uc3VtZWQ6IE4KLS0gY29uY3VycmVudCB3YXRjaGVycyBlYWNoIHdhbGsgdGhlIHJpbmcgaW5kZXBlbmRlbnRseSBhbmQgbm9uZSBzdGVhbHMgYW5vdGhlcidzCi0tIGZyYW1lcy4gVGhpcyBpcyB3aGF0IHJlcGxhY2VkIHRoZSBvbGQgc2luZ2xlLXN1YnNjcmliZXIgbG9nX3BpcGU6cSBxdWV1ZSDigJQKLS0gYSBjb250YWluZXJpemVkIGVkZ2UgdGFpbHMgdGhpcyBvdmVyIGBkb2NrZXIgZXhlYyBjdXJsYCwgYW5kIGEgY3VybCB0aGF0Ci0tIG91dGxpdmVzIGl0cyBjbGllbnQgKHRoZSBkYWVtb24gYnVmZmVycyBpdHMgc3Rkb3V0LCBzbyBubyBFUElQRSkgY2FuIG5vIGxvbmdlcgotLSBkcmFpbiB0aGUgcXVldWUgb3V0IGZyb20gdW5kZXIgdGhlIG5leHQgcmVhZGVyLgoKbG9jYWwgc2ggPSBuZ3guc2hhcmVkLnJlcXVlc3RfZGF0YQppZiBub3Qgc2ggdGhlbgogICAgbmd4LnN0YXR1cyA9IDUwMwogICAgbmd4LnNheSgic2hhcmVkIGRpY3QgdW5hdmFpbGFibGUiKQogICAgcmV0dXJuIG5neC5leGl0KDUwMykKZW5kCgpsb2NhbCBkb21haW4gPSBuZ3gudmFyLmFyZ19kb21haW4KaWYgbm90IGRvbWFpbiBvciBkb21haW4gPT0gIiIgdGhlbgogICAgbmd4LnN0YXR1cyA9IDQwMAogICAgbmd4LnNheSgibWlzc2luZyA/ZG9tYWluPSBwYXJhbWV0ZXIiKQogICAgcmV0dXJuIG5neC5leGl0KDQwMCkKZW5kCgpkb21haW4gPSBkb21haW46bG93ZXIoKQppZiBkb21haW46c3ViKDEsIDQpID09ICJ3d3cuIiB0aGVuIGRvbWFpbiA9IGRvbWFpbjpzdWIoNSkgZW5kCgotLSBNVVNUIG1hdGNoIHNpdGVfbG9nZ2VyLmx1YSdzIFJJTkcg4oCUIHNhbWUgc2xvdCBhcml0aG1ldGljIG9uIGJvdGggZW5kcy4KbG9jYWwgUklORyAgICA9IDEwMDAKbG9jYWwgU0VRX0tFWSA9ICJybG9nOiIgLi4gZG9tYWluIC4uICI6c2VxIgpsb2NhbCBzbG90X2tleSA9IGZ1bmN0aW9uKHNlcSkgcmV0dXJuICJybG9nOiIgLi4gZG9tYWluIC4uICI6IiAuLiAoc2VxICUgUklORykgZW5kCgpuZ3guaGVhZGVyWyJDb250ZW50LVR5cGUiXSAgICAgID0gInRleHQvZXZlbnQtc3RyZWFtIgpuZ3guaGVhZGVyWyJDYWNoZS1Db250cm9sIl0gICAgID0gIm5vLWNhY2hlLCBuby1zdG9yZSIKbmd4LmhlYWRlclsiQ29ubmVjdGlvbiJdICAgICAgICA9ICJrZWVwLWFsaXZlIgpuZ3guaGVhZGVyWyJYLUFjY2VsLUJ1ZmZlcmluZyJdID0gIm5vIgoKLS0gU2VuZCBpbml0aWFsIFNTRSBjb21tZW50IHNvIHRoZSBmaXJzdCBmbHVzaCBoYXMgZGF0YS4KLS0gV2l0aG91dCB0aGlzLCBuZ3guZmx1c2ggb24gYW4gZW1wdHkgYnVmZmVyIHNlbmRzIGNodW5rZWQtRU9GICgwXHJcblxyXG4pCi0tIGFuZCB0ZXJtaW5hdGVzIHRoZSByZXNwb25zZSBpbW1lZGlhdGVseS4Kbmd4LnByaW50KCI6IGNvbm5lY3RlZFxuXG4iKQppZiBub3Qgbmd4LmZsdXNoKHRydWUpIHRoZW4gcmV0dXJuIGVuZAoKLS0gU3RhcnQgYXQgdGhlIGN1cnJlbnQgaGVhZDogc3RyZWFtIG9ubHkgcmVxdWVzdHMgdGhhdCBhcnJpdmUgQUZURVIgY29ubmVjdC4KLS0gSGlzdG9yeSB1cCB0byB0aGlzIHBvaW50IGlzIHNlcnZlZCBzZXBhcmF0ZWx5IGJ5IC9sb2dzL3JlY2VudCwgYW5kIHRoZSBjbGllbnQKLS0gZGVkdXBzIHRoZSB0d28gYnkgdGhlIGRldGVybWluaXN0aWMgYHtob3N0fTp7c2VxfWAgaWQsIHNvIGEgcm93IHNlZW4gYnkgYm90aAotLSBjb2xsYXBzZXMgdG8gb25lLgpsb2NhbCBjdXJzb3IgID0gdG9udW1iZXIoc2g6Z2V0KFNFUV9LRVkpKSBvciAwCmxvY2FsIHN0YXJ0ZWQgPSBuZ3gubm93KCkKbG9jYWwgbGFzdF9oYiA9IHN0YXJ0ZWQKCndoaWxlIHRydWUgZG8KICAgIC0tIE1heCAxIGhvdXIgcGVyIGNvbm5lY3Rpb24uCiAgICBpZiBuZ3gubm93KCkgLSBzdGFydGVkID4gMzYwMCB0aGVuIHJldHVybiBlbmQKCiAgICBsb2NhbCBoZWFkID0gdG9udW1iZXIoc2g6Z2V0KFNFUV9LRVkpKSBvciAwCgogICAgLS0gSWYgd2UndmUgZmFsbGVuIG1vcmUgdGhhbiBhIGZ1bGwgcmluZyBiZWhpbmQsIHRoZSBvbGRlc3QgdW5yZWFkIHNsb3RzIGhhdmUKICAgIC0tIGFscmVhZHkgYmVlbiBvdmVyd3JpdHRlbi4gSnVtcCB0byB0aGUgb2xkZXN0IHNsb3Qgc3RpbGwgaG9sZGluZyBpdHMgb3duCiAgICAtLSBlbnRyeSAoaGVhZC1SSU5HIG1hcHMgdG8gaGVhZCdzIHNsb3QsIHNvIGhlYWQtUklORysxIGlzIHRoZSBvbGRlc3QgbGl2ZSBvbmUpCiAgICAtLSBhbmQgc2tpcCB0aGUgbG9zdCByYW5nZSDigJQgc2FtZSBib3VuZCB0aGUgb2xkIDIwMDAtZW50cnkgcXVldWUgaGFkLgogICAgaWYgY3Vyc29yIDwgaGVhZCAtIFJJTkcgdGhlbiBjdXJzb3IgPSBoZWFkIC0gUklORyBlbmQKCiAgICBsb2NhbCBzZW50ID0gMAogICAgd2hpbGUgY3Vyc29yIDwgaGVhZCBhbmQgc2VudCA8IDEwMCBkbwogICAgICAgIGxvY2FsIG5leHRfc2VxID0gY3Vyc29yICsgMQogICAgICAgIGxvY2FsIGVudHJ5ID0gc2g6Z2V0KHNsb3Rfa2V5KG5leHRfc2VxKSkKICAgICAgICBpZiBlbnRyeSB0aGVuCiAgICAgICAgICAgIG5neC5wcmludCgiZXZlbnQ6IHJlcXVlc3RcbmRhdGE6ICIsIGVudHJ5LCAiXG5cbiIpCiAgICAgICAgICAgIHNlbnQgPSBzZW50ICsgMQogICAgICAgICAgICBjdXJzb3IgPSBuZXh0X3NlcQogICAgICAgIGVsc2VpZiBuZXh0X3NlcSA8IGhlYWQgdGhlbgogICAgICAgICAgICAtLSBBIGxhdGVyIHNlcSBhbHJlYWR5IGV4aXN0cywgc28gdGhpcyBjYW4ndCBiZSB0aGUgaW5jcihzZXEp4oaSc2V0KHNsb3QpCiAgICAgICAgICAgIC0tIHdyaXRlIHdpbmRvdzogdGhlIHNsb3QgaXMgZ2VudWluZWx5IGxvc3QgKGV4cGlyZWQgb3Igd3JhcHBlZCkuIFNraXAgaXQuCiAgICAgICAgICAgIGN1cnNvciA9IG5leHRfc2VxCiAgICAgICAgZWxzZQogICAgICAgICAgICAtLSBuZXh0X3NlcSA9PSBoZWFkOiB0aGUgbmV3ZXN0IGVudHJ5J3Mgc2xvdCBtYXkgbm90IGJlIHdyaXR0ZW4geWV0CiAgICAgICAgICAgIC0tICh0aGUgbWljcm9zZWNvbmQgd2luZG93IGJldHdlZW4gaW5jcihzZXEpIGFuZCBzZXQoc2xvdCkpLiBSZXRyeSBpdAogICAgICAgICAgICAtLSBuZXh0IGN5Y2xlIHdpdGhvdXQgYWR2YW5jaW5nLgogICAgICAgICAgICBicmVhawogICAgICAgIGVuZAogICAgZW5kCgogICAgaWYgc2VudCA+IDAgdGhlbgogICAgICAgIGlmIG5vdCBuZ3guZmx1c2godHJ1ZSkgdGhlbiByZXR1cm4gZW5kCiAgICBlbmQKCiAgICBsb2NhbCBub3cgPSBuZ3gubm93KCkKCiAgICAtLSBIZWFydGJlYXQgZXZlcnkgMTVzLiBJdHMgZmx1c2ggaXMgYWxzbyBob3cgYSBkZWFkIGNsaWVudCBpcyBkZXRlY3RlZDogb25jZQogICAgLS0gdGhlIHJlYWRlciAoYSBgZG9ja2VyIGV4ZWMgY3VybGApIGdvZXMgYXdheSBhbmQgaXRzIHNvY2tldCBjbG9zZXMsIHRoaXMKICAgIC0tIGZsdXNoIGZhaWxzIGFuZCB0aGUgY29ubmVjdGlvbiB0ZWFycyBkb3duIGhlcmUuCiAgICBpZiBub3cgLSBsYXN0X2hiID4gMTUgdGhlbgogICAgICAgIG5neC5wcmludCgiOiBwaW5nXG5cbiIpCiAgICAgICAgaWYgbm90IG5neC5mbHVzaCh0cnVlKSB0aGVuIHJldHVybiBlbmQKICAgICAgICBsYXN0X2hiID0gbm93CiAgICBlbmQKCiAgICBuZ3guc2xlZXAoMC4wNSkKZW5kCg==",
38
38
  "rules_guard.lua": "LS0gcnVsZXNfZ3VhcmQubHVhCi0tIGFjY2Vzc19ieV9sdWEgZHJpdmVyOiBlbmZvcmNlIHBlci1yb3V0ZSBydWxlcyAobWV0aG9kIMK3IElQL0NJRFIgYWxsb3ctZGVueSDCtwotLSBjb3VudHJ5IGFsbG93L2JhbiDCtyBiYWQgdXNlci1hZ2VudCDCtyBob3RsaW5rIMK3IHJhdGUtbGltaXQpIGZvciB0aGUgcmVxdWVzdCdzCi0tIGhvc3QuIFJ1bGVzIGFyZSBwdXNoZWQgcmVsb2FkLWZyZWUgYnkgbWdtdF9hcGkgYFBPU1QgL3J1bGVzYDsgdGhlIERCCi0tIGByb3V0ZV9ydWxlYCB0YWJsZSBpcyB0aGUgc291cmNlIG9mIHRydXRoLiBBbGwgcGFyc2luZy9jb21waWxpbmcvbWF0Y2hpbmcKLS0gbGl2ZXMgaW4gb3BlbnNoaXAucnVsZXNfbGliIChsb2FkZWQgT05DRSBwZXIgd29ya2VyKSDigJQgdGhpcyBmaWxlIGlzIHJlLXJ1bgotLSBldmVyeSByZXF1ZXN0IHNvIGl0IHN0YXlzIG1pbmltYWwuIFNlZSBydWxlc19saWIubHVhIGZvciB0aGUgY29tcGlsZWQgc2hhcGUuCi0tCi0tIEVuZm9yY2VtZW50IHVzZXMgdGhlIGNvbm5lY3RpbmcgcGVlciAobmd4LnZhci5yZW1vdGVfYWRkcik7IGZyb250IGEgcmVhbF9pcAotLSBjb25maWcgaWYgYmVoaW5kIGEgdHJ1c3RlZCBwcm94eS4gTm8gdXNlci1zdXBwbGllZCB2YWx1ZSBpcyBldmVyIHVzZWQgYXMgYQotLSBMdWEgcGF0dGVybiBvciB3cml0dGVuIGludG8gYSByZXNwb25zZSBoZWFkZXIuCgpsb2NhbCBydWxlcyA9IG5neC5zaGFyZWQucnVsZXMKaWYgbm90IHJ1bGVzIHRoZW4gcmV0dXJuIGVuZAoKLS0gUmF0ZS1saW1pdCBjb3VudGVycyBsaXZlIGluIHRoZWlyIE9XTiBkaWN0IHNvIGEgaGlnaC1jYXJkaW5hbGl0eSBmbG9vZCAoYSBuZXcKLS0gcmw6IGtleSBwZXIgc291cmNlIElQIHBlciBzZWNvbmQpIGNhbid0IExSVS1ldmljdCB0aGUgcnVsZXNldHMgYW5kIHNpbGVudGx5Ci0tIGRpc2FibGUgZW5mb3JjZW1lbnQuIEZhbGwgYmFjayB0byBgcnVsZXNgIG9uIGEgYm94IHdob3NlIGNvbmZpZyBwcmVkYXRlcyB0aGUKLS0gc2VwYXJhdGUgZGljdCAoc3RpbGwgd29ya3MsIGp1c3Qgc2hhcmVzIHRoZSB6b25lIHVudGlsIHRoZSBuZXh0IHJlbG9hZCkuCmxvY2FsIGNvdW50ZXJzID0gbmd4LnNoYXJlZC5ybF9jb3VudGVycyBvciBydWxlcwoKbG9jYWwgaG9zdCA9IG5neC52YXIuaG9zdAppZiBub3QgaG9zdCB0aGVuIHJldHVybiBlbmQKCmxvY2FsIHJhdyA9IHJ1bGVzOmdldChob3N0KQppZiBub3QgcmF3IHRoZW4gcmV0dXJuIGVuZCAgICAgICAgICAtLSBmYXN0IHBhdGg6IG5vdGhpbmcgY29uZmlndXJlZCBmb3IgdGhpcyBob3N0Cgpsb2NhbCBsaWIgPSByZXF1aXJlICJvcGVuc2hpcC5ydWxlc19saWIiCmxvY2FsIGVudHJpZXMgPSBsaWIuZ2V0KGhvc3QsIHJhdykKbG9jYWwgbiA9ICNlbnRyaWVzCmlmIG4gPT0gMCB0aGVuIHJldHVybiBlbmQKCi0tIOKUgOKUgCBMb25nZXN0IG1hdGNoaW5nIHBhdGhQcmVmaXggd2lucyDilIDilIAKbG9jYWwgdXJpID0gbmd4LnZhci51cmkgb3IgIi8iCmxvY2FsIGNob3NlbiwgY2hvc2VuX2xlbiA9IG5pbCwgLTEKZm9yIGkgPSAxLCBuIGRvCiAgICBsb2NhbCBlID0gZW50cmllc1tpXQogICAgbG9jYWwgcCA9IGUucGF0aFByZWZpeAogICAgaWYgcCA9PSBuaWwgb3IgcCA9PSAiIiBvciBwID09ICIvIiB0aGVuCiAgICAgICAgaWYgY2hvc2VuX2xlbiA8IDAgdGhlbiBjaG9zZW4sIGNob3Nlbl9sZW4gPSBlLCAwIGVuZAogICAgZWxzZWlmIHVyaSA9PSBwIG9yIHN0cmluZy5zdWIodXJpLCAxLCAjcCkgPT0gcCB0aGVuCiAgICAgICAgaWYgI3AgPiBjaG9zZW5fbGVuIHRoZW4gY2hvc2VuLCBjaG9zZW5fbGVuID0gZSwgI3AgZW5kCiAgICBlbmQKZW5kCmlmIG5vdCBjaG9zZW4gdGhlbiByZXR1cm4gZW5kCgpsb2NhbCBzcGVjID0gY2hvc2VuLnNwZWMKbG9jYWwgZGVueV9zdGF0dXMgPSBzcGVjLmJsb2NrU3RhdHVzIG9yIDQwMwoKbG9jYWwgaXBzID0gbmd4LnZhci5yZW1vdGVfYWRkciBvciAiMC4wLjAuMCIKbG9jYWwgaXBpID0gbGliLmlwdjRfdG9faW50KGlwcykKCi0tIENvdW50cnkgcmVzb2x2ZWQgYXQgbW9zdCBvbmNlIHBlciByZXF1ZXN0IChvbmx5IHdoZW4gYSBjb3VudHJ5IHJ1bGUgZXhpc3RzKS4KbG9jYWwgY291bnRyeV9jYWNoZQpsb2NhbCBmdW5jdGlvbiBjb3VudHJ5X29mKCkKICAgIGlmIGNvdW50cnlfY2FjaGUgPT0gbmlsIHRoZW4KICAgICAgICBsb2NhbCBvaywgZ2VvID0gcGNhbGwocmVxdWlyZSwgIm9wZW5zaGlwLmdlb19jb3VudHJ5IikKICAgICAgICBjb3VudHJ5X2NhY2hlID0gKG9rIGFuZCBnZW8gYW5kIGdlby5nZXRfY291bnRyeV9jb2RlKGlwcykpIG9yIGZhbHNlCiAgICBlbmQKICAgIHJldHVybiBjb3VudHJ5X2NhY2hlIG9yIG5pbAplbmQKCi0tIOKUgOKUgCAxLiBBY2Nlc3M6IG1ldGhvZCBhbGxvdy1saXN0LCBJUCBhbGxvdy9kZW55LCBjb3VudHJ5IGFsbG93LWxpc3Qg4pSA4pSACmxvY2FsIGFjY2VzcyA9IHNwZWMuYWNjZXNzCmlmIGFjY2VzcyB0aGVuCiAgICBpZiBhY2Nlc3MubWV0aG9kcyBhbmQgbm90IGFjY2Vzcy5tZXRob2RzW25neC5yZXEuZ2V0X21ldGhvZCgpXSB0aGVuCiAgICAgICAgcmV0dXJuIG5neC5leGl0KGRlbnlfc3RhdHVzKQogICAgZW5kCiAgICBpZiBsaWIubWF0Y2hfY29tcGlsZWQoYWNjZXNzLmRlbnksIGlwaSwgaXBzKSB0aGVuIHJldHVybiBuZ3guZXhpdChkZW55X3N0YXR1cykgZW5kCiAgICBpZiBhY2Nlc3MuYWxsb3cgYW5kIG5vdCBsaWIubWF0Y2hfY29tcGlsZWQoYWNjZXNzLmFsbG93LCBpcGksIGlwcykgdGhlbgogICAgICAgIHJldHVybiBuZ3guZXhpdChkZW55X3N0YXR1cykKICAgIGVuZAogICAgLS0gQWxsb3ctbGlzdDogYW4gdW5yZXNvbHZlZCBjb3VudHJ5IGlzIG5vdCBvbiB0aGUgbGlzdCDihpIgYmxvY2tlZCAoZGVmYXVsdC1kZW55KS4KICAgIGlmIGFjY2Vzcy5hbGxvd0NvdW50cmllcyBhbmQgbm90IGFjY2Vzcy5hbGxvd0NvdW50cmllc1tjb3VudHJ5X29mKCkgb3IgIiJdIHRoZW4KICAgICAgICByZXR1cm4gbmd4LmV4aXQoZGVueV9zdGF0dXMpCiAgICBlbmQKZW5kCgotLSDilIDilIAgMi4gQmFuOiBJUC9DSURSLCBjb3VudHJ5LCB1c2VyLWFnZW50IOKUgOKUgApsb2NhbCBiYW4gPSBzcGVjLmJhbgppZiBiYW4gdGhlbgogICAgaWYgbGliLm1hdGNoX2NvbXBpbGVkKGJhbi5pcHMsIGlwaSwgaXBzKSBvciBsaWIubWF0Y2hfY29tcGlsZWQoYmFuLmNpZHJzLCBpcGksIGlwcykgdGhlbgogICAgICAgIHJldHVybiBuZ3guZXhpdChkZW55X3N0YXR1cykKICAgIGVuZAogICAgaWYgYmFuLmNvdW50cmllcyB0aGVuCiAgICAgICAgbG9jYWwgY2MgPSBjb3VudHJ5X29mKCkKICAgICAgICAtLSBGYWlsIENMT1NFRCAobWF0Y2hlcyB0aGUgYWxsb3ctbGlzdCBhYm92ZSk6IGlmIGdlbyBpcyB1bmF2YWlsYWJsZSB3ZQogICAgICAgIC0tIGNhbm5vdCBwcm92ZSB0aGUgY2xpZW50IGlzIE5PVCBmcm9tIGEgYmFubmVkIGNvdW50cnksIHNvIGJsb2NrIHJhdGhlcgogICAgICAgIC0tIHRoYW4gc2lsZW50bHkgbGV0dGluZyBiYW5uZWQgdHJhZmZpYyB0aHJvdWdoLiBBIGJsb2NrZWQgaG9zdCBpcyBhIGxvdWQKICAgICAgICAtLSBzaWduYWwgdG8gZml4IGdlbzsgZmFpbC1vcGVuIHdvdWxkIGJlIGEgc2lsZW50IHNlY3VyaXR5IGhvbGUuCiAgICAgICAgaWYgbm90IGNjIHRoZW4KICAgICAgICAgICAgbmd4LmxvZyhuZ3guV0FSTiwgInJ1bGVzX2d1YXJkOiBjb3VudHJ5IGJhbiBhY3RpdmUgYnV0IGdlbyB1bmF2YWlsYWJsZSDigJQgYmxvY2tpbmcgKGZhaWwtY2xvc2VkKSIpCiAgICAgICAgICAgIHJldHVybiBuZ3guZXhpdChkZW55X3N0YXR1cykKICAgICAgICBlbmQKICAgICAgICBpZiBiYW4uY291bnRyaWVzW2NjXSB0aGVuIHJldHVybiBuZ3guZXhpdChkZW55X3N0YXR1cykgZW5kCiAgICBlbmQKICAgIGlmIGJhbi5lbXB0eVVBIG9yIGJhbi51YXMgdGhlbgogICAgICAgIGxvY2FsIHVhID0gbmd4LnZhci5odHRwX3VzZXJfYWdlbnQKICAgICAgICBpZiBiYW4uZW1wdHlVQSBhbmQgKHVhID09IG5pbCBvciB1YSA9PSAiIikgdGhlbiByZXR1cm4gbmd4LmV4aXQoZGVueV9zdGF0dXMpIGVuZAogICAgICAgIGlmIGJhbi51YXMgYW5kIHVhIGFuZCB1YSB+PSAiIiB0aGVuCiAgICAgICAgICAgIGxvY2FsIHVhbCA9IHN0cmluZy5sb3dlcih1YSkKICAgICAgICAgICAgZm9yIGkgPSAxLCAjYmFuLnVhcyBkbwogICAgICAgICAgICAgICAgaWYgc3RyaW5nLmZpbmQodWFsLCBiYW4udWFzW2ldLCAxLCB0cnVlKSB0aGVuIHJldHVybiBuZ3guZXhpdChkZW55X3N0YXR1cykgZW5kCiAgICAgICAgICAgIGVuZAogICAgICAgIGVuZAogICAgZW5kCmVuZAoKLS0g4pSA4pSAIDMuIEhvdGxpbms6IG9ubHkgbGlzdGVkIHJlZmVyZXIgaG9zdHMgKGVtcHR5IHJlZmVyZXIgcGVyIGFsbG93RW1wdHkpIOKUgOKUgApsb2NhbCBob3QgPSBzcGVjLmhvdGxpbmsKaWYgaG90IHRoZW4KICAgIGxvY2FsIHJlZiA9IG5neC52YXIuaHR0cF9yZWZlcmVyCiAgICBpZiByZWYgPT0gbmlsIG9yIHJlZiA9PSAiIiB0aGVuCiAgICAgICAgaWYgbm90IGhvdC5hbGxvd0VtcHR5IHRoZW4gcmV0dXJuIG5neC5leGl0KGRlbnlfc3RhdHVzKSBlbmQKICAgIGVsc2UKICAgICAgICBsb2NhbCByaG9zdCA9IHN0cmluZy5tYXRjaChyZWYsICJeJXcrOi8vKFteL10rKSIpICAgICAgICAgIC0tIGF1dGhvcml0eQogICAgICAgIGlmIHJob3N0IHRoZW4gcmhvc3QgPSBzdHJpbmcubG93ZXIoc3RyaW5nLm1hdGNoKHJob3N0LCAiXihbXjpdKykiKSBvciByaG9zdCkgZW5kIC0tIHN0cmlwIDpwb3J0CiAgICAgICAgaWYgbm90IChyaG9zdCBhbmQgaG90LnJlZmVyZXJzW3Job3N0XSkgdGhlbiByZXR1cm4gbmd4LmV4aXQoZGVueV9zdGF0dXMpIGVuZAogICAgZW5kCmVuZAoKLS0g4pSA4pSAIDQuIFJhdGUgbGltaXQg4oCUIGZpeGVkIDFzIHdpbmRvdyBwZXIgKGhvc3QsIHBhdGgsIGlwKSDilIDilIAKbG9jYWwgcmwgPSBzcGVjLnJsCmlmIHJsIHRoZW4KICAgIGxvY2FsIGtleSA9ICJybDoiIC4uIGhvc3QgLi4gIjoiIC4uIChjaG9zZW4ucGF0aFByZWZpeCBvciAiLyIpIC4uICI6IiAuLiBpcHMKICAgICAgICAuLiAiOiIgLi4gbWF0aC5mbG9vcihuZ3gubm93KCkpCiAgICBsb2NhbCBjID0gY291bnRlcnM6aW5jcihrZXksIDEsIDAsIDIpICAtLSBpbml0IDAsIDJzIFRUTCDihpIgc2VsZi1leHBpcmluZyBidWNrZXRzCiAgICBpZiBjIGFuZCBjID4gcmwubGltaXQgdGhlbgogICAgICAgIG5neC5oZWFkZXJbIlJldHJ5LUFmdGVyIl0gPSAiMSIKICAgICAgICByZXR1cm4gbmd4LmV4aXQocmwuc3RhdHVzKQogICAgZW5kCmVuZAo=",
39
39
  "rules_lib.lua": "LS0gcnVsZXNfbGliLmx1YQotLSBQZXItd29ya2VyIGhlbHBlcnMgKyBwYXJzZWQtcnVsZSBjYWNoZSBmb3IgcnVsZXNfZ3VhcmQubHVhIChhY2Nlc3MgcGhhc2UpLgotLSBMb2FkZWQgT05DRSBwZXIgd29ya2VyIHZpYSByZXF1aXJlKCJvcGVuc2hpcC5ydWxlc19saWIiKS4gVGhlIGFjY2VzcyBmaWxlIGlzCi0tIHJlLWV4ZWN1dGVkIG9uIGV2ZXJ5IHJlcXVlc3QsIHNvIGFsbCBwYXJzaW5nL2NvbXBpbGluZy9tYXRjaGluZyBsaXZlcyBoZXJlIHRvCi0tIGF2b2lkIHJlLWNyZWF0aW5nIGNsb3N1cmVzIGFuZCByZS1kZWNvZGluZyBKU09OIG9uIHRoZSBob3QgcGF0aC4KLS0KLS0gU2hhcmVkLWRpY3QgdmFsdWUgYHJ1bGVzW2hvc3RdYCA9IEpTT04gYXJyYXkgb2YgeyBwYXRoUHJlZml4LCBzcGVjIH0gd2hlcmUKLS0gc3BlYyBtYXRjaGVzIEByZXBvL2NvcmUgUm91dGVSdWxlU3BlYy4gcGFyc2UoKSBkZWNvZGVzICsgcHJlY29tcGlsZXMgQ0lEUnMgdG8KLS0gaW50ZWdlcnMsIGxvd2VyY2FzZXMgVUEvcmVmZXJlciBuZWVkbGVzLCBhbmQgYnVpbGRzIE8oMSkgc2V0cyBmb3IKLS0gY291bnRyaWVzL21ldGhvZHMgT05DRTsgdGhlIGNvbXBpbGVkIHJlc3VsdCBpcyBMUlUtY2FjaGVkIHBlciBob3N0IGFuZCByZXVzZWQKLS0gdW50aWwgdGhlIHJhdyBzdHJpbmcgY2hhbmdlcyAocnVsZSBlZGl0cyBhcmUgcmFyZSwgcmVxdWVzdHMgYXJlIGhvdCkuCi0tCi0tIFNFQ1VSSVRZOiBub3RoaW5nIGhlcmUgdHVybnMgYSBydWxlIHZhbHVlIGludG8gTHVhIGNvZGUgb3IgYSBMdWEgcGF0dGVybi4KLS0gU3RyaW5ncyBhcmUgY29tcGFyZWQgd2l0aCBgPT1gL3NldC1sb29rdXBzOyB1c2VyLWFnZW50IG1hdGNoaW5nIGlzCi0tIHN0cmluZy5maW5kKGhheSwgbmVlZGxlLCAxLCB0cnVlKSDigJQgUExBSU4sIG5ldmVyIGEgcmVnZXguCgpsb2NhbCBjanNvbiA9IHJlcXVpcmUgImNqc29uLnNhZmUiCmxvY2FsIGxydWNhY2hlID0gcmVxdWlyZSAicmVzdHkubHJ1Y2FjaGUiCgpsb2NhbCBNID0ge30KCmxvY2FsIGNhY2hlID0gbHJ1Y2FjaGUubmV3KDEwMjQpIC0tIGNvbXBpbGVkIHJ1bGVzLCBwZXIgd29ya2VyLCB+MTAyNCBob3N0cwoKLS0g4pSA4pSAIElQdjQgaGVscGVycyDilIDilIAKbG9jYWwgZnVuY3Rpb24gaXB2NF90b19pbnQocykKICAgIGxvY2FsIGEsIGIsIGMsIGQgPSBzdHJpbmcubWF0Y2gocywgIl4oJWQrKSUuKCVkKyklLiglZCspJS4oJWQrKSQiKQogICAgaWYgbm90IGEgdGhlbiByZXR1cm4gbmlsIGVuZAogICAgYSwgYiwgYywgZCA9IHRvbnVtYmVyKGEpLCB0b251bWJlcihiKSwgdG9udW1iZXIoYyksIHRvbnVtYmVyKGQpCiAgICBpZiBhID4gMjU1IG9yIGIgPiAyNTUgb3IgYyA+IDI1NSBvciBkID4gMjU1IHRoZW4gcmV0dXJuIG5pbCBlbmQKICAgIHJldHVybiBhICogMTY3NzcyMTYgKyBiICogNjU1MzYgKyBjICogMjU2ICsgZAplbmQKTS5pcHY0X3RvX2ludCA9IGlwdjRfdG9faW50CgotLSBQcmVjb21waWxlIGEgQ0lEUiAvIGJhcmUtSVAgc3RyaW5nIGludG8gYSBjaGVhcCBtYXRjaCBkZXNjcmlwdG9yLgpsb2NhbCBmdW5jdGlvbiBjb21waWxlX2NpZHIocykKICAgIGxvY2FsIGJhc2UsIGJpdHMgPSBzdHJpbmcubWF0Y2gocywgIl4oW14vXSspLyglZCspJCIpCiAgICBpZiBiYXNlIHRoZW4KICAgICAgICBiaXRzID0gdG9udW1iZXIoYml0cykKICAgICAgICBsb2NhbCBiYXNlaSA9IGlwdjRfdG9faW50KGJhc2UpCiAgICAgICAgaWYgbm90IGJhc2VpIG9yIGJpdHMgPCAwIG9yIGJpdHMgPiAzMiB0aGVuIHJldHVybiB7IGV4YWN0ID0gcyB9IGVuZAogICAgICAgIGlmIGJpdHMgPT0gMCB0aGVuIHJldHVybiB7IGFsbCA9IHRydWUgfSBlbmQKICAgICAgICBsb2NhbCBkaXYgPSAyIF4gKDMyIC0gYml0cykgLS0gY29tcGFyZSB0aGUgdG9wIGBiaXRzYCBiaXRzCiAgICAgICAgcmV0dXJuIHsgbmV0ID0gbWF0aC5mbG9vcihiYXNlaSAvIGRpdiksIGRpdiA9IGRpdiB9CiAgICBlbmQKICAgIGxvY2FsIGkgPSBpcHY0X3RvX2ludChzKQogICAgaWYgaSB0aGVuIHJldHVybiB7IGlwID0gaSB9IGVuZAogICAgcmV0dXJuIHsgZXhhY3QgPSBzIH0gLS0gSVB2NiAvIHVucGFyc2VhYmxlIOKGkiBsaXRlcmFsIHN0cmluZyBjb21wYXJlCmVuZAoKbG9jYWwgZnVuY3Rpb24gY29tcGlsZV9saXN0KGxpc3QpCiAgICBpZiB0eXBlKGxpc3QpIH49ICJ0YWJsZSIgdGhlbiByZXR1cm4gbmlsIGVuZAogICAgbG9jYWwgb3V0LCBuID0ge30sIDAKICAgIGZvciBfLCBzIGluIGlwYWlycyhsaXN0KSBkbwogICAgICAgIGlmIHR5cGUocykgPT0gInN0cmluZyIgYW5kIHMgfj0gIiIgdGhlbgogICAgICAgICAgICBuID0gbiArIDEKICAgICAgICAgICAgb3V0W25dID0gY29tcGlsZV9jaWRyKHMpCiAgICAgICAgZW5kCiAgICBlbmQKICAgIHJldHVybiBuID4gMCBhbmQgb3V0IG9yIG5pbAplbmQKCi0tIE1hdGNoIGEgY2xpZW50IChpbnQgZm9ybSBgaXBpYCwgbWF5IGJlIG5pbCBmb3Igbm9uLUlQdjQ7IHJhdyBgaXBzYCkgYWdhaW5zdCBhCi0tIGNvbXBpbGVkIENJRFIvSVAgbGlzdC4KbG9jYWwgZnVuY3Rpb24gbWF0Y2hfY29tcGlsZWQoY29tcGlsZWQsIGlwaSwgaXBzKQogICAgaWYgbm90IGNvbXBpbGVkIHRoZW4gcmV0dXJuIGZhbHNlIGVuZAogICAgZm9yIGkgPSAxLCAjY29tcGlsZWQgZG8KICAgICAgICBsb2NhbCBjID0gY29tcGlsZWRbaV0KICAgICAgICBpZiBjLmFsbCB0aGVuCiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgZWxzZWlmIGMuaXAgdGhlbgogICAgICAgICAgICBpZiBpcGkgYW5kIGlwaSA9PSBjLmlwIHRoZW4gcmV0dXJuIHRydWUgZW5kCiAgICAgICAgZWxzZWlmIGMubmV0IHRoZW4KICAgICAgICAgICAgaWYgaXBpIGFuZCBtYXRoLmZsb29yKGlwaSAvIGMuZGl2KSA9PSBjLm5ldCB0aGVuIHJldHVybiB0cnVlIGVuZAogICAgICAgIGVsc2VpZiBjLmV4YWN0ID09IGlwcyB0aGVuCiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgZW5kCiAgICBlbmQKICAgIHJldHVybiBmYWxzZQplbmQKTS5tYXRjaF9jb21waWxlZCA9IG1hdGNoX2NvbXBpbGVkCgpsb2NhbCBmdW5jdGlvbiBsb3dlcl9saXN0KGxpc3QpCiAgICBpZiB0eXBlKGxpc3QpIH49ICJ0YWJsZSIgdGhlbiByZXR1cm4gbmlsIGVuZAogICAgbG9jYWwgb3V0LCBuID0ge30sIDAKICAgIGZvciBfLCBzIGluIGlwYWlycyhsaXN0KSBkbwogICAgICAgIGlmIHR5cGUocykgPT0gInN0cmluZyIgYW5kIHMgfj0gIiIgdGhlbgogICAgICAgICAgICBuID0gbiArIDEKICAgICAgICAgICAgb3V0W25dID0gc3RyaW5nLmxvd2VyKHMpCiAgICAgICAgZW5kCiAgICBlbmQKICAgIHJldHVybiBuID4gMCBhbmQgb3V0IG9yIG5pbAplbmQKCi0tIEJ1aWxkIGFuIE8oMSkgbG9va3VwIHNldCBmcm9tIGEgc3RyaW5nIGxpc3QgKG9wdGlvbmFsbHkgbG93ZXJjYXNlZCkuCmxvY2FsIGZ1bmN0aW9uIHRvX3NldChsaXN0LCBsb3dlcikKICAgIGlmIHR5cGUobGlzdCkgfj0gInRhYmxlIiB0aGVuIHJldHVybiBuaWwgZW5kCiAgICBsb2NhbCBzZXQsIGFueSA9IHt9LCBmYWxzZQogICAgZm9yIF8sIHMgaW4gaXBhaXJzKGxpc3QpIGRvCiAgICAgICAgaWYgdHlwZShzKSA9PSAic3RyaW5nIiBhbmQgcyB+PSAiIiB0aGVuCiAgICAgICAgICAgIHNldFtsb3dlciBhbmQgc3RyaW5nLmxvd2VyKHMpIG9yIHNdID0gdHJ1ZQogICAgICAgICAgICBhbnkgPSB0cnVlCiAgICAgICAgZW5kCiAgICBlbmQKICAgIHJldHVybiBhbnkgYW5kIHNldCBvciBuaWwKZW5kCgotLSBDb21waWxlIG9uZSBSb3V0ZVJ1bGVTcGVjIGludG8gYSBmYXN0LW1hdGNoIHNoYXBlLgpsb2NhbCBmdW5jdGlvbiBjb21waWxlX3NwZWMoc3BlYykKICAgIGlmIHR5cGUoc3BlYykgfj0gInRhYmxlIiB0aGVuIHJldHVybiB7IGJsb2NrU3RhdHVzID0gNDAzIH0gZW5kCiAgICBsb2NhbCBvdXQgPSB7fQoKICAgIGxvY2FsIHJsID0gc3BlYy5yYXRlTGltaXQKICAgIGxvY2FsIHJwcyA9IHJsIGFuZCB0b251bWJlcihybC5ycHMpCiAgICBpZiBycHMgYW5kIHJwcyA+IDAgdGhlbgogICAgICAgIG91dC5ybCA9IHsKICAgICAgICAgICAgbGltaXQgPSBtYXRoLmZsb29yKHJwcykgKyBtYXRoLmZsb29yKHRvbnVtYmVyKHJsLmJ1cnN0KSBvciAwKSwKICAgICAgICAgICAgc3RhdHVzID0gdG9udW1iZXIocmwuc3RhdHVzKSBvciA0MjksCiAgICAgICAgfQogICAgZW5kCgogICAgbG9jYWwgYmFuID0gc3BlYy5iYW4KICAgIGlmIHR5cGUoYmFuKSA9PSAidGFibGUiIHRoZW4KICAgICAgICBvdXQuYmFuID0gewogICAgICAgICAgICBpcHMgPSBjb21waWxlX2xpc3QoYmFuLmlwcyksCiAgICAgICAgICAgIGNpZHJzID0gY29tcGlsZV9saXN0KGJhbi5jaWRycyksCiAgICAgICAgICAgIGNvdW50cmllcyA9IHRvX3NldChiYW4uY291bnRyaWVzKSwKICAgICAgICAgICAgdWFzID0gbG93ZXJfbGlzdChiYW4udXNlckFnZW50cyksCiAgICAgICAgICAgIGVtcHR5VUEgPSBiYW4uZW1wdHlVc2VyQWdlbnQgPT0gdHJ1ZSwKICAgICAgICB9CiAgICBlbmQKCiAgICBsb2NhbCBhY2MgPSBzcGVjLmFjY2VzcwogICAgaWYgdHlwZShhY2MpID09ICJ0YWJsZSIgdGhlbgogICAgICAgIG91dC5hY2Nlc3MgPSB7CiAgICAgICAgICAgIGFsbG93ID0gY29tcGlsZV9saXN0KGFjYy5hbGxvd0NpZHJzKSwKICAgICAgICAgICAgZGVueSA9IGNvbXBpbGVfbGlzdChhY2MuZGVueUNpZHJzKSwKICAgICAgICAgICAgYWxsb3dDb3VudHJpZXMgPSB0b19zZXQoYWNjLmFsbG93Q291bnRyaWVzKSwKICAgICAgICAgICAgbWV0aG9kcyA9IHRvX3NldChhY2MubWV0aG9kcyksCiAgICAgICAgfQogICAgZW5kCgogICAgbG9jYWwgaG90ID0gc3BlYy5ob3RsaW5rCiAgICBpZiB0eXBlKGhvdCkgPT0gInRhYmxlIiB0aGVuCiAgICAgICAgbG9jYWwgcmVmcyA9IHRvX3NldChob3QuYWxsb3dSZWZlcmVycywgdHJ1ZSkKICAgICAgICBpZiByZWZzIHRoZW4KICAgICAgICAgICAgb3V0LmhvdGxpbmsgPSB7IHJlZmVyZXJzID0gcmVmcywgYWxsb3dFbXB0eSA9IGhvdC5hbGxvd0VtcHR5IH49IGZhbHNlIH0KICAgICAgICBlbmQKICAgIGVuZAoKICAgIG91dC5ibG9ja1N0YXR1cyA9ICh0eXBlKHNwZWMuYmxvY2spID09ICJ0YWJsZSIgYW5kIHRvbnVtYmVyKHNwZWMuYmxvY2suc3RhdHVzKSkgb3IgNDAzCiAgICByZXR1cm4gb3V0CmVuZAoKbG9jYWwgZnVuY3Rpb24gcGFyc2UocmF3KQogICAgbG9jYWwgZW50cmllcyA9IGNqc29uLmRlY29kZShyYXcpCiAgICBpZiB0eXBlKGVudHJpZXMpIH49ICJ0YWJsZSIgdGhlbiByZXR1cm4ge30gZW5kCiAgICBsb2NhbCBvdXQsIG4gPSB7fSwgMAogICAgZm9yIF8sIGUgaW4gaXBhaXJzKGVudHJpZXMpIGRvCiAgICAgICAgaWYgdHlwZShlKSA9PSAidGFibGUiIHRoZW4KICAgICAgICAgICAgbiA9IG4gKyAxCiAgICAgICAgICAgIG91dFtuXSA9IHsgcGF0aFByZWZpeCA9IGUucGF0aFByZWZpeCwgc3BlYyA9IGNvbXBpbGVfc3BlYyhlLnNwZWMpIH0KICAgICAgICBlbmQKICAgIGVuZAogICAgcmV0dXJuIG91dAplbmQKCi0tIExSVS1jYWNoZWQgcGFyc2U6IHJldXNlIHRoZSBjb21waWxlZCBmb3JtIHVudGlsIHRoZSByYXcgZGljdCBzdHJpbmcgY2hhbmdlcy4KZnVuY3Rpb24gTS5nZXQoaG9zdCwgcmF3KQogICAgbG9jYWwgaGl0ID0gY2FjaGU6Z2V0KGhvc3QpCiAgICBpZiBoaXQgYW5kIGhpdC5yYXcgPT0gcmF3IHRoZW4gcmV0dXJuIGhpdC5wYXJzZWQgZW5kCiAgICBsb2NhbCBwYXJzZWQgPSBwYXJzZShyYXcpCiAgICBjYWNoZTpzZXQoaG9zdCwgeyByYXcgPSByYXcsIHBhcnNlZCA9IHBhcnNlZCB9KQogICAgcmV0dXJuIHBhcnNlZAplbmQKCnJldHVybiBNCg==",
40
- "site_logger.lua": "LS0gc2l0ZV9sb2dnZXIubHVhCi0tIE9wZW5SZXN0eSBsb2dfYnlfbHVhIC0gcnVucyBBRlRFUiB0aGUgcmVzcG9uc2UgaXMgc2VudC4KLS0gUHVyZSBzaGFyZWQtZGljdCBhbmFseXRpY3MuICBObyBSZWRpcywgbm8gdGltZXJzIGZvciBjb3VudGVycywgbm8gYmF0Y2hpbmcuCi0tIEV2ZXJ5IGluY3IoKSBpcyBhdG9taWMgYWNyb3NzIHdvcmtlcnMuCi0tCi0tIFNoYXJlZCBkaWN0IGtleSBzY2hlbWEgKGFuYWx5dGljcyB6b25lKToKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OnIgICAgICAgIHJlcXVlc3QgY291bnQgICAgICAgICAgICAgICAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OmkgICAgICAgIGJhbmR3aWR0aCBpbiAgYnl0ZXMgICAgICAgICAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59Om8gICAgICAgIGJhbmR3aWR0aCBvdXQgYnl0ZXMgICAgICAgICAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OnQgICAgICAgIHJlc3BvbnNlIHRpbWUgc3VtIChzZWNvbmRzKSAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OnUgICAgICAgIHBhZ2UgKG5vbi1zdGF0aWMpIHJlcXVlc3RzICAoVFRMIDI0aCkKLS0gICBjOntkb21haW59OntlcG9jaF9taW59OntDQ30gICAgIGNvdW50cnkgcGVyIG1pbnV0ZSAgICAgICAgICAoVFRMIDI0aCkKLS0gICB0Ontkb21haW59OnIgLyA6aSAvIDpvICAgICAgICAgIGxpZmV0aW1lIHRvdGFscyAgICAgICAgICAgICAobm8gVFRMKQotLSAgIGQ6e2RvbWFpbn0gICAgICAgICAgICAgICAgICAgICAgZG9tYWluIGluZGV4IG1hcmtlciAgICAgICAgIChubyBUVEwpCi0tCi0tICAgRGFpbHkgcm9sbHVwLCBhbGwgdW5kZXIgb25lIGBnOntkb21haW59OntZWVlZTU1ERH06YCBwcmVmaXggc28gbWdtdF9hcGkncwotLSAgIC9hbmFseXRpY3MvZ2VvIHNlcnZlcyB0aGUgd2hvbGUgZGF5IGluIGEgU0lOR0xFIGRpY3Qgc2NhbjoKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06e0NDfSAgICAgIGNvdW50cnkgaGl0IGNvdW50ICAgICAgICAgICAoVFRMIDQ4aCkKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06diAgICAgICAgIGRpc3RpbmN0IHZpc2l0b3JzICAgICAgICAgICAoVFRMIDQ4aCkKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06cDp7cGF0aH0gIHBhdGggaGl0IGNvdW50ICAgICAgICAgICAgICAoVFRMIDQ4aCkKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06czp7Y29kZX0gIHN0YXR1cy1jb2RlIGNvdW50ICAgICAgICAgICAoVFRMIDQ4aCkKLS0KLS0gU2hhcmVkIGRpY3Qga2V5IHNjaGVtYSAodmlzaXRvcnMgem9uZSk6Ci0tICAgdnNhbHQ6e1lZWVlNTUREfSAgICAgICAgICAgICAgICBwZXItZGF5IGhhc2ggc2FsdCAgICAgICAgICAgKFRUTCA0OGgpCi0tICAgdmQ6e2RvbWFpbn06e1lZWVlNTUREfTp7aGFzaH0gICBkaXN0aW5jdC12aXNpdG9yIG1hcmtlciAgICAgKFRUTCA0OGgpCi0tCi0tIFNoYXJlZCBkaWN0IGtleSBzY2hlbWEgKHJlcXVlc3RfZGF0YSB6b25lKToKLS0gICBybG9nOntkb21haW59OnNlcSAgICAgICAgICAgICAgIG1vbm90b25pYyB3cml0ZSBwb2ludGVyCi0tICAgcmxvZzp7ZG9tYWlufTp7c2xvdH0gICAgICAgICAgICBKU09OIGVudHJ5IChyaW5nIGJ1ZikgICAgICAgKFRUTCAxaCkKLS0KLS0gVGhlIHJpbmcgaXMgQUxTTyB0aGUgbGl2ZSBzb3VyY2U6IHBpcGVfc3RyZWFtLmx1YSdzIFNTRSBlbmRwb2ludCByZWFkcyB0aGVzZQotLSBzbG90cyBieSBhIHBlci1jb25uZWN0aW9uIGN1cnNvciwgc28gdGhlcmUgaXMgbm8gc2VwYXJhdGUgbGl2ZSBxdWV1ZSBvcgotLSBzdWJzY3JpYmVyIGZsYWcg4oCUIGV2ZXJ5IHdhdGNoZXIgc2VlcyB0aGUgZnVsbCBzdHJlYW0gYW5kIHN0ZWFscyBmcm9tIG5vbmUuCi0tCi0tIE5PVEUgb24gYDp1YCDigJQgaXQgY291bnRzIG5vbi1zdGF0aWMgUkVRVUVTVFMsIG5vdCBwZW9wbGUuIEl0IHdhcyBzdXJmYWNlZCBhcwotLSAidW5pcXVlIElQcyIgYWxsIHRoZSB3YXkgdG8gdGhlIGRhc2hib2FyZCwgd2hpY2ggaXQgbmV2ZXIgd2FzLiBSZWFsIGRpc3RpbmN0Ci0tIHZpc2l0b3JzIGFyZSB0aGUgYHZkOmAvYDp2YCBwYWlyIGJlbG93LgoKbG9jYWwgY2pzb24gPSByZXF1aXJlICJjanNvbi5zYWZlIgoKLS0gU0FGRSBMT0FEOiBHZW9JUCBNb2R1bGUgKHBlci13b3JrZXIsIGNhY2hlZCBieSByZXF1aXJlKQpsb2NhbCBnZW9fb2ssIGdlbyA9IHBjYWxsKHJlcXVpcmUsICJvcGVuc2hpcC5nZW9fY291bnRyeSIpCmlmIG5vdCBnZW9fb2sgdGhlbgogICAgZ2VvID0gbmlsCiAgICBuZ3gubG9nKG5neC5XQVJOLCAiW3NpdGVfbG9nZ2VyXSBnZW9fY291bnRyeSBtb2R1bGUgbm90IGF2YWlsYWJsZS4gR2VvSVAgZGlzYWJsZWQuIikKZW5kCgpsb2NhbCBhbmFseXRpY3MgICAgPSBuZ3guc2hhcmVkLmFuYWx5dGljcwpsb2NhbCByZXF1ZXN0X2RhdGEgPSBuZ3guc2hhcmVkLnJlcXVlc3RfZGF0YQotLSBQZXItaG9zdCBlZGdlIGNvbmZpZywgcHVzaGVkIGJ5IHRoZSBBUEkgKHNlZSBtZ210X2FwaSdzIC9hbmFseXRpY3MvY29uZmlnKS4KLS0KLS0gVGhlIGBydWxlc2Agem9uZSwgTk9UIGBhbmFseXRpY3NgOiB0aGlzIGhvbGRzIGEgaGFuZGZ1bCBvZiBzbWFsbCBjb25maWcgdmFsdWVzIGFuZCBpcwotLSBuZXZlciB1bmRlciBldmljdGlvbiBwcmVzc3VyZSwgd2hlcmVhcyB0aGUgYW5hbHl0aWNzIHpvbmUgaXMgYSAyNTYgTUIgY2h1cm4gb2YgY291bnRlcnMuCi0tIEFuIGV2aWN0ZWQgZmxhZyB0aGVyZSB3b3VsZCBzaWxlbnRseSBzdG9wIHBhdGggY29sbGVjdGlvbiB3aXRoIG5vdGhpbmcgdG8gZXhwbGFpbiB3aHkuCmxvY2FsIHJ1bGVzX2RpY3QgICA9IG5neC5zaGFyZWQucnVsZXMKLS0gT3B0aW9uYWw6IGEgYm94IHdob3NlIG5naW54LmNvbmYgcHJlZGF0ZXMgdGhpcyB6b25lIGtlZXBzIHdvcmtpbmcsIGp1c3Qgd2l0aG91dAotLSBkaXN0aW5jdC12aXNpdG9yIGNvdW50cy4gTmV2ZXIgYXNzdW1lIGEgZGljdCBleGlzdHMuCmxvY2FsIHZpc2l0b3JzICAgICA9IG5neC5zaGFyZWQudmlzaXRvcnMKaWYgbm90IGFuYWx5dGljcyBvciBub3QgcmVxdWVzdF9kYXRhIHRoZW4gcmV0dXJuIGVuZAoKLS0g4pSA4pSAIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpsb2NhbCBmdW5jdGlvbiBub3JtYWxpemUoaG9zdCkKICAgIGlmIG5vdCBob3N0IHRoZW4gcmV0dXJuIG5pbCBlbmQKICAgIGxvY2FsIGggPSBob3N0Omxvd2VyKCkKICAgIGlmIGg6c3ViKDEsIDQpID09ICJ3d3cuIiB0aGVuIGggPSBoOnN1Yig1KSBlbmQKICAgIHJldHVybiBoCmVuZAoKbG9jYWwgX2RheSA9IHsgc3RyID0gIiIsIHRzID0gMCB9CmxvY2FsIGZ1bmN0aW9uIHRvZGF5KCkKICAgIGxvY2FsIG5vdyA9IG5neC5ub3coKQogICAgaWYgbm93IC0gX2RheS50cyA+IDYwIHRoZW4KICAgICAgICBfZGF5LnN0ciA9IG9zLmRhdGUoIiElWSVtJWQiLCBub3cpCiAgICAgICAgX2RheS50cyA9IG5vdwogICAgZW5kCiAgICByZXR1cm4gX2RheS5zdHIKZW5kCgotLSBGYXN0IGNoZWNrIGlmIFVSSSBpcyBhIHN0YXRpYyBhc3NldCAoZm9yIHVuaXF1ZV9yZXF1ZXN0cyBjb3VudGVyKQpsb2NhbCBmdW5jdGlvbiBpc19zdGF0aWNfYXNzZXQodSkKICAgIGxvY2FsIGxvd2VyID0gdTpsb3dlcigpCgogICAgLS0gU3RhdGljIGZpbGUgZXh0ZW5zaW9ucwogICAgaWYgbG93ZXI6bWF0Y2goIiUuanMkIikgb3IgbG93ZXI6bWF0Y2goIiUuY3NzJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS5qcGckIikgb3IgbG93ZXI6bWF0Y2goIiUuanBlZyQiKSBvcgogICAgICAgbG93ZXI6bWF0Y2goIiUucG5nJCIpIG9yIGxvd2VyOm1hdGNoKCIlLmdpZiQiKSBvcgogICAgICAgbG93ZXI6bWF0Y2goIiUuc3ZnJCIpIG9yIGxvd2VyOm1hdGNoKCIlLndlYnAkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLmljbyQiKSBvciBsb3dlcjptYXRjaCgiJS5ibXAkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLndvZmYyPyQiKSBvciBsb3dlcjptYXRjaCgiJS50dGYkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLmVvdCQiKSBvciBsb3dlcjptYXRjaCgiJS5vdGYkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLm1wNCQiKSBvciBsb3dlcjptYXRjaCgiJS53ZWJtJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS5tcDMkIikgb3IgbG93ZXI6bWF0Y2goIiUud2F2JCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS5wZGYkIikgb3IgbG93ZXI6bWF0Y2goIiUuemlwJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS50YXIkIikgb3IgbG93ZXI6bWF0Y2goIiUuZ3okIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLnhtbCQiKSBvciBsb3dlcjptYXRjaCgiJS5qc29uJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS50eHQkIikgb3IgbG93ZXI6bWF0Y2goIiUubWFwJCIpIHRoZW4KICAgICAgICByZXR1cm4gdHJ1ZQogICAgZW5kCgogICAgLS0gQ29tbW9uIHN0YXRpYyBwYXRocwogICAgaWYgbG93ZXI6bWF0Y2goIl4vX25leHQvc3RhdGljLyIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiXi9zdGF0aWMvIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCJeL2Fzc2V0cy8iKSBvcgogICAgICAgbG93ZXI6bWF0Y2goIl4vcHVibGljLyIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiL2Zhdmljb24lLmljbyIpIHRoZW4KICAgICAgICByZXR1cm4gdHJ1ZQogICAgZW5kCgogICAgcmV0dXJuIGZhbHNlCmVuZAoKLS0gQ29sbGFwc2UgYSByZXF1ZXN0IFVSSSBpbnRvIGEgbG93LWNhcmRpbmFsaXR5IGJ1Y2tldCBzdWl0YWJsZSBhcyBhIGRpY3Qga2V5LgotLSBXaXRob3V0IHRoaXMsICJ0b3AgcGF0aHMiIGlzIHVuYm91bmRlZDogZXZlcnkgP3Rva2VuPSwgZXZlcnkgL29yZGVycy80ODIxOSwgYW5kCi0tIGV2ZXJ5IDQwNCBhIHNjYW5uZXIgcHJvYmVzIG1pbnRzIGEgcGVybWFuZW50IGtleSwgYW5kIHRoZSBhbmFseXRpY3Mgem9uZQotLSBMUlUtZXZpY3RzIHJlYWwgY291bnRlcnMgdG8gc3RvcmUganVuay4KbG9jYWwgZnVuY3Rpb24gbm9ybWFsaXplX3BhdGgodSkKICAgIC0tIFF1ZXJ5IHN0cmluZyBjYXJyaWVzIGlkcy90b2tlbnMgYW5kIG5ldmVyIGlkZW50aWZpZXMgdGhlIHJvdXRlLgogICAgbG9jYWwgcGF0aCA9IHU6bWF0Y2goIl4oW14/I10qKSIpIG9yIHUKICAgIGlmIHBhdGggPT0gIiIgdGhlbiByZXR1cm4gIi8iIGVuZAogICAgLS0gTnVtZXJpYyBhbmQgVVVJRC9oZXggc2VnbWVudHMgYXJlIGlkcywgbm90IHJvdXRlczogL29yZGVycy80ODIxOSBhbmQKICAgIC0tIC9vcmRlcnMvNDgyMjAgYXJlIG9uZSBwYXRoLgogICAgcGF0aCA9IHBhdGg6Z3N1YigiLyVkKyIsICIvOmlkIikKICAgIHBhdGggPSBwYXRoOmdzdWIoIi8leCV4JXgleCV4JXgleCV4JS0/JXgqJS0/JXgqJS0/JXgqJS0/JXgqIiwgIi86aWQiKQogICAgLS0gQm91bmQgdGhlIGtleSBpdHNlbGYg4oCUIGEgbG9uZyBVUkkgbXVzdCBub3QgYmVjb21lIGEgbG9uZyBrZXkuCiAgICBpZiAjcGF0aCA+IDEyMCB0aGVuIHBhdGggPSBwYXRoOnN1YigxLCAxMjApIC4uICLigKYiIGVuZAogICAgcmV0dXJuIHBhdGgKZW5kCgotLSDilIDilIAgRW51bWVyYWJsZSBzZXRzLCB3aXRob3V0IGEgem9uZSBzY2FuIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAotLQotLSBSZWFkaW5nIHRoZXNlIGNvdW50ZXJzIGJhY2sgdXNlZCB0byBuZWVkIGtleSBESVNDT1ZFUlksIGFuZCBhIHNoYXJlZCBkaWN0IG9mZmVycyBleGFjdGx5Ci0tIG9uZSBtZWNoYW5pc20gZm9yIHRoYXQ6IGBnZXRfa2V5c2AsIHdoaWNoIHdhbGtzIEVWRVJZIGtleSBpbiB0aGUgem9uZSBob2xkaW5nIGl0cyBsb2NrLgotLSBDb3N0IHNjYWxlZCB3aXRoIGhvdyBtdWNoIHdhcyBpbiB0aGUgMjU2IE1CIHpvbmUsIG5vdCB3aXRoIHdoYXQgd2FzIGJlaW5nIGFza2VkIGZvciwgYW5kCi0tIGl0IHJhbiBvbiB0aGUgbWdtdCBwYXRoIGZvdXIgZGlmZmVyZW50IHdheXMuCi0tCi0tIFNvIGV2ZXJ5IHVuYm91bmRlZCBzZXQgbm93IGNhcnJpZXMgaXRzIG93biBpbmRleDogYSBjb3VudGVyIHBsdXMgbnVtYmVyZWQgc2xvdHMuCi0tCi0tICAgICA8Y291bnRlcj4gICAgICAgIGhvdyBtYW55IGRpc3RpbmN0IG1lbWJlcnMKLS0gICAgIDxwcmVmaXg+PG4+ICAgICAgdGhlIG4tdGggbWVtYmVyCi0tCi0tIEEgcmVhZGVyIHJlYWRzIHRoZSBjb3VudGVyIGFuZCB0aGVuIHJlYWRzIHNsb3RzIDEuLm4uIEJvdW5kZWQgYnkgdGhlIGFuc3dlci4KLS0KLS0gVGhlIHdyaXRlIG9ubHkgaGFwcGVucyBvbiBhIG1lbWJlcidzIEZJUlNUIHNpZ2h0aW5nLCBzbyBzdGVhZHkgc3RhdGUgY29zdHMgbm90aGluZzogdGhlCi0tIG1pbGxpb250aCByZXF1ZXN0IGZyb20gR2VybWFueSB0b2RheSB0YWtlcyB0aGUgcGxhaW4gYGluY3JgIHBhdGggYW5kIHRvdWNoZXMgbm8gaW5kZXguCmxvY2FsIGZ1bmN0aW9uIGluZGV4X2FkZChjb3VudGVyX2tleSwgc2xvdF9wcmVmaXgsIG1lbWJlciwgdHRsKQogICAgbG9jYWwgbiA9IGFuYWx5dGljczppbmNyKGNvdW50ZXJfa2V5LCAxLCAwLCB0dGwpCiAgICBpZiBuIHRoZW4gYW5hbHl0aWNzOnNldChzbG90X3ByZWZpeCAuLiBuLCBtZW1iZXIsIHR0bCkgZW5kCmVuZAoKLS0tIEFkZCAxIHRvIGEgY291bnRlciwgY3JlYXRpbmcgaXQgKHdpdGggVFRMKSBhbmQgaW5kZXhpbmcgaXQgb24gZmlyc3Qgc2lnaHRpbmcuCi0tCi0tIGBpbmNyYCB3aXRoIG5vIGBpbml0YCByZXR1cm5zIG5pbCBmb3IgYW4gYWJzZW50IGtleSwgd2hpY2ggZG91YmxlcyBhcyB0aGUgZXhpc3RlbmNlCi0tIHByb2JlIOKAlCBzbyB0aGUgY29tbW9uIGNhc2UgaXMgT05FIGhhc2ggb3BlcmF0aW9uLiBUVEwgaXMgc2V0IGJ5IHRoZSBjcmVhdGluZyBgc2FmZV9hZGRgCi0tIHJhdGhlciB0aGFuIHBhc3NlZCB0byBgaW5jcmA6IHNoZGljdCByZWplY3RzIGBpbml0X3R0bGAgd2l0aG91dCBgaW5pdGAsIGFuZCB0aGF0IHJhaXNlcyBhCi0tIEx1YSBlcnJvciB3aGljaCBhYm9ydHMgdGhlIHdob2xlIGxvZyBoYW5kbGVyIChpdCBoYXMgc2lsZW50bHkgemVyb2VkIGV2ZXJ5IGNvdW50ZXIgYmVsb3cKLS0gaXQgYmVmb3JlKS4KbG9jYWwgZnVuY3Rpb24gYnVtcF9pbmRleGVkKGtleSwgdHRsLCBjb3VudGVyX2tleSwgc2xvdF9wcmVmaXgsIG1lbWJlcikKICAgIGlmIGFuYWx5dGljczppbmNyKGtleSwgMSkgdGhlbiByZXR1cm4gZW5kCiAgICBpZiBhbmFseXRpY3M6c2FmZV9hZGQoa2V5LCAxLCB0dGwpIHRoZW4KICAgICAgICBpbmRleF9hZGQoY291bnRlcl9rZXksIHNsb3RfcHJlZml4LCBtZW1iZXIsIHR0bCkKICAgIGVsc2UKICAgICAgICAtLSBBbm90aGVyIHdvcmtlciBjcmVhdGVkIGl0IGJldHdlZW4gb3VyIHByb2JlIGFuZCBvdXIgYWRkOyBvdXIgKzEgc3RpbGwgY291bnRzLgogICAgICAgIGFuYWx5dGljczppbmNyKGtleSwgMSkKICAgIGVuZAplbmQKCmxvY2FsIFJJTkcgICA9IDEwMDAKbG9jYWwgRDI0SCAgID0gODY0MDAKbG9jYWwgRDQ4SCAgID0gMTcyODAwCmxvY2FsIEQxSCAgICA9IDM2MDAKCi0tIERpc3RpbmN0IHBhdGhzIHRyYWNrZWQgcGVyIGRvbWFpbiBwZXIgZGF5LiBQYXN0IHRoaXMgdGhlIHRhaWwgZm9sZHMgaW50bwotLSAib3RoZXIiIHJhdGhlciB0aGFuIGdyb3dpbmcgdGhlIHpvbmUg4oCUIGEgVVJMLWZ1enppbmcgYm90IGlzIGNhcHBlZCBhdCBvbmUKLS0gZXh0cmEga2V5LCBub3QgdGhvdXNhbmRzLgpsb2NhbCBQQVRIX0NBUkRJTkFMSVRZX0NBUCA9IDIwMDAKCi0tIOKUgOKUgCBDYXB0dXJlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKbG9jYWwgaG9zdCA9IG5vcm1hbGl6ZShuZ3gudmFyLmhvc3QpCmlmIG5vdCBob3N0IHRoZW4gcmV0dXJuIGVuZAoKbG9jYWwgaXAgICAgICA9IG5neC52YXIucmVtb3RlX2FkZHIgICAgb3IgIjAuMC4wLjAiCmxvY2FsIHRzICAgICAgPSBuZ3gubm93KCkKbG9jYWwgdWEgICAgICA9IG5neC52YXIuaHR0cF91c2VyX2FnZW50IG9yICIiCmxvY2FsIHVyaSAgICAgPSBuZ3gudmFyLnJlcXVlc3RfdXJpICAgIG9yICIvIgpsb2NhbCByZXFfbGVuID0gdG9udW1iZXIobmd4LnZhci5yZXF1ZXN0X2xlbmd0aCkgb3IgMApsb2NhbCBieXRlcyAgID0gdG9udW1iZXIobmd4LnZhci5ieXRlc19zZW50KSAgICAgb3IgMApsb2NhbCBydCAgICAgID0gdG9udW1iZXIobmd4LnZhci5yZXF1ZXN0X3RpbWUpICAgb3IgMCAgLS0gc2Vjb25kcyAoZmxvYXQpCmxvY2FsIG1ldGhvZCAgPSBuZ3gudmFyLnJlcXVlc3RfbWV0aG9kIG9yICJHRVQiCmxvY2FsIHN0YXR1cyAgPSBuZ3gudmFyLnN0YXR1cyAgICAgICAgIG9yICIwIgoKLS0gQ2xpZW50IGNvdW50cnksIHJlc29sdmVkIE9OQ0UgcGVyIHJlcXVlc3QuCi0tCi0tIEhvaXN0ZWQgb3V0IG9mIHRoZSBnZW8gYmxvY2sgYmVjYXVzZSBib3RoIHRoZSBkYWlseS9wZXItbWludXRlIHJvbGx1cHMgYW5kIHRoZSByYXcKLS0gcmluZyBidWZmZXIgbmVlZCBpdC4gVGhlIHJpbmcgaXMgdGhlIHNpbmdsZSBzb3VyY2UgZm9yIHRoZSByZXF1ZXN0IGxvZyDigJQgL2xvZ3MvcmVjZW50Ci0tIHJlYWRzIGl0IGRpcmVjdGx5IGFuZCB0aGUgbGl2ZSBTU0Ugc3RyZWFtIChwaXBlX3N0cmVhbS5sdWEpIHJlYWRzIHRoZSBzYW1lIHNsb3RzIGJ5Ci0tIGN1cnNvciDigJQgc28gcmVzb2x2aW5nIHRoZSBjb3VudHJ5IGhlcmUgbWVhbnMgZXZlcnkgcm93IGNhcnJpZXMgaXRzIGZsYWcgbm8gbWF0dGVyCi0tIHdoaWNoIHBhdGggZGVsaXZlcmVkIGl0LiBBbiBlYXJsaWVyIHNwbGl0IChsb29rZWQgdXAgaW4gdGhlIHJvbGx1cCwgYWdhaW4gaW4gYQotLSBzZXBhcmF0ZSBsaXZlIHBpcGUpIGxlZnQgdGhlIHJpbmcgd2l0aCBubyBjb3VudHJ5IGF0IGFsbC4KLS0KLS0gcGNhbGwnZCBiZWNhdXNlIGEgY29ycnVwdCBvciBwYXJ0aWFsbHktd3JpdHRlbiBtbWRiIG1ha2VzIHRoZSBsb29rdXAgcmFpc2UsIGFuZCBhbgotLSBlcnJvciBoZXJlIHdvdWxkIGFib3J0IGV2ZXJ5IGNvdW50ZXIgYmVsb3cgaXQgKHNlZSB0aGUgc2VjdGlvbiBoZWFkZXIpLgpsb2NhbCBjYyA9IG5pbAppZiBnZW8gYW5kIGdlby5nZXRfY291bnRyeV9jb2RlIHRoZW4KICAgIGxvY2FsIG9rX2NjLCByZXMgPSBwY2FsbChnZW8uZ2V0X2NvdW50cnlfY29kZSwgaXApCiAgICBpZiBva19jYyBhbmQgdHlwZShyZXMpID09ICJzdHJpbmciIGFuZCByZXMgfj0gIiIgdGhlbiBjYyA9IHJlcyBlbmQKZW5kCgotLSDilIDilIAgMS4gTWludXRlLWJ1Y2tldCBjb3VudGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmxvY2FsIG1pbnV0ZSA9IG1hdGguZmxvb3IodHMgLyA2MCkKbG9jYWwgcCA9ICJzOiIgLi4gaG9zdCAuLiAiOiIgLi4gbWludXRlCgphbmFseXRpY3M6aW5jcihwIC4uICI6ciIsIDEsICAgICAgMCwgRDI0SCkKYW5hbHl0aWNzOmluY3IocCAuLiAiOmkiLCByZXFfbGVuLCAwLCBEMjRIKQphbmFseXRpY3M6aW5jcihwIC4uICI6byIsIGJ5dGVzLCAgIDAsIEQyNEgpCgotLSBSZXNwb25zZSB0aW1lIGFzIGZsb2F0IHNlY29uZHMgKG1hdGNoZXMgb3JpZ2luYWwgcHJlY2lzaW9uKQppZiBydCA+IDAgdGhlbgogICAgLS0gc2FmZV9hZGQgaW5pdGlhbGl6ZXMsIGluY3IgYWRkcyAtIGVtdWxhdGUgSElOQ1JCWUZMT0FUIHdpdGggaW50ZWdlciBtaWNyb3MKICAgIGxvY2FsIHJ0X3VzID0gbWF0aC5mbG9vcihydCAqIDEwMDAwMDApCiAgICBhbmFseXRpY3M6aW5jcihwIC4uICI6dCIsIHJ0X3VzLCAwLCBEMjRIKQplbmQKCi0tIFVuaXF1ZSAobm9uLXN0YXRpYykgcmVxdWVzdCBjb3VudGVyCmlmIG5vdCBpc19zdGF0aWNfYXNzZXQodXJpKSB0aGVuCiAgICBhbmFseXRpY3M6aW5jcihwIC4uICI6dSIsIDEsIDAsIEQyNEgpCmVuZAoKLS0g4pSA4pSAIDIuIExpZmV0aW1lIHRvdGFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmFuYWx5dGljczppbmNyKCJ0OiIgLi4gaG9zdCAuLiAiOnIiLCAxLCAgICAgICAwKQphbmFseXRpY3M6aW5jcigidDoiIC4uIGhvc3QgLi4gIjppIiwgcmVxX2xlbiwgMCkKYW5hbHl0aWNzOmluY3IoInQ6IiAuLiBob3N0IC4uICI6byIsIGJ5dGVzLCAgIDApCgotLSBEb21haW4gaW5kZXguIGBzYWZlX2FkZGAgcmV0dXJuaW5nIHRydWUgbWVhbnMgdGhpcyBpcyB0aGUgZmlyc3QgcmVxdWVzdCB0aGlzIGJveCBoYXMKLS0gZXZlciBzZWVuIGZvciB0aGUgaG9zdCwgd2hpY2ggaXMgZXhhY3RseSB3aGVuIHRoZSBlbnVtZXJhYmxlIGluZGV4IG5lZWRzIGFwcGVuZGluZyDigJQKLS0gc28gZG9tYWluIGRpc2NvdmVyeSBubyBsb25nZXIgY29zdHMgYSB6b25lIHNjYW4gZWl0aGVyLgppZiBhbmFseXRpY3M6c2FmZV9hZGQoImQ6IiAuLiBob3N0LCAxKSB0aGVuCiAgICBpbmRleF9hZGQoImRuIiwgImRpOiIsIGhvc3QpCmVuZAoKLS0g4pSA4pSAIDMuIERhaWx5IHJvbGx1cDogZ2VvLCB2aXNpdG9ycywgcGF0aHMsIHN0YXR1c2VzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAotLQotLSBFYWNoIHN1Yi1ibG9jayBpcyBwY2FsbCdkIFNFUEFSQVRFTFksIGFuZCB0aGF0IGlzIGxvYWQtYmVhcmluZyByYXRoZXIgdGhhbgotLSBkZWZlbnNpdmUgaGFiaXQuIEEgcmFpc2VkIGVycm9yIGluIGxvZ19ieV9sdWEgYWJvcnRzIHRoZSByZW1haW5kZXIgb2YgdGhlCi0tIGhhbmRsZXIsIHNvIG9uZSBiYWQgc2hkaWN0IGNhbGwgc2lsZW50bHkgemVyb2VzIGV2ZXJ5IGNvdW50ZXIgd3JpdHRlbiBhZnRlciBpdCDigJQKLS0gd2hpY2ggaXMgZXhhY3RseSB3aGF0IGFuIGBpbmNyKC4uLiwgbmlsLCB0dGwpYCBoZXJlIGRpZDogcGF0aHMgQU5EIHN0YXR1c2VzIHJlYWQKLS0gYXMgIm5vIHRyYWZmaWMiIHdoaWxlIHJlcXVlc3RzIGFuZCBiYW5kd2lkdGggbG9va2VkIHBlcmZlY3QuIElzb2xhdGluZyB0aGVtCi0tIG1lYW5zIGEgZnV0dXJlIGVkaXQgY2FuIGxvc2UgYXQgbW9zdCBpdHMgb3duIG1ldHJpYy4KCmxvY2FsIGRheSAgPSB0b2RheSgpCmxvY2FsIGdwZnggPSAiZzoiIC4uIGhvc3QgLi4gIjoiIC4uIGRheSAuLiAiOiIKCi0tIDNhLiBHZW9JUC4gYGNjYCB3YXMgcmVzb2x2ZWQgb25jZSBhYm92ZSBhbmQgaXMgcmV1c2VkIGJ5IHRoZSByaW5nIGJ1ZmZlciBhbmQgdGhlCi0tIGxpdmUgcGlwZSwgc28gYSByZXF1ZXN0IGNvc3RzIGV4YWN0bHkgb25lIG1tZGIgbG9va3VwIG5vIG1hdHRlciBob3cgbWFueSBjb25zdW1lcnMKLS0gcmVwb3J0IGl0cyBjb3VudHJ5LgppZiBjYyB0aGVuCiAgICBwY2FsbChmdW5jdGlvbigpCiAgICAgICAgLS0gRGFpbHkgZ2VvIChmb3IgL2FuYWx5dGljcy9nZW8gZW5kcG9pbnQpCiAgICAgICAgYnVtcF9pbmRleGVkKGdwZnggLi4gY2MsIEQ0OEgsIGdwZnggLi4gImNuIiwgZ3BmeCAuLiAiY2k6IiwgY2MpCiAgICAgICAgLS0gUGVyLW1pbnV0ZSBnZW8gKGZvciB0aGUgdGltZS1zZXJpZXMgY291bnRyeSBicmVha2Rvd24pLiBJbmRleGVkIHBlciBNSU5VVEUsIHNvCiAgICAgICAgLS0gdGhlIHNjcmFwZXIgcmVhZHMgb25seSB0aGUgbWludXRlcyBpbiBpdHMgd2luZG93LgogICAgICAgIGxvY2FsIG1wZnggPSAiYzoiIC4uIGhvc3QgLi4gIjoiIC4uIG1pbnV0ZSAuLiAiOiIKICAgICAgICBidW1wX2luZGV4ZWQobXBmeCAuLiBjYywgRDI0SCwgbXBmeCAuLiAibiIsIG1wZnggLi4gImk6IiwgY2MpCiAgICBlbmQpCmVuZAoKLS0gM2IuIERpc3RpbmN0IHZpc2l0b3JzIOKAlCBhIENPVU5ULCBuZXZlciBhbiBpZGVudGl0eS4KLS0KLS0gVGhlIGFkZHJlc3MgaXMgaGFzaGVkIHdpdGggYSBzYWx0IHRoYXQgaXMgZ2VuZXJhdGVkIG9uIHRoaXMgYm94LCByb3RhdGVzIGRhaWx5LAotLSBhbmQgaXMgbmV2ZXIgd3JpdHRlbiBhbnl3aGVyZSBidXQgdGhpcyBzaGFyZWQgZGljdCwgc28gdGhlIG1hcmtlciBrZXlzIGFyZSBub3QKLS0gcmV2ZXJzaWJsZSB0byBhbiBJUCBhbmQgYXJlIHdvcnRobGVzcyB0aGUgbmV4dCBkYXkuIE9ubHkgdGhlIHJlc3VsdGluZyBjb3VudGVyCi0tIGlzIGV2ZXIgZmx1c2hlZCB0byBQb3N0Z3Jlczsgbm8gcGVyLXZpc2l0b3Igcm93IGV4aXN0cyBhdCBhbnkgbGF5ZXIuIFRoYXQgaXMKLS0gd2hhdCBsZXRzIHVzIHJlcG9ydCByZWFsIHZpc2l0b3IgbnVtYmVycyB3aGlsZSBzdGlsbCBub3QgY29sbGVjdGluZyBiZWhhdmlvdXJhbAotLSBhbmFseXRpY3Mgb24gYW55b25lJ3MgZW5kIHVzZXJzLgotLQotLSBQZXIgREFZLCBub3QgcGVyIG1pbnV0ZTogYSBwZXItbWludXRlIHNldCBpcyB+MTQ0MHggdGhlIGtleXMgZm9yIGEgbnVtYmVyCi0tIG5vYm9keSByZWFkcywgYW5kIHdvdWxkIGV2aWN0IHRoZSBjb3VudGVycyBpdCBleGlzdHMgdG8gYW5ub3RhdGUuCnBjYWxsKGZ1bmN0aW9uKCkKaWYgdmlzaXRvcnMgdGhlbgogICAgbG9jYWwgc2FsdF9rZXkgPSAidnNhbHQ6IiAuLiBkYXkKICAgIGxvY2FsIHNhbHQgPSB2aXNpdG9yczpnZXQoc2FsdF9rZXkpCiAgICBpZiBub3Qgc2FsdCB0aGVuCiAgICAgICAgLS0gRmlyc3Qgd3JpdGVyIHdpbnM7IGEgcmFjaW5nIHdvcmtlcidzIHNhZmVfYWRkIGZhaWxzIGFuZCBpdCByZS1yZWFkcy4gVGhlCiAgICAgICAgLS0gc2FsdCBvbmx5IGhhcyB0byBiZSB1bnByZWRpY3RhYmxlIGFuZCBzdGFibGUgZm9yIHRoZSBkYXkuCiAgICAgICAgc2FsdCA9IHRvc3RyaW5nKG5neC5ub3coKSkgLi4gdG9zdHJpbmcobWF0aC5yYW5kb20oMSwgMjE0NzQ4MzY0NykpCiAgICAgICAgbG9jYWwgb2sgPSB2aXNpdG9yczpzYWZlX2FkZChzYWx0X2tleSwgc2FsdCwgRDQ4SCkKICAgICAgICBpZiBub3Qgb2sgdGhlbiBzYWx0ID0gdmlzaXRvcnM6Z2V0KHNhbHRfa2V5KSBvciBzYWx0IGVuZAogICAgZW5kCiAgICAtLSBzYWZlX2FkZCBpcyB0aGUgZGVkdXA6IGl0IHN1Y2NlZWRzIE9OTFkgb24gdGhpcyB2aXNpdG9yJ3MgZmlyc3QgcmVxdWVzdAogICAgLS0gdG9kYXksIHNvIHRoZSBjb3VudGVyIGJlbG93IGluY3JlbWVudHMgZXhhY3RseSBvbmNlIHBlciBkaXN0aW5jdCB2aXNpdG9yLgogICAgbG9jYWwgbWFya2VyID0gInZkOiIgLi4gaG9zdCAuLiAiOiIgLi4gZGF5IC4uICI6IiAuLiBuZ3guY3JjMzJfbG9uZyhzYWx0IC4uIGlwKQogICAgaWYgdmlzaXRvcnM6c2FmZV9hZGQobWFya2VyLCAxLCBENDhIKSB0aGVuCiAgICAgICAgYW5hbHl0aWNzOmluY3IoZ3BmeCAuLiAidiIsIDEsIDAsIEQ0OEgpCiAgICBlbmQKZW5kCmVuZCkKCi0tIDNjLiBUb3AgcGF0aHMg4oCUIE9QVC1JTiwgbm9uLXN0YXRpYyBvbmx5LCBub3JtYWxpemVkIGFuZCBjYXJkaW5hbGl0eS1jYXBwZWQuCi0tCi0tIE9mZiB1bmxlc3MgdGhlIHByb2plY3QgdHVybmVkIGl0IG9uLCBiZWNhdXNlIHRoaXMgb25lIGJsb2NrIGlzIHRoZSBtb3N0IGV4cGVuc2l2ZSB0aGluZwotLSB0aGUgbG9nIGhhbmRsZXIgZG9lcy4gTWVhc3VyZWQgb24gdGhlIHNoaXBwZWQgZWRnZSBpbWFnZSwgcGVyIHJlcXVlc3Q6Ci0tCi0tICAgICBwYXRocyAod2hvbGUgYmxvY2spICAgICAgICAxLjcyIHVzICAgICAgPC0gNTclIG9mIHRoZSBjb3VudGVyIHBhdGgKLS0gICAgICAgb2Ygd2hpY2ggc3RyaW5nIHdvcmsgICAgIDEuMzggdXMgICAgICBub3JtYWxpemVfcGF0aCArIGlzX3N0YXRpY19hc3NldAotLSAgICAgbWludXRlIGJ1Y2tldHMgKDUgaW5jcikgICAgMC42MSB1cwotLSAgICAgY291bnRyeSAoMiBpbmNyKSAgICAgICAgICAgMC4yNCB1cwotLSAgICAgc3RhdHVzICgxIGluY3IpICAgICAgICAgICAgMC4xNCB1cwotLSAgICAgdGhpcyBmbGFnIHJlYWQgKDEgZ2V0KSAgICAgMC4wNyB1cwotLQotLSBTbyB0aGUgZ2F0ZSBjb3N0cyAwLjA3IHVzIGFuZCBzYXZlcyAxLjcyIHVzIOKAlCB0aGUgY291bnRlciBwYXRoIGRyb3BzIGZyb20gfjMuMCB1cyB0bwotLSB+MS4zNSB1cyB3aXRoIHBhdGhzIG9mZi4gSXQgaXMgYWxzbyB0aGUgaGlnaGVzdC1jYXJkaW5hbGl0eSBkaW1lbnNpb24gKHVwIHRvCi0tIFBBVEhfQ0FSRElOQUxJVFlfQ0FQIGtleXMgcGVyIGRvbWFpbiBwZXIgZGF5LCBhZ2FpbnN0IH4yMDAgY291bnRyaWVzIGFuZCBhIGZldyBkb3plbgotLSBzdGF0dXNlcykgYW5kIHRoZSBsYXJnZXN0IGNvbHVtbiBpbiB0aGUgZGFpbHkgcm9sbHVwLgotLQotLSBBYnNlbnQgZmxhZyA9IG9mZi4gQSBib3ggd2hvc2UgZGljdCB3YXMganVzdCByZXN0YXJ0ZWQgdGhlcmVmb3JlIGNvbGxlY3RzIG5vdGhpbmcgdW50aWwKLS0gdGhlIEFQSSByZS1wdXNoZXMsIHdoaWNoIGlzIHRoZSBzYWZlIGRpcmVjdGlvbjogbm8gZGF0YSBiZWF0cyBkYXRhIG5vYm9keSBhc2tlZCB0byBwYXkKLS0gZm9yLiBUaGUgREIgaXMgdGhlIHNvdXJjZSBvZiB0cnV0aCBhbmQgcmUtcHVzaGVzIG9uIGV2ZXJ5IHJvdXRlIGFwcGx5Lgpsb2NhbCBjb2xsZWN0X3BhdGhzID0gcnVsZXNfZGljdCBhbmQgcnVsZXNfZGljdDpnZXQoImNmZzoiIC4uIGhvc3QgLi4gIjpwYXRocyIpCgpwY2FsbChmdW5jdGlvbigpCmlmIGNvbGxlY3RfcGF0aHMgYW5kIG5vdCBpc19zdGF0aWNfYXNzZXQodXJpKSB0aGVuCiAgICAtLSBIb2lzdGVkOiBub3JtYWxpemVfcGF0aCBpcyB0aGUgc2luZ2xlIG1vc3QgZXhwZW5zaXZlIGNhbGwgaW4gdGhpcyBoYW5kbGVyICh+MS40IHVzCiAgICAtLSBvZiBzdHJpbmcgd29yayksIHNvIGl0IHJ1bnMgZXhhY3RseSBvbmNlIGV2ZW4gdGhvdWdoIGJvdGggdGhlIGNvdW50ZXIga2V5IGFuZCB0aGUKICAgIC0tIGluZGV4IHNsb3QgbmVlZCBpdHMgcmVzdWx0LgogICAgbG9jYWwgbm9ybSA9IG5vcm1hbGl6ZV9wYXRoKHVyaSkKICAgIGxvY2FsIHBhdGhfa2V5ID0gZ3BmeCAuLiAicDoiIC4uIG5vcm0KICAgIC0tIGluY3ItdGhlbi1hZGQ6IHRoZSBob3QgcGF0aCBpcyBPTkUgaGFzaCBoaXQgb24gYW4gZXhpc3Rpbmcga2V5LiBgaW5jcmAgd2l0aAogICAgLS0gbm8gaW5pdCByZXR1cm5zIG5pbCBmb3IgYW4gYWJzZW50IGtleSwgd2hpY2ggZG91YmxlcyBhcyB0aGUgZXhpc3RlbmNlIHByb2JlLAogICAgLS0gc28gb25seSBhIHBhdGggdW5zZWVuIHRvZGF5IHJlYWNoZXMgdGhlIGNhcCBjaGVjayBiZWxvdy4KICAgIC0tCiAgICAtLSBEZWxpYmVyYXRlbHkgbm8gaW5pdF90dGwgaGVyZTogc2hkaWN0IHJlamVjdHMgaW5pdF90dGwgdW5sZXNzIGluaXQgaXMgYWxzbwogICAgLS0gZ2l2ZW4gKCInaW5pdF90dGwnIG11c3QgYmUgdXNlZCB3aXRoICdpbml0JyIpLCBhbmQgdGhhdCByYWlzZXMgYSBMdWEgZXJyb3IKICAgIC0tIHdoaWNoIGFib3J0cyB0aGUgd2hvbGUgbG9nIGhhbmRsZXIg4oCUIHRha2luZyB0aGUgc3RhdHVzIGNvdW50ZXJzIGJlbG93IGRvd24KICAgIC0tIHdpdGggaXQuIFRoZSBUVEwgaXMgc2V0IGJ5IHRoZSBzYWZlX2FkZCBvbiB0aGUgY3JlYXRpbmcgcmVxdWVzdCBpbnN0ZWFkLgogICAgaWYgbm90IGFuYWx5dGljczppbmNyKHBhdGhfa2V5LCAxKSB0aGVuCiAgICAgICAgbG9jYWwgZGlzdGluY3QgPSBhbmFseXRpY3M6aW5jcihncGZ4IC4uICJwbiIsIDEsIDAsIEQ0OEgpIG9yIDAKICAgICAgICBpZiBkaXN0aW5jdCA+IFBBVEhfQ0FSRElOQUxJVFlfQ0FQIHRoZW4KICAgICAgICAgICAgYW5hbHl0aWNzOmluY3IoZ3BmeCAuLiAicDpvdGhlciIsIDEsIDAsIEQ0OEgpCiAgICAgICAgZWxzZQogICAgICAgICAgICAtLSBgcG5gIHdhcyBhbHJlYWR5IHRoZSBkaXN0aW5jdC1wYXRoIGNvdW50ZXIsIHNvIHRoZSBzbG90cyBqdXN0IGdpdmUgaXQgYW4KICAgICAgICAgICAgLS0gZW51bWVyYWJsZSBzaWRlLiBTdG9yZWQgV0lUSE9VVCB0aGUgInA6IiBwcmVmaXg7IHRoZSByZWFkZXIgYWRkcyBpdCBiYWNrLgogICAgICAgICAgICBpZiBhbmFseXRpY3M6c2FmZV9hZGQocGF0aF9rZXksIDEsIEQ0OEgpIHRoZW4KICAgICAgICAgICAgICAgIGFuYWx5dGljczpzZXQoZ3BmeCAuLiAicGk6IiAuLiBkaXN0aW5jdCwgbm9ybSwgRDQ4SCkKICAgICAgICAgICAgZW5kCiAgICAgICAgZW5kCiAgICBlbmQKZW5kCmVuZCkKCi0tIDNkLiBTdGF0dXMtY29kZSBtaXguIEJvdW5kZWQgYnkgY29uc3RydWN0aW9uIChhIGZldyBkb3plbiBjb2RlcykuCnBjYWxsKGZ1bmN0aW9uKCkKICAgIGJ1bXBfaW5kZXhlZChncGZ4IC4uICJzOiIgLi4gc3RhdHVzLCBENDhILCBncGZ4IC4uICJzbiIsIGdwZnggLi4gInNpOiIsIHN0YXR1cykKZW5kKQoKLS0g4pSA4pSAIDQuIFJhdyByZXF1ZXN0IHJpbmcgYnVmZmVyIChhbHNvIHRoZSBsaXZlIFNTRSBzb3VyY2UpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAotLQotLSBgc2VxYCBpcyBjbGFpbWVkIEJFRk9SRSBlbmNvZGluZyBzbyB0aGUgc3RvcmVkIEpTT04gY2FuIGNhcnJ5IGEgZGV0ZXJtaW5pc3RpYwotLSBpZCAoYHtob3N0fTp7c2VxfWApLiBUaGF0IGlkIGlzIHRoZSBkZWR1cCBrZXkgZXZlcnl3aGVyZSBkb3duc3RyZWFtOiAvbG9ncy9yZWNlbnQKLS0gcmV0dXJucyB0aGVzZSBlbnRyaWVzIHZlcmJhdGltLCBhbmQgcGlwZV9zdHJlYW0ubHVhIHN0cmVhbXMgdGhlIHNhbWUgc2xvdHMgbGl2ZSwKLS0gc28gdGhlIHNhbWUgcmVxdWVzdCByZWFjaGVzIHRoZSBjbGllbnQgd2l0aCBvbmUgc3RhYmxlIGlkIGluc3RlYWQgb2YgYSBmcmVzaAotLSByYW5kb20gb25lIHBlciBzb3VyY2UuIGBpbmNyYCB3aXRoIGluaXQgMCBuZXZlciByZXR1cm5zIG5pbCBoZXJlOyBndWFyZCBhbnl3YXkKLS0gc28gYSBzaGRpY3QgaGljY3VwIGNhbid0IGluZGV4IGEgbmlsIGludG8gdGhlIHNsb3Qga2V5LgoKcGNhbGwoZnVuY3Rpb24oKQogICAgbG9jYWwgc2VxID0gcmVxdWVzdF9kYXRhOmluY3IoInJsb2c6IiAuLiBob3N0IC4uICI6c2VxIiwgMSwgMCkKICAgIGlmIG5vdCBzZXEgdGhlbiByZXR1cm4gZW5kCiAgICBsb2NhbCBva19qLCBqID0gcGNhbGwoY2pzb24uZW5jb2RlLCB7CiAgICAgICAgaWQgICAgID0gaG9zdCAuLiAiOiIgLi4gc2VxLAogICAgICAgIGlwICAgICA9IGlwLAogICAgICAgIC0tIG5pbCBpcyBzaW1wbHkgb21pdHRlZCBieSBjanNvbiwgc28gYSBib3ggd2l0aCBubyBHZW9JUCB3cml0ZXMgdGhlIHNhbWUgc2hhcGUKICAgICAgICAtLSBtaW51cyB0aGlzIGtleSByYXRoZXIgdGhhbiBhIG51bGwgdGhlIHJlYWRlciBoYXMgdG8gc3BlY2lhbC1jYXNlLgogICAgICAgIGNvdW50cnkgPSBjYywKICAgICAgICB0cyAgICAgPSB0cywKICAgICAgICBtZXRob2QgPSBtZXRob2QsCiAgICAgICAgc3RhdHVzID0gc3RhdHVzLAogICAgICAgIHVyaSAgICA9IHVyaSwKICAgICAgICB1YSAgICAgPSB1YSwKICAgICAgICBid19pbiAgPSByZXFfbGVuLAogICAgICAgIGJ3X291dCA9IGJ5dGVzLAogICAgICAgIHJ0ICAgICA9IHJ0LAogICAgfSkKICAgIGlmIG9rX2ogYW5kIGogdGhlbgogICAgICAgIHJlcXVlc3RfZGF0YTpzZXQoInJsb2c6IiAuLiBob3N0IC4uICI6IiAuLiAoc2VxICUgUklORyksIGosIEQxSCkKICAgIGVuZAplbmQpCg==",
40
+ "site_logger.lua": "LS0gc2l0ZV9sb2dnZXIubHVhCi0tIE9wZW5SZXN0eSBsb2dfYnlfbHVhIC0gcnVucyBBRlRFUiB0aGUgcmVzcG9uc2UgaXMgc2VudC4KLS0gUHVyZSBzaGFyZWQtZGljdCBhbmFseXRpY3MuICBObyBSZWRpcywgbm8gdGltZXJzIGZvciBjb3VudGVycywgbm8gYmF0Y2hpbmcuCi0tIEV2ZXJ5IGluY3IoKSBpcyBhdG9taWMgYWNyb3NzIHdvcmtlcnMuCi0tCi0tIFNoYXJlZCBkaWN0IGtleSBzY2hlbWEgKGFuYWx5dGljcyB6b25lKToKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OnIgICAgICAgIHJlcXVlc3QgY291bnQgICAgICAgICAgICAgICAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OmkgICAgICAgIGJhbmR3aWR0aCBpbiAgYnl0ZXMgICAgICAgICAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59Om8gICAgICAgIGJhbmR3aWR0aCBvdXQgYnl0ZXMgICAgICAgICAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OnQgICAgICAgIHJlc3BvbnNlIHRpbWUgc3VtIChzZWNvbmRzKSAoVFRMIDI0aCkKLS0gICBzOntkb21haW59OntlcG9jaF9taW59OnUgICAgICAgIHBhZ2UgKG5vbi1zdGF0aWMpIHJlcXVlc3RzICAoVFRMIDI0aCkKLS0gICBjOntkb21haW59OntlcG9jaF9taW59OntDQ30gICAgIGNvdW50cnkgcGVyIG1pbnV0ZSAgICAgICAgICAoVFRMIDI0aCkKLS0gICB0Ontkb21haW59OnIgLyA6aSAvIDpvICAgICAgICAgIGxpZmV0aW1lIHRvdGFscyAgICAgICAgICAgICAobm8gVFRMKQotLSAgIGQ6e2RvbWFpbn0gICAgICAgICAgICAgICAgICAgICAgZG9tYWluIGluZGV4IG1hcmtlciAgICAgICAgIChubyBUVEwpCi0tCi0tICAgRGFpbHkgcm9sbHVwLCBhbGwgdW5kZXIgb25lIGBnOntkb21haW59OntZWVlZTU1ERH06YCBwcmVmaXggc28gbWdtdF9hcGkncwotLSAgIC9hbmFseXRpY3MvZ2VvIHNlcnZlcyB0aGUgd2hvbGUgZGF5IGluIGEgU0lOR0xFIGRpY3Qgc2NhbjoKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06e0NDfSAgICAgIGNvdW50cnkgaGl0IGNvdW50ICAgICAgICAgICAoVFRMIDQ4aCkKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06diAgICAgICAgIGRpc3RpbmN0IHZpc2l0b3JzICAgICAgICAgICAoVFRMIDQ4aCkKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06cDp7cGF0aH0gIHBhdGggaGl0IGNvdW50ICAgICAgICAgICAgICAoVFRMIDQ4aCkKLS0gICBnOntkb21haW59OntZWVlZTU1ERH06czp7Y29kZX0gIHN0YXR1cy1jb2RlIGNvdW50ICAgICAgICAgICAoVFRMIDQ4aCkKLS0KLS0gU2hhcmVkIGRpY3Qga2V5IHNjaGVtYSAodmlzaXRvcnMgem9uZSk6Ci0tICAgdnNhbHQ6e1lZWVlNTUREfSAgICAgICAgICAgICAgICBwZXItZGF5IGhhc2ggc2FsdCAgICAgICAgICAgKFRUTCA0OGgpCi0tICAgdmQ6e2RvbWFpbn06e1lZWVlNTUREfTp7aGFzaH0gICBkaXN0aW5jdC12aXNpdG9yIG1hcmtlciAgICAgKFRUTCA0OGgpCi0tCi0tIFNoYXJlZCBkaWN0IGtleSBzY2hlbWEgKHJlcXVlc3RfZGF0YSB6b25lKToKLS0gICBybG9nOntkb21haW59OnNlcSAgICAgICAgICAgICAgIG1vbm90b25pYyB3cml0ZSBwb2ludGVyCi0tICAgcmxvZzp7ZG9tYWlufTp7c2xvdH0gICAgICAgICAgICBKU09OIGVudHJ5IChyaW5nIGJ1ZikgICAgICAgKFRUTCAxaCkKLS0KLS0gVGhlIHJpbmcgaXMgQUxTTyB0aGUgbGl2ZSBzb3VyY2U6IHBpcGVfc3RyZWFtLmx1YSdzIFNTRSBlbmRwb2ludCByZWFkcyB0aGVzZQotLSBzbG90cyBieSBhIHBlci1jb25uZWN0aW9uIGN1cnNvciwgc28gdGhlcmUgaXMgbm8gc2VwYXJhdGUgbGl2ZSBxdWV1ZSBvcgotLSBzdWJzY3JpYmVyIGZsYWcg4oCUIGV2ZXJ5IHdhdGNoZXIgc2VlcyB0aGUgZnVsbCBzdHJlYW0gYW5kIHN0ZWFscyBmcm9tIG5vbmUuCi0tCi0tIE5PVEUgb24gYDp1YCDigJQgaXQgY291bnRzIG5vbi1zdGF0aWMgUkVRVUVTVFMsIG5vdCBwZW9wbGUuIEl0IHdhcyBzdXJmYWNlZCBhcwotLSAidW5pcXVlIElQcyIgYWxsIHRoZSB3YXkgdG8gdGhlIGRhc2hib2FyZCwgd2hpY2ggaXQgbmV2ZXIgd2FzLiBSZWFsIGRpc3RpbmN0Ci0tIHZpc2l0b3JzIGFyZSB0aGUgYHZkOmAvYDp2YCBwYWlyIGJlbG93LgoKbG9jYWwgY2pzb24gPSByZXF1aXJlICJjanNvbi5zYWZlIgoKLS0gU0FGRSBMT0FEOiBHZW9JUCBNb2R1bGUgKHBlci13b3JrZXIsIGNhY2hlZCBieSByZXF1aXJlKQpsb2NhbCBnZW9fb2ssIGdlbyA9IHBjYWxsKHJlcXVpcmUsICJvcGVuc2hpcC5nZW9fY291bnRyeSIpCmlmIG5vdCBnZW9fb2sgdGhlbgogICAgZ2VvID0gbmlsCiAgICBuZ3gubG9nKG5neC5XQVJOLCAiW3NpdGVfbG9nZ2VyXSBnZW9fY291bnRyeSBtb2R1bGUgbm90IGF2YWlsYWJsZS4gR2VvSVAgZGlzYWJsZWQuIikKZW5kCgpsb2NhbCBhbmFseXRpY3MgICAgPSBuZ3guc2hhcmVkLmFuYWx5dGljcwpsb2NhbCByZXF1ZXN0X2RhdGEgPSBuZ3guc2hhcmVkLnJlcXVlc3RfZGF0YQotLSBQZXItaG9zdCBlZGdlIGNvbmZpZywgcHVzaGVkIGJ5IHRoZSBBUEkgKHNlZSBtZ210X2FwaSdzIC9hbmFseXRpY3MvY29uZmlnKS4KLS0KLS0gVGhlIGBydWxlc2Agem9uZSwgTk9UIGBhbmFseXRpY3NgOiB0aGlzIGhvbGRzIGEgaGFuZGZ1bCBvZiBzbWFsbCBjb25maWcgdmFsdWVzIGFuZCBpcwotLSBuZXZlciB1bmRlciBldmljdGlvbiBwcmVzc3VyZSwgd2hlcmVhcyB0aGUgYW5hbHl0aWNzIHpvbmUgaXMgYSAyNTYgTUIgY2h1cm4gb2YgY291bnRlcnMuCi0tIEFuIGV2aWN0ZWQgZmxhZyB0aGVyZSB3b3VsZCBzaWxlbnRseSBzdG9wIHBhdGggY29sbGVjdGlvbiB3aXRoIG5vdGhpbmcgdG8gZXhwbGFpbiB3aHkuCmxvY2FsIHJ1bGVzX2RpY3QgICA9IG5neC5zaGFyZWQucnVsZXMKLS0gT3B0aW9uYWw6IGEgYm94IHdob3NlIG5naW54LmNvbmYgcHJlZGF0ZXMgdGhpcyB6b25lIGtlZXBzIHdvcmtpbmcsIGp1c3Qgd2l0aG91dAotLSBkaXN0aW5jdC12aXNpdG9yIGNvdW50cy4gTmV2ZXIgYXNzdW1lIGEgZGljdCBleGlzdHMuCmxvY2FsIHZpc2l0b3JzICAgICA9IG5neC5zaGFyZWQudmlzaXRvcnMKaWYgbm90IGFuYWx5dGljcyBvciBub3QgcmVxdWVzdF9kYXRhIHRoZW4gcmV0dXJuIGVuZAoKLS0g4pSA4pSAIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpsb2NhbCBmdW5jdGlvbiBub3JtYWxpemUoaG9zdCkKICAgIGlmIG5vdCBob3N0IHRoZW4gcmV0dXJuIG5pbCBlbmQKICAgIGxvY2FsIGggPSBob3N0Omxvd2VyKCkKICAgIGlmIGg6c3ViKDEsIDQpID09ICJ3d3cuIiB0aGVuIGggPSBoOnN1Yig1KSBlbmQKICAgIHJldHVybiBoCmVuZAoKbG9jYWwgX2RheSA9IHsgc3RyID0gIiIsIHRzID0gMCB9CmxvY2FsIGZ1bmN0aW9uIHRvZGF5KCkKICAgIGxvY2FsIG5vdyA9IG5neC5ub3coKQogICAgaWYgbm93IC0gX2RheS50cyA+IDYwIHRoZW4KICAgICAgICBfZGF5LnN0ciA9IG9zLmRhdGUoIiElWSVtJWQiLCBub3cpCiAgICAgICAgX2RheS50cyA9IG5vdwogICAgZW5kCiAgICByZXR1cm4gX2RheS5zdHIKZW5kCgotLSBGYXN0IGNoZWNrIGlmIFVSSSBpcyBhIHN0YXRpYyBhc3NldCAoZm9yIHVuaXF1ZV9yZXF1ZXN0cyBjb3VudGVyKQpsb2NhbCBmdW5jdGlvbiBpc19zdGF0aWNfYXNzZXQodSkKICAgIGxvY2FsIGxvd2VyID0gdTpsb3dlcigpCgogICAgLS0gU3RhdGljIGZpbGUgZXh0ZW5zaW9ucwogICAgaWYgbG93ZXI6bWF0Y2goIiUuanMkIikgb3IgbG93ZXI6bWF0Y2goIiUuY3NzJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS5qcGckIikgb3IgbG93ZXI6bWF0Y2goIiUuanBlZyQiKSBvcgogICAgICAgbG93ZXI6bWF0Y2goIiUucG5nJCIpIG9yIGxvd2VyOm1hdGNoKCIlLmdpZiQiKSBvcgogICAgICAgbG93ZXI6bWF0Y2goIiUuc3ZnJCIpIG9yIGxvd2VyOm1hdGNoKCIlLndlYnAkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLmljbyQiKSBvciBsb3dlcjptYXRjaCgiJS5ibXAkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLndvZmYyPyQiKSBvciBsb3dlcjptYXRjaCgiJS50dGYkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLmVvdCQiKSBvciBsb3dlcjptYXRjaCgiJS5vdGYkIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLm1wNCQiKSBvciBsb3dlcjptYXRjaCgiJS53ZWJtJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS5tcDMkIikgb3IgbG93ZXI6bWF0Y2goIiUud2F2JCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS5wZGYkIikgb3IgbG93ZXI6bWF0Y2goIiUuemlwJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS50YXIkIikgb3IgbG93ZXI6bWF0Y2goIiUuZ3okIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCIlLnhtbCQiKSBvciBsb3dlcjptYXRjaCgiJS5qc29uJCIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiJS50eHQkIikgb3IgbG93ZXI6bWF0Y2goIiUubWFwJCIpIHRoZW4KICAgICAgICByZXR1cm4gdHJ1ZQogICAgZW5kCgogICAgLS0gQ29tbW9uIHN0YXRpYyBwYXRocwogICAgaWYgbG93ZXI6bWF0Y2goIl4vX25leHQvc3RhdGljLyIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiXi9zdGF0aWMvIikgb3IKICAgICAgIGxvd2VyOm1hdGNoKCJeL2Fzc2V0cy8iKSBvcgogICAgICAgbG93ZXI6bWF0Y2goIl4vcHVibGljLyIpIG9yCiAgICAgICBsb3dlcjptYXRjaCgiL2Zhdmljb24lLmljbyIpIHRoZW4KICAgICAgICByZXR1cm4gdHJ1ZQogICAgZW5kCgogICAgcmV0dXJuIGZhbHNlCmVuZAoKLS0gQ29sbGFwc2UgYSByZXF1ZXN0IFVSSSBpbnRvIGEgbG93LWNhcmRpbmFsaXR5IGJ1Y2tldCBzdWl0YWJsZSBhcyBhIGRpY3Qga2V5LgotLSBXaXRob3V0IHRoaXMsICJ0b3AgcGF0aHMiIGlzIHVuYm91bmRlZDogZXZlcnkgP3Rva2VuPSwgZXZlcnkgL29yZGVycy80ODIxOSwgYW5kCi0tIGV2ZXJ5IDQwNCBhIHNjYW5uZXIgcHJvYmVzIG1pbnRzIGEgcGVybWFuZW50IGtleSwgYW5kIHRoZSBhbmFseXRpY3Mgem9uZQotLSBMUlUtZXZpY3RzIHJlYWwgY291bnRlcnMgdG8gc3RvcmUganVuay4KbG9jYWwgZnVuY3Rpb24gbm9ybWFsaXplX3BhdGgodSkKICAgIC0tIFF1ZXJ5IHN0cmluZyBjYXJyaWVzIGlkcy90b2tlbnMgYW5kIG5ldmVyIGlkZW50aWZpZXMgdGhlIHJvdXRlLgogICAgbG9jYWwgcGF0aCA9IHU6bWF0Y2goIl4oW14/I10qKSIpIG9yIHUKICAgIGlmIHBhdGggPT0gIiIgdGhlbiByZXR1cm4gIi8iIGVuZAogICAgLS0gTnVtZXJpYyBhbmQgVVVJRC9oZXggc2VnbWVudHMgYXJlIGlkcywgbm90IHJvdXRlczogL29yZGVycy80ODIxOSBhbmQKICAgIC0tIC9vcmRlcnMvNDgyMjAgYXJlIG9uZSBwYXRoLgogICAgcGF0aCA9IHBhdGg6Z3N1YigiLyVkKyIsICIvOmlkIikKICAgIHBhdGggPSBwYXRoOmdzdWIoIi8leCV4JXgleCV4JXgleCV4JS0/JXgqJS0/JXgqJS0/JXgqJS0/JXgqIiwgIi86aWQiKQogICAgLS0gQm91bmQgdGhlIGtleSBpdHNlbGYg4oCUIGEgbG9uZyBVUkkgbXVzdCBub3QgYmVjb21lIGEgbG9uZyBrZXkuCiAgICBpZiAjcGF0aCA+IDEyMCB0aGVuIHBhdGggPSBwYXRoOnN1YigxLCAxMjApIC4uICLigKYiIGVuZAogICAgcmV0dXJuIHBhdGgKZW5kCgotLSBSYXcgcmVxdWVzdCB0ZWxlbWV0cnkgbXVzdCBuZXZlciByZXRhaW4gY3JlZGVudGlhbHMgZnJvbSBhIFVSTC4gUXVlcnkKLS0gc3RyaW5ncyByb3V0aW5lbHkgY2FycnkgT0F1dGggY29kZXMsIHNpZ25lZCBVUkxzIGFuZCB0b2tlbnMsIHNvIGV4Y2x1ZGUgdGhlbQotLSBjb21wbGV0ZWx5LiBJbnZpdGF0aW9uIGNsYWltIGlkcyBhcmUgYmVhcmVyIGNyZWRlbnRpYWxzIGluIHRoZSBwYXRoIGl0c2VsZjsKLS0gY29sbGFwc2UgdGhvc2UgdHdvIGtub3duIHJvdXRlcyBiZWZvcmUgZWl0aGVyIHRvcC1wYXRoIGFnZ3JlZ2F0aW9uIG9yIHRoZQotLSBvbmUtaG91ciByZXF1ZXN0IHJpbmcgY2FuIG9ic2VydmUgdGhlbS4KbG9jYWwgZnVuY3Rpb24gdGVsZW1ldHJ5X3VyaSh1KQogICAgbG9jYWwgcGF0aCA9IHU6bWF0Y2goIl4oW14/I10qKSIpIG9yICIvIgogICAgaWYgcGF0aCA9PSAiIiB0aGVuIHJldHVybiAiLyIgZW5kCiAgICBpZiBwYXRoOm1hdGNoKCJeL2FjY2VwdCUtaW52aXRlL1teL10rIikgdGhlbgogICAgICAgIHJldHVybiAiL2FjY2VwdC1pbnZpdGUvOnRva2VuIgogICAgZW5kCiAgICBpZiBwYXRoOm1hdGNoKCJeL2FwaS9hdXRoL2ludml0YXRpb24lLXByZXZpZXcvW14vXSsiKSB0aGVuCiAgICAgICAgcmV0dXJuICIvYXBpL2F1dGgvaW52aXRhdGlvbi1wcmV2aWV3Lzp0b2tlbiIKICAgIGVuZAogICAgcmV0dXJuIHBhdGgKZW5kCgotLSDilIDilIAgRW51bWVyYWJsZSBzZXRzLCB3aXRob3V0IGEgem9uZSBzY2FuIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAotLQotLSBSZWFkaW5nIHRoZXNlIGNvdW50ZXJzIGJhY2sgdXNlZCB0byBuZWVkIGtleSBESVNDT1ZFUlksIGFuZCBhIHNoYXJlZCBkaWN0IG9mZmVycyBleGFjdGx5Ci0tIG9uZSBtZWNoYW5pc20gZm9yIHRoYXQ6IGBnZXRfa2V5c2AsIHdoaWNoIHdhbGtzIEVWRVJZIGtleSBpbiB0aGUgem9uZSBob2xkaW5nIGl0cyBsb2NrLgotLSBDb3N0IHNjYWxlZCB3aXRoIGhvdyBtdWNoIHdhcyBpbiB0aGUgMjU2IE1CIHpvbmUsIG5vdCB3aXRoIHdoYXQgd2FzIGJlaW5nIGFza2VkIGZvciwgYW5kCi0tIGl0IHJhbiBvbiB0aGUgbWdtdCBwYXRoIGZvdXIgZGlmZmVyZW50IHdheXMuCi0tCi0tIFNvIGV2ZXJ5IHVuYm91bmRlZCBzZXQgbm93IGNhcnJpZXMgaXRzIG93biBpbmRleDogYSBjb3VudGVyIHBsdXMgbnVtYmVyZWQgc2xvdHMuCi0tCi0tICAgICA8Y291bnRlcj4gICAgICAgIGhvdyBtYW55IGRpc3RpbmN0IG1lbWJlcnMKLS0gICAgIDxwcmVmaXg+PG4+ICAgICAgdGhlIG4tdGggbWVtYmVyCi0tCi0tIEEgcmVhZGVyIHJlYWRzIHRoZSBjb3VudGVyIGFuZCB0aGVuIHJlYWRzIHNsb3RzIDEuLm4uIEJvdW5kZWQgYnkgdGhlIGFuc3dlci4KLS0KLS0gVGhlIHdyaXRlIG9ubHkgaGFwcGVucyBvbiBhIG1lbWJlcidzIEZJUlNUIHNpZ2h0aW5nLCBzbyBzdGVhZHkgc3RhdGUgY29zdHMgbm90aGluZzogdGhlCi0tIG1pbGxpb250aCByZXF1ZXN0IGZyb20gR2VybWFueSB0b2RheSB0YWtlcyB0aGUgcGxhaW4gYGluY3JgIHBhdGggYW5kIHRvdWNoZXMgbm8gaW5kZXguCmxvY2FsIGZ1bmN0aW9uIGluZGV4X2FkZChjb3VudGVyX2tleSwgc2xvdF9wcmVmaXgsIG1lbWJlciwgdHRsKQogICAgbG9jYWwgbiA9IGFuYWx5dGljczppbmNyKGNvdW50ZXJfa2V5LCAxLCAwLCB0dGwpCiAgICBpZiBuIHRoZW4gYW5hbHl0aWNzOnNldChzbG90X3ByZWZpeCAuLiBuLCBtZW1iZXIsIHR0bCkgZW5kCmVuZAoKLS0tIEFkZCAxIHRvIGEgY291bnRlciwgY3JlYXRpbmcgaXQgKHdpdGggVFRMKSBhbmQgaW5kZXhpbmcgaXQgb24gZmlyc3Qgc2lnaHRpbmcuCi0tCi0tIGBpbmNyYCB3aXRoIG5vIGBpbml0YCByZXR1cm5zIG5pbCBmb3IgYW4gYWJzZW50IGtleSwgd2hpY2ggZG91YmxlcyBhcyB0aGUgZXhpc3RlbmNlCi0tIHByb2JlIOKAlCBzbyB0aGUgY29tbW9uIGNhc2UgaXMgT05FIGhhc2ggb3BlcmF0aW9uLiBUVEwgaXMgc2V0IGJ5IHRoZSBjcmVhdGluZyBgc2FmZV9hZGRgCi0tIHJhdGhlciB0aGFuIHBhc3NlZCB0byBgaW5jcmA6IHNoZGljdCByZWplY3RzIGBpbml0X3R0bGAgd2l0aG91dCBgaW5pdGAsIGFuZCB0aGF0IHJhaXNlcyBhCi0tIEx1YSBlcnJvciB3aGljaCBhYm9ydHMgdGhlIHdob2xlIGxvZyBoYW5kbGVyIChpdCBoYXMgc2lsZW50bHkgemVyb2VkIGV2ZXJ5IGNvdW50ZXIgYmVsb3cKLS0gaXQgYmVmb3JlKS4KbG9jYWwgZnVuY3Rpb24gYnVtcF9pbmRleGVkKGtleSwgdHRsLCBjb3VudGVyX2tleSwgc2xvdF9wcmVmaXgsIG1lbWJlcikKICAgIGlmIGFuYWx5dGljczppbmNyKGtleSwgMSkgdGhlbiByZXR1cm4gZW5kCiAgICBpZiBhbmFseXRpY3M6c2FmZV9hZGQoa2V5LCAxLCB0dGwpIHRoZW4KICAgICAgICBpbmRleF9hZGQoY291bnRlcl9rZXksIHNsb3RfcHJlZml4LCBtZW1iZXIsIHR0bCkKICAgIGVsc2UKICAgICAgICAtLSBBbm90aGVyIHdvcmtlciBjcmVhdGVkIGl0IGJldHdlZW4gb3VyIHByb2JlIGFuZCBvdXIgYWRkOyBvdXIgKzEgc3RpbGwgY291bnRzLgogICAgICAgIGFuYWx5dGljczppbmNyKGtleSwgMSkKICAgIGVuZAplbmQKCmxvY2FsIFJJTkcgICA9IDEwMDAKbG9jYWwgRDI0SCAgID0gODY0MDAKbG9jYWwgRDQ4SCAgID0gMTcyODAwCmxvY2FsIEQxSCAgICA9IDM2MDAKCi0tIERpc3RpbmN0IHBhdGhzIHRyYWNrZWQgcGVyIGRvbWFpbiBwZXIgZGF5LiBQYXN0IHRoaXMgdGhlIHRhaWwgZm9sZHMgaW50bwotLSAib3RoZXIiIHJhdGhlciB0aGFuIGdyb3dpbmcgdGhlIHpvbmUg4oCUIGEgVVJMLWZ1enppbmcgYm90IGlzIGNhcHBlZCBhdCBvbmUKLS0gZXh0cmEga2V5LCBub3QgdGhvdXNhbmRzLgpsb2NhbCBQQVRIX0NBUkRJTkFMSVRZX0NBUCA9IDIwMDAKCi0tIOKUgOKUgCBDYXB0dXJlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKbG9jYWwgaG9zdCA9IG5vcm1hbGl6ZShuZ3gudmFyLmhvc3QpCmlmIG5vdCBob3N0IHRoZW4gcmV0dXJuIGVuZAoKbG9jYWwgaXAgICAgICA9IG5neC52YXIucmVtb3RlX2FkZHIgICAgb3IgIjAuMC4wLjAiCmxvY2FsIHRzICAgICAgPSBuZ3gubm93KCkKbG9jYWwgdWEgICAgICA9IG5neC52YXIuaHR0cF91c2VyX2FnZW50IG9yICIiCmxvY2FsIHVyaSAgICAgPSB0ZWxlbWV0cnlfdXJpKG5neC52YXIucmVxdWVzdF91cmkgb3IgIi8iKQpsb2NhbCByZXFfbGVuID0gdG9udW1iZXIobmd4LnZhci5yZXF1ZXN0X2xlbmd0aCkgb3IgMApsb2NhbCBieXRlcyAgID0gdG9udW1iZXIobmd4LnZhci5ieXRlc19zZW50KSAgICAgb3IgMApsb2NhbCBydCAgICAgID0gdG9udW1iZXIobmd4LnZhci5yZXF1ZXN0X3RpbWUpICAgb3IgMCAgLS0gc2Vjb25kcyAoZmxvYXQpCmxvY2FsIG1ldGhvZCAgPSBuZ3gudmFyLnJlcXVlc3RfbWV0aG9kIG9yICJHRVQiCmxvY2FsIHN0YXR1cyAgPSBuZ3gudmFyLnN0YXR1cyAgICAgICAgIG9yICIwIgoKLS0gQ2xpZW50IGNvdW50cnksIHJlc29sdmVkIE9OQ0UgcGVyIHJlcXVlc3QuCi0tCi0tIEhvaXN0ZWQgb3V0IG9mIHRoZSBnZW8gYmxvY2sgYmVjYXVzZSBib3RoIHRoZSBkYWlseS9wZXItbWludXRlIHJvbGx1cHMgYW5kIHRoZSByYXcKLS0gcmluZyBidWZmZXIgbmVlZCBpdC4gVGhlIHJpbmcgaXMgdGhlIHNpbmdsZSBzb3VyY2UgZm9yIHRoZSByZXF1ZXN0IGxvZyDigJQgL2xvZ3MvcmVjZW50Ci0tIHJlYWRzIGl0IGRpcmVjdGx5IGFuZCB0aGUgbGl2ZSBTU0Ugc3RyZWFtIChwaXBlX3N0cmVhbS5sdWEpIHJlYWRzIHRoZSBzYW1lIHNsb3RzIGJ5Ci0tIGN1cnNvciDigJQgc28gcmVzb2x2aW5nIHRoZSBjb3VudHJ5IGhlcmUgbWVhbnMgZXZlcnkgcm93IGNhcnJpZXMgaXRzIGZsYWcgbm8gbWF0dGVyCi0tIHdoaWNoIHBhdGggZGVsaXZlcmVkIGl0LiBBbiBlYXJsaWVyIHNwbGl0IChsb29rZWQgdXAgaW4gdGhlIHJvbGx1cCwgYWdhaW4gaW4gYQotLSBzZXBhcmF0ZSBsaXZlIHBpcGUpIGxlZnQgdGhlIHJpbmcgd2l0aCBubyBjb3VudHJ5IGF0IGFsbC4KLS0KLS0gcGNhbGwnZCBiZWNhdXNlIGEgY29ycnVwdCBvciBwYXJ0aWFsbHktd3JpdHRlbiBtbWRiIG1ha2VzIHRoZSBsb29rdXAgcmFpc2UsIGFuZCBhbgotLSBlcnJvciBoZXJlIHdvdWxkIGFib3J0IGV2ZXJ5IGNvdW50ZXIgYmVsb3cgaXQgKHNlZSB0aGUgc2VjdGlvbiBoZWFkZXIpLgpsb2NhbCBjYyA9IG5pbAppZiBnZW8gYW5kIGdlby5nZXRfY291bnRyeV9jb2RlIHRoZW4KICAgIGxvY2FsIG9rX2NjLCByZXMgPSBwY2FsbChnZW8uZ2V0X2NvdW50cnlfY29kZSwgaXApCiAgICBpZiBva19jYyBhbmQgdHlwZShyZXMpID09ICJzdHJpbmciIGFuZCByZXMgfj0gIiIgdGhlbiBjYyA9IHJlcyBlbmQKZW5kCgotLSDilIDilIAgMS4gTWludXRlLWJ1Y2tldCBjb3VudGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmxvY2FsIG1pbnV0ZSA9IG1hdGguZmxvb3IodHMgLyA2MCkKbG9jYWwgcCA9ICJzOiIgLi4gaG9zdCAuLiAiOiIgLi4gbWludXRlCgphbmFseXRpY3M6aW5jcihwIC4uICI6ciIsIDEsICAgICAgMCwgRDI0SCkKYW5hbHl0aWNzOmluY3IocCAuLiAiOmkiLCByZXFfbGVuLCAwLCBEMjRIKQphbmFseXRpY3M6aW5jcihwIC4uICI6byIsIGJ5dGVzLCAgIDAsIEQyNEgpCgotLSBSZXNwb25zZSB0aW1lIGFzIGZsb2F0IHNlY29uZHMgKG1hdGNoZXMgb3JpZ2luYWwgcHJlY2lzaW9uKQppZiBydCA+IDAgdGhlbgogICAgLS0gc2FmZV9hZGQgaW5pdGlhbGl6ZXMsIGluY3IgYWRkcyAtIGVtdWxhdGUgSElOQ1JCWUZMT0FUIHdpdGggaW50ZWdlciBtaWNyb3MKICAgIGxvY2FsIHJ0X3VzID0gbWF0aC5mbG9vcihydCAqIDEwMDAwMDApCiAgICBhbmFseXRpY3M6aW5jcihwIC4uICI6dCIsIHJ0X3VzLCAwLCBEMjRIKQplbmQKCi0tIFVuaXF1ZSAobm9uLXN0YXRpYykgcmVxdWVzdCBjb3VudGVyCmlmIG5vdCBpc19zdGF0aWNfYXNzZXQodXJpKSB0aGVuCiAgICBhbmFseXRpY3M6aW5jcihwIC4uICI6dSIsIDEsIDAsIEQyNEgpCmVuZAoKLS0g4pSA4pSAIDIuIExpZmV0aW1lIHRvdGFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmFuYWx5dGljczppbmNyKCJ0OiIgLi4gaG9zdCAuLiAiOnIiLCAxLCAgICAgICAwKQphbmFseXRpY3M6aW5jcigidDoiIC4uIGhvc3QgLi4gIjppIiwgcmVxX2xlbiwgMCkKYW5hbHl0aWNzOmluY3IoInQ6IiAuLiBob3N0IC4uICI6byIsIGJ5dGVzLCAgIDApCgotLSBEb21haW4gaW5kZXguIGBzYWZlX2FkZGAgcmV0dXJuaW5nIHRydWUgbWVhbnMgdGhpcyBpcyB0aGUgZmlyc3QgcmVxdWVzdCB0aGlzIGJveCBoYXMKLS0gZXZlciBzZWVuIGZvciB0aGUgaG9zdCwgd2hpY2ggaXMgZXhhY3RseSB3aGVuIHRoZSBlbnVtZXJhYmxlIGluZGV4IG5lZWRzIGFwcGVuZGluZyDigJQKLS0gc28gZG9tYWluIGRpc2NvdmVyeSBubyBsb25nZXIgY29zdHMgYSB6b25lIHNjYW4gZWl0aGVyLgppZiBhbmFseXRpY3M6c2FmZV9hZGQoImQ6IiAuLiBob3N0LCAxKSB0aGVuCiAgICBpbmRleF9hZGQoImRuIiwgImRpOiIsIGhvc3QpCmVuZAoKLS0g4pSA4pSAIDMuIERhaWx5IHJvbGx1cDogZ2VvLCB2aXNpdG9ycywgcGF0aHMsIHN0YXR1c2VzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAotLQotLSBFYWNoIHN1Yi1ibG9jayBpcyBwY2FsbCdkIFNFUEFSQVRFTFksIGFuZCB0aGF0IGlzIGxvYWQtYmVhcmluZyByYXRoZXIgdGhhbgotLSBkZWZlbnNpdmUgaGFiaXQuIEEgcmFpc2VkIGVycm9yIGluIGxvZ19ieV9sdWEgYWJvcnRzIHRoZSByZW1haW5kZXIgb2YgdGhlCi0tIGhhbmRsZXIsIHNvIG9uZSBiYWQgc2hkaWN0IGNhbGwgc2lsZW50bHkgemVyb2VzIGV2ZXJ5IGNvdW50ZXIgd3JpdHRlbiBhZnRlciBpdCDigJQKLS0gd2hpY2ggaXMgZXhhY3RseSB3aGF0IGFuIGBpbmNyKC4uLiwgbmlsLCB0dGwpYCBoZXJlIGRpZDogcGF0aHMgQU5EIHN0YXR1c2VzIHJlYWQKLS0gYXMgIm5vIHRyYWZmaWMiIHdoaWxlIHJlcXVlc3RzIGFuZCBiYW5kd2lkdGggbG9va2VkIHBlcmZlY3QuIElzb2xhdGluZyB0aGVtCi0tIG1lYW5zIGEgZnV0dXJlIGVkaXQgY2FuIGxvc2UgYXQgbW9zdCBpdHMgb3duIG1ldHJpYy4KCmxvY2FsIGRheSAgPSB0b2RheSgpCmxvY2FsIGdwZnggPSAiZzoiIC4uIGhvc3QgLi4gIjoiIC4uIGRheSAuLiAiOiIKCi0tIDNhLiBHZW9JUC4gYGNjYCB3YXMgcmVzb2x2ZWQgb25jZSBhYm92ZSBhbmQgaXMgcmV1c2VkIGJ5IHRoZSByaW5nIGJ1ZmZlciBhbmQgdGhlCi0tIGxpdmUgcGlwZSwgc28gYSByZXF1ZXN0IGNvc3RzIGV4YWN0bHkgb25lIG1tZGIgbG9va3VwIG5vIG1hdHRlciBob3cgbWFueSBjb25zdW1lcnMKLS0gcmVwb3J0IGl0cyBjb3VudHJ5LgppZiBjYyB0aGVuCiAgICBwY2FsbChmdW5jdGlvbigpCiAgICAgICAgLS0gRGFpbHkgZ2VvIChmb3IgL2FuYWx5dGljcy9nZW8gZW5kcG9pbnQpCiAgICAgICAgYnVtcF9pbmRleGVkKGdwZnggLi4gY2MsIEQ0OEgsIGdwZnggLi4gImNuIiwgZ3BmeCAuLiAiY2k6IiwgY2MpCiAgICAgICAgLS0gUGVyLW1pbnV0ZSBnZW8gKGZvciB0aGUgdGltZS1zZXJpZXMgY291bnRyeSBicmVha2Rvd24pLiBJbmRleGVkIHBlciBNSU5VVEUsIHNvCiAgICAgICAgLS0gdGhlIHNjcmFwZXIgcmVhZHMgb25seSB0aGUgbWludXRlcyBpbiBpdHMgd2luZG93LgogICAgICAgIGxvY2FsIG1wZnggPSAiYzoiIC4uIGhvc3QgLi4gIjoiIC4uIG1pbnV0ZSAuLiAiOiIKICAgICAgICBidW1wX2luZGV4ZWQobXBmeCAuLiBjYywgRDI0SCwgbXBmeCAuLiAibiIsIG1wZnggLi4gImk6IiwgY2MpCiAgICBlbmQpCmVuZAoKLS0gM2IuIERpc3RpbmN0IHZpc2l0b3JzIOKAlCBhIENPVU5ULCBuZXZlciBhbiBpZGVudGl0eS4KLS0KLS0gVGhlIGFkZHJlc3MgaXMgaGFzaGVkIHdpdGggYSBzYWx0IHRoYXQgaXMgZ2VuZXJhdGVkIG9uIHRoaXMgYm94LCByb3RhdGVzIGRhaWx5LAotLSBhbmQgaXMgbmV2ZXIgd3JpdHRlbiBhbnl3aGVyZSBidXQgdGhpcyBzaGFyZWQgZGljdCwgc28gdGhlIG1hcmtlciBrZXlzIGFyZSBub3QKLS0gcmV2ZXJzaWJsZSB0byBhbiBJUCBhbmQgYXJlIHdvcnRobGVzcyB0aGUgbmV4dCBkYXkuIE9ubHkgdGhlIHJlc3VsdGluZyBjb3VudGVyCi0tIGlzIGV2ZXIgZmx1c2hlZCB0byBQb3N0Z3Jlczsgbm8gcGVyLXZpc2l0b3Igcm93IGV4aXN0cyBhdCBhbnkgbGF5ZXIuIFRoYXQgaXMKLS0gd2hhdCBsZXRzIHVzIHJlcG9ydCByZWFsIHZpc2l0b3IgbnVtYmVycyB3aGlsZSBzdGlsbCBub3QgY29sbGVjdGluZyBiZWhhdmlvdXJhbAotLSBhbmFseXRpY3Mgb24gYW55b25lJ3MgZW5kIHVzZXJzLgotLQotLSBQZXIgREFZLCBub3QgcGVyIG1pbnV0ZTogYSBwZXItbWludXRlIHNldCBpcyB+MTQ0MHggdGhlIGtleXMgZm9yIGEgbnVtYmVyCi0tIG5vYm9keSByZWFkcywgYW5kIHdvdWxkIGV2aWN0IHRoZSBjb3VudGVycyBpdCBleGlzdHMgdG8gYW5ub3RhdGUuCnBjYWxsKGZ1bmN0aW9uKCkKaWYgdmlzaXRvcnMgdGhlbgogICAgbG9jYWwgc2FsdF9rZXkgPSAidnNhbHQ6IiAuLiBkYXkKICAgIGxvY2FsIHNhbHQgPSB2aXNpdG9yczpnZXQoc2FsdF9rZXkpCiAgICBpZiBub3Qgc2FsdCB0aGVuCiAgICAgICAgLS0gRmlyc3Qgd3JpdGVyIHdpbnM7IGEgcmFjaW5nIHdvcmtlcidzIHNhZmVfYWRkIGZhaWxzIGFuZCBpdCByZS1yZWFkcy4gVGhlCiAgICAgICAgLS0gc2FsdCBvbmx5IGhhcyB0byBiZSB1bnByZWRpY3RhYmxlIGFuZCBzdGFibGUgZm9yIHRoZSBkYXkuCiAgICAgICAgc2FsdCA9IHRvc3RyaW5nKG5neC5ub3coKSkgLi4gdG9zdHJpbmcobWF0aC5yYW5kb20oMSwgMjE0NzQ4MzY0NykpCiAgICAgICAgbG9jYWwgb2sgPSB2aXNpdG9yczpzYWZlX2FkZChzYWx0X2tleSwgc2FsdCwgRDQ4SCkKICAgICAgICBpZiBub3Qgb2sgdGhlbiBzYWx0ID0gdmlzaXRvcnM6Z2V0KHNhbHRfa2V5KSBvciBzYWx0IGVuZAogICAgZW5kCiAgICAtLSBzYWZlX2FkZCBpcyB0aGUgZGVkdXA6IGl0IHN1Y2NlZWRzIE9OTFkgb24gdGhpcyB2aXNpdG9yJ3MgZmlyc3QgcmVxdWVzdAogICAgLS0gdG9kYXksIHNvIHRoZSBjb3VudGVyIGJlbG93IGluY3JlbWVudHMgZXhhY3RseSBvbmNlIHBlciBkaXN0aW5jdCB2aXNpdG9yLgogICAgbG9jYWwgbWFya2VyID0gInZkOiIgLi4gaG9zdCAuLiAiOiIgLi4gZGF5IC4uICI6IiAuLiBuZ3guY3JjMzJfbG9uZyhzYWx0IC4uIGlwKQogICAgaWYgdmlzaXRvcnM6c2FmZV9hZGQobWFya2VyLCAxLCBENDhIKSB0aGVuCiAgICAgICAgYW5hbHl0aWNzOmluY3IoZ3BmeCAuLiAidiIsIDEsIDAsIEQ0OEgpCiAgICBlbmQKZW5kCmVuZCkKCi0tIDNjLiBUb3AgcGF0aHMg4oCUIE9QVC1JTiwgbm9uLXN0YXRpYyBvbmx5LCBub3JtYWxpemVkIGFuZCBjYXJkaW5hbGl0eS1jYXBwZWQuCi0tCi0tIE9mZiB1bmxlc3MgdGhlIHByb2plY3QgdHVybmVkIGl0IG9uLCBiZWNhdXNlIHRoaXMgb25lIGJsb2NrIGlzIHRoZSBtb3N0IGV4cGVuc2l2ZSB0aGluZwotLSB0aGUgbG9nIGhhbmRsZXIgZG9lcy4gTWVhc3VyZWQgb24gdGhlIHNoaXBwZWQgZWRnZSBpbWFnZSwgcGVyIHJlcXVlc3Q6Ci0tCi0tICAgICBwYXRocyAod2hvbGUgYmxvY2spICAgICAgICAxLjcyIHVzICAgICAgPC0gNTclIG9mIHRoZSBjb3VudGVyIHBhdGgKLS0gICAgICAgb2Ygd2hpY2ggc3RyaW5nIHdvcmsgICAgIDEuMzggdXMgICAgICBub3JtYWxpemVfcGF0aCArIGlzX3N0YXRpY19hc3NldAotLSAgICAgbWludXRlIGJ1Y2tldHMgKDUgaW5jcikgICAgMC42MSB1cwotLSAgICAgY291bnRyeSAoMiBpbmNyKSAgICAgICAgICAgMC4yNCB1cwotLSAgICAgc3RhdHVzICgxIGluY3IpICAgICAgICAgICAgMC4xNCB1cwotLSAgICAgdGhpcyBmbGFnIHJlYWQgKDEgZ2V0KSAgICAgMC4wNyB1cwotLQotLSBTbyB0aGUgZ2F0ZSBjb3N0cyAwLjA3IHVzIGFuZCBzYXZlcyAxLjcyIHVzIOKAlCB0aGUgY291bnRlciBwYXRoIGRyb3BzIGZyb20gfjMuMCB1cyB0bwotLSB+MS4zNSB1cyB3aXRoIHBhdGhzIG9mZi4gSXQgaXMgYWxzbyB0aGUgaGlnaGVzdC1jYXJkaW5hbGl0eSBkaW1lbnNpb24gKHVwIHRvCi0tIFBBVEhfQ0FSRElOQUxJVFlfQ0FQIGtleXMgcGVyIGRvbWFpbiBwZXIgZGF5LCBhZ2FpbnN0IH4yMDAgY291bnRyaWVzIGFuZCBhIGZldyBkb3plbgotLSBzdGF0dXNlcykgYW5kIHRoZSBsYXJnZXN0IGNvbHVtbiBpbiB0aGUgZGFpbHkgcm9sbHVwLgotLQotLSBBYnNlbnQgZmxhZyA9IG9mZi4gQSBib3ggd2hvc2UgZGljdCB3YXMganVzdCByZXN0YXJ0ZWQgdGhlcmVmb3JlIGNvbGxlY3RzIG5vdGhpbmcgdW50aWwKLS0gdGhlIEFQSSByZS1wdXNoZXMsIHdoaWNoIGlzIHRoZSBzYWZlIGRpcmVjdGlvbjogbm8gZGF0YSBiZWF0cyBkYXRhIG5vYm9keSBhc2tlZCB0byBwYXkKLS0gZm9yLiBUaGUgREIgaXMgdGhlIHNvdXJjZSBvZiB0cnV0aCBhbmQgcmUtcHVzaGVzIG9uIGV2ZXJ5IHJvdXRlIGFwcGx5Lgpsb2NhbCBjb2xsZWN0X3BhdGhzID0gcnVsZXNfZGljdCBhbmQgcnVsZXNfZGljdDpnZXQoImNmZzoiIC4uIGhvc3QgLi4gIjpwYXRocyIpCgpwY2FsbChmdW5jdGlvbigpCmlmIGNvbGxlY3RfcGF0aHMgYW5kIG5vdCBpc19zdGF0aWNfYXNzZXQodXJpKSB0aGVuCiAgICAtLSBIb2lzdGVkOiBub3JtYWxpemVfcGF0aCBpcyB0aGUgc2luZ2xlIG1vc3QgZXhwZW5zaXZlIGNhbGwgaW4gdGhpcyBoYW5kbGVyICh+MS40IHVzCiAgICAtLSBvZiBzdHJpbmcgd29yayksIHNvIGl0IHJ1bnMgZXhhY3RseSBvbmNlIGV2ZW4gdGhvdWdoIGJvdGggdGhlIGNvdW50ZXIga2V5IGFuZCB0aGUKICAgIC0tIGluZGV4IHNsb3QgbmVlZCBpdHMgcmVzdWx0LgogICAgbG9jYWwgbm9ybSA9IG5vcm1hbGl6ZV9wYXRoKHVyaSkKICAgIGxvY2FsIHBhdGhfa2V5ID0gZ3BmeCAuLiAicDoiIC4uIG5vcm0KICAgIC0tIGluY3ItdGhlbi1hZGQ6IHRoZSBob3QgcGF0aCBpcyBPTkUgaGFzaCBoaXQgb24gYW4gZXhpc3Rpbmcga2V5LiBgaW5jcmAgd2l0aAogICAgLS0gbm8gaW5pdCByZXR1cm5zIG5pbCBmb3IgYW4gYWJzZW50IGtleSwgd2hpY2ggZG91YmxlcyBhcyB0aGUgZXhpc3RlbmNlIHByb2JlLAogICAgLS0gc28gb25seSBhIHBhdGggdW5zZWVuIHRvZGF5IHJlYWNoZXMgdGhlIGNhcCBjaGVjayBiZWxvdy4KICAgIC0tCiAgICAtLSBEZWxpYmVyYXRlbHkgbm8gaW5pdF90dGwgaGVyZTogc2hkaWN0IHJlamVjdHMgaW5pdF90dGwgdW5sZXNzIGluaXQgaXMgYWxzbwogICAgLS0gZ2l2ZW4gKCInaW5pdF90dGwnIG11c3QgYmUgdXNlZCB3aXRoICdpbml0JyIpLCBhbmQgdGhhdCByYWlzZXMgYSBMdWEgZXJyb3IKICAgIC0tIHdoaWNoIGFib3J0cyB0aGUgd2hvbGUgbG9nIGhhbmRsZXIg4oCUIHRha2luZyB0aGUgc3RhdHVzIGNvdW50ZXJzIGJlbG93IGRvd24KICAgIC0tIHdpdGggaXQuIFRoZSBUVEwgaXMgc2V0IGJ5IHRoZSBzYWZlX2FkZCBvbiB0aGUgY3JlYXRpbmcgcmVxdWVzdCBpbnN0ZWFkLgogICAgaWYgbm90IGFuYWx5dGljczppbmNyKHBhdGhfa2V5LCAxKSB0aGVuCiAgICAgICAgbG9jYWwgZGlzdGluY3QgPSBhbmFseXRpY3M6aW5jcihncGZ4IC4uICJwbiIsIDEsIDAsIEQ0OEgpIG9yIDAKICAgICAgICBpZiBkaXN0aW5jdCA+IFBBVEhfQ0FSRElOQUxJVFlfQ0FQIHRoZW4KICAgICAgICAgICAgYW5hbHl0aWNzOmluY3IoZ3BmeCAuLiAicDpvdGhlciIsIDEsIDAsIEQ0OEgpCiAgICAgICAgZWxzZQogICAgICAgICAgICAtLSBgcG5gIHdhcyBhbHJlYWR5IHRoZSBkaXN0aW5jdC1wYXRoIGNvdW50ZXIsIHNvIHRoZSBzbG90cyBqdXN0IGdpdmUgaXQgYW4KICAgICAgICAgICAgLS0gZW51bWVyYWJsZSBzaWRlLiBTdG9yZWQgV0lUSE9VVCB0aGUgInA6IiBwcmVmaXg7IHRoZSByZWFkZXIgYWRkcyBpdCBiYWNrLgogICAgICAgICAgICBpZiBhbmFseXRpY3M6c2FmZV9hZGQocGF0aF9rZXksIDEsIEQ0OEgpIHRoZW4KICAgICAgICAgICAgICAgIGFuYWx5dGljczpzZXQoZ3BmeCAuLiAicGk6IiAuLiBkaXN0aW5jdCwgbm9ybSwgRDQ4SCkKICAgICAgICAgICAgZW5kCiAgICAgICAgZW5kCiAgICBlbmQKZW5kCmVuZCkKCi0tIDNkLiBTdGF0dXMtY29kZSBtaXguIEJvdW5kZWQgYnkgY29uc3RydWN0aW9uIChhIGZldyBkb3plbiBjb2RlcykuCnBjYWxsKGZ1bmN0aW9uKCkKICAgIGJ1bXBfaW5kZXhlZChncGZ4IC4uICJzOiIgLi4gc3RhdHVzLCBENDhILCBncGZ4IC4uICJzbiIsIGdwZnggLi4gInNpOiIsIHN0YXR1cykKZW5kKQoKLS0g4pSA4pSAIDQuIFJhdyByZXF1ZXN0IHJpbmcgYnVmZmVyIChhbHNvIHRoZSBsaXZlIFNTRSBzb3VyY2UpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAotLQotLSBgc2VxYCBpcyBjbGFpbWVkIEJFRk9SRSBlbmNvZGluZyBzbyB0aGUgc3RvcmVkIEpTT04gY2FuIGNhcnJ5IGEgZGV0ZXJtaW5pc3RpYwotLSBpZCAoYHtob3N0fTp7c2VxfWApLiBUaGF0IGlkIGlzIHRoZSBkZWR1cCBrZXkgZXZlcnl3aGVyZSBkb3duc3RyZWFtOiAvbG9ncy9yZWNlbnQKLS0gcmV0dXJucyB0aGVzZSBlbnRyaWVzIHZlcmJhdGltLCBhbmQgcGlwZV9zdHJlYW0ubHVhIHN0cmVhbXMgdGhlIHNhbWUgc2xvdHMgbGl2ZSwKLS0gc28gdGhlIHNhbWUgcmVxdWVzdCByZWFjaGVzIHRoZSBjbGllbnQgd2l0aCBvbmUgc3RhYmxlIGlkIGluc3RlYWQgb2YgYSBmcmVzaAotLSByYW5kb20gb25lIHBlciBzb3VyY2UuIGBpbmNyYCB3aXRoIGluaXQgMCBuZXZlciByZXR1cm5zIG5pbCBoZXJlOyBndWFyZCBhbnl3YXkKLS0gc28gYSBzaGRpY3QgaGljY3VwIGNhbid0IGluZGV4IGEgbmlsIGludG8gdGhlIHNsb3Qga2V5LgoKcGNhbGwoZnVuY3Rpb24oKQogICAgbG9jYWwgc2VxID0gcmVxdWVzdF9kYXRhOmluY3IoInJsb2c6IiAuLiBob3N0IC4uICI6c2VxIiwgMSwgMCkKICAgIGlmIG5vdCBzZXEgdGhlbiByZXR1cm4gZW5kCiAgICBsb2NhbCBva19qLCBqID0gcGNhbGwoY2pzb24uZW5jb2RlLCB7CiAgICAgICAgaWQgICAgID0gaG9zdCAuLiAiOiIgLi4gc2VxLAogICAgICAgIGlwICAgICA9IGlwLAogICAgICAgIC0tIG5pbCBpcyBzaW1wbHkgb21pdHRlZCBieSBjanNvbiwgc28gYSBib3ggd2l0aCBubyBHZW9JUCB3cml0ZXMgdGhlIHNhbWUgc2hhcGUKICAgICAgICAtLSBtaW51cyB0aGlzIGtleSByYXRoZXIgdGhhbiBhIG51bGwgdGhlIHJlYWRlciBoYXMgdG8gc3BlY2lhbC1jYXNlLgogICAgICAgIGNvdW50cnkgPSBjYywKICAgICAgICB0cyAgICAgPSB0cywKICAgICAgICBtZXRob2QgPSBtZXRob2QsCiAgICAgICAgc3RhdHVzID0gc3RhdHVzLAogICAgICAgIHVyaSAgICA9IHVyaSwKICAgICAgICB1YSAgICAgPSB1YSwKICAgICAgICBid19pbiAgPSByZXFfbGVuLAogICAgICAgIGJ3X291dCA9IGJ5dGVzLAogICAgICAgIHJ0ICAgICA9IHJ0LAogICAgfSkKICAgIGlmIG9rX2ogYW5kIGogdGhlbgogICAgICAgIHJlcXVlc3RfZGF0YTpzZXQoInJsb2c6IiAuLiBob3N0IC4uICI6IiAuLiAoc2VxICUgUklORyksIGosIEQxSCkKICAgIGVuZAplbmQpCg==",
41
41
  "webhook_handler.lua": "LS0gd2ViaG9va19oYW5kbGVyLmx1YQotLSBIYW5kbGVzIGluY29taW5nIHdlYmhvb2sgZXZlbnRzIGZvcndhcmRlZCBmcm9tIHRoZSBTYWFTIGVkZ2UuCi0tIEludGVybmFsIG1hbmFnZW1lbnQgcG9ydCBvbmx5ICgxMjcuMC4wLjE6OTE0NSkuCi0tCi0tIFJvdXRlczoKLS0gICBQT1NUIC9faG9va3MvcHVzaCAgICAgICAgICAtIHJlY2VpdmUgYSBmb3J3YXJkZWQgR2l0SHViIHB1c2ggZXZlbnQKLS0gICBHRVQgIC9faG9va3MvcGVuZGluZyAgICAgICAtIGZldGNoIHN0b3JlZCBldmVudHMgKGZvciBsb2NhbCBhcHAgcG9sbGluZykKLS0gICBQT1NUIC9faG9va3MvYWNrICAgICAgICAgICAtIGFja25vd2xlZGdlIGNvbnN1bWVkIGV2ZW50cwotLQotLSBCZWhhdmlvciBvbiBQT1NUIC9faG9va3MvcHVzaDoKLS0gICAxLiBUcnkgdG8gcHJveHkgdG8gYSBsb2NhbCBPcGVuc2hpcCBBUEkgKGNvbmZpZ3VyYWJsZSB2aWEgWC1PcGVuc2hpcC1VcmwgaGVhZGVyKQotLSAgIDIuIElmIE9wZW5zaGlwIGlzIG5vdCByZWFjaGFibGUsIHN0b3JlIHRoZSBldmVudCBpbiBzaGFyZWQgZGljdCBmb3IgbGF0ZXIgcG9sbGluZwoKbG9jYWwgY2pzb24gPSByZXF1aXJlICJjanNvbi5zYWZlIgoKbG9jYWwgd2ViaG9va19ldmVudHMgPSBuZ3guc2hhcmVkLndlYmhvb2tfZXZlbnRzCmxvY2FsIHVyaSAgICAgICAgICAgID0gbmd4LnZhci51cmkKbG9jYWwgbWV0aG9kICAgICAgICAgPSBuZ3gucmVxLmdldF9tZXRob2QoKQoKbG9jYWwgZnVuY3Rpb24ganNvbl9yZXNwb25zZShkYXRhLCBjb2RlKQogICAgbmd4LnN0YXR1cyA9IGNvZGUgb3IgMjAwCiAgICBuZ3guaGVhZGVyWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIgogICAgbmd4LnNheShjanNvbi5lbmNvZGUoZGF0YSkpCiAgICByZXR1cm4gbmd4LmV4aXQobmd4LnN0YXR1cykKZW5kCgotLSDilIDilIAgUE9TVCAvX2hvb2tzL3B1c2gg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi0tIFJlY2VpdmVzIGZvcndhcmRlZCB3ZWJob29rIHBheWxvYWQgZnJvbSBTYWFTLgotLSBIZWFkZXJzOgotLSAgIFgtT3BlbnNoaXAtVXJsOiBodHRwOi8vMTI3LjAuMC4xOjM0NTYgKGlmIE9wZW5zaGlwIHJ1bnMgb24gdGhpcyBzZXJ2ZXIpCi0tICAgWC1Ib29rLUlkOiB0aGUgc3Vic2NyaXB0aW9uIGhvb2tJZCAoZm9yIGNvcnJlbGF0aW9uKQoKaWYgdXJpID09ICIvX2hvb2tzL3B1c2giIGFuZCBtZXRob2QgPT0gIlBPU1QiIHRoZW4KICAgIG5neC5yZXEucmVhZF9ib2R5KCkKICAgIGxvY2FsIGJvZHkgPSBuZ3gucmVxLmdldF9ib2R5X2RhdGEoKQogICAgaWYgbm90IGJvZHkgdGhlbgogICAgICAgIHJldHVybiBqc29uX3Jlc3BvbnNlKHsgZXJyb3IgPSAiZW1wdHkgYm9keSIgfSwgNDAwKQogICAgZW5kCgogICAgbG9jYWwgb3BlbnNoaXBfdXJsID0gbmd4LnJlcS5nZXRfaGVhZGVycygpWyJ4LW9wZW5zaGlwLXVybCJdCgogICAgLS0gSWYgT3BlbnNoaXAgcnVucyBvbiB0aGlzIHNlcnZlciwgcHJveHkgZGlyZWN0bHkKICAgIGlmIG9wZW5zaGlwX3VybCBhbmQgb3BlbnNoaXBfdXJsIH49ICIiIHRoZW4KICAgICAgICBsb2NhbCBodHRwID0gcmVxdWlyZSAicmVzdHkuaHR0cCIKICAgICAgICBsb2NhbCBodHRwYyA9IGh0dHAubmV3KCkKICAgICAgICBodHRwYzpzZXRfdGltZW91dCg1MDAwKQoKICAgICAgICBsb2NhbCB0YXJnZXQgPSBvcGVuc2hpcF91cmwgLi4gIi9hcGkvd2ViaG9va3MvcHVzaCIKICAgICAgICBsb2NhbCByZXMsIGVyciA9IGh0dHBjOnJlcXVlc3RfdXJpKHRhcmdldCwgewogICAgICAgICAgICBtZXRob2QgID0gIlBPU1QiLAogICAgICAgICAgICBib2R5ICAgID0gYm9keSwKICAgICAgICAgICAgaGVhZGVycyA9IHsKICAgICAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtSG9vay1JZCJdICAgID0gbmd4LnJlcS5nZXRfaGVhZGVycygpWyJ4LWhvb2staWQiXSBvciAiIiwKICAgICAgICAgICAgfSwKICAgICAgICB9KQoKICAgICAgICBpZiByZXMgYW5kIHJlcy5zdGF0dXMgPCA1MDAgdGhlbgogICAgICAgICAgICAtLSBPcGVuc2hpcCBoYW5kbGVkIGl0ICgyeHggb3IgNHh4KQogICAgICAgICAgICByZXR1cm4ganNvbl9yZXNwb25zZSh7IG9rID0gdHJ1ZSwgcHJveGllZCA9IHRydWUsIHN0YXR1cyA9IHJlcy5zdGF0dXMgfSkKICAgICAgICBlbmQKCiAgICAgICAgLS0gT3BlbnNoaXAgdW5yZWFjaGFibGUgb3IgZXJyb3JlZCAtIGZhbGwgdGhyb3VnaCB0byBzdG9yZQogICAgZW5kCgogICAgLS0gU3RvcmUgZm9yIGxhdGVyIHBvbGxpbmcgYnkgbG9jYWwvZGVza3RvcCBhcHAKICAgIGxvY2FsIGV2ZW50X2lkID0gbmd4Lm5vdygpIC4uICI6IiAuLiBtYXRoLnJhbmRvbSgxMDAwMDAsIDk5OTk5OSkKICAgIGxvY2FsIGV2ZW50ID0gY2pzb24uZW5jb2RlKHsKICAgICAgICBpZCAgICAgICA9IGV2ZW50X2lkLAogICAgICAgIGhvb2tfaWQgID0gbmd4LnJlcS5nZXRfaGVhZGVycygpWyJ4LWhvb2staWQiXSBvciAiIiwKICAgICAgICBwYXlsb2FkICA9IGJvZHksCiAgICAgICAgcmVjZWl2ZWQgPSBuZ3gubm93KCksCiAgICB9KQoKICAgIC0tIFVzZSBhIHNsb3QtYmFzZWQgcmluZyBidWZmZXIgKG1heCAyMDAgZXZlbnRzKQogICAgbG9jYWwgbWF4X2V2ZW50cyA9IDIwMAogICAgbG9jYWwgaWR4ID0gd2ViaG9va19ldmVudHM6aW5jcigiX2lkeCIsIDEsIDApIG9yIDAKICAgIGxvY2FsIHNsb3QgPSAoaWR4ICUgbWF4X2V2ZW50cykKICAgIHdlYmhvb2tfZXZlbnRzOnNldCgiZXZ0OiIgLi4gc2xvdCwgZXZlbnQsIDM2MDApIC0tIDFoIFRUTAogICAgd2ViaG9va19ldmVudHM6c2V0KCJfY291bnQiLCBtYXRoLm1pbihpZHgsIG1heF9ldmVudHMpKQoKICAgIHJldHVybiBqc29uX3Jlc3BvbnNlKHsgb2sgPSB0cnVlLCBzdG9yZWQgPSB0cnVlLCBldmVudF9pZCA9IGV2ZW50X2lkIH0pCmVuZAoKLS0g4pSA4pSAIEdFVCAvX2hvb2tzL3BlbmRpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi0tIFJldHVybnMgc3RvcmVkIHdlYmhvb2sgZXZlbnRzIGZvciBsb2NhbCBhcHAgdG8gY29uc3VtZS4KCmlmIHVyaSA9PSAiL19ob29rcy9wZW5kaW5nIiBhbmQgbWV0aG9kID09ICJHRVQiIHRoZW4KICAgIGlmIG5vdCB3ZWJob29rX2V2ZW50cyB0aGVuCiAgICAgICAgcmV0dXJuIGpzb25fcmVzcG9uc2UoeyBldmVudHMgPSB7fSB9KQogICAgZW5kCgogICAgbG9jYWwgY291bnQgPSB3ZWJob29rX2V2ZW50czpnZXQoIl9jb3VudCIpIG9yIDAKICAgIGxvY2FsIGlkeCAgID0gd2ViaG9va19ldmVudHM6Z2V0KCJfaWR4Iikgb3IgMAogICAgbG9jYWwgZXZlbnRzID0ge30KCiAgICAtLSBSZWFkIGFsbCBzdG9yZWQgZXZlbnRzIChuZXdlc3QgZmlyc3QpCiAgICBsb2NhbCBtYXhfZXZlbnRzID0gMjAwCiAgICBsb2NhbCBzdGFydCA9IG1hdGgubWF4KDAsIGlkeCAtIGNvdW50KQogICAgZm9yIGkgPSBzdGFydCwgaWR4IC0gMSBkbwogICAgICAgIGxvY2FsIHNsb3QgPSBpICUgbWF4X2V2ZW50cwogICAgICAgIGxvY2FsIHJhdyA9IHdlYmhvb2tfZXZlbnRzOmdldCgiZXZ0OiIgLi4gc2xvdCkKICAgICAgICBpZiByYXcgdGhlbgogICAgICAgICAgICBsb2NhbCBwYXJzZWQgPSBjanNvbi5kZWNvZGUocmF3KQogICAgICAgICAgICBpZiBwYXJzZWQgdGhlbgogICAgICAgICAgICAgICAgZXZlbnRzWyNldmVudHMgKyAxXSA9IHBhcnNlZAogICAgICAgICAgICBlbmQKICAgICAgICBlbmQKICAgIGVuZAoKICAgIHJldHVybiBqc29uX3Jlc3BvbnNlKHsgZXZlbnRzID0gZXZlbnRzIH0pCmVuZAoKLS0g4pSA4pSAIFBPU1QgL19ob29rcy9hY2sg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi0tIEFja25vd2xlZGdlIGV2ZW50cyBoYXZlIGJlZW4gY29uc3VtZWQgLSBjbGVhcnMgdGhlIHN0b3JlLgoKaWYgdXJpID09ICIvX2hvb2tzL2FjayIgYW5kIG1ldGhvZCA9PSAiUE9TVCIgdGhlbgogICAgaWYgd2ViaG9va19ldmVudHMgdGhlbgogICAgICAgIHdlYmhvb2tfZXZlbnRzOmZsdXNoX2FsbCgpCiAgICAgICAgd2ViaG9va19ldmVudHM6Zmx1c2hfZXhwaXJlZCgpCiAgICBlbmQKICAgIHJldHVybiBqc29uX3Jlc3BvbnNlKHsgb2sgPSB0cnVlIH0pCmVuZAoKLS0g4pSA4pSAIEZhbGxiYWNrIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgApyZXR1cm4ganNvbl9yZXNwb25zZSh7IGVycm9yID0gIm5vdCBmb3VuZCIgfSwgNDA0KQo="
42
42
  };
43
43