diff --git a/docs/evidence/2026-10-11-purpose-image-release/README.md b/docs/evidence/2026-10-11-purpose-image-release/README.md index a21f828..fa5bf5d 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/README.md +++ b/docs/evidence/2026-10-11-purpose-image-release/README.md @@ -1,9 +1 @@ -# Exact published purpose overlay and unapproved native release packet - -Actual CI task11484/run3 at3e4bcb26 published immutable763c. The registry proof, installedUID/mode/purpose checks, full scan/SBOM and actualbase comparison are retained. The full scan contains1fixable inheritedMEDIUM,0HIGH/CRITICAL; see owner follow-through/T05. Legacy serialization differences are disclosed. - -This stage prepares owner admission/service source candidates, protected native backup/restore protocol and20document offline-valid informed-decision memo. Native workload remains7f5/config6c. No native backup/export/restore, image change or human approval occurred. Initial failed CI/native preflight evidence remains in owner history. The original36path7c packet is fully archived and remains refinement-required, not approved. The amended gate adds pre-open stdlib readonlyschema5/integrity/count checks, explicitlocal/remote optimizationrefusal and actualCM/PVC UID/content/custody seals. The immutable original native capture stays sealed; future preflight requires unique output outside the sealed packet and owner source tree. - -The memo directly attaches exact execution-bundle.json in place of the rawscan, with unchanged rawscan/SBOM/base scan hash-linked by published-verification.json; twenty documents remain under256KiB; source/image receipt binds raw evidence filenames and hashes. Full owner source manifest includes all raw evidence and helper/tests. Source preparation or local checks do not approve native execution. - -The original78pathb1 packet is archived under initial-b1e3e66b with original manifest and exact source map. No previously recorded capture or product/Platform review is relabelled as review of this new packet. Exact23path mechanical helper review agreement is separate from founder approval. The all-phase deadline, isolated UID0 initializer, four Git blobs, rollback-verify and native_provider=false limitation are explicitly refined in the new decision packet/protocol. +Version2 rescue packet: original native backup COMPLETE, copy UNCERTAIN beforelocalfile, original image unchanged. New exactfounderacceptance required; no version2 nativeaction. See decision-packet/protocol/bundle; originalapproved version1 sourcepacket preserved initial-approved-bc6494cd. Rawscan/SBOM/base imageevidence unchanged and hash-bound. diff --git a/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md b/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md new file mode 100644 index 0000000..6f91a72 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md @@ -0,0 +1,17 @@ +# Version2 protected existing-snapshot rescue — prepared, unapproved + +Original approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed. + +Fresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation. + +Fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase. + +Before rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome. + +Offline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup. + +Four committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension. + +Image763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation. + +Selected route is existing snapshot rescue, not another drill backup. Original c01b six-file source-only diagnosis proposed alternatives; this version2 adds the exact executable route, sources, journal guards and human packet. diff --git a/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json b/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json new file mode 100644 index 0000000..8d8cf55 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json @@ -0,0 +1,27 @@ +{ + "state": "source-only-unapproved-repair", + "original_source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "original_receipts": { + "/tmp/infd-approved-drill-backup.json": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "/tmp/infd-approved-drill-copy.json": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56" + }, + "confirmed_metadata_reported_by_root": { + "main_bytes": 19537920, + "main_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "wal_bytes": 0, + "shm_bytes": 32768, + "private_uid": 10001, + "mode": "0600", + "nlink": 1, + "database_opened_for_capture": false + }, + "tests_passed": 5, + "test_transport": "mocked SQLite; no database/admin/native commands", + "source_files_changed_on_owner": false, + "original_uncertain_phase_retried": false, + "native_sidecars_deleted": false, + "native_database_read": false, + "native_backup_copy_restore_or_workload_action": false, + "new_founder_approval_required": true, + "recovery_actuator_implemented": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md b/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md index 11fb110..e9dd741 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md +++ b/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md @@ -1,41 +1,13 @@ -# Informed Decision purpose overlay release +# Informed Decision version2 existing-snapshot rescue and image release -## Requested decision +Approve the exact source-refined recovery of the failed drill-copy and conditional remaining backup/drill/Deployment-only image rollout. This is memo version2 in the same proposal/trial, requiring NEW founder acceptance; original version1 acceptance is retained and cannot authorize changed helperbytes. -Approve the exact purpose-only image rollout and protected real-data backup/restore protocol for the existing Informed Decision service on railiance01. This request is separate from the already approved config-only repair. Only the existing Deployment image changes through the owner's manual Argo workflow, with prune disabled. Runtime ConfigMap `informed-decision-runtime-6c221878d051`, schema5, PVC, credentials, audience, policies, registries, access, replica1 and Recreate strategy remain fixed. Execute by 2026-10-12T23:59:59Z, after refreshed sealed-source/UID/configuration checks and backup/restore gates. All phases, including recovery and verification, must begin before this deadline. If the window is exhausted, stop and obtain a fresh founder decision; this may delay recovery. No timer/controller automatically changes the released image. +Original source bc6494cd completed the protected native drill-backup, then copy failed before any localfile. Metadata-only verification proves unchanged main19537920bytes/SHA8756..., WAL0/privateSHM32768. The original reader could leave SHM indexing because its connection context manager did not close. The correction explicitlycloses all readers and uses immutable reads ONLY for a proven frozen closed-main snapshot, not live or writableclone. SHM stays unchanged; nonzeroWAL/hash/identity drift stops rescue. -## Artifact and known finding +Distinct drill-copy-rescue-r1/newlinkedjournal preserves original UNCERTAINcopy and exact journalhash/attempts. No oldretry/overwrite, no newdrillbackup. Require originalCOMPLETEbackup/UNCERTAINcopy only, absentlocalfiles/restorevolume, originalnativePodUID/currentoldimage+sourcepin and allCM/PVC/Deployment seals. Copy snapshotbytes only into a newprivate0600file. Remainingorderedphases explicitly consume COMPLETErescueresult; one isolated UID0/CAP_CHOWN-only NEWvolume initializer then UID10001 pre-open/admin/post-admin checks proves real-data compatibility before cutover. No host/nativePVC/runtimeconfig/token mounts; no service startup. Any attempted failure/ambiguity is durable and cannotretry. -Actual owner CI task11484/run3 published immutable image `sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a` from source `3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168`. Anonymous registry verification preserves all eight base compressed blobs/rootfs layers and adds only policy.py with exact source hash and mode0644. Legacy-builder media-type/default config serialization differences are recorded; the runtime semantics remain unchanged. Pulled published image executes as UID10001/GID10001 and passes ten installed checks: two supported binding forms, eight advisory/malformed refusals. Tests use synthetic transport and do not claim new native PDP authorization proof. The two failed CI attempts remain in the same trial history. +Image763c from actualCI3e4bcb26 remains unchanged8base layers pluspolicy.py; legacyserialization differences disclosed. ActualinstalledUID10001/10purposevariants pass; native_provider=false/synthetictransport is not actualPDPauthority proof, which remains separateT04gate. Actualfull44packagescan0HIGH/CRITICAL, ONEfixableinheritedMEDIUMzlibCVE-2026-85091(1.3.2-r0→r1), identicalbasefinding. Explicittemporarypermission for this finding is requested again, with ownerT05/riskrecorddueOct18; no zero-CVE/RiskNexusgradeclaim. Rawscan/SBOM/base scan stay unchangedhashbound via publishedreceipt; exacthelperandoriginalcount-onlyreceipts directlybundle-bound within20docs. -Actual unfiltered pinned scanner/DB evidence covers44packages: zero HIGH/CRITICAL, **one fixable MEDIUM**, CVE-2026-85091, zlib1.3.2-r0 fixed in1.3.2-r1. Actual current-base scan has the identical finding. Approving this packet explicitly permits this inherited finding during this narrow purpose release; it is not a RiskNexus estate risk grade or zero-CVE claim. Owner record INFD-RISK-20261011-ZLIB-85091 and live task INFD-WP-0009-T05 require separate base refresh and native approval, reviewed by2026-10-18. That review date is manual follow-through, with no auto-controller claim. Scanner notes Alpine3.24 absent EOL list; OS vulnerability detection ran against38OSpackages. Unknown vulnerabilities remain outside snapshot knowledge. +After rescue+offlinegates, distinctcutoverbackup/copy and manualArgoDeployment-only image763c/prune=false remain conditional. FourcommittedKustomizeblobs/currentfinalsourceHEAD/helpers/casehashes match; automated{} or overrides refuse. Config6c/schema5/PVC/identity/policies/replica1Recreate stayfixed. Rollbackdoesnotneed Readycandidate or itsDBexec; oldimageReady/scopedoperation/schema5currentDB is a separateproof. Preserve latestliveDB/allnewcommits and alluncertainoutcomes; neverrestoreolderbackup overlaterrecords. -## Native baseline and gates - -Original read-only capture01:25:38Z: existing Deployment UIDa588e10a, Ready1, image7f5c, unchanged runtime6c; native admission preserves the full configuration plus exactly the proposed image. Clientdiff returns1. Requests3460/4000mCPU86%, memory9472Mi59%; refresh before release. Existing Argo Application UID499868f2 is manual, target7db8485, Healthy with pre-existing OutOfSync status. Do not treat a scoped Deployment release as full-app reconciliation. Preserve its tracking-id; no unrelated resource sync/prune/adoption. - -The refined read-only helper binds original source/helper/render/baseline hashes and actual immutable ConfigMap/PVC UIDs, runtime-data checksum and bound volume identity, explicitly refuses optimized interpreters, checks exact fresh live UID/configuration and admission, and writes a separate execution receipt outside this sealed packet. Failed initial raw Kustomize metadata check is retained: direct kubectl apply would drop Argo tracking-id. The reviewed selected Deployment explicitly retains that existing ID, matching Argo ownership. Any unrelated drift, different UID, altered admission, unavailable protected backup capacity, uncertain backup, restore mismatch or unhealthy baseline stops the release. - -## Protected backup and release - -Before **any** native source or offline-restored Store/admin open, use the attached stdlib SQLite mode=ro/query_only checker to require schema5, integrity=ok and count-only baseline. The admin automatically migrates oldschemas, so a post-open report alone cannot prove no migration. Refuse other schemas before admin. Then use the existing owner admin's SQLite backup API, not a raw copy of the live database/WAL. Protect directories0700/files0600, owned by10001. Retain independently protected off-cluster snapshot custody and only count/hash receipts. No database contents, caller tokens, requester Secret or runtime credential files enter Git, State Hub, logs or this packet. Native backup and offline real-data restore have not yet occurred. Use an isolated private disposable copy, networknone and no runtime config/token mounts, run the pre-open checker and exact offline `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite` after it passes, comparing frozen snapshot counts without service startup, then clean only the disposable restored copy. Retain the original snapshot. The attached protocol binds case-specific paths and fail-closed capacity/custody checks. - -Refresh a consistent online snapshot immediately before image-only cutover. This protocol does not assert traffic/dispatcher quiescence. Current and candidate share schema5 and unchanged store code; rollback retains the latest live database and all new/uncertain evidence. Stop the old writer before the new one with existing Recreate and single-writer lock. Do not restore an older snapshot over later writes, discard unresolved external effects, scale other workloads, change policies/identity/custody, or create human dispositions to make checks green. - -Pin the existing Application to the exact owner commit containing the approved candidate source hashes, and manually sync only Deployment/informed-decision with prune=false. Verify actualimage/module/mode/UID, health/readiness and installed purpose refusals on the real placement; explicitly distinguish synthetic-transport checks from actual provider evidence. Existing native binding/lifecycle behavior must remain available. If unhealthy or verification fails, return Application source to7db8485 and scoped-sync prior same-schema image7f5c, preserving current evidence database; retain failed outcomes. Any data recovery beyond this same-schema image rollback is a separate founder decision. - -## Alternatives and estimates - -Proceed with this narrow release plus explicit inherited-medium follow-through, or defer and prepare a separate base/dependency refresh before any release. No additional recurring hosting is proposed: estimated incremental infrastructure EUR0, with private storage and attended engineering/recovery time unpriced. Risks include a brief Recreate interruption, private backup custody errors, caller refusal when advisory responses were improperly treated as binding, and the disclosed inherited finding. This decision does not promote agent autonomy or grant unrelated work. - -## Independent review refinements - -The initial36path/20document packet at manifest7c6738b3 and submissionac41c8ae is preserved in source preparation evidence, with the failed/conditional review. Independent Platform review identified admin auto-migration, optimization bypass, and actual same-name ConfigMap/PVC replacement gaps. The amended packet adds pre-open stdlib read-only schema/integrity/count gates, explicit local/remote optimization refusal, and independently sealed actual native config/PVC custody checks. These are refinements in the same proposal/trial, with no original or amended founder approval claimed. - -## Mechanically bound helper and recovery refinement - -The directly attached execution-bundle.json binds exact supervised helper sources, plan, tests and PENDING authority template. It verifies all four committed owner Kustomize inputs and rejects present automated:{} as well as source overrides. Root must freshly authenticate the exact founder native disposition before every phase; receipt bookkeeping is not an autonomous signed grant. The same proposal/trial preserves the earlier36path7c packet, amended78pathb1 packet and original11file653 helper plus conditional review findings. - -The offline copy uses one UID0/CAP_CHOWN-only initializer confined to the NEW nonce-bound local volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/livePVC/config/token mounts. All following pre-open/admin/post-open checks are UID10001. Post-admin readonly schema5/integrity/counts must match the frozen snapshot and original snapshot SHA must remain unchanged. Rollback dispatch never requires the failing candidate to be Ready or opens its database; seals/source/image pair/admission CAS still gate it. A separate rollback-verify proves recovered old-image Ready1/scoped operation/schema5 retained-current-DB integrity. Same-phase retries are refused after ambiguous outcomes. - -Raw scan/SBOM/base-scan bytes remain retained unchanged, hash-bound by the directly attached published-verification receipt; the bundle replaces only the direct raw scan attachment to stay within twenty documents. Known fixable inherited MEDIUM and T05 follow-through remain visible. Ten installed synthetic checks, including those later on actual placement, explicitly have native_provider=false. Actual provider/PDP authority evidence is a distinct T04 completion gate and is not supplied by these checks. Source preparation basis e0359bcb6cdfad9ab3e868054121fe0cebec2d68 plus9268c9ac0bbee508fe35c0b90dcefef4c24da2f5 is recorded; the final applied owner commit must be pinned before execution. +Allphases including rescue/recovery/verify mustbegin beforeOct12 23:59:59Z; expiryrequiresnewdecision and maydelayrecovery. No automaticexpirycontroller. Freshroot-authenticated nativefounderacceptance version2 beforeeachphase; receipts are supervisedbookkeeping, notsignedgrant/autonomy. EUR0 recurringinfra, existingprivatecopy/storage/attendedtime unpriced; no secondnative drillbackup. Exactoriginalapprovedpacket/failure/technicalrefinements preserved sameproposal/trial. No version2nativeoperation yet. diff --git a/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json b/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json index 70b5c80..5a57d3f 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json +++ b/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json @@ -1,48 +1,66 @@ { - "kind": "informed-decision.execution-source-bundle", - "version": 1, + "kind": "informed-decision.supervised-execution-source-bundle", + "version": 2, "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", "files": { "README.md": { - "sha256": "a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2", - "content": "# Supervised Informed Decision purpose release executor — unapproved preparation\n\nNo native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor.\n\nRun one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion.\n\nInvocation after actual approval: `python3 execution/actuator.py --phase --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase.\n\nThe private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence.\n\nNew private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required.\n\nEvery phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions.\n\nExisting Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes.\n\nSixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof.\n\nAll phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance.\n\nThe initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred.\n" + "sha256": "51b56c8ec2f30ad62f6cd09732c0f73dd7b5ebf2081320223c85bbcbf00d15a9", + "content": "# Version2 protected existing-snapshot rescue — prepared, unapproved\n\nOriginal approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed.\n\nFresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation.\n\nFixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase.\n\nBefore rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome.\n\nOffline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup.\n\nFour committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension.\n\nImage763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation.\n\nNative publication route: POST existing source /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions with expected_version1 and exact memo2/documents/summary, then publications/review-requests version2. Fresh source readback must prove currentversion1 is unbound before revision; bound/different source stops. Intake/register refuse version2 as designed and are not used. Review integration creates a NEW review-ID at its own version1; founder disposition memo_version1 belongs to that new review. Root fresh outcomes must be queried for SOURCE version2, exact newreviewID/memoSHA and confirmed nested personapproval. Receipt outcome_query pins that sourceversion2 route; it does not authenticate by itself.\n" }, "actuator.py": { - "sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5", - "content": "\"\"\"One fixed supervised phase; never run this during source preparation.\"\"\"\nimport argparse\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport re\nimport selectors\nimport stat\nimport subprocess\nimport sys\nimport time\n\nif sys.flags.optimize:\n raise SystemExit('optimized interpreter refused')\n\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\nROOT = Path(__file__).resolve().parent\nCASE = ROOT.parent\nOWNER = Path('/home/worsch/informed-decision')\nCUSTODIAN = Path('/home/worsch/the-custodian')\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\nSOCKET = 'unix:///var/run/docker.sock'\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\nVOLUME = 'infd-purpose-r1-restore-20261011'\nMAX_BYTES = 512 * 1024**2\n\n\ndef run(argv, body=None, timeout=90):\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\n\n\ndef json_result(result):\n try:\n value = json.loads(result.stdout)\n except (ValueError, TypeError):\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\n 'phase did not verify complete; raw output withheld; no retry')\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\n require(set(value) <= permitted, 'unexpected output fields withheld')\n from receipt_safety import counts\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\n if name in value:\n counts(value[name])\n for name in ('snapshot_sha256', 'client_diff_sha256'):\n if name in value:\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\n if 'snapshot_bytes' in value:\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\n 'invalid output size withheld')\n if 'snapshot_file' in value:\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\n return value\n\n\ndef docker(argv, body=None, timeout=120):\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\n body=body, timeout=timeout)\n\n\ndef remote(phase, revision, approved):\n # Fixed module imported only after main verifies every executor source hash.\n from native_program import PROGRAM\n payload = {'phase': phase, 'source_revision': revision, 'approval': approved,\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\n\n\ndef copy_snapshot(phase, revision, approved, journal):\n metadata = remote(phase, revision, approved)\n backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup'\n prior = journal.data['phases'][backup_phase]['result']\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\n name = metadata['snapshot_file']\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\n 'fixed bounded snapshot required')\n pod = metadata['pod_name']\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\n local = CUSTODY / name\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\n # Snapshot schema/count metadata was validated before opening this destination.\n with os.fdopen(fd, 'wb') as destination:\n command = ('kubectl exec -n informed-decision ' + pod +\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\n stderr=subprocess.DEVNULL)\n selector = selectors.DefaultSelector()\n selector.register(transfer.stdout, selectors.EVENT_READ)\n deadline = time.monotonic() + 150\n received = 0\n try:\n while True:\n remaining = deadline - time.monotonic()\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\n block = os.read(transfer.stdout.fileno(), 1024**2)\n if not block:\n break\n received += len(block)\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\n 'private copy exceeds frozen snapshot size')\n destination.write(block)\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\n finally:\n selector.close()\n transfer.stdout.close()\n if transfer.poll() is None:\n transfer.kill()\n transfer.wait()\n destination.flush()\n os.fsync(destination.fileno())\n private(local)\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\n # Re-read identity/hash after transfer. This is verification, not a write retry.\n after = remote(phase, revision, approved)\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\n 'source identity/snapshot changed during transfer')\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\n\n\ndef offline_verify(journal):\n from receipt_safety import counts\n snapshot = CUSTODY / 'drill.sqlite'\n private(snapshot)\n previous = journal.data['phases']['drill-copy']['result']\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\n identity = docker(['info', '--format', '{{json .Name}}'])\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\n 'local offline Docker engine identity changed')\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\n 'disposable volume absence not verified')\n nonce = journal.data['phases']['offline-verify']['attempt_id']\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\n '--label', 'informed-decision.attempt=' + nonce,\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'new volume identity unavailable')\n volume = json.loads(inspected.stdout)\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\n journal.note('offline-verify', 'created_volume_identity', identity)\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\n # No host/live PVC/config/token mount exists; this detail needs packet review.\n initializer = \"\"\"import hashlib,os,stat,sys\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\nfolder='/restore';expected=EXPECTED\nif os.listdir(folder):raise ValueError('new empty private volume required')\nos.chmod(folder,0o700)\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\ndigest=hashlib.sha256();size=0\nwith os.fdopen(fd,'wb') as target:\n while True:\n block=sys.stdin.buffer.read(1024**2)\n if not block:break\n size+=len(block)\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\n target.write(block);digest.update(block)\n target.flush();os.fsync(target.fileno())\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\nprint('{\"all_checks_pass\":true,\"private_copy_verified\":true}')\n\"\"\".replace('EXPECTED', repr(previous['snapshot_sha256']))\n with snapshot.open('rb') as source:\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\n '--entrypoint', 'python', IMAGE, '-c', initializer]\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\n json_result(copied)\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\n checked = counts(json.loads(readonly.stdout))\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\n 'inspect', '--db', '/restore/review.sqlite'])\n require(admin.returncode == 0, 'offline admin result uncertain')\n admin_counts = json.loads(admin.stdout)\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\n 'offline admin changed frozen snapshot counters')\n # Admin Store construction must not silently alter schema/integrity/counters.\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\n post_checked = counts(json.loads(post.stdout))\n require(post_checked == checked == previous['snapshot_readonly'],\n 'offline admin altered frozen snapshot proof')\n private(snapshot)\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\n 'created_volume_identity': identity,\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\n\n\ndef cleanup_offline(journal):\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\n value = json.loads(inspected.stdout)\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\n and not value[0].get('Options'), 'volume ownership/recreation changed')\n removed = docker(['volume', 'rm', VOLUME])\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\n 'cleanup outcome ambiguous; do not retry')\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\n 'native_and_offcluster_original_snapshots_retained': True}\n\n\ndef main():\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--phase', choices=PHASES, required=True)\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\n parser.add_argument('--root-native-outcome', type=Path, required=True)\n parser.add_argument('--source-revision', required=True)\n args = parser.parse_args()\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\n 'fixed supervised receipt paths required')\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\n # Verify all prepared executor/input bytes before reading authority or dispatching.\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\n 'fixed executor sources required')\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\n 'deploy/lifecycle/service.candidate.json',\n 'deploy/lifecycle/kustomization.yaml',\n 'deploy/lifecycle/registries.candidate.json'},\n 'fixed owner image sources required')\n for relative, digest in plan['executor_files'].items():\n target = ROOT / relative\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\n for relative, digest in plan['case_files'].items():\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\n 'case source path escaped')\n target = CASE / relative\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\n for relative, digest in plan['owner_source_files'].items():\n target = OWNER / relative\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\n capture_output=True)\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\n 'committed owner render source differs from approved inputs')\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\n from authority_journal import Journal, authority\n private(args.root_authority_receipt)\n private(args.root_native_outcome)\n receipt = json.loads(args.root_authority_receipt.read_text())\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\n 'root verified executor plan differs')\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\n args.source_revision, args.phase)\n parent = CUSTODY.parent\n private(parent, directory=True)\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\n if not CUSTODY.exists():\n require(args.phase == 'drill-backup', 'first approved phase must create unique private custody')\n os.mkdir(CUSTODY, 0o700)\n private(CUSTODY, directory=True)\n capacity = os.statvfs(CUSTODY)\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\n 'independent protected custody headroom insufficient')\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\n private(CUSTODY / 'empty-docker-config', directory=True)\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')})\n try:\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\n if args.phase in ('drill-copy', 'cutover-copy'):\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\n elif args.phase == 'offline-verify':\n result = offline_verify(journal)\n elif args.phase == 'cleanup-offline':\n result = cleanup_offline(journal)\n else:\n result = remote(args.phase, args.source_revision, approved)\n journal.finish(args.phase, result)\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\n except BaseException as error:\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\n 'raw_output_withheld': True}\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\n journal.finish(args.phase, safe)\n print(json.dumps(safe))\n raise SystemExit(1) from None\n finally:\n journal.close()\n\n\nif __name__ == '__main__':\n try:\n main()\n except Exception:\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\n" + "sha256": "86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2", + "content": "\"\"\"One fixed supervised phase; never run this during source preparation.\"\"\"\nimport argparse\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport re\nimport selectors\nimport stat\nimport subprocess\nimport sys\nimport time\n\nif sys.flags.optimize:\n raise SystemExit('optimized interpreter refused')\n\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\nROOT = Path(__file__).resolve().parent\nCASE = ROOT.parent\nOWNER = Path('/home/worsch/informed-decision')\nCUSTODIAN = Path('/home/worsch/the-custodian')\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\nSOCKET = 'unix:///var/run/docker.sock'\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\nVOLUME = 'infd-purpose-r1-restore-20261011'\nMAX_BYTES = 512 * 1024**2\n\n\ndef run(argv, body=None, timeout=90):\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\n\n\ndef json_result(result):\n try:\n value = json.loads(result.stdout)\n except (ValueError, TypeError):\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\n 'phase did not verify complete; raw output withheld; no retry')\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\n require(set(value) <= permitted, 'unexpected output fields withheld')\n from receipt_safety import counts\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\n if name in value:\n counts(value[name])\n for name in ('snapshot_sha256', 'client_diff_sha256'):\n if name in value:\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\n if 'snapshot_bytes' in value:\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\n 'invalid output size withheld')\n if 'snapshot_file' in value:\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\n return value\n\n\ndef docker(argv, body=None, timeout=120):\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\n body=body, timeout=timeout)\n\n\ndef remote(phase, revision, approved, snapshot_identity=None):\n # Fixed module imported only after main verifies every executor source hash.\n from native_program import PROGRAM\n payload = {'snapshot_identity': snapshot_identity, 'phase': phase, 'source_revision': revision, 'approval': approved,\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\n\n\ndef copy_snapshot(phase, revision, approved, journal):\n prior = (journal.data['identity']['recovery_anchor']['backup_result']\n if phase == 'drill-copy-rescue-r1' else journal.data['phases']['cutover-backup']['result'])\n metadata = remote(phase, revision, approved, snapshot_identity=prior)\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\n name = metadata['snapshot_file']\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\n 'fixed bounded snapshot required')\n pod = metadata['pod_name']\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\n local = CUSTODY / name\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\n # Snapshot schema/count metadata was validated before opening this destination.\n with os.fdopen(fd, 'wb') as destination:\n command = ('kubectl exec -n informed-decision ' + pod +\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\n stderr=subprocess.DEVNULL)\n selector = selectors.DefaultSelector()\n selector.register(transfer.stdout, selectors.EVENT_READ)\n deadline = time.monotonic() + 150\n received = 0\n try:\n while True:\n remaining = deadline - time.monotonic()\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\n block = os.read(transfer.stdout.fileno(), 1024**2)\n if not block:\n break\n received += len(block)\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\n 'private copy exceeds frozen snapshot size')\n destination.write(block)\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\n finally:\n selector.close()\n transfer.stdout.close()\n if transfer.poll() is None:\n transfer.kill()\n transfer.wait()\n destination.flush()\n os.fsync(destination.fileno())\n private(local)\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\n # Re-read identity/hash after transfer. This is verification, not a write retry.\n after = remote(phase, revision, approved, snapshot_identity=prior)\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\n 'source identity/snapshot changed during transfer')\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\n\n\ndef offline_verify(journal):\n from receipt_safety import counts\n snapshot = CUSTODY / 'drill.sqlite'\n private(snapshot)\n previous = journal.data['phases']['drill-copy-rescue-r1']['result']\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\n identity = docker(['info', '--format', '{{json .Name}}'])\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\n 'local offline Docker engine identity changed')\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\n 'disposable volume absence not verified')\n nonce = journal.data['phases']['offline-verify']['attempt_id']\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\n '--label', 'informed-decision.attempt=' + nonce,\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'new volume identity unavailable')\n volume = json.loads(inspected.stdout)\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\n journal.note('offline-verify', 'created_volume_identity', identity)\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\n # No host/live PVC/config/token mount exists; this detail needs packet review.\n initializer = \"\"\"import hashlib,os,stat,sys\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\nfolder='/restore';expected=EXPECTED\nif os.listdir(folder):raise ValueError('new empty private volume required')\nos.chmod(folder,0o700)\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\ndigest=hashlib.sha256();size=0\nwith os.fdopen(fd,'wb') as target:\n while True:\n block=sys.stdin.buffer.read(1024**2)\n if not block:break\n size+=len(block)\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\n target.write(block);digest.update(block)\n target.flush();os.fsync(target.fileno())\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\nprint('{\"all_checks_pass\":true,\"private_copy_verified\":true}')\n\"\"\".replace('EXPECTED', repr(previous['snapshot_sha256']))\n with snapshot.open('rb') as source:\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\n '--entrypoint', 'python', IMAGE, '-c', initializer]\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\n json_result(copied)\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\n checked = counts(json.loads(readonly.stdout))\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\n 'inspect', '--db', '/restore/review.sqlite'])\n require(admin.returncode == 0, 'offline admin result uncertain')\n admin_counts = json.loads(admin.stdout)\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\n 'offline admin changed frozen snapshot counters')\n # Admin Store construction must not silently alter schema/integrity/counters.\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\n post_checked = counts(json.loads(post.stdout))\n require(post_checked == checked == previous['snapshot_readonly'],\n 'offline admin altered frozen snapshot proof')\n private(snapshot)\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\n 'created_volume_identity': identity,\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\n\n\ndef cleanup_offline(journal):\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\n value = json.loads(inspected.stdout)\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\n and not value[0].get('Options'), 'volume ownership/recreation changed')\n removed = docker(['volume', 'rm', VOLUME])\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\n 'cleanup outcome ambiguous; do not retry')\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\n 'native_and_offcluster_original_snapshots_retained': True}\n\n\ndef main():\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--phase', choices=PHASES, required=True)\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\n parser.add_argument('--root-native-outcome', type=Path, required=True)\n parser.add_argument('--source-revision', required=True)\n args = parser.parse_args()\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\n 'fixed supervised receipt paths required')\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\n # Verify all prepared executor/input bytes before reading authority or dispatching.\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\n 'fixed executor sources required')\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\n 'deploy/lifecycle/service.candidate.json',\n 'deploy/lifecycle/kustomization.yaml',\n 'deploy/lifecycle/registries.candidate.json'},\n 'fixed owner image sources required')\n for relative, digest in plan['executor_files'].items():\n target = ROOT / relative\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\n for relative, digest in plan['case_files'].items():\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\n 'case source path escaped')\n target = CASE / relative\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\n for relative, digest in plan['owner_source_files'].items():\n target = OWNER / relative\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\n capture_output=True)\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\n 'committed owner render source differs from approved inputs')\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\n from authority_journal import Journal, authority, original_anchor\n private(args.root_authority_receipt)\n private(args.root_native_outcome)\n receipt = json.loads(args.root_authority_receipt.read_text())\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\n 'root verified executor plan differs')\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\n args.source_revision, args.phase)\n parent = CUSTODY.parent\n private(parent, directory=True)\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\n require(CUSTODY.exists(), 'original protected custody must already exist')\n private(CUSTODY, directory=True)\n capacity = os.statvfs(CUSTODY)\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\n 'independent protected custody headroom insufficient')\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\n private(CUSTODY / 'empty-docker-config', directory=True)\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\n anchor = original_anchor(CUSTODY, plan['recovery']['original_anchor'],\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\n plan['recovery']['original_identity'])\n if args.phase == 'drill-copy-rescue-r1':\n require(not os.path.lexists(CUSTODY / 'drill.sqlite')\n and not os.path.lexists(CUSTODY / 'cutover.sqlite'), 'rescue destination must be absent')\n identity = docker(['info', '--format', '{{json .Name}}'])\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\n 'local engine identity changed')\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\n 'existing restore volume forbids rescue')\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json'),\n 'recovery_anchor': anchor})\n try:\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\n if args.phase in ('drill-copy-rescue-r1', 'cutover-copy'):\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\n elif args.phase == 'offline-verify':\n result = offline_verify(journal)\n elif args.phase == 'cleanup-offline':\n result = cleanup_offline(journal)\n else:\n result = remote(args.phase, args.source_revision, approved)\n require(original_anchor(CUSTODY, plan['recovery']['original_anchor'],\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\n plan['recovery']['original_identity']) == anchor,\n 'original failed journal changed during new phase')\n journal.finish(args.phase, result)\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\n except BaseException as error:\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\n 'raw_output_withheld': True}\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\n journal.finish(args.phase, safe)\n print(json.dumps(safe))\n raise SystemExit(1) from None\n finally:\n journal.close()\n\n\nif __name__ == '__main__':\n try:\n main()\n except Exception:\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\n" }, "authority_journal.py": { - "sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa", - "content": "\"\"\"Supervised receipt bookkeeping, not an authenticated approval provider.\"\"\"\nimport datetime\nimport fcntl\nimport hashlib\nimport json\nimport os\nimport re\nfrom pathlib import Path\nimport stat\nimport uuid\n\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\n\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\n \"\"\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\n\n Receipt files/flags are not signed grants. This function checks the exact\n supervised receipt relation; existing harness/founder authority remains the\n actual permission boundary. It never authenticates a caller as human.\n \"\"\"\n now = now or datetime.datetime.now(datetime.timezone.utc)\n require(phase in PHASES, 'fixed phase required')\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\n and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha\n and receipt.get('source_revision') == source_revision\n and receipt.get('activation') == 'APPROVED'\n and receipt.get('authority_mode') == 'ADMINISTER'\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\n and receipt.get('runtime_authenticated_grant') is False,\n 'exact externally verified supervised receipt required')\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\n 'fresh root native readback required before every phase')\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\n require(now < deadline, 'approved execution window expired')\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\n review_id = outcome['review']['memo_id']\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\n accepted = [x for x in outcome.get('dispositions', [])\n if x.get('submission_state') == 'confirmed'\n and x.get('disposition', {}).get('verb') == 'accept'\n and x['disposition'].get('memo_version') == 1]\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\n accepted = accepted[0]['disposition']\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\n and accepted.get('approval_id') == receipt.get('approval_id')\n and accepted.get('id') == receipt.get('disposition_id')\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\n 'native disposition identifiers are malformed')\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\n\n\nclass Journal:\n def __init__(self, parent, identity):\n self.parent = Path(parent)\n private(self.parent, directory=True)\n self.path = self.parent / 'execution-journal.json'\n self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\n private(self.parent / 'execution.lock')\n if self.path.exists():\n private(self.path)\n self.data = json.loads(self.path.read_text())\n require(self.data['identity'] == identity, 'journal case/source identity changed')\n else:\n self.data = {'identity': identity, 'phases': {}}\n self.save()\n\n def save(self):\n temporary = self.parent / 'execution-journal.new'\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\n try:\n with os.fdopen(fd, 'w') as stream:\n json.dump(self.data, stream, indent=2)\n stream.write('\\n')\n stream.flush()\n os.fsync(stream.fileno())\n os.replace(temporary, self.path)\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\n try:\n os.fsync(directory)\n finally:\n os.close(directory)\n except BaseException:\n # Retain evidence rather than overwriting an uncertain durable intent.\n raise\n\n def start(self, phase, approval):\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\n predecessors = dict(zip(PHASES[1:8], PHASES[:7]))\n predecessors['rollback-verify'] = 'rollback'\n if phase in predecessors:\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\n 'preceding phase is not verified complete')\n if phase == 'rollback':\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\n 'attempt_id': str(uuid.uuid4()),\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\n self.save()\n\n def note(self, phase, key, value):\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\n self.data['phases'][phase][key] = value\n self.save()\n\n def finish(self, phase, result):\n entry = self.data['phases'][phase]\n require(entry['state'] == 'RUNNING', 'phase intent missing')\n entry['result'] = result\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\n self.save()\n\n def close(self):\n os.close(self.lock)\n" + "sha256": "0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68", + "content": "\"\"\"Supervised receipt bookkeeping, not an authenticated approval provider.\"\"\"\nimport datetime\nimport fcntl\nimport hashlib\nimport json\nimport os\nimport re\nfrom pathlib import Path\nimport stat\nimport uuid\n\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\n\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\n \"\"\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\n\n Receipt files/flags are not signed grants. This function checks the exact\n supervised receipt relation; existing harness/founder authority remains the\n actual permission boundary. It never authenticates a caller as human.\n \"\"\"\n now = now or datetime.datetime.now(datetime.timezone.utc)\n require(phase in PHASES, 'fixed phase required')\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\n and receipt.get('memo_version') == 2 and receipt.get('memo_sha256') == memo_sha\n and receipt.get('source_revision') == source_revision\n and receipt.get('activation') == 'APPROVED'\n and receipt.get('authority_mode') == 'ADMINISTER'\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\n and receipt.get('runtime_authenticated_grant') is False\n and receipt.get('outcome_query') == '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\n 'exact externally verified supervised receipt required')\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\n 'fresh root native readback required before every phase')\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\n require(now < deadline, 'approved execution window expired')\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\n review_id = outcome['review']['memo_id']\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\n accepted = [x for x in outcome.get('dispositions', [])\n if x.get('submission_state') == 'confirmed'\n and x.get('disposition', {}).get('verb') == 'accept'\n and x['disposition'].get('memo_version') == 1]\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\n accepted = accepted[0]['disposition']\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\n and accepted.get('approval_id') == receipt.get('approval_id')\n and accepted.get('id') == receipt.get('disposition_id')\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\n 'native disposition identifiers are malformed')\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\n\n\ndef original_anchor(parent, expected, backup_result, original_identity):\n \"\"\"Read only sanitized original journal; never rewrite/synthesize its phases.\"\"\"\n path = Path(parent) / 'execution-journal.json'\n private(path)\n require(sha(path) == expected['original_journal_sha256'], 'original journal bytes changed')\n original = json.loads(path.read_text())\n require(original.get('identity') == original_identity, 'original approved identity changed')\n phases = original.get('phases', {})\n require(set(phases) == {'drill-backup', 'drill-copy'}, 'unexpected original action or rollout')\n for name, fields in expected['phase_metadata'].items():\n require(all(phases[name].get(key) == value for key,value in fields.items()),\n 'original failed/completed attempt identity changed')\n require(phases['drill-backup'].get('result') == backup_result\n and backup_result.get('all_checks_pass') is True\n and phases['drill-copy'].get('result', {}).get('all_checks_pass') is False,\n 'original backup/copy outcome changed')\n require(backup_result.get('snapshot_sha256') == expected['snapshot_sha256']\n and backup_result.get('snapshot_bytes') == expected['snapshot_bytes']\n and backup_result.get('pod_uid') == 'e8561ae0-4b09-4455-924d-64c27b625fc7',\n 'original frozen snapshot identity changed')\n require(sha(path) == expected['original_journal_sha256'], 'original journal changed during read')\n return {'original_journal_sha256': expected['original_journal_sha256'],\n 'original_copy_attempt_id': phases['drill-copy']['attempt_id'],\n 'original_backup_attempt_id': phases['drill-backup']['attempt_id'],\n 'backup_result': backup_result, 'old_uncertain_phase_retained': True}\n\n\nclass Journal:\n def __init__(self, parent, identity):\n self.parent = Path(parent)\n private(self.parent, directory=True)\n self.path = self.parent / 'rescue-execution-journal-r1.json'\n self.lock = os.open(self.parent / 'rescue-execution-r1.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\n private(self.parent / 'rescue-execution-r1.lock')\n if self.path.exists():\n private(self.path)\n self.data = json.loads(self.path.read_text())\n require(self.data['identity'] == identity, 'journal case/source identity changed')\n else:\n self.data = {'identity': identity, 'phases': {}}\n self.save()\n\n def save(self):\n temporary = self.parent / 'execution-journal.new'\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\n try:\n with os.fdopen(fd, 'w') as stream:\n json.dump(self.data, stream, indent=2)\n stream.write('\\n')\n stream.flush()\n os.fsync(stream.fileno())\n os.replace(temporary, self.path)\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\n try:\n os.fsync(directory)\n finally:\n os.close(directory)\n except BaseException:\n # Retain evidence rather than overwriting an uncertain durable intent.\n raise\n\n def start(self, phase, approval):\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\n require(phase in PHASES, 'fixed rescue or remaining phase required')\n predecessors = dict(zip(PHASES[1:7], PHASES[:6]))\n predecessors['rollback-verify'] = 'rollback'\n if phase in predecessors:\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\n 'preceding phase is not verified complete')\n if phase == 'rollback':\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\n 'attempt_id': str(uuid.uuid4()),\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\n self.save()\n\n def note(self, phase, key, value):\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\n self.data['phases'][phase][key] = value\n self.save()\n\n def finish(self, phase, result):\n entry = self.data['phases'][phase]\n require(entry['state'] == 'RUNNING', 'phase intent missing')\n entry['result'] = result\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\n self.save()\n\n def close(self):\n os.close(self.lock)\n" }, "execution-plan.json": { - "sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6", - "content": "{\n \"kind\": \"informed-decision.supervised-mechanical-release-plan\",\n \"version\": 1,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"executor_files\": {\n \"actuator.py\": \"6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5\",\n \"authority_journal.py\": \"74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa\",\n \"native_program.py\": \"349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde\",\n \"receipt_safety.py\": \"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\"\n },\n \"case_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\",\n \"preflight-inputs.json\": \"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"published-verification.json\": \"8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2\",\n \"security-summary.json\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"source_revision\": \"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\",\n \"phases\": [\n \"drill-backup\",\n \"drill-copy\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"authorization\": \"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\",\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"raw_output_withheld\": true,\n \"native_data_or_workload_action_executed\": false,\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\"\n}\n" + "sha256": "9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258", + "content": "{\n \"kind\": \"informed-decision.supervised-mechanical-release-plan\",\n \"version\": 2,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"executor_files\": {\n \"actuator.py\": \"86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2\",\n \"authority_journal.py\": \"0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68\",\n \"native_program.py\": \"788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91\",\n \"receipt_safety.py\": \"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\"\n },\n \"case_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"sqlite_readonly.py\": \"9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509\",\n \"preflight-inputs.json\": \"03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"published-verification.json\": \"e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd\",\n \"security-summary.json\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\",\n \"original-approved-drill-backup.json\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"original-approved-drill-copy-failure.json\": \"fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56\",\n \"original-journal-sanitized-anchor.json\": \"988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"source_revision\": \"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\",\n \"phases\": [\n \"drill-copy-rescue-r1\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"authorization\": \"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\",\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"raw_output_withheld\": true,\n \"native_data_or_workload_action_executed\": false,\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\",\n \"recovery\": {\n \"original_anchor\": {\n \"original_journal_sha256\": \"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\",\n \"phase_metadata\": {\n \"drill-backup\": {\n \"state\": \"COMPLETE\",\n \"attempt_id\": \"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\",\n \"started_at\": \"2026-10-11T02:38:45.310653+00:00\"\n },\n \"drill-copy\": {\n \"state\": \"UNCERTAIN\",\n \"attempt_id\": \"329ef190-1692-4246-b953-e6a59664abcc\",\n \"started_at\": \"2026-10-11T02:39:50.198740+00:00\"\n }\n },\n \"frozen_backup_receipt_sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\",\n \"snapshot_bytes\": 19537920,\n \"off_cluster_file_exists\": false,\n \"old_uncertain_retry_authorized\": false\n },\n \"original_identity\": {\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"source_revision\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\",\n \"memo_sha256\": \"506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937\",\n \"plan_sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\"\n },\n \"new_journal\": \"rescue-execution-journal-r1.json\",\n \"new_phase\": \"drill-copy-rescue-r1\",\n \"old_uncertain_phase_overwrite_or_retry\": false,\n \"new_snapshot_backup\": false,\n \"snapshot_or_sidecar_mutation\": false,\n \"mapping\": \"offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal\"\n },\n \"source_memo_version\": 2,\n \"native_review_memo_version\": 1\n}\n" }, "native_program.py": { - "sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde", - "content": "\"\"\"Fixed remote source, passed only after exact supervised approval.\"\"\"\nPROGRAM = '\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\nif sys.flags.optimize:raise RuntimeError(\\'optimized interpreter refused\\')\\npayload=json.loads(__PAYLOAD__)\\nexec(__GUARD__)\\nphase=payload[\\'phase\\']\\nif phase not in (\\'drill-backup\\',\\'cutover-backup\\',\\'drill-copy\\',\\'cutover-copy\\',\\'release\\',\\'verify\\',\\'rollback\\',\\'rollback-verify\\'):raise ValueError(\\'fixed native phase required\\')\\ndeadline=datetime.datetime.fromisoformat(\\'2026-10-12T23:59:59+00:00\\')\\ndef require(value,reason):\\n if not value:raise ValueError(reason)\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\'drill-backup\\' else 1)+16*1024**2,\\'bounded native snapshot capacity required\\')\\n if action==\\'drill-backup\\':\\n require(not os.path.lexists(folder),\\'native case directory must be unique\\')\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\n private(folder,True)\\n filename=\\'drill.sqlite\\' if action==\\'drill-backup\\' else \\'cutover.sqlite\\';output=folder+\\'/\\'+filename\\n require(not os.path.lexists(output),\\'snapshot output must be unique\\')\\n admin=subprocess.run([\\'informed-decision-admin\\',\\'backup\\',\\'--db\\',db,\\'--output\\',output],capture_output=True,text=True,timeout=120)\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\'status\\':\\'backed_up\\',\\'consistent_snapshot\\':True},\\'backup completion not verified; do not retry\\')\\n private(output)\\n for suffix in (\\'-wal\\',\\'-shm\\'):\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\'snapshot is not closed main-file custody\\')\\n snapshot=counts(inspect_readonly(output))\\n size=os.stat(output).st_size;require(00 and size<=512*1024**2 and free>=size*(2 if action==\\'drill-backup\\' else 1)+16*1024**2,\\'bounded native snapshot capacity required\\')\\n if action==\\'drill-backup\\':\\n require(not os.path.lexists(folder),\\'native case directory must be unique\\')\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\n private(folder,True)\\n filename=\\'drill.sqlite\\' if action==\\'drill-backup\\' else \\'cutover.sqlite\\';output=folder+\\'/\\'+filename\\n require(not os.path.lexists(output),\\'snapshot output must be unique\\')\\n admin=subprocess.run([\\'informed-decision-admin\\',\\'backup\\',\\'--db\\',db,\\'--output\\',output],capture_output=True,text=True,timeout=120)\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\'status\\':\\'backed_up\\',\\'consistent_snapshot\\':True},\\'backup completion not verified; do not retry\\')\\n private(output)\\n for suffix in (\\'-wal\\',):\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\'snapshot has WAL frames; immutable read refused\\')\\n digest=hashlib.sha256()\\n with open(output,\\'rb\\') as stream:\\n for block in iter(lambda:stream.read(1024**2),b\\'\\'):digest.update(block)\\n frozen_digest=digest.hexdigest()\\n snapshot=counts(inspect_closed_snapshot(output,frozen_digest))\\n size=os.stat(output).st_size;require(0 10**12\n for number in value[group].values()):\n raise ValueError('count-only receipt values refused')\n return value\n" }, "root-authority-receipt-template.json": { - "sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813", - "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"memo_id\": \"infd-20261011-purpose-overlay-r1\",\n \"memo_version\": 1,\n \"memo_sha256\": null,\n \"source_revision\": null,\n \"activation\": \"PENDING\",\n \"authority_mode\": \"ADMINISTER\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"verification_method\": \"root-fixed-origin-native-readback\",\n \"runtime_authenticated_grant\": false,\n \"verified_at\": null,\n \"accepted_at\": null,\n \"review_memo_id\": null,\n \"approval_id\": null,\n \"disposition_id\": null,\n \"native_outcome_sha256\": null,\n \"executor_plan_sha256\": \"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\"\n}\n" + "sha256": "db28d03e3c46b4de52dc404c912054483f4a2aaa6c4f476b7892cab2a5f408d4", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"memo_id\": \"infd-20261011-purpose-overlay-r1\",\n \"memo_version\": 2,\n \"memo_sha256\": null,\n \"source_revision\": null,\n \"activation\": \"PENDING\",\n \"authority_mode\": \"ADMINISTER\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"verification_method\": \"root-fixed-origin-native-readback\",\n \"runtime_authenticated_grant\": false,\n \"verified_at\": null,\n \"accepted_at\": null,\n \"review_memo_id\": null,\n \"approval_id\": null,\n \"disposition_id\": null,\n \"native_outcome_sha256\": null,\n \"executor_plan_sha256\": \"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\",\n \"outcome_query\": \"/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2\",\n \"review_memo_version\": 1\n}\n" }, "test_execution.py": { - "sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48", - "content": "\"\"\"Synthetic custody/transport tests. No native data, Docker or cluster action.\"\"\"\nimport copy\nimport datetime\nimport io\nimport json\nimport os\nfrom pathlib import Path\nimport subprocess\nimport sys\nimport tempfile\nimport unittest\nfrom unittest.mock import patch\nfrom contextlib import redirect_stdout\n\nimport actuator\nfrom authority_journal import Journal, authority\nfrom native_program import PROGRAM\nfrom receipt_safety import counts\n\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\nREVISION = 'e' * 40\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\n\n\ndef accepted():\n approval = '11111111-1111-4111-8111-111111111111'\n review = 'review-22222222-2222-4222-8222-222222222222'\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1,\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False,\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\n 'approval_id': approval, 'id': disposition,\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\n 'at': receipt['accepted_at']}}]}\n return receipt, outcome\n\n\nclass AuthorityAndCustody(unittest.TestCase):\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\n receipt, outcome = accepted()\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW)\n self.assertEqual(result['approval_id'], receipt['approval_id'])\n\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\n mutations = [lambda r, o: r.update(activation='PENDING'),\n lambda r, o: r.update(memo_sha256='changed'),\n lambda r, o: r.update(source_revision='changed'),\n lambda r, o: r.update(target='other'),\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\n lambda r, o: r.update(verification_method='caller-asserted'),\n lambda r, o: r.update(runtime_authenticated_grant=True),\n lambda r, o: o['review'].update(stale=True),\n lambda r, o: o['review'].update(intake_state='pending'),\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2),\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n r, o = accepted()\n mutate(r, o)\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\n\n def test_expired_window_and_unknown_phase_refuse(self):\n r, o = accepted()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\n r['verified_at'] = late.isoformat()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\n\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\n with tempfile.TemporaryDirectory() as directory:\n parent = Path(directory)\n os.chmod(parent, 0o700)\n journal = Journal(parent, {'case': 'fixture'})\n journal.start('drill-backup', {'approval_id': 'fixture'})\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING')\n journal.close() # simulated crash before result\n recovered = Journal(parent, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n recovered.start('drill-backup', {})\n with self.assertRaises(ValueError):\n recovered.start('drill-copy', {})\n recovered.close()\n\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\n with tempfile.TemporaryDirectory() as directory:\n os.chmod(directory, 0o700)\n j = Journal(directory, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n j.start('release', {})\n for phase in actuator.PHASES[:6]:\n j.start(phase, {})\n j.finish(phase, {'all_checks_pass': True})\n j.start('release', {})\n j.finish('release', {'all_checks_pass': False})\n with self.assertRaises(ValueError):\n j.start('release', {})\n with self.assertRaises(ValueError):\n j.start('verify', {})\n j.start('rollback', {})\n j.finish('rollback', {'all_checks_pass': True})\n j.close()\n\n def test_secret_or_unknown_child_output_is_withheld(self):\n for body in ('not-json', '{\"all_checks_pass\":true,\"token\":\"private-value\"}',\n '{\"all_checks_pass\":true,\"snapshot_readonly\":{\"schema_version\":5}}'):\n with self.assertRaises(ValueError):\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\n wrong = copy.deepcopy(COUNT)\n wrong['outbox'] = {'private-row-value': 1}\n with self.assertRaises(ValueError):\n counts(wrong)\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\n\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\n blob = b'synthetic private fixture bytes'\n digest = __import__('hashlib').sha256(blob).hexdigest()\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\n journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})()\n real_popen = subprocess.Popen\n for extra in (b'', b'oversized'):\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\n os.chmod(folder, 0o700)\n output = io.StringIO()\n\n def child(*args, **kwargs):\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\n if extra:\n with self.assertRaises(ValueError):\n actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\n else:\n result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\n self.assertTrue(result['off_cluster_private_copy_verified'])\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\n self.assertEqual(output.getvalue(), '')\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\n\n def test_recreated_offline_volume_cannot_be_deleted(self):\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\n journal = type('FixtureJournal', (), {'data': {'phases': {\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\n with self.assertRaises(ValueError):\n actuator.cleanup_offline(journal)\n self.assertEqual(mocked.call_count, 1)\n\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\n for defect in ('none', 'post-integrity', 'original-hash'):\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\n folder=Path(directory);os.chmod(folder,0o700)\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\n digest=actuator.sha(snapshot)\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\n reads=[]\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\n def docker(argv, body=None, **kwargs):\n if argv[0]=='info':body=json.dumps('bnt-lap001')\n elif argv[:2]==['volume','ls']:body=''\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\n elif 'informed-decision-admin' in argv:\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\n elif '--entrypoint' in argv and 'python' in argv:\n reads.append(argv);proof=copy.deepcopy(COUNT)\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\n body=json.dumps(proof)\n else:raise AssertionError('unexpected offline command')\n return subprocess.CompletedProcess(argv,0,body,'')\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\"all_checks_pass\":true,\"private_copy_verified\":true}','')):\n if defect=='none':\n result=actuator.offline_verify(journal)\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\n self.assertTrue(result['original_snapshot_hash_unchanged'])\n else:\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\n self.assertEqual(len(reads),2)\n\n\nclass FixedNativeProgram(unittest.TestCase):\n def fixture(self):\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\n live = copy.deepcopy(sealed)\n live['metadata'].update(generation=42)\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\n cm = copy.deepcopy(dependencies['configmap'])\n cm.pop('canonical_data_sha256')\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\n pvc = copy.deepcopy(dependencies['pvc'])\n pvc['status'] = {'phase': 'Bound'}\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\n 'dependencies': dependencies, 'candidate': service,\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\n return objects, payload\n\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\n writes = []\n calls = []\n\n def fake(argv, input=None, **kwargs):\n calls.append(argv)\n if argv[:2] == ['kubectl', 'get']:\n kind = argv[2]\n if kind in objects:\n body = objects[kind]\n elif kind == 'pods':\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\n 'spec': objects['deployment']['spec']['template']['spec'],\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\n elif kind == 'replicaset':\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\n elif kind == 'nodes':\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\n else:\n raise AssertionError('unexpected fixed metadata route')\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\n if argv[:2] == ['kubectl', 'exec']:\n if schema_refused:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, json.dumps({\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\n if argv[:2] == ['kubectl', 'apply']:\n admitted = copy.deepcopy(payload['sealed'])\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\n if argv[:2] == ['kubectl', 'describe']:\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\n cpu 3460m (86%)\\n', '')\n if argv[:2] == ['kubectl', 'diff']:\n return subprocess.CompletedProcess(argv, 1, '-image: base\\n+image: candidate\\n', '')\n if argv[:2] == ['kubectl', 'patch']:\n if '--dry-run=server' not in argv:\n writes.append(json.loads(input))\n if ambiguous:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\n', '')\n raise AssertionError('unexpected command')\n\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n output = io.StringIO()\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\n try:\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\n except (ValueError, SystemExit):\n pass\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\n return receipt, writes, calls\n\n def test_only_existing_application_operation_and_deployment_are_requested(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n operation = writes[0][-1]['value']\n self.assertFalse(operation['sync']['prune'])\n self.assertEqual(operation['sync']['resources'], [\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\n\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\n lambda o: o['application']['spec'].update(sources=[{}]),\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n objects, payload = self.fixture()\n mutate(objects)\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n def test_preopen_schema_refusal_prevents_image_operation(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\n objects, payload = self.fixture()\n payload['phase'] = 'rollback'\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\n objects['application']['spec']['source']['targetRevision'] = REVISION\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\n\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\n for defect in ('cm', 'pvc', 'image'):\n with self.subTest(defect=defect):\n objects, payload = self.fixture();payload['phase'] = 'rollback'\n objects['deployment']['status']['readyReplicas'] = 0\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\n\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\n self.assertEqual(writes, [])\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\n objects['deployment']['status']['readyReplicas'] = 0\n receipt, writes, calls = self.execute_fake(objects,payload)\n self.assertFalse(receipt['all_checks_pass'])\n\n def test_ambiguous_patch_is_never_retried(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(len(writes), 1)\n\n\nif __name__ == '__main__':\n unittest.main()\n" + "sha256": "b250441282513862eeb990b18d01bb1eafe787b934d670a75a2bfaa9f5cfb89c", + "content": "\"\"\"Synthetic custody/transport tests. No native data, Docker or cluster action.\"\"\"\nimport copy\nimport datetime\nimport io\nimport json\nimport os\nfrom pathlib import Path\nimport subprocess\nimport sys\nimport tempfile\nimport unittest\nfrom unittest.mock import patch\nfrom contextlib import redirect_stdout\n\nimport actuator\nfrom authority_journal import Journal, authority\nfrom native_program import PROGRAM\nfrom receipt_safety import counts\n\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\nREVISION = 'e' * 40\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\n\n\ndef accepted():\n approval = '11111111-1111-4111-8111-111111111111'\n review = 'review-22222222-2222-4222-8222-222222222222'\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 2,\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False, 'outcome_query': '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\n 'approval_id': approval, 'id': disposition,\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\n 'at': receipt['accepted_at']}}]}\n return receipt, outcome\n\n\nclass AuthorityAndCustody(unittest.TestCase):\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\n receipt, outcome = accepted()\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-copy-rescue-r1', NOW)\n self.assertEqual(result['approval_id'], receipt['approval_id'])\n\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\n mutations = [lambda r, o: r.update(activation='PENDING'),\n lambda r, o: r.update(memo_sha256='changed'),\n lambda r, o: r.update(source_revision='changed'),\n lambda r, o: r.update(target='other'),\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\n lambda r, o: r.update(verification_method='caller-asserted'),\n lambda r, o: r.update(runtime_authenticated_grant=True),\n lambda r, o: o['review'].update(stale=True),\n lambda r, o: o['review'].update(intake_state='pending'),\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=3),\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n r, o = accepted()\n mutate(r, o)\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\n\n def test_expired_window_and_unknown_phase_refuse(self):\n r, o = accepted()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\n r['verified_at'] = late.isoformat()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\n\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\n with tempfile.TemporaryDirectory() as directory:\n parent = Path(directory)\n os.chmod(parent, 0o700)\n journal = Journal(parent, {'case': 'fixture'})\n journal.start('drill-copy-rescue-r1', {'approval_id': 'fixture'})\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-copy-rescue-r1']['state'], 'RUNNING')\n journal.close() # simulated crash before result\n recovered = Journal(parent, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n recovered.start('drill-copy-rescue-r1', {})\n with self.assertRaises(ValueError):\n recovered.start('drill-copy-rescue-r1', {})\n recovered.close()\n\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\n with tempfile.TemporaryDirectory() as directory:\n os.chmod(directory, 0o700)\n j = Journal(directory, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n j.start('release', {})\n for phase in actuator.PHASES[:5]:\n j.start(phase, {})\n j.finish(phase, {'all_checks_pass': True})\n j.start('release', {})\n j.finish('release', {'all_checks_pass': False})\n with self.assertRaises(ValueError):\n j.start('release', {})\n with self.assertRaises(ValueError):\n j.start('verify', {})\n j.start('rollback', {})\n j.finish('rollback', {'all_checks_pass': True})\n j.close()\n\n def test_secret_or_unknown_child_output_is_withheld(self):\n for body in ('not-json', '{\"all_checks_pass\":true,\"token\":\"private-value\"}',\n '{\"all_checks_pass\":true,\"snapshot_readonly\":{\"schema_version\":5}}'):\n with self.assertRaises(ValueError):\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\n wrong = copy.deepcopy(COUNT)\n wrong['outbox'] = {'private-row-value': 1}\n with self.assertRaises(ValueError):\n counts(wrong)\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\n\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\n blob = b'synthetic private fixture bytes'\n digest = __import__('hashlib').sha256(blob).hexdigest()\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\n journal = type('FixtureJournal', (), {'data': {'identity': {'recovery_anchor': {'backup_result': metadata}}}})()\n real_popen = subprocess.Popen\n for extra in (b'', b'oversized'):\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\n os.chmod(folder, 0o700)\n output = io.StringIO()\n\n def child(*args, **kwargs):\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\n if extra:\n with self.assertRaises(ValueError):\n actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\n else:\n result = actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\n self.assertTrue(result['off_cluster_private_copy_verified'])\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\n self.assertEqual(output.getvalue(), '')\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\n\n def test_recreated_offline_volume_cannot_be_deleted(self):\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\n journal = type('FixtureJournal', (), {'data': {'phases': {\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\n with self.assertRaises(ValueError):\n actuator.cleanup_offline(journal)\n self.assertEqual(mocked.call_count, 1)\n\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\n for defect in ('none', 'post-integrity', 'original-hash'):\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\n folder=Path(directory);os.chmod(folder,0o700)\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\n digest=actuator.sha(snapshot)\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy-rescue-r1':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\n reads=[]\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\n def docker(argv, body=None, **kwargs):\n if argv[0]=='info':body=json.dumps('bnt-lap001')\n elif argv[:2]==['volume','ls']:body=''\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\n elif 'informed-decision-admin' in argv:\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\n elif '--entrypoint' in argv and 'python' in argv:\n reads.append(argv);proof=copy.deepcopy(COUNT)\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\n body=json.dumps(proof)\n else:raise AssertionError('unexpected offline command')\n return subprocess.CompletedProcess(argv,0,body,'')\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\"all_checks_pass\":true,\"private_copy_verified\":true}','')):\n if defect=='none':\n result=actuator.offline_verify(journal)\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\n self.assertTrue(result['original_snapshot_hash_unchanged'])\n else:\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\n self.assertEqual(len(reads),2)\n\n\nclass FixedNativeProgram(unittest.TestCase):\n def fixture(self):\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\n live = copy.deepcopy(sealed)\n live['metadata'].update(generation=42)\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\n cm = copy.deepcopy(dependencies['configmap'])\n cm.pop('canonical_data_sha256')\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\n pvc = copy.deepcopy(dependencies['pvc'])\n pvc['status'] = {'phase': 'Bound'}\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\n 'dependencies': dependencies, 'candidate': service,\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\n return objects, payload\n\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\n writes = []\n calls = []\n\n def fake(argv, input=None, **kwargs):\n calls.append(argv)\n if argv[:2] == ['kubectl', 'get']:\n kind = argv[2]\n if kind in objects:\n body = objects[kind]\n elif kind == 'pods':\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\n 'spec': objects['deployment']['spec']['template']['spec'],\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\n elif kind == 'replicaset':\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\n elif kind == 'nodes':\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\n else:\n raise AssertionError('unexpected fixed metadata route')\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\n if argv[:2] == ['kubectl', 'exec']:\n if schema_refused:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, json.dumps({\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\n if argv[:2] == ['kubectl', 'apply']:\n admitted = copy.deepcopy(payload['sealed'])\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\n if argv[:2] == ['kubectl', 'describe']:\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\n cpu 3460m (86%)\\n', '')\n if argv[:2] == ['kubectl', 'diff']:\n return subprocess.CompletedProcess(argv, 1, '-image: base\\n+image: candidate\\n', '')\n if argv[:2] == ['kubectl', 'patch']:\n if '--dry-run=server' not in argv:\n writes.append(json.loads(input))\n if ambiguous:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\n', '')\n raise AssertionError('unexpected command')\n\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n output = io.StringIO()\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\n try:\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\n except (ValueError, SystemExit):\n pass\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\n return receipt, writes, calls\n\n def test_only_existing_application_operation_and_deployment_are_requested(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n operation = writes[0][-1]['value']\n self.assertFalse(operation['sync']['prune'])\n self.assertEqual(operation['sync']['resources'], [\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\n\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\n lambda o: o['application']['spec'].update(sources=[{}]),\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n objects, payload = self.fixture()\n mutate(objects)\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n def test_preopen_schema_refusal_prevents_image_operation(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\n objects, payload = self.fixture()\n payload['phase'] = 'rollback'\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\n objects['application']['spec']['source']['targetRevision'] = REVISION\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\n\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\n for defect in ('cm', 'pvc', 'image'):\n with self.subTest(defect=defect):\n objects, payload = self.fixture();payload['phase'] = 'rollback'\n objects['deployment']['status']['readyReplicas'] = 0\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\n\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\n self.assertEqual(writes, [])\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\n objects['deployment']['status']['readyReplicas'] = 0\n receipt, writes, calls = self.execute_fake(objects,payload)\n self.assertFalse(receipt['all_checks_pass'])\n\n def test_ambiguous_patch_is_never_retried(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(len(writes), 1)\n\n\nif __name__ == '__main__':\n unittest.main()\n" + }, + "test_rescue_execution.py": { + "sha256": "8ecbb0260a87a7a12bd5c4c9678fb2a9d43a4ea7322129734bc21f8ee383cd70", + "content": "\"\"\"Synthetic recovery guards; no actual private journal/DB/native command.\"\"\"\nimport copy\nimport datetime\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport tempfile\nimport unittest\nfrom authority_journal import Journal, authority, original_anchor\nfrom test_execution import accepted, NOW, REVISION\n\nROOT=Path(__file__).parent\nPLAN=json.loads((ROOT/'execution-plan.json').read_text())\nCASE=ROOT.parent\nBACKUP=json.loads((CASE/'original-approved-drill-backup.json').read_text())\n\nclass RescueGuards(unittest.TestCase):\n def original(self,parent):\n original={'identity':PLAN['recovery']['original_identity'],'phases':{}}\n for name,metadata in PLAN['recovery']['original_anchor']['phase_metadata'].items():\n original['phases'][name]={**metadata,'result':BACKUP if name=='drill-backup' else {'all_checks_pass':False}}\n p=parent/'execution-journal.json';p.write_text(json.dumps(original));os.chmod(p,0o600)\n anchor=copy.deepcopy(PLAN['recovery']['original_anchor']);anchor['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\n return p,original,anchor\n\n def test_exact_original_failed_journal_is_linked_without_mutation(self):\n with tempfile.TemporaryDirectory() as directory:\n parent=Path(directory);os.chmod(parent,0o700);p,original,expected=self.original(parent);before=p.read_bytes()\n anchor=original_anchor(parent,expected,BACKUP,original['identity'])\n j=Journal(parent,{'fixture':True,'recovery_anchor':anchor});j.start('drill-copy-rescue-r1',{})\n self.assertEqual(p.read_bytes(),before);self.assertEqual(j.path.name,'rescue-execution-journal-r1.json')\n j.finish('drill-copy-rescue-r1',{'all_checks_pass':True});j.start('offline-verify',{})\n self.assertEqual(p.read_bytes(),before);j.close()\n\n def test_original_missing_uncertain_recreated_attempt_or_rollout_refuse(self):\n for defect in ('missing','complete','attempt','rollout','hash'):\n with self.subTest(defect=defect),tempfile.TemporaryDirectory() as directory:\n parent=Path(directory);os.chmod(parent,0o700);p,o,e=self.original(parent)\n if defect=='missing':o['phases'].pop('drill-copy')\n elif defect=='complete':o['phases']['drill-copy']['state']='COMPLETE'\n elif defect=='attempt':o['phases']['drill-copy']['attempt_id']='different'\n elif defect=='rollout':o['phases']['release']={'state':'RUNNING'}\n if defect!='hash':\n p.write_text(json.dumps(o));e['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\n else:e['original_journal_sha256']='0'*64\n with self.assertRaises((ValueError,KeyError)):original_anchor(parent,e,BACKUP,PLAN['recovery']['original_identity'])\n\n def test_rescue_replay_refused_and_old_phase_never_admitted(self):\n with tempfile.TemporaryDirectory() as directory:\n os.chmod(directory,0o700);j=Journal(directory,{'fixture':True})\n with self.assertRaises(ValueError):j.start('drill-copy',{})\n with self.assertRaises(ValueError):j.start('drill-backup',{})\n with self.assertRaises(ValueError):j.start('offline-verify',{})\n j.start('drill-copy-rescue-r1',{});j.finish('drill-copy-rescue-r1',{'all_checks_pass':False})\n with self.assertRaises(ValueError):j.start('drill-copy-rescue-r1',{})\n with self.assertRaises(ValueError):j.start('offline-verify',{})\n j.close()\n\n def test_new_authority_requires_version2_old_approval_refuses(self):\n receipt,outcome=accepted();receipt['memo_version']=2;outcome['dispositions'][0]['disposition']['memo_version']=1\n authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\n receipt['memo_version']=1\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy',NOW)\n receipt['memo_version']=2;receipt['outcome_query']='/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=1'\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\n\n def test_explicit_offline_input_mapping_and_absence_guards(self):\n source=(ROOT/'actuator.py').read_text()\n self.assertIn(\"previous = journal.data['phases']['drill-copy-rescue-r1']['result']\",source)\n self.assertIn(\"not os.path.lexists(CUSTODY / 'drill.sqlite')\",source)\n self.assertIn(\"VOLUME not in listed.stdout.splitlines()\",source)\n self.assertNotIn(\"os.mkdir(CUSTODY\",source)\n import ast\n program=ast.literal_eval(next(n.value for n in ast.parse((ROOT/'native_program.py').read_text()).body if isinstance(n,ast.Assign)))\n compile(program,'native-rescue-fixture','exec')\n self.assertIn(\"phase=='drill-copy-rescue-r1':require(pod['metadata']['uid']=='e8561ae0-4b09-4455-924d-64c27b625fc7'\",program)\n\nif __name__=='__main__':unittest.main()\n" }, "validation.json": { - "sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28", - "content": "{\n \"tests\": 16,\n \"result\": \"passed\",\n \"synthetic_transport_only\": true,\n \"real_native_data_read\": false,\n \"native_backup_export_restore_executed\": false,\n \"native_workload_changed\": false,\n \"actual_founder_approval\": false,\n \"local_read_only_capability_checks\": [\n \"argocdCLI absent, existingApplication.operation path retained\",\n \"Dockerunixsocket engineName bnt-lap001\"\n ],\n \"case_source_commit_at_preparation\": \"e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)\",\n \"additional_regressions\": [\n \"Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation\",\n \"rollback still refuses CM/PVC or nonpair-image drift\",\n \"separate old-image Ready/schema5 recovery proof\",\n \"post-admin readonly integrity refusal and original snapshot tamper refusal\"\n ]\n}\n" + "sha256": "6f3379f63968e9a0294aba7b5b57ea4662adda6b1fa1b37eff11c2f72a58931f", + "content": "{\n \"state\": \"prepared-unapproved-version2\",\n \"executor_tests\": 21,\n \"snapshot_mock_tests\": 5,\n \"native_actions\": false,\n \"database_admin_commands_in_preparation\": false,\n \"old_journal_modified\": false,\n \"old_failed_phase_retried\": false,\n \"owner_head_unchanged\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\"\n}\n" } }, - "native_execution": false + "native_execution": false, + "case_evidence": { + "original-approved-drill-backup.json": { + "sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "content": "{\"phase\": \"drill-backup\", \"all_checks_pass\": true, \"raw_output_withheld\": true, \"native_approval_verified_by_root\": {\"approval_id\": \"ec92806a-9aa6-494f-a76b-0385f39ba609\", \"disposition_id\": \"disp-0968373d-294d-42bf-8979-36a7c5dd38cf\", \"accepted_at\": \"2026-10-11T02:34:20Z\", \"verified_at\": \"2026-10-11T02:38:41.777949+00:00\"}, \"native_authenticated_grant\": false, \"source_readonly_baseline\": {\"schema_version\": 5, \"lifecycle\": {\"records\": 15, \"events\": 50, \"pending\": 0}, \"outbox\": {\"delivered\": 320}, \"submissions\": {\"confirmed\": 41}, \"integrity\": \"ok\", \"read_only_pre_open\": true, \"store_constructed\": false}, \"snapshot_readonly\": {\"schema_version\": 5, \"lifecycle\": {\"records\": 15, \"events\": 50, \"pending\": 0}, \"outbox\": {\"delivered\": 320}, \"submissions\": {\"confirmed\": 41}, \"integrity\": \"ok\", \"read_only_pre_open\": true, \"store_constructed\": false}, \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\", \"snapshot_bytes\": 19537920, \"snapshot_file\": \"drill.sqlite\", \"native_parent_private\": true, \"native_uid\": 10001, \"pod_name\": \"informed-decision-f557556df-mwpz7\", \"pod_uid\": \"e8561ae0-4b09-4455-924d-64c27b625fc7\"}\n" + }, + "original-approved-drill-copy-failure.json": { + "sha256": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56", + "content": "{\"all_checks_pass\": false, \"phase\": \"drill-copy\", \"failure_class\": \"ValueError\", \"failure\": \"fixed phase outcome uncertain; original evidence retained; no retry\", \"raw_output_withheld\": true}\n" + }, + "original-journal-sanitized-anchor.json": { + "sha256": "988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454", + "content": "{\n \"original_journal_sha256\": \"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\",\n \"phase_metadata\": {\n \"drill-backup\": {\n \"state\": \"COMPLETE\",\n \"attempt_id\": \"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\",\n \"started_at\": \"2026-10-11T02:38:45.310653+00:00\"\n },\n \"drill-copy\": {\n \"state\": \"UNCERTAIN\",\n \"attempt_id\": \"329ef190-1692-4246-b953-e6a59664abcc\",\n \"started_at\": \"2026-10-11T02:39:50.198740+00:00\"\n }\n },\n \"frozen_backup_receipt_sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\",\n \"snapshot_bytes\": 19537920,\n \"off_cluster_file_exists\": false,\n \"old_uncertain_retry_authorized\": false\n}\n" + } + } } diff --git a/docs/evidence/2026-10-11-purpose-image-release/execution/README.md b/docs/evidence/2026-10-11-purpose-image-release/execution/README.md index b3c8083..deb7f51 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/execution/README.md +++ b/docs/evidence/2026-10-11-purpose-image-release/execution/README.md @@ -1,21 +1,17 @@ -# Supervised Informed Decision purpose release executor — unapproved preparation +# Version2 protected existing-snapshot rescue — prepared, unapproved -No native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor. +Original approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed. -Run one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion. +Fresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation. -Invocation after actual approval: `python3 execution/actuator.py --phase --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase. +Fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase. -The private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence. +Before rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome. -New private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required. +Offline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup. -Every phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions. +Four committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension. -Existing Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes. +Image763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation. -Sixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof. - -All phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance. - -The initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred. +Native publication route: POST existing source /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions with expected_version1 and exact memo2/documents/summary, then publications/review-requests version2. Fresh source readback must prove currentversion1 is unbound before revision; bound/different source stops. Intake/register refuse version2 as designed and are not used. Review integration creates a NEW review-ID at its own version1; founder disposition memo_version1 belongs to that new review. Root fresh outcomes must be queried for SOURCE version2, exact newreviewID/memoSHA and confirmed nested personapproval. Receipt outcome_query pins that sourceversion2 route; it does not authenticate by itself. diff --git a/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py b/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py index c5cb78f..4132e71 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py +++ b/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py @@ -14,7 +14,7 @@ import time if sys.flags.optimize: raise SystemExit('optimized interpreter refused') -PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline', +PHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline', 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') @@ -89,10 +89,10 @@ def docker(argv, body=None, timeout=120): body=body, timeout=timeout) -def remote(phase, revision, approved): +def remote(phase, revision, approved, snapshot_identity=None): # Fixed module imported only after main verifies every executor source hash. from native_program import PROGRAM - payload = {'phase': phase, 'source_revision': revision, 'approval': approved, + payload = {'snapshot_identity': snapshot_identity, 'phase': phase, 'source_revision': revision, 'approval': approved, 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()), 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()), 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()), @@ -106,9 +106,9 @@ def remote(phase, revision, approved): def copy_snapshot(phase, revision, approved, journal): - metadata = remote(phase, revision, approved) - backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup' - prior = journal.data['phases'][backup_phase]['result'] + prior = (journal.data['identity']['recovery_anchor']['backup_result'] + if phase == 'drill-copy-rescue-r1' else journal.data['phases']['cutover-backup']['result']) + metadata = remote(phase, revision, approved, snapshot_identity=prior) for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'): require(metadata[key] == prior[key], 'closed frozen snapshot changed') name = metadata['snapshot_file'] @@ -153,7 +153,7 @@ def copy_snapshot(phase, revision, approved, journal): require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes'] and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry') # Re-read identity/hash after transfer. This is verification, not a write retry. - after = remote(phase, revision, approved) + after = remote(phase, revision, approved, snapshot_identity=prior) require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'], 'source identity/snapshot changed during transfer') return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False} @@ -163,7 +163,7 @@ def offline_verify(journal): from receipt_safety import counts snapshot = CUSTODY / 'drill.sqlite' private(snapshot) - previous = journal.data['phases']['drill-copy']['result'] + previous = journal.data['phases']['drill-copy-rescue-r1']['result'] require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed') identity = docker(['info', '--format', '{{json .Name}}']) require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001', @@ -297,7 +297,7 @@ def main(): 'committed owner render source differs from approved inputs') head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD']) require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs') - from authority_journal import Journal, authority + from authority_journal import Journal, authority, original_anchor private(args.root_authority_receipt) private(args.root_native_outcome) receipt = json.loads(args.root_authority_receipt.read_text()) @@ -310,9 +310,7 @@ def main(): private(parent, directory=True) ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')]) require(ignored.returncode == 0, 'offcluster custody is not ignored') - if not CUSTODY.exists(): - require(args.phase == 'drill-backup', 'first approved phase must create unique private custody') - os.mkdir(CUSTODY, 0o700) + require(CUSTODY.exists(), 'original protected custody must already exist') private(CUSTODY, directory=True) capacity = os.statvfs(CUSTODY) require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2, @@ -320,11 +318,24 @@ def main(): os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True) private(CUSTODY / 'empty-docker-config', directory=True) require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty') + anchor = original_anchor(CUSTODY, plan['recovery']['original_anchor'], + json.loads((CASE / 'original-approved-drill-backup.json').read_text()), + plan['recovery']['original_identity']) + if args.phase == 'drill-copy-rescue-r1': + require(not os.path.lexists(CUSTODY / 'drill.sqlite') + and not os.path.lexists(CUSTODY / 'cutover.sqlite'), 'rescue destination must be absent') + identity = docker(['info', '--format', '{{json .Name}}']) + require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001', + 'local engine identity changed') + listed = docker(['volume', 'ls', '--format', '{{.Name}}']) + require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(), + 'existing restore volume forbids rescue') journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision, - 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')}) + 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json'), + 'recovery_anchor': anchor}) try: journal.start(args.phase, approved) # fsynced RUNNING before any phase effect. - if args.phase in ('drill-copy', 'cutover-copy'): + if args.phase in ('drill-copy-rescue-r1', 'cutover-copy'): result = copy_snapshot(args.phase, args.source_revision, approved, journal) elif args.phase == 'offline-verify': result = offline_verify(journal) @@ -332,6 +343,10 @@ def main(): result = cleanup_offline(journal) else: result = remote(args.phase, args.source_revision, approved) + require(original_anchor(CUSTODY, plan['recovery']['original_anchor'], + json.loads((CASE / 'original-approved-drill-backup.json').read_text()), + plan['recovery']['original_identity']) == anchor, + 'original failed journal changed during new phase') journal.finish(args.phase, result) print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes. except BaseException as error: diff --git a/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py b/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py index 00df0ec..809d13f 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py +++ b/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py @@ -12,7 +12,7 @@ import uuid FOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'} MEMO_ID = 'infd-20261011-purpose-overlay-r1' PROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1' -PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline', +PHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline', 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') @@ -46,13 +46,14 @@ def authority(receipt, outcome, memo_sha, source_revision, phase, now=None): now = now or datetime.datetime.now(datetime.timezone.utc) require(phase in PHASES, 'fixed phase required') require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID - and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha + and receipt.get('memo_version') == 2 and receipt.get('memo_sha256') == memo_sha and receipt.get('source_revision') == source_revision and receipt.get('activation') == 'APPROVED' and receipt.get('authority_mode') == 'ADMINISTER' and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision' and receipt.get('verification_method') == 'root-fixed-origin-native-readback' - and receipt.get('runtime_authenticated_grant') is False, + and receipt.get('runtime_authenticated_grant') is False + and receipt.get('outcome_query') == '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2', 'exact externally verified supervised receipt required') verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00')) require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120, @@ -82,14 +83,41 @@ def authority(receipt, outcome, memo_sha, source_revision, phase, now=None): return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')} +def original_anchor(parent, expected, backup_result, original_identity): + """Read only sanitized original journal; never rewrite/synthesize its phases.""" + path = Path(parent) / 'execution-journal.json' + private(path) + require(sha(path) == expected['original_journal_sha256'], 'original journal bytes changed') + original = json.loads(path.read_text()) + require(original.get('identity') == original_identity, 'original approved identity changed') + phases = original.get('phases', {}) + require(set(phases) == {'drill-backup', 'drill-copy'}, 'unexpected original action or rollout') + for name, fields in expected['phase_metadata'].items(): + require(all(phases[name].get(key) == value for key,value in fields.items()), + 'original failed/completed attempt identity changed') + require(phases['drill-backup'].get('result') == backup_result + and backup_result.get('all_checks_pass') is True + and phases['drill-copy'].get('result', {}).get('all_checks_pass') is False, + 'original backup/copy outcome changed') + require(backup_result.get('snapshot_sha256') == expected['snapshot_sha256'] + and backup_result.get('snapshot_bytes') == expected['snapshot_bytes'] + and backup_result.get('pod_uid') == 'e8561ae0-4b09-4455-924d-64c27b625fc7', + 'original frozen snapshot identity changed') + require(sha(path) == expected['original_journal_sha256'], 'original journal changed during read') + return {'original_journal_sha256': expected['original_journal_sha256'], + 'original_copy_attempt_id': phases['drill-copy']['attempt_id'], + 'original_backup_attempt_id': phases['drill-backup']['attempt_id'], + 'backup_result': backup_result, 'old_uncertain_phase_retained': True} + + class Journal: def __init__(self, parent, identity): self.parent = Path(parent) private(self.parent, directory=True) - self.path = self.parent / 'execution-journal.json' - self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600) + self.path = self.parent / 'rescue-execution-journal-r1.json' + self.lock = os.open(self.parent / 'rescue-execution-r1.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600) fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB) - private(self.parent / 'execution.lock') + private(self.parent / 'rescue-execution-r1.lock') if self.path.exists(): private(self.path) self.data = json.loads(self.path.read_text()) @@ -119,7 +147,8 @@ class Journal: def start(self, phase, approval): require(phase not in self.data['phases'], 'already attempted phase; no retry') - predecessors = dict(zip(PHASES[1:8], PHASES[:7])) + require(phase in PHASES, 'fixed rescue or remaining phase required') + predecessors = dict(zip(PHASES[1:7], PHASES[:6])) predecessors['rollback-verify'] = 'rollback' if phase in predecessors: require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE', diff --git a/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json b/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json index 521898f..6e6ec08 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json +++ b/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json @@ -1,26 +1,29 @@ { "kind": "informed-decision.supervised-mechanical-release-plan", - "version": 1, + "version": 2, "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", "trial_id": "infd-purpose-20261011-r1", "state": "prepared-unapproved", "executor_files": { - "actuator.py": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5", - "authority_journal.py": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa", - "native_program.py": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde", + "actuator.py": "86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2", + "authority_journal.py": "0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68", + "native_program.py": "788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91", "receipt_safety.py": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" }, "case_files": { "change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", - "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", - "preflight-inputs.json": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "sqlite_readonly.py": "9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509", + "preflight-inputs.json": "03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b", "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", "candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", "rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", - "published-verification.json": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", - "security-summary.json": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + "published-verification.json": "e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd", + "security-summary.json": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "original-approved-drill-backup.json": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "original-approved-drill-copy-failure.json": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56", + "original-journal-sanitized-anchor.json": "988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454" }, "owner_source_files": { "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", @@ -32,8 +35,7 @@ "prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", "source_revision": "must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs", "phases": [ - "drill-backup", - "drill-copy", + "drill-copy-rescue-r1", "offline-verify", "cleanup-offline", "cutover-backup", @@ -47,5 +49,41 @@ "execute_by": "2026-10-12T23:59:59Z", "raw_output_withheld": true, "native_data_or_workload_action_executed": false, - "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window." + "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.", + "recovery": { + "original_anchor": { + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false + }, + "original_identity": { + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "memo_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937", + "plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + "new_journal": "rescue-execution-journal-r1.json", + "new_phase": "drill-copy-rescue-r1", + "old_uncertain_phase_overwrite_or_retry": false, + "new_snapshot_backup": false, + "snapshot_or_sidecar_mutation": false, + "mapping": "offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal" + }, + "source_memo_version": 2, + "native_review_memo_version": 1 } diff --git a/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py b/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py index f46d24c..38f7c33 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py +++ b/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py @@ -1,2 +1,2 @@ -"""Fixed remote source, passed only after exact supervised approval.""" -PROGRAM = '\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\nif sys.flags.optimize:raise RuntimeError(\'optimized interpreter refused\')\npayload=json.loads(__PAYLOAD__)\nexec(__GUARD__)\nphase=payload[\'phase\']\nif phase not in (\'drill-backup\',\'cutover-backup\',\'drill-copy\',\'cutover-copy\',\'release\',\'verify\',\'rollback\',\'rollback-verify\'):raise ValueError(\'fixed native phase required\')\ndeadline=datetime.datetime.fromisoformat(\'2026-10-12T23:59:59+00:00\')\ndef require(value,reason):\n if not value:raise ValueError(reason)\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\'drill-backup\' else 1)+16*1024**2,\'bounded native snapshot capacity required\')\n if action==\'drill-backup\':\n require(not os.path.lexists(folder),\'native case directory must be unique\')\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\n private(folder,True)\n filename=\'drill.sqlite\' if action==\'drill-backup\' else \'cutover.sqlite\';output=folder+\'/\'+filename\n require(not os.path.lexists(output),\'snapshot output must be unique\')\n admin=subprocess.run([\'informed-decision-admin\',\'backup\',\'--db\',db,\'--output\',output],capture_output=True,text=True,timeout=120)\n require(admin.returncode==0 and json.loads(admin.stdout)=={\'status\':\'backed_up\',\'consistent_snapshot\':True},\'backup completion not verified; do not retry\')\n private(output)\n for suffix in (\'-wal\',\'-shm\'):\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\'snapshot is not closed main-file custody\')\n snapshot=counts(inspect_readonly(output))\n size=os.stat(output).st_size;require(00 and size<=512*1024**2 and free>=size*(2 if action==\'drill-backup\' else 1)+16*1024**2,\'bounded native snapshot capacity required\')\n if action==\'drill-backup\':\n require(not os.path.lexists(folder),\'native case directory must be unique\')\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\n private(folder,True)\n filename=\'drill.sqlite\' if action==\'drill-backup\' else \'cutover.sqlite\';output=folder+\'/\'+filename\n require(not os.path.lexists(output),\'snapshot output must be unique\')\n admin=subprocess.run([\'informed-decision-admin\',\'backup\',\'--db\',db,\'--output\',output],capture_output=True,text=True,timeout=120)\n require(admin.returncode==0 and json.loads(admin.stdout)=={\'status\':\'backed_up\',\'consistent_snapshot\':True},\'backup completion not verified; do not retry\')\n private(output)\n for suffix in (\'-wal\',):\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\'snapshot has WAL frames; immutable read refused\')\n digest=hashlib.sha256()\n with open(output,\'rb\') as stream:\n for block in iter(lambda:stream.read(1024**2),b\'\'):digest.update(block)\n frozen_digest=digest.hexdigest()\n snapshot=counts(inspect_closed_snapshot(output,frozen_digest))\n size=os.stat(output).st_size;require(0 --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase.\n\nThe private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence.\n\nNew private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required.\n\nEvery phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions.\n\nExisting Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes.\n\nSixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof.\n\nAll phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance.\n\nThe initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred.\n" + }, + "actuator.py": { + "sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5", + "content": "\"\"\"One fixed supervised phase; never run this during source preparation.\"\"\"\nimport argparse\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport re\nimport selectors\nimport stat\nimport subprocess\nimport sys\nimport time\n\nif sys.flags.optimize:\n raise SystemExit('optimized interpreter refused')\n\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\nROOT = Path(__file__).resolve().parent\nCASE = ROOT.parent\nOWNER = Path('/home/worsch/informed-decision')\nCUSTODIAN = Path('/home/worsch/the-custodian')\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\nSOCKET = 'unix:///var/run/docker.sock'\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\nVOLUME = 'infd-purpose-r1-restore-20261011'\nMAX_BYTES = 512 * 1024**2\n\n\ndef run(argv, body=None, timeout=90):\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\n\n\ndef json_result(result):\n try:\n value = json.loads(result.stdout)\n except (ValueError, TypeError):\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\n 'phase did not verify complete; raw output withheld; no retry')\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\n require(set(value) <= permitted, 'unexpected output fields withheld')\n from receipt_safety import counts\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\n if name in value:\n counts(value[name])\n for name in ('snapshot_sha256', 'client_diff_sha256'):\n if name in value:\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\n if 'snapshot_bytes' in value:\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\n 'invalid output size withheld')\n if 'snapshot_file' in value:\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\n return value\n\n\ndef docker(argv, body=None, timeout=120):\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\n body=body, timeout=timeout)\n\n\ndef remote(phase, revision, approved):\n # Fixed module imported only after main verifies every executor source hash.\n from native_program import PROGRAM\n payload = {'phase': phase, 'source_revision': revision, 'approval': approved,\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\n\n\ndef copy_snapshot(phase, revision, approved, journal):\n metadata = remote(phase, revision, approved)\n backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup'\n prior = journal.data['phases'][backup_phase]['result']\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\n name = metadata['snapshot_file']\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\n 'fixed bounded snapshot required')\n pod = metadata['pod_name']\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\n local = CUSTODY / name\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\n # Snapshot schema/count metadata was validated before opening this destination.\n with os.fdopen(fd, 'wb') as destination:\n command = ('kubectl exec -n informed-decision ' + pod +\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\n stderr=subprocess.DEVNULL)\n selector = selectors.DefaultSelector()\n selector.register(transfer.stdout, selectors.EVENT_READ)\n deadline = time.monotonic() + 150\n received = 0\n try:\n while True:\n remaining = deadline - time.monotonic()\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\n block = os.read(transfer.stdout.fileno(), 1024**2)\n if not block:\n break\n received += len(block)\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\n 'private copy exceeds frozen snapshot size')\n destination.write(block)\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\n finally:\n selector.close()\n transfer.stdout.close()\n if transfer.poll() is None:\n transfer.kill()\n transfer.wait()\n destination.flush()\n os.fsync(destination.fileno())\n private(local)\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\n # Re-read identity/hash after transfer. This is verification, not a write retry.\n after = remote(phase, revision, approved)\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\n 'source identity/snapshot changed during transfer')\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\n\n\ndef offline_verify(journal):\n from receipt_safety import counts\n snapshot = CUSTODY / 'drill.sqlite'\n private(snapshot)\n previous = journal.data['phases']['drill-copy']['result']\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\n identity = docker(['info', '--format', '{{json .Name}}'])\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\n 'local offline Docker engine identity changed')\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\n 'disposable volume absence not verified')\n nonce = journal.data['phases']['offline-verify']['attempt_id']\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\n '--label', 'informed-decision.attempt=' + nonce,\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'new volume identity unavailable')\n volume = json.loads(inspected.stdout)\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\n journal.note('offline-verify', 'created_volume_identity', identity)\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\n # No host/live PVC/config/token mount exists; this detail needs packet review.\n initializer = \"\"\"import hashlib,os,stat,sys\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\nfolder='/restore';expected=EXPECTED\nif os.listdir(folder):raise ValueError('new empty private volume required')\nos.chmod(folder,0o700)\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\ndigest=hashlib.sha256();size=0\nwith os.fdopen(fd,'wb') as target:\n while True:\n block=sys.stdin.buffer.read(1024**2)\n if not block:break\n size+=len(block)\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\n target.write(block);digest.update(block)\n target.flush();os.fsync(target.fileno())\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\nprint('{\"all_checks_pass\":true,\"private_copy_verified\":true}')\n\"\"\".replace('EXPECTED', repr(previous['snapshot_sha256']))\n with snapshot.open('rb') as source:\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\n '--entrypoint', 'python', IMAGE, '-c', initializer]\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\n json_result(copied)\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\n checked = counts(json.loads(readonly.stdout))\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\n 'inspect', '--db', '/restore/review.sqlite'])\n require(admin.returncode == 0, 'offline admin result uncertain')\n admin_counts = json.loads(admin.stdout)\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\n 'offline admin changed frozen snapshot counters')\n # Admin Store construction must not silently alter schema/integrity/counters.\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\n post_checked = counts(json.loads(post.stdout))\n require(post_checked == checked == previous['snapshot_readonly'],\n 'offline admin altered frozen snapshot proof')\n private(snapshot)\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\n 'created_volume_identity': identity,\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\n\n\ndef cleanup_offline(journal):\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\n value = json.loads(inspected.stdout)\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\n and not value[0].get('Options'), 'volume ownership/recreation changed')\n removed = docker(['volume', 'rm', VOLUME])\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\n 'cleanup outcome ambiguous; do not retry')\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\n 'native_and_offcluster_original_snapshots_retained': True}\n\n\ndef main():\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--phase', choices=PHASES, required=True)\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\n parser.add_argument('--root-native-outcome', type=Path, required=True)\n parser.add_argument('--source-revision', required=True)\n args = parser.parse_args()\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\n 'fixed supervised receipt paths required')\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\n # Verify all prepared executor/input bytes before reading authority or dispatching.\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\n 'fixed executor sources required')\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\n 'deploy/lifecycle/service.candidate.json',\n 'deploy/lifecycle/kustomization.yaml',\n 'deploy/lifecycle/registries.candidate.json'},\n 'fixed owner image sources required')\n for relative, digest in plan['executor_files'].items():\n target = ROOT / relative\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\n for relative, digest in plan['case_files'].items():\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\n 'case source path escaped')\n target = CASE / relative\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\n for relative, digest in plan['owner_source_files'].items():\n target = OWNER / relative\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\n capture_output=True)\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\n 'committed owner render source differs from approved inputs')\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\n from authority_journal import Journal, authority\n private(args.root_authority_receipt)\n private(args.root_native_outcome)\n receipt = json.loads(args.root_authority_receipt.read_text())\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\n 'root verified executor plan differs')\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\n args.source_revision, args.phase)\n parent = CUSTODY.parent\n private(parent, directory=True)\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\n if not CUSTODY.exists():\n require(args.phase == 'drill-backup', 'first approved phase must create unique private custody')\n os.mkdir(CUSTODY, 0o700)\n private(CUSTODY, directory=True)\n capacity = os.statvfs(CUSTODY)\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\n 'independent protected custody headroom insufficient')\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\n private(CUSTODY / 'empty-docker-config', directory=True)\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')})\n try:\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\n if args.phase in ('drill-copy', 'cutover-copy'):\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\n elif args.phase == 'offline-verify':\n result = offline_verify(journal)\n elif args.phase == 'cleanup-offline':\n result = cleanup_offline(journal)\n else:\n result = remote(args.phase, args.source_revision, approved)\n journal.finish(args.phase, result)\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\n except BaseException as error:\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\n 'raw_output_withheld': True}\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\n journal.finish(args.phase, safe)\n print(json.dumps(safe))\n raise SystemExit(1) from None\n finally:\n journal.close()\n\n\nif __name__ == '__main__':\n try:\n main()\n except Exception:\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\n" + }, + "authority_journal.py": { + "sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa", + "content": "\"\"\"Supervised receipt bookkeeping, not an authenticated approval provider.\"\"\"\nimport datetime\nimport fcntl\nimport hashlib\nimport json\nimport os\nimport re\nfrom pathlib import Path\nimport stat\nimport uuid\n\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\n\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\n \"\"\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\n\n Receipt files/flags are not signed grants. This function checks the exact\n supervised receipt relation; existing harness/founder authority remains the\n actual permission boundary. It never authenticates a caller as human.\n \"\"\"\n now = now or datetime.datetime.now(datetime.timezone.utc)\n require(phase in PHASES, 'fixed phase required')\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\n and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha\n and receipt.get('source_revision') == source_revision\n and receipt.get('activation') == 'APPROVED'\n and receipt.get('authority_mode') == 'ADMINISTER'\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\n and receipt.get('runtime_authenticated_grant') is False,\n 'exact externally verified supervised receipt required')\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\n 'fresh root native readback required before every phase')\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\n require(now < deadline, 'approved execution window expired')\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\n review_id = outcome['review']['memo_id']\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\n accepted = [x for x in outcome.get('dispositions', [])\n if x.get('submission_state') == 'confirmed'\n and x.get('disposition', {}).get('verb') == 'accept'\n and x['disposition'].get('memo_version') == 1]\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\n accepted = accepted[0]['disposition']\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\n and accepted.get('approval_id') == receipt.get('approval_id')\n and accepted.get('id') == receipt.get('disposition_id')\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\n 'native disposition identifiers are malformed')\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\n\n\nclass Journal:\n def __init__(self, parent, identity):\n self.parent = Path(parent)\n private(self.parent, directory=True)\n self.path = self.parent / 'execution-journal.json'\n self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\n private(self.parent / 'execution.lock')\n if self.path.exists():\n private(self.path)\n self.data = json.loads(self.path.read_text())\n require(self.data['identity'] == identity, 'journal case/source identity changed')\n else:\n self.data = {'identity': identity, 'phases': {}}\n self.save()\n\n def save(self):\n temporary = self.parent / 'execution-journal.new'\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\n try:\n with os.fdopen(fd, 'w') as stream:\n json.dump(self.data, stream, indent=2)\n stream.write('\\n')\n stream.flush()\n os.fsync(stream.fileno())\n os.replace(temporary, self.path)\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\n try:\n os.fsync(directory)\n finally:\n os.close(directory)\n except BaseException:\n # Retain evidence rather than overwriting an uncertain durable intent.\n raise\n\n def start(self, phase, approval):\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\n predecessors = dict(zip(PHASES[1:8], PHASES[:7]))\n predecessors['rollback-verify'] = 'rollback'\n if phase in predecessors:\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\n 'preceding phase is not verified complete')\n if phase == 'rollback':\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\n 'attempt_id': str(uuid.uuid4()),\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\n self.save()\n\n def note(self, phase, key, value):\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\n self.data['phases'][phase][key] = value\n self.save()\n\n def finish(self, phase, result):\n entry = self.data['phases'][phase]\n require(entry['state'] == 'RUNNING', 'phase intent missing')\n entry['result'] = result\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\n self.save()\n\n def close(self):\n os.close(self.lock)\n" + }, + "execution-plan.json": { + "sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6", + "content": "{\n \"kind\": \"informed-decision.supervised-mechanical-release-plan\",\n \"version\": 1,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"executor_files\": {\n \"actuator.py\": \"6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5\",\n \"authority_journal.py\": \"74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa\",\n \"native_program.py\": \"349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde\",\n \"receipt_safety.py\": \"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\"\n },\n \"case_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\",\n \"preflight-inputs.json\": \"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"published-verification.json\": \"8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2\",\n \"security-summary.json\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"source_revision\": \"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\",\n \"phases\": [\n \"drill-backup\",\n \"drill-copy\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"authorization\": \"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\",\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"raw_output_withheld\": true,\n \"native_data_or_workload_action_executed\": false,\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\"\n}\n" + }, + "native_program.py": { + "sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde", + "content": "\"\"\"Fixed remote source, passed only after exact supervised approval.\"\"\"\nPROGRAM = '\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\nif sys.flags.optimize:raise RuntimeError(\\'optimized interpreter refused\\')\\npayload=json.loads(__PAYLOAD__)\\nexec(__GUARD__)\\nphase=payload[\\'phase\\']\\nif phase not in (\\'drill-backup\\',\\'cutover-backup\\',\\'drill-copy\\',\\'cutover-copy\\',\\'release\\',\\'verify\\',\\'rollback\\',\\'rollback-verify\\'):raise ValueError(\\'fixed native phase required\\')\\ndeadline=datetime.datetime.fromisoformat(\\'2026-10-12T23:59:59+00:00\\')\\ndef require(value,reason):\\n if not value:raise ValueError(reason)\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\'drill-backup\\' else 1)+16*1024**2,\\'bounded native snapshot capacity required\\')\\n if action==\\'drill-backup\\':\\n require(not os.path.lexists(folder),\\'native case directory must be unique\\')\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\n private(folder,True)\\n filename=\\'drill.sqlite\\' if action==\\'drill-backup\\' else \\'cutover.sqlite\\';output=folder+\\'/\\'+filename\\n require(not os.path.lexists(output),\\'snapshot output must be unique\\')\\n admin=subprocess.run([\\'informed-decision-admin\\',\\'backup\\',\\'--db\\',db,\\'--output\\',output],capture_output=True,text=True,timeout=120)\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\'status\\':\\'backed_up\\',\\'consistent_snapshot\\':True},\\'backup completion not verified; do not retry\\')\\n private(output)\\n for suffix in (\\'-wal\\',\\'-shm\\'):\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\'snapshot is not closed main-file custody\\')\\n snapshot=counts(inspect_readonly(output))\\n size=os.stat(output).st_size;require(0 10**12\n for number in value[group].values()):\n raise ValueError('count-only receipt values refused')\n return value\n" + }, + "root-authority-receipt-template.json": { + "sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"memo_id\": \"infd-20261011-purpose-overlay-r1\",\n \"memo_version\": 1,\n \"memo_sha256\": null,\n \"source_revision\": null,\n \"activation\": \"PENDING\",\n \"authority_mode\": \"ADMINISTER\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"verification_method\": \"root-fixed-origin-native-readback\",\n \"runtime_authenticated_grant\": false,\n \"verified_at\": null,\n \"accepted_at\": null,\n \"review_memo_id\": null,\n \"approval_id\": null,\n \"disposition_id\": null,\n \"native_outcome_sha256\": null,\n \"executor_plan_sha256\": \"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\"\n}\n" + }, + "test_execution.py": { + "sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48", + "content": "\"\"\"Synthetic custody/transport tests. No native data, Docker or cluster action.\"\"\"\nimport copy\nimport datetime\nimport io\nimport json\nimport os\nfrom pathlib import Path\nimport subprocess\nimport sys\nimport tempfile\nimport unittest\nfrom unittest.mock import patch\nfrom contextlib import redirect_stdout\n\nimport actuator\nfrom authority_journal import Journal, authority\nfrom native_program import PROGRAM\nfrom receipt_safety import counts\n\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\nREVISION = 'e' * 40\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\n\n\ndef accepted():\n approval = '11111111-1111-4111-8111-111111111111'\n review = 'review-22222222-2222-4222-8222-222222222222'\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1,\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False,\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\n 'approval_id': approval, 'id': disposition,\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\n 'at': receipt['accepted_at']}}]}\n return receipt, outcome\n\n\nclass AuthorityAndCustody(unittest.TestCase):\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\n receipt, outcome = accepted()\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW)\n self.assertEqual(result['approval_id'], receipt['approval_id'])\n\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\n mutations = [lambda r, o: r.update(activation='PENDING'),\n lambda r, o: r.update(memo_sha256='changed'),\n lambda r, o: r.update(source_revision='changed'),\n lambda r, o: r.update(target='other'),\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\n lambda r, o: r.update(verification_method='caller-asserted'),\n lambda r, o: r.update(runtime_authenticated_grant=True),\n lambda r, o: o['review'].update(stale=True),\n lambda r, o: o['review'].update(intake_state='pending'),\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2),\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n r, o = accepted()\n mutate(r, o)\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\n\n def test_expired_window_and_unknown_phase_refuse(self):\n r, o = accepted()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\n r['verified_at'] = late.isoformat()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\n\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\n with tempfile.TemporaryDirectory() as directory:\n parent = Path(directory)\n os.chmod(parent, 0o700)\n journal = Journal(parent, {'case': 'fixture'})\n journal.start('drill-backup', {'approval_id': 'fixture'})\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING')\n journal.close() # simulated crash before result\n recovered = Journal(parent, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n recovered.start('drill-backup', {})\n with self.assertRaises(ValueError):\n recovered.start('drill-copy', {})\n recovered.close()\n\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\n with tempfile.TemporaryDirectory() as directory:\n os.chmod(directory, 0o700)\n j = Journal(directory, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n j.start('release', {})\n for phase in actuator.PHASES[:6]:\n j.start(phase, {})\n j.finish(phase, {'all_checks_pass': True})\n j.start('release', {})\n j.finish('release', {'all_checks_pass': False})\n with self.assertRaises(ValueError):\n j.start('release', {})\n with self.assertRaises(ValueError):\n j.start('verify', {})\n j.start('rollback', {})\n j.finish('rollback', {'all_checks_pass': True})\n j.close()\n\n def test_secret_or_unknown_child_output_is_withheld(self):\n for body in ('not-json', '{\"all_checks_pass\":true,\"token\":\"private-value\"}',\n '{\"all_checks_pass\":true,\"snapshot_readonly\":{\"schema_version\":5}}'):\n with self.assertRaises(ValueError):\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\n wrong = copy.deepcopy(COUNT)\n wrong['outbox'] = {'private-row-value': 1}\n with self.assertRaises(ValueError):\n counts(wrong)\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\n\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\n blob = b'synthetic private fixture bytes'\n digest = __import__('hashlib').sha256(blob).hexdigest()\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\n journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})()\n real_popen = subprocess.Popen\n for extra in (b'', b'oversized'):\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\n os.chmod(folder, 0o700)\n output = io.StringIO()\n\n def child(*args, **kwargs):\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\n if extra:\n with self.assertRaises(ValueError):\n actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\n else:\n result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\n self.assertTrue(result['off_cluster_private_copy_verified'])\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\n self.assertEqual(output.getvalue(), '')\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\n\n def test_recreated_offline_volume_cannot_be_deleted(self):\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\n journal = type('FixtureJournal', (), {'data': {'phases': {\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\n with self.assertRaises(ValueError):\n actuator.cleanup_offline(journal)\n self.assertEqual(mocked.call_count, 1)\n\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\n for defect in ('none', 'post-integrity', 'original-hash'):\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\n folder=Path(directory);os.chmod(folder,0o700)\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\n digest=actuator.sha(snapshot)\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\n reads=[]\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\n def docker(argv, body=None, **kwargs):\n if argv[0]=='info':body=json.dumps('bnt-lap001')\n elif argv[:2]==['volume','ls']:body=''\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\n elif 'informed-decision-admin' in argv:\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\n elif '--entrypoint' in argv and 'python' in argv:\n reads.append(argv);proof=copy.deepcopy(COUNT)\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\n body=json.dumps(proof)\n else:raise AssertionError('unexpected offline command')\n return subprocess.CompletedProcess(argv,0,body,'')\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\"all_checks_pass\":true,\"private_copy_verified\":true}','')):\n if defect=='none':\n result=actuator.offline_verify(journal)\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\n self.assertTrue(result['original_snapshot_hash_unchanged'])\n else:\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\n self.assertEqual(len(reads),2)\n\n\nclass FixedNativeProgram(unittest.TestCase):\n def fixture(self):\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\n live = copy.deepcopy(sealed)\n live['metadata'].update(generation=42)\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\n cm = copy.deepcopy(dependencies['configmap'])\n cm.pop('canonical_data_sha256')\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\n pvc = copy.deepcopy(dependencies['pvc'])\n pvc['status'] = {'phase': 'Bound'}\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\n 'dependencies': dependencies, 'candidate': service,\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\n return objects, payload\n\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\n writes = []\n calls = []\n\n def fake(argv, input=None, **kwargs):\n calls.append(argv)\n if argv[:2] == ['kubectl', 'get']:\n kind = argv[2]\n if kind in objects:\n body = objects[kind]\n elif kind == 'pods':\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\n 'spec': objects['deployment']['spec']['template']['spec'],\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\n elif kind == 'replicaset':\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\n elif kind == 'nodes':\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\n else:\n raise AssertionError('unexpected fixed metadata route')\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\n if argv[:2] == ['kubectl', 'exec']:\n if schema_refused:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, json.dumps({\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\n if argv[:2] == ['kubectl', 'apply']:\n admitted = copy.deepcopy(payload['sealed'])\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\n if argv[:2] == ['kubectl', 'describe']:\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\n cpu 3460m (86%)\\n', '')\n if argv[:2] == ['kubectl', 'diff']:\n return subprocess.CompletedProcess(argv, 1, '-image: base\\n+image: candidate\\n', '')\n if argv[:2] == ['kubectl', 'patch']:\n if '--dry-run=server' not in argv:\n writes.append(json.loads(input))\n if ambiguous:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\n', '')\n raise AssertionError('unexpected command')\n\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n output = io.StringIO()\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\n try:\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\n except (ValueError, SystemExit):\n pass\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\n return receipt, writes, calls\n\n def test_only_existing_application_operation_and_deployment_are_requested(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n operation = writes[0][-1]['value']\n self.assertFalse(operation['sync']['prune'])\n self.assertEqual(operation['sync']['resources'], [\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\n\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\n lambda o: o['application']['spec'].update(sources=[{}]),\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n objects, payload = self.fixture()\n mutate(objects)\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n def test_preopen_schema_refusal_prevents_image_operation(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\n objects, payload = self.fixture()\n payload['phase'] = 'rollback'\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\n objects['application']['spec']['source']['targetRevision'] = REVISION\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\n\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\n for defect in ('cm', 'pvc', 'image'):\n with self.subTest(defect=defect):\n objects, payload = self.fixture();payload['phase'] = 'rollback'\n objects['deployment']['status']['readyReplicas'] = 0\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\n\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\n self.assertEqual(writes, [])\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\n objects['deployment']['status']['readyReplicas'] = 0\n receipt, writes, calls = self.execute_fake(objects,payload)\n self.assertFalse(receipt['all_checks_pass'])\n\n def test_ambiguous_patch_is_never_retried(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(len(writes), 1)\n\n\nif __name__ == '__main__':\n unittest.main()\n" + }, + "validation.json": { + "sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28", + "content": "{\n \"tests\": 16,\n \"result\": \"passed\",\n \"synthetic_transport_only\": true,\n \"real_native_data_read\": false,\n \"native_backup_export_restore_executed\": false,\n \"native_workload_changed\": false,\n \"actual_founder_approval\": false,\n \"local_read_only_capability_checks\": [\n \"argocdCLI absent, existingApplication.operation path retained\",\n \"Dockerunixsocket engineName bnt-lap001\"\n ],\n \"case_source_commit_at_preparation\": \"e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)\",\n \"additional_regressions\": [\n \"Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation\",\n \"rollback still refuses CM/PVC or nonpair-image drift\",\n \"separate old-image Ready/schema5 recovery proof\",\n \"post-admin readonly integrity refusal and original snapshot tamper refusal\"\n ]\n}\n" + } + }, + "native_execution": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md new file mode 100644 index 0000000..b3c8083 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md @@ -0,0 +1,21 @@ +# Supervised Informed Decision purpose release executor — unapproved preparation + +No native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor. + +Run one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion. + +Invocation after actual approval: `python3 execution/actuator.py --phase --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase. + +The private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence. + +New private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required. + +Every phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions. + +Existing Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes. + +Sixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof. + +All phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance. + +The initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py new file mode 100644 index 0000000..c5cb78f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py @@ -0,0 +1,353 @@ +"""One fixed supervised phase; never run this during source preparation.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +import selectors +import stat +import subprocess +import sys +import time + +if sys.flags.optimize: + raise SystemExit('optimized interpreter refused') + +PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline', + 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') + + +def require(value, reason): + if not value: + raise ValueError(reason) + + +def sha(path): + digest = hashlib.sha256() + with Path(path).open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + digest.update(block) + return digest.hexdigest() + + +def private(path, directory=False): + info = Path(path).lstat() + require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode)) + and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600) + and (directory or info.st_nlink == 1), 'private owned custody required') + +ROOT = Path(__file__).resolve().parent +CASE = ROOT.parent +OWNER = Path('/home/worsch/informed-decision') +CUSTODIAN = Path('/home/worsch/the-custodian') +CUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1' +SOCKET = 'unix:///var/run/docker.sock' +IMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a' +VOLUME = 'infd-purpose-r1-restore-20261011' +MAX_BYTES = 512 * 1024**2 + + +def run(argv, body=None, timeout=90): + return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout) + + +def json_result(result): + try: + value = json.loads(result.stdout) + except (ValueError, TypeError): + raise ValueError('safe phase receipt unavailable; outcome uncertain') from None + require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True, + 'phase did not verify complete; raw output withheld; no retry') + permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root', + 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly', + 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private', + 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts', + 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision', + 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained', + 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained', + 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256', + 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'} + require(set(value) <= permitted, 'unexpected output fields withheld') + from receipt_safety import counts + for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'): + if name in value: + counts(value[name]) + for name in ('snapshot_sha256', 'client_diff_sha256'): + if name in value: + require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld') + if 'snapshot_bytes' in value: + require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES, + 'invalid output size withheld') + if 'snapshot_file' in value: + require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld') + return value + + +def docker(argv, body=None, timeout=120): + return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv, + body=body, timeout=timeout) + + +def remote(phase, revision, approved): + # Fixed module imported only after main verifies every executor source hash. + from native_program import PROGRAM + payload = {'phase': phase, 'source_revision': revision, 'approval': approved, + 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()), + 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()), + 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()), + 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()), + 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(), + 'purpose_checks': (CASE / 'check_installed.py').read_text(), + 'readonly': (CASE / 'sqlite_readonly.py').read_text()} + script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace( + '__GUARD__', repr((CASE / 'change_guard.py').read_text())) + return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200)) + + +def copy_snapshot(phase, revision, approved, journal): + metadata = remote(phase, revision, approved) + backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup' + prior = journal.data['phases'][backup_phase]['result'] + for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'): + require(metadata[key] == prior[key], 'closed frozen snapshot changed') + name = metadata['snapshot_file'] + require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES, + 'fixed bounded snapshot required') + pod = metadata['pod_name'] + require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required') + local = CUSTODY / name + fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600) + # Binary snapshot stdout goes only to a private file, never tool/chat/log output. + # Snapshot schema/count metadata was validated before opening this destination. + with os.fdopen(fd, 'wb') as destination: + command = ('kubectl exec -n informed-decision ' + pod + + ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name) + transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL) + selector = selectors.DefaultSelector() + selector.register(transfer.stdout, selectors.EVENT_READ) + deadline = time.monotonic() + 150 + received = 0 + try: + while True: + remaining = deadline - time.monotonic() + require(remaining > 0 and selector.select(remaining), 'private transfer timed out') + block = os.read(transfer.stdout.fileno(), 1024**2) + if not block: + break + received += len(block) + require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES, + 'private copy exceeds frozen snapshot size') + destination.write(block) + transfer.wait(timeout=max(1, deadline - time.monotonic())) + finally: + selector.close() + transfer.stdout.close() + if transfer.poll() is None: + transfer.kill() + transfer.wait() + destination.flush() + os.fsync(destination.fileno()) + private(local) + require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes'] + and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry') + # Re-read identity/hash after transfer. This is verification, not a write retry. + after = remote(phase, revision, approved) + require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'], + 'source identity/snapshot changed during transfer') + return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False} + + +def offline_verify(journal): + from receipt_safety import counts + snapshot = CUSTODY / 'drill.sqlite' + private(snapshot) + previous = journal.data['phases']['drill-copy']['result'] + require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed') + identity = docker(['info', '--format', '{{json .Name}}']) + require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001', + 'local offline Docker engine identity changed') + listed = docker(['volume', 'ls', '--format', '{{.Name}}']) + require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(), + 'disposable volume absence not verified') + nonce = journal.data['phases']['offline-verify']['attempt_id'] + labels = {'informed-decision.case': 'infd-purpose-20261011-r1', + 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce} + created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1', + '--label', 'informed-decision.attempt=' + nonce, + '--label', 'informed-decision.use=offline-restore-only', VOLUME]) + require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry') + inspected = docker(['volume', 'inspect', VOLUME]) + require(inspected.returncode == 0, 'new volume identity unavailable') + volume = json.loads(inspected.stdout) + require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels + and volume[0].get('Driver') == 'local' and not volume[0].get('Options') + and volume[0].get('Scope') == 'local', 'new isolated volume identity changed') + identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')} + journal.note('offline-verify', 'created_volume_identity', identity) + # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume. + # No host/live PVC/config/token mount exists; this detail needs packet review. + initializer = """import hashlib,os,stat,sys +if sys.flags.optimize:raise RuntimeError('optimized interpreter refused') +folder='/restore';expected=EXPECTED +if os.listdir(folder):raise ValueError('new empty private volume required') +os.chmod(folder,0o700) +fd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600) +digest=hashlib.sha256();size=0 +with os.fdopen(fd,'wb') as target: + while True: + block=sys.stdin.buffer.read(1024**2) + if not block:break + size+=len(block) + if size>512*1024**2:raise ValueError('private restore size exceeds bound') + target.write(block);digest.update(block) + target.flush();os.fsync(target.fileno()) +if digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs') +os.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001) +print('{"all_checks_pass":true,"private_copy_verified":true}') +""".replace('EXPECTED', repr(previous['snapshot_sha256'])) + with snapshot.open('rb') as source: + argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET, + 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m', + '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN', + '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore', + '--entrypoint', 'python', IMAGE, '-c', initializer] + copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150) + json_result(copied) + options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m', + '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges', + '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore'] + readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'], + (CASE / 'sqlite_readonly.py').read_text()) + require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store') + checked = counts(json.loads(readonly.stdout)) + require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ') + admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE, + 'inspect', '--db', '/restore/review.sqlite']) + require(admin.returncode == 0, 'offline admin result uncertain') + admin_counts = json.loads(admin.stdout) + require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')}, + 'offline admin changed frozen snapshot counters') + # Admin Store construction must not silently alter schema/integrity/counters. + post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'], + (CASE / 'sqlite_readonly.py').read_text()) + require(post.returncode == 0, 'offline post-admin readonly integrity gate refused') + post_checked = counts(json.loads(post.stdout)) + require(post_checked == checked == previous['snapshot_readonly'], + 'offline admin altered frozen snapshot proof') + private(snapshot) + require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill') + return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked, + 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True, + 'created_volume_identity': identity, + 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False, + 'service_entrypoint_started': False, 'original_snapshot_retained': True} + + +def cleanup_offline(journal): + inspected = docker(['volume', 'inspect', VOLUME]) + require(inspected.returncode == 0, 'owned disposable volume identity unverified') + value = json.loads(inspected.stdout) + expected = journal.data['phases']['offline-verify']['result']['created_volume_identity'] + require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected + and not value[0].get('Options'), 'volume ownership/recreation changed') + removed = docker(['volume', 'rm', VOLUME]) + require(removed.returncode == 0 and removed.stdout.strip() == VOLUME + and docker(['volume', 'inspect', VOLUME]).returncode != 0, + 'cleanup outcome ambiguous; do not retry') + return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME, + 'native_and_offcluster_original_snapshots_retained': True} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--phase', choices=PHASES, required=True) + parser.add_argument('--root-authority-receipt', type=Path, required=True) + parser.add_argument('--root-native-outcome', type=Path, required=True) + parser.add_argument('--source-revision', required=True) + args = parser.parse_args() + require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json') + and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'), + 'fixed supervised receipt paths required') + require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required') + # Verify all prepared executor/input bytes before reading authority or dispatching. + plan = json.loads((ROOT / 'execution-plan.json').read_text()) + require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'}, + 'fixed executor sources required') + require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json', + 'deploy/lifecycle/service.candidate.json', + 'deploy/lifecycle/kustomization.yaml', + 'deploy/lifecycle/registries.candidate.json'}, + 'fixed owner image sources required') + for relative, digest in plan['executor_files'].items(): + target = ROOT / relative + require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed') + for relative, digest in plan['case_files'].items(): + require(not Path(relative).is_absolute() and '..' not in Path(relative).parts, + 'case source path escaped') + target = CASE / relative + require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed') + for relative, digest in plan['owner_source_files'].items(): + target = OWNER / relative + require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed') + committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative], + capture_output=True) + require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest, + 'committed owner render source differs from approved inputs') + head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD']) + require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs') + from authority_journal import Journal, authority + private(args.root_authority_receipt) + private(args.root_native_outcome) + receipt = json.loads(args.root_authority_receipt.read_text()) + require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed') + require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'), + 'root verified executor plan differs') + approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'), + args.source_revision, args.phase) + parent = CUSTODY.parent + private(parent, directory=True) + ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')]) + require(ignored.returncode == 0, 'offcluster custody is not ignored') + if not CUSTODY.exists(): + require(args.phase == 'drill-backup', 'first approved phase must create unique private custody') + os.mkdir(CUSTODY, 0o700) + private(CUSTODY, directory=True) + capacity = os.statvfs(CUSTODY) + require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2, + 'independent protected custody headroom insufficient') + os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True) + private(CUSTODY / 'empty-docker-config', directory=True) + require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty') + journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision, + 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')}) + try: + journal.start(args.phase, approved) # fsynced RUNNING before any phase effect. + if args.phase in ('drill-copy', 'cutover-copy'): + result = copy_snapshot(args.phase, args.source_revision, approved, journal) + elif args.phase == 'offline-verify': + result = offline_verify(journal) + elif args.phase == 'cleanup-offline': + result = cleanup_offline(journal) + else: + result = remote(args.phase, args.source_revision, approved) + journal.finish(args.phase, result) + print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes. + except BaseException as error: + safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__, + 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry', + 'raw_output_withheld': True} + if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING': + journal.finish(args.phase, safe) + print(json.dumps(safe)) + raise SystemExit(1) from None + finally: + journal.close() + + +if __name__ == '__main__': + try: + main() + except Exception: + raise SystemExit('supervised execution refused before phase; raw output withheld') from None diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py new file mode 100644 index 0000000..00df0ec --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py @@ -0,0 +1,147 @@ +"""Supervised receipt bookkeeping, not an authenticated approval provider.""" +import datetime +import fcntl +import hashlib +import json +import os +import re +from pathlib import Path +import stat +import uuid + +FOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'} +MEMO_ID = 'infd-20261011-purpose-overlay-r1' +PROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1' +PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline', + 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') + + +def require(value, reason): + if not value: + raise ValueError(reason) + + +def sha(path): + digest = hashlib.sha256() + with Path(path).open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + digest.update(block) + return digest.hexdigest() + + +def private(path, directory=False): + info = Path(path).lstat() + require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode)) + and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600) + and (directory or info.st_nlink == 1), 'private owned custody required') + + +def authority(receipt, outcome, memo_sha, source_revision, phase, now=None): + """Root must freshly verify native outcome at fixed ORIGIN outside this helper. + + Receipt files/flags are not signed grants. This function checks the exact + supervised receipt relation; existing harness/founder authority remains the + actual permission boundary. It never authenticates a caller as human. + """ + now = now or datetime.datetime.now(datetime.timezone.utc) + require(phase in PHASES, 'fixed phase required') + require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID + and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha + and receipt.get('source_revision') == source_revision + and receipt.get('activation') == 'APPROVED' + and receipt.get('authority_mode') == 'ADMINISTER' + and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision' + and receipt.get('verification_method') == 'root-fixed-origin-native-readback' + and receipt.get('runtime_authenticated_grant') is False, + 'exact externally verified supervised receipt required') + verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00')) + require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120, + 'fresh root native readback required before every phase') + deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00') + require(now < deadline, 'approved execution window expired') + require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False + and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current') + review_id = outcome['review']['memo_id'] + require(review_id == receipt.get('review_memo_id'), 'native review identity changed') + accepted = [x for x in outcome.get('dispositions', []) + if x.get('submission_state') == 'confirmed' + and x.get('disposition', {}).get('verb') == 'accept' + and x['disposition'].get('memo_version') == 1] + require(len(accepted) == 1, 'one confirmed founder acceptance required') + accepted = accepted[0]['disposition'] + require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id + and accepted.get('approval_id') == receipt.get('approval_id') + and accepted.get('id') == receipt.get('disposition_id') + and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch') + require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None + and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None + and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None, + 'native disposition identifiers are malformed') + accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00')) + require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded') + return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')} + + +class Journal: + def __init__(self, parent, identity): + self.parent = Path(parent) + private(self.parent, directory=True) + self.path = self.parent / 'execution-journal.json' + self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600) + fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB) + private(self.parent / 'execution.lock') + if self.path.exists(): + private(self.path) + self.data = json.loads(self.path.read_text()) + require(self.data['identity'] == identity, 'journal case/source identity changed') + else: + self.data = {'identity': identity, 'phases': {}} + self.save() + + def save(self): + temporary = self.parent / 'execution-journal.new' + fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600) + try: + with os.fdopen(fd, 'w') as stream: + json.dump(self.data, stream, indent=2) + stream.write('\n') + stream.flush() + os.fsync(stream.fileno()) + os.replace(temporary, self.path) + directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY) + try: + os.fsync(directory) + finally: + os.close(directory) + except BaseException: + # Retain evidence rather than overwriting an uncertain durable intent. + raise + + def start(self, phase, approval): + require(phase not in self.data['phases'], 'already attempted phase; no retry') + predecessors = dict(zip(PHASES[1:8], PHASES[:7])) + predecessors['rollback-verify'] = 'rollback' + if phase in predecessors: + require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE', + 'preceding phase is not verified complete') + if phase == 'rollback': + require('release' in self.data['phases'], 'rollback requires a recorded release attempt') + self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval, + 'attempt_id': str(uuid.uuid4()), + 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()} + self.save() + + def note(self, phase, key, value): + require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing') + self.data['phases'][phase][key] = value + self.save() + + def finish(self, phase, result): + entry = self.data['phases'][phase] + require(entry['state'] == 'RUNNING', 'phase intent missing') + entry['result'] = result + entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN' + self.save() + + def close(self): + os.close(self.lock) diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json new file mode 100644 index 0000000..521898f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json @@ -0,0 +1,51 @@ +{ + "kind": "informed-decision.supervised-mechanical-release-plan", + "version": 1, + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "trial_id": "infd-purpose-20261011-r1", + "state": "prepared-unapproved", + "executor_files": { + "actuator.py": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5", + "authority_journal.py": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa", + "native_program.py": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde", + "receipt_safety.py": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + "case_files": { + "change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "preflight-inputs.json": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", + "published-verification.json": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "security-summary.json": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + "owner_source_files": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "source_revision": "must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs", + "phases": [ + "drill-backup", + "drill-copy", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "authorization": "fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant", + "execute_by": "2026-10-12T23:59:59Z", + "raw_output_withheld": true, + "native_data_or_workload_action_executed": false, + "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window." +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py new file mode 100644 index 0000000..f46d24c --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py @@ -0,0 +1,2 @@ +"""Fixed remote source, passed only after exact supervised approval.""" +PROGRAM = '\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\nif sys.flags.optimize:raise RuntimeError(\'optimized interpreter refused\')\npayload=json.loads(__PAYLOAD__)\nexec(__GUARD__)\nphase=payload[\'phase\']\nif phase not in (\'drill-backup\',\'cutover-backup\',\'drill-copy\',\'cutover-copy\',\'release\',\'verify\',\'rollback\',\'rollback-verify\'):raise ValueError(\'fixed native phase required\')\ndeadline=datetime.datetime.fromisoformat(\'2026-10-12T23:59:59+00:00\')\ndef require(value,reason):\n if not value:raise ValueError(reason)\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\'drill-backup\' else 1)+16*1024**2,\'bounded native snapshot capacity required\')\n if action==\'drill-backup\':\n require(not os.path.lexists(folder),\'native case directory must be unique\')\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\n private(folder,True)\n filename=\'drill.sqlite\' if action==\'drill-backup\' else \'cutover.sqlite\';output=folder+\'/\'+filename\n require(not os.path.lexists(output),\'snapshot output must be unique\')\n admin=subprocess.run([\'informed-decision-admin\',\'backup\',\'--db\',db,\'--output\',output],capture_output=True,text=True,timeout=120)\n require(admin.returncode==0 and json.loads(admin.stdout)=={\'status\':\'backed_up\',\'consistent_snapshot\':True},\'backup completion not verified; do not retry\')\n private(output)\n for suffix in (\'-wal\',\'-shm\'):\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\'snapshot is not closed main-file custody\')\n snapshot=counts(inspect_readonly(output))\n size=os.stat(output).st_size;require(0 10**12 + for number in value[group].values()): + raise ValueError('count-only receipt values refused') + return value diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json new file mode 100644 index 0000000..3f22cb3 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json @@ -0,0 +1,19 @@ +{ + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "memo_id": "infd-20261011-purpose-overlay-r1", + "memo_version": 1, + "memo_sha256": null, + "source_revision": null, + "activation": "PENDING", + "authority_mode": "ADMINISTER", + "target": "realm:kubernetes/railiance01/informed-decision", + "verification_method": "root-fixed-origin-native-readback", + "runtime_authenticated_grant": false, + "verified_at": null, + "accepted_at": null, + "review_memo_id": null, + "approval_id": null, + "disposition_id": null, + "native_outcome_sha256": null, + "executor_plan_sha256": "4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py new file mode 100644 index 0000000..965cceb --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py @@ -0,0 +1,367 @@ +"""Synthetic custody/transport tests. No native data, Docker or cluster action.""" +import copy +import datetime +import io +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest +from unittest.mock import patch +from contextlib import redirect_stdout + +import actuator +from authority_journal import Journal, authority +from native_program import PROGRAM +from receipt_safety import counts + +CASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release') +NOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc) +REVISION = 'e' * 40 +COUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False, + 'lifecycle': {'records': 3, 'events': 8, 'pending': 1}, + 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}} + + +def accepted(): + approval = '11111111-1111-4111-8111-111111111111' + review = 'review-22222222-2222-4222-8222-222222222222' + disposition = 'disp-33333333-3333-4333-8333-333333333333' + receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1', + 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1, + 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED', + 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision', + 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False, + 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z', + 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition} + outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'}, + 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed', + 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review, + 'approval_id': approval, 'id': disposition, + 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}, + 'at': receipt['accepted_at']}}]} + return receipt, outcome + + +class AuthorityAndCustody(unittest.TestCase): + def test_exact_nested_founder_receipt_not_top_level_approval(self): + receipt, outcome = accepted() + result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW) + self.assertEqual(result['approval_id'], receipt['approval_id']) + + def test_pending_stale_wrong_actor_version_and_binding_refuse(self): + mutations = [lambda r, o: r.update(activation='PENDING'), + lambda r, o: r.update(memo_sha256='changed'), + lambda r, o: r.update(source_revision='changed'), + lambda r, o: r.update(target='other'), + lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'), + lambda r, o: r.update(verification_method='caller-asserted'), + lambda r, o: r.update(runtime_authenticated_grant=True), + lambda r, o: o['review'].update(stale=True), + lambda r, o: o['review'].update(intake_state='pending'), + lambda r, o: o['dispositions'][0].update(submission_state='unresolved'), + lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2), + lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}), + lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))] + for mutate in mutations: + with self.subTest(mutate=mutate): + r, o = accepted() + mutate(r, o) + with self.assertRaises(ValueError): + authority(r, o, 'a' * 64, REVISION, 'release', NOW) + + def test_expired_window_and_unknown_phase_refuse(self): + r, o = accepted() + with self.assertRaises(ValueError): + authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW) + late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc) + r['verified_at'] = late.isoformat() + with self.assertRaises(ValueError): + authority(r, o, 'a' * 64, REVISION, 'rollback', late) + + def test_durable_intent_precedes_dispatch_and_never_retries(self): + with tempfile.TemporaryDirectory() as directory: + parent = Path(directory) + os.chmod(parent, 0o700) + journal = Journal(parent, {'case': 'fixture'}) + journal.start('drill-backup', {'approval_id': 'fixture'}) + self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING') + journal.close() # simulated crash before result + recovered = Journal(parent, {'case': 'fixture'}) + with self.assertRaises(ValueError): + recovered.start('drill-backup', {}) + with self.assertRaises(ValueError): + recovered.start('drill-copy', {}) + recovered.close() + + def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self): + with tempfile.TemporaryDirectory() as directory: + os.chmod(directory, 0o700) + j = Journal(directory, {'case': 'fixture'}) + with self.assertRaises(ValueError): + j.start('release', {}) + for phase in actuator.PHASES[:6]: + j.start(phase, {}) + j.finish(phase, {'all_checks_pass': True}) + j.start('release', {}) + j.finish('release', {'all_checks_pass': False}) + with self.assertRaises(ValueError): + j.start('release', {}) + with self.assertRaises(ValueError): + j.start('verify', {}) + j.start('rollback', {}) + j.finish('rollback', {'all_checks_pass': True}) + j.close() + + def test_secret_or_unknown_child_output_is_withheld(self): + for body in ('not-json', '{"all_checks_pass":true,"token":"private-value"}', + '{"all_checks_pass":true,"snapshot_readonly":{"schema_version":5}}'): + with self.assertRaises(ValueError): + actuator.json_result(subprocess.CompletedProcess([], 0, body, '')) + wrong = copy.deepcopy(COUNT) + wrong['outbox'] = {'private-row-value': 1} + with self.assertRaises(ValueError): + counts(wrong) + counts(COUNT) # blocked/unresolved counts are not required to be zero. + + def test_binary_copy_is_bounded_private_and_never_echoed(self): + blob = b'synthetic private fixture bytes' + digest = __import__('hashlib').sha256(blob).hexdigest() + metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob), + 'snapshot_sha256': digest, 'snapshot_readonly': COUNT, + 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'} + journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})() + real_popen = subprocess.Popen + for extra in (b'', b'oversized'): + with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder: + os.chmod(folder, 0o700) + output = io.StringIO() + + def child(*args, **kwargs): + return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'], + stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + + with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \ + patch('subprocess.Popen', side_effect=child), redirect_stdout(output): + if extra: + with self.assertRaises(ValueError): + actuator.copy_snapshot('drill-copy', REVISION, {}, journal) + else: + result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal) + self.assertTrue(result['off_cluster_private_copy_verified']) + self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob) + self.assertEqual(output.getvalue(), '') + self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600) + + def test_recreated_offline_volume_cannot_be_deleted(self): + identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'} + journal = type('FixtureJournal', (), {'data': {'phases': { + 'offline-verify': {'result': {'created_volume_identity': identity}}}}})() + inspected = [{**identity, 'CreatedAt': 'recreated'}] + with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked: + with self.assertRaises(ValueError): + actuator.cleanup_offline(journal) + self.assertEqual(mocked.call_count, 1) + + def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self): + for defect in ('none', 'post-integrity', 'original-hash'): + with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory: + folder=Path(directory);os.chmod(folder,0o700) + snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600) + digest=actuator.sha(snapshot) + prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT} + journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})() + reads=[] + volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None} + def docker(argv, body=None, **kwargs): + if argv[0]=='info':body=json.dumps('bnt-lap001') + elif argv[:2]==['volume','ls']:body='' + elif argv[:2]==['volume','create']:body=actuator.VOLUME + elif argv[:2]==['volume','inspect']:body=json.dumps([volume]) + elif 'informed-decision-admin' in argv: + body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')}) + if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original') + elif '--entrypoint' in argv and 'python' in argv: + reads.append(argv);proof=copy.deepcopy(COUNT) + if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt' + body=json.dumps(proof) + else:raise AssertionError('unexpected offline command') + return subprocess.CompletedProcess(argv,0,body,'') + with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{"all_checks_pass":true,"private_copy_verified":true}','')): + if defect=='none': + result=actuator.offline_verify(journal) + self.assertEqual(result['offline_post_admin_readonly'],COUNT) + self.assertTrue(result['original_snapshot_hash_unchanged']) + else: + with self.assertRaises(ValueError):actuator.offline_verify(journal) + self.assertEqual(len(reads),2) + + +class FixedNativeProgram(unittest.TestCase): + def fixture(self): + sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text()) + live = copy.deepcopy(sealed) + live['metadata'].update(generation=42) + live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42} + dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text()) + cm = copy.deepcopy(dependencies['configmap']) + cm.pop('canonical_data_sha256') + service = json.loads((CASE / 'candidate-deployment.json').read_text()) + source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text()) + cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data'] + pvc = copy.deepcopy(dependencies['pvc']) + pvc['status'] = {'phase': 'Bound'} + app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'}, + 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git', + 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'}, + 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}} + objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app} + payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed, + 'dependencies': dependencies, 'candidate': service, + 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()), + 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(), + 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()} + return objects, payload + + def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False): + writes = [] + calls = [] + + def fake(argv, input=None, **kwargs): + calls.append(argv) + if argv[:2] == ['kubectl', 'get']: + kind = argv[2] + if kind in objects: + body = objects[kind] + elif kind == 'pods': + body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid', + 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]}, + 'spec': objects['deployment']['spec']['template']['spec'], + 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]} + elif kind == 'replicaset': + body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [ + {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}} + elif kind == 'nodes': + body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': { + 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'}, + 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'} + for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]} + else: + raise AssertionError('unexpected fixed metadata route') + return subprocess.CompletedProcess(argv, 0, json.dumps(body), '') + if argv[:2] == ['kubectl', 'exec']: + if schema_refused: + return subprocess.CompletedProcess(argv, 1, '', 'withheld') + return subprocess.CompletedProcess(argv, 0, json.dumps({ + 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '') + if argv[:2] == ['kubectl', 'apply']: + admitted = copy.deepcopy(payload['sealed']) + admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image']) + return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '') + if argv[:2] == ['kubectl', 'describe']: + return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\n cpu 3460m (86%)\n', '') + if argv[:2] == ['kubectl', 'diff']: + return subprocess.CompletedProcess(argv, 1, '-image: base\n+image: candidate\n', '') + if argv[:2] == ['kubectl', 'patch']: + if '--dry-run=server' not in argv: + writes.append(json.loads(input)) + if ambiguous: + return subprocess.CompletedProcess(argv, 1, '', 'withheld') + return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\n', '') + raise AssertionError('unexpected command') + + source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace( + '__GUARD__', repr((CASE / 'change_guard.py').read_text())) + output = io.StringIO() + with patch('subprocess.run', side_effect=fake), redirect_stdout(output): + try: + exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'}) + except (ValueError, SystemExit): + pass + receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False} + return receipt, writes, calls + + def test_only_existing_application_operation_and_deployment_are_requested(self): + objects, payload = self.fixture() + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertTrue(receipt['all_checks_pass']) + self.assertFalse(receipt['rollout_verified']) + self.assertEqual(len(writes), 1) + operation = writes[0][-1]['value'] + self.assertFalse(operation['sync']['prune']) + self.assertEqual(operation['sync']['resources'], [ + {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}]) + self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls)) + self.assertEqual(writes[0][0]['path'], '/metadata/uid') + + def test_source_overrides_automation_and_custody_drift_stop_before_write(self): + mutations = [lambda o: o['application']['metadata'].update(uid='recreated'), + lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}), + lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}), + lambda o: o['application']['spec'].update(sources=[{}]), + lambda o: o['configmap']['metadata'].update(uid='recreated'), + lambda o: o['pvc']['spec'].update(volumeName='replaced'), + lambda o: o['deployment']['status'].update(readyReplicas=0)] + for mutate in mutations: + with self.subTest(mutate=mutate): + objects, payload = self.fixture() + mutate(objects) + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertFalse(receipt['all_checks_pass']) + self.assertEqual(writes, []) + + def test_preopen_schema_refusal_prevents_image_operation(self): + objects, payload = self.fixture() + receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True) + self.assertFalse(receipt['all_checks_pass']) + self.assertEqual(writes, []) + + + def test_rollback_unready_candidate_never_reads_pod_or_database(self): + objects, payload = self.fixture() + payload['phase'] = 'rollback' + objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0) + objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE + objects['application']['spec']['source']['targetRevision'] = REVISION + receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True) + self.assertTrue(receipt['all_checks_pass']) + self.assertFalse(receipt['rollout_verified']) + self.assertEqual(len(writes), 1) + self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls)) + self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf') + + def test_rollback_still_refuses_custody_or_nonpair_image_drift(self): + for defect in ('cm', 'pvc', 'image'): + with self.subTest(defect=defect): + objects, payload = self.fixture();payload['phase'] = 'rollback' + objects['deployment']['status']['readyReplicas'] = 0 + if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated' + elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced' + else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image' + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, []) + + def test_recovery_verification_is_separate_ready_old_image_schema_proof(self): + objects, payload = self.fixture();payload['phase'] = 'rollback-verify' + objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': { + 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False, + 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}} + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification']) + self.assertEqual(writes, []) + self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls)) + objects['deployment']['status']['readyReplicas'] = 0 + receipt, writes, calls = self.execute_fake(objects,payload) + self.assertFalse(receipt['all_checks_pass']) + + def test_ambiguous_patch_is_never_retried(self): + objects, payload = self.fixture() + receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True) + self.assertFalse(receipt['all_checks_pass']) + self.assertEqual(len(writes), 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json new file mode 100644 index 0000000..321f6fa --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json @@ -0,0 +1,20 @@ +{ + "tests": 16, + "result": "passed", + "synthetic_transport_only": true, + "real_native_data_read": false, + "native_backup_export_restore_executed": false, + "native_workload_changed": false, + "actual_founder_approval": false, + "local_read_only_capability_checks": [ + "argocdCLI absent, existingApplication.operation path retained", + "Dockerunixsocket engineName bnt-lap001" + ], + "case_source_commit_at_preparation": "e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)", + "additional_regressions": [ + "Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation", + "rollback still refuses CM/PVC or nonpair-image drift", + "separate old-image Ready/schema5 recovery proof", + "post-admin readonly integrity refusal and original snapshot tamper refusal" + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json new file mode 100644 index 0000000..1fc30be --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json @@ -0,0 +1,50 @@ +{ + "node_allocatable_cpu_m": 4000, + "node_requested_cpu_m": 3460, + "captured_at": "2026-10-11T01:39:14.234277+00:00", + "native_workload_changed": false, + "native_backup_restore_executed": false, + "argo": { + "uid": "499868f2-eabc-4df4-ae31-b89ce58d750d", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "path": "deploy/lifecycle", + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "automated": false, + "sync": { + "comparedTo": { + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "source": { + "path": "deploy/lifecycle", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf" + } + }, + "revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "status": "OutOfSync" + }, + "health": { + "lastTransitionTime": "2026-10-10T23:14:52Z", + "status": "Healthy" + } + }, + "native_dependencies_checked": true, + "configmap_uid": "90113d2d-54d9-4e82-b1d3-90b49ebed2b5", + "pvc_uid": "d80b25b1-141a-441b-b205-98fa2fd98b7c", + "live_ready_replicas": 1, + "admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92", + "server_dry_run_passed": true, + "admitted_spec_exactly_live_plus_image": true, + "client_diff_exit": 1, + "client_diff_sha256": "840769c7d2a9c1655c40a3259f833d1fc8f69950ceb3bedb707a955fed711566", + "node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)", + "all_checks_pass": true, + "sealed_preflight_inputs_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "fresh_execution_receipt": true +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json new file mode 100644 index 0000000..f0fa85b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json @@ -0,0 +1,21 @@ +{ + "id": "INFD-RISK-20261011-ZLIB-85091", + "kind": "owner-vulnerability-follow-through", + "owner": "informed-decision", + "task": "INFD-WP-0009-T05", + "status": "open", + "created": "2026-10-11", + "review_due": "2026-10-18", + "finding": "CVE-2026-85091", + "scanner_severity": "MEDIUM", + "estate_risk_grade": null, + "affected_package": "zlib", + "installed": "1.3.2-r0", + "fixed": "1.3.2-r1", + "actual_current_base_and_candidate_findings_identical": true, + "source_evidence": "security-summary.json, trivy-full.json, base-trivy-full.json", + "human_temporary_disposition": "pending", + "follow_through": "Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload", + "manual_review_expiry": "Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed", + "close_condition": "Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json new file mode 100644 index 0000000..243335c --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json @@ -0,0 +1,261 @@ +{ + "kind": "informed-decision.memo-intake", + "version": 1, + "idempotency_key": "infd-20261011-purpose-overlay-r1-v1", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "drafted_by": "custodian-codex", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + }, + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 1, + "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "packet": [ + { + "item_id": "decision-packet-md", + "media_type": "text/markdown", + "content": "# Informed Decision purpose overlay release\n\n## Requested decision\n\nApprove the exact purpose-only image rollout and protected real-data backup/restore protocol for the existing Informed Decision service on railiance01. This request is separate from the already approved config-only repair. Only the existing Deployment image changes through the owner's manual Argo workflow, with prune disabled. Runtime ConfigMap `informed-decision-runtime-6c221878d051`, schema5, PVC, credentials, audience, policies, registries, access, replica1 and Recreate strategy remain fixed. Execute by 2026-10-12T23:59:59Z, after refreshed sealed-source/UID/configuration checks and backup/restore gates. All phases, including recovery and verification, must begin before this deadline. If the window is exhausted, stop and obtain a fresh founder decision; this may delay recovery. No timer/controller automatically changes the released image.\n\n## Artifact and known finding\n\nActual owner CI task11484/run3 published immutable image `sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a` from source `3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168`. Anonymous registry verification preserves all eight base compressed blobs/rootfs layers and adds only policy.py with exact source hash and mode0644. Legacy-builder media-type/default config serialization differences are recorded; the runtime semantics remain unchanged. Pulled published image executes as UID10001/GID10001 and passes ten installed checks: two supported binding forms, eight advisory/malformed refusals. Tests use synthetic transport and do not claim new native PDP authorization proof. The two failed CI attempts remain in the same trial history.\n\nActual unfiltered pinned scanner/DB evidence covers44packages: zero HIGH/CRITICAL, **one fixable MEDIUM**, CVE-2026-85091, zlib1.3.2-r0 fixed in1.3.2-r1. Actual current-base scan has the identical finding. Approving this packet explicitly permits this inherited finding during this narrow purpose release; it is not a RiskNexus estate risk grade or zero-CVE claim. Owner record INFD-RISK-20261011-ZLIB-85091 and live task INFD-WP-0009-T05 require separate base refresh and native approval, reviewed by2026-10-18. That review date is manual follow-through, with no auto-controller claim. Scanner notes Alpine3.24 absent EOL list; OS vulnerability detection ran against38OSpackages. Unknown vulnerabilities remain outside snapshot knowledge.\n\n## Native baseline and gates\n\nOriginal read-only capture01:25:38Z: existing Deployment UIDa588e10a, Ready1, image7f5c, unchanged runtime6c; native admission preserves the full configuration plus exactly the proposed image. Clientdiff returns1. Requests3460/4000mCPU86%, memory9472Mi59%; refresh before release. Existing Argo Application UID499868f2 is manual, target7db8485, Healthy with pre-existing OutOfSync status. Do not treat a scoped Deployment release as full-app reconciliation. Preserve its tracking-id; no unrelated resource sync/prune/adoption.\n\nThe refined read-only helper binds original source/helper/render/baseline hashes and actual immutable ConfigMap/PVC UIDs, runtime-data checksum and bound volume identity, explicitly refuses optimized interpreters, checks exact fresh live UID/configuration and admission, and writes a separate execution receipt outside this sealed packet. Failed initial raw Kustomize metadata check is retained: direct kubectl apply would drop Argo tracking-id. The reviewed selected Deployment explicitly retains that existing ID, matching Argo ownership. Any unrelated drift, different UID, altered admission, unavailable protected backup capacity, uncertain backup, restore mismatch or unhealthy baseline stops the release.\n\n## Protected backup and release\n\nBefore **any** native source or offline-restored Store/admin open, use the attached stdlib SQLite mode=ro/query_only checker to require schema5, integrity=ok and count-only baseline. The admin automatically migrates oldschemas, so a post-open report alone cannot prove no migration. Refuse other schemas before admin. Then use the existing owner admin's SQLite backup API, not a raw copy of the live database/WAL. Protect directories0700/files0600, owned by10001. Retain independently protected off-cluster snapshot custody and only count/hash receipts. No database contents, caller tokens, requester Secret or runtime credential files enter Git, State Hub, logs or this packet. Native backup and offline real-data restore have not yet occurred. Use an isolated private disposable copy, networknone and no runtime config/token mounts, run the pre-open checker and exact offline `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite` after it passes, comparing frozen snapshot counts without service startup, then clean only the disposable restored copy. Retain the original snapshot. The attached protocol binds case-specific paths and fail-closed capacity/custody checks.\n\nRefresh a consistent online snapshot immediately before image-only cutover. This protocol does not assert traffic/dispatcher quiescence. Current and candidate share schema5 and unchanged store code; rollback retains the latest live database and all new/uncertain evidence. Stop the old writer before the new one with existing Recreate and single-writer lock. Do not restore an older snapshot over later writes, discard unresolved external effects, scale other workloads, change policies/identity/custody, or create human dispositions to make checks green.\n\nPin the existing Application to the exact owner commit containing the approved candidate source hashes, and manually sync only Deployment/informed-decision with prune=false. Verify actualimage/module/mode/UID, health/readiness and installed purpose refusals on the real placement; explicitly distinguish synthetic-transport checks from actual provider evidence. Existing native binding/lifecycle behavior must remain available. If unhealthy or verification fails, return Application source to7db8485 and scoped-sync prior same-schema image7f5c, preserving current evidence database; retain failed outcomes. Any data recovery beyond this same-schema image rollback is a separate founder decision.\n\n## Alternatives and estimates\n\nProceed with this narrow release plus explicit inherited-medium follow-through, or defer and prepare a separate base/dependency refresh before any release. No additional recurring hosting is proposed: estimated incremental infrastructure EUR0, with private storage and attended engineering/recovery time unpriced. Risks include a brief Recreate interruption, private backup custody errors, caller refusal when advisory responses were improperly treated as binding, and the disclosed inherited finding. This decision does not promote agent autonomy or grant unrelated work.\n\n## Independent review refinements\n\nThe initial36path/20document packet at manifest7c6738b3 and submissionac41c8ae is preserved in source preparation evidence, with the failed/conditional review. Independent Platform review identified admin auto-migration, optimization bypass, and actual same-name ConfigMap/PVC replacement gaps. The amended packet adds pre-open stdlib read-only schema/integrity/count gates, explicit local/remote optimization refusal, and independently sealed actual native config/PVC custody checks. These are refinements in the same proposal/trial, with no original or amended founder approval claimed.\n\n## Mechanically bound helper and recovery refinement\n\nThe directly attached execution-bundle.json binds exact supervised helper sources, plan, tests and PENDING authority template. It verifies all four committed owner Kustomize inputs and rejects present automated:{} as well as source overrides. Root must freshly authenticate the exact founder native disposition before every phase; receipt bookkeeping is not an autonomous signed grant. The same proposal/trial preserves the earlier36path7c packet, amended78pathb1 packet and original11file653 helper plus conditional review findings.\n\nThe offline copy uses one UID0/CAP_CHOWN-only initializer confined to the NEW nonce-bound local volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/livePVC/config/token mounts. All following pre-open/admin/post-open checks are UID10001. Post-admin readonly schema5/integrity/counts must match the frozen snapshot and original snapshot SHA must remain unchanged. Rollback dispatch never requires the failing candidate to be Ready or opens its database; seals/source/image pair/admission CAS still gate it. A separate rollback-verify proves recovered old-image Ready1/scoped operation/schema5 retained-current-DB integrity. Same-phase retries are refused after ambiguous outcomes.\n\nRaw scan/SBOM/base-scan bytes remain retained unchanged, hash-bound by the directly attached published-verification receipt; the bundle replaces only the direct raw scan attachment to stay within twenty documents. Known fixable inherited MEDIUM and T05 follow-through remain visible. Ten installed synthetic checks, including those later on actual placement, explicitly have native_provider=false. Actual provider/PDP authority evidence is a distinct T04 completion gate and is not supplied by these checks. Source preparation basis e0359bcb6cdfad9ab3e868054121fe0cebec2d68 plus9268c9ac0bbee508fe35c0b90dcefef4c24da2f5 is recorded; the final applied owner commit must be pinned before execution.\n" + }, + { + "item_id": "proposal-json", + "media_type": "application/json", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"authority\": \"ADMINISTER; activation APPROVED only upon exact founder disposition\",\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"published_source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"prior_argo_revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"native_object\": {\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"namespace\": \"informed-decision\",\n \"name\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"argo_application_uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"source_gate\": \"All four exact committed owner Kustomize input blobs in execution-plan.json and clean current owner HEAD must match; source preparation is not native approval\",\n \"sync_scope\": [\n \"apps:Deployment:informed-decision\"\n ],\n \"prune\": false,\n \"automated_sync\": false,\n \"runtime_configmap\": \"informed-decision-runtime-6c221878d051\",\n \"schema\": 5,\n \"requested_operations\": [\n \"Protected SQLite-consistent native backup and independently protected off-cluster custody\",\n \"Offline restore/integrity/count comparison on a private disposable volume with exact candidate, no runtime tokens/config/network\",\n \"Refresh a consistent pre-cutover snapshot, retain private copies and count-only/hash receipts\",\n \"Pin existing manual Argo Application to exact approved owner source and manually sync only existing Deployment image\",\n \"Verify health/readiness/image/module/installed fail-closed purpose checks and retained schema/count evidence; recover to prior same-schema image if needed\"\n ],\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"temporary_vulnerability_review_due\": \"2026-10-18\",\n \"known_scan_findings\": \"0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical\",\n \"vulnerability_record\": \"INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05\",\n \"cost_estimate_EUR\": 0,\n \"cost_limits\": \"No new recurring infrastructure; private backup storage and attended engineering/recovery time unpriced, not an autopilot cost grant\",\n \"risk_estimates\": [\n \"Brief Recreate service interruption; no concurrent new writer/surge\",\n \"Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence\",\n \"Candidate purpose refusal may expose callers relying on advisory results as binding\",\n \"Inherited known fixable MEDIUM remains until separately approved owner remediation\",\n \"Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted\",\n \"All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller.\"\n ],\n \"rollback\": \"Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes\",\n \"native_executed\": false,\n \"human_approval\": false,\n \"refinement_of_manifest\": \"7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300\",\n \"mandatory_pre_open_gate\": \"stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration\",\n \"optimized_interpreters\": \"local+remote explicitlyrefused beforeassert gates\",\n \"native_dependency_gate\": \"sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads\",\n \"live_counts\": \"Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained\",\n \"source_basis\": {\n \"reviewed_protocol_commit\": \"e0359bcb6cdfad9ab3e868054121fe0cebec2d68\",\n \"owner_followthrough_commit\": \"9268c9ac0bbee508fe35c0b90dcefef4c24da2f5\",\n \"final_execution_source\": \"exact subsequent root-applied source commit must be bound by founder receipt and verified against four approved Git blobs\"\n },\n \"approved_owner_render_blob_sha256\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"execution_bundle_sha256\": \"27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d\",\n \"execution_helper_manifest_sha256\": \"f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c\",\n \"execution_plan_sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\",\n \"execution_phases\": [\n \"drill-backup\",\n \"drill-copy\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\",\n \"offline_initializer\": \"One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.\",\n \"rollback_dispatch\": \"Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.\",\n \"purpose_proof_limit\": \"Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.\",\n \"refinement_of_amended_manifest\": \"b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033\"\n}\n" + }, + { + "item_id": "candidate-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "rollback-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "candidate-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "rollback-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "published-verification-json", + "media_type": "application/json", + "content": "{\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"observed_at\": \"2026-10-11T01:24:01.985128+00:00\",\n \"native_owner_publication_job\": {\n \"id\": 11484,\n \"name\": \"publish-candidate\",\n \"head_branch\": \"main\",\n \"head_sha\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"run_number\": 3,\n \"event\": \"push\",\n \"display_title\": \"Prepare readable overlay context with the admitted legacy builder\",\n \"status\": \"success\",\n \"workflow_id\": \"purpose-overlay-image.yaml\",\n \"url\": \"https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3\",\n \"created_at\": \"2026-10-11T01:20:59Z\",\n \"updated_at\": \"2026-10-11T01:21:08Z\",\n \"run_started_at\": \"2026-10-11T01:20:59Z\"\n },\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"registry_proof_sha256\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"source_render_change_only\": \"Deployment/informed-decision spec.template.spec.containers[0].image\",\n \"runtime_configmap_unchanged\": \"informed-decision-runtime-6c221878d051\",\n \"installed_image_execution\": {\n \"immutable_registry_artifact_pulled_anonymously\": true,\n \"UID\": 10001,\n \"GID\": 10001,\n \"policy_file_UID\": 0,\n \"policy_file_mode\": \"0644\",\n \"purpose_variants\": 10,\n \"binding_forms_allowed\": 2,\n \"advisory_or_malformed_refused\": 8,\n \"network\": \"none\",\n \"read_only\": true,\n \"synthetic_transport\": true,\n \"native_PDP_test\": false\n },\n \"scan_summary_sha256\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\",\n \"historical_failed_runs_retained\": [\n \"f66de505/task11482/run1\",\n \"acecad887/task11483/run2\"\n ],\n \"native_hosting_changed\": false,\n \"native_backup_restore_executed\": false,\n \"human_approval\": false,\n \"evidence_file_sha256\": {\n \"image-manifest.json\": \"978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb\",\n \"image-config.json\": \"4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10\",\n \"base-image-config.json\": \"b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00\",\n \"registry-proof.json\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"trivy-full.json\": \"f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e\",\n \"sbom.cdx.json\": \"a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d\",\n \"base-trivy-full.json\": \"d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"verify_registry.py\": \"413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4\",\n \"sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"review-refinement.json\": \"ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75\",\n \"test_change_guard.py\": \"da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f\",\n \"test_sqlite_readonly.py\": \"c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323\",\n \"test_preflight_optimization.py\": \"a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d\"\n }\n}\n" + }, + { + "item_id": "registry-proof-json", + "media_type": "application/json", + "content": "{\n \"image_digest\": \"sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"base_image_digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"base_layer_bytes_identical\": true,\n \"layer_media_type_conversion\": \"OCI gzip to Docker gzip, same digest and size\",\n \"base_runtime_config_semantics_identical\": true,\n \"legacy_builder_config_additions\": {\n \"Hostname\": \"\",\n \"Domainname\": \"\",\n \"AttachStdin\": false,\n \"AttachStdout\": false,\n \"AttachStderr\": false,\n \"Tty\": false,\n \"OpenStdin\": false,\n \"StdinOnce\": false,\n \"Cmd\": null,\n \"Volumes\": null,\n \"OnBuild\": null,\n \"Image\": \"sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883\"\n },\n \"base_rootfs_prefix_identical\": true,\n \"overlay_regular_files\": [\n \"opt/venv/lib/python3.12/site-packages/informed_decision/policy.py\"\n ],\n \"overlay_directories\": [\n \"opt\",\n \"opt/venv\",\n \"opt/venv/lib\",\n \"opt/venv/lib/python3.12\",\n \"opt/venv/lib/python3.12/site-packages\",\n \"opt/venv/lib/python3.12/site-packages/informed_decision\"\n ],\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"policy_mode\": \"0644\",\n \"base_user\": \"10001:10001\",\n \"source_scope_labels\": {\n \"org.opencontainers.image.revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"org.opencontainers.image.base.digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"social.coulomb.source.policy.sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"social.coulomb.release.scope\": \"INFD-WP-0009-T04/purpose-overlay-v1\"\n },\n \"registry_read_route\": \"anonymous public scoped bearer challenge, no token retention\",\n \"image_executed\": false,\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false\n}\n" + }, + { + "item_id": "security-summary-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"scanner\": \"aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969\",\n \"version\": \"0.74.0\",\n \"db_metadata\": {\n \"Version\": 2,\n \"NextUpdate\": \"2026-10-11T18:59:50.889010572Z\",\n \"UpdatedAt\": \"2026-10-10T18:59:50.889010923Z\",\n \"DownloadedAt\": \"2026-10-10T23:32:32.380033131Z\"\n },\n \"suppression\": false,\n \"ignore_unfixed\": false,\n \"severity_filter\": null,\n \"package_count\": 44,\n \"findings_by_severity\": {\n \"MEDIUM\": 1\n },\n \"findings\": [\n {\n \"id\": \"CVE-2026-85091\",\n \"package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"severity\": \"MEDIUM\"\n }\n ],\n \"coverage_limits\": [\n \"Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages\",\n \"Known findings asof pinnedDB, not claim absence of unknown vulnerabilities\"\n ],\n \"high_critical\": 0,\n \"same_scanner_actual_base_scan_findings_identical\": true,\n \"base_scan_file\": \"base-trivy-full.json\"\n}\n" + }, + { + "item_id": "execution-bundle-json", + "media_type": "application/json", + "content": "{\n \"kind\": \"informed-decision.execution-source-bundle\",\n \"version\": 1,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"files\": {\n \"README.md\": {\n \"sha256\": \"a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2\",\n \"content\": \"# Supervised Informed Decision purpose release executor — unapproved preparation\\n\\nNo native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor.\\n\\nRun one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion.\\n\\nInvocation after actual approval: `python3 execution/actuator.py --phase --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase.\\n\\nThe private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence.\\n\\nNew private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required.\\n\\nEvery phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions.\\n\\nExisting Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes.\\n\\nSixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof.\\n\\nAll phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance.\\n\\nThe initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred.\\n\"\n },\n \"actuator.py\": {\n \"sha256\": \"6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5\",\n \"content\": \"\\\"\\\"\\\"One fixed supervised phase; never run this during source preparation.\\\"\\\"\\\"\\nimport argparse\\nimport hashlib\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport re\\nimport selectors\\nimport stat\\nimport subprocess\\nimport sys\\nimport time\\n\\nif sys.flags.optimize:\\n raise SystemExit('optimized interpreter refused')\\n\\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\nROOT = Path(__file__).resolve().parent\\nCASE = ROOT.parent\\nOWNER = Path('/home/worsch/informed-decision')\\nCUSTODIAN = Path('/home/worsch/the-custodian')\\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\\nSOCKET = 'unix:///var/run/docker.sock'\\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\\nVOLUME = 'infd-purpose-r1-restore-20261011'\\nMAX_BYTES = 512 * 1024**2\\n\\n\\ndef run(argv, body=None, timeout=90):\\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\\n\\n\\ndef json_result(result):\\n try:\\n value = json.loads(result.stdout)\\n except (ValueError, TypeError):\\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\\n 'phase did not verify complete; raw output withheld; no retry')\\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\\n require(set(value) <= permitted, 'unexpected output fields withheld')\\n from receipt_safety import counts\\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\\n if name in value:\\n counts(value[name])\\n for name in ('snapshot_sha256', 'client_diff_sha256'):\\n if name in value:\\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\\n if 'snapshot_bytes' in value:\\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\\n 'invalid output size withheld')\\n if 'snapshot_file' in value:\\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\\n return value\\n\\n\\ndef docker(argv, body=None, timeout=120):\\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\\n body=body, timeout=timeout)\\n\\n\\ndef remote(phase, revision, approved):\\n # Fixed module imported only after main verifies every executor source hash.\\n from native_program import PROGRAM\\n payload = {'phase': phase, 'source_revision': revision, 'approval': approved,\\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\\n\\n\\ndef copy_snapshot(phase, revision, approved, journal):\\n metadata = remote(phase, revision, approved)\\n backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup'\\n prior = journal.data['phases'][backup_phase]['result']\\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\\n name = metadata['snapshot_file']\\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\\n 'fixed bounded snapshot required')\\n pod = metadata['pod_name']\\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\\n local = CUSTODY / name\\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\\n # Snapshot schema/count metadata was validated before opening this destination.\\n with os.fdopen(fd, 'wb') as destination:\\n command = ('kubectl exec -n informed-decision ' + pod +\\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\\n stderr=subprocess.DEVNULL)\\n selector = selectors.DefaultSelector()\\n selector.register(transfer.stdout, selectors.EVENT_READ)\\n deadline = time.monotonic() + 150\\n received = 0\\n try:\\n while True:\\n remaining = deadline - time.monotonic()\\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\\n block = os.read(transfer.stdout.fileno(), 1024**2)\\n if not block:\\n break\\n received += len(block)\\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\\n 'private copy exceeds frozen snapshot size')\\n destination.write(block)\\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\\n finally:\\n selector.close()\\n transfer.stdout.close()\\n if transfer.poll() is None:\\n transfer.kill()\\n transfer.wait()\\n destination.flush()\\n os.fsync(destination.fileno())\\n private(local)\\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\\n # Re-read identity/hash after transfer. This is verification, not a write retry.\\n after = remote(phase, revision, approved)\\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\\n 'source identity/snapshot changed during transfer')\\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\\n\\n\\ndef offline_verify(journal):\\n from receipt_safety import counts\\n snapshot = CUSTODY / 'drill.sqlite'\\n private(snapshot)\\n previous = journal.data['phases']['drill-copy']['result']\\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\\n identity = docker(['info', '--format', '{{json .Name}}'])\\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\\n 'local offline Docker engine identity changed')\\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\\n 'disposable volume absence not verified')\\n nonce = journal.data['phases']['offline-verify']['attempt_id']\\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\\n '--label', 'informed-decision.attempt=' + nonce,\\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'new volume identity unavailable')\\n volume = json.loads(inspected.stdout)\\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\\n journal.note('offline-verify', 'created_volume_identity', identity)\\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\\n # No host/live PVC/config/token mount exists; this detail needs packet review.\\n initializer = \\\"\\\"\\\"import hashlib,os,stat,sys\\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\\nfolder='/restore';expected=EXPECTED\\nif os.listdir(folder):raise ValueError('new empty private volume required')\\nos.chmod(folder,0o700)\\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\\ndigest=hashlib.sha256();size=0\\nwith os.fdopen(fd,'wb') as target:\\n while True:\\n block=sys.stdin.buffer.read(1024**2)\\n if not block:break\\n size+=len(block)\\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\\n target.write(block);digest.update(block)\\n target.flush();os.fsync(target.fileno())\\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\\nprint('{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}')\\n\\\"\\\"\\\".replace('EXPECTED', repr(previous['snapshot_sha256']))\\n with snapshot.open('rb') as source:\\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\\n '--entrypoint', 'python', IMAGE, '-c', initializer]\\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\\n json_result(copied)\\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\\n checked = counts(json.loads(readonly.stdout))\\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\\n 'inspect', '--db', '/restore/review.sqlite'])\\n require(admin.returncode == 0, 'offline admin result uncertain')\\n admin_counts = json.loads(admin.stdout)\\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\\n 'offline admin changed frozen snapshot counters')\\n # Admin Store construction must not silently alter schema/integrity/counters.\\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\\n post_checked = counts(json.loads(post.stdout))\\n require(post_checked == checked == previous['snapshot_readonly'],\\n 'offline admin altered frozen snapshot proof')\\n private(snapshot)\\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\\n 'created_volume_identity': identity,\\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\\n\\n\\ndef cleanup_offline(journal):\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\\n value = json.loads(inspected.stdout)\\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\\n and not value[0].get('Options'), 'volume ownership/recreation changed')\\n removed = docker(['volume', 'rm', VOLUME])\\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\\n 'cleanup outcome ambiguous; do not retry')\\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\\n 'native_and_offcluster_original_snapshots_retained': True}\\n\\n\\ndef main():\\n parser = argparse.ArgumentParser(description=__doc__)\\n parser.add_argument('--phase', choices=PHASES, required=True)\\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\\n parser.add_argument('--root-native-outcome', type=Path, required=True)\\n parser.add_argument('--source-revision', required=True)\\n args = parser.parse_args()\\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\\n 'fixed supervised receipt paths required')\\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\\n # Verify all prepared executor/input bytes before reading authority or dispatching.\\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\\n 'fixed executor sources required')\\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\\n 'deploy/lifecycle/service.candidate.json',\\n 'deploy/lifecycle/kustomization.yaml',\\n 'deploy/lifecycle/registries.candidate.json'},\\n 'fixed owner image sources required')\\n for relative, digest in plan['executor_files'].items():\\n target = ROOT / relative\\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\\n for relative, digest in plan['case_files'].items():\\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\\n 'case source path escaped')\\n target = CASE / relative\\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\\n for relative, digest in plan['owner_source_files'].items():\\n target = OWNER / relative\\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\\n capture_output=True)\\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\\n 'committed owner render source differs from approved inputs')\\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\\n from authority_journal import Journal, authority\\n private(args.root_authority_receipt)\\n private(args.root_native_outcome)\\n receipt = json.loads(args.root_authority_receipt.read_text())\\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\\n 'root verified executor plan differs')\\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\\n args.source_revision, args.phase)\\n parent = CUSTODY.parent\\n private(parent, directory=True)\\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\\n if not CUSTODY.exists():\\n require(args.phase == 'drill-backup', 'first approved phase must create unique private custody')\\n os.mkdir(CUSTODY, 0o700)\\n private(CUSTODY, directory=True)\\n capacity = os.statvfs(CUSTODY)\\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\\n 'independent protected custody headroom insufficient')\\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\\n private(CUSTODY / 'empty-docker-config', directory=True)\\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')})\\n try:\\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\\n if args.phase in ('drill-copy', 'cutover-copy'):\\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\\n elif args.phase == 'offline-verify':\\n result = offline_verify(journal)\\n elif args.phase == 'cleanup-offline':\\n result = cleanup_offline(journal)\\n else:\\n result = remote(args.phase, args.source_revision, approved)\\n journal.finish(args.phase, result)\\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\\n except BaseException as error:\\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\\n 'raw_output_withheld': True}\\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\\n journal.finish(args.phase, safe)\\n print(json.dumps(safe))\\n raise SystemExit(1) from None\\n finally:\\n journal.close()\\n\\n\\nif __name__ == '__main__':\\n try:\\n main()\\n except Exception:\\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\\n\"\n },\n \"authority_journal.py\": {\n \"sha256\": \"74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa\",\n \"content\": \"\\\"\\\"\\\"Supervised receipt bookkeeping, not an authenticated approval provider.\\\"\\\"\\\"\\nimport datetime\\nimport fcntl\\nimport hashlib\\nimport json\\nimport os\\nimport re\\nfrom pathlib import Path\\nimport stat\\nimport uuid\\n\\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\n\\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\\n \\\"\\\"\\\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\\n\\n Receipt files/flags are not signed grants. This function checks the exact\\n supervised receipt relation; existing harness/founder authority remains the\\n actual permission boundary. It never authenticates a caller as human.\\n \\\"\\\"\\\"\\n now = now or datetime.datetime.now(datetime.timezone.utc)\\n require(phase in PHASES, 'fixed phase required')\\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\\n and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha\\n and receipt.get('source_revision') == source_revision\\n and receipt.get('activation') == 'APPROVED'\\n and receipt.get('authority_mode') == 'ADMINISTER'\\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\\n and receipt.get('runtime_authenticated_grant') is False,\\n 'exact externally verified supervised receipt required')\\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\\n 'fresh root native readback required before every phase')\\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\\n require(now < deadline, 'approved execution window expired')\\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\\n review_id = outcome['review']['memo_id']\\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\\n accepted = [x for x in outcome.get('dispositions', [])\\n if x.get('submission_state') == 'confirmed'\\n and x.get('disposition', {}).get('verb') == 'accept'\\n and x['disposition'].get('memo_version') == 1]\\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\\n accepted = accepted[0]['disposition']\\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\\n and accepted.get('approval_id') == receipt.get('approval_id')\\n and accepted.get('id') == receipt.get('disposition_id')\\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\\n 'native disposition identifiers are malformed')\\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\\n\\n\\nclass Journal:\\n def __init__(self, parent, identity):\\n self.parent = Path(parent)\\n private(self.parent, directory=True)\\n self.path = self.parent / 'execution-journal.json'\\n self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\\n private(self.parent / 'execution.lock')\\n if self.path.exists():\\n private(self.path)\\n self.data = json.loads(self.path.read_text())\\n require(self.data['identity'] == identity, 'journal case/source identity changed')\\n else:\\n self.data = {'identity': identity, 'phases': {}}\\n self.save()\\n\\n def save(self):\\n temporary = self.parent / 'execution-journal.new'\\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\\n try:\\n with os.fdopen(fd, 'w') as stream:\\n json.dump(self.data, stream, indent=2)\\n stream.write('\\\\n')\\n stream.flush()\\n os.fsync(stream.fileno())\\n os.replace(temporary, self.path)\\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\\n try:\\n os.fsync(directory)\\n finally:\\n os.close(directory)\\n except BaseException:\\n # Retain evidence rather than overwriting an uncertain durable intent.\\n raise\\n\\n def start(self, phase, approval):\\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\\n predecessors = dict(zip(PHASES[1:8], PHASES[:7]))\\n predecessors['rollback-verify'] = 'rollback'\\n if phase in predecessors:\\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\\n 'preceding phase is not verified complete')\\n if phase == 'rollback':\\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\\n 'attempt_id': str(uuid.uuid4()),\\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\\n self.save()\\n\\n def note(self, phase, key, value):\\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\\n self.data['phases'][phase][key] = value\\n self.save()\\n\\n def finish(self, phase, result):\\n entry = self.data['phases'][phase]\\n require(entry['state'] == 'RUNNING', 'phase intent missing')\\n entry['result'] = result\\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\\n self.save()\\n\\n def close(self):\\n os.close(self.lock)\\n\"\n },\n \"execution-plan.json\": {\n \"sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\",\n \"content\": \"{\\n \\\"kind\\\": \\\"informed-decision.supervised-mechanical-release-plan\\\",\\n \\\"version\\\": 1,\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"trial_id\\\": \\\"infd-purpose-20261011-r1\\\",\\n \\\"state\\\": \\\"prepared-unapproved\\\",\\n \\\"executor_files\\\": {\\n \\\"actuator.py\\\": \\\"6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5\\\",\\n \\\"authority_journal.py\\\": \\\"74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa\\\",\\n \\\"native_program.py\\\": \\\"349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde\\\",\\n \\\"receipt_safety.py\\\": \\\"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\\\"\\n },\\n \\\"case_files\\\": {\\n \\\"change_guard.py\\\": \\\"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\\\",\\n \\\"sqlite_readonly.py\\\": \\\"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\\\",\\n \\\"preflight-inputs.json\\\": \\\"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\\\",\\n \\\"sealed-live-deployment.json\\\": \\\"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\\\",\\n \\\"sealed-native-dependencies.json\\\": \\\"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\\\",\\n \\\"candidate-deployment.json\\\": \\\"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\\\",\\n \\\"rollback-deployment.json\\\": \\\"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\\\",\\n \\\"check_installed.py\\\": \\\"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\\\",\\n \\\"published-verification.json\\\": \\\"8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2\\\",\\n \\\"security-summary.json\\\": \\\"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\\\"\\n },\\n \\\"owner_source_files\\\": {\\n \\\"deploy/lifecycle/admission.candidate.json\\\": \\\"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\\\",\\n \\\"deploy/lifecycle/service.candidate.json\\\": \\\"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\\\",\\n \\\"deploy/lifecycle/kustomization.yaml\\\": \\\"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\\\",\\n \\\"deploy/lifecycle/registries.candidate.json\\\": \\\"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\\\"\\n },\\n \\\"candidate_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\\\",\\n \\\"prior_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\\",\\n \\\"source_revision\\\": \\\"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\\\",\\n \\\"phases\\\": [\\n \\\"drill-backup\\\",\\n \\\"drill-copy\\\",\\n \\\"offline-verify\\\",\\n \\\"cleanup-offline\\\",\\n \\\"cutover-backup\\\",\\n \\\"cutover-copy\\\",\\n \\\"release\\\",\\n \\\"verify\\\",\\n \\\"rollback\\\",\\n \\\"rollback-verify\\\"\\n ],\\n \\\"authorization\\\": \\\"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\\\",\\n \\\"execute_by\\\": \\\"2026-10-12T23:59:59Z\\\",\\n \\\"raw_output_withheld\\\": true,\\n \\\"native_data_or_workload_action_executed\\\": false,\\n \\\"deadline_semantics\\\": \\\"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\\\"\\n}\\n\"\n },\n \"native_program.py\": {\n \"sha256\": \"349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde\",\n \"content\": \"\\\"\\\"\\\"Fixed remote source, passed only after exact supervised approval.\\\"\\\"\\\"\\nPROGRAM = '\\\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\\\nif sys.flags.optimize:raise RuntimeError(\\\\'optimized interpreter refused\\\\')\\\\npayload=json.loads(__PAYLOAD__)\\\\nexec(__GUARD__)\\\\nphase=payload[\\\\'phase\\\\']\\\\nif phase not in (\\\\'drill-backup\\\\',\\\\'cutover-backup\\\\',\\\\'drill-copy\\\\',\\\\'cutover-copy\\\\',\\\\'release\\\\',\\\\'verify\\\\',\\\\'rollback\\\\',\\\\'rollback-verify\\\\'):raise ValueError(\\\\'fixed native phase required\\\\')\\\\ndeadline=datetime.datetime.fromisoformat(\\\\'2026-10-12T23:59:59+00:00\\\\')\\\\ndef require(value,reason):\\\\n if not value:raise ValueError(reason)\\\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\\\'drill-backup\\\\' else 1)+16*1024**2,\\\\'bounded native snapshot capacity required\\\\')\\\\n if action==\\\\'drill-backup\\\\':\\\\n require(not os.path.lexists(folder),\\\\'native case directory must be unique\\\\')\\\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\\\n private(folder,True)\\\\n filename=\\\\'drill.sqlite\\\\' if action==\\\\'drill-backup\\\\' else \\\\'cutover.sqlite\\\\';output=folder+\\\\'/\\\\'+filename\\\\n require(not os.path.lexists(output),\\\\'snapshot output must be unique\\\\')\\\\n admin=subprocess.run([\\\\'informed-decision-admin\\\\',\\\\'backup\\\\',\\\\'--db\\\\',db,\\\\'--output\\\\',output],capture_output=True,text=True,timeout=120)\\\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\\\'status\\\\':\\\\'backed_up\\\\',\\\\'consistent_snapshot\\\\':True},\\\\'backup completion not verified; do not retry\\\\')\\\\n private(output)\\\\n for suffix in (\\\\'-wal\\\\',\\\\'-shm\\\\'):\\\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\\\'snapshot is not closed main-file custody\\\\')\\\\n snapshot=counts(inspect_readonly(output))\\\\n size=os.stat(output).st_size;require(0 10**12\\n for number in value[group].values()):\\n raise ValueError('count-only receipt values refused')\\n return value\\n\"\n },\n \"root-authority-receipt-template.json\": {\n \"sha256\": \"15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813\",\n \"content\": \"{\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"memo_id\\\": \\\"infd-20261011-purpose-overlay-r1\\\",\\n \\\"memo_version\\\": 1,\\n \\\"memo_sha256\\\": null,\\n \\\"source_revision\\\": null,\\n \\\"activation\\\": \\\"PENDING\\\",\\n \\\"authority_mode\\\": \\\"ADMINISTER\\\",\\n \\\"target\\\": \\\"realm:kubernetes/railiance01/informed-decision\\\",\\n \\\"verification_method\\\": \\\"root-fixed-origin-native-readback\\\",\\n \\\"runtime_authenticated_grant\\\": false,\\n \\\"verified_at\\\": null,\\n \\\"accepted_at\\\": null,\\n \\\"review_memo_id\\\": null,\\n \\\"approval_id\\\": null,\\n \\\"disposition_id\\\": null,\\n \\\"native_outcome_sha256\\\": null,\\n \\\"executor_plan_sha256\\\": \\\"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\\\"\\n}\\n\"\n },\n \"test_execution.py\": {\n \"sha256\": \"9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48\",\n \"content\": \"\\\"\\\"\\\"Synthetic custody/transport tests. No native data, Docker or cluster action.\\\"\\\"\\\"\\nimport copy\\nimport datetime\\nimport io\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport subprocess\\nimport sys\\nimport tempfile\\nimport unittest\\nfrom unittest.mock import patch\\nfrom contextlib import redirect_stdout\\n\\nimport actuator\\nfrom authority_journal import Journal, authority\\nfrom native_program import PROGRAM\\nfrom receipt_safety import counts\\n\\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\\nREVISION = 'e' * 40\\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\\n\\n\\ndef accepted():\\n approval = '11111111-1111-4111-8111-111111111111'\\n review = 'review-22222222-2222-4222-8222-222222222222'\\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1,\\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False,\\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\\n 'approval_id': approval, 'id': disposition,\\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\\n 'at': receipt['accepted_at']}}]}\\n return receipt, outcome\\n\\n\\nclass AuthorityAndCustody(unittest.TestCase):\\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\\n receipt, outcome = accepted()\\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW)\\n self.assertEqual(result['approval_id'], receipt['approval_id'])\\n\\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\\n mutations = [lambda r, o: r.update(activation='PENDING'),\\n lambda r, o: r.update(memo_sha256='changed'),\\n lambda r, o: r.update(source_revision='changed'),\\n lambda r, o: r.update(target='other'),\\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\\n lambda r, o: r.update(verification_method='caller-asserted'),\\n lambda r, o: r.update(runtime_authenticated_grant=True),\\n lambda r, o: o['review'].update(stale=True),\\n lambda r, o: o['review'].update(intake_state='pending'),\\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2),\\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n r, o = accepted()\\n mutate(r, o)\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\\n\\n def test_expired_window_and_unknown_phase_refuse(self):\\n r, o = accepted()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\\n r['verified_at'] = late.isoformat()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\\n\\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\\n with tempfile.TemporaryDirectory() as directory:\\n parent = Path(directory)\\n os.chmod(parent, 0o700)\\n journal = Journal(parent, {'case': 'fixture'})\\n journal.start('drill-backup', {'approval_id': 'fixture'})\\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING')\\n journal.close() # simulated crash before result\\n recovered = Journal(parent, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-backup', {})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-copy', {})\\n recovered.close()\\n\\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\\n with tempfile.TemporaryDirectory() as directory:\\n os.chmod(directory, 0o700)\\n j = Journal(directory, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n for phase in actuator.PHASES[:6]:\\n j.start(phase, {})\\n j.finish(phase, {'all_checks_pass': True})\\n j.start('release', {})\\n j.finish('release', {'all_checks_pass': False})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n with self.assertRaises(ValueError):\\n j.start('verify', {})\\n j.start('rollback', {})\\n j.finish('rollback', {'all_checks_pass': True})\\n j.close()\\n\\n def test_secret_or_unknown_child_output_is_withheld(self):\\n for body in ('not-json', '{\\\"all_checks_pass\\\":true,\\\"token\\\":\\\"private-value\\\"}',\\n '{\\\"all_checks_pass\\\":true,\\\"snapshot_readonly\\\":{\\\"schema_version\\\":5}}'):\\n with self.assertRaises(ValueError):\\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\\n wrong = copy.deepcopy(COUNT)\\n wrong['outbox'] = {'private-row-value': 1}\\n with self.assertRaises(ValueError):\\n counts(wrong)\\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\\n\\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\\n blob = b'synthetic private fixture bytes'\\n digest = __import__('hashlib').sha256(blob).hexdigest()\\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\\n journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})()\\n real_popen = subprocess.Popen\\n for extra in (b'', b'oversized'):\\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\\n os.chmod(folder, 0o700)\\n output = io.StringIO()\\n\\n def child(*args, **kwargs):\\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\\n\\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\\\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\\n if extra:\\n with self.assertRaises(ValueError):\\n actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\\n else:\\n result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\\n self.assertTrue(result['off_cluster_private_copy_verified'])\\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\\n self.assertEqual(output.getvalue(), '')\\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\\n\\n def test_recreated_offline_volume_cannot_be_deleted(self):\\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\\n journal = type('FixtureJournal', (), {'data': {'phases': {\\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\\n with self.assertRaises(ValueError):\\n actuator.cleanup_offline(journal)\\n self.assertEqual(mocked.call_count, 1)\\n\\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\\n for defect in ('none', 'post-integrity', 'original-hash'):\\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\\n folder=Path(directory);os.chmod(folder,0o700)\\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\\n digest=actuator.sha(snapshot)\\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\\n reads=[]\\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\\n def docker(argv, body=None, **kwargs):\\n if argv[0]=='info':body=json.dumps('bnt-lap001')\\n elif argv[:2]==['volume','ls']:body=''\\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\\n elif 'informed-decision-admin' in argv:\\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\\n elif '--entrypoint' in argv and 'python' in argv:\\n reads.append(argv);proof=copy.deepcopy(COUNT)\\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\\n body=json.dumps(proof)\\n else:raise AssertionError('unexpected offline command')\\n return subprocess.CompletedProcess(argv,0,body,'')\\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}','')):\\n if defect=='none':\\n result=actuator.offline_verify(journal)\\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\\n self.assertTrue(result['original_snapshot_hash_unchanged'])\\n else:\\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\\n self.assertEqual(len(reads),2)\\n\\n\\nclass FixedNativeProgram(unittest.TestCase):\\n def fixture(self):\\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\\n live = copy.deepcopy(sealed)\\n live['metadata'].update(generation=42)\\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\\n cm = copy.deepcopy(dependencies['configmap'])\\n cm.pop('canonical_data_sha256')\\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\\n pvc = copy.deepcopy(dependencies['pvc'])\\n pvc['status'] = {'phase': 'Bound'}\\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\\n 'dependencies': dependencies, 'candidate': service,\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\\n return objects, payload\\n\\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\\n writes = []\\n calls = []\\n\\n def fake(argv, input=None, **kwargs):\\n calls.append(argv)\\n if argv[:2] == ['kubectl', 'get']:\\n kind = argv[2]\\n if kind in objects:\\n body = objects[kind]\\n elif kind == 'pods':\\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\\n 'spec': objects['deployment']['spec']['template']['spec'],\\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\\n elif kind == 'replicaset':\\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\\n elif kind == 'nodes':\\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\\n else:\\n raise AssertionError('unexpected fixed metadata route')\\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\\n if argv[:2] == ['kubectl', 'exec']:\\n if schema_refused:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, json.dumps({\\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\\n if argv[:2] == ['kubectl', 'apply']:\\n admitted = copy.deepcopy(payload['sealed'])\\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\\n if argv[:2] == ['kubectl', 'describe']:\\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\\\n cpu 3460m (86%)\\\\n', '')\\n if argv[:2] == ['kubectl', 'diff']:\\n return subprocess.CompletedProcess(argv, 1, '-image: base\\\\n+image: candidate\\\\n', '')\\n if argv[:2] == ['kubectl', 'patch']:\\n if '--dry-run=server' not in argv:\\n writes.append(json.loads(input))\\n if ambiguous:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\\\n', '')\\n raise AssertionError('unexpected command')\\n\\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n output = io.StringIO()\\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\\n try:\\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\\n except (ValueError, SystemExit):\\n pass\\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\\n return receipt, writes, calls\\n\\n def test_only_existing_application_operation_and_deployment_are_requested(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n operation = writes[0][-1]['value']\\n self.assertFalse(operation['sync']['prune'])\\n self.assertEqual(operation['sync']['resources'], [\\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\\n\\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\\n lambda o: o['application']['spec'].update(sources=[{}]),\\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n objects, payload = self.fixture()\\n mutate(objects)\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n def test_preopen_schema_refusal_prevents_image_operation(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n\\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\\n objects, payload = self.fixture()\\n payload['phase'] = 'rollback'\\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\\n objects['application']['spec']['source']['targetRevision'] = REVISION\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\\n\\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\\n for defect in ('cm', 'pvc', 'image'):\\n with self.subTest(defect=defect):\\n objects, payload = self.fixture();payload['phase'] = 'rollback'\\n objects['deployment']['status']['readyReplicas'] = 0\\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\\n\\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\\n self.assertEqual(writes, [])\\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\\n objects['deployment']['status']['readyReplicas'] = 0\\n receipt, writes, calls = self.execute_fake(objects,payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n\\n def test_ambiguous_patch_is_never_retried(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(len(writes), 1)\\n\\n\\nif __name__ == '__main__':\\n unittest.main()\\n\"\n },\n \"validation.json\": {\n \"sha256\": \"26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28\",\n \"content\": \"{\\n \\\"tests\\\": 16,\\n \\\"result\\\": \\\"passed\\\",\\n \\\"synthetic_transport_only\\\": true,\\n \\\"real_native_data_read\\\": false,\\n \\\"native_backup_export_restore_executed\\\": false,\\n \\\"native_workload_changed\\\": false,\\n \\\"actual_founder_approval\\\": false,\\n \\\"local_read_only_capability_checks\\\": [\\n \\\"argocdCLI absent, existingApplication.operation path retained\\\",\\n \\\"Dockerunixsocket engineName bnt-lap001\\\"\\n ],\\n \\\"case_source_commit_at_preparation\\\": \\\"e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)\\\",\\n \\\"additional_regressions\\\": [\\n \\\"Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation\\\",\\n \\\"rollback still refuses CM/PVC or nonpair-image drift\\\",\\n \\\"separate old-image Ready/schema5 recovery proof\\\",\\n \\\"post-admin readonly integrity refusal and original snapshot tamper refusal\\\"\\n ]\\n}\\n\"\n }\n },\n \"native_execution\": false\n}\n" + }, + { + "item_id": "sqlite-readonly-py", + "media_type": "text/plain", + "content": "\"\"\"Pre-open schema/integrity/count proof; stdlib only, never constructs Store.\"\"\"\nimport argparse\nimport json\nfrom pathlib import Path\nimport sqlite3\n\n\ndef inspect_readonly(path):\n path = Path(path)\n if not path.is_file() or path.is_symlink():\n raise ValueError('existing nonsymlink private database required')\n with sqlite3.connect(path.resolve().as_uri() + '?mode=ro', uri=True, timeout=5) as db:\n db.execute('PRAGMA query_only=ON')\n db.execute('BEGIN')\n version = db.execute('PRAGMA user_version').fetchone()[0]\n if version != 5:\n raise ValueError('pre-open database is not schema5; refuse migration')\n if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]:\n raise ValueError('read-only integrity check refused')\n lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0]\n for name, table in (('records', 'lifecycle_records'),\n ('events', 'lifecycle_events'),\n ('pending', 'lifecycle_pending'))}\n result = {'schema_version': version, 'lifecycle': lifecycle,\n 'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')),\n 'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')),\n 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False}\n db.rollback()\n return result\n\n\nif __name__ == '__main__':\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--db', type=Path, required=True)\n args = parser.parse_args()\n try:\n print(json.dumps(inspect_readonly(args.db), sort_keys=True))\n except Exception:\n raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None\n" + }, + { + "item_id": "sealed-native-dependencies-json", + "media_type": "application/json", + "content": "{\n \"configmap\": {\n \"apiVersion\": \"v1\",\n \"immutable\": true,\n \"kind\": \"ConfigMap\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/ConfigMap:informed-decision/informed-decision-runtime-6c221878d051\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision-runtime-6c221878d051\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\"\n },\n \"canonical_data_sha256\": \"8ec462d12347548f506eeebf1e3c7cc47648019c8a783804d09bcc79b0f22af6\"\n },\n \"pvc\": {\n \"apiVersion\": \"v1\",\n \"kind\": \"PersistentVolumeClaim\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/PersistentVolumeClaim:informed-decision/informed-decision-data\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"pv.kubernetes.io/bind-completed\": \"yes\",\n \"pv.kubernetes.io/bound-by-controller\": \"yes\",\n \"volume.beta.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\",\n \"volume.kubernetes.io/selected-node\": \"239.62.205.92.host.secureserver.net\",\n \"volume.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\"\n },\n \"finalizers\": [\n \"kubernetes.io/pvc-protection\"\n ],\n \"name\": \"informed-decision-data\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n },\n \"spec\": {\n \"accessModes\": [\n \"ReadWriteOnce\"\n ],\n \"resources\": {\n \"requests\": {\n \"storage\": \"1Gi\"\n }\n },\n \"storageClassName\": \"local-path\",\n \"volumeMode\": \"Filesystem\",\n \"volumeName\": \"pvc-d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n }\n },\n \"pvc_phase\": \"Bound\"\n}\n" + }, + { + "item_id": "native-backup-restore-protocol-md", + "media_type": "text/markdown", + "content": "# Protected native backup/restore and image-only release protocol\n\nPrepared protocol for `INFD-WP-0009-T04/purpose-overlay-v1`. No actual native backup, data export, restore, workload change or approval is recorded here. Candidate registry image identity remains a prerequisite; only after actual artifact proof may the founder approve one exact conditional protocol/rollout packet. The config-only7db8485 approval is outside this scope.\n\n## Preconditions and protected custody\n\nFreeze exact candidate and prior7f5c6cb image digests, source/installed policy hashes, current manually managed Argo Application/revision, runtime ConfigMap6c221878d051, Deployment UID/template/spec, schema5, policy package pins, database path `/data/private/review.sqlite`, PVC binding, replicas1/Recreate and stable keys for intended verification. Confirm no concurrent writer or custody change. Use fixed metadata; never fetch Secret objects or token values. A changed image/config/schema/owner invalidates the packet. Fresh resources/headroom and exact source/native server-dry-run/diff remain required.\n\nBackups are private evidence containing real decision records, not logs or packet attachments. Allocate a unique backup directory under existing protected PVC custody, owned10001, mode0700, snapshot file0600, no symlink/hardlink/reused output path. An off-cluster copy belongs only in the already established ignored `.private-backups/` custody with0700/0600 permissions; no Git, StateHub, public object store or terminal-content dump. Record only schema, integrity pass/fail, bounded table/state counts and protected receipt identifier; retain byte digests in protected custody if needed for internal copy identity. No credential, record payload or token fingerprint enters public evidence.\n\n## Approved online compatibility drill\n\nWithin the explicit founder-approved action, run the existing base image's `informed-decision-admin backup --db /data/private/review.sqlite --output ` in the actual serving workload. This uses SQLite's backup API for a transactionally consistent snapshot; copying a live main database while ignoring WAL is prohibited. Suppress raw failures/output and retain only sanitized status. Observe schema/integrity and count-only metadata from the resulting snapshot, not record content.\n\nTransfer that consistent snapshot only into protected off-cluster custody through the existing authorized operator lane. The copy is real production data even in build mode. Verify private permissions, unique identity and protected internal digest agreement. Do not export mounted workload credentials or directory trees; copy only the exact snapshot.\n\nCreate a separate private disposable restore volume/directory; retain the original snapshot unchanged. Run the exact published candidate with network disabled, no production ConfigMap/token mounts, read-only image and only that isolated volume writable. Override the service entrypoint with the owner's count-only administrative inspection/integrity check; do not start HTTP listeners, audit delivery, requester exchanges or approval operations. The current candidate changes policy.py only and retains the schema/store module bytes; still prove schema5, SQLite integrity and exact bounded counts before/after opening the restored copy. Refuse any migration/downgrade, lost/changed counts, unexpected write class or unknown outcome. Keep pending/uncertain submission and outbox states; never replay, discard or mark them delivered to green the drill. Cleanup only the disposable copy/volume after verified receipt; retain the original protected backup for the approved recovery interval.\n\nThis step is actual native-data compatibility evidence once performed. Its previous synthetic fixture checks remain mechanism evidence and cannot be renamed native success. A failed drill stops rollout and remains a failed/unverified outcome in the same trial.\n\n## Fresh cutover snapshot and single-writer rollout\n\nAfter successful actual-data compatibility checks, create another unique SQLite-consistent online snapshot immediately before the image cutover, retaining its point-in-time schema/integrity/count receipt. This is an online transactional snapshot, not a claim that dispatchers or human writes were quiesced. Every later committed record remains in the live database; same-schema rollback retains that database and never restores the earlier snapshot over it. The narrow image-only update does not need dispatcher/configuration/PVC/temporary-pod changes or a schema cutover. If fresh verification shows a migration or any data-restoration requirement, stop and refine the proposal rather than applying this protocol.\n\nThe existing Recreate rollout drains/stops the single old writer before starting the new image on the same PVC; the inherited single-writer lock independently refuses concurrent serving processes. Do not add an admin pod, scale-to-zero, dispatcher stop, network-policy rewrite or snapshot overwrite as an improvised image-only step. The existing owner admin backup operation runs inside the admitted serving workload, and its separate protected restore drill runs off-cluster with network disabled and no workload credentials. Those exact custody operations must be enumerated in the founder packet alongside the one Deployment image change.\n\nOnce backup/compatibility/preflight gates pass, manually pin the existing Argo Application to the exact reviewed source revision and sync only Deployment/informed-decision with prune false, keeping the current immutable runtime ConfigMap and all other resources. The source patch changes only the image in admission/rendered Deployment; no Secret, PVC, policy, database or dispatcher change is included unless separately enumerated in the final proposal. Observe five-minute readiness and exact image/config/schema/pins. Run the ten installed purpose variants on the actual native placement using synthetic transport; they prove exact installed module refusal behavior and explicitly report native_provider=false. They do not prove an actual provider response, PDP authority or native lifecycle binding; any required actual-provider proof remains a distinct T04 completion gate with separate authorized preparation, and must not be claimed by this helper. Do not contaminate the live PDP, create human approvals, read credentials through CLI, or replay unknown external outcomes for testing.\n\n## Same-schema rollback and evidence retention\n\nOn startup/readiness/binding/refusal failure, retain current database, cutover backup and every post-cutover evidence/uncertain outcome. Restore only the prior7f5c6cb image through the same manual Argo owner path, retaining schema5 and current DB/configuration; never restore an old snapshot over current live evidence just to roll the image back. Verify old image/Ready1, same schema/counts and prior behavior, and reconcile any external effects using existing lifecycle/audit ownership. The narrow overlay's identical store/schema/dependency bytes permit this image-only rollback; it is not permission for a schema downgrade or data loss.\n\nRecord original/approved/executed source and image revisions, backup/drill/cutover/rollout timestamps, exact disposition and sanitized outcomes in the existing supervised trial receipt. EUR0 incremental infrastructure estimate uses existing service/storage/operator lane; protected temporary copy/storage consumption and15–30minute recovery time remain operational costs. No EUR incident-loss cap or autonomy grant is inferred. TaskT04 cannot close until actual published image, approved native compatibility and release plus post-release refusal/binding evidence all exist.\n\n## Exact release case identifiers\n\nProposal `INFD-WP-0009-T04/purpose-overlay-v1`, trial `infd-purpose-20261011-r1`.\nProtected native parent `/data/private/purpose-overlay-r1` must be unique/non-symlink, owned10001 and0700. The drill snapshot is `drill.sqlite`, the refreshed pre-cutover snapshot `cutover.sqlite`, each new0600 file; refuse any existing output. Off-cluster custody is the existing ignored Custodian `.private-backups/20261011-infd-purpose-r1` parent0700, files0600; no snapshot is an evidence attachment. Check owner UID, no symlinks, ignored status and free capacity for both native snapshots plus independently protected copies before making any snapshot.\n\nThe disposable offline restore volume is `infd-purpose-r1-restore-20261011`; refuse an existing volume, copy only the selected frozen snapshot, and run exact published candidate763c with networknone/read-only image,128MiB/core1 and no runtime config/token mounts. SQLite `PRAGMA integrity_check` must return `ok`, `PRAGMA user_version`/Store inspection must agree with actual schema5 semantics, and installed admin count-only inspection must match the frozen snapshot. Validate the actual schema representation rather than assume PRAGMA user_version is the schema authority. No synthetic restoration is reported as native restoration. Native original/off-cluster copies remain retained; only the disposable restore copy/volume may be removed under the exact approved cleanup scope.\n\n## Mandatory pre-open schema gate and offline command\n\n`informed-decision-admin inspect` and `backup` construct Store, which can migrate schemas1–4 to5. Therefore **before any Store/admin open**, run the exact attached stdlib-only `sqlite_readonly.py` against the native source database using SQLite URI mode=ro, query_only and one read transaction. Require PRAGMA user_version5, integrity_check=ok and retain count-only baseline. Refuse any other/unknown schema or incomplete integrity/count check before constructing Store; do not infer no migration from a post-open admin report. This native gate has not been executed in this source-preparation stage. Repeat before each native backup/admin operation.\n\nAfter copying the selected consistent snapshot to the isolated restored private path `/restore/review.sqlite`, run the same read-only checker **before** any offline candidate admin/Store opens that copy. Frozen snapshot and restored-copy schema/integrity/count reports must agree exactly; the copied main-file digest must match the selected closed snapshot. Reject oldschema fixtures rather than allow migration. Only after this pre-open gate may the offline candidate admin inspect run.\n\nOffline command vectors use exactimage `forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a`, `--network none --read-only --cpus 1 --memory 128m`, private restored volume mounted at `/restore`, and **no runtime config/credential/token mounts**. First override entrypoint to `python`, arguments `- --db /restore/review.sqlite`, streaming only the verified attached checker on stdin. Then override entrypoint to **`informed-decision-admin`**, arguments **`inspect --db /restore/review.sqlite`**. This does not start `informed-decision-container`, the HTTP service, dispatcher or delivery workers. Compare the admin's schema/lifecycle/outbox/submission counters to the frozen pre-open snapshot report; integrity and migration-free pre-open proof come from the stdlib checker, not admin output alone.\n\nLive reads and online snapshots may legitimately differ because reviews, intake and delivery can commit concurrently. Exact counter equality is required between the frozen selected snapshot and its offline restored clone; it is **not** required between a running post-cutover/rollback database and an earlier snapshot. Live count changes must be accounted for as legitimate committed records/state transitions; preserve all current and uncertain entries. Do not discard new commits or restore the old snapshot to force equality. Same-schema image rollback keeps the current live DB, followed by read-only schema5/integrity and count-only health checks; any unexplained evidence loss or required data recovery stops and requires a separate founder decision.\n\nThe fresh preflight also independently reads the actual immutable nonsecret ConfigMap and bound PVC: compares sealed UIDs/fullmetadata/PVCspec+volumeName and canonical runtime data checksum, returning no raw runtime data. Same-name deletion/recreation or content/custody drift stops before admission. Secret values remain excluded. Both local and remote optimized Python interpreters are explicitly refused before assertion-based gates.\n\n## Exact supervised mechanical execution refinement\n\nThe directly attached `execution-bundle.json` contains the exact helper source, plan, tests and PENDING receipt template. It replaces the direct raw scan attachment within the twenty-document limit; `published-verification.json` still binds the unchanged actual unfiltered raw scan, raw SBOM and base scan SHA256 values, retained in the owner evidence package. The known inherited fixable MEDIUM remains explicit, with owner T05/risk follow-through. Neither archive nor technical agreement supplies human approval.\n\nThe reviewed protocol basis is owner commit e0359bcb6cdfad9ab3e868054121fe0cebec2d68, with source follow-through9268c9ac0bbee508fe35c0b90dcefef4c24da2f5. The subsequent exact applied helper/packet owner commit must be named in the externally verified founder receipt before execution. Verify the four committed Git blobs (admission.candidate.json, service.candidate.json, kustomization.yaml, registries.candidate.json) against execution-plan.json as well as current worktree/HEAD; reject overrides/plugins/multiple Application sources and any present automated configuration, including automated:{}.\n\nRoot freshly authenticates the exact confirmed founder person/platform-root ACCEPT of this stable memo/version1 at the fixed native Informed Decision origin before each phase, and supplies protected0600 receipt/outcome files. The helper checks their exact relation and freshness120seconds; these files are supervised bookkeeping, not signed authenticated grants, a human-provider implementation, or autonomous agent authority. Do not derive them from technical reviews or caller assertions.\n\nFixed order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. A separate recorded release attempt permits rollback → rollback-verify. Every phase fsyncs an attempt nonce/RUNNING journal before effects. Failure/interruption/ambiguous actuation stays UNCERTAIN and the same phase cannot be retried. No improvised adapter or whole-Application sync is permitted.\n\nThe NEW nonce-labelled local volume requires one explicit isolated initializer as UID0:0 with only CAP_CHOWN, exact763c image, --network none --read-only --cpus 1 --memory 128m --cap-drop ALL --cap-add CHOWN --security-opt no-new-privileges. Its only mount is that new named volume at /restore; no host mount, native PVC, runtime config or token mount. Protected snapshot stdin goes only to a unique0600 main file with exact digest, and directory/file custody is set0700/0600 UID/GID10001. Then all pre-open, admin and post-admin checks run UID10001:10001, capabilities dropped, networknone. The second stdlib readonly schema5/integrity/count proof after admin must exactly equal the frozen snapshot proof; independently recheck the retained original protected snapshot SHA. No service startup occurs.\n\nRollback dispatch must be available if the candidate is unready or cannot start: it checks sealed Deployment/CM/PVC custody, only prior/candidate source/image pair, node health/headroom and fresh old-image server admission plus Application UID/resourceVersion/source CAS, with no failing candidate Pod/exec/database prerequisite. Dispatch acknowledgment is not recovered health. `rollback-verify` separately requires old image Ready1, succeeded exact Deployment-only/prune=false operation and readonly schema5/integrity/count proof of the latest retained live database. No snapshot replaces the current database.\n\n**Deadline refinement:** all phases, including rollback and verification, must begin before2026-10-12T23:59:59Z. The earlier amended packet described unstarted-release expiry; this exact helper also bounds recovery/verification. Start early enough to complete the bounded drill and any recovery within the window. If exhausted, stop and obtain a fresh founder decision rather than silently extend a grant. This may delay recovery and is an explicit operational risk. No timer/controller automatically rolls back or changes service at expiry.\n" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "media_type": "application/json", + "content": "{\n \"id\": \"INFD-RISK-20261011-ZLIB-85091\",\n \"kind\": \"owner-vulnerability-follow-through\",\n \"owner\": \"informed-decision\",\n \"task\": \"INFD-WP-0009-T05\",\n \"status\": \"open\",\n \"created\": \"2026-10-11\",\n \"review_due\": \"2026-10-18\",\n \"finding\": \"CVE-2026-85091\",\n \"scanner_severity\": \"MEDIUM\",\n \"estate_risk_grade\": null,\n \"affected_package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"actual_current_base_and_candidate_findings_identical\": true,\n \"source_evidence\": \"security-summary.json, trivy-full.json, base-trivy-full.json\",\n \"human_temporary_disposition\": \"pending\",\n \"follow_through\": \"Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload\",\n \"manual_review_expiry\": \"Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed\",\n \"close_condition\": \"Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition\"\n}\n" + }, + { + "item_id": "native-preflight-json", + "media_type": "application/json", + "content": "{\n \"captured_at\": \"2026-10-11T01:25:38.793555+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true\n}\n" + }, + { + "item_id": "sealed-live-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"revisionHistoryLimit\": 10,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"imagePullPolicy\": \"IfNotPresent\",\n \"livenessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\",\n \"protocol\": \"TCP\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\",\n \"protocol\": \"TCP\"\n }\n ],\n \"readinessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"terminationMessagePath\": \"/dev/termination-log\",\n \"terminationMessagePolicy\": \"File\",\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"dnsPolicy\": \"ClusterFirst\",\n \"restartPolicy\": \"Always\",\n \"schedulerName\": \"default-scheduler\",\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccount\": \"review\",\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "change-guard-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only exact Deployment and admission boundaries; no mutation authority.\"\"\"\nimport copy\nimport hashlib\nimport json\n\nBASE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'\nCANDIDATE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\n\n\ndef dependency_projection(configmap, pvc):\n if (configmap.get('kind') != 'ConfigMap' or configmap.get('immutable') is not True\n or configmap['metadata']['namespace'] != 'informed-decision'\n or configmap['metadata']['name'] != 'informed-decision-runtime-6c221878d051'\n or set(configmap.get('data', {})) != {'runtime.json'}\n or configmap.get('binaryData')):\n raise ValueError('unexpected immutable runtime config identity')\n if (pvc.get('kind') != 'PersistentVolumeClaim'\n or pvc['metadata']['namespace'] != 'informed-decision'\n or pvc['metadata']['name'] != 'informed-decision-data'\n or pvc.get('status', {}).get('phase') != 'Bound'\n or not pvc.get('spec', {}).get('volumeName')):\n raise ValueError('unexpected bound PVC custody')\n config = projection(configmap)\n config.pop('data')\n config['canonical_data_sha256'] = hashlib.sha256(json.dumps(\n configmap['data'], sort_keys=True, separators=(',', ':')).encode()).hexdigest()\n return {'configmap': config, 'pvc': projection(pvc), 'pvc_phase': 'Bound'}\n\n\ndef check_dependencies(configmap, pvc, sealed):\n if dependency_projection(configmap, pvc) != sealed:\n raise ValueError('runtime config or PVC identity/custody changed')\n\n\ndef projection(value):\n value = copy.deepcopy(value)\n value.pop('status', None)\n for key in ('resourceVersion', 'generation', 'creationTimestamp', 'managedFields'):\n value['metadata'].pop(key, None)\n for key in ('kubectl.kubernetes.io/last-applied-configuration', 'deployment.kubernetes.io/revision'):\n value['metadata'].get('annotations', {}).pop(key, None)\n return value\n\n\ndef check_current(current, sealed):\n if projection(current) != sealed:\n raise ValueError('sealed live UID or configuration changed')\n\n\ndef check_admitted(admitted, sealed):\n expected = copy.deepcopy(sealed)\n containers = expected['spec']['template']['spec']['containers']\n if len(containers) != 1 or containers[0]['name'] != 'informed-decision' or containers[0]['image'] != BASE:\n raise ValueError('unexpected baseline container identity')\n containers[0]['image'] = CANDIDATE\n if projection(admitted) != expected:\n raise ValueError('admission changed configuration beyond the sole image pin')\n\n\ndef transport_result(exit_code, output):\n import json\n try:\n value = json.loads(output)\n except (ValueError, TypeError):\n return {'all_checks_pass': False, 'reason': 'invalid transport result'}\n if exit_code != 0 or not isinstance(value, dict) or value.get('all_checks_pass') is not True:\n return {'all_checks_pass': False, 'reason': 'read-only preflight refused'}\n return value\n" + }, + { + "item_id": "preflight-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only refresh; exact original capture remains immutable; never execute cutover.\"\"\"\nimport argparse,hashlib,json,subprocess,sys\nfrom pathlib import Path\nif sys.flags.optimize:\n raise SystemExit(\"optimized interpreter refused before source/transport execution\")\nROOT=Path(__file__).resolve().parent\np=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args()\nout=a.receipt_output.resolve()\nif not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists():\n raise SystemExit('unique execution receipt must be outside the sealed packet')\ninputs=json.loads((ROOT/'preflight-inputs.json').read_text())\nfor relative,digest in inputs['packet_files'].items():\n path=ROOT/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed')\nfor relative,digest in inputs['owner_source_files'].items():\n path=a.source_root/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed')\nfrom change_guard import transport_result\nprogram='import subprocess,json,hashlib,datetime,sys,copy,re\\nif sys.flags.optimize:raise RuntimeError(\"optimized interpreter refused\")\\ncandidate=json.loads(CANDIDATE_LITERAL)\\nsealed_dependencies=json.loads(DEPENDENCIES_LITERAL)\\nsealed_baseline=json.loads(SEALED_LITERAL)\\nexec(GUARD_LITERAL)\\ndef run(args,data=None):\\n p=subprocess.run(args,input=data,text=True,capture_output=True)\\n if p.returncode: raise ValueError(\\'read-only command failed: \\'+args[1]+\\' \\'+args[2])\\n return p.stdout\\nlive=json.loads(run([\\'kubectl\\',\\'get\\',\\'deployment\\',\\'informed-decision\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncm=json.loads(run([\\'kubectl\\',\\'get\\',\\'configmap\\',\\'informed-decision-runtime-6c221878d051\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\npvc=json.loads(run([\\'kubectl\\',\\'get\\',\\'pvc\\',\\'informed-decision-data\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncheck_dependencies(cm,pvc,sealed_dependencies)\\ncheck_current(live,sealed_baseline)\\nspec=live[\\'spec\\']; cs=spec[\\'template\\'][\\'spec\\'][\\'containers\\'];assert len(cs)==1 and cs[0][\\'name\\']==\\'informed-decision\\'\\nexpected_env={\\'INFD_KEYCAPE_ISSUER\\':\\'https://kc.coulomb.social\\',\\'INFD_CONTAINER_CONFIG\\':\\'/configuration/runtime.json\\'}\\nassert cs[0].get(\\'env\\')==[{\\'name\\':\\'INFD_KEYCAPE_ISSUER\\',\\'value\\':expected_env[\\'INFD_KEYCAPE_ISSUER\\']},{\\'name\\':\\'INFD_CONTAINER_CONFIG\\',\\'value\\':expected_env[\\'INFD_CONTAINER_CONFIG\\']}]\\nassert cs[0][\\'image\\']==\\'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\'\\nassert spec[\\'replicas\\']==1 and spec[\\'strategy\\']=={\\'type\\':\\'Recreate\\'}\\nassert next(v for v in spec[\\'template\\'][\\'spec\\'][\\'volumes\\'] if v[\\'name\\']==\\'configuration\\')[\\'configMap\\'][\\'name\\']==\\'informed-decision-runtime-6c221878d051\\'\\nassert live[\\'status\\'].get(\\'readyReplicas\\')==1 and live[\\'status\\'].get(\\'updatedReplicas\\')==1\\nsealed={\\'apiVersion\\':live[\\'apiVersion\\'],\\'kind\\':live[\\'kind\\'],\\'metadata\\':{k:copy.deepcopy(v) for k,v in live[\\'metadata\\'].items() if k not in (\\'resourceVersion\\',\\'generation\\',\\'creationTimestamp\\',\\'managedFields\\')},\\'spec\\':copy.deepcopy(spec)}\\nfor key in (\\'kubectl.kubernetes.io/last-applied-configuration\\',\\'deployment.kubernetes.io/revision\\'):sealed[\\'metadata\\'].get(\\'annotations\\',{}).pop(key,None)\\nadmitted=json.loads(run([\\'kubectl\\',\\'apply\\',\\'--dry-run=server\\',\\'-f\\',\\'-\\',\\'-o\\',\\'json\\'],json.dumps(candidate)))\\ncheck_admitted(admitted,sealed_baseline)\\napp=json.loads(run([\\'kubectl\\',\\'get\\',\\'application\\',\\'informed-decision\\',\\'-n\\',\\'argocd\\',\\'-o\\',\\'json\\']))\\nassert app[\\'spec\\'][\\'source\\'][\\'path\\']==\\'deploy/lifecycle\\' and not app[\\'spec\\'].get(\\'syncPolicy\\',{}).get(\\'automated\\')\\nargo={\\'uid\\':app[\\'metadata\\'][\\'uid\\'],\\'repoURL\\':app[\\'spec\\'][\\'source\\'][\\'repoURL\\'],\\'targetRevision\\':app[\\'spec\\'][\\'source\\'][\\'targetRevision\\'],\\'path\\':app[\\'spec\\'][\\'source\\'][\\'path\\'],\\'destination\\':app[\\'spec\\'][\\'destination\\'],\\'automated\\':False,\\'sync\\':app.get(\\'status\\',{}).get(\\'sync\\'),\\'health\\':app.get(\\'status\\',{}).get(\\'health\\')}\\nexpected_argo=json.loads(ARGO_LITERAL)\\nfor key in (\\'uid\\',\\'repoURL\\',\\'targetRevision\\',\\'path\\',\\'destination\\',\\'automated\\'):\\n assert argo[key]==expected_argo[key]\\nassert argo[\\'health\\'][\\'status\\']==\\'Healthy\\'\\ndiff=subprocess.run([\\'kubectl\\',\\'diff\\',\\'-f\\',\\'-\\'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\\nnode=run([\\'kubectl\\',\\'describe\\',\\'node\\']);allocated=re.search(r\\'Allocated resources:.*?CPU Requests|Allocated resources:\\',node,re.S)\\nsection=node.split(\\'Allocated resources:\\')[1].split(\\'Events:\\')[0] if \\'Allocated resources:\\' in node else \\'\\'\\nnodes=json.loads(run([\\'kubectl\\',\\'get\\',\\'nodes\\',\\'-o\\',\\'json\\']))[\\'items\\'];assert len(nodes)==1\\nalloc=nodes[0][\\'status\\'][\\'allocatable\\'];cpu=alloc[\\'cpu\\'];cpu_m=int(cpu[:-1]) if cpu.endswith(\\'m\\') else int(cpu)*1000\\nrequested=int(re.search(r\\'cpu\\\\s+(\\\\d+)m\\',section).group(1));assert requested<=cpu_m\\nreceipt={\\'node_allocatable_cpu_m\\':cpu_m,\\'node_requested_cpu_m\\':requested,\\'captured_at\\':datetime.datetime.now(datetime.timezone.utc).isoformat(),\\'native_workload_changed\\':False,\\'native_backup_restore_executed\\':False,\\'argo\\':argo,\\'native_dependencies_checked\\':True,\\'configmap_uid\\':cm[\\'metadata\\'][\\'uid\\'],\\'pvc_uid\\':pvc[\\'metadata\\'][\\'uid\\'],\\'live_ready_replicas\\':1,\\'admitted_uid\\':admitted[\\'metadata\\'][\\'uid\\'],\\'server_dry_run_passed\\':True,\\'admitted_spec_exactly_live_plus_image\\':True,\\'client_diff_exit\\':diff.returncode,\\'client_diff_sha256\\':hashlib.sha256(diff.stdout.encode()).hexdigest(),\\'node_allocated_resources\\':section.strip(),\\'all_checks_pass\\':True}\\nprint(json.dumps(receipt))\\n'\nfor marker,value in [('DEPENDENCIES_LITERAL',(ROOT/'sealed-native-dependencies.json').read_text()),('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]:\n program=program.replace(marker,repr(value))\nprogram='import traceback,json\\ntry:\\n'+''.join(' '+line+'\\n' for line in program.splitlines())+\"except Exception as error:\\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\\n\"\nr=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True)\nresult=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True\nout.write_text(json.dumps(result,indent=2)+'\\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1)\n" + }, + { + "item_id": "preflight-inputs-json", + "media_type": "application/json", + "content": "{\n \"packet_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"preflight.py\": \"6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"native-preflight.json\": \"eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\"\n }\n}\n" + }, + { + "item_id": "fresh-preflight-validation-json", + "media_type": "application/json", + "content": "{\n \"node_allocatable_cpu_m\": 4000,\n \"node_requested_cpu_m\": 3460,\n \"captured_at\": \"2026-10-11T01:39:14.234277+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"native_dependencies_checked\": true,\n \"configmap_uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\",\n \"pvc_uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\",\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"840769c7d2a9c1655c40a3259f833d1fc8f69950ceb3bedb707a955fed711566\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true,\n \"sealed_preflight_inputs_sha256\": \"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\",\n \"fresh_execution_receipt\": true\n}\n" + } + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json new file mode 100644 index 0000000..1df1d5b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json @@ -0,0 +1,277 @@ +[ + { + "id": "infd-20261011-purpose-overlay-r1", + "register": { + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 1, + "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "documents": [ + { + "digest": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6", + "media_type": "text/markdown", + "content_base64": "IyBJbmZvcm1lZCBEZWNpc2lvbiBwdXJwb3NlIG92ZXJsYXkgcmVsZWFzZQoKIyMgUmVxdWVzdGVkIGRlY2lzaW9uCgpBcHByb3ZlIHRoZSBleGFjdCBwdXJwb3NlLW9ubHkgaW1hZ2Ugcm9sbG91dCBhbmQgcHJvdGVjdGVkIHJlYWwtZGF0YSBiYWNrdXAvcmVzdG9yZSBwcm90b2NvbCBmb3IgdGhlIGV4aXN0aW5nIEluZm9ybWVkIERlY2lzaW9uIHNlcnZpY2Ugb24gcmFpbGlhbmNlMDEuIFRoaXMgcmVxdWVzdCBpcyBzZXBhcmF0ZSBmcm9tIHRoZSBhbHJlYWR5IGFwcHJvdmVkIGNvbmZpZy1vbmx5IHJlcGFpci4gT25seSB0aGUgZXhpc3RpbmcgRGVwbG95bWVudCBpbWFnZSBjaGFuZ2VzIHRocm91Z2ggdGhlIG93bmVyJ3MgbWFudWFsIEFyZ28gd29ya2Zsb3csIHdpdGggcHJ1bmUgZGlzYWJsZWQuIFJ1bnRpbWUgQ29uZmlnTWFwIGBpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MWAsIHNjaGVtYTUsIFBWQywgY3JlZGVudGlhbHMsIGF1ZGllbmNlLCBwb2xpY2llcywgcmVnaXN0cmllcywgYWNjZXNzLCByZXBsaWNhMSBhbmQgUmVjcmVhdGUgc3RyYXRlZ3kgcmVtYWluIGZpeGVkLiBFeGVjdXRlIGJ5IDIwMjYtMTAtMTJUMjM6NTk6NTlaLCBhZnRlciByZWZyZXNoZWQgc2VhbGVkLXNvdXJjZS9VSUQvY29uZmlndXJhdGlvbiBjaGVja3MgYW5kIGJhY2t1cC9yZXN0b3JlIGdhdGVzLiBBbGwgcGhhc2VzLCBpbmNsdWRpbmcgcmVjb3ZlcnkgYW5kIHZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUgdGhpcyBkZWFkbGluZS4gSWYgdGhlIHdpbmRvdyBpcyBleGhhdXN0ZWQsIHN0b3AgYW5kIG9idGFpbiBhIGZyZXNoIGZvdW5kZXIgZGVjaXNpb247IHRoaXMgbWF5IGRlbGF5IHJlY292ZXJ5LiBObyB0aW1lci9jb250cm9sbGVyIGF1dG9tYXRpY2FsbHkgY2hhbmdlcyB0aGUgcmVsZWFzZWQgaW1hZ2UuCgojIyBBcnRpZmFjdCBhbmQga25vd24gZmluZGluZwoKQWN0dWFsIG93bmVyIENJIHRhc2sxMTQ4NC9ydW4zIHB1Ymxpc2hlZCBpbW11dGFibGUgaW1hZ2UgYHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhYCBmcm9tIHNvdXJjZSBgM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OGAuIEFub255bW91cyByZWdpc3RyeSB2ZXJpZmljYXRpb24gcHJlc2VydmVzIGFsbCBlaWdodCBiYXNlIGNvbXByZXNzZWQgYmxvYnMvcm9vdGZzIGxheWVycyBhbmQgYWRkcyBvbmx5IHBvbGljeS5weSB3aXRoIGV4YWN0IHNvdXJjZSBoYXNoIGFuZCBtb2RlMDY0NC4gTGVnYWN5LWJ1aWxkZXIgbWVkaWEtdHlwZS9kZWZhdWx0IGNvbmZpZyBzZXJpYWxpemF0aW9uIGRpZmZlcmVuY2VzIGFyZSByZWNvcmRlZDsgdGhlIHJ1bnRpbWUgc2VtYW50aWNzIHJlbWFpbiB1bmNoYW5nZWQuIFB1bGxlZCBwdWJsaXNoZWQgaW1hZ2UgZXhlY3V0ZXMgYXMgVUlEMTAwMDEvR0lEMTAwMDEgYW5kIHBhc3NlcyB0ZW4gaW5zdGFsbGVkIGNoZWNrczogdHdvIHN1cHBvcnRlZCBiaW5kaW5nIGZvcm1zLCBlaWdodCBhZHZpc29yeS9tYWxmb3JtZWQgcmVmdXNhbHMuIFRlc3RzIHVzZSBzeW50aGV0aWMgdHJhbnNwb3J0IGFuZCBkbyBub3QgY2xhaW0gbmV3IG5hdGl2ZSBQRFAgYXV0aG9yaXphdGlvbiBwcm9vZi4gVGhlIHR3byBmYWlsZWQgQ0kgYXR0ZW1wdHMgcmVtYWluIGluIHRoZSBzYW1lIHRyaWFsIGhpc3RvcnkuCgpBY3R1YWwgdW5maWx0ZXJlZCBwaW5uZWQgc2Nhbm5lci9EQiBldmlkZW5jZSBjb3ZlcnM0NHBhY2thZ2VzOiB6ZXJvIEhJR0gvQ1JJVElDQUwsICoqb25lIGZpeGFibGUgTUVESVVNKiosIENWRS0yMDI2LTg1MDkxLCB6bGliMS4zLjItcjAgZml4ZWQgaW4xLjMuMi1yMS4gQWN0dWFsIGN1cnJlbnQtYmFzZSBzY2FuIGhhcyB0aGUgaWRlbnRpY2FsIGZpbmRpbmcuIEFwcHJvdmluZyB0aGlzIHBhY2tldCBleHBsaWNpdGx5IHBlcm1pdHMgdGhpcyBpbmhlcml0ZWQgZmluZGluZyBkdXJpbmcgdGhpcyBuYXJyb3cgcHVycG9zZSByZWxlYXNlOyBpdCBpcyBub3QgYSBSaXNrTmV4dXMgZXN0YXRlIHJpc2sgZ3JhZGUgb3IgemVyby1DVkUgY2xhaW0uIE93bmVyIHJlY29yZCBJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSBhbmQgbGl2ZSB0YXNrIElORkQtV1AtMDAwOS1UMDUgcmVxdWlyZSBzZXBhcmF0ZSBiYXNlIHJlZnJlc2ggYW5kIG5hdGl2ZSBhcHByb3ZhbCwgcmV2aWV3ZWQgYnkyMDI2LTEwLTE4LiBUaGF0IHJldmlldyBkYXRlIGlzIG1hbnVhbCBmb2xsb3ctdGhyb3VnaCwgd2l0aCBubyBhdXRvLWNvbnRyb2xsZXIgY2xhaW0uIFNjYW5uZXIgbm90ZXMgQWxwaW5lMy4yNCBhYnNlbnQgRU9MIGxpc3Q7IE9TIHZ1bG5lcmFiaWxpdHkgZGV0ZWN0aW9uIHJhbiBhZ2FpbnN0MzhPU3BhY2thZ2VzLiBVbmtub3duIHZ1bG5lcmFiaWxpdGllcyByZW1haW4gb3V0c2lkZSBzbmFwc2hvdCBrbm93bGVkZ2UuCgojIyBOYXRpdmUgYmFzZWxpbmUgYW5kIGdhdGVzCgpPcmlnaW5hbCByZWFkLW9ubHkgY2FwdHVyZTAxOjI1OjM4WjogZXhpc3RpbmcgRGVwbG95bWVudCBVSURhNTg4ZTEwYSwgUmVhZHkxLCBpbWFnZTdmNWMsIHVuY2hhbmdlZCBydW50aW1lNmM7IG5hdGl2ZSBhZG1pc3Npb24gcHJlc2VydmVzIHRoZSBmdWxsIGNvbmZpZ3VyYXRpb24gcGx1cyBleGFjdGx5IHRoZSBwcm9wb3NlZCBpbWFnZS4gQ2xpZW50ZGlmZiByZXR1cm5zMS4gUmVxdWVzdHMzNDYwLzQwMDBtQ1BVODYlLCBtZW1vcnk5NDcyTWk1OSU7IHJlZnJlc2ggYmVmb3JlIHJlbGVhc2UuIEV4aXN0aW5nIEFyZ28gQXBwbGljYXRpb24gVUlENDk5ODY4ZjIgaXMgbWFudWFsLCB0YXJnZXQ3ZGI4NDg1LCBIZWFsdGh5IHdpdGggcHJlLWV4aXN0aW5nIE91dE9mU3luYyBzdGF0dXMuIERvIG5vdCB0cmVhdCBhIHNjb3BlZCBEZXBsb3ltZW50IHJlbGVhc2UgYXMgZnVsbC1hcHAgcmVjb25jaWxpYXRpb24uIFByZXNlcnZlIGl0cyB0cmFja2luZy1pZDsgbm8gdW5yZWxhdGVkIHJlc291cmNlIHN5bmMvcHJ1bmUvYWRvcHRpb24uCgpUaGUgcmVmaW5lZCByZWFkLW9ubHkgaGVscGVyIGJpbmRzIG9yaWdpbmFsIHNvdXJjZS9oZWxwZXIvcmVuZGVyL2Jhc2VsaW5lIGhhc2hlcyBhbmQgYWN0dWFsIGltbXV0YWJsZSBDb25maWdNYXAvUFZDIFVJRHMsIHJ1bnRpbWUtZGF0YSBjaGVja3N1bSBhbmQgYm91bmQgdm9sdW1lIGlkZW50aXR5LCBleHBsaWNpdGx5IHJlZnVzZXMgb3B0aW1pemVkIGludGVycHJldGVycywgY2hlY2tzIGV4YWN0IGZyZXNoIGxpdmUgVUlEL2NvbmZpZ3VyYXRpb24gYW5kIGFkbWlzc2lvbiwgYW5kIHdyaXRlcyBhIHNlcGFyYXRlIGV4ZWN1dGlvbiByZWNlaXB0IG91dHNpZGUgdGhpcyBzZWFsZWQgcGFja2V0LiBGYWlsZWQgaW5pdGlhbCByYXcgS3VzdG9taXplIG1ldGFkYXRhIGNoZWNrIGlzIHJldGFpbmVkOiBkaXJlY3Qga3ViZWN0bCBhcHBseSB3b3VsZCBkcm9wIEFyZ28gdHJhY2tpbmctaWQuIFRoZSByZXZpZXdlZCBzZWxlY3RlZCBEZXBsb3ltZW50IGV4cGxpY2l0bHkgcmV0YWlucyB0aGF0IGV4aXN0aW5nIElELCBtYXRjaGluZyBBcmdvIG93bmVyc2hpcC4gQW55IHVucmVsYXRlZCBkcmlmdCwgZGlmZmVyZW50IFVJRCwgYWx0ZXJlZCBhZG1pc3Npb24sIHVuYXZhaWxhYmxlIHByb3RlY3RlZCBiYWNrdXAgY2FwYWNpdHksIHVuY2VydGFpbiBiYWNrdXAsIHJlc3RvcmUgbWlzbWF0Y2ggb3IgdW5oZWFsdGh5IGJhc2VsaW5lIHN0b3BzIHRoZSByZWxlYXNlLgoKIyMgUHJvdGVjdGVkIGJhY2t1cCBhbmQgcmVsZWFzZQoKQmVmb3JlICoqYW55KiogbmF0aXZlIHNvdXJjZSBvciBvZmZsaW5lLXJlc3RvcmVkIFN0b3JlL2FkbWluIG9wZW4sIHVzZSB0aGUgYXR0YWNoZWQgc3RkbGliIFNRTGl0ZSBtb2RlPXJvL3F1ZXJ5X29ubHkgY2hlY2tlciB0byByZXF1aXJlIHNjaGVtYTUsIGludGVncml0eT1vayBhbmQgY291bnQtb25seSBiYXNlbGluZS4gVGhlIGFkbWluIGF1dG9tYXRpY2FsbHkgbWlncmF0ZXMgb2xkc2NoZW1hcywgc28gYSBwb3N0LW9wZW4gcmVwb3J0IGFsb25lIGNhbm5vdCBwcm92ZSBubyBtaWdyYXRpb24uIFJlZnVzZSBvdGhlciBzY2hlbWFzIGJlZm9yZSBhZG1pbi4gVGhlbiB1c2UgdGhlIGV4aXN0aW5nIG93bmVyIGFkbWluJ3MgU1FMaXRlIGJhY2t1cCBBUEksIG5vdCBhIHJhdyBjb3B5IG9mIHRoZSBsaXZlIGRhdGFiYXNlL1dBTC4gUHJvdGVjdCBkaXJlY3RvcmllczA3MDAvZmlsZXMwNjAwLCBvd25lZCBieTEwMDAxLiBSZXRhaW4gaW5kZXBlbmRlbnRseSBwcm90ZWN0ZWQgb2ZmLWNsdXN0ZXIgc25hcHNob3QgY3VzdG9keSBhbmQgb25seSBjb3VudC9oYXNoIHJlY2VpcHRzLiBObyBkYXRhYmFzZSBjb250ZW50cywgY2FsbGVyIHRva2VucywgcmVxdWVzdGVyIFNlY3JldCBvciBydW50aW1lIGNyZWRlbnRpYWwgZmlsZXMgZW50ZXIgR2l0LCBTdGF0ZSBIdWIsIGxvZ3Mgb3IgdGhpcyBwYWNrZXQuIE5hdGl2ZSBiYWNrdXAgYW5kIG9mZmxpbmUgcmVhbC1kYXRhIHJlc3RvcmUgaGF2ZSBub3QgeWV0IG9jY3VycmVkLiBVc2UgYW4gaXNvbGF0ZWQgcHJpdmF0ZSBkaXNwb3NhYmxlIGNvcHksIG5ldHdvcmtub25lIGFuZCBubyBydW50aW1lIGNvbmZpZy90b2tlbiBtb3VudHMsIHJ1biB0aGUgcHJlLW9wZW4gY2hlY2tlciBhbmQgZXhhY3Qgb2ZmbGluZSBgLS1lbnRyeXBvaW50IGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGluc3BlY3QgLS1kYiAvcmVzdG9yZS9yZXZpZXcuc3FsaXRlYCBhZnRlciBpdCBwYXNzZXMsIGNvbXBhcmluZyBmcm96ZW4gc25hcHNob3QgY291bnRzIHdpdGhvdXQgc2VydmljZSBzdGFydHVwLCB0aGVuIGNsZWFuIG9ubHkgdGhlIGRpc3Bvc2FibGUgcmVzdG9yZWQgY29weS4gUmV0YWluIHRoZSBvcmlnaW5hbCBzbmFwc2hvdC4gVGhlIGF0dGFjaGVkIHByb3RvY29sIGJpbmRzIGNhc2Utc3BlY2lmaWMgcGF0aHMgYW5kIGZhaWwtY2xvc2VkIGNhcGFjaXR5L2N1c3RvZHkgY2hlY2tzLgoKUmVmcmVzaCBhIGNvbnNpc3RlbnQgb25saW5lIHNuYXBzaG90IGltbWVkaWF0ZWx5IGJlZm9yZSBpbWFnZS1vbmx5IGN1dG92ZXIuIFRoaXMgcHJvdG9jb2wgZG9lcyBub3QgYXNzZXJ0IHRyYWZmaWMvZGlzcGF0Y2hlciBxdWllc2NlbmNlLiBDdXJyZW50IGFuZCBjYW5kaWRhdGUgc2hhcmUgc2NoZW1hNSBhbmQgdW5jaGFuZ2VkIHN0b3JlIGNvZGU7IHJvbGxiYWNrIHJldGFpbnMgdGhlIGxhdGVzdCBsaXZlIGRhdGFiYXNlIGFuZCBhbGwgbmV3L3VuY2VydGFpbiBldmlkZW5jZS4gU3RvcCB0aGUgb2xkIHdyaXRlciBiZWZvcmUgdGhlIG5ldyBvbmUgd2l0aCBleGlzdGluZyBSZWNyZWF0ZSBhbmQgc2luZ2xlLXdyaXRlciBsb2NrLiBEbyBub3QgcmVzdG9yZSBhbiBvbGRlciBzbmFwc2hvdCBvdmVyIGxhdGVyIHdyaXRlcywgZGlzY2FyZCB1bnJlc29sdmVkIGV4dGVybmFsIGVmZmVjdHMsIHNjYWxlIG90aGVyIHdvcmtsb2FkcywgY2hhbmdlIHBvbGljaWVzL2lkZW50aXR5L2N1c3RvZHksIG9yIGNyZWF0ZSBodW1hbiBkaXNwb3NpdGlvbnMgdG8gbWFrZSBjaGVja3MgZ3JlZW4uCgpQaW4gdGhlIGV4aXN0aW5nIEFwcGxpY2F0aW9uIHRvIHRoZSBleGFjdCBvd25lciBjb21taXQgY29udGFpbmluZyB0aGUgYXBwcm92ZWQgY2FuZGlkYXRlIHNvdXJjZSBoYXNoZXMsIGFuZCBtYW51YWxseSBzeW5jIG9ubHkgRGVwbG95bWVudC9pbmZvcm1lZC1kZWNpc2lvbiB3aXRoIHBydW5lPWZhbHNlLiBWZXJpZnkgYWN0dWFsaW1hZ2UvbW9kdWxlL21vZGUvVUlELCBoZWFsdGgvcmVhZGluZXNzIGFuZCBpbnN0YWxsZWQgcHVycG9zZSByZWZ1c2FscyBvbiB0aGUgcmVhbCBwbGFjZW1lbnQ7IGV4cGxpY2l0bHkgZGlzdGluZ3Vpc2ggc3ludGhldGljLXRyYW5zcG9ydCBjaGVja3MgZnJvbSBhY3R1YWwgcHJvdmlkZXIgZXZpZGVuY2UuIEV4aXN0aW5nIG5hdGl2ZSBiaW5kaW5nL2xpZmVjeWNsZSBiZWhhdmlvciBtdXN0IHJlbWFpbiBhdmFpbGFibGUuIElmIHVuaGVhbHRoeSBvciB2ZXJpZmljYXRpb24gZmFpbHMsIHJldHVybiBBcHBsaWNhdGlvbiBzb3VyY2UgdG83ZGI4NDg1IGFuZCBzY29wZWQtc3luYyBwcmlvciBzYW1lLXNjaGVtYSBpbWFnZTdmNWMsIHByZXNlcnZpbmcgY3VycmVudCBldmlkZW5jZSBkYXRhYmFzZTsgcmV0YWluIGZhaWxlZCBvdXRjb21lcy4gQW55IGRhdGEgcmVjb3ZlcnkgYmV5b25kIHRoaXMgc2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sgaXMgYSBzZXBhcmF0ZSBmb3VuZGVyIGRlY2lzaW9uLgoKIyMgQWx0ZXJuYXRpdmVzIGFuZCBlc3RpbWF0ZXMKClByb2NlZWQgd2l0aCB0aGlzIG5hcnJvdyByZWxlYXNlIHBsdXMgZXhwbGljaXQgaW5oZXJpdGVkLW1lZGl1bSBmb2xsb3ctdGhyb3VnaCwgb3IgZGVmZXIgYW5kIHByZXBhcmUgYSBzZXBhcmF0ZSBiYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCBiZWZvcmUgYW55IHJlbGVhc2UuIE5vIGFkZGl0aW9uYWwgcmVjdXJyaW5nIGhvc3RpbmcgaXMgcHJvcG9zZWQ6IGVzdGltYXRlZCBpbmNyZW1lbnRhbCBpbmZyYXN0cnVjdHVyZSBFVVIwLCB3aXRoIHByaXZhdGUgc3RvcmFnZSBhbmQgYXR0ZW5kZWQgZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZC4gUmlza3MgaW5jbHVkZSBhIGJyaWVmIFJlY3JlYXRlIGludGVycnVwdGlvbiwgcHJpdmF0ZSBiYWNrdXAgY3VzdG9keSBlcnJvcnMsIGNhbGxlciByZWZ1c2FsIHdoZW4gYWR2aXNvcnkgcmVzcG9uc2VzIHdlcmUgaW1wcm9wZXJseSB0cmVhdGVkIGFzIGJpbmRpbmcsIGFuZCB0aGUgZGlzY2xvc2VkIGluaGVyaXRlZCBmaW5kaW5nLiBUaGlzIGRlY2lzaW9uIGRvZXMgbm90IHByb21vdGUgYWdlbnQgYXV0b25vbXkgb3IgZ3JhbnQgdW5yZWxhdGVkIHdvcmsuCgojIyBJbmRlcGVuZGVudCByZXZpZXcgcmVmaW5lbWVudHMKClRoZSBpbml0aWFsMzZwYXRoLzIwZG9jdW1lbnQgcGFja2V0IGF0IG1hbmlmZXN0N2M2NzM4YjMgYW5kIHN1Ym1pc3Npb25hYzQxYzhhZSBpcyBwcmVzZXJ2ZWQgaW4gc291cmNlIHByZXBhcmF0aW9uIGV2aWRlbmNlLCB3aXRoIHRoZSBmYWlsZWQvY29uZGl0aW9uYWwgcmV2aWV3LiBJbmRlcGVuZGVudCBQbGF0Zm9ybSByZXZpZXcgaWRlbnRpZmllZCBhZG1pbiBhdXRvLW1pZ3JhdGlvbiwgb3B0aW1pemF0aW9uIGJ5cGFzcywgYW5kIGFjdHVhbCBzYW1lLW5hbWUgQ29uZmlnTWFwL1BWQyByZXBsYWNlbWVudCBnYXBzLiBUaGUgYW1lbmRlZCBwYWNrZXQgYWRkcyBwcmUtb3BlbiBzdGRsaWIgcmVhZC1vbmx5IHNjaGVtYS9pbnRlZ3JpdHkvY291bnQgZ2F0ZXMsIGV4cGxpY2l0IGxvY2FsL3JlbW90ZSBvcHRpbWl6YXRpb24gcmVmdXNhbCwgYW5kIGluZGVwZW5kZW50bHkgc2VhbGVkIGFjdHVhbCBuYXRpdmUgY29uZmlnL1BWQyBjdXN0b2R5IGNoZWNrcy4gVGhlc2UgYXJlIHJlZmluZW1lbnRzIGluIHRoZSBzYW1lIHByb3Bvc2FsL3RyaWFsLCB3aXRoIG5vIG9yaWdpbmFsIG9yIGFtZW5kZWQgZm91bmRlciBhcHByb3ZhbCBjbGFpbWVkLgoKIyMgTWVjaGFuaWNhbGx5IGJvdW5kIGhlbHBlciBhbmQgcmVjb3ZlcnkgcmVmaW5lbWVudAoKVGhlIGRpcmVjdGx5IGF0dGFjaGVkIGV4ZWN1dGlvbi1idW5kbGUuanNvbiBiaW5kcyBleGFjdCBzdXBlcnZpc2VkIGhlbHBlciBzb3VyY2VzLCBwbGFuLCB0ZXN0cyBhbmQgUEVORElORyBhdXRob3JpdHkgdGVtcGxhdGUuIEl0IHZlcmlmaWVzIGFsbCBmb3VyIGNvbW1pdHRlZCBvd25lciBLdXN0b21pemUgaW5wdXRzIGFuZCByZWplY3RzIHByZXNlbnQgYXV0b21hdGVkOnt9IGFzIHdlbGwgYXMgc291cmNlIG92ZXJyaWRlcy4gUm9vdCBtdXN0IGZyZXNobHkgYXV0aGVudGljYXRlIHRoZSBleGFjdCBmb3VuZGVyIG5hdGl2ZSBkaXNwb3NpdGlvbiBiZWZvcmUgZXZlcnkgcGhhc2U7IHJlY2VpcHQgYm9va2tlZXBpbmcgaXMgbm90IGFuIGF1dG9ub21vdXMgc2lnbmVkIGdyYW50LiBUaGUgc2FtZSBwcm9wb3NhbC90cmlhbCBwcmVzZXJ2ZXMgdGhlIGVhcmxpZXIzNnBhdGg3YyBwYWNrZXQsIGFtZW5kZWQ3OHBhdGhiMSBwYWNrZXQgYW5kIG9yaWdpbmFsMTFmaWxlNjUzIGhlbHBlciBwbHVzIGNvbmRpdGlvbmFsIHJldmlldyBmaW5kaW5ncy4KClRoZSBvZmZsaW5lIGNvcHkgdXNlcyBvbmUgVUlEMC9DQVBfQ0hPV04tb25seSBpbml0aWFsaXplciBjb25maW5lZCB0byB0aGUgTkVXIG5vbmNlLWJvdW5kIGxvY2FsIHZvbHVtZSwgZXhhY3QgY2FuZGlkYXRlIGltYWdlLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pLCBubyBob3N0L2xpdmVQVkMvY29uZmlnL3Rva2VuIG1vdW50cy4gQWxsIGZvbGxvd2luZyBwcmUtb3Blbi9hZG1pbi9wb3N0LW9wZW4gY2hlY2tzIGFyZSBVSUQxMDAwMS4gUG9zdC1hZG1pbiByZWFkb25seSBzY2hlbWE1L2ludGVncml0eS9jb3VudHMgbXVzdCBtYXRjaCB0aGUgZnJvemVuIHNuYXBzaG90IGFuZCBvcmlnaW5hbCBzbmFwc2hvdCBTSEEgbXVzdCByZW1haW4gdW5jaGFuZ2VkLiBSb2xsYmFjayBkaXNwYXRjaCBuZXZlciByZXF1aXJlcyB0aGUgZmFpbGluZyBjYW5kaWRhdGUgdG8gYmUgUmVhZHkgb3Igb3BlbnMgaXRzIGRhdGFiYXNlOyBzZWFscy9zb3VyY2UvaW1hZ2UgcGFpci9hZG1pc3Npb24gQ0FTIHN0aWxsIGdhdGUgaXQuIEEgc2VwYXJhdGUgcm9sbGJhY2stdmVyaWZ5IHByb3ZlcyByZWNvdmVyZWQgb2xkLWltYWdlIFJlYWR5MS9zY29wZWQgb3BlcmF0aW9uL3NjaGVtYTUgcmV0YWluZWQtY3VycmVudC1EQiBpbnRlZ3JpdHkuIFNhbWUtcGhhc2UgcmV0cmllcyBhcmUgcmVmdXNlZCBhZnRlciBhbWJpZ3VvdXMgb3V0Y29tZXMuCgpSYXcgc2Nhbi9TQk9NL2Jhc2Utc2NhbiBieXRlcyByZW1haW4gcmV0YWluZWQgdW5jaGFuZ2VkLCBoYXNoLWJvdW5kIGJ5IHRoZSBkaXJlY3RseSBhdHRhY2hlZCBwdWJsaXNoZWQtdmVyaWZpY2F0aW9uIHJlY2VpcHQ7IHRoZSBidW5kbGUgcmVwbGFjZXMgb25seSB0aGUgZGlyZWN0IHJhdyBzY2FuIGF0dGFjaG1lbnQgdG8gc3RheSB3aXRoaW4gdHdlbnR5IGRvY3VtZW50cy4gS25vd24gZml4YWJsZSBpbmhlcml0ZWQgTUVESVVNIGFuZCBUMDUgZm9sbG93LXRocm91Z2ggcmVtYWluIHZpc2libGUuIFRlbiBpbnN0YWxsZWQgc3ludGhldGljIGNoZWNrcywgaW5jbHVkaW5nIHRob3NlIGxhdGVyIG9uIGFjdHVhbCBwbGFjZW1lbnQsIGV4cGxpY2l0bHkgaGF2ZSBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIEFjdHVhbCBwcm92aWRlci9QRFAgYXV0aG9yaXR5IGV2aWRlbmNlIGlzIGEgZGlzdGluY3QgVDA0IGNvbXBsZXRpb24gZ2F0ZSBhbmQgaXMgbm90IHN1cHBsaWVkIGJ5IHRoZXNlIGNoZWNrcy4gU291cmNlIHByZXBhcmF0aW9uIGJhc2lzIGUwMzU5YmNiNmNkZmFkOWFiM2U4NjgwNTQxMjFmZTBjZWJlYzJkNjggcGx1czkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUgaXMgcmVjb3JkZWQ7IHRoZSBmaW5hbCBhcHBsaWVkIG93bmVyIGNvbW1pdCBtdXN0IGJlIHBpbm5lZCBiZWZvcmUgZXhlY3V0aW9uLgo=" + }, + { + "digest": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbF9pZCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgInRyaWFsX2lkIjogImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMSIsCiAgInN0YXRlIjogInByZXBhcmVkLXVuYXBwcm92ZWQiLAogICJ0YXJnZXQiOiAicmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbiIsCiAgImF1dGhvcml0eSI6ICJBRE1JTklTVEVSOyBhY3RpdmF0aW9uIEFQUFJPVkVEIG9ubHkgdXBvbiBleGFjdCBmb3VuZGVyIGRpc3Bvc2l0aW9uIiwKICAiY2FuZGlkYXRlX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYSIsCiAgInB1Ymxpc2hlZF9zb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInByaW9yX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgInByaW9yX2FyZ29fcmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgIm5hdGl2ZV9vYmplY3QiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJhcHBzL3YxIiwKICAgICJraW5kIjogIkRlcGxveW1lbnQiLAogICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAidWlkIjogImE1ODhlMTBhLTkwZDItNDg4My05NzVlLTZkZDhiOGZlY2E5MiIKICB9LAogICJhcmdvX2FwcGxpY2F0aW9uX3VpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICJzb3VyY2VfZ2F0ZSI6ICJBbGwgZm91ciBleGFjdCBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGluIGV4ZWN1dGlvbi1wbGFuLmpzb24gYW5kIGNsZWFuIGN1cnJlbnQgb3duZXIgSEVBRCBtdXN0IG1hdGNoOyBzb3VyY2UgcHJlcGFyYXRpb24gaXMgbm90IG5hdGl2ZSBhcHByb3ZhbCIsCiAgInN5bmNfc2NvcGUiOiBbCiAgICAiYXBwczpEZXBsb3ltZW50OmluZm9ybWVkLWRlY2lzaW9uIgogIF0sCiAgInBydW5lIjogZmFsc2UsCiAgImF1dG9tYXRlZF9zeW5jIjogZmFsc2UsCiAgInJ1bnRpbWVfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAic2NoZW1hIjogNSwKICAicmVxdWVzdGVkX29wZXJhdGlvbnMiOiBbCiAgICAiUHJvdGVjdGVkIFNRTGl0ZS1jb25zaXN0ZW50IG5hdGl2ZSBiYWNrdXAgYW5kIGluZGVwZW5kZW50bHkgcHJvdGVjdGVkIG9mZi1jbHVzdGVyIGN1c3RvZHkiLAogICAgIk9mZmxpbmUgcmVzdG9yZS9pbnRlZ3JpdHkvY291bnQgY29tcGFyaXNvbiBvbiBhIHByaXZhdGUgZGlzcG9zYWJsZSB2b2x1bWUgd2l0aCBleGFjdCBjYW5kaWRhdGUsIG5vIHJ1bnRpbWUgdG9rZW5zL2NvbmZpZy9uZXR3b3JrIiwKICAgICJSZWZyZXNoIGEgY29uc2lzdGVudCBwcmUtY3V0b3ZlciBzbmFwc2hvdCwgcmV0YWluIHByaXZhdGUgY29waWVzIGFuZCBjb3VudC1vbmx5L2hhc2ggcmVjZWlwdHMiLAogICAgIlBpbiBleGlzdGluZyBtYW51YWwgQXJnbyBBcHBsaWNhdGlvbiB0byBleGFjdCBhcHByb3ZlZCBvd25lciBzb3VyY2UgYW5kIG1hbnVhbGx5IHN5bmMgb25seSBleGlzdGluZyBEZXBsb3ltZW50IGltYWdlIiwKICAgICJWZXJpZnkgaGVhbHRoL3JlYWRpbmVzcy9pbWFnZS9tb2R1bGUvaW5zdGFsbGVkIGZhaWwtY2xvc2VkIHB1cnBvc2UgY2hlY2tzIGFuZCByZXRhaW5lZCBzY2hlbWEvY291bnQgZXZpZGVuY2U7IHJlY292ZXIgdG8gcHJpb3Igc2FtZS1zY2hlbWEgaW1hZ2UgaWYgbmVlZGVkIgogIF0sCiAgImV4ZWN1dGVfYnkiOiAiMjAyNi0xMC0xMlQyMzo1OTo1OVoiLAogICJ0ZW1wb3JhcnlfdnVsbmVyYWJpbGl0eV9yZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJrbm93bl9zY2FuX2ZpbmRpbmdzIjogIjBISUdIL0NSSVRJQ0FMLDFmaXhhYmxlIGluaGVyaXRlZE1FRElVTSB6bGliLCBhY3R1YWwgY3VycmVudGJhc2UrY2FuZGlkYXRlIGZpbmRpbmdzIGlkZW50aWNhbCIsCiAgInZ1bG5lcmFiaWxpdHlfcmVjb3JkIjogIklORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxIC8gSU5GRC1XUC0wMDA5LVQwNSIsCiAgImNvc3RfZXN0aW1hdGVfRVVSIjogMCwKICAiY29zdF9saW1pdHMiOiAiTm8gbmV3IHJlY3VycmluZyBpbmZyYXN0cnVjdHVyZTsgcHJpdmF0ZSBiYWNrdXAgc3RvcmFnZSBhbmQgYXR0ZW5kZWQgZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZCwgbm90IGFuIGF1dG9waWxvdCBjb3N0IGdyYW50IiwKICAicmlza19lc3RpbWF0ZXMiOiBbCiAgICAiQnJpZWYgUmVjcmVhdGUgc2VydmljZSBpbnRlcnJ1cHRpb247IG5vIGNvbmN1cnJlbnQgbmV3IHdyaXRlci9zdXJnZSIsCiAgICAiUHJpdmF0ZSBldmlkZW5jZSBzbmFwc2hvdCBjdXN0b2R5IGFuZCBkaXNwb3NhbCBlcnJvcnM7IG5vIHNuYXBzaG90cy90b2tlbnMgaW4gcHVibGljIGV2aWRlbmNlIiwKICAgICJDYW5kaWRhdGUgcHVycG9zZSByZWZ1c2FsIG1heSBleHBvc2UgY2FsbGVycyByZWx5aW5nIG9uIGFkdmlzb3J5IHJlc3VsdHMgYXMgYmluZGluZyIsCiAgICAiSW5oZXJpdGVkIGtub3duIGZpeGFibGUgTUVESVVNIHJlbWFpbnMgdW50aWwgc2VwYXJhdGVseSBhcHByb3ZlZCBvd25lciByZW1lZGlhdGlvbiIsCiAgICAiRXhpc3RpbmcgQXJnbyBPdXRPZlN5bmMgYmFzZWxpbmUgaXMgcmV0YWluZWQ7IG5vIHdob2xlLWFwcCBzeW5jIG9yIHVucmVsYXRlZCByZXBhaXJzIHBlcm1pdHRlZCIsCiAgICAiQWxsIHBoYXNlcywgaW5jbHVkaW5nIHJlY292ZXJ5L3ZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUgT2N0MTIgZGVhZGxpbmU7IGlmIHJlY292ZXJ5IHdpbmRvdyBpcyBleGhhdXN0ZWQgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gTm8gYXV0b21hdGljIGV4cGlyeSBjb250cm9sbGVyLiIKICBdLAogICJyb2xsYmFjayI6ICJNYW51YWwgQXJnbyBzb3VyY2UgcGluIGJhY2sgdG83ZGI4NDg1IGFuZCBzY29wZWQgRGVwbG95bWVudC1vbmx5IHN5bmMgdG83ZjVjIGltYWdlOyByZXRhaW4gY3VycmVudCBzY2hlbWE1IGRhdGFiYXNlIGFuZCBhbGwgcG9zdC1jdXRvdmVyIGV2aWRlbmNlLCBuZXZlciByZXN0b3JlIG9sZGVyIHNuYXBzaG90IG92ZXIgbGl2ZSB3cml0ZXMiLAogICJuYXRpdmVfZXhlY3V0ZWQiOiBmYWxzZSwKICAiaHVtYW5fYXBwcm92YWwiOiBmYWxzZSwKICAicmVmaW5lbWVudF9vZl9tYW5pZmVzdCI6ICI3YzY3MzhiMzllYThlNTRlNjFjOGVkNjI1ZTk0YWQwYjI3NTVlNjcyZTE1NzZlZmNkZjg0YTFkNjY1YWMzMzAwIiwKICAibWFuZGF0b3J5X3ByZV9vcGVuX2dhdGUiOiAic3RkbGliU1FMaXRlIG1vZGU9cm8vcXVlcnlfb25seTogc2NoZW1hNStpbnRlZ3JpdHkrY291bnQgYmFzZWxpbmUgYmVmb3JlIEFOWSBTdG9yZS9hZG1pbiBvbiBuYXRpdmUgc291cmNlIG9yIHJlc3RvcmVkY29weTsgcmVmdXNlb2xkc2NoZW1hcyB3aXRob3V0IG1pZ3JhdGlvbiIsCiAgIm9wdGltaXplZF9pbnRlcnByZXRlcnMiOiAibG9jYWwrcmVtb3RlIGV4cGxpY2l0bHlyZWZ1c2VkIGJlZm9yZWFzc2VydCBnYXRlcyIsCiAgIm5hdGl2ZV9kZXBlbmRlbmN5X2dhdGUiOiAic2VhbGVkIGFjdHVhbENNIFVJRC9pbW11dGFibGUvY2Fub25pY2FsZGF0YWhhc2grUFZDIFVJRC9mdWxsc3BlYy9Cb3VuZC92b2x1bWVOYW1lLCBubyByYXdDTWRhdGEgb3JTZWNyZXQgcmVhZHMiLAogICJsaXZlX2NvdW50cyI6ICJGcm96ZW4gc25hcHNob3QvY2xvbmUgZXhhY3Rjb3VudGVyIGVxdWFsaXR5OyBwb3N0Y3V0b3Zlci9yb2xsYmFjayBsaXZlY291bnRlcmNoYW5nZXMgbWF5IHJlZmxlY3QgbGVnaXRpbWF0ZSBjb25jdXJyZW50Y29tbWl0cy9zdGF0ZSB0cmFuc2l0aW9ucywgbGF0ZXN0REIgYWx3YXlzcmV0YWluZWQiLAogICJzb3VyY2VfYmFzaXMiOiB7CiAgICAicmV2aWV3ZWRfcHJvdG9jb2xfY29tbWl0IjogImUwMzU5YmNiNmNkZmFkOWFiM2U4NjgwNTQxMjFmZTBjZWJlYzJkNjgiLAogICAgIm93bmVyX2ZvbGxvd3Rocm91Z2hfY29tbWl0IjogIjkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUiLAogICAgImZpbmFsX2V4ZWN1dGlvbl9zb3VyY2UiOiAiZXhhY3Qgc3Vic2VxdWVudCByb290LWFwcGxpZWQgc291cmNlIGNvbW1pdCBtdXN0IGJlIGJvdW5kIGJ5IGZvdW5kZXIgcmVjZWlwdCBhbmQgdmVyaWZpZWQgYWdhaW5zdCBmb3VyIGFwcHJvdmVkIEdpdCBibG9icyIKICB9LAogICJhcHByb3ZlZF9vd25lcl9yZW5kZXJfYmxvYl9zaGEyNTYiOiB7CiAgICAiZGVwbG95L2xpZmVjeWNsZS9hZG1pc3Npb24uY2FuZGlkYXRlLmpzb24iOiAiOTIzODJhNTZiMzQ5YzNiODk1ZTU4MDZlOTc1MDgyNTI3YmI5OWQxYTAwMTE0MGU2OWQ4NTdlNWIwMzkxZmE1NSIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uIjogIjM4Yjc4YjljYmVlNWFkZTc3NTBhNThkNTE1NmNhNGM1NzczMzUyZTk0N2FjYjMwNGVlNzE0YjU5ZTc0OWNlYjQiLAogICAgImRlcGxveS9saWZlY3ljbGUva3VzdG9taXphdGlvbi55YW1sIjogIjFiYmNlODFiYzY3NTg0MzQzNTQxNTdmODYwMTUzNDMyMGM1ZDAyOTA1ODc5MDhmZDE1YTZkMjVlM2ZhNTdmNDciLAogICAgImRlcGxveS9saWZlY3ljbGUvcmVnaXN0cmllcy5jYW5kaWRhdGUuanNvbiI6ICI5YmFkNmRiNWZiYzIxNzhkMzFiMDQxMjAwMTZhNDE4MzBjMzU1MmZiYjllMjUxN2I3MThmOWJiZTg3Y2Y2NDllIgogIH0sCiAgImV4ZWN1dGlvbl9idW5kbGVfc2hhMjU2IjogIjI3ZDZkNmQzMTMzYzk2M2RhMWRkZTkyZDQ5OGQ2MzY2MTczODdjMTZlODUwYTE3YzU5ODE0OGFiYzM1Yzc3NWQiLAogICJleGVjdXRpb25faGVscGVyX21hbmlmZXN0X3NoYTI1NiI6ICJmMmZhZDZjMjUxZmJiNDQyMGUwN2MxMzI5ODAyZjUyMWI1MTNiYmY2NmU1MWY2NGM1ZDY3M2VmMDRmMTYyODRjIiwKICAiZXhlY3V0aW9uX3BsYW5fc2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiLAogICJleGVjdXRpb25fcGhhc2VzIjogWwogICAgImRyaWxsLWJhY2t1cCIsCiAgICAiZHJpbGwtY29weSIsCiAgICAib2ZmbGluZS12ZXJpZnkiLAogICAgImNsZWFudXAtb2ZmbGluZSIsCiAgICAiY3V0b3Zlci1iYWNrdXAiLAogICAgImN1dG92ZXItY29weSIsCiAgICAicmVsZWFzZSIsCiAgICAidmVyaWZ5IiwKICAgICJyb2xsYmFjayIsCiAgICAicm9sbGJhY2stdmVyaWZ5IgogIF0sCiAgImRlYWRsaW5lX3NlbWFudGljcyI6ICJBbGwgcGhhc2VzIGluY2x1ZGluZyB2ZXJpZmljYXRpb24vcmVjb3ZlcnkgbXVzdCBiZWdpbiBiZWZvcmUgZXhlY3V0ZV9ieS4gTm8gZXh0ZW5zaW9uIG9yIGF1dG9tYXRpYyBlbWVyZ2VuY3kgZ3JhbnQ7IGJleW9uZCBkZWFkbGluZSBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBDb21wbGV0ZSB0aGUgYm91bmRlZCBkcmlsbCBhbmQgcm9sbG91dCBlYXJseSBlbm91Z2ggdG8gYWxsb3cgcmVjb3Zlcnkgd2l0aGluIHRoZSB3aW5kb3cuIiwKICAib2ZmbGluZV9pbml0aWFsaXplciI6ICJPbmUgaXNvbGF0ZWQgbG9jYWwgVUlEMDowL0NBUF9DSE9XTi1vbmx5IGluaXRpYWxpemVyIG9mIHRoZSBuZXdseSBjcmVhdGVkIG5vbmNlLWJvdW5kIGRpc3Bvc2FibGUgdm9sdW1lLCBleGFjdCBjYW5kaWRhdGUgaW1hZ2UsIG5ldHdvcmtub25lL3JlYWRvbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzL0NQVTEvMTI4TWk7IG5vIGhvc3QvbGl2ZVBWQy90b2tlbi9jb25maWcgbW91bnQuIFN1YnNlcXVlbnQgcHJlLW9wZW4vYWRtaW4vcG9zdC1vcGVuIGNoZWNrcyBVSUQxMDAwMToxMDAwMS4iLAogICJyb2xsYmFja19kaXNwYXRjaCI6ICJTZWFsZWQgRGVwbG95bWVudC9DTS9QVkMgYW5kIHNhbWUtc2NoZW1hIHNvdXJjZS9pbWFnZSBwYWlyIHBsdXMgYWRtaXNzaW9uIENBUzsgbm8gUmVhZHkgY2FuZGlkYXRlIG9yIFBvZC9kYXRhYmFzZSBleGVjIHByZXJlcXVpc2l0ZS4gcm9sbGJhY2stdmVyaWZ5IHNlcGFyYXRlbHkgcHJvdmVzIHJlY292ZXJlZCBvbGQgaW1hZ2UvUmVhZHkxL3Njb3BlZCBvcGVyYXRpb24gYW5kIHJlYWRvbmx5IGN1cnJlbnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzLiIsCiAgInB1cnBvc2VfcHJvb2ZfbGltaXQiOiAiVGVuIGluc3RhbGxlZCBzeW50aGV0aWMtdHJhbnNwb3J0IGNoZWNrcyBvbiBhY3R1YWwgcGxhY2VtZW50OyBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIE5vdCBhY3R1YWwgcHJvdmlkZXIvUERQIGF1dGhvcml0eSBwcm9vZiwgd2hpY2ggcmVtYWlucyBhIGRpc3RpbmN0IFQwNCBjb21wbGV0aW9uIGdhdGUuIiwKICAicmVmaW5lbWVudF9vZl9hbWVuZGVkX21hbmlmZXN0IjogImIxZTNlNjZiYzQwMjNkYzgwYzZlYTU5NTY0YzM1NTdjNzY1M2ZiM2MzMDdmNDZhMDQ5OTk3Yjc2MTk4YTkwMzMiCn0K" + }, + { + "digest": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgIm9ic2VydmVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjQ6MDEuOTg1MTI4KzAwOjAwIiwKICAibmF0aXZlX293bmVyX3B1YmxpY2F0aW9uX2pvYiI6IHsKICAgICJpZCI6IDExNDg0LAogICAgIm5hbWUiOiAicHVibGlzaC1jYW5kaWRhdGUiLAogICAgImhlYWRfYnJhbmNoIjogIm1haW4iLAogICAgImhlYWRfc2hhIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgInJ1bl9udW1iZXIiOiAzLAogICAgImV2ZW50IjogInB1c2giLAogICAgImRpc3BsYXlfdGl0bGUiOiAiUHJlcGFyZSByZWFkYWJsZSBvdmVybGF5IGNvbnRleHQgd2l0aCB0aGUgYWRtaXR0ZWQgbGVnYWN5IGJ1aWxkZXIiLAogICAgInN0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJ3b3JrZmxvd19pZCI6ICJwdXJwb3NlLW92ZXJsYXktaW1hZ2UueWFtbCIsCiAgICAidXJsIjogImh0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uL2FjdGlvbnMvcnVucy8zIiwKICAgICJjcmVhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjA6NTlaIiwKICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjE6MDhaIiwKICAgICJydW5fc3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjIwOjU5WiIKICB9LAogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInBvbGljeV9zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgInJlZ2lzdHJ5X3Byb29mX3NoYTI1NiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAic291cmNlX3JlbmRlcl9jaGFuZ2Vfb25seSI6ICJEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHNwZWMudGVtcGxhdGUuc3BlYy5jb250YWluZXJzWzBdLmltYWdlIiwKICAicnVudGltZV9jb25maWdtYXBfdW5jaGFuZ2VkIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAiaW5zdGFsbGVkX2ltYWdlX2V4ZWN1dGlvbiI6IHsKICAgICJpbW11dGFibGVfcmVnaXN0cnlfYXJ0aWZhY3RfcHVsbGVkX2Fub255bW91c2x5IjogdHJ1ZSwKICAgICJVSUQiOiAxMDAwMSwKICAgICJHSUQiOiAxMDAwMSwKICAgICJwb2xpY3lfZmlsZV9VSUQiOiAwLAogICAgInBvbGljeV9maWxlX21vZGUiOiAiMDY0NCIsCiAgICAicHVycG9zZV92YXJpYW50cyI6IDEwLAogICAgImJpbmRpbmdfZm9ybXNfYWxsb3dlZCI6IDIsCiAgICAiYWR2aXNvcnlfb3JfbWFsZm9ybWVkX3JlZnVzZWQiOiA4LAogICAgIm5ldHdvcmsiOiAibm9uZSIsCiAgICAicmVhZF9vbmx5IjogdHJ1ZSwKICAgICJzeW50aGV0aWNfdHJhbnNwb3J0IjogdHJ1ZSwKICAgICJuYXRpdmVfUERQX3Rlc3QiOiBmYWxzZQogIH0sCiAgInNjYW5fc3VtbWFyeV9zaGEyNTYiOiAiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NCIsCiAgImhpc3RvcmljYWxfZmFpbGVkX3J1bnNfcmV0YWluZWQiOiBbCiAgICAiZjY2ZGU1MDUvdGFzazExNDgyL3J1bjEiLAogICAgImFjZWNhZDg4Ny90YXNrMTE0ODMvcnVuMiIKICBdLAogICJuYXRpdmVfaG9zdGluZ19jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJodW1hbl9hcHByb3ZhbCI6IGZhbHNlLAogICJldmlkZW5jZV9maWxlX3NoYTI1NiI6IHsKICAgICJpbWFnZS1tYW5pZmVzdC5qc29uIjogIjk3OGM1NzVkM2M3YmYwZGUzOWRiZTRlOTU2N2MzOWNkMzZmNzBiN2U1NWJjMTczNTdiZGIwM2ZiM2I5NmIwZmIiLAogICAgImltYWdlLWNvbmZpZy5qc29uIjogIjRhZDcyNDljNzVmZDlmYzAzOWNlYjE4Njc3MjQxOWUxY2JhNWZkOTc1OWM0MDQ1NTY0NTljODBhMmQyODVkMTAiLAogICAgImJhc2UtaW1hZ2UtY29uZmlnLmpzb24iOiAiYjcwNmM5MjA5ZTMyNGYzOWE4NmZmY2RhMmEzZTlkOTRjOTI2NDk3MzlhZDViMjFmZTQ2MTEwMDZlMzZmNmYwMCIsCiAgICAicmVnaXN0cnktcHJvb2YuanNvbiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAgICJ0cml2eS1mdWxsLmpzb24iOiAiZjM4YThmN2U2YzQxOWVlZDkxNTRkNzc2MmY5MzJiOWRlYjY2ODBhNjIyMjQ3YjA4MTk2Yjc0NThiODkzNDM0ZSIsCiAgICAic2JvbS5jZHguanNvbiI6ICJhNDI1Mjk1MWUyMDI3NDcyYzI2ZDg2NzljYjU0M2UzMDk4MzE4MDgwOWQ2ZGQzYzdjOTRiODgzZDYyODAzZTVkIiwKICAgICJiYXNlLXRyaXZ5LWZ1bGwuanNvbiI6ICJkNDRjNTU1YWVjYmIxYTQ1MThmNDEyN2Q0ODAxNWVhNDU5MzI1YzkzZThiMDM3MTkxMGE1NWRlNDcyOTNjYTgwIiwKICAgICJjaGVja19pbnN0YWxsZWQucHkiOiAiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZCIsCiAgICAidmVyaWZ5X3JlZ2lzdHJ5LnB5IjogIjQxM2Y1NzVjMjFhMmJkMThhMzY5NmY4ZjJkOTM5ZWVhZGM1MmQ3NmYyODJjNDI4MTNmNzZiYjBlM2VlOGEyYTQiLAogICAgInNxbGl0ZV9yZWFkb25seS5weSI6ICJlZWY1M2RkMjMzZWVlNzRjMTdmMjA4MjNiZDdmNTc4N2M2MGNhZDc5YWM2NDgwMjFjOTQ3OTY0M2M2Y2U5ZTM4IiwKICAgICJzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uIjogIjA0MjMyN2EwMzZlZDI1NGNmOTVkYmViMGMwNTZhYzI1YjAzYTZhODQ0Yjk1YTMzMmM5OTJkZjI5NDM2OTEzNjkiLAogICAgInJldmlldy1yZWZpbmVtZW50Lmpzb24iOiAiZWE2Mjg0NWNlZTVlZTZmNGY2Y2I3ZjVkY2QwYWY2MDFiYTI5YTIxYzhmZjgwZWZiYmMwMmFkMTZlMzViZWE3NSIsCiAgICAidGVzdF9jaGFuZ2VfZ3VhcmQucHkiOiAiZGE1MzUwNDM3MzU3YmEzMjkyMzZjYzEzNzYxMGMwMzg1NmYzOGY4MzZkZGYyODU2MDI1YmMxMjAxMWZhZDA3ZiIsCiAgICAidGVzdF9zcWxpdGVfcmVhZG9ubHkucHkiOiAiYzdhOTFkMGM2YTM3M2Q3MzhjODhiYjgxN2Q5YmZiMmZmOGExNzliYzYxYjkzMDYzYjg5Njc3YjU2NjUyMDMyMyIsCiAgICAidGVzdF9wcmVmbGlnaHRfb3B0aW1pemF0aW9uLnB5IjogImEwYzRmYTE4YzVkNmMyMTQ3NmEwNmM2ZDA1ZmU3NjU2MjU5ZDIwNDI5OTEzODg1MTU5OWU5MjE0ZDkxMTIwNmQiCiAgfQp9Cg==" + }, + { + "digest": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZV9kaWdlc3QiOiAic2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgImJhc2VfaW1hZ2VfZGlnZXN0IjogInNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAiYmFzZV9sYXllcl9ieXRlc19pZGVudGljYWwiOiB0cnVlLAogICJsYXllcl9tZWRpYV90eXBlX2NvbnZlcnNpb24iOiAiT0NJIGd6aXAgdG8gRG9ja2VyIGd6aXAsIHNhbWUgZGlnZXN0IGFuZCBzaXplIiwKICAiYmFzZV9ydW50aW1lX2NvbmZpZ19zZW1hbnRpY3NfaWRlbnRpY2FsIjogdHJ1ZSwKICAibGVnYWN5X2J1aWxkZXJfY29uZmlnX2FkZGl0aW9ucyI6IHsKICAgICJIb3N0bmFtZSI6ICIiLAogICAgIkRvbWFpbm5hbWUiOiAiIiwKICAgICJBdHRhY2hTdGRpbiI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZG91dCI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZGVyciI6IGZhbHNlLAogICAgIlR0eSI6IGZhbHNlLAogICAgIk9wZW5TdGRpbiI6IGZhbHNlLAogICAgIlN0ZGluT25jZSI6IGZhbHNlLAogICAgIkNtZCI6IG51bGwsCiAgICAiVm9sdW1lcyI6IG51bGwsCiAgICAiT25CdWlsZCI6IG51bGwsCiAgICAiSW1hZ2UiOiAic2hhMjU2OjkwZjE1NzRmOWVkYTM1ZmE2Y2I5NzI5NjFiZWIyN2E3Y2I5MDRjMzY1NjBlMzgxOTMwYjBlMTQwNjVjMjM4ODMiCiAgfSwKICAiYmFzZV9yb290ZnNfcHJlZml4X2lkZW50aWNhbCI6IHRydWUsCiAgIm92ZXJsYXlfcmVndWxhcl9maWxlcyI6IFsKICAgICJvcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weSIKICBdLAogICJvdmVybGF5X2RpcmVjdG9yaWVzIjogWwogICAgIm9wdCIsCiAgICAib3B0L3ZlbnYiLAogICAgIm9wdC92ZW52L2xpYiIsCiAgICAib3B0L3ZlbnYvbGliL3B5dGhvbjMuMTIiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24iCiAgXSwKICAicG9saWN5X3NoYTI1NiI6ICI5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyIiwKICAicG9saWN5X21vZGUiOiAiMDY0NCIsCiAgImJhc2VfdXNlciI6ICIxMDAwMToxMDAwMSIsCiAgInNvdXJjZV9zY29wZV9sYWJlbHMiOiB7CiAgICAib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnJldmlzaW9uIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgIm9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5iYXNlLmRpZ2VzdCI6ICJzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgICAic29jaWFsLmNvdWxvbWIuc291cmNlLnBvbGljeS5zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgICAic29jaWFsLmNvdWxvbWIucmVsZWFzZS5zY29wZSI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIKICB9LAogICJyZWdpc3RyeV9yZWFkX3JvdXRlIjogImFub255bW91cyBwdWJsaWMgc2NvcGVkIGJlYXJlciBjaGFsbGVuZ2UsIG5vIHRva2VuIHJldGVudGlvbiIsCiAgImltYWdlX2V4ZWN1dGVkIjogZmFsc2UsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlCn0K" + }, + { + "digest": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInNjYW5uZXIiOiAiYXF1YXNlYy90cml2eUBzaGEyNTY6NjJiMWU2NWU4ODY5YmM0YjRjNmFhNGZhMmIyMTU5NTI1NmM3YzJmNjAxOGE5ZDlhZDYxY2FmODcxODdjMTk2OSIsCiAgInZlcnNpb24iOiAiMC43NC4wIiwKICAiZGJfbWV0YWRhdGEiOiB7CiAgICAiVmVyc2lvbiI6IDIsCiAgICAiTmV4dFVwZGF0ZSI6ICIyMDI2LTEwLTExVDE4OjU5OjUwLjg4OTAxMDU3MloiLAogICAgIlVwZGF0ZWRBdCI6ICIyMDI2LTEwLTEwVDE4OjU5OjUwLjg4OTAxMDkyM1oiLAogICAgIkRvd25sb2FkZWRBdCI6ICIyMDI2LTEwLTEwVDIzOjMyOjMyLjM4MDAzMzEzMVoiCiAgfSwKICAic3VwcHJlc3Npb24iOiBmYWxzZSwKICAiaWdub3JlX3VuZml4ZWQiOiBmYWxzZSwKICAic2V2ZXJpdHlfZmlsdGVyIjogbnVsbCwKICAicGFja2FnZV9jb3VudCI6IDQ0LAogICJmaW5kaW5nc19ieV9zZXZlcml0eSI6IHsKICAgICJNRURJVU0iOiAxCiAgfSwKICAiZmluZGluZ3MiOiBbCiAgICB7CiAgICAgICJpZCI6ICJDVkUtMjAyNi04NTA5MSIsCiAgICAgICJwYWNrYWdlIjogInpsaWIiLAogICAgICAiaW5zdGFsbGVkIjogIjEuMy4yLXIwIiwKICAgICAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAgICAgInNldmVyaXR5IjogIk1FRElVTSIKICAgIH0KICBdLAogICJjb3ZlcmFnZV9saW1pdHMiOiBbCiAgICAiQWxwaW5lMy4yNCBhYnNlbnQgc2Nhbm5lciBFT0wgbGlzdDsgT1MgZGV0ZWN0b3IgcmFuIGFnYWluc3QgQWxwaW5lMy4yNCByZXBvc2l0b3J5IG9uMzhPUyBwYWNrYWdlcyIsCiAgICAiS25vd24gZmluZGluZ3MgYXNvZiBwaW5uZWREQiwgbm90IGNsYWltIGFic2VuY2Ugb2YgdW5rbm93biB2dWxuZXJhYmlsaXRpZXMiCiAgXSwKICAiaGlnaF9jcml0aWNhbCI6IDAsCiAgInNhbWVfc2Nhbm5lcl9hY3R1YWxfYmFzZV9zY2FuX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgImJhc2Vfc2Nhbl9maWxlIjogImJhc2UtdHJpdnktZnVsbC5qc29uIgp9Cg==" + }, + { + "digest": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "media_type": "application/json", + "content_base64": "ewogICJraW5kIjogImluZm9ybWVkLWRlY2lzaW9uLmV4ZWN1dGlvbi1zb3VyY2UtYnVuZGxlIiwKICAidmVyc2lvbiI6IDEsCiAgInByb3Bvc2FsX2lkIjogIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxIiwKICAiZmlsZXMiOiB7CiAgICAiUkVBRE1FLm1kIjogewogICAgICAic2hhMjU2IjogImE2ZWNkYWJlYmNlMTJlZWFmZWE2MTE3M2VkYjZlNmQwZTM0OWE3NmUzNjY1NDY5NzhlMmVkMDJlN2IxMDlkZjIiLAogICAgICAiY29udGVudCI6ICIjIFN1cGVydmlzZWQgSW5mb3JtZWQgRGVjaXNpb24gcHVycG9zZSByZWxlYXNlIGV4ZWN1dG9yIOKAlCB1bmFwcHJvdmVkIHByZXBhcmF0aW9uXG5cbk5vIG5hdGl2ZSBkYXRhYmFzZSByZWFkLCBiYWNrdXAvZXhwb3J0L3Jlc3RvcmUgb3Igd29ya2xvYWQgYWN0aW9uIGhhcyBiZWVuIHJ1bi4gVGhpcyBzb3VyY2UgaW1wbGVtZW50cyB0aGUgcmV2aWV3ZWQgcHJvdG9jb2w7IGl0cyBhZGRpdGlvbmFsIG1lY2hhbmljYWwgZGV0YWlscyBuZWVkIHBlZXIgcmV2aWV3IGFuZCBhbiBhbWVuZGVkIGhhc2gtYm91bmQgcGFja2V0IGJlZm9yZSBmaXJzdCBodW1hbiBzdWJtaXNzaW9uLiBUaGUgb3JpZ2luYWw3OHBhdGggcGFja2V0L3Jldmlld3MgcmVtYWluIGhpc3RvcmljYWwgdGVjaG5pY2FsIGFncmVlbWVudCwgbm90IGZvdW5kZXIgYXBwcm92YWwgb2YgdGhpcyBleGVjdXRvci5cblxuUnVuIG9uZSBwaGFzZSBhdCBhIHRpbWUgb25seSBhZnRlciB0aGUgY29vcmRpbmF0b3IgaGFzIGZyZXNobHkgYXV0aGVudGljYXRlZCB0aGUgZXhhY3QgZm91bmRlciBkaXNwb3NpdGlvbiBhdCB0aGUgZXhpc3RpbmcgZml4ZWQgSW5mb3JtZWQgRGVjaXNpb24gb3JpZ2luLiBSb290IHdyaXRlcyB0aGUgcHJvdGVjdGVkMDYwMCBmaXhlZCBmaWxlcyBgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2Utcm9vdC1hdXRob3JpdHkuanNvbmAgYW5kIGAvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1uYXRpdmUtb3V0Y29tZS1sYXRlc3QuanNvbmAuIFRoZSByZWNlaXB0IHRlbXBsYXRlIGlzIFBFTkRJTkcgYW5kIGNhbm5vdCBhdXRob3JpemUgYW55dGhpbmcuIFRoZSBoZWxwZXIgY2hlY2tzIGV4YWN0IG5lc3RlZCBjb25maXJtZWQgcGVyc29uL3BsYXRmb3JtLXJvb3QgQUNDRVBUIHZlcnNpb24xLCBvcmlnaW5hbCBtZW1vIGlkZW50aXR5L2N1cnJlbnQgbWVtbyBTSEEsIHNvdXJjZSBjb21taXQsIHBsYW4gU0hBIGFuZCBmcmVzaG5lc3MxMjBzZWNvbmRzLiBUaGlzIGlzIHN1cGVydmlzZWQgcmVjZWlwdCBib29ra2VlcGluZywgbm90IGNyeXB0b2dyYXBoaWMgcHJvdmlkZXIgdmVyaWZpY2F0aW9uLCBhIHNpZ25lZCBncmFudCBvciBhZ2VudCBhdXRvbm9teSBwcm9tb3Rpb24uIFJvb3QvaGFybmVzcyBzdXBlcnZpc2lvbiByZW1haW5zIHRoZSBhdXRob3JpdHkgYm91bmRhcnkuIE5ldmVyIHN5bnRoZXNpemUgYW4gYXBwcm92YWwgcmVjZWlwdCBmcm9tIGEgdGVjaG5pY2FsIHJldmlldyBvciBjYWxsZXIgYXNzZXJ0aW9uLlxuXG5JbnZvY2F0aW9uIGFmdGVyIGFjdHVhbCBhcHByb3ZhbDogYHB5dGhvbjMgZXhlY3V0aW9uL2FjdHVhdG9yLnB5IC0tcGhhc2UgPGZpeGVkLXBoYXNlPiAtLXJvb3QtYXV0aG9yaXR5LXJlY2VpcHQgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2Utcm9vdC1hdXRob3JpdHkuanNvbiAtLXJvb3QtbmF0aXZlLW91dGNvbWUgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2UtbmF0aXZlLW91dGNvbWUtbGF0ZXN0Lmpzb24gLS1zb3VyY2UtcmV2aXNpb24gPGV4YWN0LWZpbmFsLW93bmVyLWNvbW1pdD5gLiBPcmRlcjogZHJpbGwtYmFja3VwIOKGkiBkcmlsbC1jb3B5IOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnkuIFJvbGxiYWNrIGlzIGEgZGlzdGluY3QgYXV0aG9yaXplZCByZWNvdmVyeSBhZnRlciBhIHJlY29yZGVkIHJlbGVhc2UgYXR0ZW1wdCwgZm9sbG93ZWQgYnkgcm9sbGJhY2stdmVyaWZ5LiBSb2xsYmFjayBkaXNwYXRjaCBuZWVkcyBubyBSZWFkeSBQb2Qgb3IgY2FuZGlkYXRlIGRhdGFiYXNlIGV4ZWM6IHNlYWxlZCBEZXBsb3ltZW50L0NNL1BWQy9zb3VyY2UvaW1hZ2UgcGFpciBhbmQgYWRtaXNzaW9uIENBUyByZW1haW4gbWFuZGF0b3J5LiBJdHMgYWNrbm93bGVkZ21lbnQgaXMgbm90IHJlY292ZXJ5IGNvbXBsZXRpb247IHJvbGxiYWNrLXZlcmlmeSBzZXBhcmF0ZWx5IHJlcXVpcmVzIFJlYWR5MSBvZiB0aGUgb2xkIGltYWdlLCBzdWNjZWVkZWQgZXhhY3Qgc2NvcGVkIG9wZXJhdGlvbiBhbmQgcmVhZG9ubHkgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnQgcHJvb2Ygb2YgdGhlIGN1cnJlbnQgcmV0YWluZWQgZGF0YWJhc2UuIFJvb3QgcmVmcmVzaGVzIGFjdHVhbCBuYXRpdmUgYWNjZXB0YW5jZSBpbW1lZGlhdGVseSBiZWZvcmUgZWFjaCBwaGFzZS5cblxuVGhlIHByaXZhdGUgaWdub3JlZCBDdXN0b2RpYW4gY3VzdG9keSBwYXJlbnQgYC5wcml2YXRlLWJhY2t1cHNgIG11c3QgYWxyZWFkeSBleGlzdCwwNzAwIG93bmVkIGJ5IHRoZSB3b3Jrc3RhdGlvbiBhZ2VudCB1c2VyOyB0aGUgZXhhY3QgY2FzZSBjaGlsZDIwMjYxMDExLWluZmQtcHVycG9zZS1yMSBpcyBjcmVhdGVkIG9ubHkgYWZ0ZXIgYXV0aG9yaXR5IGNoZWNrcy4gTmF0aXZlIHBhcmVudCBgL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjFgIGlzIHVuaXF1ZWx5IGNyZWF0ZWQgYnkgVUlEMTAwMDEgZm9yIGRyaWxsL2N1dG92ZXIgU1FMaXRlLWNvbnNpc3RlbnQgc25hcHNob3RzLCBlYWNoMDYwMC9ub25zeW1saW5rL3NpbmdsZS1saW5rLiBUaGUgYXR0YWNoZWQgc3RkbGliIHJlYWRvbmx5IGNoZWNrZXIgbXVzdCByZXBvcnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzIGJlZm9yZSBhbnkgU3RvcmUvYWRtaW4gb24gbmF0aXZlIHNvdXJjZSBvciBvZmZsaW5lY2xvbmUuIEludmFsaWQgc3RhdGVzL2NvdW50IHNoYXBlcyBhbmQgYWxsIHJhdyBjaGlsZCBvdXRwdXRzIGFyZSB3aXRoaGVsZC4gTWFpbi1vbmx5IHNuYXBzaG90IGNsb3N1cmUgaXMgdmVyaWZpZWQgYmVmb3JlIGJpbmFyeSB0cmFuc2Zlcjsgc3RkaW4vc3Rkb3V0IHNuYXBzaG90IGJ5dGVzIHJlYWNoIG9ubHkgcHJpdmF0ZSBmaWxlcyBvciB0aGUgaXNvbGF0ZWQgcmVzdG9yZSBjb3B5LCBuZXZlciB0b29sL2NoYXQvbG9nIG91dHB1dC4gU3RyZWFtcyBzdG9wIGJleW9uZCBmcm96ZW4gYnl0ZSBjb3VudC81MTJNaUI7IGZhaWx1cmVzIHJldGFpbiBwYXJ0aWFsIHByaXZhdGUgZXZpZGVuY2UuXG5cbk5ldyBwcml2YXRlIG9mZmxpbmUgdm9sdW1lIGBpbmZkLXB1cnBvc2UtcjEtcmVzdG9yZS0yMDI2MTAxMWAgaXMgY3JlYXRlZCBvbmx5IG9uIHRoZSBwaW5uZWQgbG9jYWwgd29ya3N0YXRpb24gRG9ja2VyIHNvY2tldC9lbmdpbmUgYm50LWxhcDAwMSwgd2l0aCBsb2NhbGRyaXZlci9ub29wdGlvbnMgYW5kIGF0dGVtcHRub25jZSBsYWJlbHMuIE9uZS10aW1lIGluaXRpYWxpemVyIHJ1bnMgZXhhY3Q3NjNjIGFzIFVJRDAgd2l0aCBvbmx5IENBUF9DSE9XTiwgbmV0d29ya25vbmUvcmVhZC1vbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzLCBvbmUgTkVXIG5hbWVkdm9sdW1lIG1vdW50LCBubyBob3N0L2xpdmVQVkMvY3JlZGVudGlhbC9jb25maWcgbW91bnRzLiBJdCByZWNlaXZlcyBvbmx5IHRoZSBwcm90ZWN0ZWQgc25hcHNob3Qgb24gc3RkaW4sIHZlcmlmaWVzIGJ5dGVzLCBzZXRzIGZvbGRlcjA3MDAvZmlsZTA2MDAgb3duZWQxMDAwMS4gVGhlbiBVSUQxMDAwMSBwZXJmb3JtcyByZWFkb25seSBwcmUtb3BlbiB2YWxpZGF0aW9uLCBgLS1lbnRyeXBvaW50IGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGluc3BlY3QgLS1kYiAvcmVzdG9yZS9yZXZpZXcuc3FsaXRlYCwgbmV2ZXIgdGhlIHNlcnZpY2UgZW50cnlwb2ludC4gQSBzZWNvbmQgVUlEMTAwMDEvbmV0d29yay1ub25lIHJlYWRvbmx5IGludGVncml0eS9zY2hlbWEvY291bnQgY2hlY2sgYWZ0ZXIgYWRtaW4gbXVzdCBleGFjdGx5IGVxdWFsIHRoZSBmcm96ZW4gc25hcHNob3QgcHJvb2YsIGFuZCB0aGUgb3JpZ2luYWwgcHJvdGVjdGVkIHNuYXBzaG90IFNIQSBtdXN0IHJlbWFpbiB1bmNoYW5nZWQuIENsZWFudXAgY29tcGFyZXMgZXhhY3Qgbm9uY2UvY3JlYXRpb24gaWRlbnRpdHkgYW5kIHJlbW92ZXMgb25seSB0aGlzIGNsb25lIHZvbHVtZSwgcmV0YWluaW5nIGFsbCBuYXRpdmUvb2ZmY2x1c3RlciBvcmlnaW5hbHMuIENQVTEvbWVtb3J5MTI4TWlCOyBwcml2YXRlIG9mZmNsdXN0ZXIgY2FwYWNpdHkgYXQgbGVhc3QxR2lCKzE2TWlCIGFuZCBuYXRpdmUgZXN0aW1hdGVkIHR3by9vbmUtc25hcHNob3QgaGVhZHJvb20gcmVxdWlyZWQuXG5cbkV2ZXJ5IHBoYXNlIGZzeW5jcyBSVU5OSU5HIGludGVudCBiZWZvcmUgZGlzcGF0Y2guIEFueSBmYWlsdXJlL2ludGVycnVwdGlvbi9hbWJpZ3VvdXMgcmVzdWx0IHJlbWFpbnMgVU5DRVJUQUlOOyBzYW1lLXBoYXNlIHJldHJ5IGlzIHJlZnVzZWQuIFNlcGFyYXRlIG9wZXJhdG9yIGRpYWdub3NpcyBhbmQgYW55IG5lZWRlZCByZWNvdmVyeSBhcmUgcmVjb3JkZWQ7IG5laXRoZXIgc25hcHNob3RzIG5vciB1bnJlc29sdmVkL25ldyByZWNvcmRzIGFyZSByZW1vdmVkIHRvIG1ha2UgY2hlY2tzIGdyZWVuLiBGcm96ZW4gc25hcHNob3QvY2xvbmUgY291bnRlcnMgbXVzdCBhZ3JlZTsgbGl2ZSBwb3N0LWN1dG92ZXIvcm9sbGJhY2sgY291bnRlcnMgY2FuIGluY2x1ZGUgbGVnaXRpbWF0ZSBjb25jdXJyZW50IGNvbW1pdHMvc3RhdGUgdHJhbnNpdGlvbnMuXG5cbkV4aXN0aW5nIEFwcGxpY2F0aW9uIFVJRCBhbmQgYWN0dWFsIERlcGxveW1lbnQvUG9kL0NNL1BWQyBjdXN0b2R5L3NvdXJjZSBhcmUgY2hlY2tlZC4gQWxsIGZvdXIgb3duZXIgcmVuZGVyIEdpdCBibG9icyBtdXN0IG1hdGNoOyBvdmVycmlkZXMvcGx1Z2lucy9tdWx0aXBsZSBzb3VyY2VzIGFuZCBldmVuIGF1dG9tYXRlZDp7fSBhcmUgcmVqZWN0ZWQuIFRoZSBleGlzdGluZyBBcHBsaWNhdGlvbi5vcGVyYXRpb24gQVBJIGlzIHVzZWQgKG5hdGl2ZSBhcmdvY2QgQ0xJIGlzIGFic2VudCksIHdpdGggc2VydmVyIGRyeS1ydW4sIHJlc291cmNlVmVyc2lvbi9VSUQvc291cmNlIHRlc3RzLCBvbmUgRGVwbG95bWVudCBvbmx5LCBwcnVuZT1mYWxzZS4gRGlzcGF0Y2ggYWNrbm93bGVkZ21lbnQgaXMgbm90IHJvbGxvdXQgY29tcGxldGlvbi4gVmVyaWZ5IHJlcXVpcmVzIGV4YWN0IHN1Y2NlZWRlZCBvcGVyYXRpb24vY29udHJvbGxlciBnZW5lcmF0aW9uL1JlYWR5MSwgc2FtZSBzY2hlbWE1IERCLCBhY3R1YWwgaW5zdGFsbGVkIGhhc2gvbW9kZS9VSUQgYW5kMTBwdXJwb3NlIGNoZWNrcyBwbHVzIGJvdW5kZWQgbG9jYWxob3N0aGVhbHRoL3JlYWRpbmVzcy4gUHVycG9zZSB0cmFuc3BvcnQgcmVtYWlucyBzeW50aGV0aWMgYW5kIGlzIGV4cGxpY2l0bHkgbm90IGEgbmF0aXZlIFBEUCBhdXRob3JpdHkgdGVzdC4gUm9sbGJhY2sgcGlucyBwcmlvcjdkYi83ZjUgdGhyb3VnaCB0aGUgc2FtZSBzY29wZWQgd29ya2Zsb3cgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQgbGl2ZSBkYXRhYmFzZTsgaXQgbmV2ZXIgcmVzdG9yZXMgYW4gb2xkZXIgc25hcHNob3Qgb3ZlciBsYXRlciB3cml0ZXMuXG5cblNpeHRlZW4gc3ludGhldGljIHRlc3RzIHBhc3MgYWdhaW5zdCBmcm96ZW4gY2FzZSBtZXRhZGF0YTogYXV0aG9yaXR5L2V4cGlyeS9hY3Rvci9hbWJpZ3VpdHkgcmVmdXNhbHMsIGNyYXNoIGludGVudC9ubyByZXRyeS9vcmRlciwgY3JlZGVudGlhbC1vdXRwdXQgd2l0aGhvbGRpbmcsIHByaXZhdGUgYm91bmRlZCBiaW5hcnljb3B5LCB2b2x1bWUgcmVjcmVhdGlvbiBjbGVhbnVwIHJlZnVzYWwsIHNvdXJjZS9hdXRvbWF0aW9uL0NNL1BWQy9SZWFkeSBkcmlmdCwgcHJlLW9wZW4gZ2F0ZSByZWZ1c2FsIGFuZCBleGFjdCBEZXBsb3ltZW50LW9ubHkgb3BlcmF0aW9uL2RyeS1ydW4uIFRoZXNlIGFyZSBzb3VyY2UgdGVzdHMsIG5vdCBuYXRpdmUgYmFja3VwIG9yIHJlbGVhc2UgcHJvb2YuXG5cbkFsbCBwaGFzZXMsIGluY2x1ZGluZyByZWNvdmVyeSBhbmQgdmVyaWZpY2F0aW9uLCBhcmUgYm91bmRlZCBieSAyMDI2LTEwLTEyVDIzOjU5OjU5Wi4gVGhpcyBleHBsaWNpdGx5IHJlZmluZXMgdGhlIGVhcmxpZXIgcGFja2V0IGRlYWRsaW5lIHdvcmRpbmcgZm9yIHVuc3RhcnRlZCByZWxlYXNlOiB0aGUgaGVscGVyIGRvZXMgbm90IGV4dGVuZCBhdXRob3JpdHkgcGFzdCB0aGUgZGVhZGxpbmUuIFN0YXJ0IHN1ZmZpY2llbnRseSBlYXJseSB0byBjb21wbGV0ZSBkcmlsbC9jdXRvdmVyL3JlY292ZXJ5OyBhZnRlciBleHBpcnkgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gVGhpcyBtYXkgZGVsYXkgcmVjb3ZlcnkgaWYgdGhlIHdpbmRvdyBpcyBleGhhdXN0ZWQsIGFuZCBtdXN0IGJlIGRpc2Nsb3NlZCBiZWZvcmUgYWNjZXB0YW5jZS5cblxuVGhlIGluaXRpYWwgMTEtZmlsZSBoZWxwZXIgZnJlZXplIFNIQTY1M2I2OGMzODkxYzA2NmY0MGQxMDRiZmM2N2EzNWRhNWU0MzY2MDVjZDk5YWZkNTJmYmFjNGI0N2E5NTUzZmUgYW5kIGluZGVwZW5kZW50IGNvbmRpdGlvbmFsIGZpbmRpbmdzIHJlbWFpbiBhcmNoaXZlZCB1bmRlciBleGVjdXRpb24taGlzdG9yeS9pbml0aWFsLTY1M2I2OGMzLiBUaGlzIHJlZmluZW1lbnQgaXMgdGhlIHNhbWUgcHJvcG9zYWwvdHJpYWw7IG5vIG5hdGl2ZSBleGVjdXRpb24gb3IgaHVtYW4gYWNjZXB0YW5jZSBoYXMgb2NjdXJyZWQuXG4iCiAgICB9LAogICAgImFjdHVhdG9yLnB5IjogewogICAgICAic2hhMjU2IjogIjZiOWQ2NDM5ODYyNDU0ZjI2MWVlNzdmMDViMjY1MTlmODEwOTU5OWIxZjY3MDc4YmM0ZTFmN2M3YzQwNjFiYTUiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmUgZml4ZWQgc3VwZXJ2aXNlZCBwaGFzZTsgbmV2ZXIgcnVuIHRoaXMgZHVyaW5nIHNvdXJjZSBwcmVwYXJhdGlvbi5cIlwiXCJcbmltcG9ydCBhcmdwYXJzZVxuaW1wb3J0IGhhc2hsaWJcbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHJlXG5pbXBvcnQgc2VsZWN0b3JzXG5pbXBvcnQgc3RhdFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0aW1lXG5cbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KCdvcHRpbWl6ZWQgaW50ZXJwcmV0ZXIgcmVmdXNlZCcpXG5cblBIQVNFUyA9ICgnZHJpbGwtYmFja3VwJywgJ2RyaWxsLWNvcHknLCAnb2ZmbGluZS12ZXJpZnknLCAnY2xlYW51cC1vZmZsaW5lJyxcbiAgICAgICAgICAnY3V0b3Zlci1iYWNrdXAnLCAnY3V0b3Zlci1jb3B5JywgJ3JlbGVhc2UnLCAndmVyaWZ5JywgJ3JvbGxiYWNrJywgJ3JvbGxiYWNrLXZlcmlmeScpXG5cblxuZGVmIHJlcXVpcmUodmFsdWUsIHJlYXNvbik6XG4gICAgaWYgbm90IHZhbHVlOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcblxuXG5kZWYgc2hhKHBhdGgpOlxuICAgIGRpZ2VzdCA9IGhhc2hsaWIuc2hhMjU2KClcbiAgICB3aXRoIFBhdGgocGF0aCkub3BlbigncmInKSBhcyBzdHJlYW06XG4gICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6XG4gICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJsb2NrKVxuICAgIHJldHVybiBkaWdlc3QuaGV4ZGlnZXN0KClcblxuXG5kZWYgcHJpdmF0ZShwYXRoLCBkaXJlY3Rvcnk9RmFsc2UpOlxuICAgIGluZm8gPSBQYXRoKHBhdGgpLmxzdGF0KClcbiAgICByZXF1aXJlKChzdGF0LlNfSVNESVIoaW5mby5zdF9tb2RlKSBpZiBkaXJlY3RvcnkgZWxzZSBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSlcbiAgICAgICAgICAgIGFuZCBpbmZvLnN0X3VpZCA9PSBvcy5nZXR1aWQoKSBhbmQgc3RhdC5TX0lNT0RFKGluZm8uc3RfbW9kZSkgPT0gKDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxuICAgICAgICAgICAgYW5kIChkaXJlY3Rvcnkgb3IgaW5mby5zdF9ubGluayA9PSAxKSwgJ3ByaXZhdGUgb3duZWQgY3VzdG9keSByZXF1aXJlZCcpXG5cblJPT1QgPSBQYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50XG5DQVNFID0gUk9PVC5wYXJlbnRcbk9XTkVSID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uJylcbkNVU1RPRElBTiA9IFBhdGgoJy9ob21lL3dvcnNjaC90aGUtY3VzdG9kaWFuJylcbkNVU1RPRFkgPSBDVVNUT0RJQU4gLyAnLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjEnXG5TT0NLRVQgPSAndW5peDovLy92YXIvcnVuL2RvY2tlci5zb2NrJ1xuSU1BR0UgPSAnZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhJ1xuVk9MVU1FID0gJ2luZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExJ1xuTUFYX0JZVEVTID0gNTEyICogMTAyNCoqMlxuXG5cbmRlZiBydW4oYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTkwKTpcbiAgICByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndiwgaW5wdXQ9Ym9keSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIGpzb25fcmVzdWx0KHJlc3VsdCk6XG4gICAgdHJ5OlxuICAgICAgICB2YWx1ZSA9IGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcbiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhZmUgcGhhc2UgcmVjZWlwdCB1bmF2YWlsYWJsZTsgb3V0Y29tZSB1bmNlcnRhaW4nKSBmcm9tIE5vbmVcbiAgICByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlID09IDAgYW5kIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIFRydWUsXG4gICAgICAgICAgICAncGhhc2UgZGlkIG5vdCB2ZXJpZnkgY29tcGxldGU7IHJhdyBvdXRwdXQgd2l0aGhlbGQ7IG5vIHJldHJ5JylcbiAgICBwZXJtaXR0ZWQgPSB7J3BoYXNlJywgJ2FsbF9jaGVja3NfcGFzcycsICdyYXdfb3V0cHV0X3dpdGhoZWxkJywgJ25hdGl2ZV9hcHByb3ZhbF92ZXJpZmllZF9ieV9yb290JyxcbiAgICAgICAgICAgICAgICAgJ25hdGl2ZV9hdXRoZW50aWNhdGVkX2dyYW50JywgJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZScsICdzbmFwc2hvdF9yZWFkb25seScsXG4gICAgICAgICAgICAgICAgICdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICduYXRpdmVfcGFyZW50X3ByaXZhdGUnLFxuICAgICAgICAgICAgICAgICAnbmF0aXZlX3VpZCcsICdwb2RfbmFtZScsICdwb2RfdWlkJywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnLFxuICAgICAgICAgICAgICAgICAnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzJywgJ29wZXJhdGlvbl9yZXF1ZXN0ZWQnLCAnc291cmNlX3JldmlzaW9uJyxcbiAgICAgICAgICAgICAgICAgJ3Jlc291cmNlcycsICdwcnVuZScsICdyb2xsb3V0X3ZlcmlmaWVkJywgJ2xhdGVzdF9saXZlX2RhdGFiYXNlX3JldGFpbmVkJyxcbiAgICAgICAgICAgICAgICAgJ2NsaWVudF9kaWZmX3NoYTI1NicsICduYXRpdmVfcm9sbG91dF92ZXJpZmllZCcsICdjdXJyZW50X3NjaGVtYTVfZGF0YWJhc2VfcmV0YWluZWQnLFxuICAgICAgICAgICAgICAgICAncHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJywgJ2luc3RhbGxlZF9wdXJwb3NlX2NoZWNrcycsICdwb2xpY3lfc2hhMjU2JyxcbiAgICAgICAgICAgICAgICAgJ3BvbGljeV9tb2RlJywgJ3BvbGljeV91aWQnLCAnaGVhbHRoX3N0YXR1c2VzJywgJ25hdGl2ZV9wcm92aWRlcl9wcm9iZScsICdyZWNvdmVyeV92ZXJpZmljYXRpb24nfVxuICAgIHJlcXVpcmUoc2V0KHZhbHVlKSA8PSBwZXJtaXR0ZWQsICd1bmV4cGVjdGVkIG91dHB1dCBmaWVsZHMgd2l0aGhlbGQnKVxuICAgIGZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuICAgIGZvciBuYW1lIGluICgnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lJywgJ3NuYXBzaG90X3JlYWRvbmx5JywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIGNvdW50cyh2YWx1ZVtuYW1lXSlcbiAgICBmb3IgbmFtZSBpbiAoJ3NuYXBzaG90X3NoYTI1NicsICdjbGllbnRfZGlmZl9zaGEyNTYnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOV17NjR9JywgdmFsdWVbbmFtZV0pIGlzIG5vdCBOb25lLCAnaW52YWxpZCBvdXRwdXQgZGlnZXN0IHdpdGhoZWxkJylcbiAgICBpZiAnc25hcHNob3RfYnl0ZXMnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHR5cGUodmFsdWVbJ3NuYXBzaG90X2J5dGVzJ10pIGlzIGludCBhbmQgMCA8IHZhbHVlWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAnaW52YWxpZCBvdXRwdXQgc2l6ZSB3aXRoaGVsZCcpXG4gICAgaWYgJ3NuYXBzaG90X2ZpbGUnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHZhbHVlWydzbmFwc2hvdF9maWxlJ10gaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSwgJ2ludmFsaWQgb3V0cHV0IGZpbGUgd2l0aGhlbGQnKVxuICAgIHJldHVybiB2YWx1ZVxuXG5cbmRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTEyMCk6XG4gICAgcmV0dXJuIHJ1bihbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVF0gKyBhcmd2LFxuICAgICAgICAgICAgICAgYm9keT1ib2R5LCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKTpcbiAgICAjIEZpeGVkIG1vZHVsZSBpbXBvcnRlZCBvbmx5IGFmdGVyIG1haW4gdmVyaWZpZXMgZXZlcnkgZXhlY3V0b3Igc291cmNlIGhhc2guXG4gICAgZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuICAgIHBheWxvYWQgPSB7J3BoYXNlJzogcGhhc2UsICdzb3VyY2VfcmV2aXNpb24nOiByZXZpc2lvbiwgJ2FwcHJvdmFsJzogYXBwcm92ZWQsXG4gICAgICAgICAgICAgICAnc2VhbGVkJzoganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJzoganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ2NhbmRpZGF0ZSc6IGpzb24ubG9hZHMoKENBU0UgLyAnY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdyb2xsYmFjayc6IGpzb24ubG9hZHMoKENBU0UgLyAncm9sbGJhY2stZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ3JlY2VpcHRfc2FmZXR5JzogKFJPT1QgLyAncmVjZWlwdF9zYWZldHkucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICdwdXJwb3NlX2NoZWNrcyc6IChDQVNFIC8gJ2NoZWNrX2luc3RhbGxlZC5weScpLnJlYWRfdGV4dCgpLFxuICAgICAgICAgICAgICAgJ3JlYWRvbmx5JzogKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCl9XG4gICAgc2NyaXB0ID0gUFJPR1JBTS5yZXBsYWNlKCdfX1BBWUxPQURfXycsIHJlcHIoanNvbi5kdW1wcyhwYXlsb2FkKSkpLnJlcGxhY2UoXG4gICAgICAgICdfX0dVQVJEX18nLCByZXByKChDQVNFIC8gJ2NoYW5nZV9ndWFyZC5weScpLnJlYWRfdGV4dCgpKSlcbiAgICByZXR1cm4ganNvbl9yZXN1bHQocnVuKFsnc3NoJywgJ3JhaWxpYW5jZTAxJywgJ3B5dGhvbjMgLSddLCBzY3JpcHQsIHRpbWVvdXQ9MjAwKSlcblxuXG5kZWYgY29weV9zbmFwc2hvdChwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkLCBqb3VybmFsKTpcbiAgICBtZXRhZGF0YSA9IHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKVxuICAgIGJhY2t1cF9waGFzZSA9ICdkcmlsbC1iYWNrdXAnIGlmIHBoYXNlID09ICdkcmlsbC1jb3B5JyBlbHNlICdjdXRvdmVyLWJhY2t1cCdcbiAgICBwcmlvciA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bYmFja3VwX3BoYXNlXVsncmVzdWx0J11cbiAgICBmb3Iga2V5IGluICgnc25hcHNob3Rfc2hhMjU2JywgJ3NuYXBzaG90X2J5dGVzJywgJ3NuYXBzaG90X2ZpbGUnLCAnc25hcHNob3RfcmVhZG9ubHknKTpcbiAgICAgICAgcmVxdWlyZShtZXRhZGF0YVtrZXldID09IHByaW9yW2tleV0sICdjbG9zZWQgZnJvemVuIHNuYXBzaG90IGNoYW5nZWQnKVxuICAgIG5hbWUgPSBtZXRhZGF0YVsnc25hcHNob3RfZmlsZSddXG4gICAgcmVxdWlyZShuYW1lIGluICgnZHJpbGwuc3FsaXRlJywgJ2N1dG92ZXIuc3FsaXRlJykgYW5kIDAgPCBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXSA8PSBNQVhfQllURVMsXG4gICAgICAgICAgICAnZml4ZWQgYm91bmRlZCBzbmFwc2hvdCByZXF1aXJlZCcpXG4gICAgcG9kID0gbWV0YWRhdGFbJ3BvZF9uYW1lJ11cbiAgICByZXF1aXJlKHJlLmZ1bGxtYXRjaChyJ1thLXowLTldKFstYS16MC05XSpbYS16MC05XSk/JywgcG9kKSBpcyBub3QgTm9uZSwgJ2ZpeGVkIG93bmVyIHBvZCBuYW1lIHJlcXVpcmVkJylcbiAgICBsb2NhbCA9IENVU1RPRFkgLyBuYW1lXG4gICAgZmQgPSBvcy5vcGVuKGxvY2FsLCBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX0VYQ0wgfCBvcy5PX05PRk9MTE9XLCAwbzYwMClcbiAgICAjIEJpbmFyeSBzbmFwc2hvdCBzdGRvdXQgZ29lcyBvbmx5IHRvIGEgcHJpdmF0ZSBmaWxlLCBuZXZlciB0b29sL2NoYXQvbG9nIG91dHB1dC5cbiAgICAjIFNuYXBzaG90IHNjaGVtYS9jb3VudCBtZXRhZGF0YSB3YXMgdmFsaWRhdGVkIGJlZm9yZSBvcGVuaW5nIHRoaXMgZGVzdGluYXRpb24uXG4gICAgd2l0aCBvcy5mZG9wZW4oZmQsICd3YicpIGFzIGRlc3RpbmF0aW9uOlxuICAgICAgICBjb21tYW5kID0gKCdrdWJlY3RsIGV4ZWMgLW4gaW5mb3JtZWQtZGVjaXNpb24gJyArIHBvZCArXG4gICAgICAgICAgICAgICAgICAgJyAtYyBpbmZvcm1lZC1kZWNpc2lvbiAtLSBjYXQgL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjEvJyArIG5hbWUpXG4gICAgICAgIHRyYW5zZmVyID0gc3VicHJvY2Vzcy5Qb3BlbihbJ3NzaCcsICdyYWlsaWFuY2UwMScsIGNvbW1hbmRdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTClcbiAgICAgICAgc2VsZWN0b3IgPSBzZWxlY3RvcnMuRGVmYXVsdFNlbGVjdG9yKClcbiAgICAgICAgc2VsZWN0b3IucmVnaXN0ZXIodHJhbnNmZXIuc3Rkb3V0LCBzZWxlY3RvcnMuRVZFTlRfUkVBRClcbiAgICAgICAgZGVhZGxpbmUgPSB0aW1lLm1vbm90b25pYygpICsgMTUwXG4gICAgICAgIHJlY2VpdmVkID0gMFxuICAgICAgICB0cnk6XG4gICAgICAgICAgICB3aGlsZSBUcnVlOlxuICAgICAgICAgICAgICAgIHJlbWFpbmluZyA9IGRlYWRsaW5lIC0gdGltZS5tb25vdG9uaWMoKVxuICAgICAgICAgICAgICAgIHJlcXVpcmUocmVtYWluaW5nID4gMCBhbmQgc2VsZWN0b3Iuc2VsZWN0KHJlbWFpbmluZyksICdwcml2YXRlIHRyYW5zZmVyIHRpbWVkIG91dCcpXG4gICAgICAgICAgICAgICAgYmxvY2sgPSBvcy5yZWFkKHRyYW5zZmVyLnN0ZG91dC5maWxlbm8oKSwgMTAyNCoqMilcbiAgICAgICAgICAgICAgICBpZiBub3QgYmxvY2s6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQgKz0gbGVuKGJsb2NrKVxuICAgICAgICAgICAgICAgIHJlcXVpcmUocmVjZWl2ZWQgPD0gbWV0YWRhdGFbJ3NuYXBzaG90X2J5dGVzJ10gYW5kIHJlY2VpdmVkIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdwcml2YXRlIGNvcHkgZXhjZWVkcyBmcm96ZW4gc25hcHNob3Qgc2l6ZScpXG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb24ud3JpdGUoYmxvY2spXG4gICAgICAgICAgICB0cmFuc2Zlci53YWl0KHRpbWVvdXQ9bWF4KDEsIGRlYWRsaW5lIC0gdGltZS5tb25vdG9uaWMoKSkpXG4gICAgICAgIGZpbmFsbHk6XG4gICAgICAgICAgICBzZWxlY3Rvci5jbG9zZSgpXG4gICAgICAgICAgICB0cmFuc2Zlci5zdGRvdXQuY2xvc2UoKVxuICAgICAgICAgICAgaWYgdHJhbnNmZXIucG9sbCgpIGlzIE5vbmU6XG4gICAgICAgICAgICAgICAgdHJhbnNmZXIua2lsbCgpXG4gICAgICAgICAgICAgICAgdHJhbnNmZXIud2FpdCgpXG4gICAgICAgIGRlc3RpbmF0aW9uLmZsdXNoKClcbiAgICAgICAgb3MuZnN5bmMoZGVzdGluYXRpb24uZmlsZW5vKCkpXG4gICAgcHJpdmF0ZShsb2NhbClcbiAgICByZXF1aXJlKHRyYW5zZmVyLnJldHVybmNvZGUgPT0gMCBhbmQgbG9jYWwuc3RhdCgpLnN0X3NpemUgPT0gbWV0YWRhdGFbJ3NuYXBzaG90X2J5dGVzJ11cbiAgICAgICAgICAgIGFuZCBzaGEobG9jYWwpID09IG1ldGFkYXRhWydzbmFwc2hvdF9zaGEyNTYnXSwgJ3ByaXZhdGUgY29weSBpbmNvbXBsZXRlL3VuY2VydGFpbjsgcmV0YWluLCBubyByZXRyeScpXG4gICAgIyBSZS1yZWFkIGlkZW50aXR5L2hhc2ggYWZ0ZXIgdHJhbnNmZXIuIFRoaXMgaXMgdmVyaWZpY2F0aW9uLCBub3QgYSB3cml0ZSByZXRyeS5cbiAgICBhZnRlciA9IHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKVxuICAgIHJlcXVpcmUoYWZ0ZXJbJ3BvZF91aWQnXSA9PSBtZXRhZGF0YVsncG9kX3VpZCddIGFuZCBhZnRlclsnc25hcHNob3Rfc2hhMjU2J10gPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLFxuICAgICAgICAgICAgJ3NvdXJjZSBpZGVudGl0eS9zbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyB0cmFuc2ZlcicpXG4gICAgcmV0dXJuIHsqKm1ldGFkYXRhLCAnb2ZmX2NsdXN0ZXJfcHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJzogVHJ1ZSwgJ3NuYXBzaG90X2NvbnRlbnRzX291dHB1dCc6IEZhbHNlfVxuXG5cbmRlZiBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKTpcbiAgICBmcm9tIHJlY2VpcHRfc2FmZXR5IGltcG9ydCBjb3VudHNcbiAgICBzbmFwc2hvdCA9IENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJ1xuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcHJldmlvdXMgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydkcmlsbC1jb3B5J11bJ3Jlc3VsdCddXG4gICAgcmVxdWlyZShzaGEoc25hcHNob3QpID09IHByZXZpb3VzWydzbmFwc2hvdF9zaGEyNTYnXSwgJ3Byb3RlY3RlZCBzbmFwc2hvdCBieXRlcyBjaGFuZ2VkJylcbiAgICBpZGVudGl0eSA9IGRvY2tlcihbJ2luZm8nLCAnLS1mb3JtYXQnLCAne3tqc29uIC5OYW1lfX0nXSlcbiAgICByZXF1aXJlKGlkZW50aXR5LnJldHVybmNvZGUgPT0gMCBhbmQganNvbi5sb2FkcyhpZGVudGl0eS5zdGRvdXQpID09ICdibnQtbGFwMDAxJyxcbiAgICAgICAgICAgICdsb2NhbCBvZmZsaW5lIERvY2tlciBlbmdpbmUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgbGlzdGVkID0gZG9ja2VyKFsndm9sdW1lJywgJ2xzJywgJy0tZm9ybWF0JywgJ3t7Lk5hbWV9fSddKVxuICAgIHJlcXVpcmUobGlzdGVkLnJldHVybmNvZGUgPT0gMCBhbmQgVk9MVU1FIG5vdCBpbiBsaXN0ZWQuc3Rkb3V0LnNwbGl0bGluZXMoKSxcbiAgICAgICAgICAgICdkaXNwb3NhYmxlIHZvbHVtZSBhYnNlbmNlIG5vdCB2ZXJpZmllZCcpXG4gICAgbm9uY2UgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydvZmZsaW5lLXZlcmlmeSddWydhdHRlbXB0X2lkJ11cbiAgICBsYWJlbHMgPSB7J2luZm9ybWVkLWRlY2lzaW9uLmNhc2UnOiAnaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxJyxcbiAgICAgICAgICAgICAgJ2luZm9ybWVkLWRlY2lzaW9uLnVzZSc6ICdvZmZsaW5lLXJlc3RvcmUtb25seScsICdpbmZvcm1lZC1kZWNpc2lvbi5hdHRlbXB0Jzogbm9uY2V9XG4gICAgY3JlYXRlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdjcmVhdGUnLCAnLS1kcml2ZXInLCAnbG9jYWwnLCAnLS1sYWJlbCcsICdpbmZvcm1lZC1kZWNpc2lvbi5jYXNlPWluZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsXG4gICAgICAgICAgICAgICAgICAgICAgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdD0nICsgbm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24udXNlPW9mZmxpbmUtcmVzdG9yZS1vbmx5JywgVk9MVU1FXSlcbiAgICByZXF1aXJlKGNyZWF0ZWQucmV0dXJuY29kZSA9PSAwIGFuZCBjcmVhdGVkLnN0ZG91dC5zdHJpcCgpID09IFZPTFVNRSwgJ3ZvbHVtZSBjcmVhdGlvbiB1bmNlcnRhaW47IG5vIHJldHJ5JylcbiAgICBpbnNwZWN0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnaW5zcGVjdCcsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShpbnNwZWN0ZWQucmV0dXJuY29kZSA9PSAwLCAnbmV3IHZvbHVtZSBpZGVudGl0eSB1bmF2YWlsYWJsZScpXG4gICAgdm9sdW1lID0ganNvbi5sb2FkcyhpbnNwZWN0ZWQuc3Rkb3V0KVxuICAgIHJlcXVpcmUobGVuKHZvbHVtZSkgPT0gMSBhbmQgdm9sdW1lWzBdWydOYW1lJ10gPT0gVk9MVU1FIGFuZCB2b2x1bWVbMF0uZ2V0KCdMYWJlbHMnKSA9PSBsYWJlbHNcbiAgICAgICAgICAgIGFuZCB2b2x1bWVbMF0uZ2V0KCdEcml2ZXInKSA9PSAnbG9jYWwnIGFuZCBub3Qgdm9sdW1lWzBdLmdldCgnT3B0aW9ucycpXG4gICAgICAgICAgICBhbmQgdm9sdW1lWzBdLmdldCgnU2NvcGUnKSA9PSAnbG9jYWwnLCAnbmV3IGlzb2xhdGVkIHZvbHVtZSBpZGVudGl0eSBjaGFuZ2VkJylcbiAgICBpZGVudGl0eSA9IHtrZXk6IHZvbHVtZVswXVtrZXldIGZvciBrZXkgaW4gKCdOYW1lJywgJ0xhYmVscycsICdEcml2ZXInLCAnU2NvcGUnLCAnQ3JlYXRlZEF0Jyl9XG4gICAgam91cm5hbC5ub3RlKCdvZmZsaW5lLXZlcmlmeScsICdjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eScsIGlkZW50aXR5KVxuICAgICMgT25lLXRpbWUgVUlEMC9DQVBfQ0hPV04gaW5pdGlhbGl6YXRpb24gaXMgaXNvbGF0ZWQgdG8gdGhlIE5FVyBuYW1lZCB2b2x1bWUuXG4gICAgIyBObyBob3N0L2xpdmUgUFZDL2NvbmZpZy90b2tlbiBtb3VudCBleGlzdHM7IHRoaXMgZGV0YWlsIG5lZWRzIHBhY2tldCByZXZpZXcuXG4gICAgaW5pdGlhbGl6ZXIgPSBcIlwiXCJpbXBvcnQgaGFzaGxpYixvcyxzdGF0LHN5c1xuaWYgc3lzLmZsYWdzLm9wdGltaXplOnJhaXNlIFJ1bnRpbWVFcnJvcignb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQnKVxuZm9sZGVyPScvcmVzdG9yZSc7ZXhwZWN0ZWQ9RVhQRUNURURcbmlmIG9zLmxpc3RkaXIoZm9sZGVyKTpyYWlzZSBWYWx1ZUVycm9yKCduZXcgZW1wdHkgcHJpdmF0ZSB2b2x1bWUgcmVxdWlyZWQnKVxub3MuY2htb2QoZm9sZGVyLDBvNzAwKVxuZmQ9b3Mub3Blbihmb2xkZXIrJy9yZXZpZXcuc3FsaXRlJyxvcy5PX0NSRUFUfG9zLk9fRVhDTHxvcy5PX05PRk9MTE9XfG9zLk9fV1JPTkxZLDBvNjAwKVxuZGlnZXN0PWhhc2hsaWIuc2hhMjU2KCk7c2l6ZT0wXG53aXRoIG9zLmZkb3BlbihmZCwnd2InKSBhcyB0YXJnZXQ6XG4gd2hpbGUgVHJ1ZTpcbiAgYmxvY2s9c3lzLnN0ZGluLmJ1ZmZlci5yZWFkKDEwMjQqKjIpXG4gIGlmIG5vdCBibG9jazpicmVha1xuICBzaXplKz1sZW4oYmxvY2spXG4gIGlmIHNpemU+NTEyKjEwMjQqKjI6cmFpc2UgVmFsdWVFcnJvcigncHJpdmF0ZSByZXN0b3JlIHNpemUgZXhjZWVkcyBib3VuZCcpXG4gIHRhcmdldC53cml0ZShibG9jayk7ZGlnZXN0LnVwZGF0ZShibG9jaylcbiB0YXJnZXQuZmx1c2goKTtvcy5mc3luYyh0YXJnZXQuZmlsZW5vKCkpXG5pZiBkaWdlc3QuaGV4ZGlnZXN0KCkhPWV4cGVjdGVkOnJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgY29waWVkIHNuYXBzaG90IGRpZmZlcnMnKVxub3MuY2hvd24oZm9sZGVyKycvcmV2aWV3LnNxbGl0ZScsMTAwMDEsMTAwMDEpO29zLmNob3duKGZvbGRlciwxMDAwMSwxMDAwMSlcbnByaW50KCd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwicHJpdmF0ZV9jb3B5X3ZlcmlmaWVkXCI6dHJ1ZX0nKVxuXCJcIlwiLnJlcGxhY2UoJ0VYUEVDVEVEJywgcmVwcihwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10pKVxuICAgIHdpdGggc25hcHNob3Qub3BlbigncmInKSBhcyBzb3VyY2U6XG4gICAgICAgIGFyZ3YgPSBbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVCxcbiAgICAgICAgICAgICAgICAncnVuJywgJy0tcm0nLCAnLWknLCAnLS1uZXR3b3JrJywgJ25vbmUnLCAnLS1yZWFkLW9ubHknLCAnLS1jcHVzJywgJzEnLCAnLS1tZW1vcnknLCAnMTI4bScsXG4gICAgICAgICAgICAgICAgJy0tdXNlcicsICcwOjAnLCAnLS1jYXAtZHJvcCcsICdBTEwnLCAnLS1jYXAtYWRkJywgJ0NIT1dOJyxcbiAgICAgICAgICAgICAgICAnLS1zZWN1cml0eS1vcHQnLCAnbm8tbmV3LXByaXZpbGVnZXMnLCAnLS1tb3VudCcsICd0eXBlPXZvbHVtZSxzcmM9JyArIFZPTFVNRSArICcsZHN0PS9yZXN0b3JlJyxcbiAgICAgICAgICAgICAgICAnLS1lbnRyeXBvaW50JywgJ3B5dGhvbicsIElNQUdFLCAnLWMnLCBpbml0aWFsaXplcl1cbiAgICAgICAgY29waWVkID0gc3VicHJvY2Vzcy5ydW4oYXJndiwgc3RkaW49c291cmNlLCB0ZXh0PVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRpbWVvdXQ9MTUwKVxuICAgIGpzb25fcmVzdWx0KGNvcGllZClcbiAgICBvcHRpb25zID0gWydydW4nLCAnLS1ybScsICctaScsICctLW5ldHdvcmsnLCAnbm9uZScsICctLXJlYWQtb25seScsICctLWNwdXMnLCAnMScsICctLW1lbW9yeScsICcxMjhtJyxcbiAgICAgICAgICAgICAgICctLXVzZXInLCAnMTAwMDE6MTAwMDEnLCAnLS1jYXAtZHJvcCcsICdBTEwnLCAnLS1zZWN1cml0eS1vcHQnLCAnbm8tbmV3LXByaXZpbGVnZXMnLFxuICAgICAgICAgICAgICAgJy0tbW91bnQnLCAndHlwZT12b2x1bWUsc3JjPScgKyBWT0xVTUUgKyAnLGRzdD0vcmVzdG9yZSddXG4gICAgcmVhZG9ubHkgPSBkb2NrZXIob3B0aW9ucyArIFsnLS1lbnRyeXBvaW50JywgJ3B5dGhvbicsIElNQUdFLCAnLScsICctLWRiJywgJy9yZXN0b3JlL3Jldmlldy5zcWxpdGUnXSxcbiAgICAgICAgICAgICAgICAgICAgICAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlYWRvbmx5LnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgcHJlLW9wZW4gc2NoZW1hL2ludGVncml0eSBnYXRlIHJlZnVzZWQ7IG5ldmVyIG9wZW4gU3RvcmUnKVxuICAgIGNoZWNrZWQgPSBjb3VudHMoanNvbi5sb2FkcyhyZWFkb25seS5zdGRvdXQpKVxuICAgIHJlcXVpcmUoY2hlY2tlZCA9PSBwcmV2aW91c1snc25hcHNob3RfcmVhZG9ubHknXSwgJ2Zyb3plbiBzbmFwc2hvdC9jbG9uZSByZWFkb25seSBjb3VudHMgZGlmZmVyJylcbiAgICBhZG1pbiA9IGRvY2tlcihvcHRpb25zICsgWyctLWVudHJ5cG9pbnQnLCAnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4nLCBJTUFHRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpbnNwZWN0JywgJy0tZGInLCAnL3Jlc3RvcmUvcmV2aWV3LnNxbGl0ZSddKVxuICAgIHJlcXVpcmUoYWRtaW4ucmV0dXJuY29kZSA9PSAwLCAnb2ZmbGluZSBhZG1pbiByZXN1bHQgdW5jZXJ0YWluJylcbiAgICBhZG1pbl9jb3VudHMgPSBqc29uLmxvYWRzKGFkbWluLnN0ZG91dClcbiAgICByZXF1aXJlKGFkbWluX2NvdW50cyA9PSB7a2V5OiBjaGVja2VkW2tleV0gZm9yIGtleSBpbiAoJ3NjaGVtYV92ZXJzaW9uJywgJ2xpZmVjeWNsZScsICdvdXRib3gnLCAnc3VibWlzc2lvbnMnKX0sXG4gICAgICAgICAgICAnb2ZmbGluZSBhZG1pbiBjaGFuZ2VkIGZyb3plbiBzbmFwc2hvdCBjb3VudGVycycpXG4gICAgIyBBZG1pbiBTdG9yZSBjb25zdHJ1Y3Rpb24gbXVzdCBub3Qgc2lsZW50bHkgYWx0ZXIgc2NoZW1hL2ludGVncml0eS9jb3VudGVycy5cbiAgICBwb3N0ID0gZG9ja2VyKG9wdGlvbnMgKyBbJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy0nLCAnLS1kYicsICcvcmVzdG9yZS9yZXZpZXcuc3FsaXRlJ10sXG4gICAgICAgICAgICAgICAgICAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHBvc3QucmV0dXJuY29kZSA9PSAwLCAnb2ZmbGluZSBwb3N0LWFkbWluIHJlYWRvbmx5IGludGVncml0eSBnYXRlIHJlZnVzZWQnKVxuICAgIHBvc3RfY2hlY2tlZCA9IGNvdW50cyhqc29uLmxvYWRzKHBvc3Quc3Rkb3V0KSlcbiAgICByZXF1aXJlKHBvc3RfY2hlY2tlZCA9PSBjaGVja2VkID09IHByZXZpb3VzWydzbmFwc2hvdF9yZWFkb25seSddLFxuICAgICAgICAgICAgJ29mZmxpbmUgYWRtaW4gYWx0ZXJlZCBmcm96ZW4gc25hcHNob3QgcHJvb2YnKVxuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcmVxdWlyZShzaGEoc25hcHNob3QpID09IHByZXZpb3VzWydzbmFwc2hvdF9zaGEyNTYnXSwgJ29yaWdpbmFsIHByb3RlY3RlZCBzbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyBkcmlsbCcpXG4gICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ29mZmxpbmVfdm9sdW1lJzogVk9MVU1FLCAnb2ZmbGluZV9yZWFkb25seSc6IGNoZWNrZWQsXG4gICAgICAgICAgICAnb2ZmbGluZV9wb3N0X2FkbWluX3JlYWRvbmx5JzogcG9zdF9jaGVja2VkLCAnb3JpZ2luYWxfc25hcHNob3RfaGFzaF91bmNoYW5nZWQnOiBUcnVlLFxuICAgICAgICAgICAgJ2NyZWF0ZWRfdm9sdW1lX2lkZW50aXR5JzogaWRlbnRpdHksXG4gICAgICAgICAgICAnYWRtaW5fY291bnRzJzogYWRtaW5fY291bnRzLCAnbmV0d29yayc6ICdub25lJywgJ3J1bnRpbWVfdG9rZW5zX29yX2NvbmZpZ19tb3VudGVkJzogRmFsc2UsXG4gICAgICAgICAgICAnc2VydmljZV9lbnRyeXBvaW50X3N0YXJ0ZWQnOiBGYWxzZSwgJ29yaWdpbmFsX3NuYXBzaG90X3JldGFpbmVkJzogVHJ1ZX1cblxuXG5kZWYgY2xlYW51cF9vZmZsaW5lKGpvdXJuYWwpOlxuICAgIGluc3BlY3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdpbnNwZWN0JywgVk9MVU1FXSlcbiAgICByZXF1aXJlKGluc3BlY3RlZC5yZXR1cm5jb2RlID09IDAsICdvd25lZCBkaXNwb3NhYmxlIHZvbHVtZSBpZGVudGl0eSB1bnZlcmlmaWVkJylcbiAgICB2YWx1ZSA9IGpzb24ubG9hZHMoaW5zcGVjdGVkLnN0ZG91dClcbiAgICBleHBlY3RlZCA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ29mZmxpbmUtdmVyaWZ5J11bJ3Jlc3VsdCddWydjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eSddXG4gICAgcmVxdWlyZShsZW4odmFsdWUpID09IDEgYW5kIHtrZXk6IHZhbHVlWzBdLmdldChrZXkpIGZvciBrZXkgaW4gZXhwZWN0ZWR9ID09IGV4cGVjdGVkXG4gICAgICAgICAgICBhbmQgbm90IHZhbHVlWzBdLmdldCgnT3B0aW9ucycpLCAndm9sdW1lIG93bmVyc2hpcC9yZWNyZWF0aW9uIGNoYW5nZWQnKVxuICAgIHJlbW92ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAncm0nLCBWT0xVTUVdKVxuICAgIHJlcXVpcmUocmVtb3ZlZC5yZXR1cm5jb2RlID09IDAgYW5kIHJlbW92ZWQuc3Rkb3V0LnN0cmlwKCkgPT0gVk9MVU1FXG4gICAgICAgICAgICBhbmQgZG9ja2VyKFsndm9sdW1lJywgJ2luc3BlY3QnLCBWT0xVTUVdKS5yZXR1cm5jb2RlICE9IDAsXG4gICAgICAgICAgICAnY2xlYW51cCBvdXRjb21lIGFtYmlndW91czsgZG8gbm90IHJldHJ5JylcbiAgICByZXR1cm4geydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlLCAnb25seV9kaXNwb3NhYmxlX29mZmxpbmVfdm9sdW1lX3JlbW92ZWQnOiBWT0xVTUUsXG4gICAgICAgICAgICAnbmF0aXZlX2FuZF9vZmZjbHVzdGVyX29yaWdpbmFsX3NuYXBzaG90c19yZXRhaW5lZCc6IFRydWV9XG5cblxuZGVmIG1haW4oKTpcbiAgICBwYXJzZXIgPSBhcmdwYXJzZS5Bcmd1bWVudFBhcnNlcihkZXNjcmlwdGlvbj1fX2RvY19fKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tcGhhc2UnLCBjaG9pY2VzPVBIQVNFUywgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXJvb3QtYXV0aG9yaXR5LXJlY2VpcHQnLCB0eXBlPVBhdGgsIHJlcXVpcmVkPVRydWUpXG4gICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1yb290LW5hdGl2ZS1vdXRjb21lJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tc291cmNlLXJldmlzaW9uJywgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBhcmdzID0gcGFyc2VyLnBhcnNlX2FyZ3MoKVxuICAgIHJlcXVpcmUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0ID09IFBhdGgoJy90bXAvc2VjdXJpdHktaW5mZC1wdXJwb3NlLXJvb3QtYXV0aG9yaXR5Lmpzb24nKVxuICAgICAgICAgICAgYW5kIGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZSA9PSBQYXRoKCcvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1uYXRpdmUtb3V0Y29tZS1sYXRlc3QuanNvbicpLFxuICAgICAgICAgICAgJ2ZpeGVkIHN1cGVydmlzZWQgcmVjZWlwdCBwYXRocyByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShyZS5mdWxsbWF0Y2gocidbMC05YS1mXXs0MH0nLCBhcmdzLnNvdXJjZV9yZXZpc2lvbikgaXMgbm90IE5vbmUsICdleGFjdCBzb3VyY2UgY29tbWl0IHJlcXVpcmVkJylcbiAgICAjIFZlcmlmeSBhbGwgcHJlcGFyZWQgZXhlY3V0b3IvaW5wdXQgYnl0ZXMgYmVmb3JlIHJlYWRpbmcgYXV0aG9yaXR5IG9yIGRpc3BhdGNoaW5nLlxuICAgIHBsYW4gPSBqc29uLmxvYWRzKChST09UIC8gJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHNldChwbGFuWydleGVjdXRvcl9maWxlcyddKSA9PSB7J2FjdHVhdG9yLnB5JywgJ2F1dGhvcml0eV9qb3VybmFsLnB5JywgJ25hdGl2ZV9wcm9ncmFtLnB5JywgJ3JlY2VpcHRfc2FmZXR5LnB5J30sXG4gICAgICAgICAgICAnZml4ZWQgZXhlY3V0b3Igc291cmNlcyByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShzZXQocGxhblsnb3duZXJfc291cmNlX2ZpbGVzJ10pID09IHsnZGVwbG95L2xpZmVjeWNsZS9hZG1pc3Npb24uY2FuZGlkYXRlLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL2t1c3RvbWl6YXRpb24ueWFtbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RlcGxveS9saWZlY3ljbGUvcmVnaXN0cmllcy5jYW5kaWRhdGUuanNvbid9LFxuICAgICAgICAgICAgJ2ZpeGVkIG93bmVyIGltYWdlIHNvdXJjZXMgcmVxdWlyZWQnKVxuICAgIGZvciByZWxhdGl2ZSwgZGlnZXN0IGluIHBsYW5bJ2V4ZWN1dG9yX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgdGFyZ2V0ID0gUk9PVCAvIHJlbGF0aXZlXG4gICAgICAgIHJlcXVpcmUobm90IHRhcmdldC5pc19zeW1saW5rKCkgYW5kIHNoYSh0YXJnZXQpID09IGRpZ2VzdCwgJ2V4ZWN1dG9yIHNvdXJjZSBieXRlcyBjaGFuZ2VkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydjYXNlX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgcmVxdWlyZShub3QgUGF0aChyZWxhdGl2ZSkuaXNfYWJzb2x1dGUoKSBhbmQgJy4uJyBub3QgaW4gUGF0aChyZWxhdGl2ZSkucGFydHMsXG4gICAgICAgICAgICAgICAgJ2Nhc2Ugc291cmNlIHBhdGggZXNjYXBlZCcpXG4gICAgICAgIHRhcmdldCA9IENBU0UgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdjYXNlIHNvdXJjZSBieXRlcyBjaGFuZ2VkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydvd25lcl9zb3VyY2VfZmlsZXMnXS5pdGVtcygpOlxuICAgICAgICB0YXJnZXQgPSBPV05FUiAvIHJlbGF0aXZlXG4gICAgICAgIHJlcXVpcmUobm90IHRhcmdldC5pc19zeW1saW5rKCkgYW5kIHNoYSh0YXJnZXQpID09IGRpZ2VzdCwgJ293bmVyIGltYWdlLW9ubHkgc291cmNlIGNoYW5nZWQnKVxuICAgICAgICBjb21taXR0ZWQgPSBzdWJwcm9jZXNzLnJ1bihbJ2dpdCcsICctQycsIHN0cihPV05FUiksICdzaG93JywgYXJncy5zb3VyY2VfcmV2aXNpb24gKyAnOicgKyByZWxhdGl2ZV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVfb3V0cHV0PVRydWUpXG4gICAgICAgIHJlcXVpcmUoY29tbWl0dGVkLnJldHVybmNvZGUgPT0gMCBhbmQgaGFzaGxpYi5zaGEyNTYoY29tbWl0dGVkLnN0ZG91dCkuaGV4ZGlnZXN0KCkgPT0gZGlnZXN0LFxuICAgICAgICAgICAgICAgICdjb21taXR0ZWQgb3duZXIgcmVuZGVyIHNvdXJjZSBkaWZmZXJzIGZyb20gYXBwcm92ZWQgaW5wdXRzJylcbiAgICBoZWFkID0gcnVuKFsnZ2l0JywgJy1DJywgc3RyKE9XTkVSKSwgJ3Jldi1wYXJzZScsICdIRUFEJ10pXG4gICAgcmVxdWlyZShoZWFkLnJldHVybmNvZGUgPT0gMCBhbmQgaGVhZC5zdGRvdXQuc3RyaXAoKSA9PSBhcmdzLnNvdXJjZV9yZXZpc2lvbiwgJ293bmVyIHNvdXJjZSBIRUFEIGRpZmZlcnMnKVxuICAgIGZyb20gYXV0aG9yaXR5X2pvdXJuYWwgaW1wb3J0IEpvdXJuYWwsIGF1dGhvcml0eVxuICAgIHByaXZhdGUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0KVxuICAgIHByaXZhdGUoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKVxuICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlY2VpcHQuZ2V0KCduYXRpdmVfb3V0Y29tZV9zaGEyNTYnKSA9PSBzaGEoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKSwgJ25hdGl2ZSBvdXRjb21lIGJ5dGVzIGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ2V4ZWN1dG9yX3BsYW5fc2hhMjU2JykgPT0gc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgJ3Jvb3QgdmVyaWZpZWQgZXhlY3V0b3IgcGxhbiBkaWZmZXJzJylcbiAgICBhcHByb3ZlZCA9IGF1dGhvcml0eShyZWNlaXB0LCBqc29uLmxvYWRzKGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZS5yZWFkX3RleHQoKSksIHNoYShDQVNFIC8gJ21lbW8uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcmdzLnBoYXNlKVxuICAgIHBhcmVudCA9IENVU1RPRFkucGFyZW50XG4gICAgcHJpdmF0ZShwYXJlbnQsIGRpcmVjdG9yeT1UcnVlKVxuICAgIGlnbm9yZWQgPSBydW4oWydnaXQnLCAnLUMnLCBzdHIoQ1VTVE9ESUFOKSwgJ2NoZWNrLWlnbm9yZScsICctLW5vLWluZGV4Jywgc3RyKENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJyldKVxuICAgIHJlcXVpcmUoaWdub3JlZC5yZXR1cm5jb2RlID09IDAsICdvZmZjbHVzdGVyIGN1c3RvZHkgaXMgbm90IGlnbm9yZWQnKVxuICAgIGlmIG5vdCBDVVNUT0RZLmV4aXN0cygpOlxuICAgICAgICByZXF1aXJlKGFyZ3MucGhhc2UgPT0gJ2RyaWxsLWJhY2t1cCcsICdmaXJzdCBhcHByb3ZlZCBwaGFzZSBtdXN0IGNyZWF0ZSB1bmlxdWUgcHJpdmF0ZSBjdXN0b2R5JylcbiAgICAgICAgb3MubWtkaXIoQ1VTVE9EWSwgMG83MDApXG4gICAgcHJpdmF0ZShDVVNUT0RZLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICBjYXBhY2l0eSA9IG9zLnN0YXR2ZnMoQ1VTVE9EWSlcbiAgICByZXF1aXJlKGNhcGFjaXR5LmZfYmF2YWlsICogY2FwYWNpdHkuZl9mcnNpemUgPj0gMiAqIE1BWF9CWVRFUyArIDE2ICogMTAyNCoqMixcbiAgICAgICAgICAgICdpbmRlcGVuZGVudCBwcm90ZWN0ZWQgY3VzdG9keSBoZWFkcm9vbSBpbnN1ZmZpY2llbnQnKVxuICAgIG9zLm1ha2VkaXJzKENVU1RPRFkgLyAnZW1wdHktZG9ja2VyLWNvbmZpZycsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpXG4gICAgcHJpdmF0ZShDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICByZXF1aXJlKG5vdCBsaXN0KChDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKS5pdGVyZGlyKCkpLCAncHVibGljIERvY2tlciByZWFkIGNvbmZpZyBtdXN0IHN0YXkgZW1wdHknKVxuICAgIGpvdXJuYWwgPSBKb3VybmFsKENVU1RPRFksIHsncHJvcG9zYWwnOiBwbGFuWydwcm9wb3NhbF9pZCddLCAnc291cmNlX3JldmlzaW9uJzogYXJncy5zb3VyY2VfcmV2aXNpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21lbW9fc2hhMjU2Jzogc2hhKENBU0UgLyAnbWVtby5qc29uJyksICdwbGFuX3NoYTI1Nic6IHNoYShST09UIC8gJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKX0pXG4gICAgdHJ5OlxuICAgICAgICBqb3VybmFsLnN0YXJ0KGFyZ3MucGhhc2UsIGFwcHJvdmVkKSAjIGZzeW5jZWQgUlVOTklORyBiZWZvcmUgYW55IHBoYXNlIGVmZmVjdC5cbiAgICAgICAgaWYgYXJncy5waGFzZSBpbiAoJ2RyaWxsLWNvcHknLCAnY3V0b3Zlci1jb3B5Jyk6XG4gICAgICAgICAgICByZXN1bHQgPSBjb3B5X3NuYXBzaG90KGFyZ3MucGhhc2UsIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcHByb3ZlZCwgam91cm5hbClcbiAgICAgICAgZWxpZiBhcmdzLnBoYXNlID09ICdvZmZsaW5lLXZlcmlmeSc6XG4gICAgICAgICAgICByZXN1bHQgPSBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKVxuICAgICAgICBlbGlmIGFyZ3MucGhhc2UgPT0gJ2NsZWFudXAtb2ZmbGluZSc6XG4gICAgICAgICAgICByZXN1bHQgPSBjbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgZWxzZTpcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlbW90ZShhcmdzLnBoYXNlLCBhcmdzLnNvdXJjZV9yZXZpc2lvbiwgYXBwcm92ZWQpXG4gICAgICAgIGpvdXJuYWwuZmluaXNoKGFyZ3MucGhhc2UsIHJlc3VsdClcbiAgICAgICAgcHJpbnQoanNvbi5kdW1wcyhyZXN1bHQpKSAjIE9ubHkgY291bnQvaGFzaC9pZGVudGl0eSByZWNlaXB0cywgbmV2ZXIgc25hcHNob3QgYnl0ZXMuXG4gICAgZXhjZXB0IEJhc2VFeGNlcHRpb24gYXMgZXJyb3I6XG4gICAgICAgIHNhZmUgPSB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncGhhc2UnOiBhcmdzLnBoYXNlLCAnZmFpbHVyZV9jbGFzcyc6IHR5cGUoZXJyb3IpLl9fbmFtZV9fLFxuICAgICAgICAgICAgICAgICdmYWlsdXJlJzogJ2ZpeGVkIHBoYXNlIG91dGNvbWUgdW5jZXJ0YWluOyBvcmlnaW5hbCBldmlkZW5jZSByZXRhaW5lZDsgbm8gcmV0cnknLFxuICAgICAgICAgICAgICAgICdyYXdfb3V0cHV0X3dpdGhoZWxkJzogVHJ1ZX1cbiAgICAgICAgaWYgam91cm5hbC5kYXRhWydwaGFzZXMnXS5nZXQoYXJncy5waGFzZSwge30pLmdldCgnc3RhdGUnKSA9PSAnUlVOTklORyc6XG4gICAgICAgICAgICBqb3VybmFsLmZpbmlzaChhcmdzLnBoYXNlLCBzYWZlKVxuICAgICAgICBwcmludChqc29uLmR1bXBzKHNhZmUpKVxuICAgICAgICByYWlzZSBTeXN0ZW1FeGl0KDEpIGZyb20gTm9uZVxuICAgIGZpbmFsbHk6XG4gICAgICAgIGpvdXJuYWwuY2xvc2UoKVxuXG5cbmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6XG4gICAgdHJ5OlxuICAgICAgICBtYWluKClcbiAgICBleGNlcHQgRXhjZXB0aW9uOlxuICAgICAgICByYWlzZSBTeXN0ZW1FeGl0KCdzdXBlcnZpc2VkIGV4ZWN1dGlvbiByZWZ1c2VkIGJlZm9yZSBwaGFzZTsgcmF3IG91dHB1dCB3aXRoaGVsZCcpIGZyb20gTm9uZVxuIgogICAgfSwKICAgICJhdXRob3JpdHlfam91cm5hbC5weSI6IHsKICAgICAgInNoYTI1NiI6ICI3NGQ2YTkxMTY5Mjk2YTk5ZmE3ZGFjMmQwOTAyNTY3MjgwZjkxMGFmNzQzNTgwZWM0YjQ1NGYyYWJmODM3NGFhIiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiU3VwZXJ2aXNlZCByZWNlaXB0IGJvb2trZWVwaW5nLCBub3QgYW4gYXV0aGVudGljYXRlZCBhcHByb3ZhbCBwcm92aWRlci5cIlwiXCJcbmltcG9ydCBkYXRldGltZVxuaW1wb3J0IGZjbnRsXG5pbXBvcnQgaGFzaGxpYlxuaW1wb3J0IGpzb25cbmltcG9ydCBvc1xuaW1wb3J0IHJlXG5mcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGhcbmltcG9ydCBzdGF0XG5pbXBvcnQgdXVpZFxuXG5GT1VOREVSID0geydraW5kJzogJ3BlcnNvbicsICdzdWInOiAndWlkPXBsYXRmb3JtLXJvb3Qsb3U9cGVvcGxlLGRjPW5ldGtpbmdkb20sZGM9bG9jYWwnfVxuTUVNT19JRCA9ICdpbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMSdcblBST1BPU0FMID0gJ0lORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxJ1xuUEhBU0VTID0gKCdkcmlsbC1iYWNrdXAnLCAnZHJpbGwtY29weScsICdvZmZsaW5lLXZlcmlmeScsICdjbGVhbnVwLW9mZmxpbmUnLFxuICAgICAgICAgICdjdXRvdmVyLWJhY2t1cCcsICdjdXRvdmVyLWNvcHknLCAncmVsZWFzZScsICd2ZXJpZnknLCAncm9sbGJhY2snLCAncm9sbGJhY2stdmVyaWZ5JylcblxuXG5kZWYgcmVxdWlyZSh2YWx1ZSwgcmVhc29uKTpcbiAgICBpZiBub3QgdmFsdWU6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IocmVhc29uKVxuXG5cbmRlZiBzaGEocGF0aCk6XG4gICAgZGlnZXN0ID0gaGFzaGxpYi5zaGEyNTYoKVxuICAgIHdpdGggUGF0aChwYXRoKS5vcGVuKCdyYicpIGFzIHN0cmVhbTpcbiAgICAgICAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOiBzdHJlYW0ucmVhZCgxMDI0KioyKSwgYicnKTpcbiAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUoYmxvY2spXG4gICAgcmV0dXJuIGRpZ2VzdC5oZXhkaWdlc3QoKVxuXG5cbmRlZiBwcml2YXRlKHBhdGgsIGRpcmVjdG9yeT1GYWxzZSk6XG4gICAgaW5mbyA9IFBhdGgocGF0aCkubHN0YXQoKVxuICAgIHJlcXVpcmUoKHN0YXQuU19JU0RJUihpbmZvLnN0X21vZGUpIGlmIGRpcmVjdG9yeSBlbHNlIHN0YXQuU19JU1JFRyhpbmZvLnN0X21vZGUpKVxuICAgICAgICAgICAgYW5kIGluZm8uc3RfdWlkID09IG9zLmdldHVpZCgpIGFuZCBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKSA9PSAoMG83MDAgaWYgZGlyZWN0b3J5IGVsc2UgMG82MDApXG4gICAgICAgICAgICBhbmQgKGRpcmVjdG9yeSBvciBpbmZvLnN0X25saW5rID09IDEpLCAncHJpdmF0ZSBvd25lZCBjdXN0b2R5IHJlcXVpcmVkJylcblxuXG5kZWYgYXV0aG9yaXR5KHJlY2VpcHQsIG91dGNvbWUsIG1lbW9fc2hhLCBzb3VyY2VfcmV2aXNpb24sIHBoYXNlLCBub3c9Tm9uZSk6XG4gICAgXCJcIlwiUm9vdCBtdXN0IGZyZXNobHkgdmVyaWZ5IG5hdGl2ZSBvdXRjb21lIGF0IGZpeGVkIE9SSUdJTiBvdXRzaWRlIHRoaXMgaGVscGVyLlxuXG4gICAgUmVjZWlwdCBmaWxlcy9mbGFncyBhcmUgbm90IHNpZ25lZCBncmFudHMuIFRoaXMgZnVuY3Rpb24gY2hlY2tzIHRoZSBleGFjdFxuICAgIHN1cGVydmlzZWQgcmVjZWlwdCByZWxhdGlvbjsgZXhpc3RpbmcgaGFybmVzcy9mb3VuZGVyIGF1dGhvcml0eSByZW1haW5zIHRoZVxuICAgIGFjdHVhbCBwZXJtaXNzaW9uIGJvdW5kYXJ5LiBJdCBuZXZlciBhdXRoZW50aWNhdGVzIGEgY2FsbGVyIGFzIGh1bWFuLlxuICAgIFwiXCJcIlxuICAgIG5vdyA9IG5vdyBvciBkYXRldGltZS5kYXRldGltZS5ub3coZGF0ZXRpbWUudGltZXpvbmUudXRjKVxuICAgIHJlcXVpcmUocGhhc2UgaW4gUEhBU0VTLCAnZml4ZWQgcGhhc2UgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ3Byb3Bvc2FsX2lkJykgPT0gUFJPUE9TQUwgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX2lkJykgPT0gTUVNT19JRFxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX3ZlcnNpb24nKSA9PSAxIGFuZCByZWNlaXB0LmdldCgnbWVtb19zaGEyNTYnKSA9PSBtZW1vX3NoYVxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdzb3VyY2VfcmV2aXNpb24nKSA9PSBzb3VyY2VfcmV2aXNpb25cbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgnYWN0aXZhdGlvbicpID09ICdBUFBST1ZFRCdcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgnYXV0aG9yaXR5X21vZGUnKSA9PSAnQURNSU5JU1RFUidcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgndGFyZ2V0JykgPT0gJ3JlYWxtOmt1YmVybmV0ZXMvcmFpbGlhbmNlMDEvaW5mb3JtZWQtZGVjaXNpb24nXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3ZlcmlmaWNhdGlvbl9tZXRob2QnKSA9PSAncm9vdC1maXhlZC1vcmlnaW4tbmF0aXZlLXJlYWRiYWNrJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdydW50aW1lX2F1dGhlbnRpY2F0ZWRfZ3JhbnQnKSBpcyBGYWxzZSxcbiAgICAgICAgICAgICdleGFjdCBleHRlcm5hbGx5IHZlcmlmaWVkIHN1cGVydmlzZWQgcmVjZWlwdCByZXF1aXJlZCcpXG4gICAgdmVyaWZpZWQgPSBkYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KHJlY2VpcHRbJ3ZlcmlmaWVkX2F0J10ucmVwbGFjZSgnWicsICcrMDA6MDAnKSlcbiAgICByZXF1aXJlKHZlcmlmaWVkLnR6aW5mbyBpcyBub3QgTm9uZSBhbmQgMCA8PSAobm93IC0gdmVyaWZpZWQpLnRvdGFsX3NlY29uZHMoKSA8PSAxMjAsXG4gICAgICAgICAgICAnZnJlc2ggcm9vdCBuYXRpdmUgcmVhZGJhY2sgcmVxdWlyZWQgYmVmb3JlIGV2ZXJ5IHBoYXNlJylcbiAgICBkZWFkbGluZSA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQoJzIwMjYtMTAtMTJUMjM6NTk6NTkrMDA6MDAnKVxuICAgIHJlcXVpcmUobm93IDwgZGVhZGxpbmUsICdhcHByb3ZlZCBleGVjdXRpb24gd2luZG93IGV4cGlyZWQnKVxuICAgIHJlcXVpcmUob3V0Y29tZS5nZXQoJ21lbW9faWQnKSA9PSBNRU1PX0lEIGFuZCBvdXRjb21lLmdldCgncmV2aWV3Jywge30pLmdldCgnc3RhbGUnKSBpcyBGYWxzZVxuICAgICAgICAgICAgYW5kIG91dGNvbWVbJ3JldmlldyddLmdldCgnaW50YWtlX3N0YXRlJykgPT0gJ3JlYWR5JywgJ25hdGl2ZSByZXZpZXcgaXMgbm90IHJlYWR5L2N1cnJlbnQnKVxuICAgIHJldmlld19pZCA9IG91dGNvbWVbJ3JldmlldyddWydtZW1vX2lkJ11cbiAgICByZXF1aXJlKHJldmlld19pZCA9PSByZWNlaXB0LmdldCgncmV2aWV3X21lbW9faWQnKSwgJ25hdGl2ZSByZXZpZXcgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgYWNjZXB0ZWQgPSBbeCBmb3IgeCBpbiBvdXRjb21lLmdldCgnZGlzcG9zaXRpb25zJywgW10pXG4gICAgICAgICAgICAgICAgaWYgeC5nZXQoJ3N1Ym1pc3Npb25fc3RhdGUnKSA9PSAnY29uZmlybWVkJ1xuICAgICAgICAgICAgICAgIGFuZCB4LmdldCgnZGlzcG9zaXRpb24nLCB7fSkuZ2V0KCd2ZXJiJykgPT0gJ2FjY2VwdCdcbiAgICAgICAgICAgICAgICBhbmQgeFsnZGlzcG9zaXRpb24nXS5nZXQoJ21lbW9fdmVyc2lvbicpID09IDFdXG4gICAgcmVxdWlyZShsZW4oYWNjZXB0ZWQpID09IDEsICdvbmUgY29uZmlybWVkIGZvdW5kZXIgYWNjZXB0YW5jZSByZXF1aXJlZCcpXG4gICAgYWNjZXB0ZWQgPSBhY2NlcHRlZFswXVsnZGlzcG9zaXRpb24nXVxuICAgIHJlcXVpcmUoYWNjZXB0ZWQuZ2V0KCdhY3RvcicpID09IEZPVU5ERVIgYW5kIGFjY2VwdGVkLmdldCgnbWVtb19pZCcpID09IHJldmlld19pZFxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnYXBwcm92YWxfaWQnKSA9PSByZWNlaXB0LmdldCgnYXBwcm92YWxfaWQnKVxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnaWQnKSA9PSByZWNlaXB0LmdldCgnZGlzcG9zaXRpb25faWQnKVxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnYXQnKSA9PSByZWNlaXB0LmdldCgnYWNjZXB0ZWRfYXQnKSwgJ2V4YWN0IGZvdW5kZXIgZGlzcG9zaXRpb24gbWlzbWF0Y2gnKVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOS1dezM2fScsIGFjY2VwdGVkWydhcHByb3ZhbF9pZCddKSBpcyBub3QgTm9uZVxuICAgICAgICAgICAgYW5kIHJlLmZ1bGxtYXRjaChyJ2Rpc3AtW2EtZjAtOS1dezM2fScsIGFjY2VwdGVkWydpZCddKSBpcyBub3QgTm9uZVxuICAgICAgICAgICAgYW5kIHJlLmZ1bGxtYXRjaChyJ3Jldmlldy1bYS1mMC05LV17MzZ9JywgcmV2aWV3X2lkKSBpcyBub3QgTm9uZSxcbiAgICAgICAgICAgICduYXRpdmUgZGlzcG9zaXRpb24gaWRlbnRpZmllcnMgYXJlIG1hbGZvcm1lZCcpXG4gICAgYWNjZXB0ZWRfYXQgPSBkYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KGFjY2VwdGVkWydhdCddLnJlcGxhY2UoJ1onLCAnKzAwOjAwJykpXG4gICAgcmVxdWlyZShhY2NlcHRlZF9hdC50emluZm8gaXMgbm90IE5vbmUgYW5kIGFjY2VwdGVkX2F0IDw9IHZlcmlmaWVkLCAnYWNjZXB0YW5jZSB0aW1lIG5vdCBib3VuZGVkJylcbiAgICByZXR1cm4ge2tleTogcmVjZWlwdFtrZXldIGZvciBrZXkgaW4gKCdhcHByb3ZhbF9pZCcsICdkaXNwb3NpdGlvbl9pZCcsICdhY2NlcHRlZF9hdCcsICd2ZXJpZmllZF9hdCcpfVxuXG5cbmNsYXNzIEpvdXJuYWw6XG4gICAgZGVmIF9faW5pdF9fKHNlbGYsIHBhcmVudCwgaWRlbnRpdHkpOlxuICAgICAgICBzZWxmLnBhcmVudCA9IFBhdGgocGFyZW50KVxuICAgICAgICBwcml2YXRlKHNlbGYucGFyZW50LCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICAgICAgc2VsZi5wYXRoID0gc2VsZi5wYXJlbnQgLyAnZXhlY3V0aW9uLWpvdXJuYWwuanNvbidcbiAgICAgICAgc2VsZi5sb2NrID0gb3Mub3BlbihzZWxmLnBhcmVudCAvICdleGVjdXRpb24ubG9jaycsIG9zLk9fQ1JFQVQgfCBvcy5PX05PRk9MTE9XIHwgb3MuT19SRFdSLCAwbzYwMClcbiAgICAgICAgZmNudGwuZmxvY2soc2VsZi5sb2NrLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQilcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCAvICdleGVjdXRpb24ubG9jaycpXG4gICAgICAgIGlmIHNlbGYucGF0aC5leGlzdHMoKTpcbiAgICAgICAgICAgIHByaXZhdGUoc2VsZi5wYXRoKVxuICAgICAgICAgICAgc2VsZi5kYXRhID0ganNvbi5sb2FkcyhzZWxmLnBhdGgucmVhZF90ZXh0KCkpXG4gICAgICAgICAgICByZXF1aXJlKHNlbGYuZGF0YVsnaWRlbnRpdHknXSA9PSBpZGVudGl0eSwgJ2pvdXJuYWwgY2FzZS9zb3VyY2UgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgICAgIGVsc2U6XG4gICAgICAgICAgICBzZWxmLmRhdGEgPSB7J2lkZW50aXR5JzogaWRlbnRpdHksICdwaGFzZXMnOiB7fX1cbiAgICAgICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgc2F2ZShzZWxmKTpcbiAgICAgICAgdGVtcG9yYXJ5ID0gc2VsZi5wYXJlbnQgLyAnZXhlY3V0aW9uLWpvdXJuYWwubmV3J1xuICAgICAgICBmZCA9IG9zLm9wZW4odGVtcG9yYXJ5LCBvcy5PX0NSRUFUIHwgb3MuT19FWENMIHwgb3MuT19OT0ZPTExPVyB8IG9zLk9fV1JPTkxZLCAwbzYwMClcbiAgICAgICAgdHJ5OlxuICAgICAgICAgICAgd2l0aCBvcy5mZG9wZW4oZmQsICd3JykgYXMgc3RyZWFtOlxuICAgICAgICAgICAgICAgIGpzb24uZHVtcChzZWxmLmRhdGEsIHN0cmVhbSwgaW5kZW50PTIpXG4gICAgICAgICAgICAgICAgc3RyZWFtLndyaXRlKCdcXG4nKVxuICAgICAgICAgICAgICAgIHN0cmVhbS5mbHVzaCgpXG4gICAgICAgICAgICAgICAgb3MuZnN5bmMoc3RyZWFtLmZpbGVubygpKVxuICAgICAgICAgICAgb3MucmVwbGFjZSh0ZW1wb3JhcnksIHNlbGYucGF0aClcbiAgICAgICAgICAgIGRpcmVjdG9yeSA9IG9zLm9wZW4oc2VsZi5wYXJlbnQsIG9zLk9fRElSRUNUT1JZIHwgb3MuT19SRE9OTFkpXG4gICAgICAgICAgICB0cnk6XG4gICAgICAgICAgICAgICAgb3MuZnN5bmMoZGlyZWN0b3J5KVxuICAgICAgICAgICAgZmluYWxseTpcbiAgICAgICAgICAgICAgICBvcy5jbG9zZShkaXJlY3RvcnkpXG4gICAgICAgIGV4Y2VwdCBCYXNlRXhjZXB0aW9uOlxuICAgICAgICAgICAgIyBSZXRhaW4gZXZpZGVuY2UgcmF0aGVyIHRoYW4gb3ZlcndyaXRpbmcgYW4gdW5jZXJ0YWluIGR1cmFibGUgaW50ZW50LlxuICAgICAgICAgICAgcmFpc2VcblxuICAgIGRlZiBzdGFydChzZWxmLCBwaGFzZSwgYXBwcm92YWwpOlxuICAgICAgICByZXF1aXJlKHBoYXNlIG5vdCBpbiBzZWxmLmRhdGFbJ3BoYXNlcyddLCAnYWxyZWFkeSBhdHRlbXB0ZWQgcGhhc2U7IG5vIHJldHJ5JylcbiAgICAgICAgcHJlZGVjZXNzb3JzID0gZGljdCh6aXAoUEhBU0VTWzE6OF0sIFBIQVNFU1s6N10pKVxuICAgICAgICBwcmVkZWNlc3NvcnNbJ3JvbGxiYWNrLXZlcmlmeSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICBpZiBwaGFzZSBpbiBwcmVkZWNlc3NvcnM6XG4gICAgICAgICAgICByZXF1aXJlKHNlbGYuZGF0YVsncGhhc2VzJ10uZ2V0KHByZWRlY2Vzc29yc1twaGFzZV0sIHt9KS5nZXQoJ3N0YXRlJykgPT0gJ0NPTVBMRVRFJyxcbiAgICAgICAgICAgICAgICAgICAgJ3ByZWNlZGluZyBwaGFzZSBpcyBub3QgdmVyaWZpZWQgY29tcGxldGUnKVxuICAgICAgICBpZiBwaGFzZSA9PSAncm9sbGJhY2snOlxuICAgICAgICAgICAgcmVxdWlyZSgncmVsZWFzZScgaW4gc2VsZi5kYXRhWydwaGFzZXMnXSwgJ3JvbGxiYWNrIHJlcXVpcmVzIGEgcmVjb3JkZWQgcmVsZWFzZSBhdHRlbXB0JylcbiAgICAgICAgc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV0gPSB7J3N0YXRlJzogJ1JVTk5JTkcnLCAnYXBwcm92YWwnOiBhcHByb3ZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2F0dGVtcHRfaWQnOiBzdHIodXVpZC51dWlkNCgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0YXJ0ZWRfYXQnOiBkYXRldGltZS5kYXRldGltZS5ub3coZGF0ZXRpbWUudGltZXpvbmUudXRjKS5pc29mb3JtYXQoKX1cbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBub3RlKHNlbGYsIHBoYXNlLCBrZXksIHZhbHVlKTpcbiAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVsnc3RhdGUnXSA9PSAnUlVOTklORycsICdwaGFzZSBpbnRlbnQgbWlzc2luZycpXG4gICAgICAgIHNlbGYuZGF0YVsncGhhc2VzJ11bcGhhc2VdW2tleV0gPSB2YWx1ZVxuICAgICAgICBzZWxmLnNhdmUoKVxuXG4gICAgZGVmIGZpbmlzaChzZWxmLCBwaGFzZSwgcmVzdWx0KTpcbiAgICAgICAgZW50cnkgPSBzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVxuICAgICAgICByZXF1aXJlKGVudHJ5WydzdGF0ZSddID09ICdSVU5OSU5HJywgJ3BoYXNlIGludGVudCBtaXNzaW5nJylcbiAgICAgICAgZW50cnlbJ3Jlc3VsdCddID0gcmVzdWx0XG4gICAgICAgIGVudHJ5WydzdGF0ZSddID0gJ0NPTVBMRVRFJyBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgJ1VOQ0VSVEFJTidcbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBjbG9zZShzZWxmKTpcbiAgICAgICAgb3MuY2xvc2Uoc2VsZi5sb2NrKVxuIgogICAgfSwKICAgICJleGVjdXRpb24tcGxhbi5qc29uIjogewogICAgICAic2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwia2luZFwiOiBcImluZm9ybWVkLWRlY2lzaW9uLnN1cGVydmlzZWQtbWVjaGFuaWNhbC1yZWxlYXNlLXBsYW5cIixcbiAgXCJ2ZXJzaW9uXCI6IDEsXG4gIFwicHJvcG9zYWxfaWRcIjogXCJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MVwiLFxuICBcInRyaWFsX2lkXCI6IFwiaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxXCIsXG4gIFwic3RhdGVcIjogXCJwcmVwYXJlZC11bmFwcHJvdmVkXCIsXG4gIFwiZXhlY3V0b3JfZmlsZXNcIjoge1xuICAgIFwiYWN0dWF0b3IucHlcIjogXCI2YjlkNjQzOTg2MjQ1NGYyNjFlZTc3ZjA1YjI2NTE5ZjgxMDk1OTliMWY2NzA3OGJjNGUxZjdjN2M0MDYxYmE1XCIsXG4gICAgXCJhdXRob3JpdHlfam91cm5hbC5weVwiOiBcIjc0ZDZhOTExNjkyOTZhOTlmYTdkYWMyZDA5MDI1NjcyODBmOTEwYWY3NDM1ODBlYzRiNDU0ZjJhYmY4Mzc0YWFcIixcbiAgICBcIm5hdGl2ZV9wcm9ncmFtLnB5XCI6IFwiMzQ5ZjUxNmE0ZTU1ZjdmYjQ3NDcwMTQ0Y2U3ODFhNjY1ZmIwMDNlYmZmMzgwZDA1NGY2NDJiMjIxMzNkMWNkZVwiLFxuICAgIFwicmVjZWlwdF9zYWZldHkucHlcIjogXCI1YzU0MzczZjJkYzRiMDY0MDA4MjI1YzE4NmVmYjFkNWFmZGVlYzM2ZDE1MzUwYmRhMGExMmRlZDk3NjAyZDFiXCJcbiAgfSxcbiAgXCJjYXNlX2ZpbGVzXCI6IHtcbiAgICBcImNoYW5nZV9ndWFyZC5weVwiOiBcImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmVcIixcbiAgICBcInNxbGl0ZV9yZWFkb25seS5weVwiOiBcImVlZjUzZGQyMzNlZWU3NGMxN2YyMDgyM2JkN2Y1Nzg3YzYwY2FkNzlhYzY0ODAyMWM5NDc5NjQzYzZjZTllMzhcIixcbiAgICBcInByZWZsaWdodC1pbnB1dHMuanNvblwiOiBcIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDZcIixcbiAgICBcInNlYWxlZC1saXZlLWRlcGxveW1lbnQuanNvblwiOiBcImQxOGQyNzA2M2QwNmY1MzVhZTg4NGVhMDFmOTY3NDdmZTMwMTY4NTUxOGFiOTRiMWNiYTA3MmExZTE1MTkzNjJcIixcbiAgICBcInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb25cIjogXCIwNDIzMjdhMDM2ZWQyNTRjZjk1ZGJlYjBjMDU2YWMyNWIwM2E2YTg0NGI5NWEzMzJjOTkyZGYyOTQzNjkxMzY5XCIsXG4gICAgXCJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uXCI6IFwiNzIyYThlMmRjNTJiZWMyMTdiZjk2MGUyM2IyZmRkZmM3YWMyN2QzNDNhYzg3NDM3OTBlMzE4M2RiODFhNmEwZVwiLFxuICAgIFwicm9sbGJhY2stZGVwbG95bWVudC5qc29uXCI6IFwiMzliM2Y0M2JiODRlZjQ5MjFjYzNhMWZiY2RjNDQ0NjEwNzQxZWQ4ODA5MTQ5ZDhmOGYxN2VkODA1ZjI2MjEyMVwiLFxuICAgIFwiY2hlY2tfaW5zdGFsbGVkLnB5XCI6IFwiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZFwiLFxuICAgIFwicHVibGlzaGVkLXZlcmlmaWNhdGlvbi5qc29uXCI6IFwiOGE2NzZjMzhmODlmOWNhNzYyYjhlYmU5NDViNWFjYjkwZDQ3YTRjYjM1MDY5MjY4N2FiYjk4NWJiYjJkOGFlMlwiLFxuICAgIFwic2VjdXJpdHktc3VtbWFyeS5qc29uXCI6IFwiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NFwiXG4gIH0sXG4gIFwib3duZXJfc291cmNlX2ZpbGVzXCI6IHtcbiAgICBcImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uXCI6IFwiOTIzODJhNTZiMzQ5YzNiODk1ZTU4MDZlOTc1MDgyNTI3YmI5OWQxYTAwMTE0MGU2OWQ4NTdlNWIwMzkxZmE1NVwiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uXCI6IFwiMzhiNzhiOWNiZWU1YWRlNzc1MGE1OGQ1MTU2Y2E0YzU3NzMzNTJlOTQ3YWNiMzA0ZWU3MTRiNTllNzQ5Y2ViNFwiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWxcIjogXCIxYmJjZTgxYmM2NzU4NDM0MzU0MTU3Zjg2MDE1MzQzMjBjNWQwMjkwNTg3OTA4ZmQxNWE2ZDI1ZTNmYTU3ZjQ3XCIsXG4gICAgXCJkZXBsb3kvbGlmZWN5Y2xlL3JlZ2lzdHJpZXMuY2FuZGlkYXRlLmpzb25cIjogXCI5YmFkNmRiNWZiYzIxNzhkMzFiMDQxMjAwMTZhNDE4MzBjMzU1MmZiYjllMjUxN2I3MThmOWJiZTg3Y2Y2NDllXCJcbiAgfSxcbiAgXCJjYW5kaWRhdGVfaW1hZ2VcIjogXCJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2FcIixcbiAgXCJwcmlvcl9pbWFnZVwiOiBcImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3M1wiLFxuICBcInNvdXJjZV9yZXZpc2lvblwiOiBcIm11c3QtYmUtZXhhY3QtZmluYWwtb3duZXItSEVBRC13aXRoLWFwcHJvdmVkLWZvdXItR2l0LWJsb2JzXCIsXG4gIFwicGhhc2VzXCI6IFtcbiAgICBcImRyaWxsLWJhY2t1cFwiLFxuICAgIFwiZHJpbGwtY29weVwiLFxuICAgIFwib2ZmbGluZS12ZXJpZnlcIixcbiAgICBcImNsZWFudXAtb2ZmbGluZVwiLFxuICAgIFwiY3V0b3Zlci1iYWNrdXBcIixcbiAgICBcImN1dG92ZXItY29weVwiLFxuICAgIFwicmVsZWFzZVwiLFxuICAgIFwidmVyaWZ5XCIsXG4gICAgXCJyb2xsYmFja1wiLFxuICAgIFwicm9sbGJhY2stdmVyaWZ5XCJcbiAgXSxcbiAgXCJhdXRob3JpemF0aW9uXCI6IFwiZnJlc2ggZXh0ZXJuYWxseSBhdXRoZW50aWNhdGVkIHJvb3QgZml4ZWQtb3JpZ2luIG5hdGl2ZSByZWFkYmFjayBiZWZvcmUgZWFjaCBwaGFzZTsgZXhhY3QgY29uZmlybWVkIHBsYXRmb3JtLXJvb3QgZGlzcG9zaXRpb24gYW5kIGN1cnJlbnQgcGFja2V0IFNIQS9zb3VyY2UgY29tbWl0OyByZWNlaXB0IGJvb2trZWVwaW5nIGlzIG5vdCBhbiBhdXRvbm9tb3VzIHNpZ25lZCBncmFudFwiLFxuICBcImV4ZWN1dGVfYnlcIjogXCIyMDI2LTEwLTEyVDIzOjU5OjU5WlwiLFxuICBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZSxcbiAgXCJuYXRpdmVfZGF0YV9vcl93b3JrbG9hZF9hY3Rpb25fZXhlY3V0ZWRcIjogZmFsc2UsXG4gIFwiZGVhZGxpbmVfc2VtYW50aWNzXCI6IFwiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LlwiXG59XG4iCiAgICB9LAogICAgIm5hdGl2ZV9wcm9ncmFtLnB5IjogewogICAgICAic2hhMjU2IjogIjM0OWY1MTZhNGU1NWY3ZmI0NzQ3MDE0NGNlNzgxYTY2NWZiMDAzZWJmZjM4MGQwNTRmNjQyYjIyMTMzZDFjZGUiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJGaXhlZCByZW1vdGUgc291cmNlLCBwYXNzZWQgb25seSBhZnRlciBleGFjdCBzdXBlcnZpc2VkIGFwcHJvdmFsLlwiXCJcIlxuUFJPR1JBTSA9ICdcXG5pbXBvcnQgY29weSxkYXRldGltZSxoYXNobGliLGpzb24sb3MscmUsc3VicHJvY2VzcyxzeXNcXG5pZiBzeXMuZmxhZ3Mub3B0aW1pemU6cmFpc2UgUnVudGltZUVycm9yKFxcJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkXFwnKVxcbnBheWxvYWQ9anNvbi5sb2FkcyhfX1BBWUxPQURfXylcXG5leGVjKF9fR1VBUkRfXylcXG5waGFzZT1wYXlsb2FkW1xcJ3BoYXNlXFwnXVxcbmlmIHBoYXNlIG5vdCBpbiAoXFwnZHJpbGwtYmFja3VwXFwnLFxcJ2N1dG92ZXItYmFja3VwXFwnLFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnLFxcJ3JlbGVhc2VcXCcsXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrXFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6cmFpc2UgVmFsdWVFcnJvcihcXCdmaXhlZCBuYXRpdmUgcGhhc2UgcmVxdWlyZWRcXCcpXFxuZGVhZGxpbmU9ZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdChcXCcyMDI2LTEwLTEyVDIzOjU5OjU5KzAwOjAwXFwnKVxcbmRlZiByZXF1aXJlKHZhbHVlLHJlYXNvbik6XFxuIGlmIG5vdCB2YWx1ZTpyYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcXG5yZXF1aXJlKGRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpPGRlYWRsaW5lLFxcJ2V4ZWN1dGlvbiB3aW5kb3cgZXhwaXJlZFxcJylcXG5lbnY9eyoqb3MuZW52aXJvbixcXCdLVUJFQ09ORklHXFwnOlxcJy9ldGMvcmFuY2hlci9rM3MvazNzLnlhbWxcXCd9XFxuZGVmIHJ1bihhcmd2LGJvZHk9Tm9uZSx0aW1lb3V0PTkwKTpcXG4gcmV0dXJuIHN1YnByb2Nlc3MucnVuKGFyZ3YsaW5wdXQ9Ym9keSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0aW1lb3V0PXRpbWVvdXQsZW52PWVudilcXG5kZWYgcmVhZChraW5kLG5hbWUsbmFtZXNwYWNlKTpcXG4gcmVzdWx0PXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsa2luZCxuYW1lLFxcJy1uXFwnLG5hbWVzcGFjZSxcXCctb1xcJyxcXCdqc29uXFwnXSlcXG4gcmVxdWlyZShyZXN1bHQucmV0dXJuY29kZT09MCxcXCdmaXhlZCBtZXRhZGF0YSByZWFkIHJlZnVzZWRcXCcpXFxuIHJldHVybiBqc29uLmxvYWRzKHJlc3VsdC5zdGRvdXQpXFxuc2VhbGVkPXBheWxvYWRbXFwnc2VhbGVkXFwnXTsgZGVwZW5kZW5jaWVzPXBheWxvYWRbXFwnZGVwZW5kZW5jaWVzXFwnXVxcbmxpdmU9cmVhZChcXCdkZXBsb3ltZW50XFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbmNtPXJlYWQoXFwnY29uZmlnbWFwXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbnB2Yz1yZWFkKFxcJ3B2Y1xcJyxcXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsZGVwZW5kZW5jaWVzKVxcbmFwcD1yZWFkKFxcJ2FwcGxpY2F0aW9uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ2FyZ29jZFxcJylcXG5yZXF1aXJlKGFwcFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09XFwnNDk5ODY4ZjItZWFiYy00ZGY0LWFlMzEtYjg5Y2U1OGQ3NTBkXFwnLFxcJ0FwcGxpY2F0aW9uIFVJRCBjaGFuZ2VkXFwnKVxcbnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwncmVwb1VSTFxcJ109PVxcJ2h0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uLmdpdFxcJ1xcbiBhbmQgYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwncGF0aFxcJ109PVxcJ2RlcGxveS9saWZlY3ljbGVcXCdcXG4gYW5kIGFwcFtcXCdzcGVjXFwnXVtcXCdkZXN0aW5hdGlvblxcJ109PXtcXCduYW1lc3BhY2VcXCc6XFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnc2VydmVyXFwnOlxcJ2h0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Y1xcJ31cXG4gYW5kIGFwcFtcXCdzcGVjXFwnXS5nZXQoXFwnc3luY1BvbGljeVxcJyx7fSkuZ2V0KFxcJ2F1dG9tYXRlZFxcJykgaXMgTm9uZVxcbiBhbmQgc2V0KGFwcFtcXCdzcGVjXFwnXVtcXCdzb3VyY2VcXCddKT09e1xcJ3JlcG9VUkxcXCcsXFwncGF0aFxcJyxcXCd0YXJnZXRSZXZpc2lvblxcJ30gYW5kIG5vdCBhcHBbXFwnc3BlY1xcJ10uZ2V0KFxcJ3NvdXJjZXNcXCcpLFxcJ0FwcGxpY2F0aW9uIG93bmVyL3Njb3BlIGNoYW5nZWRcXCcpXFxuZXhwZWN0ZWQ9Y29weS5kZWVwY29weShzZWFsZWQpXFxuaWYgcGhhc2U9PVxcJ3ZlcmlmeVxcJzpleHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddPUNBTkRJREFURVxcbmlmIHBoYXNlPT1cXCdyb2xsYmFja1xcJzpcXG4gaW1hZ2U9bGl2ZVtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddXFxuIHJlcXVpcmUoaW1hZ2UgaW4gKEJBU0UsQ0FORElEQVRFKSxcXCdyb2xsYmFjayBpbWFnZSBpcyBvdXRzaWRlIHNhbWUtc2NoZW1hIHBhaXJcXCcpXFxuIGV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109aW1hZ2VcXG5jaGVja19jdXJyZW50KGxpdmUsZXhwZWN0ZWQpXFxuaWYgcGhhc2UhPVxcJ3JvbGxiYWNrXFwnOlxcbiByZXF1aXJlKGxpdmUuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ3JlYWR5UmVwbGljYXNcXCcpPT0xXFxuICBhbmQgbGl2ZVtcXCdzdGF0dXNcXCddLmdldChcXCd1cGRhdGVkUmVwbGljYXNcXCcpPT0xXFxuICBhbmQgbGl2ZVtcXCdzdGF0dXNcXCddLmdldChcXCdvYnNlcnZlZEdlbmVyYXRpb25cXCcpPT1saXZlW1xcJ21ldGFkYXRhXFwnXVtcXCdnZW5lcmF0aW9uXFwnXSxcXCdzZXJ2aWNlIG5vdCBSZWFkeTFcXCcpXFxudGFyZ2V0PXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwndmVyaWZ5XFwnIGVsc2UgXFwnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZlxcJ1xcbmlmIHBoYXNlPT1cXCdyb2xsYmFja1xcJzpyZXF1aXJlKGFwcFtcXCdzcGVjXFwnXVtcXCdzb3VyY2VcXCddW1xcJ3RhcmdldFJldmlzaW9uXFwnXSBpbiAodGFyZ2V0LHBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSksXFwncm9sbGJhY2sgc291cmNlIGlzIG91dHNpZGUgcGFpclxcJylcXG5lbHNlOnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwndGFyZ2V0UmV2aXNpb25cXCddPT10YXJnZXQsXFwndW5leHBlY3RlZCBzb3VyY2UgcGluXFwnKVxcbnJlc3VsdD17XFwncGhhc2VcXCc6cGhhc2UsXFwnYWxsX2NoZWNrc19wYXNzXFwnOkZhbHNlLFxcJ3Jhd19vdXRwdXRfd2l0aGhlbGRcXCc6VHJ1ZSxcXG4gXFwnbmF0aXZlX2FwcHJvdmFsX3ZlcmlmaWVkX2J5X3Jvb3RcXCc6cGF5bG9hZFtcXCdhcHByb3ZhbFxcJ10sXFwnbmF0aXZlX2F1dGhlbnRpY2F0ZWRfZ3JhbnRcXCc6RmFsc2V9XFxudHJ5OlxcbiBpZiBwaGFzZSBpbiAoXFwnZHJpbGwtYmFja3VwXFwnLFxcJ2N1dG92ZXItYmFja3VwXFwnLFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnLFxcJ3JlbGVhc2VcXCcsXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBwb2RsaXN0PXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwncG9kc1xcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctbFxcJyxcXCdhcHAua3ViZXJuZXRlcy5pby9uYW1lPWluZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddKVxcbiAgcmVxdWlyZShwb2RsaXN0LnJldHVybmNvZGU9PTAsXFwncG9kIG1ldGFkYXRhIHF1ZXJ5IHJlZnVzZWRcXCcpXFxuICBwb2RzPVtwIGZvciBwIGluIGpzb24ubG9hZHMocG9kbGlzdC5zdGRvdXQpW1xcJ2l0ZW1zXFwnXSBpZiBub3QgcFtcXCdtZXRhZGF0YVxcJ10uZ2V0KFxcJ2RlbGV0aW9uVGltZXN0YW1wXFwnKV1cXG4gIHJlcXVpcmUobGVuKHBvZHMpPT0xLFxcJ2V4YWN0IHNpbmdsZSBsaXZlIG93bmVyIHBvZCByZXF1aXJlZFxcJyk7cG9kPXBvZHNbMF1cXG4gIHJlcXVpcmUocG9kW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ3BoYXNlXFwnKT09XFwnUnVubmluZ1xcJyBhbmQgbGVuKHBvZFtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXSk9PTFcXG4gICBhbmQgcG9kW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXT09ZXhwZWN0ZWRbXFwnc3BlY1xcJ11bXFwndGVtcGxhdGVcXCddW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXVxcbiAgIGFuZCBsZW4ocG9kW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ2NvbnRhaW5lclN0YXR1c2VzXFwnLFtdKSk9PTFcXG4gICBhbmQgcG9kW1xcJ3N0YXR1c1xcJ11bXFwnY29udGFpbmVyU3RhdHVzZXNcXCddWzBdLmdldChcXCduYW1lXFwnKT09XFwnaW5mb3JtZWQtZGVjaXNpb25cXCdcXG4gICBhbmQgcG9kW1xcJ3N0YXR1c1xcJ11bXFwnY29udGFpbmVyU3RhdHVzZXNcXCddWzBdLmdldChcXCdyZWFkeVxcJykgaXMgVHJ1ZSxcXCdvd25lciBwb2QgcmVhZGluZXNzL2ltYWdlIGNoYW5nZWRcXCcpXFxuICB0ZW1wbGF0ZT1leHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11cXG4gIGNvbnRyb2xsZWQ9c2V0KHRlbXBsYXRlKXx7XFwnaW5pdENvbnRhaW5lcnNcXCcsXFwnaG9zdE5ldHdvcmtcXCcsXFwnaG9zdFBJRFxcJyxcXCdob3N0SVBDXFwnLFxcJ3J1bnRpbWVDbGFzc05hbWVcXCcsXFwnc2hhcmVQcm9jZXNzTmFtZXNwYWNlXFwnfVxcbiAgcmVxdWlyZShhbGwocG9kW1xcJ3NwZWNcXCddLmdldChrZXkpPT10ZW1wbGF0ZS5nZXQoa2V5KSBmb3Iga2V5IGluIGNvbnRyb2xsZWQpLFxcJ2FjdHVhbCBvd25lciBQb2QgY29uZmlndXJhdGlvbiBkcmlmdGVkXFwnKVxcbiAgb3duZXJzPXBvZFtcXCdtZXRhZGF0YVxcJ10uZ2V0KFxcJ293bmVyUmVmZXJlbmNlc1xcJyxbXSk7cmVxdWlyZShsZW4ob3duZXJzKT09MSBhbmQgb3duZXJzWzBdW1xcJ2tpbmRcXCddPT1cXCdSZXBsaWNhU2V0XFwnLFxcJ3BvZCBvd25lciBjaGFpbiBjaGFuZ2VkXFwnKVxcbiAgcnM9cmVhZChcXCdyZXBsaWNhc2V0XFwnLG93bmVyc1swXVtcXCduYW1lXFwnXSxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJylcXG4gIHJlcXVpcmUocnNbXFwnbWV0YWRhdGFcXCddW1xcJ3VpZFxcJ109PW93bmVyc1swXVtcXCd1aWRcXCddIGFuZCBhbnkoby5nZXQoXFwndWlkXFwnKT09c2VhbGVkW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddXFxuICAgYW5kIG8uZ2V0KFxcJ2tpbmRcXCcpPT1cXCdEZXBsb3ltZW50XFwnIGZvciBvIGluIHJzW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnb3duZXJSZWZlcmVuY2VzXFwnLFtdKSksXFwnUmVwbGljYVNldCBvd25lcnNoaXAgY2hhbmdlZFxcJylcXG4gIGlubmVyPXJcIlwiXCJcXG5pbXBvcnQgaGFzaGxpYixqc29uLG9zLHN0YXQsc3VicHJvY2VzcyxzeXNcXG5pZiBzeXMuZmxhZ3Mub3B0aW1pemU6cmFpc2UgUnVudGltZUVycm9yKFxcJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkXFwnKVxcbmV4ZWMoX19SRUFET05MWV9fKVxcbmV4ZWMoX19TQUZFVFlfXylcXG5hY3Rpb249X19BQ1RJT05fXztkYj1cXCcvZGF0YS9wcml2YXRlL3Jldmlldy5zcWxpdGVcXCc7Zm9sZGVyPVxcJy9kYXRhL3ByaXZhdGUvcHVycG9zZS1vdmVybGF5LXIxXFwnXFxuZGVmIHJlcXVpcmUodixyKTpcXG4gaWYgbm90IHY6cmFpc2UgVmFsdWVFcnJvcihyKVxcbnJlcXVpcmUob3MuZ2V0dWlkKCk9PTEwMDAxIGFuZCBvcy5nZXRnaWQoKT09MTAwMDEsXFwnbmF0aXZlIG93bmVyIFVJRC9HSUQgcmVxdWlyZWRcXCcpXFxuZGVmIHByaXZhdGUocCxkaXJlY3Rvcnk9RmFsc2UpOlxcbiBzPW9zLmxzdGF0KHApO3JlcXVpcmUoKHN0YXQuU19JU0RJUihzLnN0X21vZGUpIGlmIGRpcmVjdG9yeSBlbHNlIHN0YXQuU19JU1JFRyhzLnN0X21vZGUpKVxcbiAgYW5kIHMuc3RfdWlkPT0xMDAwMSBhbmQgc3RhdC5TX0lNT0RFKHMuc3RfbW9kZSk9PSgwbzcwMCBpZiBkaXJlY3RvcnkgZWxzZSAwbzYwMClcXG4gIGFuZCAoZGlyZWN0b3J5IG9yIHMuc3Rfbmxpbms9PTEpLFxcJ3ByaXZhdGUgbmF0aXZlIGN1c3RvZHkgcmVxdWlyZWRcXCcpXFxucHJpdmF0ZShcXCcvZGF0YS9wcml2YXRlXFwnLFRydWUpO3ByaXZhdGUoZGIpXFxuYmFzZWxpbmU9Y291bnRzKGluc3BlY3RfcmVhZG9ubHkoZGIpKSAjIE1VU1QgcHJlY2VkZSBhbnkgU3RvcmUvYWRtaW4gb3Blbi5cXG5pZiBhY3Rpb24gaW4gKFxcJ2RyaWxsLWJhY2t1cFxcJyxcXCdjdXRvdmVyLWJhY2t1cFxcJyk6XFxuIHNpemU9b3Muc3RhdChkYikuc3Rfc2l6ZVxcbiBpZiBvcy5wYXRoLmV4aXN0cyhkYitcXCctd2FsXFwnKTpzaXplKz1vcy5zdGF0KGRiK1xcJy13YWxcXCcpLnN0X3NpemVcXG4gdj1vcy5zdGF0dmZzKFxcJy9kYXRhL3ByaXZhdGVcXCcpO2ZyZWU9di5mX2JhdmFpbCp2LmZfZnJzaXplXFxuIHJlcXVpcmUoc2l6ZT4wIGFuZCBzaXplPD01MTIqMTAyNCoqMiBhbmQgZnJlZT49c2l6ZSooMiBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJyBlbHNlIDEpKzE2KjEwMjQqKjIsXFwnYm91bmRlZCBuYXRpdmUgc25hcHNob3QgY2FwYWNpdHkgcmVxdWlyZWRcXCcpXFxuIGlmIGFjdGlvbj09XFwnZHJpbGwtYmFja3VwXFwnOlxcbiAgcmVxdWlyZShub3Qgb3MucGF0aC5sZXhpc3RzKGZvbGRlciksXFwnbmF0aXZlIGNhc2UgZGlyZWN0b3J5IG11c3QgYmUgdW5pcXVlXFwnKVxcbiAgb3MubWtkaXIoZm9sZGVyLDBvNzAwKTtvcy5jaG1vZChmb2xkZXIsMG83MDApXFxuIHByaXZhdGUoZm9sZGVyLFRydWUpXFxuIGZpbGVuYW1lPVxcJ2RyaWxsLnNxbGl0ZVxcJyBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJyBlbHNlIFxcJ2N1dG92ZXIuc3FsaXRlXFwnO291dHB1dD1mb2xkZXIrXFwnL1xcJytmaWxlbmFtZVxcbiByZXF1aXJlKG5vdCBvcy5wYXRoLmxleGlzdHMob3V0cHV0KSxcXCdzbmFwc2hvdCBvdXRwdXQgbXVzdCBiZSB1bmlxdWVcXCcpXFxuIGFkbWluPXN1YnByb2Nlc3MucnVuKFtcXCdpbmZvcm1lZC1kZWNpc2lvbi1hZG1pblxcJyxcXCdiYWNrdXBcXCcsXFwnLS1kYlxcJyxkYixcXCctLW91dHB1dFxcJyxvdXRwdXRdLGNhcHR1cmVfb3V0cHV0PVRydWUsdGV4dD1UcnVlLHRpbWVvdXQ9MTIwKVxcbiByZXF1aXJlKGFkbWluLnJldHVybmNvZGU9PTAgYW5kIGpzb24ubG9hZHMoYWRtaW4uc3Rkb3V0KT09e1xcJ3N0YXR1c1xcJzpcXCdiYWNrZWRfdXBcXCcsXFwnY29uc2lzdGVudF9zbmFwc2hvdFxcJzpUcnVlfSxcXCdiYWNrdXAgY29tcGxldGlvbiBub3QgdmVyaWZpZWQ7IGRvIG5vdCByZXRyeVxcJylcXG4gcHJpdmF0ZShvdXRwdXQpXFxuIGZvciBzdWZmaXggaW4gKFxcJy13YWxcXCcsXFwnLXNobVxcJyk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnc25hcHNob3QgaXMgbm90IGNsb3NlZCBtYWluLWZpbGUgY3VzdG9keVxcJylcXG4gc25hcHNob3Q9Y291bnRzKGluc3BlY3RfcmVhZG9ubHkob3V0cHV0KSlcXG4gc2l6ZT1vcy5zdGF0KG91dHB1dCkuc3Rfc2l6ZTtyZXF1aXJlKDA8c2l6ZTw9NTEyKjEwMjQqKjIsXFwnc25hcHNob3Qgb3V0c2lkZSBib3VuZGVkIGNvcHkgc2l6ZVxcJylcXG4gZGlnZXN0PWhhc2hsaWIuc2hhMjU2KClcXG4gd2l0aCBvcGVuKG91dHB1dCxcXCdyYlxcJykgYXMgc3RyZWFtOlxcbiAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOnN0cmVhbS5yZWFkKDEwMjQqKjIpLGJcXCdcXCcpOmRpZ2VzdC51cGRhdGUoYmxvY2spXFxuIHByaW50KGpzb24uZHVtcHMoe1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZVxcJzpiYXNlbGluZSxcXCdzbmFwc2hvdF9yZWFkb25seVxcJzpzbmFwc2hvdCxcXCdzbmFwc2hvdF9zaGEyNTZcXCc6ZGlnZXN0LmhleGRpZ2VzdCgpLFxcJ3NuYXBzaG90X2J5dGVzXFwnOnNpemUsXFwnc25hcHNob3RfZmlsZVxcJzpmaWxlbmFtZSxcXCduYXRpdmVfcGFyZW50X3ByaXZhdGVcXCc6VHJ1ZSxcXCduYXRpdmVfdWlkXFwnOm9zLmdldHVpZCgpfSkpXFxuZWxpZiBhY3Rpb24gaW4gKFxcJ3ZlcmlmeVxcJyxcXCdyZWxlYXNlXFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuIHByb29mPXtcXCdhbGxfY2hlY2tzX3Bhc3NcXCc6VHJ1ZSxcXCdsaXZlX3JlYWRvbmx5X3NjaGVtYV9pbnRlZ3JpdHlfY291bnRzXFwnOmJhc2VsaW5lLFxcJ2xpdmVfY291bnRzX21heV9pbmNsdWRlX2NvbmN1cnJlbnRfY29tbWl0c1xcJzpUcnVlfVxcbiBpZiBhY3Rpb249PVxcJ3ZlcmlmeVxcJzpcXG4gIGltcG9ydCB1cmxsaWIucmVxdWVzdFxcbiAgbW9kdWxlPVxcJy9vcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weVxcJztpbmZvPW9zLmxzdGF0KG1vZHVsZSlcXG4gIHJlcXVpcmUoc3RhdC5TX0lTUkVHKGluZm8uc3RfbW9kZSkgYW5kIGluZm8uc3RfdWlkPT0wIGFuZCBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKT09MG82NDQsXFwnaW5zdGFsbGVkIHBvbGljeSBtZXRhZGF0YSBkaWZmZXJzXFwnKVxcbiAgd2l0aCBvcGVuKG1vZHVsZSxcXCdyYlxcJykgYXMgc291cmNlOm1vZHVsZV9kaWdlc3Q9aGFzaGxpYi5zaGEyNTYoc291cmNlLnJlYWQoKSkuaGV4ZGlnZXN0KClcXG4gIHJlcXVpcmUobW9kdWxlX2RpZ2VzdD09XFwnOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MlxcJyxcXCdpbnN0YWxsZWQgc291cmNlIG1vZHVsZSBkaWZmZXJzXFwnKVxcbiAgcHVycG9zZT1zdWJwcm9jZXNzLnJ1bihbc3lzLmV4ZWN1dGFibGUsXFwnLVxcJ10saW5wdXQ9X19QVVJQT1NFX18sdGV4dD1UcnVlLGNhcHR1cmVfb3V0cHV0PVRydWUsdGltZW91dD0zMClcXG4gIHJlcXVpcmUocHVycG9zZS5yZXR1cm5jb2RlPT0wLFxcJ2luc3RhbGxlZCBuYXRpdmUtcGxhY2VtZW50IHB1cnBvc2UgY2hlY2tzIGZhaWxlZFxcJylcXG4gIHRlc3RlZD1qc29uLmxvYWRzKHB1cnBvc2Uuc3Rkb3V0KVxcbiAgcmVxdWlyZSh0ZXN0ZWQ9PXtcXCdpbnN0YWxsZWRfaW1hZ2VfcHVycG9zZV92YXJpYW50c1xcJzoxMCxcXCdiaW5kaW5nX2Zvcm1zX2FsbG93ZWRcXCc6MixcXCdhZHZpc29yeV9vcl9tYWxmb3JtZWRfcmVmdXNlZFxcJzo4LFxcJ3N5bnRoZXRpY19vbmx5XFwnOlRydWUsXFwnbmF0aXZlX3Byb3ZpZGVyXFwnOkZhbHNlfSxcXCdwdXJwb3NlIHJlc3VsdCBkaWZmZXJzXFwnKVxcbiAgY2xhc3MgTm9SZWRpcmVjdCh1cmxsaWIucmVxdWVzdC5IVFRQUmVkaXJlY3RIYW5kbGVyKTpcXG4gICBkZWYgcmVkaXJlY3RfcmVxdWVzdChzZWxmLCphcmdzLCoqa3dhcmdzKTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2hlYWx0aCByZWRpcmVjdCByZWZ1c2VkXFwnKVxcbiAgb3BlbmVyPXVybGxpYi5yZXF1ZXN0LmJ1aWxkX29wZW5lcihOb1JlZGlyZWN0KCkpO3N0YXR1c2VzPXt9XFxuICBmb3Igcm91dGUgaW4gKFxcJy9oZWFsdGh6XFwnLFxcJy9yZWFkeXpcXCcpOlxcbiAgIHdpdGggb3BlbmVyLm9wZW4oXFwnaHR0cDovLzEyNy4wLjAuMTo4MDgwXFwnK3JvdXRlLHRpbWVvdXQ9MTApIGFzIHJlc3BvbnNlOlxcbiAgICByZXF1aXJlKHJlc3BvbnNlLnN0YXR1cz09MjAwIGFuZCBsZW4ocmVzcG9uc2UucmVhZCg4MTkzKSk8PTgxOTIsXFwnYm91bmRlZCBoZWFsdGggY2hlY2sgcmVmdXNlZFxcJyk7c3RhdHVzZXNbcm91dGVdPTIwMFxcbiAgcHJvb2YudXBkYXRlKGluc3RhbGxlZF9wdXJwb3NlX2NoZWNrcz10ZXN0ZWQscG9saWN5X3NoYTI1Nj1tb2R1bGVfZGlnZXN0LHBvbGljeV9tb2RlPVxcJzA2NDRcXCcscG9saWN5X3VpZD0wLGhlYWx0aF9zdGF0dXNlcz1zdGF0dXNlcyxuYXRpdmVfcHJvdmlkZXJfcHJvYmU9RmFsc2UpXFxuIHByaW50KGpzb24uZHVtcHMocHJvb2YpKVxcbmVsaWYgYWN0aW9uIGluIChcXCdkcmlsbC1jb3B5XFwnLFxcJ2N1dG92ZXItY29weVxcJyk6XFxuIHByaXZhdGUoZm9sZGVyLFRydWUpO2ZpbGVuYW1lPVxcJ2RyaWxsLnNxbGl0ZVxcJyBpZiBhY3Rpb249PVxcJ2RyaWxsLWNvcHlcXCcgZWxzZSBcXCdjdXRvdmVyLnNxbGl0ZVxcJztvdXRwdXQ9Zm9sZGVyK1xcJy9cXCcrZmlsZW5hbWU7cHJpdmF0ZShvdXRwdXQpXFxuIGZvciBzdWZmaXggaW4gKFxcJy13YWxcXCcsXFwnLXNobVxcJyk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnY2xvc2VkIG1haW4gc25hcHNob3QgcmVxdWlyZWRcXCcpXFxuIHNuYXBzaG90PWNvdW50cyhpbnNwZWN0X3JlYWRvbmx5KG91dHB1dCkpO3NpemU9b3Muc3RhdChvdXRwdXQpLnN0X3NpemU7cmVxdWlyZSgwPHNpemU8PTUxMioxMDI0KioyLFxcJ3NuYXBzaG90IHNpemUgb3V0c2lkZSBib3VuZFxcJylcXG4gZGlnZXN0PWhhc2hsaWIuc2hhMjU2KClcXG4gd2l0aCBvcGVuKG91dHB1dCxcXCdyYlxcJykgYXMgc3RyZWFtOlxcbiAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOnN0cmVhbS5yZWFkKDEwMjQqKjIpLGJcXCdcXCcpOmRpZ2VzdC51cGRhdGUoYmxvY2spXFxuIHByaW50KGpzb24uZHVtcHMoe1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ3NuYXBzaG90X2ZpbGVcXCc6ZmlsZW5hbWUsXFwnc25hcHNob3RfYnl0ZXNcXCc6c2l6ZSxcXCdzbmFwc2hvdF9zaGEyNTZcXCc6ZGlnZXN0LmhleGRpZ2VzdCgpLFxcJ3NuYXBzaG90X3JlYWRvbmx5XFwnOnNuYXBzaG90fSkpXFxuZWxzZTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2ZpeGVkIG5hdGl2ZSBiYWNrdXAvdmVyaWZ5IHBoYXNlIHJlcXVpcmVkXFwnKVxcblwiXCJcIlxcbiAgIyBTdHJpcCB0aGUgQ0xJIGJyYW5jaDogZXhlYyBvbmx5IHRoZSB2ZXJpZmllZCBzdGRsaWIgZnVuY3Rpb24sIG5ldmVyIFN0b3JlLlxcbiAgcmVhZG9ubHk9cGF5bG9hZFtcXCdyZWFkb25seVxcJ10uc3BsaXQoXCJpZiBfX25hbWVfXyA9PSBcXCdfX21haW5fX1xcJzpcIiwxKVswXVxcbiAgaW5uZXI9aW5uZXIucmVwbGFjZShcXCdfX1JFQURPTkxZX19cXCcscmVwcihyZWFkb25seSkpLnJlcGxhY2UoXFwnX19TQUZFVFlfX1xcJyxyZXByKHBheWxvYWRbXFwncmVjZWlwdF9zYWZldHlcXCddKSkucmVwbGFjZShcXCdfX0FDVElPTl9fXFwnLHJlcHIocGhhc2UpKS5yZXBsYWNlKFxcJ19fUFVSUE9TRV9fXFwnLHJlcHIocGF5bG9hZFtcXCdwdXJwb3NlX2NoZWNrc1xcJ10pKVxcbiAgcD1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnZXhlY1xcJyxcXCctaVxcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxwb2RbXFwnbWV0YWRhdGFcXCddW1xcJ25hbWVcXCddLFxcJy1jXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy0tXFwnLFxcJ3B5dGhvblxcJyxcXCctXFwnXSxpbm5lciwxNTApXFxuICByZXF1aXJlKHAucmV0dXJuY29kZT09MCxcXCduYXRpdmUgcGhhc2Ugb3V0Y29tZSB1bnZlcmlmaWVkOyByYXcgb3V0cHV0IHdpdGhoZWxkLCBkbyBub3QgcmV0cnlcXCcpXFxuICBvdXRjb21lPWpzb24ubG9hZHMocC5zdGRvdXQpO3JlcXVpcmUob3V0Y29tZS5nZXQoXFwnYWxsX2NoZWNrc19wYXNzXFwnKSBpcyBUcnVlLFxcJ25hdGl2ZSBwaGFzZSBnYXRlIHJlZnVzZWRcXCcpXFxuICByZXN1bHQudXBkYXRlKG91dGNvbWUscG9kX25hbWU9cG9kW1xcJ21ldGFkYXRhXFwnXVtcXCduYW1lXFwnXSxwb2RfdWlkPXBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXSlcXG4gaWYgcGhhc2UgaW4gKFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2tcXCcpOlxcbiAgbm9kZV9yZWFkPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwnbm9kZXNcXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pO3JlcXVpcmUobm9kZV9yZWFkLnJldHVybmNvZGU9PTAsXFwnbm9kZSBtZXRhZGF0YSB1bmF2YWlsYWJsZVxcJylcXG4gIG5vZGVzPWpzb24ubG9hZHMobm9kZV9yZWFkLnN0ZG91dClbXFwnaXRlbXNcXCddO3JlcXVpcmUobGVuKG5vZGVzKT09MSxcXCdvbmUgdGFyZ2V0IG5vZGUgcmVxdWlyZWRcXCcpO25vZGU9bm9kZXNbMF1cXG4gIHJlcXVpcmUoYW55KGEuZ2V0KFxcJ2FkZHJlc3NcXCcpPT1cXCc5Mi4yMDUuNjIuMjM5XFwnIGZvciBhIGluIG5vZGVbXFwnc3RhdHVzXFwnXVtcXCdhZGRyZXNzZXNcXCddKSxcXCd0YXJnZXQgbm9kZSBhZGRyZXNzIGNoYW5nZWRcXCcpXFxuICBjb25kaXRpb25zPXtjW1xcJ3R5cGVcXCddOmNbXFwnc3RhdHVzXFwnXSBmb3IgYyBpbiBub2RlW1xcJ3N0YXR1c1xcJ11bXFwnY29uZGl0aW9uc1xcJ119XFxuICByZXF1aXJlKGNvbmRpdGlvbnMuZ2V0KFxcJ1JlYWR5XFwnKT09XFwnVHJ1ZVxcJyBhbmQgYWxsKGNvbmRpdGlvbnMuZ2V0KGspPT1cXCdGYWxzZVxcJyBmb3IgayBpbiAoXFwnTWVtb3J5UHJlc3N1cmVcXCcsXFwnRGlza1ByZXNzdXJlXFwnLFxcJ1BJRFByZXNzdXJlXFwnKSksXFwnbm9kZSB1bmhlYWx0aHkgb3IgcHJlc3N1cmVkXFwnKVxcbiAgZGVzY3JpcHRpb249cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2Rlc2NyaWJlXFwnLFxcJ25vZGVcXCcsbm9kZVtcXCdtZXRhZGF0YVxcJ11bXFwnbmFtZVxcJ11dKTtyZXF1aXJlKGRlc2NyaXB0aW9uLnJldHVybmNvZGU9PTAsXFwnaGVhZHJvb20gY2FwdHVyZSB1bmF2YWlsYWJsZVxcJylcXG4gIHRhYmxlPWRlc2NyaXB0aW9uLnN0ZG91dC5zcGxpdChcXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcJywxKVsxXTtyZXF1ZXN0ZWQ9aW50KHJlLnNlYXJjaChyXFwnY3B1XFxcXHMrKFxcXFxkKyltXFwnLHRhYmxlKS5ncm91cCgxKSk7YWxsb2M9bm9kZVtcXCdzdGF0dXNcXCddW1xcJ2FsbG9jYXRhYmxlXFwnXVtcXCdjcHVcXCddO2NhcGFjaXR5PWludChhbGxvY1s6LTFdKSBpZiBhbGxvYy5lbmRzd2l0aChcXCdtXFwnKSBlbHNlIGludChhbGxvYykqMTAwMFxcbiAgcmVxdWlyZShyZXF1ZXN0ZWQ8PWNhcGFjaXR5LFxcJ1JlY3JlYXRlIHJlcXVlc3RlZCBDUFUgZXhjZWVkcyBjYXBhY2l0eVxcJylcXG4gIHJlcXVpcmUobm90IGFwcC5nZXQoXFwnb3BlcmF0aW9uXFwnKSBhbmQgYXBwLmdldChcXCdzdGF0dXNcXCcse30pLmdldChcXCdvcGVyYXRpb25TdGF0ZVxcJyx7fSkuZ2V0KFxcJ3BoYXNlXFwnKSBub3QgaW4gKFxcJ1J1bm5pbmdcXCcsXFwnVGVybWluYXRpbmdcXCcpLFxcJ2V4aXN0aW5nIEFyZ28gb3BlcmF0aW9uIG11c3QgYmUgc2V0dGxlZFxcJylcXG4gIGRlc3RpbmF0aW9uPXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwncmVsZWFzZVxcJyBlbHNlIFxcJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmZcXCdcXG4gIGJvZHk9Y29weS5kZWVwY29weShwYXlsb2FkW1xcJ2NhbmRpZGF0ZVxcJ10gaWYgcGhhc2U9PVxcJ3JlbGVhc2VcXCcgZWxzZSBwYXlsb2FkW1xcJ3JvbGxiYWNrXFwnXSlcXG4gIGRyeT1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnYXBwbHlcXCcsXFwnLS1kcnktcnVuPXNlcnZlclxcJyxcXCctZlxcJyxcXCctXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddLGpzb24uZHVtcHMoYm9keSkpXFxuICByZXF1aXJlKGRyeS5yZXR1cm5jb2RlPT0wLFxcJ2ZyZXNoIG93bmVyIHNlcnZlciBhZG1pc3Npb24gcmVmdXNlZFxcJylcXG4gIGFkbWl0dGVkPWpzb24ubG9hZHMoZHJ5LnN0ZG91dCk7d2FudGVkPWNvcHkuZGVlcGNvcHkoc2VhbGVkKVxcbiAgd2FudGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFIGlmIHBoYXNlPT1cXCdyZWxlYXNlXFwnIGVsc2UgQkFTRVxcbiAgcmVxdWlyZShwcm9qZWN0aW9uKGFkbWl0dGVkKT09d2FudGVkLFxcJ2RyeS1ydW4gY2hhbmdlZCBhbnl0aGluZyBiZXlvbmQgZXhhY3QgaW1hZ2VcXCcpXFxuICBkaWZmPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdkaWZmXFwnLFxcJy1mXFwnLFxcJy1cXCddLGpzb24uZHVtcHMoYm9keSkpO3JlcXVpcmUoZGlmZi5yZXR1cm5jb2RlIGluICgwLDEpLFxcJ2NsaWVudCBkaWZmIHVuYXZhaWxhYmxlXFwnKVxcbiAgb3BlcmF0aW9uPXtcXCdpbml0aWF0ZWRCeVxcJzp7XFwndXNlcm5hbWVcXCc6XFwnY3VzdG9kaWFuLWNvZGV4XFwnfSxcXCdzeW5jXFwnOntcXCdyZXZpc2lvblxcJzpkZXN0aW5hdGlvbixcXCdwcnVuZVxcJzpGYWxzZSxcXG4gICBcXCdyZXNvdXJjZXNcXCc6W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dfX1cXG4gIHBhdGNoPVt7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS91aWRcXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS9yZXNvdXJjZVZlcnNpb25cXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCdyZXNvdXJjZVZlcnNpb25cXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9zcGVjL3NvdXJjZS90YXJnZXRSZXZpc2lvblxcJyxcXCd2YWx1ZVxcJzphcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ119LFxcbiAgIHtcXCdvcFxcJzpcXCdyZXBsYWNlXFwnLFxcJ3BhdGhcXCc6XFwnL3NwZWMvc291cmNlL3RhcmdldFJldmlzaW9uXFwnLFxcJ3ZhbHVlXFwnOmRlc3RpbmF0aW9ufSxcXG4gICB7XFwnb3BcXCc6XFwnYWRkXFwnLFxcJ3BhdGhcXCc6XFwnL29wZXJhdGlvblxcJyxcXCd2YWx1ZVxcJzpvcGVyYXRpb259XVxcbiAgYXJndj1bXFwna3ViZWN0bFxcJyxcXCdwYXRjaFxcJyxcXCdhcHBsaWNhdGlvblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctblxcJyxcXCdhcmdvY2RcXCcsXFwnLS10eXBlPWpzb25cXCcsXFwnLS1wYXRjaC1maWxlPS9kZXYvc3RkaW5cXCcsXFwnLW9cXCcsXFwnbmFtZVxcJ11cXG4gIHBhdGNoZHJ5PXJ1bihhcmd2K1tcXCctLWRyeS1ydW49c2VydmVyXFwnXSxqc29uLmR1bXBzKHBhdGNoKSk7cmVxdWlyZShwYXRjaGRyeS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIG9wZXJhdGlvbiBkcnktcnVuIHJlZnVzZWRcXCcpXFxuICBjaGFuZ2U9cnVuKGFyZ3YsanNvbi5kdW1wcyhwYXRjaCkpXFxuICByZXF1aXJlKGNoYW5nZS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIHBhdGNoIG91dGNvbWUgYW1iaWd1b3VzOyBkbyBub3QgcmV0cnlcXCcpXFxuICByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1UcnVlLG9wZXJhdGlvbl9yZXF1ZXN0ZWQ9VHJ1ZSxzb3VyY2VfcmV2aXNpb249ZGVzdGluYXRpb24sXFxuICAgcmVzb3VyY2VzPW9wZXJhdGlvbltcXCdzeW5jXFwnXVtcXCdyZXNvdXJjZXNcXCddLHBydW5lPUZhbHNlLHJvbGxvdXRfdmVyaWZpZWQ9RmFsc2UsXFxuICAgbGF0ZXN0X2xpdmVfZGF0YWJhc2VfcmV0YWluZWQ9VHJ1ZSxjbGllbnRfZGlmZl9zaGEyNTY9aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpKVxcbiBpZiBwaGFzZSBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBvcD1hcHAuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ29wZXJhdGlvblN0YXRlXFwnLHt9KTtzeW5jPW9wLmdldChcXCdvcGVyYXRpb25cXCcse30pLmdldChcXCdzeW5jXFwnLHt9KVxcbiAgcmVxdWlyZShvcC5nZXQoXFwncGhhc2VcXCcpPT1cXCdTdWNjZWVkZWRcXCcgYW5kIHN5bmMuZ2V0KFxcJ3JldmlzaW9uXFwnKT09dGFyZ2V0IGFuZCBzeW5jLmdldChcXCdwcnVuZVxcJykgaXMgRmFsc2VcXG4gICBhbmQgc3luYy5nZXQoXFwncmVzb3VyY2VzXFwnKT09W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dLFxcJ2V4YWN0IG5hdGl2ZSBBcmdvIG9wZXJhdGlvbiBjb21wbGV0aW9uIHVudmVyaWZpZWRcXCcpXFxuICByZXF1aXJlKGxpdmVbXFwnc3RhdHVzXFwnXS5nZXQoXFwnb2JzZXJ2ZWRHZW5lcmF0aW9uXFwnKT09bGl2ZVtcXCdtZXRhZGF0YVxcJ11bXFwnZ2VuZXJhdGlvblxcJ10sXFwnY29udHJvbGxlciBnZW5lcmF0aW9uIG5vdCBzZXR0bGVkXFwnKVxcbiAgcmVzdWx0LnVwZGF0ZShuYXRpdmVfcm9sbG91dF92ZXJpZmllZD1UcnVlLGN1cnJlbnRfc2NoZW1hNV9kYXRhYmFzZV9yZXRhaW5lZD1UcnVlLHJlY292ZXJ5X3ZlcmlmaWNhdGlvbj1waGFzZT09XFwncm9sbGJhY2stdmVyaWZ5XFwnKVxcbmV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGVycm9yOlxcbiByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1GYWxzZSxmYWlsdXJlX2NsYXNzPXR5cGUoZXJyb3IpLl9fbmFtZV9fLFxcbiAgZmFpbHVyZT1cXCdmaXhlZCBwaGFzZSBvdXRjb21lIHJlZnVzZWQgb3IgYW1iaWd1b3VzOyByYXcgb3V0cHV0IHdpdGhoZWxkOyBubyByZXRyeVxcJylcXG5wcmludChqc29uLmR1bXBzKHJlc3VsdCkpO3N5cy5leGl0KDAgaWYgcmVzdWx0LmdldChcXCdhbGxfY2hlY2tzX3Bhc3NcXCcpIGlzIFRydWUgZWxzZSAxKVxcbidcbiIKICAgIH0sCiAgICAicGFja2V0LXJlZmluZW1lbnQuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICJlZjM3MGE0OTE0NjhkZjI4NjgzZjMwMDJjYjZlOGJiYjdlNDdiNjVlOGU0ZDAyZmY0ZDA5ZTljMzlmMDIwYzhhIiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJwcmlvcl9yZXZpZXdlZF9wYWNrZXRfbWFuaWZlc3Rfc2hhMjU2XCI6IFwiYjFlM2U2NmJjNDAyM2RjODBjNmVhNTk1NjRjMzU1N2M3NjUzZmIzYzMwN2Y0NmEwNDk5OTdiNzYxOThhOTAzM1wiLFxuICBcImtpbmRcIjogXCJtZWNoYW5pY2FsLWFjdHVhdG9yLXBhY2tldC1yZWZpbmVtZW50LXJlcXVpcmVkLWJlZm9yZS1maXJzdC1odW1hbi1wb3N0XCIsXG4gIFwiY2hhbmdlc1wiOiBbXG4gICAgXCJIYXNoLWJpbmQgYWxsIGV4ZWN1dG9yIGJ5dGVzL2V4ZWN1dGlvbnBsYW4gaW4gYW1lbmRlZDIwZG9jIHBhY2tldCwgcHJlc2VydmUgcHJpb3I3OHBhdGggdGVjaG5pY2FsIHJldmlld3MgYXMgaGlzdG9yeVwiLFxuICAgIFwiUmVxdWlyZSBmcmVzaCByb290IGZpeGVkLW9yaWdpbiBjb25maXJtZWQgZm91bmRlciByZWNlaXB0IGJlZm9yZSBlYWNoIHBoYXNlLCBubyBzaWduZWQgYXV0b25vbW91cyBncmFudFwiLFxuICAgIFwiQmluZCBhbGwgZm91ciBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGFuZCByZWplY3QgQXBwbGljYXRpb24gc291cmNlIG92ZXJyaWRlcyBvciBhdXRvbWF0ZWQ6e31cIixcbiAgICBcIkV4cGxpY2l0IG5ldyBpc29sYXRlZCBvZmZsaW5lIHZvbHVtZSBVSUQwL0NBUF9DSE9XTiBpbml0aWFsaXplciwgbm8gaG9zdC9saXZlUFZDL3Rva2VuL2NvbmZpZyBtb3VudHMsIGJvdW5kZWQ1MTJNaUIgcHJpdmF0ZSBzbmFwc2hvdCBzdHJlYW0gYW5kIG5hbWVkVm9sdW1lIG5vbmNlIG93bmVyc2hpcFwiLFxuICAgIFwiRHVyYWJsZSBwZXItcGhhc2UgUlVOTklORyBiZWZvcmUgYWN0aW9uOyBubyBzYW1lLXBoYXNlIHJldHJpZXMgYWZ0ZXIgZmFpbHVyZXMvY3Jhc2gsIGRpc3RpbmN0IHN1cGVydmlzZWQgc2FtZS1zY2hlbWEgcm9sbGJhY2sgcmV0YWlucyBsYXRlc3REQlwiLFxuICAgIFwiQWN0dWFsIG5hdGl2ZSBwcmUtb3BlbiByZWFkb25seXNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgYmVmb3JlIGJhY2t1cC9hZG1pbiwgYWN0dWFsIFBvZC9DTS9QVkMvc291cmNlIHNlYWxzLCBvZmZsaW5lIHByZS1vcGVuIGNoZWNrIGJlZm9yZSBhZG1pbmluc3BlY3QsIG5hdGl2ZWluc3RhbGxlZDEwc3ludGhldGljcHVycG9zZSBjaGVja3MrYm91bmRlZGxvY2FsaG9zdGhlYWx0aCBhZnRlcmNvbnRyb2xsZXJjb21wbGV0aW9uXCJcbiAgXSxcbiAgXCJ1bmNoYW5nZWRcIjogW1xuICAgIFwiaW1tdXRhYmxlNzYzYyBwdXJwb3Nlb25seSBpbWFnZVwiLFxuICAgIFwiQ29uZmlnTWFwNmMvcnVudGltZS9wb2xpY3kgcGlucy9hdWRpZW5jZXMvY3JlZGVudGlhbHNcIixcbiAgICBcIkRlcGxveW1lbnQtb25seSBtYW51YWxBcmdvIHNjb3BlZCBvcGVyYXRpb24vcHJ1bmVmYWxzZVwiLFxuICAgIFwiZXhpc3RpbmdQVkMvc2luZ2xld3JpdGVyL1JlY3JlYXRlL3NjaGVtYTVcIixcbiAgICBcImV4cGxpY2l0IGluaGVyaXRlZDFmaXhhYmxlTUVEIG93bmVyVDA1IGZvbGxvdy10aHJvdWdoXCJcbiAgXSxcbiAgXCJuYXRpdmVfYWN0aW9uX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICBcImZvdW5kZXJfYXBwcm92YWxcIjogZmFsc2UsXG4gIFwibWVjaGFuaWNhbF9yZXZpZXdfcmVmaW5lbWVudFwiOiB7XG4gICAgXCJvcmlnaW5hbF9tYW5pZmVzdF9zaGEyNTZcIjogXCI2NTNiNjhjMzg5MWMwNjZmNDBkMTA0YmZjNjdhMzVkYTVlNDM2NjA1Y2Q5OWFmZDUyZmJhYzRiNDdhOTU1M2ZlXCIsXG4gICAgXCJhcmNoaXZlXCI6IFwiZXhlY3V0aW9uLWhpc3RvcnkvaW5pdGlhbC02NTNiNjhjM1wiLFxuICAgIFwiZmluZGluZ3NcIjogW1xuICAgICAgXCJyb2xsYmFjayBpbmNvcnJlY3RseSBkZXBlbmRlZCBvbiBSZWFkeSBjYW5kaWRhdGUgYW5kIGRhdGFiYXNlIGV4ZWNcIixcbiAgICAgIFwib2ZmbGluZSBhZG1pbiBsYWNrZWQgcG9zdC1vcGVuIHJlYWRvbmx5IGZ1bGwgcHJvb2YgYW5kIG9yaWdpbmFsIHNuYXBzaG90IFNIQSBjaGVja1wiLFxuICAgICAgXCJhbGwtcGhhc2UgaGVscGVyIGRlYWRsaW5lIHdhcyBub3QgZGlzY2xvc2VkIGJ5IHByaW9yIHVuc3RhcnRlZC1yZWxlYXNlIHBhY2tldCB3b3JkaW5nXCJcbiAgICBdLFxuICAgIFwicmVzb2x2ZWRfYnlcIjogW1xuICAgICAgXCJyb2xsYmFjayBkaXNwYXRjaCBleGNsdWRlcyBQb2QgbWV0YWRhdGEvZXhlYyBlbnRpcmVseTsgc2VwYXJhdGUgcm9sbGJhY2stdmVyaWZ5IHByb3ZlcyByZWNvdmVyZWQgb2xkLWltYWdlL3NjaGVtYTUgREJcIixcbiAgICAgIFwicG9zdC1hZG1pbiBVSUQxMDAwMSByZWFkb25seSBpbnRlZ3JpdHkvc2NoZW1hL2NvdW50IHByb29mIGVxdWFscyBmcm96ZW4gc25hcHNob3Q7IHJldGFpbmVkIG9yaWdpbmFsIFNIQSB1bmNoYW5nZWRcIixcbiAgICAgIFwiZXhwbGljaXQgYWxsLXBoYXNlIGluY2x1ZGluZyByZWNvdmVyeS92ZXJpZmljYXRpb24gZGVhZGxpbmUgYW5kIGZyZXNoLWZvdW5kZXItZGVjaXNpb24gcmVxdWlyZW1lbnQgYmV5b25kIGV4cGlyeVwiXG4gICAgXSxcbiAgICBcInNhbWVfcHJvcG9zYWxfdHJpYWxcIjogdHJ1ZSxcbiAgICBcIm5hdGl2ZV9hY3Rpb25zX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICAgIFwiaHVtYW5fYWNjZXB0YW5jZVwiOiBmYWxzZVxuICB9XG59XG4iCiAgICB9LAogICAgInJlY2VpcHRfc2FmZXR5LnB5IjogewogICAgICAic2hhMjU2IjogIjVjNTQzNzNmMmRjNGIwNjQwMDgyMjVjMTg2ZWZiMWQ1YWZkZWVjMzZkMTUzNTBiZGEwYTEyZGVkOTc2MDJkMWIiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmx5IHN0cnVjdHVyYWwgY291bnQvaGFzaCByZWNlaXB0cyBjYW4gbGVhdmUgdGhlIHByaXZhdGUgZXhlY3V0aW9uIHBoYXNlLlwiXCJcIlxuZGVmIGNvdW50cyh2YWx1ZSk6XG4gICAgaWYgKHNldCh2YWx1ZSkgIT0geydzY2hlbWFfdmVyc2lvbicsICdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJywgJ2ludGVncml0eScsXG4gICAgICAgICAgICAgICAgICAgICAgICdyZWFkX29ubHlfcHJlX29wZW4nLCAnc3RvcmVfY29uc3RydWN0ZWQnfVxuICAgICAgICAgICAgb3IgdmFsdWVbJ3NjaGVtYV92ZXJzaW9uJ10gIT0gNSBvciB2YWx1ZVsnaW50ZWdyaXR5J10gIT0gJ29rJ1xuICAgICAgICAgICAgb3IgdmFsdWVbJ3JlYWRfb25seV9wcmVfb3BlbiddIGlzIG5vdCBUcnVlIG9yIHZhbHVlWydzdG9yZV9jb25zdHJ1Y3RlZCddIGlzIG5vdCBGYWxzZVxuICAgICAgICAgICAgb3Igc2V0KHZhbHVlWydsaWZlY3ljbGUnXSkgIT0geydyZWNvcmRzJywgJ2V2ZW50cycsICdwZW5kaW5nJ31cbiAgICAgICAgICAgIG9yIG5vdCBzZXQodmFsdWVbJ291dGJveCddKSA8PSB7J3BlbmRpbmcnLCAnZGVsaXZlcmVkJywgJ2Jsb2NrZWQnfVxuICAgICAgICAgICAgb3Igbm90IHNldCh2YWx1ZVsnc3VibWlzc2lvbnMnXSkgPD0geydwcmVwYXJlZCcsICdpbl9mbGlnaHQnLCAnY29uZmlybWVkJywgJ3VucmVzb2x2ZWQnfSk6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ2NvdW50LW9ubHkgcmVjZWlwdCBzaGFwZS9zdGF0ZSByZWZ1c2VkOyB2YWx1ZXMgd2l0aGhlbGQnKVxuICAgIGZvciBncm91cCBpbiAoJ2xpZmVjeWNsZScsICdvdXRib3gnLCAnc3VibWlzc2lvbnMnKTpcbiAgICAgICAgaWYgYW55KHR5cGUobnVtYmVyKSBpcyBub3QgaW50IG9yIG51bWJlciA8IDAgb3IgbnVtYmVyID4gMTAqKjEyXG4gICAgICAgICAgICAgICBmb3IgbnVtYmVyIGluIHZhbHVlW2dyb3VwXS52YWx1ZXMoKSk6XG4gICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdjb3VudC1vbmx5IHJlY2VpcHQgdmFsdWVzIHJlZnVzZWQnKVxuICAgIHJldHVybiB2YWx1ZVxuIgogICAgfSwKICAgICJyb290LWF1dGhvcml0eS1yZWNlaXB0LXRlbXBsYXRlLmpzb24iOiB7CiAgICAgICJzaGEyNTYiOiAiMTU5NjZiN2M2ZjA4OGEwMzNiYWYxZmVmODc4ZGRiMzUxZGUyZmEyYWU0NmI1YmM3MTAyNjVlZDE3MmFiMjgxMyIsCiAgICAgICJjb250ZW50IjogIntcbiAgXCJwcm9wb3NhbF9pZFwiOiBcIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxXCIsXG4gIFwibWVtb19pZFwiOiBcImluZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxXCIsXG4gIFwibWVtb192ZXJzaW9uXCI6IDEsXG4gIFwibWVtb19zaGEyNTZcIjogbnVsbCxcbiAgXCJzb3VyY2VfcmV2aXNpb25cIjogbnVsbCxcbiAgXCJhY3RpdmF0aW9uXCI6IFwiUEVORElOR1wiLFxuICBcImF1dGhvcml0eV9tb2RlXCI6IFwiQURNSU5JU1RFUlwiLFxuICBcInRhcmdldFwiOiBcInJlYWxtOmt1YmVybmV0ZXMvcmFpbGlhbmNlMDEvaW5mb3JtZWQtZGVjaXNpb25cIixcbiAgXCJ2ZXJpZmljYXRpb25fbWV0aG9kXCI6IFwicm9vdC1maXhlZC1vcmlnaW4tbmF0aXZlLXJlYWRiYWNrXCIsXG4gIFwicnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50XCI6IGZhbHNlLFxuICBcInZlcmlmaWVkX2F0XCI6IG51bGwsXG4gIFwiYWNjZXB0ZWRfYXRcIjogbnVsbCxcbiAgXCJyZXZpZXdfbWVtb19pZFwiOiBudWxsLFxuICBcImFwcHJvdmFsX2lkXCI6IG51bGwsXG4gIFwiZGlzcG9zaXRpb25faWRcIjogbnVsbCxcbiAgXCJuYXRpdmVfb3V0Y29tZV9zaGEyNTZcIjogbnVsbCxcbiAgXCJleGVjdXRvcl9wbGFuX3NoYTI1NlwiOiBcIjRkNTUzMGU3NDE4ZjYzOGIxMGNjZmYwZTBkOWEwNzI3YWRjNjRhN2YzYTQ1OTA3ZjZkZWI1NzM5YWQyYWRjODVcIlxufVxuIgogICAgfSwKICAgICJ0ZXN0X2V4ZWN1dGlvbi5weSI6IHsKICAgICAgInNoYTI1NiI6ICI5Y2NmNmQ0MjFiZjIwZjBlODM1MGY2NzEzZDZkMWNlZTJiYTE5OWY0ODVkY2FmMjU1OGMzODc0MjFkOWEyYjQ4IiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiU3ludGhldGljIGN1c3RvZHkvdHJhbnNwb3J0IHRlc3RzLiBObyBuYXRpdmUgZGF0YSwgRG9ja2VyIG9yIGNsdXN0ZXIgYWN0aW9uLlwiXCJcIlxuaW1wb3J0IGNvcHlcbmltcG9ydCBkYXRldGltZVxuaW1wb3J0IGlvXG5pbXBvcnQganNvblxuaW1wb3J0IG9zXG5mcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGhcbmltcG9ydCBzdWJwcm9jZXNzXG5pbXBvcnQgc3lzXG5pbXBvcnQgdGVtcGZpbGVcbmltcG9ydCB1bml0dGVzdFxuZnJvbSB1bml0dGVzdC5tb2NrIGltcG9ydCBwYXRjaFxuZnJvbSBjb250ZXh0bGliIGltcG9ydCByZWRpcmVjdF9zdGRvdXRcblxuaW1wb3J0IGFjdHVhdG9yXG5mcm9tIGF1dGhvcml0eV9qb3VybmFsIGltcG9ydCBKb3VybmFsLCBhdXRob3JpdHlcbmZyb20gbmF0aXZlX3Byb2dyYW0gaW1wb3J0IFBST0dSQU1cbmZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuXG5DQVNFID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uL2RvY3MvZXZpZGVuY2UvMjAyNi0xMC0xMS1wdXJwb3NlLWltYWdlLXJlbGVhc2UnKVxuTk9XID0gZGF0ZXRpbWUuZGF0ZXRpbWUoMjAyNiwgMTAsIDExLCAyLCAwLCB0emluZm89ZGF0ZXRpbWUudGltZXpvbmUudXRjKVxuUkVWSVNJT04gPSAnZScgKiA0MFxuQ09VTlQgPSB7J3NjaGVtYV92ZXJzaW9uJzogNSwgJ2ludGVncml0eSc6ICdvaycsICdyZWFkX29ubHlfcHJlX29wZW4nOiBUcnVlLCAnc3RvcmVfY29uc3RydWN0ZWQnOiBGYWxzZSxcbiAgICAgICAgICdsaWZlY3ljbGUnOiB7J3JlY29yZHMnOiAzLCAnZXZlbnRzJzogOCwgJ3BlbmRpbmcnOiAxfSxcbiAgICAgICAgICdvdXRib3gnOiB7J3BlbmRpbmcnOiAyLCAnZGVsaXZlcmVkJzogMTB9LCAnc3VibWlzc2lvbnMnOiB7J2NvbmZpcm1lZCc6IDEsICd1bnJlc29sdmVkJzogMX19XG5cblxuZGVmIGFjY2VwdGVkKCk6XG4gICAgYXBwcm92YWwgPSAnMTExMTExMTEtMTExMS00MTExLTgxMTEtMTExMTExMTExMTExJ1xuICAgIHJldmlldyA9ICdyZXZpZXctMjIyMjIyMjItMjIyMi00MjIyLTgyMjItMjIyMjIyMjIyMjIyJ1xuICAgIGRpc3Bvc2l0aW9uID0gJ2Rpc3AtMzMzMzMzMzMtMzMzMy00MzMzLTgzMzMtMzMzMzMzMzMzMzMzJ1xuICAgIHJlY2VpcHQgPSB7J3Byb3Bvc2FsX2lkJzogJ0lORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxJyxcbiAgICAgICAgICAgICAgICdtZW1vX2lkJzogJ2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxJywgJ21lbW9fdmVyc2lvbic6IDEsXG4gICAgICAgICAgICAgICAnbWVtb19zaGEyNTYnOiAnYScgKiA2NCwgJ3NvdXJjZV9yZXZpc2lvbic6IFJFVklTSU9OLCAnYWN0aXZhdGlvbic6ICdBUFBST1ZFRCcsXG4gICAgICAgICAgICAgICAnYXV0aG9yaXR5X21vZGUnOiAnQURNSU5JU1RFUicsICd0YXJnZXQnOiAncmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbicsXG4gICAgICAgICAgICAgICAndmVyaWZpY2F0aW9uX21ldGhvZCc6ICdyb290LWZpeGVkLW9yaWdpbi1uYXRpdmUtcmVhZGJhY2snLCAncnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50JzogRmFsc2UsXG4gICAgICAgICAgICAgICAndmVyaWZpZWRfYXQnOiAnMjAyNi0xMC0xMVQwMjowMDowMFonLCAnYWNjZXB0ZWRfYXQnOiAnMjAyNi0xMC0xMVQwMTo1OTowMFonLFxuICAgICAgICAgICAgICAgJ3Jldmlld19tZW1vX2lkJzogcmV2aWV3LCAnYXBwcm92YWxfaWQnOiBhcHByb3ZhbCwgJ2Rpc3Bvc2l0aW9uX2lkJzogZGlzcG9zaXRpb259XG4gICAgb3V0Y29tZSA9IHsnbWVtb19pZCc6IHJlY2VpcHRbJ21lbW9faWQnXSwgJ3Jldmlldyc6IHsnbWVtb19pZCc6IHJldmlldywgJ3N0YWxlJzogRmFsc2UsICdpbnRha2Vfc3RhdGUnOiAncmVhZHknfSxcbiAgICAgICAgICAgICAgICdkaXNwb3NpdGlvbnMnOiBbeydhcHByb3ZhbF9pZCc6IE5vbmUsICdzdWJtaXNzaW9uX3N0YXRlJzogJ2NvbmZpcm1lZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGlzcG9zaXRpb24nOiB7J3ZlcmInOiAnYWNjZXB0JywgJ21lbW9fdmVyc2lvbic6IDEsICdtZW1vX2lkJzogcmV2aWV3LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhcHByb3ZhbF9pZCc6IGFwcHJvdmFsLCAnaWQnOiBkaXNwb3NpdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYWN0b3InOiB7J2tpbmQnOiAncGVyc29uJywgJ3N1Yic6ICd1aWQ9cGxhdGZvcm0tcm9vdCxvdT1wZW9wbGUsZGM9bmV0a2luZ2RvbSxkYz1sb2NhbCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhdCc6IHJlY2VpcHRbJ2FjY2VwdGVkX2F0J119fV19XG4gICAgcmV0dXJuIHJlY2VpcHQsIG91dGNvbWVcblxuXG5jbGFzcyBBdXRob3JpdHlBbmRDdXN0b2R5KHVuaXR0ZXN0LlRlc3RDYXNlKTpcbiAgICBkZWYgdGVzdF9leGFjdF9uZXN0ZWRfZm91bmRlcl9yZWNlaXB0X25vdF90b3BfbGV2ZWxfYXBwcm92YWwoc2VsZik6XG4gICAgICAgIHJlY2VpcHQsIG91dGNvbWUgPSBhY2NlcHRlZCgpXG4gICAgICAgIHJlc3VsdCA9IGF1dGhvcml0eShyZWNlaXB0LCBvdXRjb21lLCAnYScgKiA2NCwgUkVWSVNJT04sICdkcmlsbC1iYWNrdXAnLCBOT1cpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydhcHByb3ZhbF9pZCddLCByZWNlaXB0WydhcHByb3ZhbF9pZCddKVxuXG4gICAgZGVmIHRlc3RfcGVuZGluZ19zdGFsZV93cm9uZ19hY3Rvcl92ZXJzaW9uX2FuZF9iaW5kaW5nX3JlZnVzZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSByLCBvOiByLnVwZGF0ZShhY3RpdmF0aW9uPSdQRU5ESU5HJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUobWVtb19zaGEyNTY9J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZShzb3VyY2VfcmV2aXNpb249J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZSh0YXJnZXQ9J290aGVyJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpZWRfYXQ9JzIwMjYtMTAtMTFUMDE6MDA6MDBaJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpY2F0aW9uX21ldGhvZD0nY2FsbGVyLWFzc2VydGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUocnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50PVRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ3JldmlldyddLnVwZGF0ZShzdGFsZT1UcnVlKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydyZXZpZXcnXS51cGRhdGUoaW50YWtlX3N0YXRlPSdwZW5kaW5nJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ11bMF0udXBkYXRlKHN1Ym1pc3Npb25fc3RhdGU9J3VucmVzb2x2ZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydkaXNwb3NpdGlvbnMnXVswXVsnZGlzcG9zaXRpb24nXS51cGRhdGUobWVtb192ZXJzaW9uPTIpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddLnVwZGF0ZShhY3Rvcj17J2tpbmQnOiAnYWdlbnQnLCAnc3ViJzogJ3BsYXRmb3JtLXJvb3QnfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ10uYXBwZW5kKGNvcHkuZGVlcGNvcHkob1snZGlzcG9zaXRpb25zJ11bMF0pKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShyLCBvKVxuICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyZWxlYXNlJywgTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwaXJlZF93aW5kb3dfYW5kX3Vua25vd25fcGhhc2VfcmVmdXNlKHNlbGYpOlxuICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgYXV0aG9yaXR5KHIsIG8sICdhJyAqIDY0LCBSRVZJU0lPTiwgJ2FyYml0cmFyeScsIE5PVylcbiAgICAgICAgbGF0ZSA9IGRhdGV0aW1lLmRhdGV0aW1lKDIwMjYsIDEwLCAxMywgdHppbmZvPWRhdGV0aW1lLnRpbWV6b25lLnV0YylcbiAgICAgICAgclsndmVyaWZpZWRfYXQnXSA9IGxhdGUuaXNvZm9ybWF0KClcbiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyb2xsYmFjaycsIGxhdGUpXG5cbiAgICBkZWYgdGVzdF9kdXJhYmxlX2ludGVudF9wcmVjZWRlc19kaXNwYXRjaF9hbmRfbmV2ZXJfcmV0cmllcyhzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQgPSBQYXRoKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIG9zLmNobW9kKHBhcmVudCwgMG83MDApXG4gICAgICAgICAgICBqb3VybmFsID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICBqb3VybmFsLnN0YXJ0KCdkcmlsbC1iYWNrdXAnLCB7J2FwcHJvdmFsX2lkJzogJ2ZpeHR1cmUnfSlcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoanNvbi5sb2Fkcyhqb3VybmFsLnBhdGgucmVhZF90ZXh0KCkpWydwaGFzZXMnXVsnZHJpbGwtYmFja3VwJ11bJ3N0YXRlJ10sICdSVU5OSU5HJylcbiAgICAgICAgICAgIGpvdXJuYWwuY2xvc2UoKSAgIyBzaW11bGF0ZWQgY3Jhc2ggYmVmb3JlIHJlc3VsdFxuICAgICAgICAgICAgcmVjb3ZlcmVkID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtYmFja3VwJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtY29weScsIHt9KVxuICAgICAgICAgICAgcmVjb3ZlcmVkLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X3BoYXNlX29yZGVyX2FuZF91bmNlcnRhaW5fcmVsZWFzZV9hbGxvd3Nfb25seV9kaXN0aW5jdF9yZWNvdmVyeShzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBvcy5jaG1vZChkaXJlY3RvcnksIDBvNzAwKVxuICAgICAgICAgICAgaiA9IEpvdXJuYWwoZGlyZWN0b3J5LCB7J2Nhc2UnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICBmb3IgcGhhc2UgaW4gYWN0dWF0b3IuUEhBU0VTWzo2XTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KHBoYXNlLCB7fSlcbiAgICAgICAgICAgICAgICBqLmZpbmlzaChwaGFzZSwgeydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlfSlcbiAgICAgICAgICAgIGouc3RhcnQoJ3JlbGVhc2UnLCB7fSlcbiAgICAgICAgICAgIGouZmluaXNoKCdyZWxlYXNlJywgeydhbGxfY2hlY2tzX3Bhc3MnOiBGYWxzZX0pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGouc3RhcnQoJ3JlbGVhc2UnLCB7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgai5zdGFydCgndmVyaWZ5Jywge30pXG4gICAgICAgICAgICBqLnN0YXJ0KCdyb2xsYmFjaycsIHt9KVxuICAgICAgICAgICAgai5maW5pc2goJ3JvbGxiYWNrJywgeydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlfSlcbiAgICAgICAgICAgIGouY2xvc2UoKVxuXG4gICAgZGVmIHRlc3Rfc2VjcmV0X29yX3Vua25vd25fY2hpbGRfb3V0cHV0X2lzX3dpdGhoZWxkKHNlbGYpOlxuICAgICAgICBmb3IgYm9keSBpbiAoJ25vdC1qc29uJywgJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJ0b2tlblwiOlwicHJpdmF0ZS12YWx1ZVwifScsXG4gICAgICAgICAgICAgICAgICAgICAne1wiYWxsX2NoZWNrc19wYXNzXCI6dHJ1ZSxcInNuYXBzaG90X3JlYWRvbmx5XCI6e1wic2NoZW1hX3ZlcnNpb25cIjo1fX0nKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgYWN0dWF0b3IuanNvbl9yZXN1bHQoc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBib2R5LCAnJykpXG4gICAgICAgIHdyb25nID0gY29weS5kZWVwY29weShDT1VOVClcbiAgICAgICAgd3JvbmdbJ291dGJveCddID0geydwcml2YXRlLXJvdy12YWx1ZSc6IDF9XG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICBjb3VudHMod3JvbmcpXG4gICAgICAgIGNvdW50cyhDT1VOVCkgICMgYmxvY2tlZC91bnJlc29sdmVkIGNvdW50cyBhcmUgbm90IHJlcXVpcmVkIHRvIGJlIHplcm8uXG5cbiAgICBkZWYgdGVzdF9iaW5hcnlfY29weV9pc19ib3VuZGVkX3ByaXZhdGVfYW5kX25ldmVyX2VjaG9lZChzZWxmKTpcbiAgICAgICAgYmxvYiA9IGInc3ludGhldGljIHByaXZhdGUgZml4dHVyZSBieXRlcydcbiAgICAgICAgZGlnZXN0ID0gX19pbXBvcnRfXygnaGFzaGxpYicpLnNoYTI1NihibG9iKS5oZXhkaWdlc3QoKVxuICAgICAgICBtZXRhZGF0YSA9IHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ3NuYXBzaG90X2ZpbGUnOiAnZHJpbGwuc3FsaXRlJywgJ3NuYXBzaG90X2J5dGVzJzogbGVuKGJsb2IpLFxuICAgICAgICAgICAgICAgICAgICAnc25hcHNob3Rfc2hhMjU2JzogZGlnZXN0LCAnc25hcHNob3RfcmVhZG9ubHknOiBDT1VOVCxcbiAgICAgICAgICAgICAgICAgICAgJ3BvZF9uYW1lJzogJ2ZpeHR1cmUtcG9kJywgJ3BvZF91aWQnOiAnZml4dHVyZS11aWQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7J2RyaWxsLWJhY2t1cCc6IHsncmVzdWx0JzogbWV0YWRhdGF9fX19KSgpXG4gICAgICAgIHJlYWxfcG9wZW4gPSBzdWJwcm9jZXNzLlBvcGVuXG4gICAgICAgIGZvciBleHRyYSBpbiAoYicnLCBiJ292ZXJzaXplZCcpOlxuICAgICAgICAgICAgd2l0aCBzZWxmLnN1YlRlc3QoZXh0cmE9ZXh0cmEpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBmb2xkZXI6XG4gICAgICAgICAgICAgICAgb3MuY2htb2QoZm9sZGVyLCAwbzcwMClcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSBpby5TdHJpbmdJTygpXG5cbiAgICAgICAgICAgICAgICBkZWYgY2hpbGQoKmFyZ3MsICoqa3dhcmdzKTpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWxfcG9wZW4oW3N5cy5leGVjdXRhYmxlLCAnLWMnLCAnaW1wb3J0IHN5cztzeXMuc3Rkb3V0LmJ1ZmZlci53cml0ZSgnICsgcmVwcihibG9iICsgZXh0cmEpICsgJyknXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTClcblxuICAgICAgICAgICAgICAgIHdpdGggcGF0Y2gub2JqZWN0KGFjdHVhdG9yLCAnQ1VTVE9EWScsIFBhdGgoZm9sZGVyKSksIHBhdGNoLm9iamVjdChhY3R1YXRvciwgJ3JlbW90ZScsIHJldHVybl92YWx1ZT1tZXRhZGF0YSksIFxcXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRjaCgnc3VicHJvY2Vzcy5Qb3BlbicsIHNpZGVfZWZmZWN0PWNoaWxkKSwgcmVkaXJlY3Rfc3Rkb3V0KG91dHB1dCk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGV4dHJhOlxuICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YXRvci5jb3B5X3NuYXBzaG90KCdkcmlsbC1jb3B5JywgUkVWSVNJT04sIHt9LCBqb3VybmFsKVxuICAgICAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYWN0dWF0b3IuY29weV9zbmFwc2hvdCgnZHJpbGwtY29weScsIFJFVklTSU9OLCB7fSwgam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29mZl9jbHVzdGVyX3ByaXZhdGVfY29weV92ZXJpZmllZCddKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoUGF0aChmb2xkZXIpIC8gJ2RyaWxsLnNxbGl0ZScpLnJlYWRfYnl0ZXMoKSwgYmxvYilcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG91dHB1dC5nZXR2YWx1ZSgpLCAnJylcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKChQYXRoKGZvbGRlcikgLyAnZHJpbGwuc3FsaXRlJykuc3RhdCgpLnN0X21vZGUgJiAwbzc3NywgMG82MDApXG5cbiAgICBkZWYgdGVzdF9yZWNyZWF0ZWRfb2ZmbGluZV92b2x1bWVfY2Fubm90X2JlX2RlbGV0ZWQoc2VsZik6XG4gICAgICAgIGlkZW50aXR5ID0geydOYW1lJzogYWN0dWF0b3IuVk9MVU1FLCAnTGFiZWxzJzogeydub25jZSc6ICdvbGQnfSwgJ0NyZWF0ZWRBdCc6ICdvbGQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7XG4gICAgICAgICAgICAnb2ZmbGluZS12ZXJpZnknOiB7J3Jlc3VsdCc6IHsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknOiBpZGVudGl0eX19fX19KSgpXG4gICAgICAgIGluc3BlY3RlZCA9IFt7KippZGVudGl0eSwgJ0NyZWF0ZWRBdCc6ICdyZWNyZWF0ZWQnfV1cbiAgICAgICAgd2l0aCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdkb2NrZXInLCByZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBqc29uLmR1bXBzKGluc3BlY3RlZCksICcnKSkgYXMgbW9ja2VkOlxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBhY3R1YXRvci5jbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobW9ja2VkLmNhbGxfY291bnQsIDEpXG5cbiAgICBkZWYgdGVzdF9vZmZsaW5lX3Bvc3RfYWRtaW5faW50ZWdyaXR5X2FuZF9vcmlnaW5hbF9oYXNoX2FyZV9yZWNoZWNrZWQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdub25lJywgJ3Bvc3QtaW50ZWdyaXR5JywgJ29yaWdpbmFsLWhhc2gnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgZm9sZGVyPVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChmb2xkZXIsMG83MDApXG4gICAgICAgICAgICAgICAgc25hcHNob3Q9Zm9sZGVyLydkcmlsbC5zcWxpdGUnO3NuYXBzaG90LndyaXRlX2J5dGVzKGIncHJpdmF0ZSBzeW50aGV0aWMgc25hcHNob3QnKTtvcy5jaG1vZChzbmFwc2hvdCwwbzYwMClcbiAgICAgICAgICAgICAgICBkaWdlc3Q9YWN0dWF0b3Iuc2hhKHNuYXBzaG90KVxuICAgICAgICAgICAgICAgIHByaW9yPXsnc25hcHNob3Rfc2hhMjU2JzpkaWdlc3QsJ3NuYXBzaG90X3JlYWRvbmx5JzpDT1VOVH1cbiAgICAgICAgICAgICAgICBqb3VybmFsPXR5cGUoJ0ZpeHR1cmVKb3VybmFsJywoKSx7J2RhdGEnOnsncGhhc2VzJzp7J2RyaWxsLWNvcHknOnsncmVzdWx0Jzpwcmlvcn0sJ29mZmxpbmUtdmVyaWZ5Jzp7J2F0dGVtcHRfaWQnOidub25jZSd9fX0sJ25vdGUnOmxhbWJkYSAqYXJnczpOb25lfSkoKVxuICAgICAgICAgICAgICAgIHJlYWRzPVtdXG4gICAgICAgICAgICAgICAgdm9sdW1lPXsnTmFtZSc6YWN0dWF0b3IuVk9MVU1FLCdMYWJlbHMnOnsnaW5mb3JtZWQtZGVjaXNpb24uY2FzZSc6J2luZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsJ2luZm9ybWVkLWRlY2lzaW9uLnVzZSc6J29mZmxpbmUtcmVzdG9yZS1vbmx5JywnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdCc6J25vbmNlJ30sJ0RyaXZlcic6J2xvY2FsJywnU2NvcGUnOidsb2NhbCcsJ0NyZWF0ZWRBdCc6J2ZpeHR1cmUnLCdPcHRpb25zJzpOb25lfVxuICAgICAgICAgICAgICAgIGRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCAqKmt3YXJncyk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGFyZ3ZbMF09PSdpbmZvJzpib2R5PWpzb24uZHVtcHMoJ2JudC1sYXAwMDEnKVxuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2xzJ106Ym9keT0nJ1xuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2NyZWF0ZSddOmJvZHk9YWN0dWF0b3IuVk9MVU1FXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgYXJndls6Ml09PVsndm9sdW1lJywnaW5zcGVjdCddOmJvZHk9anNvbi5kdW1wcyhbdm9sdW1lXSlcbiAgICAgICAgICAgICAgICAgICAgZWxpZiAnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4nIGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5PWpzb24uZHVtcHMoe2tleTpDT1VOVFtrZXldIGZvciBrZXkgaW4gKCdzY2hlbWFfdmVyc2lvbicsJ2xpZmVjeWNsZScsJ291dGJveCcsJ3N1Ym1pc3Npb25zJyl9KVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgZGVmZWN0PT0nb3JpZ2luYWwtaGFzaCc6c25hcHNob3Qud3JpdGVfYnl0ZXMoYidjaGFuZ2VkIHN5bnRoZXRpYyBvcmlnaW5hbCcpXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgJy0tZW50cnlwb2ludCcgaW4gYXJndiBhbmQgJ3B5dGhvbicgaW4gYXJndjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRzLmFwcGVuZChhcmd2KTtwcm9vZj1jb3B5LmRlZXBjb3B5KENPVU5UKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKHJlYWRzKT09MiBhbmQgZGVmZWN0PT0ncG9zdC1pbnRlZ3JpdHknOnByb29mWydpbnRlZ3JpdHknXT0nY29ycnVwdCdcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk9anNvbi5kdW1wcyhwcm9vZilcbiAgICAgICAgICAgICAgICAgICAgZWxzZTpyYWlzZSBBc3NlcnRpb25FcnJvcigndW5leHBlY3RlZCBvZmZsaW5lIGNvbW1hbmQnKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsMCxib2R5LCcnKVxuICAgICAgICAgICAgICAgIHdpdGggcGF0Y2gub2JqZWN0KGFjdHVhdG9yLCdDVVNUT0RZJyxmb2xkZXIpLHBhdGNoLm9iamVjdChhY3R1YXRvciwnQ0FTRScsQ0FTRSkscGF0Y2gub2JqZWN0KGFjdHVhdG9yLCdkb2NrZXInLHNpZGVfZWZmZWN0PWRvY2tlcikscGF0Y2goJ3N1YnByb2Nlc3MucnVuJyxyZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLDAsJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJwcml2YXRlX2NvcHlfdmVyaWZpZWRcIjp0cnVlfScsJycpKTpcbiAgICAgICAgICAgICAgICAgICAgaWYgZGVmZWN0PT0nbm9uZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ9YWN0dWF0b3Iub2ZmbGluZV92ZXJpZnkoam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydvZmZsaW5lX3Bvc3RfYWRtaW5fcmVhZG9ubHknXSxDT1VOVClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29yaWdpbmFsX3NuYXBzaG90X2hhc2hfdW5jaGFuZ2VkJ10pXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmFjdHVhdG9yLm9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVhZHMpLDIpXG5cblxuY2xhc3MgRml4ZWROYXRpdmVQcm9ncmFtKHVuaXR0ZXN0LlRlc3RDYXNlKTpcbiAgICBkZWYgZml4dHVyZShzZWxmKTpcbiAgICAgICAgc2VhbGVkID0ganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgbGl2ZSA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKVxuICAgICAgICBsaXZlWydtZXRhZGF0YSddLnVwZGF0ZShnZW5lcmF0aW9uPTQyKVxuICAgICAgICBsaXZlWydzdGF0dXMnXSA9IHsncmVhZHlSZXBsaWNhcyc6IDEsICd1cGRhdGVkUmVwbGljYXMnOiAxLCAnb2JzZXJ2ZWRHZW5lcmF0aW9uJzogNDJ9XG4gICAgICAgIGRlcGVuZGVuY2llcyA9IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLW5hdGl2ZS1kZXBlbmRlbmNpZXMuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBjbSA9IGNvcHkuZGVlcGNvcHkoZGVwZW5kZW5jaWVzWydjb25maWdtYXAnXSlcbiAgICAgICAgY20ucG9wKCdjYW5vbmljYWxfZGF0YV9zaGEyNTYnKVxuICAgICAgICBzZXJ2aWNlID0ganNvbi5sb2FkcygoQ0FTRSAvICdjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgICAgIHNvdXJjZV9zZXJ2aWNlID0ganNvbi5sb2FkcygoQ0FTRS5wYXJlbnRzWzJdIC8gJ2RlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBjbVsnZGF0YSddID0gbmV4dCh4IGZvciB4IGluIHNvdXJjZV9zZXJ2aWNlWydpdGVtcyddIGlmIHhbJ2tpbmQnXSA9PSAnQ29uZmlnTWFwJylbJ2RhdGEnXVxuICAgICAgICBwdmMgPSBjb3B5LmRlZXBjb3B5KGRlcGVuZGVuY2llc1sncHZjJ10pXG4gICAgICAgIHB2Y1snc3RhdHVzJ10gPSB7J3BoYXNlJzogJ0JvdW5kJ31cbiAgICAgICAgYXBwID0geydtZXRhZGF0YSc6IHsndWlkJzogJzQ5OTg2OGYyLWVhYmMtNGRmNC1hZTMxLWI4OWNlNThkNzUwZCcsICdyZXNvdXJjZVZlcnNpb24nOiAnMTcnfSxcbiAgICAgICAgICAgICAgICdzcGVjJzogeydzb3VyY2UnOiB7J3JlcG9VUkwnOiAnaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhdGgnOiAnZGVwbG95L2xpZmVjeWNsZScsICd0YXJnZXRSZXZpc2lvbic6ICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGVzdGluYXRpb24nOiB7J25hbWVzcGFjZSc6ICdpbmZvcm1lZC1kZWNpc2lvbicsICdzZXJ2ZXInOiAnaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjJ319fVxuICAgICAgICBvYmplY3RzID0geydkZXBsb3ltZW50JzogbGl2ZSwgJ2NvbmZpZ21hcCc6IGNtLCAncHZjJzogcHZjLCAnYXBwbGljYXRpb24nOiBhcHB9XG4gICAgICAgIHBheWxvYWQgPSB7J3BoYXNlJzogJ3JlbGVhc2UnLCAnc291cmNlX3JldmlzaW9uJzogUkVWSVNJT04sICdhcHByb3ZhbCc6IHt9LCAnc2VhbGVkJzogc2VhbGVkLFxuICAgICAgICAgICAgICAgICAgICdkZXBlbmRlbmNpZXMnOiBkZXBlbmRlbmNpZXMsICdjYW5kaWRhdGUnOiBzZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICdyb2xsYmFjayc6IGpzb24ubG9hZHMoKENBU0UgLyAncm9sbGJhY2stZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgICAgICdyZWFkb25seSc6IChDQVNFIC8gJ3NxbGl0ZV9yZWFkb25seS5weScpLnJlYWRfdGV4dCgpLCdwdXJwb3NlX2NoZWNrcyc6KENBU0UvJ2NoZWNrX2luc3RhbGxlZC5weScpLnJlYWRfdGV4dCgpLFxuICAgICAgICAgICAgICAgICAgICdyZWNlaXB0X3NhZmV0eSc6IChQYXRoKF9fZmlsZV9fKS5wYXJlbnQgLyAncmVjZWlwdF9zYWZldHkucHknKS5yZWFkX3RleHQoKX1cbiAgICAgICAgcmV0dXJuIG9iamVjdHMsIHBheWxvYWRcblxuICAgIGRlZiBleGVjdXRlX2Zha2Uoc2VsZiwgb2JqZWN0cywgcGF5bG9hZCwgYW1iaWd1b3VzPUZhbHNlLCBzY2hlbWFfcmVmdXNlZD1GYWxzZSk6XG4gICAgICAgIHdyaXRlcyA9IFtdXG4gICAgICAgIGNhbGxzID0gW11cblxuICAgICAgICBkZWYgZmFrZShhcmd2LCBpbnB1dD1Ob25lLCAqKmt3YXJncyk6XG4gICAgICAgICAgICBjYWxscy5hcHBlbmQoYXJndilcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdnZXQnXTpcbiAgICAgICAgICAgICAgICBraW5kID0gYXJndlsyXVxuICAgICAgICAgICAgICAgIGlmIGtpbmQgaW4gb2JqZWN0czpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IG9iamVjdHNba2luZF1cbiAgICAgICAgICAgICAgICBlbGlmIGtpbmQgPT0gJ3BvZHMnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydpdGVtcyc6IFt7J21ldGFkYXRhJzogeyduYW1lJzogJ2ZpeHR1cmUtcG9kJywgJ3VpZCc6ICdwb2QtdWlkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvd25lclJlZmVyZW5jZXMnOiBbeydraW5kJzogJ1JlcGxpY2FTZXQnLCAnbmFtZSc6ICdmaXh0dXJlLXJzJywgJ3VpZCc6ICdycy11aWQnfV19LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BlYyc6IG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3BlYyddWyd0ZW1wbGF0ZSddWydzcGVjJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdGF0dXMnOiB7J3BoYXNlJzogJ1J1bm5pbmcnLCAnY29udGFpbmVyU3RhdHVzZXMnOiBbeyduYW1lJzonaW5mb3JtZWQtZGVjaXNpb24nLCdyZWFkeSc6IFRydWV9XX19XX1cbiAgICAgICAgICAgICAgICBlbGlmIGtpbmQgPT0gJ3JlcGxpY2FzZXQnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydtZXRhZGF0YSc6IHsndWlkJzogJ3JzLXVpZCcsICdvd25lclJlZmVyZW5jZXMnOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7J2tpbmQnOiAnRGVwbG95bWVudCcsICd1aWQnOiBwYXlsb2FkWydzZWFsZWQnXVsnbWV0YWRhdGEnXVsndWlkJ119XX19XG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdub2Rlcyc6XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSB7J2l0ZW1zJzogW3snbWV0YWRhdGEnOiB7J25hbWUnOiAnZml4dHVyZS1ub2RlJ30sICdzdGF0dXMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnYWRkcmVzc2VzJzogW3snYWRkcmVzcyc6ICc5Mi4yMDUuNjIuMjM5J31dLCAnYWxsb2NhdGFibGUnOiB7J2NwdSc6ICc0J30sXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZGl0aW9ucyc6IFt7J3R5cGUnOiBrZXksICdzdGF0dXMnOiAnVHJ1ZScgaWYga2V5ID09ICdSZWFkeScgZWxzZSAnRmFsc2UnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIGtleSBpbiAoJ1JlYWR5JywgJ01lbW9yeVByZXNzdXJlJywgJ0Rpc2tQcmVzc3VyZScsICdQSURQcmVzc3VyZScpXX19XX1cbiAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICByYWlzZSBBc3NlcnRpb25FcnJvcigndW5leHBlY3RlZCBmaXhlZCBtZXRhZGF0YSByb3V0ZScpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKGJvZHkpLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdleGVjJ106XG4gICAgICAgICAgICAgICAgaWYgc2NoZW1hX3JlZnVzZWQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJycsICd3aXRoaGVsZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKHtcbiAgICAgICAgICAgICAgICAgICAgJ2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdsaXZlX3JlYWRvbmx5X3NjaGVtYV9pbnRlZ3JpdHlfY291bnRzJzogQ09VTlR9KSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnYXBwbHknXTpcbiAgICAgICAgICAgICAgICBhZG1pdHRlZCA9IGNvcHkuZGVlcGNvcHkocGF5bG9hZFsnc2VhbGVkJ10pXG4gICAgICAgICAgICAgICAgYWRtaXR0ZWRbJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSAoYWN0dWF0b3IuSU1BR0UgaWYgcGF5bG9hZFsncGhhc2UnXT09J3JlbGVhc2UnIGVsc2UgcGF5bG9hZFsnc2VhbGVkJ11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKGFkbWl0dGVkKSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZGVzY3JpYmUnXTpcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDAsICdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcbiBjcHUgMzQ2MG0gKDg2JSlcXG4nLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdkaWZmJ106XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAxLCAnLWltYWdlOiBiYXNlXFxuK2ltYWdlOiBjYW5kaWRhdGVcXG4nLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdwYXRjaCddOlxuICAgICAgICAgICAgICAgIGlmICctLWRyeS1ydW49c2VydmVyJyBub3QgaW4gYXJndjpcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVzLmFwcGVuZChqc29uLmxvYWRzKGlucHV0KSlcbiAgICAgICAgICAgICAgICAgICAgaWYgYW1iaWd1b3VzOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAxLCAnJywgJ3dpdGhoZWxkJylcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDAsICdhcHBsaWNhdGlvbi5hcmdvcHJvai5pby9pbmZvcm1lZC1kZWNpc2lvblxcbicsICcnKVxuICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgY29tbWFuZCcpXG5cbiAgICAgICAgc291cmNlID0gUFJPR1JBTS5yZXBsYWNlKCdfX1BBWUxPQURfXycsIHJlcHIoanNvbi5kdW1wcyhwYXlsb2FkKSkpLnJlcGxhY2UoXG4gICAgICAgICAgICAnX19HVUFSRF9fJywgcmVwcigoQ0FTRSAvICdjaGFuZ2VfZ3VhcmQucHknKS5yZWFkX3RleHQoKSkpXG4gICAgICAgIG91dHB1dCA9IGlvLlN0cmluZ0lPKClcbiAgICAgICAgd2l0aCBwYXRjaCgnc3VicHJvY2Vzcy5ydW4nLCBzaWRlX2VmZmVjdD1mYWtlKSwgcmVkaXJlY3Rfc3Rkb3V0KG91dHB1dCk6XG4gICAgICAgICAgICB0cnk6XG4gICAgICAgICAgICAgICAgZXhlYyhjb21waWxlKHNvdXJjZSwgJ2ZpeGVkLW5hdGl2ZS1maXh0dXJlJywgJ2V4ZWMnKSwgeydfX25hbWVfXyc6ICdfX2ZpeHR1cmVfXyd9KVxuICAgICAgICAgICAgZXhjZXB0IChWYWx1ZUVycm9yLCBTeXN0ZW1FeGl0KTpcbiAgICAgICAgICAgICAgICBwYXNzXG4gICAgICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKG91dHB1dC5nZXR2YWx1ZSgpKSBpZiBvdXRwdXQuZ2V0dmFsdWUoKSBlbHNlIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2V9XG4gICAgICAgIHJldHVybiByZWNlaXB0LCB3cml0ZXMsIGNhbGxzXG5cbiAgICBkZWYgdGVzdF9vbmx5X2V4aXN0aW5nX2FwcGxpY2F0aW9uX29wZXJhdGlvbl9hbmRfZGVwbG95bWVudF9hcmVfcmVxdWVzdGVkKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0Wydyb2xsb3V0X3ZlcmlmaWVkJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHdyaXRlcyksIDEpXG4gICAgICAgIG9wZXJhdGlvbiA9IHdyaXRlc1swXVstMV1bJ3ZhbHVlJ11cbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShvcGVyYXRpb25bJ3N5bmMnXVsncHJ1bmUnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChvcGVyYXRpb25bJ3N5bmMnXVsncmVzb3VyY2VzJ10sIFtcbiAgICAgICAgICAgIHsnZ3JvdXAnOiAnYXBwcycsICdraW5kJzogJ0RlcGxveW1lbnQnLCAnbmFtZSc6ICdpbmZvcm1lZC1kZWNpc2lvbicsICduYW1lc3BhY2UnOiAnaW5mb3JtZWQtZGVjaXNpb24nfV0pXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShhbnkoJy0tZHJ5LXJ1bj1zZXJ2ZXInIGluIGFyZ3YgYW5kIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdwYXRjaCddIGZvciBhcmd2IGluIGNhbGxzKSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXNbMF1bMF1bJ3BhdGgnXSwgJy9tZXRhZGF0YS91aWQnKVxuXG4gICAgZGVmIHRlc3Rfc291cmNlX292ZXJyaWRlc19hdXRvbWF0aW9uX2FuZF9jdXN0b2R5X2RyaWZ0X3N0b3BfYmVmb3JlX3dyaXRlKHNlbGYpOlxuICAgICAgICBtdXRhdGlvbnMgPSBbbGFtYmRhIG86IG9bJ2FwcGxpY2F0aW9uJ11bJ21ldGFkYXRhJ10udXBkYXRlKHVpZD0ncmVjcmVhdGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddLnVwZGF0ZShzeW5jUG9saWN5PXsnYXV0b21hdGVkJzoge319KSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydzcGVjJ11bJ3NvdXJjZSddLnVwZGF0ZShrdXN0b21pemU9eydpbWFnZXMnOiBbJ290aGVyJ119KSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydzcGVjJ10udXBkYXRlKHNvdXJjZXM9W3t9XSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snY29uZmlnbWFwJ11bJ21ldGFkYXRhJ10udXBkYXRlKHVpZD0ncmVjcmVhdGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1sncHZjJ11bJ3NwZWMnXS51cGRhdGUodm9sdW1lTmFtZT0ncmVwbGFjZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydkZXBsb3ltZW50J11bJ3N0YXR1cyddLnVwZGF0ZShyZWFkeVJlcGxpY2FzPTApXVxuICAgICAgICBmb3IgbXV0YXRlIGluIG11dGF0aW9uczpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KG11dGF0ZT1tdXRhdGUpOlxuICAgICAgICAgICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShvYmplY3RzKVxuICAgICAgICAgICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuXG4gICAgZGVmIHRlc3RfcHJlb3Blbl9zY2hlbWFfcmVmdXNhbF9wcmV2ZW50c19pbWFnZV9vcGVyYXRpb24oc2VsZik6XG4gICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZCwgc2NoZW1hX3JlZnVzZWQ9VHJ1ZSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuXG5cbiAgICBkZWYgdGVzdF9yb2xsYmFja191bnJlYWR5X2NhbmRpZGF0ZV9uZXZlcl9yZWFkc19wb2Rfb3JfZGF0YWJhc2Uoc2VsZik6XG4gICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICBwYXlsb2FkWydwaGFzZSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddLnVwZGF0ZShyZWFkeVJlcGxpY2FzPTAsIHVwZGF0ZWRSZXBsaWNhcz0wKVxuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSBhY3R1YXRvci5JTUFHRVxuICAgICAgICBvYmplY3RzWydhcHBsaWNhdGlvbiddWydzcGVjJ11bJ3NvdXJjZSddWyd0YXJnZXRSZXZpc2lvbiddID0gUkVWSVNJT05cbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIHNjaGVtYV9yZWZ1c2VkPVRydWUpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0Wydyb2xsb3V0X3ZlcmlmaWVkJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHdyaXRlcyksIDEpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UoYW55KGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdleGVjJ10gb3IgYXJndls6M10gPT0gWydrdWJlY3RsJywgJ2dldCcsICdwb2RzJ10gZm9yIGFyZ3YgaW4gY2FsbHMpKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHdyaXRlc1swXVstMV1bJ3ZhbHVlJ11bJ3N5bmMnXVsncmV2aXNpb24nXSwgJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYnKVxuXG4gICAgZGVmIHRlc3Rfcm9sbGJhY2tfc3RpbGxfcmVmdXNlc19jdXN0b2R5X29yX25vbnBhaXJfaW1hZ2VfZHJpZnQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdjbScsICdwdmMnLCAnaW1hZ2UnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpOlxuICAgICAgICAgICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKTtwYXlsb2FkWydwaGFzZSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICAgICAgICAgIG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3RhdHVzJ11bJ3JlYWR5UmVwbGljYXMnXSA9IDBcbiAgICAgICAgICAgICAgICBpZiBkZWZlY3QgPT0gJ2NtJzpvYmplY3RzWydjb25maWdtYXAnXVsnbWV0YWRhdGEnXVsndWlkJ10gPSAncmVjcmVhdGVkJ1xuICAgICAgICAgICAgICAgIGVsaWYgZGVmZWN0ID09ICdwdmMnOm9iamVjdHNbJ3B2YyddWydzcGVjJ11bJ3ZvbHVtZU5hbWUnXSA9ICdyZXBsYWNlZCdcbiAgICAgICAgICAgICAgICBlbHNlOm9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3BlYyddWyd0ZW1wbGF0ZSddWydzcGVjJ11bJ2NvbnRhaW5lcnMnXVswXVsnaW1hZ2UnXSA9ICdmb3JlaWduLWltYWdlJ1xuICAgICAgICAgICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pO3NlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuICAgIGRlZiB0ZXN0X3JlY292ZXJ5X3ZlcmlmaWNhdGlvbl9pc19zZXBhcmF0ZV9yZWFkeV9vbGRfaW1hZ2Vfc2NoZW1hX3Byb29mKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKCk7cGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjay12ZXJpZnknXG4gICAgICAgIG9iamVjdHNbJ2FwcGxpY2F0aW9uJ11bJ3N0YXR1cyddID0geydvcGVyYXRpb25TdGF0ZSc6IHsncGhhc2UnOiAnU3VjY2VlZGVkJywgJ29wZXJhdGlvbic6IHsnc3luYyc6IHtcbiAgICAgICAgICAgICdyZXZpc2lvbic6ICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJywgJ3BydW5lJzogRmFsc2UsXG4gICAgICAgICAgICAncmVzb3VyY2VzJzogW3snZ3JvdXAnOidhcHBzJywna2luZCc6J0RlcGxveW1lbnQnLCduYW1lJzonaW5mb3JtZWQtZGVjaXNpb24nLCduYW1lc3BhY2UnOidpbmZvcm1lZC1kZWNpc2lvbid9XX19fX1cbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSk7c2VsZi5hc3NlcnRUcnVlKHJlY2VpcHRbJ3JlY292ZXJ5X3ZlcmlmaWNhdGlvbiddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHdyaXRlcywgW10pXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShhbnkoYXJndls6Ml09PVsna3ViZWN0bCcsJ2V4ZWMnXSBmb3IgYXJndiBpbiBjYWxscykpXG4gICAgICAgIG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3RhdHVzJ11bJ3JlYWR5UmVwbGljYXMnXSA9IDBcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMscGF5bG9hZClcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcblxuICAgIGRlZiB0ZXN0X2FtYmlndW91c19wYXRjaF9pc19uZXZlcl9yZXRyaWVkKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIGFtYmlndW91cz1UcnVlKVxuICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuXG5cbmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6XG4gICAgdW5pdHRlc3QubWFpbigpXG4iCiAgICB9LAogICAgInZhbGlkYXRpb24uanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIyNmM1YWNmYTZlMmVmNTkwOWZmOWYzZmM4MTljYTE3NjNiNzlmM2NiNjViM2M0MzM3MWY3OTQ0YTI4NGNkZTI4IiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInRlc3RzXCI6IDE2LFxuICBcInJlc3VsdFwiOiBcInBhc3NlZFwiLFxuICBcInN5bnRoZXRpY190cmFuc3BvcnRfb25seVwiOiB0cnVlLFxuICBcInJlYWxfbmF0aXZlX2RhdGFfcmVhZFwiOiBmYWxzZSxcbiAgXCJuYXRpdmVfYmFja3VwX2V4cG9ydF9yZXN0b3JlX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICBcIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkXCI6IGZhbHNlLFxuICBcImFjdHVhbF9mb3VuZGVyX2FwcHJvdmFsXCI6IGZhbHNlLFxuICBcImxvY2FsX3JlYWRfb25seV9jYXBhYmlsaXR5X2NoZWNrc1wiOiBbXG4gICAgXCJhcmdvY2RDTEkgYWJzZW50LCBleGlzdGluZ0FwcGxpY2F0aW9uLm9wZXJhdGlvbiBwYXRoIHJldGFpbmVkXCIsXG4gICAgXCJEb2NrZXJ1bml4c29ja2V0IGVuZ2luZU5hbWUgYm50LWxhcDAwMVwiXG4gIF0sXG4gIFwiY2FzZV9zb3VyY2VfY29tbWl0X2F0X3ByZXBhcmF0aW9uXCI6IFwiZTAzNTliYyAob3duZXIgb3JpZ2luYWw3OHNvdXJjZTsgZmluYWwgaGVscGVyY29tbWl0IG11c3RiZSBleHBsaWNpdGx5cGlubmVkKVwiLFxuICBcImFkZGl0aW9uYWxfcmVncmVzc2lvbnNcIjogW1xuICAgIFwiUmVhZHkwIGNhbmRpZGF0ZSByb2xsYmFjayBkaXNwYXRjaCBoYXMgbm8gUG9kIG1ldGFkYXRhL0RCIGV4ZWMgYW5kIG9uZSBzY29wZWQgQ0FTIG9wZXJhdGlvblwiLFxuICAgIFwicm9sbGJhY2sgc3RpbGwgcmVmdXNlcyBDTS9QVkMgb3Igbm9ucGFpci1pbWFnZSBkcmlmdFwiLFxuICAgIFwic2VwYXJhdGUgb2xkLWltYWdlIFJlYWR5L3NjaGVtYTUgcmVjb3ZlcnkgcHJvb2ZcIixcbiAgICBcInBvc3QtYWRtaW4gcmVhZG9ubHkgaW50ZWdyaXR5IHJlZnVzYWwgYW5kIG9yaWdpbmFsIHNuYXBzaG90IHRhbXBlciByZWZ1c2FsXCJcbiAgXVxufVxuIgogICAgfQogIH0sCiAgIm5hdGl2ZV9leGVjdXRpb24iOiBmYWxzZQp9Cg==" + }, + { + "digest": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "media_type": "text/plain", + "content_base64": "IiIiUHJlLW9wZW4gc2NoZW1hL2ludGVncml0eS9jb3VudCBwcm9vZjsgc3RkbGliIG9ubHksIG5ldmVyIGNvbnN0cnVjdHMgU3RvcmUuIiIiCmltcG9ydCBhcmdwYXJzZQppbXBvcnQganNvbgpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaW1wb3J0IHNxbGl0ZTMKCgpkZWYgaW5zcGVjdF9yZWFkb25seShwYXRoKToKICAgIHBhdGggPSBQYXRoKHBhdGgpCiAgICBpZiBub3QgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZXhpc3Rpbmcgbm9uc3ltbGluayBwcml2YXRlIGRhdGFiYXNlIHJlcXVpcmVkJykKICAgIHdpdGggc3FsaXRlMy5jb25uZWN0KHBhdGgucmVzb2x2ZSgpLmFzX3VyaSgpICsgJz9tb2RlPXJvJywgdXJpPVRydWUsIHRpbWVvdXQ9NSkgYXMgZGI6CiAgICAgICAgZGIuZXhlY3V0ZSgnUFJBR01BIHF1ZXJ5X29ubHk9T04nKQogICAgICAgIGRiLmV4ZWN1dGUoJ0JFR0lOJykKICAgICAgICB2ZXJzaW9uID0gZGIuZXhlY3V0ZSgnUFJBR01BIHVzZXJfdmVyc2lvbicpLmZldGNob25lKClbMF0KICAgICAgICBpZiB2ZXJzaW9uICE9IDU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3ByZS1vcGVuIGRhdGFiYXNlIGlzIG5vdCBzY2hlbWE1OyByZWZ1c2UgbWlncmF0aW9uJykKICAgICAgICBpZiBkYi5leGVjdXRlKCdQUkFHTUEgaW50ZWdyaXR5X2NoZWNrJykuZmV0Y2hhbGwoKSAhPSBbKCdvaycsKV06CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3JlYWQtb25seSBpbnRlZ3JpdHkgY2hlY2sgcmVmdXNlZCcpCiAgICAgICAgbGlmZWN5Y2xlID0ge25hbWU6IGRiLmV4ZWN1dGUoJ1NFTEVDVCBDT1VOVCgqKSBGUk9NICcgKyB0YWJsZSkuZmV0Y2hvbmUoKVswXQogICAgICAgICAgICAgICAgICAgICBmb3IgbmFtZSwgdGFibGUgaW4gKCgncmVjb3JkcycsICdsaWZlY3ljbGVfcmVjb3JkcycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgnZXZlbnRzJywgJ2xpZmVjeWNsZV9ldmVudHMnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJ3BlbmRpbmcnLCAnbGlmZWN5Y2xlX3BlbmRpbmcnKSl9CiAgICAgICAgcmVzdWx0ID0geydzY2hlbWFfdmVyc2lvbic6IHZlcnNpb24sICdsaWZlY3ljbGUnOiBsaWZlY3ljbGUsCiAgICAgICAgICAgICAgICAgICdvdXRib3gnOiBkaWN0KGRiLmV4ZWN1dGUoJ1NFTEVDVCBzdGF0ZSxDT1VOVCgqKSBGUk9NIG91dGJveCBHUk9VUCBCWSBzdGF0ZScpKSwKICAgICAgICAgICAgICAgICAgJ3N1Ym1pc3Npb25zJzogZGljdChkYi5leGVjdXRlKCdTRUxFQ1Qgc3RhdGUsQ09VTlQoKikgRlJPTSBzdWJtaXNzaW9ucyBHUk9VUCBCWSBzdGF0ZScpKSwKICAgICAgICAgICAgICAgICAgJ2ludGVncml0eSc6ICdvaycsICdyZWFkX29ubHlfcHJlX29wZW4nOiBUcnVlLCAnc3RvcmVfY29uc3RydWN0ZWQnOiBGYWxzZX0KICAgICAgICBkYi5yb2xsYmFjaygpCiAgICByZXR1cm4gcmVzdWx0CgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHBhcnNlciA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPV9fZG9jX18pCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWRiJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKICAgIHRyeToKICAgICAgICBwcmludChqc29uLmR1bXBzKGluc3BlY3RfcmVhZG9ubHkoYXJncy5kYiksIHNvcnRfa2V5cz1UcnVlKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmFpc2UgU3lzdGVtRXhpdCgncmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgcmVmdXNlZDsgbm8gU3RvcmUvYWRtaW4gb3BlbicpIGZyb20gTm9uZQo=" + }, + { + "digest": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "media_type": "application/json", + "content_base64": "ewogICJjb25maWdtYXAiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJ2MSIsCiAgICAiaW1tdXRhYmxlIjogdHJ1ZSwKICAgICJraW5kIjogIkNvbmZpZ01hcCIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOi9Db25maWdNYXA6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiLAogICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICB9LAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIsCiAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAidWlkIjogIjkwMTEzZDJkLTU0ZDktNGU4Mi1iMWQzLTkwYjQ5ZWJlZDJiNSIKICAgIH0sCiAgICAiY2Fub25pY2FsX2RhdGFfc2hhMjU2IjogIjhlYzQ2MmQxMjM0NzU0OGY1MDZlZWViZjFlM2M3Y2M0NzY0ODAxOWM4YTc4MzgwNGQwOWJjYzc5YjBmMjJhZjYiCiAgfSwKICAicHZjIjogewogICAgImFwaVZlcnNpb24iOiAidjEiLAogICAgImtpbmQiOiAiUGVyc2lzdGVudFZvbHVtZUNsYWltIiwKICAgICJtZXRhZGF0YSI6IHsKICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICJhcmdvY2QuYXJnb3Byb2ouaW8vdHJhY2tpbmctaWQiOiAiaW5mb3JtZWQtZGVjaXNpb246L1BlcnNpc3RlbnRWb2x1bWVDbGFpbTppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIsCiAgICAgICAgInB2Lmt1YmVybmV0ZXMuaW8vYmluZC1jb21wbGV0ZWQiOiAieWVzIiwKICAgICAgICAicHYua3ViZXJuZXRlcy5pby9ib3VuZC1ieS1jb250cm9sbGVyIjogInllcyIsCiAgICAgICAgInZvbHVtZS5iZXRhLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiLAogICAgICAgICJ2b2x1bWUua3ViZXJuZXRlcy5pby9zZWxlY3RlZC1ub2RlIjogIjIzOS42Mi4yMDUuOTIuaG9zdC5zZWN1cmVzZXJ2ZXIubmV0IiwKICAgICAgICAidm9sdW1lLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiCiAgICAgIH0sCiAgICAgICJmaW5hbGl6ZXJzIjogWwogICAgICAgICJrdWJlcm5ldGVzLmlvL3B2Yy1wcm90ZWN0aW9uIgogICAgICBdLAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICJ1aWQiOiAiZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfSwKICAgICJzcGVjIjogewogICAgICAiYWNjZXNzTW9kZXMiOiBbCiAgICAgICAgIlJlYWRXcml0ZU9uY2UiCiAgICAgIF0sCiAgICAgICJyZXNvdXJjZXMiOiB7CiAgICAgICAgInJlcXVlc3RzIjogewogICAgICAgICAgInN0b3JhZ2UiOiAiMUdpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInN0b3JhZ2VDbGFzc05hbWUiOiAibG9jYWwtcGF0aCIsCiAgICAgICJ2b2x1bWVNb2RlIjogIkZpbGVzeXN0ZW0iLAogICAgICAidm9sdW1lTmFtZSI6ICJwdmMtZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfQogIH0sCiAgInB2Y19waGFzZSI6ICJCb3VuZCIKfQo=" + }, + { + "digest": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478", + "media_type": "text/markdown", + "content_base64": "IyBQcm90ZWN0ZWQgbmF0aXZlIGJhY2t1cC9yZXN0b3JlIGFuZCBpbWFnZS1vbmx5IHJlbGVhc2UgcHJvdG9jb2wKClByZXBhcmVkIHByb3RvY29sIGZvciBgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFgLiBObyBhY3R1YWwgbmF0aXZlIGJhY2t1cCwgZGF0YSBleHBvcnQsIHJlc3RvcmUsIHdvcmtsb2FkIGNoYW5nZSBvciBhcHByb3ZhbCBpcyByZWNvcmRlZCBoZXJlLiBDYW5kaWRhdGUgcmVnaXN0cnkgaW1hZ2UgaWRlbnRpdHkgcmVtYWlucyBhIHByZXJlcXVpc2l0ZTsgb25seSBhZnRlciBhY3R1YWwgYXJ0aWZhY3QgcHJvb2YgbWF5IHRoZSBmb3VuZGVyIGFwcHJvdmUgb25lIGV4YWN0IGNvbmRpdGlvbmFsIHByb3RvY29sL3JvbGxvdXQgcGFja2V0LiBUaGUgY29uZmlnLW9ubHk3ZGI4NDg1IGFwcHJvdmFsIGlzIG91dHNpZGUgdGhpcyBzY29wZS4KCiMjIFByZWNvbmRpdGlvbnMgYW5kIHByb3RlY3RlZCBjdXN0b2R5CgpGcmVlemUgZXhhY3QgY2FuZGlkYXRlIGFuZCBwcmlvcjdmNWM2Y2IgaW1hZ2UgZGlnZXN0cywgc291cmNlL2luc3RhbGxlZCBwb2xpY3kgaGFzaGVzLCBjdXJyZW50IG1hbnVhbGx5IG1hbmFnZWQgQXJnbyBBcHBsaWNhdGlvbi9yZXZpc2lvbiwgcnVudGltZSBDb25maWdNYXA2YzIyMTg3OGQwNTEsIERlcGxveW1lbnQgVUlEL3RlbXBsYXRlL3NwZWMsIHNjaGVtYTUsIHBvbGljeSBwYWNrYWdlIHBpbnMsIGRhdGFiYXNlIHBhdGggYC9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZWAsIFBWQyBiaW5kaW5nLCByZXBsaWNhczEvUmVjcmVhdGUgYW5kIHN0YWJsZSBrZXlzIGZvciBpbnRlbmRlZCB2ZXJpZmljYXRpb24uIENvbmZpcm0gbm8gY29uY3VycmVudCB3cml0ZXIgb3IgY3VzdG9keSBjaGFuZ2UuIFVzZSBmaXhlZCBtZXRhZGF0YTsgbmV2ZXIgZmV0Y2ggU2VjcmV0IG9iamVjdHMgb3IgdG9rZW4gdmFsdWVzLiBBIGNoYW5nZWQgaW1hZ2UvY29uZmlnL3NjaGVtYS9vd25lciBpbnZhbGlkYXRlcyB0aGUgcGFja2V0LiBGcmVzaCByZXNvdXJjZXMvaGVhZHJvb20gYW5kIGV4YWN0IHNvdXJjZS9uYXRpdmUgc2VydmVyLWRyeS1ydW4vZGlmZiByZW1haW4gcmVxdWlyZWQuCgpCYWNrdXBzIGFyZSBwcml2YXRlIGV2aWRlbmNlIGNvbnRhaW5pbmcgcmVhbCBkZWNpc2lvbiByZWNvcmRzLCBub3QgbG9ncyBvciBwYWNrZXQgYXR0YWNobWVudHMuIEFsbG9jYXRlIGEgdW5pcXVlIGJhY2t1cCBkaXJlY3RvcnkgdW5kZXIgZXhpc3RpbmcgcHJvdGVjdGVkIFBWQyBjdXN0b2R5LCBvd25lZDEwMDAxLCBtb2RlMDcwMCwgc25hcHNob3QgZmlsZTA2MDAsIG5vIHN5bWxpbmsvaGFyZGxpbmsvcmV1c2VkIG91dHB1dCBwYXRoLiBBbiBvZmYtY2x1c3RlciBjb3B5IGJlbG9uZ3Mgb25seSBpbiB0aGUgYWxyZWFkeSBlc3RhYmxpc2hlZCBpZ25vcmVkIGAucHJpdmF0ZS1iYWNrdXBzLzx1bmlxdWUtdHJpYWwtZGlyZWN0b3J5PmAgY3VzdG9keSB3aXRoMDcwMC8wNjAwIHBlcm1pc3Npb25zOyBubyBHaXQsIFN0YXRlSHViLCBwdWJsaWMgb2JqZWN0IHN0b3JlIG9yIHRlcm1pbmFsLWNvbnRlbnQgZHVtcC4gUmVjb3JkIG9ubHkgc2NoZW1hLCBpbnRlZ3JpdHkgcGFzcy9mYWlsLCBib3VuZGVkIHRhYmxlL3N0YXRlIGNvdW50cyBhbmQgcHJvdGVjdGVkIHJlY2VpcHQgaWRlbnRpZmllcjsgcmV0YWluIGJ5dGUgZGlnZXN0cyBpbiBwcm90ZWN0ZWQgY3VzdG9keSBpZiBuZWVkZWQgZm9yIGludGVybmFsIGNvcHkgaWRlbnRpdHkuIE5vIGNyZWRlbnRpYWwsIHJlY29yZCBwYXlsb2FkIG9yIHRva2VuIGZpbmdlcnByaW50IGVudGVycyBwdWJsaWMgZXZpZGVuY2UuCgojIyBBcHByb3ZlZCBvbmxpbmUgY29tcGF0aWJpbGl0eSBkcmlsbAoKV2l0aGluIHRoZSBleHBsaWNpdCBmb3VuZGVyLWFwcHJvdmVkIGFjdGlvbiwgcnVuIHRoZSBleGlzdGluZyBiYXNlIGltYWdlJ3MgYGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGJhY2t1cCAtLWRiIC9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZSAtLW91dHB1dCA8bmV3LXByaXZhdGUtc25hcHNob3Q+YCBpbiB0aGUgYWN0dWFsIHNlcnZpbmcgd29ya2xvYWQuIFRoaXMgdXNlcyBTUUxpdGUncyBiYWNrdXAgQVBJIGZvciBhIHRyYW5zYWN0aW9uYWxseSBjb25zaXN0ZW50IHNuYXBzaG90OyBjb3B5aW5nIGEgbGl2ZSBtYWluIGRhdGFiYXNlIHdoaWxlIGlnbm9yaW5nIFdBTCBpcyBwcm9oaWJpdGVkLiBTdXBwcmVzcyByYXcgZmFpbHVyZXMvb3V0cHV0IGFuZCByZXRhaW4gb25seSBzYW5pdGl6ZWQgc3RhdHVzLiBPYnNlcnZlIHNjaGVtYS9pbnRlZ3JpdHkgYW5kIGNvdW50LW9ubHkgbWV0YWRhdGEgZnJvbSB0aGUgcmVzdWx0aW5nIHNuYXBzaG90LCBub3QgcmVjb3JkIGNvbnRlbnQuCgpUcmFuc2ZlciB0aGF0IGNvbnNpc3RlbnQgc25hcHNob3Qgb25seSBpbnRvIHByb3RlY3RlZCBvZmYtY2x1c3RlciBjdXN0b2R5IHRocm91Z2ggdGhlIGV4aXN0aW5nIGF1dGhvcml6ZWQgb3BlcmF0b3IgbGFuZS4gVGhlIGNvcHkgaXMgcmVhbCBwcm9kdWN0aW9uIGRhdGEgZXZlbiBpbiBidWlsZCBtb2RlLiBWZXJpZnkgcHJpdmF0ZSBwZXJtaXNzaW9ucywgdW5pcXVlIGlkZW50aXR5IGFuZCBwcm90ZWN0ZWQgaW50ZXJuYWwgZGlnZXN0IGFncmVlbWVudC4gRG8gbm90IGV4cG9ydCBtb3VudGVkIHdvcmtsb2FkIGNyZWRlbnRpYWxzIG9yIGRpcmVjdG9yeSB0cmVlczsgY29weSBvbmx5IHRoZSBleGFjdCBzbmFwc2hvdC4KCkNyZWF0ZSBhIHNlcGFyYXRlIHByaXZhdGUgZGlzcG9zYWJsZSByZXN0b3JlIHZvbHVtZS9kaXJlY3Rvcnk7IHJldGFpbiB0aGUgb3JpZ2luYWwgc25hcHNob3QgdW5jaGFuZ2VkLiBSdW4gdGhlIGV4YWN0IHB1Ymxpc2hlZCBjYW5kaWRhdGUgd2l0aCBuZXR3b3JrIGRpc2FibGVkLCBubyBwcm9kdWN0aW9uIENvbmZpZ01hcC90b2tlbiBtb3VudHMsIHJlYWQtb25seSBpbWFnZSBhbmQgb25seSB0aGF0IGlzb2xhdGVkIHZvbHVtZSB3cml0YWJsZS4gT3ZlcnJpZGUgdGhlIHNlcnZpY2UgZW50cnlwb2ludCB3aXRoIHRoZSBvd25lcidzIGNvdW50LW9ubHkgYWRtaW5pc3RyYXRpdmUgaW5zcGVjdGlvbi9pbnRlZ3JpdHkgY2hlY2s7IGRvIG5vdCBzdGFydCBIVFRQIGxpc3RlbmVycywgYXVkaXQgZGVsaXZlcnksIHJlcXVlc3RlciBleGNoYW5nZXMgb3IgYXBwcm92YWwgb3BlcmF0aW9ucy4gVGhlIGN1cnJlbnQgY2FuZGlkYXRlIGNoYW5nZXMgcG9saWN5LnB5IG9ubHkgYW5kIHJldGFpbnMgdGhlIHNjaGVtYS9zdG9yZSBtb2R1bGUgYnl0ZXM7IHN0aWxsIHByb3ZlIHNjaGVtYTUsIFNRTGl0ZSBpbnRlZ3JpdHkgYW5kIGV4YWN0IGJvdW5kZWQgY291bnRzIGJlZm9yZS9hZnRlciBvcGVuaW5nIHRoZSByZXN0b3JlZCBjb3B5LiBSZWZ1c2UgYW55IG1pZ3JhdGlvbi9kb3duZ3JhZGUsIGxvc3QvY2hhbmdlZCBjb3VudHMsIHVuZXhwZWN0ZWQgd3JpdGUgY2xhc3Mgb3IgdW5rbm93biBvdXRjb21lLiBLZWVwIHBlbmRpbmcvdW5jZXJ0YWluIHN1Ym1pc3Npb24gYW5kIG91dGJveCBzdGF0ZXM7IG5ldmVyIHJlcGxheSwgZGlzY2FyZCBvciBtYXJrIHRoZW0gZGVsaXZlcmVkIHRvIGdyZWVuIHRoZSBkcmlsbC4gQ2xlYW51cCBvbmx5IHRoZSBkaXNwb3NhYmxlIGNvcHkvdm9sdW1lIGFmdGVyIHZlcmlmaWVkIHJlY2VpcHQ7IHJldGFpbiB0aGUgb3JpZ2luYWwgcHJvdGVjdGVkIGJhY2t1cCBmb3IgdGhlIGFwcHJvdmVkIHJlY292ZXJ5IGludGVydmFsLgoKVGhpcyBzdGVwIGlzIGFjdHVhbCBuYXRpdmUtZGF0YSBjb21wYXRpYmlsaXR5IGV2aWRlbmNlIG9uY2UgcGVyZm9ybWVkLiBJdHMgcHJldmlvdXMgc3ludGhldGljIGZpeHR1cmUgY2hlY2tzIHJlbWFpbiBtZWNoYW5pc20gZXZpZGVuY2UgYW5kIGNhbm5vdCBiZSByZW5hbWVkIG5hdGl2ZSBzdWNjZXNzLiBBIGZhaWxlZCBkcmlsbCBzdG9wcyByb2xsb3V0IGFuZCByZW1haW5zIGEgZmFpbGVkL3VudmVyaWZpZWQgb3V0Y29tZSBpbiB0aGUgc2FtZSB0cmlhbC4KCiMjIEZyZXNoIGN1dG92ZXIgc25hcHNob3QgYW5kIHNpbmdsZS13cml0ZXIgcm9sbG91dAoKQWZ0ZXIgc3VjY2Vzc2Z1bCBhY3R1YWwtZGF0YSBjb21wYXRpYmlsaXR5IGNoZWNrcywgY3JlYXRlIGFub3RoZXIgdW5pcXVlIFNRTGl0ZS1jb25zaXN0ZW50IG9ubGluZSBzbmFwc2hvdCBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGltYWdlIGN1dG92ZXIsIHJldGFpbmluZyBpdHMgcG9pbnQtaW4tdGltZSBzY2hlbWEvaW50ZWdyaXR5L2NvdW50IHJlY2VpcHQuIFRoaXMgaXMgYW4gb25saW5lIHRyYW5zYWN0aW9uYWwgc25hcHNob3QsIG5vdCBhIGNsYWltIHRoYXQgZGlzcGF0Y2hlcnMgb3IgaHVtYW4gd3JpdGVzIHdlcmUgcXVpZXNjZWQuIEV2ZXJ5IGxhdGVyIGNvbW1pdHRlZCByZWNvcmQgcmVtYWlucyBpbiB0aGUgbGl2ZSBkYXRhYmFzZTsgc2FtZS1zY2hlbWEgcm9sbGJhY2sgcmV0YWlucyB0aGF0IGRhdGFiYXNlIGFuZCBuZXZlciByZXN0b3JlcyB0aGUgZWFybGllciBzbmFwc2hvdCBvdmVyIGl0LiBUaGUgbmFycm93IGltYWdlLW9ubHkgdXBkYXRlIGRvZXMgbm90IG5lZWQgZGlzcGF0Y2hlci9jb25maWd1cmF0aW9uL1BWQy90ZW1wb3JhcnktcG9kIGNoYW5nZXMgb3IgYSBzY2hlbWEgY3V0b3Zlci4gSWYgZnJlc2ggdmVyaWZpY2F0aW9uIHNob3dzIGEgbWlncmF0aW9uIG9yIGFueSBkYXRhLXJlc3RvcmF0aW9uIHJlcXVpcmVtZW50LCBzdG9wIGFuZCByZWZpbmUgdGhlIHByb3Bvc2FsIHJhdGhlciB0aGFuIGFwcGx5aW5nIHRoaXMgcHJvdG9jb2wuCgpUaGUgZXhpc3RpbmcgUmVjcmVhdGUgcm9sbG91dCBkcmFpbnMvc3RvcHMgdGhlIHNpbmdsZSBvbGQgd3JpdGVyIGJlZm9yZSBzdGFydGluZyB0aGUgbmV3IGltYWdlIG9uIHRoZSBzYW1lIFBWQzsgdGhlIGluaGVyaXRlZCBzaW5nbGUtd3JpdGVyIGxvY2sgaW5kZXBlbmRlbnRseSByZWZ1c2VzIGNvbmN1cnJlbnQgc2VydmluZyBwcm9jZXNzZXMuIERvIG5vdCBhZGQgYW4gYWRtaW4gcG9kLCBzY2FsZS10by16ZXJvLCBkaXNwYXRjaGVyIHN0b3AsIG5ldHdvcmstcG9saWN5IHJld3JpdGUgb3Igc25hcHNob3Qgb3ZlcndyaXRlIGFzIGFuIGltcHJvdmlzZWQgaW1hZ2Utb25seSBzdGVwLiBUaGUgZXhpc3Rpbmcgb3duZXIgYWRtaW4gYmFja3VwIG9wZXJhdGlvbiBydW5zIGluc2lkZSB0aGUgYWRtaXR0ZWQgc2VydmluZyB3b3JrbG9hZCwgYW5kIGl0cyBzZXBhcmF0ZSBwcm90ZWN0ZWQgcmVzdG9yZSBkcmlsbCBydW5zIG9mZi1jbHVzdGVyIHdpdGggbmV0d29yayBkaXNhYmxlZCBhbmQgbm8gd29ya2xvYWQgY3JlZGVudGlhbHMuIFRob3NlIGV4YWN0IGN1c3RvZHkgb3BlcmF0aW9ucyBtdXN0IGJlIGVudW1lcmF0ZWQgaW4gdGhlIGZvdW5kZXIgcGFja2V0IGFsb25nc2lkZSB0aGUgb25lIERlcGxveW1lbnQgaW1hZ2UgY2hhbmdlLgoKT25jZSBiYWNrdXAvY29tcGF0aWJpbGl0eS9wcmVmbGlnaHQgZ2F0ZXMgcGFzcywgbWFudWFsbHkgcGluIHRoZSBleGlzdGluZyBBcmdvIEFwcGxpY2F0aW9uIHRvIHRoZSBleGFjdCByZXZpZXdlZCBzb3VyY2UgcmV2aXNpb24gYW5kIHN5bmMgb25seSBEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHdpdGggcHJ1bmUgZmFsc2UsIGtlZXBpbmcgdGhlIGN1cnJlbnQgaW1tdXRhYmxlIHJ1bnRpbWUgQ29uZmlnTWFwIGFuZCBhbGwgb3RoZXIgcmVzb3VyY2VzLiBUaGUgc291cmNlIHBhdGNoIGNoYW5nZXMgb25seSB0aGUgaW1hZ2UgaW4gYWRtaXNzaW9uL3JlbmRlcmVkIERlcGxveW1lbnQ7IG5vIFNlY3JldCwgUFZDLCBwb2xpY3ksIGRhdGFiYXNlIG9yIGRpc3BhdGNoZXIgY2hhbmdlIGlzIGluY2x1ZGVkIHVubGVzcyBzZXBhcmF0ZWx5IGVudW1lcmF0ZWQgaW4gdGhlIGZpbmFsIHByb3Bvc2FsLiBPYnNlcnZlIGZpdmUtbWludXRlIHJlYWRpbmVzcyBhbmQgZXhhY3QgaW1hZ2UvY29uZmlnL3NjaGVtYS9waW5zLiBSdW4gdGhlIHRlbiBpbnN0YWxsZWQgcHVycG9zZSB2YXJpYW50cyBvbiB0aGUgYWN0dWFsIG5hdGl2ZSBwbGFjZW1lbnQgdXNpbmcgc3ludGhldGljIHRyYW5zcG9ydDsgdGhleSBwcm92ZSBleGFjdCBpbnN0YWxsZWQgbW9kdWxlIHJlZnVzYWwgYmVoYXZpb3IgYW5kIGV4cGxpY2l0bHkgcmVwb3J0IG5hdGl2ZV9wcm92aWRlcj1mYWxzZS4gVGhleSBkbyBub3QgcHJvdmUgYW4gYWN0dWFsIHByb3ZpZGVyIHJlc3BvbnNlLCBQRFAgYXV0aG9yaXR5IG9yIG5hdGl2ZSBsaWZlY3ljbGUgYmluZGluZzsgYW55IHJlcXVpcmVkIGFjdHVhbC1wcm92aWRlciBwcm9vZiByZW1haW5zIGEgZGlzdGluY3QgVDA0IGNvbXBsZXRpb24gZ2F0ZSB3aXRoIHNlcGFyYXRlIGF1dGhvcml6ZWQgcHJlcGFyYXRpb24sIGFuZCBtdXN0IG5vdCBiZSBjbGFpbWVkIGJ5IHRoaXMgaGVscGVyLiBEbyBub3QgY29udGFtaW5hdGUgdGhlIGxpdmUgUERQLCBjcmVhdGUgaHVtYW4gYXBwcm92YWxzLCByZWFkIGNyZWRlbnRpYWxzIHRocm91Z2ggQ0xJLCBvciByZXBsYXkgdW5rbm93biBleHRlcm5hbCBvdXRjb21lcyBmb3IgdGVzdGluZy4KCiMjIFNhbWUtc2NoZW1hIHJvbGxiYWNrIGFuZCBldmlkZW5jZSByZXRlbnRpb24KCk9uIHN0YXJ0dXAvcmVhZGluZXNzL2JpbmRpbmcvcmVmdXNhbCBmYWlsdXJlLCByZXRhaW4gY3VycmVudCBkYXRhYmFzZSwgY3V0b3ZlciBiYWNrdXAgYW5kIGV2ZXJ5IHBvc3QtY3V0b3ZlciBldmlkZW5jZS91bmNlcnRhaW4gb3V0Y29tZS4gUmVzdG9yZSBvbmx5IHRoZSBwcmlvcjdmNWM2Y2IgaW1hZ2UgdGhyb3VnaCB0aGUgc2FtZSBtYW51YWwgQXJnbyBvd25lciBwYXRoLCByZXRhaW5pbmcgc2NoZW1hNSBhbmQgY3VycmVudCBEQi9jb25maWd1cmF0aW9uOyBuZXZlciByZXN0b3JlIGFuIG9sZCBzbmFwc2hvdCBvdmVyIGN1cnJlbnQgbGl2ZSBldmlkZW5jZSBqdXN0IHRvIHJvbGwgdGhlIGltYWdlIGJhY2suIFZlcmlmeSBvbGQgaW1hZ2UvUmVhZHkxLCBzYW1lIHNjaGVtYS9jb3VudHMgYW5kIHByaW9yIGJlaGF2aW9yLCBhbmQgcmVjb25jaWxlIGFueSBleHRlcm5hbCBlZmZlY3RzIHVzaW5nIGV4aXN0aW5nIGxpZmVjeWNsZS9hdWRpdCBvd25lcnNoaXAuIFRoZSBuYXJyb3cgb3ZlcmxheSdzIGlkZW50aWNhbCBzdG9yZS9zY2hlbWEvZGVwZW5kZW5jeSBieXRlcyBwZXJtaXQgdGhpcyBpbWFnZS1vbmx5IHJvbGxiYWNrOyBpdCBpcyBub3QgcGVybWlzc2lvbiBmb3IgYSBzY2hlbWEgZG93bmdyYWRlIG9yIGRhdGEgbG9zcy4KClJlY29yZCBvcmlnaW5hbC9hcHByb3ZlZC9leGVjdXRlZCBzb3VyY2UgYW5kIGltYWdlIHJldmlzaW9ucywgYmFja3VwL2RyaWxsL2N1dG92ZXIvcm9sbG91dCB0aW1lc3RhbXBzLCBleGFjdCBkaXNwb3NpdGlvbiBhbmQgc2FuaXRpemVkIG91dGNvbWVzIGluIHRoZSBleGlzdGluZyBzdXBlcnZpc2VkIHRyaWFsIHJlY2VpcHQuIEVVUjAgaW5jcmVtZW50YWwgaW5mcmFzdHJ1Y3R1cmUgZXN0aW1hdGUgdXNlcyBleGlzdGluZyBzZXJ2aWNlL3N0b3JhZ2Uvb3BlcmF0b3IgbGFuZTsgcHJvdGVjdGVkIHRlbXBvcmFyeSBjb3B5L3N0b3JhZ2UgY29uc3VtcHRpb24gYW5kMTXigJMzMG1pbnV0ZSByZWNvdmVyeSB0aW1lIHJlbWFpbiBvcGVyYXRpb25hbCBjb3N0cy4gTm8gRVVSIGluY2lkZW50LWxvc3MgY2FwIG9yIGF1dG9ub215IGdyYW50IGlzIGluZmVycmVkLiBUYXNrVDA0IGNhbm5vdCBjbG9zZSB1bnRpbCBhY3R1YWwgcHVibGlzaGVkIGltYWdlLCBhcHByb3ZlZCBuYXRpdmUgY29tcGF0aWJpbGl0eSBhbmQgcmVsZWFzZSBwbHVzIHBvc3QtcmVsZWFzZSByZWZ1c2FsL2JpbmRpbmcgZXZpZGVuY2UgYWxsIGV4aXN0LgoKIyMgRXhhY3QgcmVsZWFzZSBjYXNlIGlkZW50aWZpZXJzCgpQcm9wb3NhbCBgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFgLCB0cmlhbCBgaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxYC4KUHJvdGVjdGVkIG5hdGl2ZSBwYXJlbnQgYC9kYXRhL3ByaXZhdGUvcHVycG9zZS1vdmVybGF5LXIxYCBtdXN0IGJlIHVuaXF1ZS9ub24tc3ltbGluaywgb3duZWQxMDAwMSBhbmQwNzAwLiBUaGUgZHJpbGwgc25hcHNob3QgaXMgYGRyaWxsLnNxbGl0ZWAsIHRoZSByZWZyZXNoZWQgcHJlLWN1dG92ZXIgc25hcHNob3QgYGN1dG92ZXIuc3FsaXRlYCwgZWFjaCBuZXcwNjAwIGZpbGU7IHJlZnVzZSBhbnkgZXhpc3Rpbmcgb3V0cHV0LiBPZmYtY2x1c3RlciBjdXN0b2R5IGlzIHRoZSBleGlzdGluZyBpZ25vcmVkIEN1c3RvZGlhbiBgLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjFgIHBhcmVudDA3MDAsIGZpbGVzMDYwMDsgbm8gc25hcHNob3QgaXMgYW4gZXZpZGVuY2UgYXR0YWNobWVudC4gQ2hlY2sgb3duZXIgVUlELCBubyBzeW1saW5rcywgaWdub3JlZCBzdGF0dXMgYW5kIGZyZWUgY2FwYWNpdHkgZm9yIGJvdGggbmF0aXZlIHNuYXBzaG90cyBwbHVzIGluZGVwZW5kZW50bHkgcHJvdGVjdGVkIGNvcGllcyBiZWZvcmUgbWFraW5nIGFueSBzbmFwc2hvdC4KClRoZSBkaXNwb3NhYmxlIG9mZmxpbmUgcmVzdG9yZSB2b2x1bWUgaXMgYGluZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExYDsgcmVmdXNlIGFuIGV4aXN0aW5nIHZvbHVtZSwgY29weSBvbmx5IHRoZSBzZWxlY3RlZCBmcm96ZW4gc25hcHNob3QsIGFuZCBydW4gZXhhY3QgcHVibGlzaGVkIGNhbmRpZGF0ZTc2M2Mgd2l0aCBuZXR3b3Jrbm9uZS9yZWFkLW9ubHkgaW1hZ2UsMTI4TWlCL2NvcmUxIGFuZCBubyBydW50aW1lIGNvbmZpZy90b2tlbiBtb3VudHMuIFNRTGl0ZSBgUFJBR01BIGludGVncml0eV9jaGVja2AgbXVzdCByZXR1cm4gYG9rYCwgYFBSQUdNQSB1c2VyX3ZlcnNpb25gL1N0b3JlIGluc3BlY3Rpb24gbXVzdCBhZ3JlZSB3aXRoIGFjdHVhbCBzY2hlbWE1IHNlbWFudGljcywgYW5kIGluc3RhbGxlZCBhZG1pbiBjb3VudC1vbmx5IGluc3BlY3Rpb24gbXVzdCBtYXRjaCB0aGUgZnJvemVuIHNuYXBzaG90LiBWYWxpZGF0ZSB0aGUgYWN0dWFsIHNjaGVtYSByZXByZXNlbnRhdGlvbiByYXRoZXIgdGhhbiBhc3N1bWUgUFJBR01BIHVzZXJfdmVyc2lvbiBpcyB0aGUgc2NoZW1hIGF1dGhvcml0eS4gTm8gc3ludGhldGljIHJlc3RvcmF0aW9uIGlzIHJlcG9ydGVkIGFzIG5hdGl2ZSByZXN0b3JhdGlvbi4gTmF0aXZlIG9yaWdpbmFsL29mZi1jbHVzdGVyIGNvcGllcyByZW1haW4gcmV0YWluZWQ7IG9ubHkgdGhlIGRpc3Bvc2FibGUgcmVzdG9yZSBjb3B5L3ZvbHVtZSBtYXkgYmUgcmVtb3ZlZCB1bmRlciB0aGUgZXhhY3QgYXBwcm92ZWQgY2xlYW51cCBzY29wZS4KCiMjIE1hbmRhdG9yeSBwcmUtb3BlbiBzY2hlbWEgZ2F0ZSBhbmQgb2ZmbGluZSBjb21tYW5kCgpgaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4gaW5zcGVjdGAgYW5kIGBiYWNrdXBgIGNvbnN0cnVjdCBTdG9yZSwgd2hpY2ggY2FuIG1pZ3JhdGUgc2NoZW1hczHigJM0IHRvNS4gVGhlcmVmb3JlICoqYmVmb3JlIGFueSBTdG9yZS9hZG1pbiBvcGVuKiosIHJ1biB0aGUgZXhhY3QgYXR0YWNoZWQgc3RkbGliLW9ubHkgYHNxbGl0ZV9yZWFkb25seS5weWAgYWdhaW5zdCB0aGUgbmF0aXZlIHNvdXJjZSBkYXRhYmFzZSB1c2luZyBTUUxpdGUgVVJJIG1vZGU9cm8sIHF1ZXJ5X29ubHkgYW5kIG9uZSByZWFkIHRyYW5zYWN0aW9uLiBSZXF1aXJlIFBSQUdNQSB1c2VyX3ZlcnNpb241LCBpbnRlZ3JpdHlfY2hlY2s9b2sgYW5kIHJldGFpbiBjb3VudC1vbmx5IGJhc2VsaW5lLiBSZWZ1c2UgYW55IG90aGVyL3Vua25vd24gc2NoZW1hIG9yIGluY29tcGxldGUgaW50ZWdyaXR5L2NvdW50IGNoZWNrIGJlZm9yZSBjb25zdHJ1Y3RpbmcgU3RvcmU7IGRvIG5vdCBpbmZlciBubyBtaWdyYXRpb24gZnJvbSBhIHBvc3Qtb3BlbiBhZG1pbiByZXBvcnQuIFRoaXMgbmF0aXZlIGdhdGUgaGFzIG5vdCBiZWVuIGV4ZWN1dGVkIGluIHRoaXMgc291cmNlLXByZXBhcmF0aW9uIHN0YWdlLiBSZXBlYXQgYmVmb3JlIGVhY2ggbmF0aXZlIGJhY2t1cC9hZG1pbiBvcGVyYXRpb24uCgpBZnRlciBjb3B5aW5nIHRoZSBzZWxlY3RlZCBjb25zaXN0ZW50IHNuYXBzaG90IHRvIHRoZSBpc29sYXRlZCByZXN0b3JlZCBwcml2YXRlIHBhdGggYC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgLCBydW4gdGhlIHNhbWUgcmVhZC1vbmx5IGNoZWNrZXIgKipiZWZvcmUqKiBhbnkgb2ZmbGluZSBjYW5kaWRhdGUgYWRtaW4vU3RvcmUgb3BlbnMgdGhhdCBjb3B5LiBGcm96ZW4gc25hcHNob3QgYW5kIHJlc3RvcmVkLWNvcHkgc2NoZW1hL2ludGVncml0eS9jb3VudCByZXBvcnRzIG11c3QgYWdyZWUgZXhhY3RseTsgdGhlIGNvcGllZCBtYWluLWZpbGUgZGlnZXN0IG11c3QgbWF0Y2ggdGhlIHNlbGVjdGVkIGNsb3NlZCBzbmFwc2hvdC4gUmVqZWN0IG9sZHNjaGVtYSBmaXh0dXJlcyByYXRoZXIgdGhhbiBhbGxvdyBtaWdyYXRpb24uIE9ubHkgYWZ0ZXIgdGhpcyBwcmUtb3BlbiBnYXRlIG1heSB0aGUgb2ZmbGluZSBjYW5kaWRhdGUgYWRtaW4gaW5zcGVjdCBydW4uCgpPZmZsaW5lIGNvbW1hbmQgdmVjdG9ycyB1c2UgZXhhY3RpbWFnZSBgZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhYCwgYC0tbmV0d29yayBub25lIC0tcmVhZC1vbmx5IC0tY3B1cyAxIC0tbWVtb3J5IDEyOG1gLCBwcml2YXRlIHJlc3RvcmVkIHZvbHVtZSBtb3VudGVkIGF0IGAvcmVzdG9yZWAsIGFuZCAqKm5vIHJ1bnRpbWUgY29uZmlnL2NyZWRlbnRpYWwvdG9rZW4gbW91bnRzKiouIEZpcnN0IG92ZXJyaWRlIGVudHJ5cG9pbnQgdG8gYHB5dGhvbmAsIGFyZ3VtZW50cyBgLSAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgLCBzdHJlYW1pbmcgb25seSB0aGUgdmVyaWZpZWQgYXR0YWNoZWQgY2hlY2tlciBvbiBzdGRpbi4gVGhlbiBvdmVycmlkZSBlbnRyeXBvaW50IHRvICoqYGluZm9ybWVkLWRlY2lzaW9uLWFkbWluYCoqLCBhcmd1bWVudHMgKipgaW5zcGVjdCAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgKiouIFRoaXMgZG9lcyBub3Qgc3RhcnQgYGluZm9ybWVkLWRlY2lzaW9uLWNvbnRhaW5lcmAsIHRoZSBIVFRQIHNlcnZpY2UsIGRpc3BhdGNoZXIgb3IgZGVsaXZlcnkgd29ya2Vycy4gQ29tcGFyZSB0aGUgYWRtaW4ncyBzY2hlbWEvbGlmZWN5Y2xlL291dGJveC9zdWJtaXNzaW9uIGNvdW50ZXJzIHRvIHRoZSBmcm96ZW4gcHJlLW9wZW4gc25hcHNob3QgcmVwb3J0OyBpbnRlZ3JpdHkgYW5kIG1pZ3JhdGlvbi1mcmVlIHByZS1vcGVuIHByb29mIGNvbWUgZnJvbSB0aGUgc3RkbGliIGNoZWNrZXIsIG5vdCBhZG1pbiBvdXRwdXQgYWxvbmUuCgpMaXZlIHJlYWRzIGFuZCBvbmxpbmUgc25hcHNob3RzIG1heSBsZWdpdGltYXRlbHkgZGlmZmVyIGJlY2F1c2UgcmV2aWV3cywgaW50YWtlIGFuZCBkZWxpdmVyeSBjYW4gY29tbWl0IGNvbmN1cnJlbnRseS4gRXhhY3QgY291bnRlciBlcXVhbGl0eSBpcyByZXF1aXJlZCBiZXR3ZWVuIHRoZSBmcm96ZW4gc2VsZWN0ZWQgc25hcHNob3QgYW5kIGl0cyBvZmZsaW5lIHJlc3RvcmVkIGNsb25lOyBpdCBpcyAqKm5vdCoqIHJlcXVpcmVkIGJldHdlZW4gYSBydW5uaW5nIHBvc3QtY3V0b3Zlci9yb2xsYmFjayBkYXRhYmFzZSBhbmQgYW4gZWFybGllciBzbmFwc2hvdC4gTGl2ZSBjb3VudCBjaGFuZ2VzIG11c3QgYmUgYWNjb3VudGVkIGZvciBhcyBsZWdpdGltYXRlIGNvbW1pdHRlZCByZWNvcmRzL3N0YXRlIHRyYW5zaXRpb25zOyBwcmVzZXJ2ZSBhbGwgY3VycmVudCBhbmQgdW5jZXJ0YWluIGVudHJpZXMuIERvIG5vdCBkaXNjYXJkIG5ldyBjb21taXRzIG9yIHJlc3RvcmUgdGhlIG9sZCBzbmFwc2hvdCB0byBmb3JjZSBlcXVhbGl0eS4gU2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sga2VlcHMgdGhlIGN1cnJlbnQgbGl2ZSBEQiwgZm9sbG93ZWQgYnkgcmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5IGFuZCBjb3VudC1vbmx5IGhlYWx0aCBjaGVja3M7IGFueSB1bmV4cGxhaW5lZCBldmlkZW5jZSBsb3NzIG9yIHJlcXVpcmVkIGRhdGEgcmVjb3Zlcnkgc3RvcHMgYW5kIHJlcXVpcmVzIGEgc2VwYXJhdGUgZm91bmRlciBkZWNpc2lvbi4KClRoZSBmcmVzaCBwcmVmbGlnaHQgYWxzbyBpbmRlcGVuZGVudGx5IHJlYWRzIHRoZSBhY3R1YWwgaW1tdXRhYmxlIG5vbnNlY3JldCBDb25maWdNYXAgYW5kIGJvdW5kIFBWQzogY29tcGFyZXMgc2VhbGVkIFVJRHMvZnVsbG1ldGFkYXRhL1BWQ3NwZWMrdm9sdW1lTmFtZSBhbmQgY2Fub25pY2FsIHJ1bnRpbWUgZGF0YSBjaGVja3N1bSwgcmV0dXJuaW5nIG5vIHJhdyBydW50aW1lIGRhdGEuIFNhbWUtbmFtZSBkZWxldGlvbi9yZWNyZWF0aW9uIG9yIGNvbnRlbnQvY3VzdG9keSBkcmlmdCBzdG9wcyBiZWZvcmUgYWRtaXNzaW9uLiBTZWNyZXQgdmFsdWVzIHJlbWFpbiBleGNsdWRlZC4gQm90aCBsb2NhbCBhbmQgcmVtb3RlIG9wdGltaXplZCBQeXRob24gaW50ZXJwcmV0ZXJzIGFyZSBleHBsaWNpdGx5IHJlZnVzZWQgYmVmb3JlIGFzc2VydGlvbi1iYXNlZCBnYXRlcy4KCiMjIEV4YWN0IHN1cGVydmlzZWQgbWVjaGFuaWNhbCBleGVjdXRpb24gcmVmaW5lbWVudAoKVGhlIGRpcmVjdGx5IGF0dGFjaGVkIGBleGVjdXRpb24tYnVuZGxlLmpzb25gIGNvbnRhaW5zIHRoZSBleGFjdCBoZWxwZXIgc291cmNlLCBwbGFuLCB0ZXN0cyBhbmQgUEVORElORyByZWNlaXB0IHRlbXBsYXRlLiBJdCByZXBsYWNlcyB0aGUgZGlyZWN0IHJhdyBzY2FuIGF0dGFjaG1lbnQgd2l0aGluIHRoZSB0d2VudHktZG9jdW1lbnQgbGltaXQ7IGBwdWJsaXNoZWQtdmVyaWZpY2F0aW9uLmpzb25gIHN0aWxsIGJpbmRzIHRoZSB1bmNoYW5nZWQgYWN0dWFsIHVuZmlsdGVyZWQgcmF3IHNjYW4sIHJhdyBTQk9NIGFuZCBiYXNlIHNjYW4gU0hBMjU2IHZhbHVlcywgcmV0YWluZWQgaW4gdGhlIG93bmVyIGV2aWRlbmNlIHBhY2thZ2UuIFRoZSBrbm93biBpbmhlcml0ZWQgZml4YWJsZSBNRURJVU0gcmVtYWlucyBleHBsaWNpdCwgd2l0aCBvd25lciBUMDUvcmlzayBmb2xsb3ctdGhyb3VnaC4gTmVpdGhlciBhcmNoaXZlIG5vciB0ZWNobmljYWwgYWdyZWVtZW50IHN1cHBsaWVzIGh1bWFuIGFwcHJvdmFsLgoKVGhlIHJldmlld2VkIHByb3RvY29sIGJhc2lzIGlzIG93bmVyIGNvbW1pdCBlMDM1OWJjYjZjZGZhZDlhYjNlODY4MDU0MTIxZmUwY2ViZWMyZDY4LCB3aXRoIHNvdXJjZSBmb2xsb3ctdGhyb3VnaDkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUuIFRoZSBzdWJzZXF1ZW50IGV4YWN0IGFwcGxpZWQgaGVscGVyL3BhY2tldCBvd25lciBjb21taXQgbXVzdCBiZSBuYW1lZCBpbiB0aGUgZXh0ZXJuYWxseSB2ZXJpZmllZCBmb3VuZGVyIHJlY2VpcHQgYmVmb3JlIGV4ZWN1dGlvbi4gVmVyaWZ5IHRoZSBmb3VyIGNvbW1pdHRlZCBHaXQgYmxvYnMgKGFkbWlzc2lvbi5jYW5kaWRhdGUuanNvbiwgc2VydmljZS5jYW5kaWRhdGUuanNvbiwga3VzdG9taXphdGlvbi55YW1sLCByZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uKSBhZ2FpbnN0IGV4ZWN1dGlvbi1wbGFuLmpzb24gYXMgd2VsbCBhcyBjdXJyZW50IHdvcmt0cmVlL0hFQUQ7IHJlamVjdCBvdmVycmlkZXMvcGx1Z2lucy9tdWx0aXBsZSBBcHBsaWNhdGlvbiBzb3VyY2VzIGFuZCBhbnkgcHJlc2VudCBhdXRvbWF0ZWQgY29uZmlndXJhdGlvbiwgaW5jbHVkaW5nIGF1dG9tYXRlZDp7fS4KClJvb3QgZnJlc2hseSBhdXRoZW50aWNhdGVzIHRoZSBleGFjdCBjb25maXJtZWQgZm91bmRlciBwZXJzb24vcGxhdGZvcm0tcm9vdCBBQ0NFUFQgb2YgdGhpcyBzdGFibGUgbWVtby92ZXJzaW9uMSBhdCB0aGUgZml4ZWQgbmF0aXZlIEluZm9ybWVkIERlY2lzaW9uIG9yaWdpbiBiZWZvcmUgZWFjaCBwaGFzZSwgYW5kIHN1cHBsaWVzIHByb3RlY3RlZDA2MDAgcmVjZWlwdC9vdXRjb21lIGZpbGVzLiBUaGUgaGVscGVyIGNoZWNrcyB0aGVpciBleGFjdCByZWxhdGlvbiBhbmQgZnJlc2huZXNzMTIwc2Vjb25kczsgdGhlc2UgZmlsZXMgYXJlIHN1cGVydmlzZWQgYm9va2tlZXBpbmcsIG5vdCBzaWduZWQgYXV0aGVudGljYXRlZCBncmFudHMsIGEgaHVtYW4tcHJvdmlkZXIgaW1wbGVtZW50YXRpb24sIG9yIGF1dG9ub21vdXMgYWdlbnQgYXV0aG9yaXR5LiBEbyBub3QgZGVyaXZlIHRoZW0gZnJvbSB0ZWNobmljYWwgcmV2aWV3cyBvciBjYWxsZXIgYXNzZXJ0aW9ucy4KCkZpeGVkIG9yZGVyOiBkcmlsbC1iYWNrdXAg4oaSIGRyaWxsLWNvcHkg4oaSIG9mZmxpbmUtdmVyaWZ5IOKGkiBjbGVhbnVwLW9mZmxpbmUg4oaSIGN1dG92ZXItYmFja3VwIOKGkiBjdXRvdmVyLWNvcHkg4oaSIHJlbGVhc2Ug4oaSIHZlcmlmeS4gQSBzZXBhcmF0ZSByZWNvcmRlZCByZWxlYXNlIGF0dGVtcHQgcGVybWl0cyByb2xsYmFjayDihpIgcm9sbGJhY2stdmVyaWZ5LiBFdmVyeSBwaGFzZSBmc3luY3MgYW4gYXR0ZW1wdCBub25jZS9SVU5OSU5HIGpvdXJuYWwgYmVmb3JlIGVmZmVjdHMuIEZhaWx1cmUvaW50ZXJydXB0aW9uL2FtYmlndW91cyBhY3R1YXRpb24gc3RheXMgVU5DRVJUQUlOIGFuZCB0aGUgc2FtZSBwaGFzZSBjYW5ub3QgYmUgcmV0cmllZC4gTm8gaW1wcm92aXNlZCBhZGFwdGVyIG9yIHdob2xlLUFwcGxpY2F0aW9uIHN5bmMgaXMgcGVybWl0dGVkLgoKVGhlIE5FVyBub25jZS1sYWJlbGxlZCBsb2NhbCB2b2x1bWUgcmVxdWlyZXMgb25lIGV4cGxpY2l0IGlzb2xhdGVkIGluaXRpYWxpemVyIGFzIFVJRDA6MCB3aXRoIG9ubHkgQ0FQX0NIT1dOLCBleGFjdDc2M2MgaW1hZ2UsIC0tbmV0d29yayBub25lIC0tcmVhZC1vbmx5IC0tY3B1cyAxIC0tbWVtb3J5IDEyOG0gLS1jYXAtZHJvcCBBTEwgLS1jYXAtYWRkIENIT1dOIC0tc2VjdXJpdHktb3B0IG5vLW5ldy1wcml2aWxlZ2VzLiBJdHMgb25seSBtb3VudCBpcyB0aGF0IG5ldyBuYW1lZCB2b2x1bWUgYXQgL3Jlc3RvcmU7IG5vIGhvc3QgbW91bnQsIG5hdGl2ZSBQVkMsIHJ1bnRpbWUgY29uZmlnIG9yIHRva2VuIG1vdW50LiBQcm90ZWN0ZWQgc25hcHNob3Qgc3RkaW4gZ29lcyBvbmx5IHRvIGEgdW5pcXVlMDYwMCBtYWluIGZpbGUgd2l0aCBleGFjdCBkaWdlc3QsIGFuZCBkaXJlY3RvcnkvZmlsZSBjdXN0b2R5IGlzIHNldDA3MDAvMDYwMCBVSUQvR0lEMTAwMDEuIFRoZW4gYWxsIHByZS1vcGVuLCBhZG1pbiBhbmQgcG9zdC1hZG1pbiBjaGVja3MgcnVuIFVJRDEwMDAxOjEwMDAxLCBjYXBhYmlsaXRpZXMgZHJvcHBlZCwgbmV0d29ya25vbmUuIFRoZSBzZWNvbmQgc3RkbGliIHJlYWRvbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IHByb29mIGFmdGVyIGFkbWluIG11c3QgZXhhY3RseSBlcXVhbCB0aGUgZnJvemVuIHNuYXBzaG90IHByb29mOyBpbmRlcGVuZGVudGx5IHJlY2hlY2sgdGhlIHJldGFpbmVkIG9yaWdpbmFsIHByb3RlY3RlZCBzbmFwc2hvdCBTSEEuIE5vIHNlcnZpY2Ugc3RhcnR1cCBvY2N1cnMuCgpSb2xsYmFjayBkaXNwYXRjaCBtdXN0IGJlIGF2YWlsYWJsZSBpZiB0aGUgY2FuZGlkYXRlIGlzIHVucmVhZHkgb3IgY2Fubm90IHN0YXJ0OiBpdCBjaGVja3Mgc2VhbGVkIERlcGxveW1lbnQvQ00vUFZDIGN1c3RvZHksIG9ubHkgcHJpb3IvY2FuZGlkYXRlIHNvdXJjZS9pbWFnZSBwYWlyLCBub2RlIGhlYWx0aC9oZWFkcm9vbSBhbmQgZnJlc2ggb2xkLWltYWdlIHNlcnZlciBhZG1pc3Npb24gcGx1cyBBcHBsaWNhdGlvbiBVSUQvcmVzb3VyY2VWZXJzaW9uL3NvdXJjZSBDQVMsIHdpdGggbm8gZmFpbGluZyBjYW5kaWRhdGUgUG9kL2V4ZWMvZGF0YWJhc2UgcHJlcmVxdWlzaXRlLiBEaXNwYXRjaCBhY2tub3dsZWRnbWVudCBpcyBub3QgcmVjb3ZlcmVkIGhlYWx0aC4gYHJvbGxiYWNrLXZlcmlmeWAgc2VwYXJhdGVseSByZXF1aXJlcyBvbGQgaW1hZ2UgUmVhZHkxLCBzdWNjZWVkZWQgZXhhY3QgRGVwbG95bWVudC1vbmx5L3BydW5lPWZhbHNlIG9wZXJhdGlvbiBhbmQgcmVhZG9ubHkgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnQgcHJvb2Ygb2YgdGhlIGxhdGVzdCByZXRhaW5lZCBsaXZlIGRhdGFiYXNlLiBObyBzbmFwc2hvdCByZXBsYWNlcyB0aGUgY3VycmVudCBkYXRhYmFzZS4KCioqRGVhZGxpbmUgcmVmaW5lbWVudDoqKiBhbGwgcGhhc2VzLCBpbmNsdWRpbmcgcm9sbGJhY2sgYW5kIHZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUyMDI2LTEwLTEyVDIzOjU5OjU5Wi4gVGhlIGVhcmxpZXIgYW1lbmRlZCBwYWNrZXQgZGVzY3JpYmVkIHVuc3RhcnRlZC1yZWxlYXNlIGV4cGlyeTsgdGhpcyBleGFjdCBoZWxwZXIgYWxzbyBib3VuZHMgcmVjb3ZlcnkvdmVyaWZpY2F0aW9uLiBTdGFydCBlYXJseSBlbm91Z2ggdG8gY29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIGFueSByZWNvdmVyeSB3aXRoaW4gdGhlIHdpbmRvdy4gSWYgZXhoYXVzdGVkLCBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uIHJhdGhlciB0aGFuIHNpbGVudGx5IGV4dGVuZCBhIGdyYW50LiBUaGlzIG1heSBkZWxheSByZWNvdmVyeSBhbmQgaXMgYW4gZXhwbGljaXQgb3BlcmF0aW9uYWwgcmlzay4gTm8gdGltZXIvY29udHJvbGxlciBhdXRvbWF0aWNhbGx5IHJvbGxzIGJhY2sgb3IgY2hhbmdlcyBzZXJ2aWNlIGF0IGV4cGlyeS4K" + }, + { + "digest": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101", + "media_type": "application/json", + "content_base64": "ewogICJpZCI6ICJJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSIsCiAgImtpbmQiOiAib3duZXItdnVsbmVyYWJpbGl0eS1mb2xsb3ctdGhyb3VnaCIsCiAgIm93bmVyIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAidGFzayI6ICJJTkZELVdQLTAwMDktVDA1IiwKICAic3RhdHVzIjogIm9wZW4iLAogICJjcmVhdGVkIjogIjIwMjYtMTAtMTEiLAogICJyZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJmaW5kaW5nIjogIkNWRS0yMDI2LTg1MDkxIiwKICAic2Nhbm5lcl9zZXZlcml0eSI6ICJNRURJVU0iLAogICJlc3RhdGVfcmlza19ncmFkZSI6IG51bGwsCiAgImFmZmVjdGVkX3BhY2thZ2UiOiAiemxpYiIsCiAgImluc3RhbGxlZCI6ICIxLjMuMi1yMCIsCiAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAiYWN0dWFsX2N1cnJlbnRfYmFzZV9hbmRfY2FuZGlkYXRlX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgInNvdXJjZV9ldmlkZW5jZSI6ICJzZWN1cml0eS1zdW1tYXJ5Lmpzb24sIHRyaXZ5LWZ1bGwuanNvbiwgYmFzZS10cml2eS1mdWxsLmpzb24iLAogICJodW1hbl90ZW1wb3JhcnlfZGlzcG9zaXRpb24iOiAicGVuZGluZyIsCiAgImZvbGxvd190aHJvdWdoIjogIlByZXBhcmUgYSBzZXBhcmF0ZWx5IHNvdXJjZS1ib3VuZCBvZmZpY2lhbC1iYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCB0aHJvdWdoIG5vcm1hbCBvd25lciBDSSwgdmVyaWZ5IGZ1bGwgc2NhbiBhbmQgcnVudGltZSBjb21wYXRpYmlsaXR5LCBvYnRhaW4gZGlzdGluY3QgbmF0aXZlIHJlbGVhc2UgYXBwcm92YWwgYmVmb3JlIHVwZGF0aW5nIHRoaXMgd29ya2xvYWQiLAogICJtYW51YWxfcmV2aWV3X2V4cGlyeSI6ICJEdWUgZGF0ZSByZXF1aXJlcyBvd25lciByZXZpZXcvZXNjYWxhdGlvbiBpZiB1bnJlc29sdmVkOyBubyBhdXRvbWF0aWMgcm9sbGJhY2svY29udHJvbGxlciBpcyBpbnN0YWxsZWQiLAogICJjbG9zZV9jb25kaXRpb24iOiAiVmVyaWZpZWQgaW5zdGFsbGVkIG5hdGl2ZSBmaXhlZCBwYWNrYWdlIGFuZCBmdWxsIHVuZmlsdGVyZWQgcmVzY2FuOyBwcmVzZXJ2ZSBvcmlnaW5hbCBkZXRlY3Rpb24gYW5kIGFueSBodW1hbiBkaXNwb3NpdGlvbiIKfQo=" + }, + { + "digest": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "media_type": "application/json", + "content_base64": "ewogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjI1OjM4Ljc5MzU1NSswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibGl2ZV9yZWFkeV9yZXBsaWNhcyI6IDEsCiAgImFkbWl0dGVkX3VpZCI6ICJhNTg4ZTEwYS05MGQyLTQ4ODMtOTc1ZS02ZGQ4YjhmZWNhOTIiLAogICJzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWQiOiB0cnVlLAogICJhZG1pdHRlZF9zcGVjX2V4YWN0bHlfbGl2ZV9wbHVzX2ltYWdlIjogdHJ1ZSwKICAiY2xpZW50X2RpZmZfZXhpdCI6IDEsCiAgImNsaWVudF9kaWZmX3NoYTI1NiI6ICJhNGJjMDI0YThjZWM2NThmODM1Mjg1ZWQ1MTk2NGUyZTA4NGVkYmFmMTAzZDQ1YTQ4Yjg5YzA5NTBiY2QzZTdkIiwKICAibm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzIjogIihUb3RhbCBsaW1pdHMgbWF5IGJlIG92ZXIgMTAwIHBlcmNlbnQsIGkuZS4sIG92ZXJjb21taXR0ZWQuKVxuICBSZXNvdXJjZSAgICAgICAgICAgUmVxdWVzdHMgICAgICBMaW1pdHNcbiAgLS0tLS0tLS0gICAgICAgICAgIC0tLS0tLS0tICAgICAgLS0tLS0tXG4gIGNwdSAgICAgICAgICAgICAgICAzNDYwbSAoODYlKSAgIDM2MjAwbSAoOTA1JSlcbiAgbWVtb3J5ICAgICAgICAgICAgIDk0NzJNaSAoNTklKSAgMzI4OThNaSAoMjA1JSlcbiAgZXBoZW1lcmFsLXN0b3JhZ2UgIDAgKDAlKSAgICAgICAgMCAoMCUpXG4gIGh1Z2VwYWdlcy0xR2kgICAgICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMk1pICAgICAgMCAoMCUpICAgICAgICAwICgwJSkiLAogICJhbGxfY2hlY2tzX3Bhc3MiOiB0cnVlCn0K" + }, + { + "digest": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImFyZ29jZC5hcmdvcHJvai5pby90cmFja2luZy1pZCI6ICJpbmZvcm1lZC1kZWNpc2lvbjphcHBzL0RlcGxveW1lbnQ6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICJ1aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInJldmlzaW9uSGlzdG9yeUxpbWl0IjogMTAsCiAgICAic2VsZWN0b3IiOiB7CiAgICAgICJtYXRjaExhYmVscyI6IHsKICAgICAgICAiYXBwLmt1YmVybmV0ZXMuaW8vbmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIKICAgICAgfQogICAgfSwKICAgICJzdHJhdGVneSI6IHsKICAgICAgInR5cGUiOiAiUmVjcmVhdGUiCiAgICB9LAogICAgInRlbXBsYXRlIjogewogICAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiCiAgICAgICAgfSwKICAgICAgICAibGFiZWxzIjogewogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ICJyZXZpZXciLAogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgICAgfQogICAgICB9LAogICAgICAic3BlYyI6IHsKICAgICAgICAiYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbiI6IGZhbHNlLAogICAgICAgICJjb250YWluZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiZW52IjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIklORkRfS0VZQ0FQRV9JU1NVRVIiLAogICAgICAgICAgICAgICAgInZhbHVlIjogImh0dHBzOi8va2MuY291bG9tYi5zb2NpYWwiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0NPTlRBSU5FUl9DT05GSUciLAogICAgICAgICAgICAgICAgInZhbHVlIjogIi9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvbiIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICAgICAgICAgICAiaW1hZ2VQdWxsUG9saWN5IjogIklmTm90UHJlc2VudCIsCiAgICAgICAgICAgICJsaXZlbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICAgICAgICJwb3J0cyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODAsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJodHRwIiwKICAgICAgICAgICAgICAgICJwcm90b2NvbCI6ICJUQ1AiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIsCiAgICAgICAgICAgICAgICAicHJvdG9jb2wiOiAiVENQIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlYWRpbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVzb3VyY2VzIjogewogICAgICAgICAgICAgICJsaW1pdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjUwMG0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICIyNTZNaSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZXF1ZXN0cyI6IHsKICAgICAgICAgICAgICAgICJjcHUiOiAiNW0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICI2NE1pIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInNlY3VyaXR5Q29udGV4dCI6IHsKICAgICAgICAgICAgICAiYWxsb3dQcml2aWxlZ2VFc2NhbGF0aW9uIjogZmFsc2UsCiAgICAgICAgICAgICAgImNhcGFiaWxpdGllcyI6IHsKICAgICAgICAgICAgICAgICJkcm9wIjogWwogICAgICAgICAgICAgICAgICAiQUxMIgogICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInJlYWRPbmx5Um9vdEZpbGVzeXN0ZW0iOiB0cnVlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzdGFydHVwUHJvYmUiOiB7CiAgICAgICAgICAgICAgImZhaWx1cmVUaHJlc2hvbGQiOiAxMiwKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAidGVybWluYXRpb25NZXNzYWdlUGF0aCI6ICIvZGV2L3Rlcm1pbmF0aW9uLWxvZyIsCiAgICAgICAgICAgICJ0ZXJtaW5hdGlvbk1lc3NhZ2VQb2xpY3kiOiAiRmlsZSIsCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJkbnNQb2xpY3kiOiAiQ2x1c3RlckZpcnN0IiwKICAgICAgICAicmVzdGFydFBvbGljeSI6ICJBbHdheXMiLAogICAgICAgICJzY2hlZHVsZXJOYW1lIjogImRlZmF1bHQtc2NoZWR1bGVyIiwKICAgICAgICAic2VjdXJpdHlDb250ZXh0IjogewogICAgICAgICAgImZzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJmc0dyb3VwQ2hhbmdlUG9saWN5IjogIk9uUm9vdE1pc21hdGNoIiwKICAgICAgICAgICJydW5Bc0dyb3VwIjogMTAwMDEsCiAgICAgICAgICAicnVuQXNOb25Sb290IjogdHJ1ZSwKICAgICAgICAgICJydW5Bc1VzZXIiOiAxMDAwMSwKICAgICAgICAgICJzZWNjb21wUHJvZmlsZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiUnVudGltZURlZmF1bHQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic2VydmljZUFjY291bnQiOiAicmV2aWV3IiwKICAgICAgICAic2VydmljZUFjY291bnROYW1lIjogInJldmlldyIsCiAgICAgICAgInRlcm1pbmF0aW9uR3JhY2VQZXJpb2RTZWNvbmRzIjogNDUsCiAgICAgICAgInZvbHVtZXMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImRhdGEiLAogICAgICAgICAgICAicGVyc2lzdGVudFZvbHVtZUNsYWltIjogewogICAgICAgICAgICAgICJjbGFpbU5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tZGF0YSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImVtcHR5RGlyIjogewogICAgICAgICAgICAgICJtZWRpdW0iOiAiTWVtb3J5IiwKICAgICAgICAgICAgICAic2l6ZUxpbWl0IjogIjE2TWkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImNvbmZpZ3VyYXRpb24iCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJjYWxsZXIiLAogICAgICAgICAgICAicHJvamVjdGVkIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAic291cmNlcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgInNlcnZpY2VBY2NvdW50VG9rZW4iOiB7CiAgICAgICAgICAgICAgICAgICAgImF1ZGllbmNlIjogImZsZXgtYXV0aCIsCiAgICAgICAgICAgICAgICAgICAgImV4cGlyYXRpb25TZWNvbmRzIjogMzYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiYXVkaXQiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAidG9rZW4iLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJzZWNyZXROYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLWF1ZGl0IgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiA2MDAsCiAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAidG9rZW4iCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAia2V5IjogImNhLmNydCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXRoIjogImNhLmNydCIKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICJuYW1lIjogImt1YmUtcm9vdC1jYS5jcnQiCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjkyLAogICAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgInNlY3JldCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAia2V5IjogImNsaWVudC1zZWNyZXQiLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJjbGllbnQtc2VjcmV0IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm9wdGlvbmFsIjogZmFsc2UsCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy1yZXF1ZXN0ZXIiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0KICAgIH0KICB9Cn0K" + }, + { + "digest": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IGV4YWN0IERlcGxveW1lbnQgYW5kIGFkbWlzc2lvbiBib3VuZGFyaWVzOyBubyBtdXRhdGlvbiBhdXRob3JpdHkuIiIiCmltcG9ydCBjb3B5CmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCgpCQVNFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MycKQ0FORElEQVRFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYScKCgpkZWYgZGVwZW5kZW5jeV9wcm9qZWN0aW9uKGNvbmZpZ21hcCwgcHZjKToKICAgIGlmIChjb25maWdtYXAuZ2V0KCdraW5kJykgIT0gJ0NvbmZpZ01hcCcgb3IgY29uZmlnbWFwLmdldCgnaW1tdXRhYmxlJykgaXMgbm90IFRydWUKICAgICAgICAgICAgb3IgY29uZmlnbWFwWydtZXRhZGF0YSddWyduYW1lc3BhY2UnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24nCiAgICAgICAgICAgIG9yIGNvbmZpZ21hcFsnbWV0YWRhdGEnXVsnbmFtZSddICE9ICdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MScKICAgICAgICAgICAgb3Igc2V0KGNvbmZpZ21hcC5nZXQoJ2RhdGEnLCB7fSkpICE9IHsncnVudGltZS5qc29uJ30KICAgICAgICAgICAgb3IgY29uZmlnbWFwLmdldCgnYmluYXJ5RGF0YScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGltbXV0YWJsZSBydW50aW1lIGNvbmZpZyBpZGVudGl0eScpCiAgICBpZiAocHZjLmdldCgna2luZCcpICE9ICdQZXJzaXN0ZW50Vm9sdW1lQ2xhaW0nCiAgICAgICAgICAgIG9yIHB2Y1snbWV0YWRhdGEnXVsnbmFtZXNwYWNlJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJwogICAgICAgICAgICBvciBwdmNbJ21ldGFkYXRhJ11bJ25hbWUnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24tZGF0YScKICAgICAgICAgICAgb3IgcHZjLmdldCgnc3RhdHVzJywge30pLmdldCgncGhhc2UnKSAhPSAnQm91bmQnCiAgICAgICAgICAgIG9yIG5vdCBwdmMuZ2V0KCdzcGVjJywge30pLmdldCgndm9sdW1lTmFtZScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGJvdW5kIFBWQyBjdXN0b2R5JykKICAgIGNvbmZpZyA9IHByb2plY3Rpb24oY29uZmlnbWFwKQogICAgY29uZmlnLnBvcCgnZGF0YScpCiAgICBjb25maWdbJ2Nhbm9uaWNhbF9kYXRhX3NoYTI1NiddID0gaGFzaGxpYi5zaGEyNTYoanNvbi5kdW1wcygKICAgICAgICBjb25maWdtYXBbJ2RhdGEnXSwgc29ydF9rZXlzPVRydWUsIHNlcGFyYXRvcnM9KCcsJywgJzonKSkuZW5jb2RlKCkpLmhleGRpZ2VzdCgpCiAgICByZXR1cm4geydjb25maWdtYXAnOiBjb25maWcsICdwdmMnOiBwcm9qZWN0aW9uKHB2YyksICdwdmNfcGhhc2UnOiAnQm91bmQnfQoKCmRlZiBjaGVja19kZXBlbmRlbmNpZXMoY29uZmlnbWFwLCBwdmMsIHNlYWxlZCk6CiAgICBpZiBkZXBlbmRlbmN5X3Byb2plY3Rpb24oY29uZmlnbWFwLCBwdmMpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdydW50aW1lIGNvbmZpZyBvciBQVkMgaWRlbnRpdHkvY3VzdG9keSBjaGFuZ2VkJykKCgpkZWYgcHJvamVjdGlvbih2YWx1ZSk6CiAgICB2YWx1ZSA9IGNvcHkuZGVlcGNvcHkodmFsdWUpCiAgICB2YWx1ZS5wb3AoJ3N0YXR1cycsIE5vbmUpCiAgICBmb3Iga2V5IGluICgncmVzb3VyY2VWZXJzaW9uJywgJ2dlbmVyYXRpb24nLCAnY3JlYXRpb25UaW1lc3RhbXAnLCAnbWFuYWdlZEZpZWxkcycpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLnBvcChrZXksIE5vbmUpCiAgICBmb3Iga2V5IGluICgna3ViZWN0bC5rdWJlcm5ldGVzLmlvL2xhc3QtYXBwbGllZC1jb25maWd1cmF0aW9uJywgJ2RlcGxveW1lbnQua3ViZXJuZXRlcy5pby9yZXZpc2lvbicpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLmdldCgnYW5ub3RhdGlvbnMnLCB7fSkucG9wKGtleSwgTm9uZSkKICAgIHJldHVybiB2YWx1ZQoKCmRlZiBjaGVja19jdXJyZW50KGN1cnJlbnQsIHNlYWxlZCk6CiAgICBpZiBwcm9qZWN0aW9uKGN1cnJlbnQpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzZWFsZWQgbGl2ZSBVSUQgb3IgY29uZmlndXJhdGlvbiBjaGFuZ2VkJykKCgpkZWYgY2hlY2tfYWRtaXR0ZWQoYWRtaXR0ZWQsIHNlYWxlZCk6CiAgICBleHBlY3RlZCA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKQogICAgY29udGFpbmVycyA9IGV4cGVjdGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddCiAgICBpZiBsZW4oY29udGFpbmVycykgIT0gMSBvciBjb250YWluZXJzWzBdWyduYW1lJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJyBvciBjb250YWluZXJzWzBdWydpbWFnZSddICE9IEJBU0U6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigndW5leHBlY3RlZCBiYXNlbGluZSBjb250YWluZXIgaWRlbnRpdHknKQogICAgY29udGFpbmVyc1swXVsnaW1hZ2UnXSA9IENBTkRJREFURQogICAgaWYgcHJvamVjdGlvbihhZG1pdHRlZCkgIT0gZXhwZWN0ZWQ6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignYWRtaXNzaW9uIGNoYW5nZWQgY29uZmlndXJhdGlvbiBiZXlvbmQgdGhlIHNvbGUgaW1hZ2UgcGluJykKCgpkZWYgdHJhbnNwb3J0X3Jlc3VsdChleGl0X2NvZGUsIG91dHB1dCk6CiAgICBpbXBvcnQganNvbgogICAgdHJ5OgogICAgICAgIHZhbHVlID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6CiAgICAgICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdyZWFzb24nOiAnaW52YWxpZCB0cmFuc3BvcnQgcmVzdWx0J30KICAgIGlmIGV4aXRfY29kZSAhPSAwIG9yIG5vdCBpc2luc3RhbmNlKHZhbHVlLCBkaWN0KSBvciB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIG5vdCBUcnVlOgogICAgICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncmVhc29uJzogJ3JlYWQtb25seSBwcmVmbGlnaHQgcmVmdXNlZCd9CiAgICByZXR1cm4gdmFsdWUK" + }, + { + "digest": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IHJlZnJlc2g7IGV4YWN0IG9yaWdpbmFsIGNhcHR1cmUgcmVtYWlucyBpbW11dGFibGU7IG5ldmVyIGV4ZWN1dGUgY3V0b3Zlci4iIiIKaW1wb3J0IGFyZ3BhcnNlLGhhc2hsaWIsanNvbixzdWJwcm9jZXNzLHN5cwpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaWYgc3lzLmZsYWdzLm9wdGltaXplOgogcmFpc2UgU3lzdGVtRXhpdCgib3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQgYmVmb3JlIHNvdXJjZS90cmFuc3BvcnQgZXhlY3V0aW9uIikKUk9PVD1QYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50CnA9YXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKTtwLmFkZF9hcmd1bWVudCgnLS1yZWNlaXB0LW91dHB1dCcsdHlwZT1QYXRoLHJlcXVpcmVkPVRydWUpO3AuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yb290Jyx0eXBlPVBhdGgsZGVmYXVsdD1QYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24nKSk7YT1wLnBhcnNlX2FyZ3MoKQpvdXQ9YS5yZWNlaXB0X291dHB1dC5yZXNvbHZlKCkKaWYgbm90IGEucmVjZWlwdF9vdXRwdXQuaXNfYWJzb2x1dGUoKSBvciBvdXQ9PVJPT1Qgb3IgUk9PVCBpbiBvdXQucGFyZW50cyBvciBvdXQ9PWEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIG9yIGEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIGluIG91dC5wYXJlbnRzIG9yIG91dC5leGlzdHMoKToKIHJhaXNlIFN5c3RlbUV4aXQoJ3VuaXF1ZSBleGVjdXRpb24gcmVjZWlwdCBtdXN0IGJlIG91dHNpZGUgdGhlIHNlYWxlZCBwYWNrZXQnKQppbnB1dHM9anNvbi5sb2FkcygoUk9PVC8ncHJlZmxpZ2h0LWlucHV0cy5qc29uJykucmVhZF90ZXh0KCkpCmZvciByZWxhdGl2ZSxkaWdlc3QgaW4gaW5wdXRzWydwYWNrZXRfZmlsZXMnXS5pdGVtcygpOgogcGF0aD1ST09UL3JlbGF0aXZlCiBpZiBwYXRoLmlzX3N5bWxpbmsoKSBvciBoYXNobGliLnNoYTI1NihwYXRoLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCkhPWRpZ2VzdDpyYWlzZSBTeXN0ZW1FeGl0KCdzZWFsZWQgaGVscGVyL2lucHV0IGJ5dGVzIGNoYW5nZWQnKQpmb3IgcmVsYXRpdmUsZGlnZXN0IGluIGlucHV0c1snb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKToKIHBhdGg9YS5zb3VyY2Vfcm9vdC9yZWxhdGl2ZQogaWYgcGF0aC5pc19zeW1saW5rKCkgb3IgaGFzaGxpYi5zaGEyNTYocGF0aC5yZWFkX2J5dGVzKCkpLmhleGRpZ2VzdCgpIT1kaWdlc3Q6cmFpc2UgU3lzdGVtRXhpdCgnb3duZXIgc291cmNlIGJ5dGVzIGNoYW5nZWQnKQpmcm9tIGNoYW5nZV9ndWFyZCBpbXBvcnQgdHJhbnNwb3J0X3Jlc3VsdApwcm9ncmFtPSdpbXBvcnQgc3VicHJvY2Vzcyxqc29uLGhhc2hsaWIsZGF0ZXRpbWUsc3lzLGNvcHkscmVcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoIm9wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkIilcbmNhbmRpZGF0ZT1qc29uLmxvYWRzKENBTkRJREFURV9MSVRFUkFMKVxuc2VhbGVkX2RlcGVuZGVuY2llcz1qc29uLmxvYWRzKERFUEVOREVOQ0lFU19MSVRFUkFMKVxuc2VhbGVkX2Jhc2VsaW5lPWpzb24ubG9hZHMoU0VBTEVEX0xJVEVSQUwpXG5leGVjKEdVQVJEX0xJVEVSQUwpXG5kZWYgcnVuKGFyZ3MsZGF0YT1Ob25lKTpcbiBwPXN1YnByb2Nlc3MucnVuKGFyZ3MsaW5wdXQ9ZGF0YSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSlcbiBpZiBwLnJldHVybmNvZGU6IHJhaXNlIFZhbHVlRXJyb3IoXCdyZWFkLW9ubHkgY29tbWFuZCBmYWlsZWQ6IFwnK2FyZ3NbMV0rXCcgXCcrYXJnc1syXSlcbiByZXR1cm4gcC5zdGRvdXRcbmxpdmU9anNvbi5sb2FkcyhydW4oW1wna3ViZWN0bFwnLFwnZ2V0XCcsXCdkZXBsb3ltZW50XCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2luZm9ybWVkLWRlY2lzaW9uXCcsXCctb1wnLFwnanNvblwnXSkpXG5jbT1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2NvbmZpZ21hcFwnLFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcJyxcJy1uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW9cJyxcJ2pzb25cJ10pKVxucHZjPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwncHZjXCcsXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXCcsXCctblwnLFwnaW5mb3JtZWQtZGVjaXNpb25cJyxcJy1vXCcsXCdqc29uXCddKSlcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsc2VhbGVkX2RlcGVuZGVuY2llcylcbmNoZWNrX2N1cnJlbnQobGl2ZSxzZWFsZWRfYmFzZWxpbmUpXG5zcGVjPWxpdmVbXCdzcGVjXCddOyBjcz1zcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wnY29udGFpbmVyc1wnXTthc3NlcnQgbGVuKGNzKT09MSBhbmQgY3NbMF1bXCduYW1lXCddPT1cJ2luZm9ybWVkLWRlY2lzaW9uXCdcbmV4cGVjdGVkX2Vudj17XCdJTkZEX0tFWUNBUEVfSVNTVUVSXCc6XCdodHRwczovL2tjLmNvdWxvbWIuc29jaWFsXCcsXCdJTkZEX0NPTlRBSU5FUl9DT05GSUdcJzpcJy9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvblwnfVxuYXNzZXJ0IGNzWzBdLmdldChcJ2VudlwnKT09W3tcJ25hbWVcJzpcJ0lORkRfS0VZQ0FQRV9JU1NVRVJcJyxcJ3ZhbHVlXCc6ZXhwZWN0ZWRfZW52W1wnSU5GRF9LRVlDQVBFX0lTU1VFUlwnXX0se1wnbmFtZVwnOlwnSU5GRF9DT05UQUlORVJfQ09ORklHXCcsXCd2YWx1ZVwnOmV4cGVjdGVkX2VudltcJ0lORkRfQ09OVEFJTkVSX0NPTkZJR1wnXX1dXG5hc3NlcnQgY3NbMF1bXCdpbWFnZVwnXT09XCdmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcJ1xuYXNzZXJ0IHNwZWNbXCdyZXBsaWNhc1wnXT09MSBhbmQgc3BlY1tcJ3N0cmF0ZWd5XCddPT17XCd0eXBlXCc6XCdSZWNyZWF0ZVwnfVxuYXNzZXJ0IG5leHQodiBmb3IgdiBpbiBzcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wndm9sdW1lc1wnXSBpZiB2W1wnbmFtZVwnXT09XCdjb25maWd1cmF0aW9uXCcpW1wnY29uZmlnTWFwXCddW1wnbmFtZVwnXT09XCdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MVwnXG5hc3NlcnQgbGl2ZVtcJ3N0YXR1c1wnXS5nZXQoXCdyZWFkeVJlcGxpY2FzXCcpPT0xIGFuZCBsaXZlW1wnc3RhdHVzXCddLmdldChcJ3VwZGF0ZWRSZXBsaWNhc1wnKT09MVxuc2VhbGVkPXtcJ2FwaVZlcnNpb25cJzpsaXZlW1wnYXBpVmVyc2lvblwnXSxcJ2tpbmRcJzpsaXZlW1wna2luZFwnXSxcJ21ldGFkYXRhXCc6e2s6Y29weS5kZWVwY29weSh2KSBmb3Igayx2IGluIGxpdmVbXCdtZXRhZGF0YVwnXS5pdGVtcygpIGlmIGsgbm90IGluIChcJ3Jlc291cmNlVmVyc2lvblwnLFwnZ2VuZXJhdGlvblwnLFwnY3JlYXRpb25UaW1lc3RhbXBcJyxcJ21hbmFnZWRGaWVsZHNcJyl9LFwnc3BlY1wnOmNvcHkuZGVlcGNvcHkoc3BlYyl9XG5mb3Iga2V5IGluIChcJ2t1YmVjdGwua3ViZXJuZXRlcy5pby9sYXN0LWFwcGxpZWQtY29uZmlndXJhdGlvblwnLFwnZGVwbG95bWVudC5rdWJlcm5ldGVzLmlvL3JldmlzaW9uXCcpOnNlYWxlZFtcJ21ldGFkYXRhXCddLmdldChcJ2Fubm90YXRpb25zXCcse30pLnBvcChrZXksTm9uZSlcbmFkbWl0dGVkPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2FwcGx5XCcsXCctLWRyeS1ydW49c2VydmVyXCcsXCctZlwnLFwnLVwnLFwnLW9cJyxcJ2pzb25cJ10sanNvbi5kdW1wcyhjYW5kaWRhdGUpKSlcbmNoZWNrX2FkbWl0dGVkKGFkbWl0dGVkLHNlYWxlZF9iYXNlbGluZSlcbmFwcD1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2FwcGxpY2F0aW9uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2FyZ29jZFwnLFwnLW9cJyxcJ2pzb25cJ10pKVxuYXNzZXJ0IGFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCdwYXRoXCddPT1cJ2RlcGxveS9saWZlY3ljbGVcJyBhbmQgbm90IGFwcFtcJ3NwZWNcJ10uZ2V0KFwnc3luY1BvbGljeVwnLHt9KS5nZXQoXCdhdXRvbWF0ZWRcJylcbmFyZ289e1wndWlkXCc6YXBwW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdyZXBvVVJMXCc6YXBwW1wnc3BlY1wnXVtcJ3NvdXJjZVwnXVtcJ3JlcG9VUkxcJ10sXCd0YXJnZXRSZXZpc2lvblwnOmFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCd0YXJnZXRSZXZpc2lvblwnXSxcJ3BhdGhcJzphcHBbXCdzcGVjXCddW1wnc291cmNlXCddW1wncGF0aFwnXSxcJ2Rlc3RpbmF0aW9uXCc6YXBwW1wnc3BlY1wnXVtcJ2Rlc3RpbmF0aW9uXCddLFwnYXV0b21hdGVkXCc6RmFsc2UsXCdzeW5jXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdzeW5jXCcpLFwnaGVhbHRoXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdoZWFsdGhcJyl9XG5leHBlY3RlZF9hcmdvPWpzb24ubG9hZHMoQVJHT19MSVRFUkFMKVxuZm9yIGtleSBpbiAoXCd1aWRcJyxcJ3JlcG9VUkxcJyxcJ3RhcmdldFJldmlzaW9uXCcsXCdwYXRoXCcsXCdkZXN0aW5hdGlvblwnLFwnYXV0b21hdGVkXCcpOlxuIGFzc2VydCBhcmdvW2tleV09PWV4cGVjdGVkX2FyZ29ba2V5XVxuYXNzZXJ0IGFyZ29bXCdoZWFsdGhcJ11bXCdzdGF0dXNcJ109PVwnSGVhbHRoeVwnXG5kaWZmPXN1YnByb2Nlc3MucnVuKFtcJ2t1YmVjdGxcJyxcJ2RpZmZcJyxcJy1mXCcsXCctXCddLGlucHV0PWpzb24uZHVtcHMoY2FuZGlkYXRlKSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSk7YXNzZXJ0IGRpZmYucmV0dXJuY29kZSBpbiAoMCwxKVxuIyBEaWZmIGNhbiBjb250YWluIG9ubHkgbm9uc2VjcmV0IERlcGxveW1lbnQgcmVmZXJlbmNlczsgcHJlc2VydmUgZGlnZXN0IHJhdGhlciB0aGFuIHJhdyBzdGRvdXQuXG5ub2RlPXJ1bihbXCdrdWJlY3RsXCcsXCdkZXNjcmliZVwnLFwnbm9kZVwnXSk7YWxsb2NhdGVkPXJlLnNlYXJjaChyXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOi4qP0NQVSBSZXF1ZXN0c3xBbGxvY2F0ZWQgcmVzb3VyY2VzOlwnLG5vZGUscmUuUylcbnNlY3Rpb249bm9kZS5zcGxpdChcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcpWzFdLnNwbGl0KFwnRXZlbnRzOlwnKVswXSBpZiBcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcgaW4gbm9kZSBlbHNlIFwnXCdcbm5vZGVzPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwnbm9kZXNcJyxcJy1vXCcsXCdqc29uXCddKSlbXCdpdGVtc1wnXTthc3NlcnQgbGVuKG5vZGVzKT09MVxuYWxsb2M9bm9kZXNbMF1bXCdzdGF0dXNcJ11bXCdhbGxvY2F0YWJsZVwnXTtjcHU9YWxsb2NbXCdjcHVcJ107Y3B1X209aW50KGNwdVs6LTFdKSBpZiBjcHUuZW5kc3dpdGgoXCdtXCcpIGVsc2UgaW50KGNwdSkqMTAwMFxucmVxdWVzdGVkPWludChyZS5zZWFyY2goclwnY3B1XFxzKyhcXGQrKW1cJyxzZWN0aW9uKS5ncm91cCgxKSk7YXNzZXJ0IHJlcXVlc3RlZDw9Y3B1X21cbnJlY2VpcHQ9e1wnbm9kZV9hbGxvY2F0YWJsZV9jcHVfbVwnOmNwdV9tLFwnbm9kZV9yZXF1ZXN0ZWRfY3B1X21cJzpyZXF1ZXN0ZWQsXCdjYXB0dXJlZF9hdFwnOmRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpLmlzb2Zvcm1hdCgpLFwnbmF0aXZlX3dvcmtsb2FkX2NoYW5nZWRcJzpGYWxzZSxcJ25hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZFwnOkZhbHNlLFwnYXJnb1wnOmFyZ28sXCduYXRpdmVfZGVwZW5kZW5jaWVzX2NoZWNrZWRcJzpUcnVlLFwnY29uZmlnbWFwX3VpZFwnOmNtW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdwdmNfdWlkXCc6cHZjW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdsaXZlX3JlYWR5X3JlcGxpY2FzXCc6MSxcJ2FkbWl0dGVkX3VpZFwnOmFkbWl0dGVkW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWRcJzpUcnVlLFwnYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZVwnOlRydWUsXCdjbGllbnRfZGlmZl9leGl0XCc6ZGlmZi5yZXR1cm5jb2RlLFwnY2xpZW50X2RpZmZfc2hhMjU2XCc6aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpLFwnbm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzXCc6c2VjdGlvbi5zdHJpcCgpLFwnYWxsX2NoZWNrc19wYXNzXCc6VHJ1ZX1cbnByaW50KGpzb24uZHVtcHMocmVjZWlwdCkpXG4nCmZvciBtYXJrZXIsdmFsdWUgaW4gWygnREVQRU5ERU5DSUVTX0xJVEVSQUwnLChST09ULydzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLCgnQ0FORElEQVRFX0xJVEVSQUwnLChST09ULydjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLCgnU0VBTEVEX0xJVEVSQUwnLChST09ULydzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksKCdHVUFSRF9MSVRFUkFMJywoUk9PVC8nY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpLCgnQVJHT19MSVRFUkFMJyxqc29uLmR1bXBzKGpzb24ubG9hZHMoKFJPT1QvJ25hdGl2ZS1wcmVmbGlnaHQuanNvbicpLnJlYWRfdGV4dCgpKVsnYXJnbyddKSldOgogcHJvZ3JhbT1wcm9ncmFtLnJlcGxhY2UobWFya2VyLHJlcHIodmFsdWUpKQpwcm9ncmFtPSdpbXBvcnQgdHJhY2ViYWNrLGpzb25cbnRyeTpcbicrJycuam9pbignICAgICcrbGluZSsnXG4nIGZvciBsaW5lIGluIHByb2dyYW0uc3BsaXRsaW5lcygpKSsiZXhjZXB0IEV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICBwcmludChqc29uLmR1bXBzKHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZSwnZXhjZXB0aW9uX3R5cGUnOnR5cGUoZXJyb3IpLl9fbmFtZV9fLCdleGNlcHRpb25fbGluZSc6dHJhY2ViYWNrLmV4dHJhY3RfdGIoZXJyb3IuX190cmFjZWJhY2tfXylbLTFdLmxpbmVub30pKVxuIgpyPXN1YnByb2Nlc3MucnVuKFsnc3NoJywncmFpbGlhbmNlMDEnLCdweXRob24zIC0nXSxpbnB1dD1wcm9ncmFtLHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlKQpyZXN1bHQ9dHJhbnNwb3J0X3Jlc3VsdChyLnJldHVybmNvZGUsci5zdGRvdXQpO3Jlc3VsdFsnc2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2J109aGFzaGxpYi5zaGEyNTYoKFJPT1QvJ3ByZWZsaWdodC1pbnB1dHMuanNvbicpLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCk7cmVzdWx0WydmcmVzaF9leGVjdXRpb25fcmVjZWlwdCddPVRydWUKb3V0LndyaXRlX3RleHQoanNvbi5kdW1wcyhyZXN1bHQsaW5kZW50PTIpKydcbicpO3ByaW50KGpzb24uZHVtcHMocmVzdWx0LGluZGVudD0yKSk7c3lzLmV4aXQoMCBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgMSkK" + }, + { + "digest": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "media_type": "application/json", + "content_base64": "ewogICJwYWNrZXRfZmlsZXMiOiB7CiAgICAiY2hhbmdlX2d1YXJkLnB5IjogImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmUiLAogICAgInByZWZsaWdodC5weSI6ICI2YjRjNjVmNzA4MjM4YzlhOWQxN2ZkMDY1ODc2YzdhMDBlMWYxNzQ1OTI2Zjk5MGExZGQ1ZTY2NzI5ODM0MGNkIiwKICAgICJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uIjogIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGUiLAogICAgInJvbGxiYWNrLWRlcGxveW1lbnQuanNvbiI6ICIzOWIzZjQzYmI4NGVmNDkyMWNjM2ExZmJjZGM0NDQ2MTA3NDFlZDg4MDkxNDlkOGY4ZjE3ZWQ4MDVmMjYyMTIxIiwKICAgICJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24iOiAiZDE4ZDI3MDYzZDA2ZjUzNWFlODg0ZWEwMWY5Njc0N2ZlMzAxNjg1NTE4YWI5NGIxY2JhMDcyYTFlMTUxOTM2MiIsCiAgICAibmF0aXZlLXByZWZsaWdodC5qc29uIjogImViNWY0MWFlZmI5NzY2NmJiMGMxMjc5NjE3ZTk1YTdjMDUwMTdhNjA5NDE1NjI0ZGFlZTcyNGM0OGI5MGQyNjIiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAic3FsaXRlX3JlYWRvbmx5LnB5IjogImVlZjUzZGQyMzNlZWU3NGMxN2YyMDgyM2JkN2Y1Nzg3YzYwY2FkNzlhYzY0ODAyMWM5NDc5NjQzYzZjZTllMzgiCiAgfSwKICAib3duZXJfc291cmNlX2ZpbGVzIjogewogICAgImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uIjogIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTUiLAogICAgImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbiI6ICIzOGI3OGI5Y2JlZTVhZGU3NzUwYTU4ZDUxNTZjYTRjNTc3MzM1MmU5NDdhY2IzMDRlZTcxNGI1OWU3NDljZWI0IgogIH0KfQo=" + }, + { + "digest": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7", + "media_type": "application/json", + "content_base64": "ewogICJub2RlX2FsbG9jYXRhYmxlX2NwdV9tIjogNDAwMCwKICAibm9kZV9yZXF1ZXN0ZWRfY3B1X20iOiAzNDYwLAogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjM5OjE0LjIzNDI3NyswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibmF0aXZlX2RlcGVuZGVuY2llc19jaGVja2VkIjogdHJ1ZSwKICAiY29uZmlnbWFwX3VpZCI6ICI5MDExM2QyZC01NGQ5LTRlODItYjFkMy05MGI0OWViZWQyYjUiLAogICJwdmNfdWlkIjogImQ4MGIyNWIxLTE0MWEtNDQxYi1iMjA1LTk4ZmEyZmQ5OGI3YyIsCiAgImxpdmVfcmVhZHlfcmVwbGljYXMiOiAxLAogICJhZG1pdHRlZF91aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIiwKICAic2VydmVyX2RyeV9ydW5fcGFzc2VkIjogdHJ1ZSwKICAiYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZSI6IHRydWUsCiAgImNsaWVudF9kaWZmX2V4aXQiOiAxLAogICJjbGllbnRfZGlmZl9zaGEyNTYiOiAiODQwNzY5YzdkMmE5YzE2NTVjNDBhMzI1OWY4MzNkMWZjOGY2OTk1MGNlYjNiZWRiNzA3YTk1NWZlZDcxMTU2NiIsCiAgIm5vZGVfYWxsb2NhdGVkX3Jlc291cmNlcyI6ICIoVG90YWwgbGltaXRzIG1heSBiZSBvdmVyIDEwMCBwZXJjZW50LCBpLmUuLCBvdmVyY29tbWl0dGVkLilcbiAgUmVzb3VyY2UgICAgICAgICAgIFJlcXVlc3RzICAgICAgTGltaXRzXG4gIC0tLS0tLS0tICAgICAgICAgICAtLS0tLS0tLSAgICAgIC0tLS0tLVxuICBjcHUgICAgICAgICAgICAgICAgMzQ2MG0gKDg2JSkgICAzNjIwMG0gKDkwNSUpXG4gIG1lbW9yeSAgICAgICAgICAgICA5NDcyTWkgKDU5JSkgIDMyODk4TWkgKDIwNSUpXG4gIGVwaGVtZXJhbC1zdG9yYWdlICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMUdpICAgICAgMCAoMCUpICAgICAgICAwICgwJSlcbiAgaHVnZXBhZ2VzLTJNaSAgICAgIDAgKDAlKSAgICAgICAgMCAoMCUpIiwKICAiYWxsX2NoZWNrc19wYXNzIjogdHJ1ZSwKICAic2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2IjogIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDYiLAogICJmcmVzaF9leGVjdXRpb25fcmVjZWlwdCI6IHRydWUKfQo=" + } + ] + }, + "publish": { + "version": 1, + "audience": { + "subjects": [], + "groups": [ + "net-kingdom-admins" + ] + } + }, + "review": { + "version": 1, + "options": { + "submitter": "state-hub", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + } + } + } + } +] diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json new file mode 100644 index 0000000..f83c393 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json @@ -0,0 +1,141 @@ +{ + "id": "infd-20261011-purpose-overlay-r1", + "version": 1, + "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md new file mode 100644 index 0000000..e9374f6 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md @@ -0,0 +1,68 @@ +# Protected native backup/restore and image-only release protocol + +Prepared protocol for `INFD-WP-0009-T04/purpose-overlay-v1`. No actual native backup, data export, restore, workload change or approval is recorded here. Candidate registry image identity remains a prerequisite; only after actual artifact proof may the founder approve one exact conditional protocol/rollout packet. The config-only7db8485 approval is outside this scope. + +## Preconditions and protected custody + +Freeze exact candidate and prior7f5c6cb image digests, source/installed policy hashes, current manually managed Argo Application/revision, runtime ConfigMap6c221878d051, Deployment UID/template/spec, schema5, policy package pins, database path `/data/private/review.sqlite`, PVC binding, replicas1/Recreate and stable keys for intended verification. Confirm no concurrent writer or custody change. Use fixed metadata; never fetch Secret objects or token values. A changed image/config/schema/owner invalidates the packet. Fresh resources/headroom and exact source/native server-dry-run/diff remain required. + +Backups are private evidence containing real decision records, not logs or packet attachments. Allocate a unique backup directory under existing protected PVC custody, owned10001, mode0700, snapshot file0600, no symlink/hardlink/reused output path. An off-cluster copy belongs only in the already established ignored `.private-backups/` custody with0700/0600 permissions; no Git, StateHub, public object store or terminal-content dump. Record only schema, integrity pass/fail, bounded table/state counts and protected receipt identifier; retain byte digests in protected custody if needed for internal copy identity. No credential, record payload or token fingerprint enters public evidence. + +## Approved online compatibility drill + +Within the explicit founder-approved action, run the existing base image's `informed-decision-admin backup --db /data/private/review.sqlite --output ` in the actual serving workload. This uses SQLite's backup API for a transactionally consistent snapshot; copying a live main database while ignoring WAL is prohibited. Suppress raw failures/output and retain only sanitized status. Observe schema/integrity and count-only metadata from the resulting snapshot, not record content. + +Transfer that consistent snapshot only into protected off-cluster custody through the existing authorized operator lane. The copy is real production data even in build mode. Verify private permissions, unique identity and protected internal digest agreement. Do not export mounted workload credentials or directory trees; copy only the exact snapshot. + +Create a separate private disposable restore volume/directory; retain the original snapshot unchanged. Run the exact published candidate with network disabled, no production ConfigMap/token mounts, read-only image and only that isolated volume writable. Override the service entrypoint with the owner's count-only administrative inspection/integrity check; do not start HTTP listeners, audit delivery, requester exchanges or approval operations. The current candidate changes policy.py only and retains the schema/store module bytes; still prove schema5, SQLite integrity and exact bounded counts before/after opening the restored copy. Refuse any migration/downgrade, lost/changed counts, unexpected write class or unknown outcome. Keep pending/uncertain submission and outbox states; never replay, discard or mark them delivered to green the drill. Cleanup only the disposable copy/volume after verified receipt; retain the original protected backup for the approved recovery interval. + +This step is actual native-data compatibility evidence once performed. Its previous synthetic fixture checks remain mechanism evidence and cannot be renamed native success. A failed drill stops rollout and remains a failed/unverified outcome in the same trial. + +## Fresh cutover snapshot and single-writer rollout + +After successful actual-data compatibility checks, create another unique SQLite-consistent online snapshot immediately before the image cutover, retaining its point-in-time schema/integrity/count receipt. This is an online transactional snapshot, not a claim that dispatchers or human writes were quiesced. Every later committed record remains in the live database; same-schema rollback retains that database and never restores the earlier snapshot over it. The narrow image-only update does not need dispatcher/configuration/PVC/temporary-pod changes or a schema cutover. If fresh verification shows a migration or any data-restoration requirement, stop and refine the proposal rather than applying this protocol. + +The existing Recreate rollout drains/stops the single old writer before starting the new image on the same PVC; the inherited single-writer lock independently refuses concurrent serving processes. Do not add an admin pod, scale-to-zero, dispatcher stop, network-policy rewrite or snapshot overwrite as an improvised image-only step. The existing owner admin backup operation runs inside the admitted serving workload, and its separate protected restore drill runs off-cluster with network disabled and no workload credentials. Those exact custody operations must be enumerated in the founder packet alongside the one Deployment image change. + +Once backup/compatibility/preflight gates pass, manually pin the existing Argo Application to the exact reviewed source revision and sync only Deployment/informed-decision with prune false, keeping the current immutable runtime ConfigMap and all other resources. The source patch changes only the image in admission/rendered Deployment; no Secret, PVC, policy, database or dispatcher change is included unless separately enumerated in the final proposal. Observe five-minute readiness and exact image/config/schema/pins. Run the ten installed purpose variants on the actual native placement using synthetic transport; they prove exact installed module refusal behavior and explicitly report native_provider=false. They do not prove an actual provider response, PDP authority or native lifecycle binding; any required actual-provider proof remains a distinct T04 completion gate with separate authorized preparation, and must not be claimed by this helper. Do not contaminate the live PDP, create human approvals, read credentials through CLI, or replay unknown external outcomes for testing. + +## Same-schema rollback and evidence retention + +On startup/readiness/binding/refusal failure, retain current database, cutover backup and every post-cutover evidence/uncertain outcome. Restore only the prior7f5c6cb image through the same manual Argo owner path, retaining schema5 and current DB/configuration; never restore an old snapshot over current live evidence just to roll the image back. Verify old image/Ready1, same schema/counts and prior behavior, and reconcile any external effects using existing lifecycle/audit ownership. The narrow overlay's identical store/schema/dependency bytes permit this image-only rollback; it is not permission for a schema downgrade or data loss. + +Record original/approved/executed source and image revisions, backup/drill/cutover/rollout timestamps, exact disposition and sanitized outcomes in the existing supervised trial receipt. EUR0 incremental infrastructure estimate uses existing service/storage/operator lane; protected temporary copy/storage consumption and15–30minute recovery time remain operational costs. No EUR incident-loss cap or autonomy grant is inferred. TaskT04 cannot close until actual published image, approved native compatibility and release plus post-release refusal/binding evidence all exist. + +## Exact release case identifiers + +Proposal `INFD-WP-0009-T04/purpose-overlay-v1`, trial `infd-purpose-20261011-r1`. +Protected native parent `/data/private/purpose-overlay-r1` must be unique/non-symlink, owned10001 and0700. The drill snapshot is `drill.sqlite`, the refreshed pre-cutover snapshot `cutover.sqlite`, each new0600 file; refuse any existing output. Off-cluster custody is the existing ignored Custodian `.private-backups/20261011-infd-purpose-r1` parent0700, files0600; no snapshot is an evidence attachment. Check owner UID, no symlinks, ignored status and free capacity for both native snapshots plus independently protected copies before making any snapshot. + +The disposable offline restore volume is `infd-purpose-r1-restore-20261011`; refuse an existing volume, copy only the selected frozen snapshot, and run exact published candidate763c with networknone/read-only image,128MiB/core1 and no runtime config/token mounts. SQLite `PRAGMA integrity_check` must return `ok`, `PRAGMA user_version`/Store inspection must agree with actual schema5 semantics, and installed admin count-only inspection must match the frozen snapshot. Validate the actual schema representation rather than assume PRAGMA user_version is the schema authority. No synthetic restoration is reported as native restoration. Native original/off-cluster copies remain retained; only the disposable restore copy/volume may be removed under the exact approved cleanup scope. + +## Mandatory pre-open schema gate and offline command + +`informed-decision-admin inspect` and `backup` construct Store, which can migrate schemas1–4 to5. Therefore **before any Store/admin open**, run the exact attached stdlib-only `sqlite_readonly.py` against the native source database using SQLite URI mode=ro, query_only and one read transaction. Require PRAGMA user_version5, integrity_check=ok and retain count-only baseline. Refuse any other/unknown schema or incomplete integrity/count check before constructing Store; do not infer no migration from a post-open admin report. This native gate has not been executed in this source-preparation stage. Repeat before each native backup/admin operation. + +After copying the selected consistent snapshot to the isolated restored private path `/restore/review.sqlite`, run the same read-only checker **before** any offline candidate admin/Store opens that copy. Frozen snapshot and restored-copy schema/integrity/count reports must agree exactly; the copied main-file digest must match the selected closed snapshot. Reject oldschema fixtures rather than allow migration. Only after this pre-open gate may the offline candidate admin inspect run. + +Offline command vectors use exactimage `forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a`, `--network none --read-only --cpus 1 --memory 128m`, private restored volume mounted at `/restore`, and **no runtime config/credential/token mounts**. First override entrypoint to `python`, arguments `- --db /restore/review.sqlite`, streaming only the verified attached checker on stdin. Then override entrypoint to **`informed-decision-admin`**, arguments **`inspect --db /restore/review.sqlite`**. This does not start `informed-decision-container`, the HTTP service, dispatcher or delivery workers. Compare the admin's schema/lifecycle/outbox/submission counters to the frozen pre-open snapshot report; integrity and migration-free pre-open proof come from the stdlib checker, not admin output alone. + +Live reads and online snapshots may legitimately differ because reviews, intake and delivery can commit concurrently. Exact counter equality is required between the frozen selected snapshot and its offline restored clone; it is **not** required between a running post-cutover/rollback database and an earlier snapshot. Live count changes must be accounted for as legitimate committed records/state transitions; preserve all current and uncertain entries. Do not discard new commits or restore the old snapshot to force equality. Same-schema image rollback keeps the current live DB, followed by read-only schema5/integrity and count-only health checks; any unexplained evidence loss or required data recovery stops and requires a separate founder decision. + +The fresh preflight also independently reads the actual immutable nonsecret ConfigMap and bound PVC: compares sealed UIDs/fullmetadata/PVCspec+volumeName and canonical runtime data checksum, returning no raw runtime data. Same-name deletion/recreation or content/custody drift stops before admission. Secret values remain excluded. Both local and remote optimized Python interpreters are explicitly refused before assertion-based gates. + +## Exact supervised mechanical execution refinement + +The directly attached `execution-bundle.json` contains the exact helper source, plan, tests and PENDING receipt template. It replaces the direct raw scan attachment within the twenty-document limit; `published-verification.json` still binds the unchanged actual unfiltered raw scan, raw SBOM and base scan SHA256 values, retained in the owner evidence package. The known inherited fixable MEDIUM remains explicit, with owner T05/risk follow-through. Neither archive nor technical agreement supplies human approval. + +The reviewed protocol basis is owner commit e0359bcb6cdfad9ab3e868054121fe0cebec2d68, with source follow-through9268c9ac0bbee508fe35c0b90dcefef4c24da2f5. The subsequent exact applied helper/packet owner commit must be named in the externally verified founder receipt before execution. Verify the four committed Git blobs (admission.candidate.json, service.candidate.json, kustomization.yaml, registries.candidate.json) against execution-plan.json as well as current worktree/HEAD; reject overrides/plugins/multiple Application sources and any present automated configuration, including automated:{}. + +Root freshly authenticates the exact confirmed founder person/platform-root ACCEPT of this stable memo/version1 at the fixed native Informed Decision origin before each phase, and supplies protected0600 receipt/outcome files. The helper checks their exact relation and freshness120seconds; these files are supervised bookkeeping, not signed authenticated grants, a human-provider implementation, or autonomous agent authority. Do not derive them from technical reviews or caller assertions. + +Fixed order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. A separate recorded release attempt permits rollback → rollback-verify. Every phase fsyncs an attempt nonce/RUNNING journal before effects. Failure/interruption/ambiguous actuation stays UNCERTAIN and the same phase cannot be retried. No improvised adapter or whole-Application sync is permitted. + +The NEW nonce-labelled local volume requires one explicit isolated initializer as UID0:0 with only CAP_CHOWN, exact763c image, --network none --read-only --cpus 1 --memory 128m --cap-drop ALL --cap-add CHOWN --security-opt no-new-privileges. Its only mount is that new named volume at /restore; no host mount, native PVC, runtime config or token mount. Protected snapshot stdin goes only to a unique0600 main file with exact digest, and directory/file custody is set0700/0600 UID/GID10001. Then all pre-open, admin and post-admin checks run UID10001:10001, capabilities dropped, networknone. The second stdlib readonly schema5/integrity/count proof after admin must exactly equal the frozen snapshot proof; independently recheck the retained original protected snapshot SHA. No service startup occurs. + +Rollback dispatch must be available if the candidate is unready or cannot start: it checks sealed Deployment/CM/PVC custody, only prior/candidate source/image pair, node health/headroom and fresh old-image server admission plus Application UID/resourceVersion/source CAS, with no failing candidate Pod/exec/database prerequisite. Dispatch acknowledgment is not recovered health. `rollback-verify` separately requires old image Ready1, succeeded exact Deployment-only/prune=false operation and readonly schema5/integrity/count proof of the latest retained live database. No snapshot replaces the current database. + +**Deadline refinement:** all phases, including rollback and verification, must begin before2026-10-12T23:59:59Z. The earlier amended packet described unstarted-release expiry; this exact helper also bounds recovery/verification. Start early enough to complete the bounded drill and any recovery within the window. If exhausted, stop and obtain a fresh founder decision rather than silently extend a grant. This may delay recovery and is an explicit operational risk. No timer/controller automatically rolls back or changes service at expiry. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json new file mode 100644 index 0000000..10603b4 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json @@ -0,0 +1,43 @@ +{ + "captured_at": "2026-10-11T01:25:38.793555+00:00", + "native_workload_changed": false, + "native_backup_restore_executed": false, + "argo": { + "uid": "499868f2-eabc-4df4-ae31-b89ce58d750d", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "path": "deploy/lifecycle", + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "automated": false, + "sync": { + "comparedTo": { + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "source": { + "path": "deploy/lifecycle", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf" + } + }, + "revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "status": "OutOfSync" + }, + "health": { + "lastTransitionTime": "2026-10-10T23:14:52Z", + "status": "Healthy" + } + }, + "live_ready_replicas": 1, + "admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92", + "server_dry_run_passed": true, + "admitted_spec_exactly_live_plus_image": true, + "client_diff_exit": 1, + "client_diff_sha256": "a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d", + "node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)", + "all_checks_pass": true +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json new file mode 100644 index 0000000..8fd7728 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json @@ -0,0 +1,786 @@ +[ + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/README.md", + "original_sha256": "ca2c34727a462c63f017700f703324d934f5fa3adc858c2756d62096b119c40c", + "staged_sha256": "c866ca0d026e25612f5c8404a7668ea7142d19065c93d33dec996f5821e53af1" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/combined-source-boundary-validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/combined-source-boundary-validation.json", + "original_sha256": null, + "staged_sha256": "877f93485c1a6817bdfde257051f202d33e14f0ee54e03e597043c8924723337" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "original_sha256": "23da78cf998a32af0481e68567db94bb40781cc18f147461f779d40ebd329fd1", + "staged_sha256": "a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/README.md", + "original_sha256": null, + "staged_sha256": "a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py", + "original_sha256": null, + "staged_sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py", + "original_sha256": null, + "staged_sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json", + "original_sha256": null, + "staged_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py", + "original_sha256": null, + "staged_sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json", + "original_sha256": null, + "staged_sha256": "ef370a491468df28683f3002cb6e8bbb7e47b65e8e4d02ff4d09e9c39f020c8a" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/receipt_safety.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/receipt_safety.py", + "original_sha256": null, + "staged_sha256": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json", + "original_sha256": null, + "staged_sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py", + "original_sha256": null, + "staged_sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/validation.json", + "original_sha256": null, + "staged_sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json", + "original_sha256": null, + "staged_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/README.md", + "original_sha256": null, + "staged_sha256": "91d7b3c36498629bb4632b2a45cd75b67bf3a8ce8ab924d6a754a67410fadf6f" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/actuator.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/actuator.py", + "original_sha256": null, + "staged_sha256": "faf019cd011dee1032d3f309e85b1f1b0bf5f333d6e279701c3f7e233d54fe23" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/authority_journal.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/authority_journal.py", + "original_sha256": null, + "staged_sha256": "55e441b1af7288540c31ea4733c3471559a2100a26fae8b6b0ed415e04d469a5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/execution-plan.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/execution-plan.json", + "original_sha256": null, + "staged_sha256": "4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/native_program.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/native_program.py", + "original_sha256": null, + "staged_sha256": "3ad4fe28d0556a001f6334f3f8267d1e21d76e17db9765d3cc35b679a9db9ec5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/packet-refinement.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/packet-refinement.json", + "original_sha256": null, + "staged_sha256": "003f08e4ff4abe96478f1db9d5b13e4a49a16cdc724090ba0d40a9f7e8440624" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/receipt_safety.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/receipt_safety.py", + "original_sha256": null, + "staged_sha256": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/root-authority-receipt-template.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/root-authority-receipt-template.json", + "original_sha256": null, + "staged_sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/test_execution.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/test_execution.py", + "original_sha256": null, + "staged_sha256": "d4f20fba850f0303a87971d2498bccc894ab39b7584ce98756e1c536e517fb18" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/validation.json", + "original_sha256": null, + "staged_sha256": "abefda88f48ae455205cf6c27033fa81f99e89baea9ffffb8c26749a53815a39" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution-bundle.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution-bundle.json", + "original_sha256": null, + "staged_sha256": "0a79eda40fe0954fd3828bf06fd6ccf149e294ac194bc6fe605e585b878fa8d3" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/original-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/original-manifest.json", + "original_sha256": null, + "staged_sha256": "653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/archive-map.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/archive-map.json", + "original_sha256": null, + "staged_sha256": "7b3ddb4cf2b459676f744bc8312ced37be76356f9acbdbe5e7e92c2b137e7b62" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/original-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/original-manifest.json", + "original_sha256": null, + "staged_sha256": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/service.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/service.candidate.json", + "original_sha256": null, + "staged_sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "original_sha256": null, + "staged_sha256": "ca2c34727a462c63f017700f703324d934f5fa3adc858c2756d62096b119c40c" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "original_sha256": null, + "staged_sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "original_sha256": null, + "staged_sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "original_sha256": null, + "staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "original_sha256": null, + "staged_sha256": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "original_sha256": null, + "staged_sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "original_sha256": null, + "staged_sha256": "23da78cf998a32af0481e68567db94bb40781cc18f147461f779d40ebd329fd1" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "original_sha256": null, + "staged_sha256": "2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "original_sha256": null, + "staged_sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "original_sha256": null, + "staged_sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "original_sha256": null, + "staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json", + "original_sha256": null, + "staged_sha256": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json", + "original_sha256": null, + "staged_sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "original_sha256": null, + "staged_sha256": "f88a79a93fff34a1b438e2dc0344cad88d6c7960dde04bc7f3c04ac1fbb992c7" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "original_sha256": null, + "staged_sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "original_sha256": null, + "staged_sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "original_sha256": null, + "staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "original_sha256": null, + "staged_sha256": "830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "original_sha256": null, + "staged_sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "original_sha256": null, + "staged_sha256": "7f6d8987f65dff479eeead67b7ca940ef44c22c1cdbdd6ca33fd732b824c8f02" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "original_sha256": null, + "staged_sha256": "aa1d494e42491f0619f731a836c597df9178409887d734c166a8df81f8807a27" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "original_sha256": null, + "staged_sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "original_sha256": null, + "staged_sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "original_sha256": null, + "staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "original_sha256": null, + "staged_sha256": "9a39631362f20168da409cef74f7690f3aa1b8f841fc96ecd8770f73a1f954ac" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "original_sha256": null, + "staged_sha256": "b6210dcd34e5485c94e35f4bdd3329fb72c1d40fa9357caf40ac42b4f8afa5c2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "original_sha256": null, + "staged_sha256": "06530425dd9634182f70a65dd2da56cbad3da967bc842b3c7b01c30542222128" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "original_sha256": null, + "staged_sha256": "aa9758d4de587d14c6ce0fdaccd84002c5c5099425b9169ca7c972a86e9d3dec" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "original_sha256": null, + "staged_sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "original_sha256": null, + "staged_sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "original_sha256": null, + "staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "original_sha256": null, + "staged_sha256": "0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "original_sha256": null, + "staged_sha256": "c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "original_sha256": null, + "staged_sha256": "08c5573eaad05efd24b6df6737d33e7189543eb621f21704e38bab4326094914" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "original_sha256": null, + "staged_sha256": "e304dd29571bf7d7b9f1db2ade0163dd39cfec012a5ce6986139f019f37e65a2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "original_sha256": null, + "staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "original_sha256": null, + "staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "original_sha256": null, + "staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "original_sha256": null, + "staged_sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "original_sha256": null, + "staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "original_sha256": null, + "staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "original_sha256": null, + "staged_sha256": "b7cd28b2ada33004c9264cb54c9749fa501f60166638f926e50e264ddebe037d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "original_sha256": null, + "staged_sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "original_sha256": null, + "staged_sha256": "3b57f525bbbb1db9dc46bcc6b0057a8dd9f45c461fad0a8dea5391ca78038c36" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "original_sha256": null, + "staged_sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt", + "original_sha256": null, + "staged_sha256": "18205c0c7aa8f3460d78e3b7ad9dddd9e361395f9a28d93a7a384c29c9602d36" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "original_sha256": null, + "staged_sha256": "f61da7bf60e42728c2ef2f98838f310e9f97765096015492917ef8e9cab2d000" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "original_sha256": null, + "staged_sha256": "c25d47a084401aafe4f17b9e9ac87bf099d7c9f423bd181509617314884bd28a" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "original_sha256": null, + "staged_sha256": "33a321fe0c276733034288e7395496cb52c8eaf7730da880637cfa379276978c" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "original_sha256": null, + "staged_sha256": "2f8d4894c2861b34977ec020593b7515a8ee35a43ce2e6aef2d96a6d34a94ddc" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "original_sha256": null, + "staged_sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "original_sha256": null, + "staged_sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "original_sha256": null, + "staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "original_sha256": null, + "staged_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "original_sha256": null, + "staged_sha256": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "original_sha256": null, + "staged_sha256": "a59bcddc6c79e3ba8265a95b4b68facda2683abda8e47e5bb48ce402b9e1fa82" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "original_sha256": null, + "staged_sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "original_sha256": null, + "staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/review-refinement.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/review-refinement.json", + "original_sha256": null, + "staged_sha256": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "original_sha256": null, + "staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "original_sha256": null, + "staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "original_sha256": null, + "staged_sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "original_sha256": null, + "staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json", + "original_sha256": null, + "staged_sha256": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "original_sha256": null, + "staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py", + "original_sha256": null, + "staged_sha256": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "original_sha256": null, + "staged_sha256": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py", + "original_sha256": null, + "staged_sha256": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py", + "original_sha256": null, + "staged_sha256": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "original_sha256": null, + "staged_sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "original_sha256": null, + "staged_sha256": "303490dd5a89da0ea2ea92149cfa7cd580e8f3270d3db42edae1c59e4aaf42ca" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "original_sha256": null, + "staged_sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.source.txt", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.source.txt", + "original_sha256": null, + "staged_sha256": "24e4b022f17ca041ccfbfb11d6de6373c90f4e790690e1cd4cf00e84fde6b838" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/intake.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "original_sha256": "f61da7bf60e42728c2ef2f98838f310e9f97765096015492917ef8e9cab2d000", + "staged_sha256": "4947868e1bf7ac07ff7cb00d29188e591adcc7faad74a5d1b24a38656210cc3e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "original_sha256": "c25d47a084401aafe4f17b9e9ac87bf099d7c9f423bd181509617314884bd28a", + "staged_sha256": "de159c1ef1bb3fc4fea9bbc1deae14d03ecd2f891d608a5dfb78f00799337574" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/memo.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "original_sha256": "33a321fe0c276733034288e7395496cb52c8eaf7730da880637cfa379276978c", + "staged_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "original_sha256": "2f8d4894c2861b34977ec020593b7515a8ee35a43ce2e6aef2d96a6d34a94ddc", + "staged_sha256": "440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "original_sha256": "a59bcddc6c79e3ba8265a95b4b68facda2683abda8e47e5bb48ce402b9e1fa82", + "staged_sha256": "7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "original_sha256": "303490dd5a89da0ea2ea92149cfa7cd580e8f3270d3db42edae1c59e4aaf42ca", + "staged_sha256": "044775a8cbdf9c7c2fdc9e020b33a90d5366d60584807b87604df2b2a9f88638" + } +] diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json new file mode 100644 index 0000000..d7ded46 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json @@ -0,0 +1,16 @@ +{ + "packet_files": { + "change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "preflight.py": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "native-preflight.json": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + "owner_source_files": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4" + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py new file mode 100644 index 0000000..e7d6e22 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py @@ -0,0 +1,25 @@ +"""Read-only refresh; exact original capture remains immutable; never execute cutover.""" +import argparse,hashlib,json,subprocess,sys +from pathlib import Path +if sys.flags.optimize: + raise SystemExit("optimized interpreter refused before source/transport execution") +ROOT=Path(__file__).resolve().parent +p=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args() +out=a.receipt_output.resolve() +if not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists(): + raise SystemExit('unique execution receipt must be outside the sealed packet') +inputs=json.loads((ROOT/'preflight-inputs.json').read_text()) +for relative,digest in inputs['packet_files'].items(): + path=ROOT/relative + if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed') +for relative,digest in inputs['owner_source_files'].items(): + path=a.source_root/relative + if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed') +from change_guard import transport_result +program='import subprocess,json,hashlib,datetime,sys,copy,re\nif sys.flags.optimize:raise RuntimeError("optimized interpreter refused")\ncandidate=json.loads(CANDIDATE_LITERAL)\nsealed_dependencies=json.loads(DEPENDENCIES_LITERAL)\nsealed_baseline=json.loads(SEALED_LITERAL)\nexec(GUARD_LITERAL)\ndef run(args,data=None):\n p=subprocess.run(args,input=data,text=True,capture_output=True)\n if p.returncode: raise ValueError(\'read-only command failed: \'+args[1]+\' \'+args[2])\n return p.stdout\nlive=json.loads(run([\'kubectl\',\'get\',\'deployment\',\'informed-decision\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\ncm=json.loads(run([\'kubectl\',\'get\',\'configmap\',\'informed-decision-runtime-6c221878d051\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\npvc=json.loads(run([\'kubectl\',\'get\',\'pvc\',\'informed-decision-data\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\ncheck_dependencies(cm,pvc,sealed_dependencies)\ncheck_current(live,sealed_baseline)\nspec=live[\'spec\']; cs=spec[\'template\'][\'spec\'][\'containers\'];assert len(cs)==1 and cs[0][\'name\']==\'informed-decision\'\nexpected_env={\'INFD_KEYCAPE_ISSUER\':\'https://kc.coulomb.social\',\'INFD_CONTAINER_CONFIG\':\'/configuration/runtime.json\'}\nassert cs[0].get(\'env\')==[{\'name\':\'INFD_KEYCAPE_ISSUER\',\'value\':expected_env[\'INFD_KEYCAPE_ISSUER\']},{\'name\':\'INFD_CONTAINER_CONFIG\',\'value\':expected_env[\'INFD_CONTAINER_CONFIG\']}]\nassert cs[0][\'image\']==\'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\'\nassert spec[\'replicas\']==1 and spec[\'strategy\']=={\'type\':\'Recreate\'}\nassert next(v for v in spec[\'template\'][\'spec\'][\'volumes\'] if v[\'name\']==\'configuration\')[\'configMap\'][\'name\']==\'informed-decision-runtime-6c221878d051\'\nassert live[\'status\'].get(\'readyReplicas\')==1 and live[\'status\'].get(\'updatedReplicas\')==1\nsealed={\'apiVersion\':live[\'apiVersion\'],\'kind\':live[\'kind\'],\'metadata\':{k:copy.deepcopy(v) for k,v in live[\'metadata\'].items() if k not in (\'resourceVersion\',\'generation\',\'creationTimestamp\',\'managedFields\')},\'spec\':copy.deepcopy(spec)}\nfor key in (\'kubectl.kubernetes.io/last-applied-configuration\',\'deployment.kubernetes.io/revision\'):sealed[\'metadata\'].get(\'annotations\',{}).pop(key,None)\nadmitted=json.loads(run([\'kubectl\',\'apply\',\'--dry-run=server\',\'-f\',\'-\',\'-o\',\'json\'],json.dumps(candidate)))\ncheck_admitted(admitted,sealed_baseline)\napp=json.loads(run([\'kubectl\',\'get\',\'application\',\'informed-decision\',\'-n\',\'argocd\',\'-o\',\'json\']))\nassert app[\'spec\'][\'source\'][\'path\']==\'deploy/lifecycle\' and not app[\'spec\'].get(\'syncPolicy\',{}).get(\'automated\')\nargo={\'uid\':app[\'metadata\'][\'uid\'],\'repoURL\':app[\'spec\'][\'source\'][\'repoURL\'],\'targetRevision\':app[\'spec\'][\'source\'][\'targetRevision\'],\'path\':app[\'spec\'][\'source\'][\'path\'],\'destination\':app[\'spec\'][\'destination\'],\'automated\':False,\'sync\':app.get(\'status\',{}).get(\'sync\'),\'health\':app.get(\'status\',{}).get(\'health\')}\nexpected_argo=json.loads(ARGO_LITERAL)\nfor key in (\'uid\',\'repoURL\',\'targetRevision\',\'path\',\'destination\',\'automated\'):\n assert argo[key]==expected_argo[key]\nassert argo[\'health\'][\'status\']==\'Healthy\'\ndiff=subprocess.run([\'kubectl\',\'diff\',\'-f\',\'-\'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\nnode=run([\'kubectl\',\'describe\',\'node\']);allocated=re.search(r\'Allocated resources:.*?CPU Requests|Allocated resources:\',node,re.S)\nsection=node.split(\'Allocated resources:\')[1].split(\'Events:\')[0] if \'Allocated resources:\' in node else \'\'\nnodes=json.loads(run([\'kubectl\',\'get\',\'nodes\',\'-o\',\'json\']))[\'items\'];assert len(nodes)==1\nalloc=nodes[0][\'status\'][\'allocatable\'];cpu=alloc[\'cpu\'];cpu_m=int(cpu[:-1]) if cpu.endswith(\'m\') else int(cpu)*1000\nrequested=int(re.search(r\'cpu\\s+(\\d+)m\',section).group(1));assert requested<=cpu_m\nreceipt={\'node_allocatable_cpu_m\':cpu_m,\'node_requested_cpu_m\':requested,\'captured_at\':datetime.datetime.now(datetime.timezone.utc).isoformat(),\'native_workload_changed\':False,\'native_backup_restore_executed\':False,\'argo\':argo,\'native_dependencies_checked\':True,\'configmap_uid\':cm[\'metadata\'][\'uid\'],\'pvc_uid\':pvc[\'metadata\'][\'uid\'],\'live_ready_replicas\':1,\'admitted_uid\':admitted[\'metadata\'][\'uid\'],\'server_dry_run_passed\':True,\'admitted_spec_exactly_live_plus_image\':True,\'client_diff_exit\':diff.returncode,\'client_diff_sha256\':hashlib.sha256(diff.stdout.encode()).hexdigest(),\'node_allocated_resources\':section.strip(),\'all_checks_pass\':True}\nprint(json.dumps(receipt))\n' +for marker,value in [('DEPENDENCIES_LITERAL',(ROOT/'sealed-native-dependencies.json').read_text()),('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]: + program=program.replace(marker,repr(value)) +program='import traceback,json\ntry:\n'+''.join(' '+line+'\n' for line in program.splitlines())+"except Exception as error:\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\n" +r=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True) +result=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True +out.write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1) diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json new file mode 100644 index 0000000..3dcc48a --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json @@ -0,0 +1,87 @@ +{ + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "trial_id": "infd-purpose-20261011-r1", + "state": "prepared-unapproved", + "target": "realm:kubernetes/railiance01/informed-decision", + "authority": "ADMINISTER; activation APPROVED only upon exact founder disposition", + "candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "published_source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "prior_argo_revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "native_object": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "namespace": "informed-decision", + "name": "informed-decision", + "uid": "a588e10a-90d2-4883-975e-6dd8b8feca92" + }, + "argo_application_uid": "499868f2-eabc-4df4-ae31-b89ce58d750d", + "source_gate": "All four exact committed owner Kustomize input blobs in execution-plan.json and clean current owner HEAD must match; source preparation is not native approval", + "sync_scope": [ + "apps:Deployment:informed-decision" + ], + "prune": false, + "automated_sync": false, + "runtime_configmap": "informed-decision-runtime-6c221878d051", + "schema": 5, + "requested_operations": [ + "Protected SQLite-consistent native backup and independently protected off-cluster custody", + "Offline restore/integrity/count comparison on a private disposable volume with exact candidate, no runtime tokens/config/network", + "Refresh a consistent pre-cutover snapshot, retain private copies and count-only/hash receipts", + "Pin existing manual Argo Application to exact approved owner source and manually sync only existing Deployment image", + "Verify health/readiness/image/module/installed fail-closed purpose checks and retained schema/count evidence; recover to prior same-schema image if needed" + ], + "execute_by": "2026-10-12T23:59:59Z", + "temporary_vulnerability_review_due": "2026-10-18", + "known_scan_findings": "0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical", + "vulnerability_record": "INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05", + "cost_estimate_EUR": 0, + "cost_limits": "No new recurring infrastructure; private backup storage and attended engineering/recovery time unpriced, not an autopilot cost grant", + "risk_estimates": [ + "Brief Recreate service interruption; no concurrent new writer/surge", + "Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence", + "Candidate purpose refusal may expose callers relying on advisory results as binding", + "Inherited known fixable MEDIUM remains until separately approved owner remediation", + "Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted", + "All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller." + ], + "rollback": "Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes", + "native_executed": false, + "human_approval": false, + "refinement_of_manifest": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300", + "mandatory_pre_open_gate": "stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration", + "optimized_interpreters": "local+remote explicitlyrefused beforeassert gates", + "native_dependency_gate": "sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads", + "live_counts": "Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained", + "source_basis": { + "reviewed_protocol_commit": "e0359bcb6cdfad9ab3e868054121fe0cebec2d68", + "owner_followthrough_commit": "9268c9ac0bbee508fe35c0b90dcefef4c24da2f5", + "final_execution_source": "exact subsequent root-applied source commit must be bound by founder receipt and verified against four approved Git blobs" + }, + "approved_owner_render_blob_sha256": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "execution_bundle_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "execution_helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", + "execution_plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6", + "execution_phases": [ + "drill-backup", + "drill-copy", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.", + "offline_initializer": "One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.", + "rollback_dispatch": "Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.", + "purpose_proof_limit": "Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.", + "refinement_of_amended_manifest": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json new file mode 100644 index 0000000..5db68f7 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json @@ -0,0 +1,64 @@ +{ + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "observed_at": "2026-10-11T01:24:01.985128+00:00", + "native_owner_publication_job": { + "id": 11484, + "name": "publish-candidate", + "head_branch": "main", + "head_sha": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "run_number": 3, + "event": "push", + "display_title": "Prepare readable overlay context with the admitted legacy builder", + "status": "success", + "workflow_id": "purpose-overlay-image.yaml", + "url": "https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3", + "created_at": "2026-10-11T01:20:59Z", + "updated_at": "2026-10-11T01:21:08Z", + "run_started_at": "2026-10-11T01:20:59Z" + }, + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62", + "registry_proof_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "source_render_change_only": "Deployment/informed-decision spec.template.spec.containers[0].image", + "runtime_configmap_unchanged": "informed-decision-runtime-6c221878d051", + "installed_image_execution": { + "immutable_registry_artifact_pulled_anonymously": true, + "UID": 10001, + "GID": 10001, + "policy_file_UID": 0, + "policy_file_mode": "0644", + "purpose_variants": 10, + "binding_forms_allowed": 2, + "advisory_or_malformed_refused": 8, + "network": "none", + "read_only": true, + "synthetic_transport": true, + "native_PDP_test": false + }, + "scan_summary_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "historical_failed_runs_retained": [ + "f66de505/task11482/run1", + "acecad887/task11483/run2" + ], + "native_hosting_changed": false, + "native_backup_restore_executed": false, + "human_approval": false, + "evidence_file_sha256": { + "image-manifest.json": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb", + "image-config.json": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10", + "base-image-config.json": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00", + "registry-proof.json": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "trivy-full.json": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e", + "sbom.cdx.json": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d", + "base-trivy-full.json": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80", + "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", + "verify_registry.py": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4", + "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "review-refinement.json": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75", + "test_change_guard.py": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f", + "test_sqlite_readonly.py": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323", + "test_preflight_optimization.py": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d" + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json new file mode 100644 index 0000000..918ff6d --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json @@ -0,0 +1,47 @@ +{ + "image_digest": "sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "base_image_digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "base_layer_bytes_identical": true, + "layer_media_type_conversion": "OCI gzip to Docker gzip, same digest and size", + "base_runtime_config_semantics_identical": true, + "legacy_builder_config_additions": { + "Hostname": "", + "Domainname": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Cmd": null, + "Volumes": null, + "OnBuild": null, + "Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883" + }, + "base_rootfs_prefix_identical": true, + "overlay_regular_files": [ + "opt/venv/lib/python3.12/site-packages/informed_decision/policy.py" + ], + "overlay_directories": [ + "opt", + "opt/venv", + "opt/venv/lib", + "opt/venv/lib/python3.12", + "opt/venv/lib/python3.12/site-packages", + "opt/venv/lib/python3.12/site-packages/informed_decision" + ], + "policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62", + "policy_mode": "0644", + "base_user": "10001:10001", + "source_scope_labels": { + "org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62", + "social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1" + }, + "registry_read_route": "anonymous public scoped bearer challenge, no token retention", + "image_executed": false, + "native_workload_changed": false, + "native_backup_restore_executed": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json new file mode 100644 index 0000000..a474665 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json @@ -0,0 +1,52 @@ +{ + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "policy": { + "origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080", + "package": "informed-decision.compact-sitting", + "version": "v13", + "package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873", + "pod_name": "flex-auth-informed-decision-sitting" + }, + "keycape_egress_ips": [ + "92.205.62.239" + ], + "storage_class": "local-path", + "ordinary_approval_ids": [ + "2ce76d7f-01c3-4b63-8476-8d1230679769", + "c2af4bcf-15b4-4305-aac1-acc7e4dcb099", + "dc22666a-d5d7-46bc-9490-ebe9fe09dc38" + ], + "lifecycle_policy": { + "package": "informed-decision.lifecycle", + "version": "v2", + "package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c", + "origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080", + "pod_name": "flex-auth-informed-decision-lifecycle" + }, + "lifecycle_delivery": true, + "intake_attributes": true, + "intake_delivery": { + "hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000" + }, + "workload_api": { + "registries_configmap": "informed-decision-workload-registry", + "peers": [ + { + "namespace": "state-hub", + "app": "state-hub" + } + ], + "api_egress": [ + { + "ip": "10.43.0.1", + "port": 443 + }, + { + "ip": "92.205.62.239", + "port": 6443 + } + ], + "intake": true, + "lifecycle": true + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json new file mode 100644 index 0000000..7459f8f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json @@ -0,0 +1,267 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "annotations": { + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover", + "argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision" + }, + "name": "informed-decision", + "namespace": "informed-decision" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 1, + "selector": { + "matchLabels": { + "app.kubernetes.io/name": "informed-decision" + } + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "annotations": { + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "labels": { + "app.kubernetes.io/component": "review", + "app.kubernetes.io/name": "informed-decision" + } + }, + "spec": { + "automountServiceAccountToken": false, + "containers": [ + { + "env": [ + { + "name": "INFD_KEYCAPE_ISSUER", + "value": "https://kc.coulomb.social" + }, + { + "name": "INFD_CONTAINER_CONFIG", + "value": "/configuration/runtime.json" + } + ], + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "livenessProbe": { + "httpGet": { + "path": "/healthz", + "port": "http" + }, + "periodSeconds": 10, + "timeoutSeconds": 2 + }, + "name": "informed-decision", + "ports": [ + { + "containerPort": 8080, + "name": "http" + }, + { + "containerPort": 8081, + "name": "workload" + } + ], + "readinessProbe": { + "httpGet": { + "path": "/healthz", + "port": "http" + }, + "periodSeconds": 10, + "timeoutSeconds": 2 + }, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "5m", + "memory": "64Mi" + } + }, + "securityContext": { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + }, + "readOnlyRootFilesystem": true + }, + "startupProbe": { + "failureThreshold": 12, + "httpGet": { + "path": "/healthz", + "port": "http" + }, + "periodSeconds": 10, + "timeoutSeconds": 2 + }, + "volumeMounts": [ + { + "mountPath": "/data", + "name": "data" + }, + { + "mountPath": "/run/informed-decision", + "name": "runtime" + }, + { + "mountPath": "/tmp", + "name": "tmp" + }, + { + "mountPath": "/configuration", + "name": "configuration", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/policy", + "name": "caller", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/audit", + "name": "audit", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/kubernetes", + "name": "kubernetes-api", + "readOnly": true + }, + { + "mountPath": "/workload-registry", + "name": "workload-registry", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/requester", + "name": "sitting-requester", + "readOnly": true + } + ] + } + ], + "securityContext": { + "fsGroup": 10001, + "fsGroupChangePolicy": "OnRootMismatch", + "runAsGroup": 10001, + "runAsNonRoot": true, + "runAsUser": 10001, + "seccompProfile": { + "type": "RuntimeDefault" + } + }, + "serviceAccountName": "review", + "terminationGracePeriodSeconds": 45, + "volumes": [ + { + "name": "data", + "persistentVolumeClaim": { + "claimName": "informed-decision-data" + } + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "runtime" + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "tmp" + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-runtime-6c221878d051" + }, + "name": "configuration" + }, + { + "name": "caller", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "audience": "flex-auth", + "expirationSeconds": 3600, + "path": "token" + } + } + ] + } + }, + { + "name": "audit", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "token", + "path": "token" + } + ], + "secretName": "informed-decision-audit" + } + }, + { + "name": "kubernetes-api", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "expirationSeconds": 600, + "path": "token" + } + }, + { + "configMap": { + "items": [ + { + "key": "ca.crt", + "path": "ca.crt" + } + ], + "name": "kube-root-ca.crt" + } + } + ] + } + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-workload-registry" + }, + "name": "workload-registry" + }, + { + "name": "sitting-requester", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "client-secret", + "path": "client-secret" + } + ], + "optional": false, + "secretName": "informed-decision-sitting-requester" + } + } + ] + } + } + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json new file mode 100644 index 0000000..f6f812d --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json @@ -0,0 +1,286 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "annotations": { + "argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision", + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "name": "informed-decision", + "namespace": "informed-decision", + "uid": "a588e10a-90d2-4883-975e-6dd8b8feca92" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 1, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app.kubernetes.io/name": "informed-decision" + } + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "annotations": { + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "labels": { + "app.kubernetes.io/component": "review", + "app.kubernetes.io/name": "informed-decision" + } + }, + "spec": { + "automountServiceAccountToken": false, + "containers": [ + { + "env": [ + { + "name": "INFD_KEYCAPE_ISSUER", + "value": "https://kc.coulomb.social" + }, + { + "name": "INFD_CONTAINER_CONFIG", + "value": "/configuration/runtime.json" + } + ], + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "imagePullPolicy": "IfNotPresent", + "livenessProbe": { + "failureThreshold": 3, + "httpGet": { + "path": "/healthz", + "port": "http", + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 2 + }, + "name": "informed-decision", + "ports": [ + { + "containerPort": 8080, + "name": "http", + "protocol": "TCP" + }, + { + "containerPort": 8081, + "name": "workload", + "protocol": "TCP" + } + ], + "readinessProbe": { + "failureThreshold": 3, + "httpGet": { + "path": "/healthz", + "port": "http", + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 2 + }, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "5m", + "memory": "64Mi" + } + }, + "securityContext": { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + }, + "readOnlyRootFilesystem": true + }, + "startupProbe": { + "failureThreshold": 12, + "httpGet": { + "path": "/healthz", + "port": "http", + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 2 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/data", + "name": "data" + }, + { + "mountPath": "/run/informed-decision", + "name": "runtime" + }, + { + "mountPath": "/tmp", + "name": "tmp" + }, + { + "mountPath": "/configuration", + "name": "configuration", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/policy", + "name": "caller", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/audit", + "name": "audit", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/kubernetes", + "name": "kubernetes-api", + "readOnly": true + }, + { + "mountPath": "/workload-registry", + "name": "workload-registry", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/requester", + "name": "sitting-requester", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": { + "fsGroup": 10001, + "fsGroupChangePolicy": "OnRootMismatch", + "runAsGroup": 10001, + "runAsNonRoot": true, + "runAsUser": 10001, + "seccompProfile": { + "type": "RuntimeDefault" + } + }, + "serviceAccount": "review", + "serviceAccountName": "review", + "terminationGracePeriodSeconds": 45, + "volumes": [ + { + "name": "data", + "persistentVolumeClaim": { + "claimName": "informed-decision-data" + } + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "runtime" + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "tmp" + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-runtime-6c221878d051" + }, + "name": "configuration" + }, + { + "name": "caller", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "audience": "flex-auth", + "expirationSeconds": 3600, + "path": "token" + } + } + ] + } + }, + { + "name": "audit", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "token", + "path": "token" + } + ], + "secretName": "informed-decision-audit" + } + }, + { + "name": "kubernetes-api", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "expirationSeconds": 600, + "path": "token" + } + }, + { + "configMap": { + "items": [ + { + "key": "ca.crt", + "path": "ca.crt" + } + ], + "name": "kube-root-ca.crt" + } + } + ] + } + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-workload-registry" + }, + "name": "workload-registry" + }, + { + "name": "sitting-requester", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "client-secret", + "path": "client-secret" + } + ], + "optional": false, + "secretName": "informed-decision-sitting-requester" + } + } + ] + } + } + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json new file mode 100644 index 0000000..8490089 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json @@ -0,0 +1,52 @@ +{ + "configmap": { + "apiVersion": "v1", + "immutable": true, + "kind": "ConfigMap", + "metadata": { + "annotations": { + "argocd.argoproj.io/tracking-id": "informed-decision:/ConfigMap:informed-decision/informed-decision-runtime-6c221878d051", + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "name": "informed-decision-runtime-6c221878d051", + "namespace": "informed-decision", + "uid": "90113d2d-54d9-4e82-b1d3-90b49ebed2b5" + }, + "canonical_data_sha256": "8ec462d12347548f506eeebf1e3c7cc47648019c8a783804d09bcc79b0f22af6" + }, + "pvc": { + "apiVersion": "v1", + "kind": "PersistentVolumeClaim", + "metadata": { + "annotations": { + "argocd.argoproj.io/tracking-id": "informed-decision:/PersistentVolumeClaim:informed-decision/informed-decision-data", + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover", + "pv.kubernetes.io/bind-completed": "yes", + "pv.kubernetes.io/bound-by-controller": "yes", + "volume.beta.kubernetes.io/storage-provisioner": "rancher.io/local-path", + "volume.kubernetes.io/selected-node": "239.62.205.92.host.secureserver.net", + "volume.kubernetes.io/storage-provisioner": "rancher.io/local-path" + }, + "finalizers": [ + "kubernetes.io/pvc-protection" + ], + "name": "informed-decision-data", + "namespace": "informed-decision", + "uid": "d80b25b1-141a-441b-b205-98fa2fd98b7c" + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "1Gi" + } + }, + "storageClassName": "local-path", + "volumeMode": "Filesystem", + "volumeName": "pvc-d80b25b1-141a-441b-b205-98fa2fd98b7c" + } + }, + "pvc_phase": "Bound" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json new file mode 100644 index 0000000..48926d3 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json @@ -0,0 +1,35 @@ +{ + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "scanner": "aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969", + "version": "0.74.0", + "db_metadata": { + "Version": 2, + "NextUpdate": "2026-10-11T18:59:50.889010572Z", + "UpdatedAt": "2026-10-10T18:59:50.889010923Z", + "DownloadedAt": "2026-10-10T23:32:32.380033131Z" + }, + "suppression": false, + "ignore_unfixed": false, + "severity_filter": null, + "package_count": 44, + "findings_by_severity": { + "MEDIUM": 1 + }, + "findings": [ + { + "id": "CVE-2026-85091", + "package": "zlib", + "installed": "1.3.2-r0", + "fixed": "1.3.2-r1", + "severity": "MEDIUM" + } + ], + "coverage_limits": [ + "Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages", + "Known findings asof pinnedDB, not claim absence of unknown vulnerabilities" + ], + "high_critical": 0, + "same_scanner_actual_base_scan_findings_identical": true, + "base_scan_file": "base-trivy-full.json" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py new file mode 100644 index 0000000..833721b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py @@ -0,0 +1,39 @@ +"""Pre-open schema/integrity/count proof; stdlib only, never constructs Store.""" +import argparse +import json +from pathlib import Path +import sqlite3 + + +def inspect_readonly(path): + path = Path(path) + if not path.is_file() or path.is_symlink(): + raise ValueError('existing nonsymlink private database required') + with sqlite3.connect(path.resolve().as_uri() + '?mode=ro', uri=True, timeout=5) as db: + db.execute('PRAGMA query_only=ON') + db.execute('BEGIN') + version = db.execute('PRAGMA user_version').fetchone()[0] + if version != 5: + raise ValueError('pre-open database is not schema5; refuse migration') + if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]: + raise ValueError('read-only integrity check refused') + lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0] + for name, table in (('records', 'lifecycle_records'), + ('events', 'lifecycle_events'), + ('pending', 'lifecycle_pending'))} + result = {'schema_version': version, 'lifecycle': lifecycle, + 'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')), + 'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')), + 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False} + db.rollback() + return result + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--db', type=Path, required=True) + args = parser.parse_args() + try: + print(json.dumps(inspect_readonly(args.db), sort_keys=True)) + except Exception: + raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json new file mode 100644 index 0000000..957926b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json @@ -0,0 +1,57 @@ +{ + "intake_valid_offline": true, + "typed_memo_valid": true, + "lifecycle_documents_valid": 20, + "packet_actual_file_bytes_verified": true, + "submission_digest": "sha256:fd78d486174670e12efb2f812bac02e68f294e7791b9302d0d458c053240f5a9", + "offline_constructed_grant": "state-hub/decision-record/net-kingdom-admins", + "deployed_submitter_admission_verified": false, + "human_approval": false, + "live_submitted": false, + "native_backup_restore_executed": false, + "native_workload_changed": false, + "packet_bytes_total": 171910, + "guard_tests": 11, + "guard_drift_negative_assertions": 28, + "transport_negative_cases": 6, + "fresh_readonly_preflight_all_checks_pass": true, + "fresh_readonly_capture": "2026-10-11T01:39:14Z", + "original_capture_bytes_preserved": true, + "pre_open_old_unknown_schema_negative_cases": 6, + "optimized_interpreter_negative_cases": 2, + "native_dependencies_checked": true, + "native_pre_open_schema_checked": false, + "original36path_snapshot_preserved": true, + "refinement_same_proposal_trial": true, + "register_json_bytes": 238209, + "mechanical_helper_tests": 16, + "mechanical_review_manifest_sha256": "80fd16e0f5841b83a012ce195b28ebf5b0dad37c87d1efa5d8cbfd219a780824", + "helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", + "execution_bundle_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "combined_source_negative_cases": [ + { + "case": "document-content-changed", + "refused": true + }, + { + "case": "helper-hash-changed", + "refused": true + }, + { + "case": "duplicate-document-identity", + "refused": true + }, + { + "case": "typed-source-bytes-changed", + "refused": true + }, + { + "case": "typed-duplicate-digest", + "refused": true + } + ], + "original78path_snapshot_preserved": true, + "actual_provider_probe": false, + "source_hash_negative_refusals_before_authority_or_dispatch": 4, + "source_boundary_receipt_sha256": "877f93485c1a6817bdfde257051f202d33e14f0ee54e03e597043c8924723337" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/archive-map.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/archive-map.json new file mode 100644 index 0000000..0a431e1 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/archive-map.json @@ -0,0 +1,266 @@ +{ + "docs/evidence/2026-10-11-purpose-image-release/README.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "sha256": "7800766bc2c042703b1a8f70e43eb695691c7f0c76781dfb5137bc9d5b4001e3" + }, + "docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md", + "sha256": "8a0df7255cf820821cf1096a59e28c76264020a7ec67146e1f2276370b4bd106" + }, + "docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json", + "sha256": "a6832b134edb9046dd037444443c78b57672f429bc8069874a8948d0d9a3a476" + }, + "docs/evidence/2026-10-11-purpose-image-release/decision-packet.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "sha256": "c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/README.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/README.md", + "sha256": "51b56c8ec2f30ad62f6cd09732c0f73dd7b5ebf2081320223c85bbcbf00d15a9" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py", + "sha256": "86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py", + "sha256": "0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json", + "sha256": "9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py", + "sha256": "788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json", + "sha256": "31b718a49ed475865edea1b2f6d749a50a3e66f56dbc4fa9b5ff1158acaef563" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json", + "sha256": "db28d03e3c46b4de52dc404c912054483f4a2aaa6c4f476b7892cab2a5f408d4" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py", + "sha256": "b250441282513862eeb990b18d01bb1eafe787b934d670a75a2bfaa9f5cfb89c" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/test_rescue_execution.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/test_rescue_execution.py", + "sha256": "8ecbb0260a87a7a12bd5c4c9678fb2a9d43a4ea7322129734bc21f8ee383cd70" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution/validation.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/validation.json", + "sha256": "6f3379f63968e9a0294aba7b5b57ea4662adda6b1fa1b37eff11c2f72a58931f" + }, + "docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json", + "sha256": "49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/README.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/README.md", + "sha256": "c866ca0d026e25612f5c8404a7668ea7142d19065c93d33dec996f5821e53af1" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/archive-map.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/archive-map.json", + "sha256": "371d3442b6da795cf02163055805ee0b3b6e4d1c80de48ee2abf3ffd546184f5" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-admission.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-admission.json", + "sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-deployment.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-deployment.json", + "sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/change_guard.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/change_guard.py", + "sha256": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/decision-packet.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/decision-packet.md", + "sha256": "a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md", + "sha256": "a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py", + "sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py", + "sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json", + "sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py", + "sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/packet-refinement.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/packet-refinement.json", + "sha256": "ef370a491468df28683f3002cb6e8bbb7e47b65e8e4d02ff4d09e9c39f020c8a" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/receipt_safety.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/receipt_safety.py", + "sha256": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json", + "sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py", + "sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json", + "sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution-bundle.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution-bundle.json", + "sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json", + "sha256": "2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json", + "sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json", + "sha256": "4947868e1bf7ac07ff7cb00d29188e591adcc7faad74a5d1b24a38656210cc3e" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json", + "sha256": "de159c1ef1bb3fc4fea9bbc1deae14d03ecd2f891d608a5dfb78f00799337574" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json", + "sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md", + "sha256": "440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json", + "sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json", + "sha256": "ffa2679a94a24e69a75d1248a808825498a80e711ceda98f3639a4143c40ec1b" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json", + "sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py", + "sha256": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json", + "sha256": "7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json", + "sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json", + "sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json", + "sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json", + "sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json", + "sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json", + "sha256": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json", + "sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py", + "sha256": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json", + "sha256": "044775a8cbdf9c7c2fdc9e020b33a90d5366d60584807b87604df2b2a9f88638" + }, + "docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "sha256": "75ccb148dff0166bf49cb11aa713c3216c4f8df03ae895e4b3c3d896ab82d5ee" + }, + "docs/evidence/2026-10-11-purpose-image-release/memo.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "sha256": "cac3fede955c6024d2566f443d04d259cefb7a0ef2368e7f05c174fa4b029cf3" + }, + "docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "sha256": "54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + "docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json", + "sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e" + }, + "docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json", + "sha256": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56" + }, + "docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json", + "sha256": "988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454" + }, + "docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "sha256": "03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + "docs/evidence/2026-10-11-purpose-image-release/proposal.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "sha256": "34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e" + }, + "docs/evidence/2026-10-11-purpose-image-release/published-verification.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "sha256": "e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + "docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json", + "sha256": "2a71a480d9a8ff70f22a9fb6d859756d6e2eb99454d78b567533ea08deb1b04f" + }, + "docs/evidence/2026-10-11-purpose-image-release/revision-command.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/revision-command.json", + "sha256": "14fed420ec79c780433302ac2b418bc1bde1320d73133a25861630a1218c92f3" + }, + "docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py", + "sha256": "9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + "docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py", + "sha256": "fb5e5111a544bc342a15c09dbf8e55af5763aa96917dce20d1c61103ca4eeaed" + }, + "docs/evidence/2026-10-11-purpose-image-release/validation.json": { + "archive_relative": "initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "sha256": "00aff2084abbadb162471585a34bbe57aa20c1327337a13e4a17ca14f29c034a" + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/original-manifest.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/original-manifest.json new file mode 100644 index 0000000..4a03844 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/original-manifest.json @@ -0,0 +1,464 @@ +[ + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/README.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/README.md", + "original_sha256": "c866ca0d026e25612f5c8404a7668ea7142d19065c93d33dec996f5821e53af1", + "staged_sha256": "7800766bc2c042703b1a8f70e43eb695691c7f0c76781dfb5137bc9d5b4001e3" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md", + "original_sha256": null, + "staged_sha256": "8a0df7255cf820821cf1096a59e28c76264020a7ec67146e1f2276370b4bd106" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json", + "original_sha256": null, + "staged_sha256": "a6832b134edb9046dd037444443c78b57672f429bc8069874a8948d0d9a3a476" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "original_sha256": "a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6", + "staged_sha256": "c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/README.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/README.md", + "original_sha256": "a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2", + "staged_sha256": "51b56c8ec2f30ad62f6cd09732c0f73dd7b5ebf2081320223c85bbcbf00d15a9" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py", + "original_sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5", + "staged_sha256": "86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py", + "original_sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa", + "staged_sha256": "0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json", + "original_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6", + "staged_sha256": "9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py", + "original_sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde", + "staged_sha256": "788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json", + "original_sha256": "ef370a491468df28683f3002cb6e8bbb7e47b65e8e4d02ff4d09e9c39f020c8a", + "staged_sha256": "31b718a49ed475865edea1b2f6d749a50a3e66f56dbc4fa9b5ff1158acaef563" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json", + "original_sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813", + "staged_sha256": "db28d03e3c46b4de52dc404c912054483f4a2aaa6c4f476b7892cab2a5f408d4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py", + "original_sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48", + "staged_sha256": "b250441282513862eeb990b18d01bb1eafe787b934d670a75a2bfaa9f5cfb89c" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/test_rescue_execution.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/test_rescue_execution.py", + "original_sha256": null, + "staged_sha256": "8ecbb0260a87a7a12bd5c4c9678fb2a9d43a4ea7322129734bc21f8ee383cd70" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/validation.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/validation.json", + "original_sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28", + "staged_sha256": "6f3379f63968e9a0294aba7b5b57ea4662adda6b1fa1b37eff11c2f72a58931f" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json", + "original_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "staged_sha256": "49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/README.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/README.md", + "original_sha256": null, + "staged_sha256": "c866ca0d026e25612f5c8404a7668ea7142d19065c93d33dec996f5821e53af1" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/archive-map.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/archive-map.json", + "original_sha256": null, + "staged_sha256": "371d3442b6da795cf02163055805ee0b3b6e4d1c80de48ee2abf3ffd546184f5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-admission.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-admission.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-deployment.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/candidate-deployment.json", + "original_sha256": null, + "staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/change_guard.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/change_guard.py", + "original_sha256": null, + "staged_sha256": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/decision-packet.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/decision-packet.md", + "original_sha256": null, + "staged_sha256": "a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md", + "original_sha256": null, + "staged_sha256": "a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py", + "original_sha256": null, + "staged_sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py", + "original_sha256": null, + "staged_sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json", + "original_sha256": null, + "staged_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py", + "original_sha256": null, + "staged_sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/packet-refinement.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/packet-refinement.json", + "original_sha256": null, + "staged_sha256": "ef370a491468df28683f3002cb6e8bbb7e47b65e8e4d02ff4d09e9c39f020c8a" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/receipt_safety.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/receipt_safety.py", + "original_sha256": null, + "staged_sha256": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json", + "original_sha256": null, + "staged_sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py", + "original_sha256": null, + "staged_sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json", + "original_sha256": null, + "staged_sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution-bundle.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution-bundle.json", + "original_sha256": null, + "staged_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json", + "original_sha256": null, + "staged_sha256": "2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json", + "original_sha256": null, + "staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json", + "original_sha256": null, + "staged_sha256": "4947868e1bf7ac07ff7cb00d29188e591adcc7faad74a5d1b24a38656210cc3e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json", + "original_sha256": null, + "staged_sha256": "de159c1ef1bb3fc4fea9bbc1deae14d03ecd2f891d608a5dfb78f00799337574" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json", + "original_sha256": null, + "staged_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md", + "original_sha256": null, + "staged_sha256": "440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json", + "original_sha256": null, + "staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json", + "original_sha256": null, + "staged_sha256": "ffa2679a94a24e69a75d1248a808825498a80e711ceda98f3639a4143c40ec1b" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json", + "original_sha256": null, + "staged_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py", + "original_sha256": null, + "staged_sha256": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json", + "original_sha256": null, + "staged_sha256": "7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json", + "original_sha256": null, + "staged_sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json", + "original_sha256": null, + "staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json", + "original_sha256": null, + "staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json", + "original_sha256": null, + "staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json", + "original_sha256": null, + "staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json", + "original_sha256": null, + "staged_sha256": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json", + "original_sha256": null, + "staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py", + "original_sha256": null, + "staged_sha256": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json", + "original_sha256": null, + "staged_sha256": "044775a8cbdf9c7c2fdc9e020b33a90d5366d60584807b87604df2b2a9f88638" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "original_sha256": "de159c1ef1bb3fc4fea9bbc1deae14d03ecd2f891d608a5dfb78f00799337574", + "staged_sha256": "75ccb148dff0166bf49cb11aa713c3216c4f8df03ae895e4b3c3d896ab82d5ee" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/memo.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "original_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937", + "staged_sha256": "cac3fede955c6024d2566f443d04d259cefb7a0ef2368e7f05c174fa4b029cf3" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "original_sha256": "440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478", + "staged_sha256": "54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json", + "original_sha256": null, + "staged_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json", + "original_sha256": null, + "staged_sha256": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json", + "original_sha256": null, + "staged_sha256": "988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "original_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "staged_sha256": "03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "original_sha256": "7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df", + "staged_sha256": "34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "original_sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "staged_sha256": "e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json", + "original_sha256": null, + "staged_sha256": "2a71a480d9a8ff70f22a9fb6d859756d6e2eb99454d78b567533ea08deb1b04f" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/revision-command.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/revision-command.json", + "original_sha256": null, + "staged_sha256": "14fed420ec79c780433302ac2b418bc1bde1320d73133a25861630a1218c92f3" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py", + "original_sha256": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "staged_sha256": "9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py", + "original_sha256": null, + "staged_sha256": "fb5e5111a544bc342a15c09dbf8e55af5763aa96917dce20d1c61103ca4eeaed" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/validation.json", + "staged_path": "/tmp/infd-purpose-rescue-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "original_sha256": "044775a8cbdf9c7c2fdc9e020b33a90d5366d60584807b87604df2b2a9f88638", + "staged_sha256": "00aff2084abbadb162471585a34bbe57aa20c1327337a13e4a17ca14f29c034a" + } +] diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md new file mode 100644 index 0000000..fa5bf5d --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md @@ -0,0 +1 @@ +Version2 rescue packet: original native backup COMPLETE, copy UNCERTAIN beforelocalfile, original image unchanged. New exactfounderacceptance required; no version2 nativeaction. See decision-packet/protocol/bundle; originalapproved version1 sourcepacket preserved initial-approved-bc6494cd. Rawscan/SBOM/base imageevidence unchanged and hash-bound. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md new file mode 100644 index 0000000..6f91a72 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-design.md @@ -0,0 +1,17 @@ +# Version2 protected existing-snapshot rescue — prepared, unapproved + +Original approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed. + +Fresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation. + +Fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase. + +Before rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome. + +Offline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup. + +Four committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension. + +Image763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation. + +Selected route is existing snapshot rescue, not another drill backup. Original c01b six-file source-only diagnosis proposed alternatives; this version2 adds the exact executable route, sources, journal guards and human packet. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json new file mode 100644 index 0000000..8d8cf55 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/copy-failure-repair-validation.json @@ -0,0 +1,27 @@ +{ + "state": "source-only-unapproved-repair", + "original_source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "original_receipts": { + "/tmp/infd-approved-drill-backup.json": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "/tmp/infd-approved-drill-copy.json": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56" + }, + "confirmed_metadata_reported_by_root": { + "main_bytes": 19537920, + "main_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "wal_bytes": 0, + "shm_bytes": 32768, + "private_uid": 10001, + "mode": "0600", + "nlink": 1, + "database_opened_for_capture": false + }, + "tests_passed": 5, + "test_transport": "mocked SQLite; no database/admin/native commands", + "source_files_changed_on_owner": false, + "original_uncertain_phase_retried": false, + "native_sidecars_deleted": false, + "native_database_read": false, + "native_backup_copy_restore_or_workload_action": false, + "new_founder_approval_required": true, + "recovery_actuator_implemented": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md new file mode 100644 index 0000000..e9dd741 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md @@ -0,0 +1,13 @@ +# Informed Decision version2 existing-snapshot rescue and image release + +Approve the exact source-refined recovery of the failed drill-copy and conditional remaining backup/drill/Deployment-only image rollout. This is memo version2 in the same proposal/trial, requiring NEW founder acceptance; original version1 acceptance is retained and cannot authorize changed helperbytes. + +Original source bc6494cd completed the protected native drill-backup, then copy failed before any localfile. Metadata-only verification proves unchanged main19537920bytes/SHA8756..., WAL0/privateSHM32768. The original reader could leave SHM indexing because its connection context manager did not close. The correction explicitlycloses all readers and uses immutable reads ONLY for a proven frozen closed-main snapshot, not live or writableclone. SHM stays unchanged; nonzeroWAL/hash/identity drift stops rescue. + +Distinct drill-copy-rescue-r1/newlinkedjournal preserves original UNCERTAINcopy and exact journalhash/attempts. No oldretry/overwrite, no newdrillbackup. Require originalCOMPLETEbackup/UNCERTAINcopy only, absentlocalfiles/restorevolume, originalnativePodUID/currentoldimage+sourcepin and allCM/PVC/Deployment seals. Copy snapshotbytes only into a newprivate0600file. Remainingorderedphases explicitly consume COMPLETErescueresult; one isolated UID0/CAP_CHOWN-only NEWvolume initializer then UID10001 pre-open/admin/post-admin checks proves real-data compatibility before cutover. No host/nativePVC/runtimeconfig/token mounts; no service startup. Any attempted failure/ambiguity is durable and cannotretry. + +Image763c from actualCI3e4bcb26 remains unchanged8base layers pluspolicy.py; legacyserialization differences disclosed. ActualinstalledUID10001/10purposevariants pass; native_provider=false/synthetictransport is not actualPDPauthority proof, which remains separateT04gate. Actualfull44packagescan0HIGH/CRITICAL, ONEfixableinheritedMEDIUMzlibCVE-2026-85091(1.3.2-r0→r1), identicalbasefinding. Explicittemporarypermission for this finding is requested again, with ownerT05/riskrecorddueOct18; no zero-CVE/RiskNexusgradeclaim. Rawscan/SBOM/base scan stay unchangedhashbound via publishedreceipt; exacthelperandoriginalcount-onlyreceipts directlybundle-bound within20docs. + +After rescue+offlinegates, distinctcutoverbackup/copy and manualArgoDeployment-only image763c/prune=false remain conditional. FourcommittedKustomizeblobs/currentfinalsourceHEAD/helpers/casehashes match; automated{} or overrides refuse. Config6c/schema5/PVC/identity/policies/replica1Recreate stayfixed. Rollbackdoesnotneed Readycandidate or itsDBexec; oldimageReady/scopedoperation/schema5currentDB is a separateproof. Preserve latestliveDB/allnewcommits and alluncertainoutcomes; neverrestoreolderbackup overlaterrecords. + +Allphases including rescue/recovery/verify mustbegin beforeOct12 23:59:59Z; expiryrequiresnewdecision and maydelayrecovery. No automaticexpirycontroller. Freshroot-authenticated nativefounderacceptance version2 beforeeachphase; receipts are supervisedbookkeeping, notsignedgrant/autonomy. EUR0 recurringinfra, existingprivatecopy/storage/attendedtime unpriced; no secondnative drillbackup. Exactoriginalapprovedpacket/failure/technicalrefinements preserved sameproposal/trial. No version2nativeoperation yet. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json new file mode 100644 index 0000000..5a57d3f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json @@ -0,0 +1,66 @@ +{ + "kind": "informed-decision.supervised-execution-source-bundle", + "version": 2, + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "files": { + "README.md": { + "sha256": "51b56c8ec2f30ad62f6cd09732c0f73dd7b5ebf2081320223c85bbcbf00d15a9", + "content": "# Version2 protected existing-snapshot rescue — prepared, unapproved\n\nOriginal approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed.\n\nFresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation.\n\nFixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase.\n\nBefore rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome.\n\nOffline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup.\n\nFour committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension.\n\nImage763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation.\n\nNative publication route: POST existing source /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions with expected_version1 and exact memo2/documents/summary, then publications/review-requests version2. Fresh source readback must prove currentversion1 is unbound before revision; bound/different source stops. Intake/register refuse version2 as designed and are not used. Review integration creates a NEW review-ID at its own version1; founder disposition memo_version1 belongs to that new review. Root fresh outcomes must be queried for SOURCE version2, exact newreviewID/memoSHA and confirmed nested personapproval. Receipt outcome_query pins that sourceversion2 route; it does not authenticate by itself.\n" + }, + "actuator.py": { + "sha256": "86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2", + "content": "\"\"\"One fixed supervised phase; never run this during source preparation.\"\"\"\nimport argparse\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport re\nimport selectors\nimport stat\nimport subprocess\nimport sys\nimport time\n\nif sys.flags.optimize:\n raise SystemExit('optimized interpreter refused')\n\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\nROOT = Path(__file__).resolve().parent\nCASE = ROOT.parent\nOWNER = Path('/home/worsch/informed-decision')\nCUSTODIAN = Path('/home/worsch/the-custodian')\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\nSOCKET = 'unix:///var/run/docker.sock'\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\nVOLUME = 'infd-purpose-r1-restore-20261011'\nMAX_BYTES = 512 * 1024**2\n\n\ndef run(argv, body=None, timeout=90):\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\n\n\ndef json_result(result):\n try:\n value = json.loads(result.stdout)\n except (ValueError, TypeError):\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\n 'phase did not verify complete; raw output withheld; no retry')\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\n require(set(value) <= permitted, 'unexpected output fields withheld')\n from receipt_safety import counts\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\n if name in value:\n counts(value[name])\n for name in ('snapshot_sha256', 'client_diff_sha256'):\n if name in value:\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\n if 'snapshot_bytes' in value:\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\n 'invalid output size withheld')\n if 'snapshot_file' in value:\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\n return value\n\n\ndef docker(argv, body=None, timeout=120):\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\n body=body, timeout=timeout)\n\n\ndef remote(phase, revision, approved, snapshot_identity=None):\n # Fixed module imported only after main verifies every executor source hash.\n from native_program import PROGRAM\n payload = {'snapshot_identity': snapshot_identity, 'phase': phase, 'source_revision': revision, 'approval': approved,\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\n\n\ndef copy_snapshot(phase, revision, approved, journal):\n prior = (journal.data['identity']['recovery_anchor']['backup_result']\n if phase == 'drill-copy-rescue-r1' else journal.data['phases']['cutover-backup']['result'])\n metadata = remote(phase, revision, approved, snapshot_identity=prior)\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\n name = metadata['snapshot_file']\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\n 'fixed bounded snapshot required')\n pod = metadata['pod_name']\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\n local = CUSTODY / name\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\n # Snapshot schema/count metadata was validated before opening this destination.\n with os.fdopen(fd, 'wb') as destination:\n command = ('kubectl exec -n informed-decision ' + pod +\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\n stderr=subprocess.DEVNULL)\n selector = selectors.DefaultSelector()\n selector.register(transfer.stdout, selectors.EVENT_READ)\n deadline = time.monotonic() + 150\n received = 0\n try:\n while True:\n remaining = deadline - time.monotonic()\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\n block = os.read(transfer.stdout.fileno(), 1024**2)\n if not block:\n break\n received += len(block)\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\n 'private copy exceeds frozen snapshot size')\n destination.write(block)\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\n finally:\n selector.close()\n transfer.stdout.close()\n if transfer.poll() is None:\n transfer.kill()\n transfer.wait()\n destination.flush()\n os.fsync(destination.fileno())\n private(local)\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\n # Re-read identity/hash after transfer. This is verification, not a write retry.\n after = remote(phase, revision, approved, snapshot_identity=prior)\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\n 'source identity/snapshot changed during transfer')\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\n\n\ndef offline_verify(journal):\n from receipt_safety import counts\n snapshot = CUSTODY / 'drill.sqlite'\n private(snapshot)\n previous = journal.data['phases']['drill-copy-rescue-r1']['result']\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\n identity = docker(['info', '--format', '{{json .Name}}'])\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\n 'local offline Docker engine identity changed')\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\n 'disposable volume absence not verified')\n nonce = journal.data['phases']['offline-verify']['attempt_id']\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\n '--label', 'informed-decision.attempt=' + nonce,\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'new volume identity unavailable')\n volume = json.loads(inspected.stdout)\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\n journal.note('offline-verify', 'created_volume_identity', identity)\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\n # No host/live PVC/config/token mount exists; this detail needs packet review.\n initializer = \"\"\"import hashlib,os,stat,sys\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\nfolder='/restore';expected=EXPECTED\nif os.listdir(folder):raise ValueError('new empty private volume required')\nos.chmod(folder,0o700)\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\ndigest=hashlib.sha256();size=0\nwith os.fdopen(fd,'wb') as target:\n while True:\n block=sys.stdin.buffer.read(1024**2)\n if not block:break\n size+=len(block)\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\n target.write(block);digest.update(block)\n target.flush();os.fsync(target.fileno())\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\nprint('{\"all_checks_pass\":true,\"private_copy_verified\":true}')\n\"\"\".replace('EXPECTED', repr(previous['snapshot_sha256']))\n with snapshot.open('rb') as source:\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\n '--entrypoint', 'python', IMAGE, '-c', initializer]\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\n json_result(copied)\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\n checked = counts(json.loads(readonly.stdout))\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\n 'inspect', '--db', '/restore/review.sqlite'])\n require(admin.returncode == 0, 'offline admin result uncertain')\n admin_counts = json.loads(admin.stdout)\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\n 'offline admin changed frozen snapshot counters')\n # Admin Store construction must not silently alter schema/integrity/counters.\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\n post_checked = counts(json.loads(post.stdout))\n require(post_checked == checked == previous['snapshot_readonly'],\n 'offline admin altered frozen snapshot proof')\n private(snapshot)\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\n 'created_volume_identity': identity,\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\n\n\ndef cleanup_offline(journal):\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\n value = json.loads(inspected.stdout)\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\n and not value[0].get('Options'), 'volume ownership/recreation changed')\n removed = docker(['volume', 'rm', VOLUME])\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\n 'cleanup outcome ambiguous; do not retry')\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\n 'native_and_offcluster_original_snapshots_retained': True}\n\n\ndef main():\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--phase', choices=PHASES, required=True)\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\n parser.add_argument('--root-native-outcome', type=Path, required=True)\n parser.add_argument('--source-revision', required=True)\n args = parser.parse_args()\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\n 'fixed supervised receipt paths required')\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\n # Verify all prepared executor/input bytes before reading authority or dispatching.\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\n 'fixed executor sources required')\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\n 'deploy/lifecycle/service.candidate.json',\n 'deploy/lifecycle/kustomization.yaml',\n 'deploy/lifecycle/registries.candidate.json'},\n 'fixed owner image sources required')\n for relative, digest in plan['executor_files'].items():\n target = ROOT / relative\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\n for relative, digest in plan['case_files'].items():\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\n 'case source path escaped')\n target = CASE / relative\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\n for relative, digest in plan['owner_source_files'].items():\n target = OWNER / relative\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\n capture_output=True)\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\n 'committed owner render source differs from approved inputs')\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\n from authority_journal import Journal, authority, original_anchor\n private(args.root_authority_receipt)\n private(args.root_native_outcome)\n receipt = json.loads(args.root_authority_receipt.read_text())\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\n 'root verified executor plan differs')\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\n args.source_revision, args.phase)\n parent = CUSTODY.parent\n private(parent, directory=True)\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\n require(CUSTODY.exists(), 'original protected custody must already exist')\n private(CUSTODY, directory=True)\n capacity = os.statvfs(CUSTODY)\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\n 'independent protected custody headroom insufficient')\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\n private(CUSTODY / 'empty-docker-config', directory=True)\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\n anchor = original_anchor(CUSTODY, plan['recovery']['original_anchor'],\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\n plan['recovery']['original_identity'])\n if args.phase == 'drill-copy-rescue-r1':\n require(not os.path.lexists(CUSTODY / 'drill.sqlite')\n and not os.path.lexists(CUSTODY / 'cutover.sqlite'), 'rescue destination must be absent')\n identity = docker(['info', '--format', '{{json .Name}}'])\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\n 'local engine identity changed')\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\n 'existing restore volume forbids rescue')\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json'),\n 'recovery_anchor': anchor})\n try:\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\n if args.phase in ('drill-copy-rescue-r1', 'cutover-copy'):\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\n elif args.phase == 'offline-verify':\n result = offline_verify(journal)\n elif args.phase == 'cleanup-offline':\n result = cleanup_offline(journal)\n else:\n result = remote(args.phase, args.source_revision, approved)\n require(original_anchor(CUSTODY, plan['recovery']['original_anchor'],\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\n plan['recovery']['original_identity']) == anchor,\n 'original failed journal changed during new phase')\n journal.finish(args.phase, result)\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\n except BaseException as error:\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\n 'raw_output_withheld': True}\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\n journal.finish(args.phase, safe)\n print(json.dumps(safe))\n raise SystemExit(1) from None\n finally:\n journal.close()\n\n\nif __name__ == '__main__':\n try:\n main()\n except Exception:\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\n" + }, + "authority_journal.py": { + "sha256": "0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68", + "content": "\"\"\"Supervised receipt bookkeeping, not an authenticated approval provider.\"\"\"\nimport datetime\nimport fcntl\nimport hashlib\nimport json\nimport os\nimport re\nfrom pathlib import Path\nimport stat\nimport uuid\n\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\n\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\n \"\"\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\n\n Receipt files/flags are not signed grants. This function checks the exact\n supervised receipt relation; existing harness/founder authority remains the\n actual permission boundary. It never authenticates a caller as human.\n \"\"\"\n now = now or datetime.datetime.now(datetime.timezone.utc)\n require(phase in PHASES, 'fixed phase required')\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\n and receipt.get('memo_version') == 2 and receipt.get('memo_sha256') == memo_sha\n and receipt.get('source_revision') == source_revision\n and receipt.get('activation') == 'APPROVED'\n and receipt.get('authority_mode') == 'ADMINISTER'\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\n and receipt.get('runtime_authenticated_grant') is False\n and receipt.get('outcome_query') == '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\n 'exact externally verified supervised receipt required')\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\n 'fresh root native readback required before every phase')\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\n require(now < deadline, 'approved execution window expired')\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\n review_id = outcome['review']['memo_id']\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\n accepted = [x for x in outcome.get('dispositions', [])\n if x.get('submission_state') == 'confirmed'\n and x.get('disposition', {}).get('verb') == 'accept'\n and x['disposition'].get('memo_version') == 1]\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\n accepted = accepted[0]['disposition']\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\n and accepted.get('approval_id') == receipt.get('approval_id')\n and accepted.get('id') == receipt.get('disposition_id')\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\n 'native disposition identifiers are malformed')\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\n\n\ndef original_anchor(parent, expected, backup_result, original_identity):\n \"\"\"Read only sanitized original journal; never rewrite/synthesize its phases.\"\"\"\n path = Path(parent) / 'execution-journal.json'\n private(path)\n require(sha(path) == expected['original_journal_sha256'], 'original journal bytes changed')\n original = json.loads(path.read_text())\n require(original.get('identity') == original_identity, 'original approved identity changed')\n phases = original.get('phases', {})\n require(set(phases) == {'drill-backup', 'drill-copy'}, 'unexpected original action or rollout')\n for name, fields in expected['phase_metadata'].items():\n require(all(phases[name].get(key) == value for key,value in fields.items()),\n 'original failed/completed attempt identity changed')\n require(phases['drill-backup'].get('result') == backup_result\n and backup_result.get('all_checks_pass') is True\n and phases['drill-copy'].get('result', {}).get('all_checks_pass') is False,\n 'original backup/copy outcome changed')\n require(backup_result.get('snapshot_sha256') == expected['snapshot_sha256']\n and backup_result.get('snapshot_bytes') == expected['snapshot_bytes']\n and backup_result.get('pod_uid') == 'e8561ae0-4b09-4455-924d-64c27b625fc7',\n 'original frozen snapshot identity changed')\n require(sha(path) == expected['original_journal_sha256'], 'original journal changed during read')\n return {'original_journal_sha256': expected['original_journal_sha256'],\n 'original_copy_attempt_id': phases['drill-copy']['attempt_id'],\n 'original_backup_attempt_id': phases['drill-backup']['attempt_id'],\n 'backup_result': backup_result, 'old_uncertain_phase_retained': True}\n\n\nclass Journal:\n def __init__(self, parent, identity):\n self.parent = Path(parent)\n private(self.parent, directory=True)\n self.path = self.parent / 'rescue-execution-journal-r1.json'\n self.lock = os.open(self.parent / 'rescue-execution-r1.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\n private(self.parent / 'rescue-execution-r1.lock')\n if self.path.exists():\n private(self.path)\n self.data = json.loads(self.path.read_text())\n require(self.data['identity'] == identity, 'journal case/source identity changed')\n else:\n self.data = {'identity': identity, 'phases': {}}\n self.save()\n\n def save(self):\n temporary = self.parent / 'execution-journal.new'\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\n try:\n with os.fdopen(fd, 'w') as stream:\n json.dump(self.data, stream, indent=2)\n stream.write('\\n')\n stream.flush()\n os.fsync(stream.fileno())\n os.replace(temporary, self.path)\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\n try:\n os.fsync(directory)\n finally:\n os.close(directory)\n except BaseException:\n # Retain evidence rather than overwriting an uncertain durable intent.\n raise\n\n def start(self, phase, approval):\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\n require(phase in PHASES, 'fixed rescue or remaining phase required')\n predecessors = dict(zip(PHASES[1:7], PHASES[:6]))\n predecessors['rollback-verify'] = 'rollback'\n if phase in predecessors:\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\n 'preceding phase is not verified complete')\n if phase == 'rollback':\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\n 'attempt_id': str(uuid.uuid4()),\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\n self.save()\n\n def note(self, phase, key, value):\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\n self.data['phases'][phase][key] = value\n self.save()\n\n def finish(self, phase, result):\n entry = self.data['phases'][phase]\n require(entry['state'] == 'RUNNING', 'phase intent missing')\n entry['result'] = result\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\n self.save()\n\n def close(self):\n os.close(self.lock)\n" + }, + "execution-plan.json": { + "sha256": "9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258", + "content": "{\n \"kind\": \"informed-decision.supervised-mechanical-release-plan\",\n \"version\": 2,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"executor_files\": {\n \"actuator.py\": \"86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2\",\n \"authority_journal.py\": \"0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68\",\n \"native_program.py\": \"788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91\",\n \"receipt_safety.py\": \"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\"\n },\n \"case_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"sqlite_readonly.py\": \"9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509\",\n \"preflight-inputs.json\": \"03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"published-verification.json\": \"e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd\",\n \"security-summary.json\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\",\n \"original-approved-drill-backup.json\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"original-approved-drill-copy-failure.json\": \"fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56\",\n \"original-journal-sanitized-anchor.json\": \"988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"source_revision\": \"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\",\n \"phases\": [\n \"drill-copy-rescue-r1\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"authorization\": \"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\",\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"raw_output_withheld\": true,\n \"native_data_or_workload_action_executed\": false,\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\",\n \"recovery\": {\n \"original_anchor\": {\n \"original_journal_sha256\": \"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\",\n \"phase_metadata\": {\n \"drill-backup\": {\n \"state\": \"COMPLETE\",\n \"attempt_id\": \"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\",\n \"started_at\": \"2026-10-11T02:38:45.310653+00:00\"\n },\n \"drill-copy\": {\n \"state\": \"UNCERTAIN\",\n \"attempt_id\": \"329ef190-1692-4246-b953-e6a59664abcc\",\n \"started_at\": \"2026-10-11T02:39:50.198740+00:00\"\n }\n },\n \"frozen_backup_receipt_sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\",\n \"snapshot_bytes\": 19537920,\n \"off_cluster_file_exists\": false,\n \"old_uncertain_retry_authorized\": false\n },\n \"original_identity\": {\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"source_revision\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\",\n \"memo_sha256\": \"506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937\",\n \"plan_sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\"\n },\n \"new_journal\": \"rescue-execution-journal-r1.json\",\n \"new_phase\": \"drill-copy-rescue-r1\",\n \"old_uncertain_phase_overwrite_or_retry\": false,\n \"new_snapshot_backup\": false,\n \"snapshot_or_sidecar_mutation\": false,\n \"mapping\": \"offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal\"\n },\n \"source_memo_version\": 2,\n \"native_review_memo_version\": 1\n}\n" + }, + "native_program.py": { + "sha256": "788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91", + "content": "\"\"\"Fixed version2 recovery remote source; requires fresh exact acceptance.\"\"\"\nPROGRAM = '\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\nif sys.flags.optimize:raise RuntimeError(\\'optimized interpreter refused\\')\\npayload=json.loads(__PAYLOAD__)\\nexec(__GUARD__)\\nphase=payload[\\'phase\\']\\nif phase not in (\\'cutover-backup\\',\\'drill-copy-rescue-r1\\',\\'cutover-copy\\',\\'release\\',\\'verify\\',\\'rollback\\',\\'rollback-verify\\'):raise ValueError(\\'fixed native phase required\\')\\ndeadline=datetime.datetime.fromisoformat(\\'2026-10-12T23:59:59+00:00\\')\\ndef require(value,reason):\\n if not value:raise ValueError(reason)\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\'drill-backup\\' else 1)+16*1024**2,\\'bounded native snapshot capacity required\\')\\n if action==\\'drill-backup\\':\\n require(not os.path.lexists(folder),\\'native case directory must be unique\\')\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\n private(folder,True)\\n filename=\\'drill.sqlite\\' if action==\\'drill-backup\\' else \\'cutover.sqlite\\';output=folder+\\'/\\'+filename\\n require(not os.path.lexists(output),\\'snapshot output must be unique\\')\\n admin=subprocess.run([\\'informed-decision-admin\\',\\'backup\\',\\'--db\\',db,\\'--output\\',output],capture_output=True,text=True,timeout=120)\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\'status\\':\\'backed_up\\',\\'consistent_snapshot\\':True},\\'backup completion not verified; do not retry\\')\\n private(output)\\n for suffix in (\\'-wal\\',):\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\'snapshot has WAL frames; immutable read refused\\')\\n digest=hashlib.sha256()\\n with open(output,\\'rb\\') as stream:\\n for block in iter(lambda:stream.read(1024**2),b\\'\\'):digest.update(block)\\n frozen_digest=digest.hexdigest()\\n snapshot=counts(inspect_closed_snapshot(output,frozen_digest))\\n size=os.stat(output).st_size;require(0 10**12\n for number in value[group].values()):\n raise ValueError('count-only receipt values refused')\n return value\n" + }, + "root-authority-receipt-template.json": { + "sha256": "db28d03e3c46b4de52dc404c912054483f4a2aaa6c4f476b7892cab2a5f408d4", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"memo_id\": \"infd-20261011-purpose-overlay-r1\",\n \"memo_version\": 2,\n \"memo_sha256\": null,\n \"source_revision\": null,\n \"activation\": \"PENDING\",\n \"authority_mode\": \"ADMINISTER\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"verification_method\": \"root-fixed-origin-native-readback\",\n \"runtime_authenticated_grant\": false,\n \"verified_at\": null,\n \"accepted_at\": null,\n \"review_memo_id\": null,\n \"approval_id\": null,\n \"disposition_id\": null,\n \"native_outcome_sha256\": null,\n \"executor_plan_sha256\": \"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\",\n \"outcome_query\": \"/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2\",\n \"review_memo_version\": 1\n}\n" + }, + "test_execution.py": { + "sha256": "b250441282513862eeb990b18d01bb1eafe787b934d670a75a2bfaa9f5cfb89c", + "content": "\"\"\"Synthetic custody/transport tests. No native data, Docker or cluster action.\"\"\"\nimport copy\nimport datetime\nimport io\nimport json\nimport os\nfrom pathlib import Path\nimport subprocess\nimport sys\nimport tempfile\nimport unittest\nfrom unittest.mock import patch\nfrom contextlib import redirect_stdout\n\nimport actuator\nfrom authority_journal import Journal, authority\nfrom native_program import PROGRAM\nfrom receipt_safety import counts\n\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\nREVISION = 'e' * 40\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\n\n\ndef accepted():\n approval = '11111111-1111-4111-8111-111111111111'\n review = 'review-22222222-2222-4222-8222-222222222222'\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 2,\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False, 'outcome_query': '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\n 'approval_id': approval, 'id': disposition,\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\n 'at': receipt['accepted_at']}}]}\n return receipt, outcome\n\n\nclass AuthorityAndCustody(unittest.TestCase):\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\n receipt, outcome = accepted()\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-copy-rescue-r1', NOW)\n self.assertEqual(result['approval_id'], receipt['approval_id'])\n\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\n mutations = [lambda r, o: r.update(activation='PENDING'),\n lambda r, o: r.update(memo_sha256='changed'),\n lambda r, o: r.update(source_revision='changed'),\n lambda r, o: r.update(target='other'),\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\n lambda r, o: r.update(verification_method='caller-asserted'),\n lambda r, o: r.update(runtime_authenticated_grant=True),\n lambda r, o: o['review'].update(stale=True),\n lambda r, o: o['review'].update(intake_state='pending'),\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=3),\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n r, o = accepted()\n mutate(r, o)\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\n\n def test_expired_window_and_unknown_phase_refuse(self):\n r, o = accepted()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\n r['verified_at'] = late.isoformat()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\n\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\n with tempfile.TemporaryDirectory() as directory:\n parent = Path(directory)\n os.chmod(parent, 0o700)\n journal = Journal(parent, {'case': 'fixture'})\n journal.start('drill-copy-rescue-r1', {'approval_id': 'fixture'})\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-copy-rescue-r1']['state'], 'RUNNING')\n journal.close() # simulated crash before result\n recovered = Journal(parent, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n recovered.start('drill-copy-rescue-r1', {})\n with self.assertRaises(ValueError):\n recovered.start('drill-copy-rescue-r1', {})\n recovered.close()\n\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\n with tempfile.TemporaryDirectory() as directory:\n os.chmod(directory, 0o700)\n j = Journal(directory, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n j.start('release', {})\n for phase in actuator.PHASES[:5]:\n j.start(phase, {})\n j.finish(phase, {'all_checks_pass': True})\n j.start('release', {})\n j.finish('release', {'all_checks_pass': False})\n with self.assertRaises(ValueError):\n j.start('release', {})\n with self.assertRaises(ValueError):\n j.start('verify', {})\n j.start('rollback', {})\n j.finish('rollback', {'all_checks_pass': True})\n j.close()\n\n def test_secret_or_unknown_child_output_is_withheld(self):\n for body in ('not-json', '{\"all_checks_pass\":true,\"token\":\"private-value\"}',\n '{\"all_checks_pass\":true,\"snapshot_readonly\":{\"schema_version\":5}}'):\n with self.assertRaises(ValueError):\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\n wrong = copy.deepcopy(COUNT)\n wrong['outbox'] = {'private-row-value': 1}\n with self.assertRaises(ValueError):\n counts(wrong)\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\n\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\n blob = b'synthetic private fixture bytes'\n digest = __import__('hashlib').sha256(blob).hexdigest()\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\n journal = type('FixtureJournal', (), {'data': {'identity': {'recovery_anchor': {'backup_result': metadata}}}})()\n real_popen = subprocess.Popen\n for extra in (b'', b'oversized'):\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\n os.chmod(folder, 0o700)\n output = io.StringIO()\n\n def child(*args, **kwargs):\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\n if extra:\n with self.assertRaises(ValueError):\n actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\n else:\n result = actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\n self.assertTrue(result['off_cluster_private_copy_verified'])\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\n self.assertEqual(output.getvalue(), '')\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\n\n def test_recreated_offline_volume_cannot_be_deleted(self):\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\n journal = type('FixtureJournal', (), {'data': {'phases': {\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\n with self.assertRaises(ValueError):\n actuator.cleanup_offline(journal)\n self.assertEqual(mocked.call_count, 1)\n\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\n for defect in ('none', 'post-integrity', 'original-hash'):\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\n folder=Path(directory);os.chmod(folder,0o700)\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\n digest=actuator.sha(snapshot)\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy-rescue-r1':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\n reads=[]\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\n def docker(argv, body=None, **kwargs):\n if argv[0]=='info':body=json.dumps('bnt-lap001')\n elif argv[:2]==['volume','ls']:body=''\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\n elif 'informed-decision-admin' in argv:\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\n elif '--entrypoint' in argv and 'python' in argv:\n reads.append(argv);proof=copy.deepcopy(COUNT)\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\n body=json.dumps(proof)\n else:raise AssertionError('unexpected offline command')\n return subprocess.CompletedProcess(argv,0,body,'')\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\"all_checks_pass\":true,\"private_copy_verified\":true}','')):\n if defect=='none':\n result=actuator.offline_verify(journal)\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\n self.assertTrue(result['original_snapshot_hash_unchanged'])\n else:\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\n self.assertEqual(len(reads),2)\n\n\nclass FixedNativeProgram(unittest.TestCase):\n def fixture(self):\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\n live = copy.deepcopy(sealed)\n live['metadata'].update(generation=42)\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\n cm = copy.deepcopy(dependencies['configmap'])\n cm.pop('canonical_data_sha256')\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\n pvc = copy.deepcopy(dependencies['pvc'])\n pvc['status'] = {'phase': 'Bound'}\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\n 'dependencies': dependencies, 'candidate': service,\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\n return objects, payload\n\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\n writes = []\n calls = []\n\n def fake(argv, input=None, **kwargs):\n calls.append(argv)\n if argv[:2] == ['kubectl', 'get']:\n kind = argv[2]\n if kind in objects:\n body = objects[kind]\n elif kind == 'pods':\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\n 'spec': objects['deployment']['spec']['template']['spec'],\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\n elif kind == 'replicaset':\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\n elif kind == 'nodes':\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\n else:\n raise AssertionError('unexpected fixed metadata route')\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\n if argv[:2] == ['kubectl', 'exec']:\n if schema_refused:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, json.dumps({\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\n if argv[:2] == ['kubectl', 'apply']:\n admitted = copy.deepcopy(payload['sealed'])\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\n if argv[:2] == ['kubectl', 'describe']:\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\n cpu 3460m (86%)\\n', '')\n if argv[:2] == ['kubectl', 'diff']:\n return subprocess.CompletedProcess(argv, 1, '-image: base\\n+image: candidate\\n', '')\n if argv[:2] == ['kubectl', 'patch']:\n if '--dry-run=server' not in argv:\n writes.append(json.loads(input))\n if ambiguous:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\n', '')\n raise AssertionError('unexpected command')\n\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n output = io.StringIO()\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\n try:\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\n except (ValueError, SystemExit):\n pass\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\n return receipt, writes, calls\n\n def test_only_existing_application_operation_and_deployment_are_requested(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n operation = writes[0][-1]['value']\n self.assertFalse(operation['sync']['prune'])\n self.assertEqual(operation['sync']['resources'], [\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\n\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\n lambda o: o['application']['spec'].update(sources=[{}]),\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n objects, payload = self.fixture()\n mutate(objects)\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n def test_preopen_schema_refusal_prevents_image_operation(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\n objects, payload = self.fixture()\n payload['phase'] = 'rollback'\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\n objects['application']['spec']['source']['targetRevision'] = REVISION\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\n\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\n for defect in ('cm', 'pvc', 'image'):\n with self.subTest(defect=defect):\n objects, payload = self.fixture();payload['phase'] = 'rollback'\n objects['deployment']['status']['readyReplicas'] = 0\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\n\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\n self.assertEqual(writes, [])\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\n objects['deployment']['status']['readyReplicas'] = 0\n receipt, writes, calls = self.execute_fake(objects,payload)\n self.assertFalse(receipt['all_checks_pass'])\n\n def test_ambiguous_patch_is_never_retried(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(len(writes), 1)\n\n\nif __name__ == '__main__':\n unittest.main()\n" + }, + "test_rescue_execution.py": { + "sha256": "8ecbb0260a87a7a12bd5c4c9678fb2a9d43a4ea7322129734bc21f8ee383cd70", + "content": "\"\"\"Synthetic recovery guards; no actual private journal/DB/native command.\"\"\"\nimport copy\nimport datetime\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport tempfile\nimport unittest\nfrom authority_journal import Journal, authority, original_anchor\nfrom test_execution import accepted, NOW, REVISION\n\nROOT=Path(__file__).parent\nPLAN=json.loads((ROOT/'execution-plan.json').read_text())\nCASE=ROOT.parent\nBACKUP=json.loads((CASE/'original-approved-drill-backup.json').read_text())\n\nclass RescueGuards(unittest.TestCase):\n def original(self,parent):\n original={'identity':PLAN['recovery']['original_identity'],'phases':{}}\n for name,metadata in PLAN['recovery']['original_anchor']['phase_metadata'].items():\n original['phases'][name]={**metadata,'result':BACKUP if name=='drill-backup' else {'all_checks_pass':False}}\n p=parent/'execution-journal.json';p.write_text(json.dumps(original));os.chmod(p,0o600)\n anchor=copy.deepcopy(PLAN['recovery']['original_anchor']);anchor['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\n return p,original,anchor\n\n def test_exact_original_failed_journal_is_linked_without_mutation(self):\n with tempfile.TemporaryDirectory() as directory:\n parent=Path(directory);os.chmod(parent,0o700);p,original,expected=self.original(parent);before=p.read_bytes()\n anchor=original_anchor(parent,expected,BACKUP,original['identity'])\n j=Journal(parent,{'fixture':True,'recovery_anchor':anchor});j.start('drill-copy-rescue-r1',{})\n self.assertEqual(p.read_bytes(),before);self.assertEqual(j.path.name,'rescue-execution-journal-r1.json')\n j.finish('drill-copy-rescue-r1',{'all_checks_pass':True});j.start('offline-verify',{})\n self.assertEqual(p.read_bytes(),before);j.close()\n\n def test_original_missing_uncertain_recreated_attempt_or_rollout_refuse(self):\n for defect in ('missing','complete','attempt','rollout','hash'):\n with self.subTest(defect=defect),tempfile.TemporaryDirectory() as directory:\n parent=Path(directory);os.chmod(parent,0o700);p,o,e=self.original(parent)\n if defect=='missing':o['phases'].pop('drill-copy')\n elif defect=='complete':o['phases']['drill-copy']['state']='COMPLETE'\n elif defect=='attempt':o['phases']['drill-copy']['attempt_id']='different'\n elif defect=='rollout':o['phases']['release']={'state':'RUNNING'}\n if defect!='hash':\n p.write_text(json.dumps(o));e['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\n else:e['original_journal_sha256']='0'*64\n with self.assertRaises((ValueError,KeyError)):original_anchor(parent,e,BACKUP,PLAN['recovery']['original_identity'])\n\n def test_rescue_replay_refused_and_old_phase_never_admitted(self):\n with tempfile.TemporaryDirectory() as directory:\n os.chmod(directory,0o700);j=Journal(directory,{'fixture':True})\n with self.assertRaises(ValueError):j.start('drill-copy',{})\n with self.assertRaises(ValueError):j.start('drill-backup',{})\n with self.assertRaises(ValueError):j.start('offline-verify',{})\n j.start('drill-copy-rescue-r1',{});j.finish('drill-copy-rescue-r1',{'all_checks_pass':False})\n with self.assertRaises(ValueError):j.start('drill-copy-rescue-r1',{})\n with self.assertRaises(ValueError):j.start('offline-verify',{})\n j.close()\n\n def test_new_authority_requires_version2_old_approval_refuses(self):\n receipt,outcome=accepted();receipt['memo_version']=2;outcome['dispositions'][0]['disposition']['memo_version']=1\n authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\n receipt['memo_version']=1\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy',NOW)\n receipt['memo_version']=2;receipt['outcome_query']='/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=1'\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\n\n def test_explicit_offline_input_mapping_and_absence_guards(self):\n source=(ROOT/'actuator.py').read_text()\n self.assertIn(\"previous = journal.data['phases']['drill-copy-rescue-r1']['result']\",source)\n self.assertIn(\"not os.path.lexists(CUSTODY / 'drill.sqlite')\",source)\n self.assertIn(\"VOLUME not in listed.stdout.splitlines()\",source)\n self.assertNotIn(\"os.mkdir(CUSTODY\",source)\n import ast\n program=ast.literal_eval(next(n.value for n in ast.parse((ROOT/'native_program.py').read_text()).body if isinstance(n,ast.Assign)))\n compile(program,'native-rescue-fixture','exec')\n self.assertIn(\"phase=='drill-copy-rescue-r1':require(pod['metadata']['uid']=='e8561ae0-4b09-4455-924d-64c27b625fc7'\",program)\n\nif __name__=='__main__':unittest.main()\n" + }, + "validation.json": { + "sha256": "6f3379f63968e9a0294aba7b5b57ea4662adda6b1fa1b37eff11c2f72a58931f", + "content": "{\n \"state\": \"prepared-unapproved-version2\",\n \"executor_tests\": 21,\n \"snapshot_mock_tests\": 5,\n \"native_actions\": false,\n \"database_admin_commands_in_preparation\": false,\n \"old_journal_modified\": false,\n \"old_failed_phase_retried\": false,\n \"owner_head_unchanged\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\"\n}\n" + } + }, + "native_execution": false, + "case_evidence": { + "original-approved-drill-backup.json": { + "sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "content": "{\"phase\": \"drill-backup\", \"all_checks_pass\": true, \"raw_output_withheld\": true, \"native_approval_verified_by_root\": {\"approval_id\": \"ec92806a-9aa6-494f-a76b-0385f39ba609\", \"disposition_id\": \"disp-0968373d-294d-42bf-8979-36a7c5dd38cf\", \"accepted_at\": \"2026-10-11T02:34:20Z\", \"verified_at\": \"2026-10-11T02:38:41.777949+00:00\"}, \"native_authenticated_grant\": false, \"source_readonly_baseline\": {\"schema_version\": 5, \"lifecycle\": {\"records\": 15, \"events\": 50, \"pending\": 0}, \"outbox\": {\"delivered\": 320}, \"submissions\": {\"confirmed\": 41}, \"integrity\": \"ok\", \"read_only_pre_open\": true, \"store_constructed\": false}, \"snapshot_readonly\": {\"schema_version\": 5, \"lifecycle\": {\"records\": 15, \"events\": 50, \"pending\": 0}, \"outbox\": {\"delivered\": 320}, \"submissions\": {\"confirmed\": 41}, \"integrity\": \"ok\", \"read_only_pre_open\": true, \"store_constructed\": false}, \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\", \"snapshot_bytes\": 19537920, \"snapshot_file\": \"drill.sqlite\", \"native_parent_private\": true, \"native_uid\": 10001, \"pod_name\": \"informed-decision-f557556df-mwpz7\", \"pod_uid\": \"e8561ae0-4b09-4455-924d-64c27b625fc7\"}\n" + }, + "original-approved-drill-copy-failure.json": { + "sha256": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56", + "content": "{\"all_checks_pass\": false, \"phase\": \"drill-copy\", \"failure_class\": \"ValueError\", \"failure\": \"fixed phase outcome uncertain; original evidence retained; no retry\", \"raw_output_withheld\": true}\n" + }, + "original-journal-sanitized-anchor.json": { + "sha256": "988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454", + "content": "{\n \"original_journal_sha256\": \"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\",\n \"phase_metadata\": {\n \"drill-backup\": {\n \"state\": \"COMPLETE\",\n \"attempt_id\": \"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\",\n \"started_at\": \"2026-10-11T02:38:45.310653+00:00\"\n },\n \"drill-copy\": {\n \"state\": \"UNCERTAIN\",\n \"attempt_id\": \"329ef190-1692-4246-b953-e6a59664abcc\",\n \"started_at\": \"2026-10-11T02:39:50.198740+00:00\"\n }\n },\n \"frozen_backup_receipt_sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\",\n \"snapshot_bytes\": 19537920,\n \"off_cluster_file_exists\": false,\n \"old_uncertain_retry_authorized\": false\n}\n" + } + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/README.md b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/README.md new file mode 100644 index 0000000..deb7f51 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/README.md @@ -0,0 +1,17 @@ +# Version2 protected existing-snapshot rescue — prepared, unapproved + +Original approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed. + +Fresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation. + +Fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase. + +Before rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome. + +Offline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup. + +Four committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension. + +Image763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation. + +Native publication route: POST existing source /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions with expected_version1 and exact memo2/documents/summary, then publications/review-requests version2. Fresh source readback must prove currentversion1 is unbound before revision; bound/different source stops. Intake/register refuse version2 as designed and are not used. Review integration creates a NEW review-ID at its own version1; founder disposition memo_version1 belongs to that new review. Root fresh outcomes must be queried for SOURCE version2, exact newreviewID/memoSHA and confirmed nested personapproval. Receipt outcome_query pins that sourceversion2 route; it does not authenticate by itself. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py new file mode 100644 index 0000000..4132e71 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py @@ -0,0 +1,368 @@ +"""One fixed supervised phase; never run this during source preparation.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +import selectors +import stat +import subprocess +import sys +import time + +if sys.flags.optimize: + raise SystemExit('optimized interpreter refused') + +PHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline', + 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') + + +def require(value, reason): + if not value: + raise ValueError(reason) + + +def sha(path): + digest = hashlib.sha256() + with Path(path).open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + digest.update(block) + return digest.hexdigest() + + +def private(path, directory=False): + info = Path(path).lstat() + require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode)) + and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600) + and (directory or info.st_nlink == 1), 'private owned custody required') + +ROOT = Path(__file__).resolve().parent +CASE = ROOT.parent +OWNER = Path('/home/worsch/informed-decision') +CUSTODIAN = Path('/home/worsch/the-custodian') +CUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1' +SOCKET = 'unix:///var/run/docker.sock' +IMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a' +VOLUME = 'infd-purpose-r1-restore-20261011' +MAX_BYTES = 512 * 1024**2 + + +def run(argv, body=None, timeout=90): + return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout) + + +def json_result(result): + try: + value = json.loads(result.stdout) + except (ValueError, TypeError): + raise ValueError('safe phase receipt unavailable; outcome uncertain') from None + require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True, + 'phase did not verify complete; raw output withheld; no retry') + permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root', + 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly', + 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private', + 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts', + 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision', + 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained', + 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained', + 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256', + 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'} + require(set(value) <= permitted, 'unexpected output fields withheld') + from receipt_safety import counts + for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'): + if name in value: + counts(value[name]) + for name in ('snapshot_sha256', 'client_diff_sha256'): + if name in value: + require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld') + if 'snapshot_bytes' in value: + require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES, + 'invalid output size withheld') + if 'snapshot_file' in value: + require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld') + return value + + +def docker(argv, body=None, timeout=120): + return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv, + body=body, timeout=timeout) + + +def remote(phase, revision, approved, snapshot_identity=None): + # Fixed module imported only after main verifies every executor source hash. + from native_program import PROGRAM + payload = {'snapshot_identity': snapshot_identity, 'phase': phase, 'source_revision': revision, 'approval': approved, + 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()), + 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()), + 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()), + 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()), + 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(), + 'purpose_checks': (CASE / 'check_installed.py').read_text(), + 'readonly': (CASE / 'sqlite_readonly.py').read_text()} + script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace( + '__GUARD__', repr((CASE / 'change_guard.py').read_text())) + return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200)) + + +def copy_snapshot(phase, revision, approved, journal): + prior = (journal.data['identity']['recovery_anchor']['backup_result'] + if phase == 'drill-copy-rescue-r1' else journal.data['phases']['cutover-backup']['result']) + metadata = remote(phase, revision, approved, snapshot_identity=prior) + for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'): + require(metadata[key] == prior[key], 'closed frozen snapshot changed') + name = metadata['snapshot_file'] + require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES, + 'fixed bounded snapshot required') + pod = metadata['pod_name'] + require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required') + local = CUSTODY / name + fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600) + # Binary snapshot stdout goes only to a private file, never tool/chat/log output. + # Snapshot schema/count metadata was validated before opening this destination. + with os.fdopen(fd, 'wb') as destination: + command = ('kubectl exec -n informed-decision ' + pod + + ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name) + transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL) + selector = selectors.DefaultSelector() + selector.register(transfer.stdout, selectors.EVENT_READ) + deadline = time.monotonic() + 150 + received = 0 + try: + while True: + remaining = deadline - time.monotonic() + require(remaining > 0 and selector.select(remaining), 'private transfer timed out') + block = os.read(transfer.stdout.fileno(), 1024**2) + if not block: + break + received += len(block) + require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES, + 'private copy exceeds frozen snapshot size') + destination.write(block) + transfer.wait(timeout=max(1, deadline - time.monotonic())) + finally: + selector.close() + transfer.stdout.close() + if transfer.poll() is None: + transfer.kill() + transfer.wait() + destination.flush() + os.fsync(destination.fileno()) + private(local) + require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes'] + and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry') + # Re-read identity/hash after transfer. This is verification, not a write retry. + after = remote(phase, revision, approved, snapshot_identity=prior) + require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'], + 'source identity/snapshot changed during transfer') + return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False} + + +def offline_verify(journal): + from receipt_safety import counts + snapshot = CUSTODY / 'drill.sqlite' + private(snapshot) + previous = journal.data['phases']['drill-copy-rescue-r1']['result'] + require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed') + identity = docker(['info', '--format', '{{json .Name}}']) + require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001', + 'local offline Docker engine identity changed') + listed = docker(['volume', 'ls', '--format', '{{.Name}}']) + require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(), + 'disposable volume absence not verified') + nonce = journal.data['phases']['offline-verify']['attempt_id'] + labels = {'informed-decision.case': 'infd-purpose-20261011-r1', + 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce} + created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1', + '--label', 'informed-decision.attempt=' + nonce, + '--label', 'informed-decision.use=offline-restore-only', VOLUME]) + require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry') + inspected = docker(['volume', 'inspect', VOLUME]) + require(inspected.returncode == 0, 'new volume identity unavailable') + volume = json.loads(inspected.stdout) + require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels + and volume[0].get('Driver') == 'local' and not volume[0].get('Options') + and volume[0].get('Scope') == 'local', 'new isolated volume identity changed') + identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')} + journal.note('offline-verify', 'created_volume_identity', identity) + # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume. + # No host/live PVC/config/token mount exists; this detail needs packet review. + initializer = """import hashlib,os,stat,sys +if sys.flags.optimize:raise RuntimeError('optimized interpreter refused') +folder='/restore';expected=EXPECTED +if os.listdir(folder):raise ValueError('new empty private volume required') +os.chmod(folder,0o700) +fd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600) +digest=hashlib.sha256();size=0 +with os.fdopen(fd,'wb') as target: + while True: + block=sys.stdin.buffer.read(1024**2) + if not block:break + size+=len(block) + if size>512*1024**2:raise ValueError('private restore size exceeds bound') + target.write(block);digest.update(block) + target.flush();os.fsync(target.fileno()) +if digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs') +os.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001) +print('{"all_checks_pass":true,"private_copy_verified":true}') +""".replace('EXPECTED', repr(previous['snapshot_sha256'])) + with snapshot.open('rb') as source: + argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET, + 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m', + '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN', + '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore', + '--entrypoint', 'python', IMAGE, '-c', initializer] + copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150) + json_result(copied) + options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m', + '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges', + '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore'] + readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'], + (CASE / 'sqlite_readonly.py').read_text()) + require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store') + checked = counts(json.loads(readonly.stdout)) + require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ') + admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE, + 'inspect', '--db', '/restore/review.sqlite']) + require(admin.returncode == 0, 'offline admin result uncertain') + admin_counts = json.loads(admin.stdout) + require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')}, + 'offline admin changed frozen snapshot counters') + # Admin Store construction must not silently alter schema/integrity/counters. + post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'], + (CASE / 'sqlite_readonly.py').read_text()) + require(post.returncode == 0, 'offline post-admin readonly integrity gate refused') + post_checked = counts(json.loads(post.stdout)) + require(post_checked == checked == previous['snapshot_readonly'], + 'offline admin altered frozen snapshot proof') + private(snapshot) + require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill') + return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked, + 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True, + 'created_volume_identity': identity, + 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False, + 'service_entrypoint_started': False, 'original_snapshot_retained': True} + + +def cleanup_offline(journal): + inspected = docker(['volume', 'inspect', VOLUME]) + require(inspected.returncode == 0, 'owned disposable volume identity unverified') + value = json.loads(inspected.stdout) + expected = journal.data['phases']['offline-verify']['result']['created_volume_identity'] + require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected + and not value[0].get('Options'), 'volume ownership/recreation changed') + removed = docker(['volume', 'rm', VOLUME]) + require(removed.returncode == 0 and removed.stdout.strip() == VOLUME + and docker(['volume', 'inspect', VOLUME]).returncode != 0, + 'cleanup outcome ambiguous; do not retry') + return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME, + 'native_and_offcluster_original_snapshots_retained': True} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--phase', choices=PHASES, required=True) + parser.add_argument('--root-authority-receipt', type=Path, required=True) + parser.add_argument('--root-native-outcome', type=Path, required=True) + parser.add_argument('--source-revision', required=True) + args = parser.parse_args() + require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json') + and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'), + 'fixed supervised receipt paths required') + require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required') + # Verify all prepared executor/input bytes before reading authority or dispatching. + plan = json.loads((ROOT / 'execution-plan.json').read_text()) + require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'}, + 'fixed executor sources required') + require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json', + 'deploy/lifecycle/service.candidate.json', + 'deploy/lifecycle/kustomization.yaml', + 'deploy/lifecycle/registries.candidate.json'}, + 'fixed owner image sources required') + for relative, digest in plan['executor_files'].items(): + target = ROOT / relative + require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed') + for relative, digest in plan['case_files'].items(): + require(not Path(relative).is_absolute() and '..' not in Path(relative).parts, + 'case source path escaped') + target = CASE / relative + require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed') + for relative, digest in plan['owner_source_files'].items(): + target = OWNER / relative + require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed') + committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative], + capture_output=True) + require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest, + 'committed owner render source differs from approved inputs') + head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD']) + require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs') + from authority_journal import Journal, authority, original_anchor + private(args.root_authority_receipt) + private(args.root_native_outcome) + receipt = json.loads(args.root_authority_receipt.read_text()) + require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed') + require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'), + 'root verified executor plan differs') + approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'), + args.source_revision, args.phase) + parent = CUSTODY.parent + private(parent, directory=True) + ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')]) + require(ignored.returncode == 0, 'offcluster custody is not ignored') + require(CUSTODY.exists(), 'original protected custody must already exist') + private(CUSTODY, directory=True) + capacity = os.statvfs(CUSTODY) + require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2, + 'independent protected custody headroom insufficient') + os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True) + private(CUSTODY / 'empty-docker-config', directory=True) + require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty') + anchor = original_anchor(CUSTODY, plan['recovery']['original_anchor'], + json.loads((CASE / 'original-approved-drill-backup.json').read_text()), + plan['recovery']['original_identity']) + if args.phase == 'drill-copy-rescue-r1': + require(not os.path.lexists(CUSTODY / 'drill.sqlite') + and not os.path.lexists(CUSTODY / 'cutover.sqlite'), 'rescue destination must be absent') + identity = docker(['info', '--format', '{{json .Name}}']) + require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001', + 'local engine identity changed') + listed = docker(['volume', 'ls', '--format', '{{.Name}}']) + require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(), + 'existing restore volume forbids rescue') + journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision, + 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json'), + 'recovery_anchor': anchor}) + try: + journal.start(args.phase, approved) # fsynced RUNNING before any phase effect. + if args.phase in ('drill-copy-rescue-r1', 'cutover-copy'): + result = copy_snapshot(args.phase, args.source_revision, approved, journal) + elif args.phase == 'offline-verify': + result = offline_verify(journal) + elif args.phase == 'cleanup-offline': + result = cleanup_offline(journal) + else: + result = remote(args.phase, args.source_revision, approved) + require(original_anchor(CUSTODY, plan['recovery']['original_anchor'], + json.loads((CASE / 'original-approved-drill-backup.json').read_text()), + plan['recovery']['original_identity']) == anchor, + 'original failed journal changed during new phase') + journal.finish(args.phase, result) + print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes. + except BaseException as error: + safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__, + 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry', + 'raw_output_withheld': True} + if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING': + journal.finish(args.phase, safe) + print(json.dumps(safe)) + raise SystemExit(1) from None + finally: + journal.close() + + +if __name__ == '__main__': + try: + main() + except Exception: + raise SystemExit('supervised execution refused before phase; raw output withheld') from None diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py new file mode 100644 index 0000000..809d13f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py @@ -0,0 +1,176 @@ +"""Supervised receipt bookkeeping, not an authenticated approval provider.""" +import datetime +import fcntl +import hashlib +import json +import os +import re +from pathlib import Path +import stat +import uuid + +FOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'} +MEMO_ID = 'infd-20261011-purpose-overlay-r1' +PROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1' +PHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline', + 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') + + +def require(value, reason): + if not value: + raise ValueError(reason) + + +def sha(path): + digest = hashlib.sha256() + with Path(path).open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + digest.update(block) + return digest.hexdigest() + + +def private(path, directory=False): + info = Path(path).lstat() + require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode)) + and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600) + and (directory or info.st_nlink == 1), 'private owned custody required') + + +def authority(receipt, outcome, memo_sha, source_revision, phase, now=None): + """Root must freshly verify native outcome at fixed ORIGIN outside this helper. + + Receipt files/flags are not signed grants. This function checks the exact + supervised receipt relation; existing harness/founder authority remains the + actual permission boundary. It never authenticates a caller as human. + """ + now = now or datetime.datetime.now(datetime.timezone.utc) + require(phase in PHASES, 'fixed phase required') + require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID + and receipt.get('memo_version') == 2 and receipt.get('memo_sha256') == memo_sha + and receipt.get('source_revision') == source_revision + and receipt.get('activation') == 'APPROVED' + and receipt.get('authority_mode') == 'ADMINISTER' + and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision' + and receipt.get('verification_method') == 'root-fixed-origin-native-readback' + and receipt.get('runtime_authenticated_grant') is False + and receipt.get('outcome_query') == '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2', + 'exact externally verified supervised receipt required') + verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00')) + require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120, + 'fresh root native readback required before every phase') + deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00') + require(now < deadline, 'approved execution window expired') + require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False + and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current') + review_id = outcome['review']['memo_id'] + require(review_id == receipt.get('review_memo_id'), 'native review identity changed') + accepted = [x for x in outcome.get('dispositions', []) + if x.get('submission_state') == 'confirmed' + and x.get('disposition', {}).get('verb') == 'accept' + and x['disposition'].get('memo_version') == 1] + require(len(accepted) == 1, 'one confirmed founder acceptance required') + accepted = accepted[0]['disposition'] + require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id + and accepted.get('approval_id') == receipt.get('approval_id') + and accepted.get('id') == receipt.get('disposition_id') + and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch') + require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None + and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None + and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None, + 'native disposition identifiers are malformed') + accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00')) + require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded') + return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')} + + +def original_anchor(parent, expected, backup_result, original_identity): + """Read only sanitized original journal; never rewrite/synthesize its phases.""" + path = Path(parent) / 'execution-journal.json' + private(path) + require(sha(path) == expected['original_journal_sha256'], 'original journal bytes changed') + original = json.loads(path.read_text()) + require(original.get('identity') == original_identity, 'original approved identity changed') + phases = original.get('phases', {}) + require(set(phases) == {'drill-backup', 'drill-copy'}, 'unexpected original action or rollout') + for name, fields in expected['phase_metadata'].items(): + require(all(phases[name].get(key) == value for key,value in fields.items()), + 'original failed/completed attempt identity changed') + require(phases['drill-backup'].get('result') == backup_result + and backup_result.get('all_checks_pass') is True + and phases['drill-copy'].get('result', {}).get('all_checks_pass') is False, + 'original backup/copy outcome changed') + require(backup_result.get('snapshot_sha256') == expected['snapshot_sha256'] + and backup_result.get('snapshot_bytes') == expected['snapshot_bytes'] + and backup_result.get('pod_uid') == 'e8561ae0-4b09-4455-924d-64c27b625fc7', + 'original frozen snapshot identity changed') + require(sha(path) == expected['original_journal_sha256'], 'original journal changed during read') + return {'original_journal_sha256': expected['original_journal_sha256'], + 'original_copy_attempt_id': phases['drill-copy']['attempt_id'], + 'original_backup_attempt_id': phases['drill-backup']['attempt_id'], + 'backup_result': backup_result, 'old_uncertain_phase_retained': True} + + +class Journal: + def __init__(self, parent, identity): + self.parent = Path(parent) + private(self.parent, directory=True) + self.path = self.parent / 'rescue-execution-journal-r1.json' + self.lock = os.open(self.parent / 'rescue-execution-r1.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600) + fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB) + private(self.parent / 'rescue-execution-r1.lock') + if self.path.exists(): + private(self.path) + self.data = json.loads(self.path.read_text()) + require(self.data['identity'] == identity, 'journal case/source identity changed') + else: + self.data = {'identity': identity, 'phases': {}} + self.save() + + def save(self): + temporary = self.parent / 'execution-journal.new' + fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600) + try: + with os.fdopen(fd, 'w') as stream: + json.dump(self.data, stream, indent=2) + stream.write('\n') + stream.flush() + os.fsync(stream.fileno()) + os.replace(temporary, self.path) + directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY) + try: + os.fsync(directory) + finally: + os.close(directory) + except BaseException: + # Retain evidence rather than overwriting an uncertain durable intent. + raise + + def start(self, phase, approval): + require(phase not in self.data['phases'], 'already attempted phase; no retry') + require(phase in PHASES, 'fixed rescue or remaining phase required') + predecessors = dict(zip(PHASES[1:7], PHASES[:6])) + predecessors['rollback-verify'] = 'rollback' + if phase in predecessors: + require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE', + 'preceding phase is not verified complete') + if phase == 'rollback': + require('release' in self.data['phases'], 'rollback requires a recorded release attempt') + self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval, + 'attempt_id': str(uuid.uuid4()), + 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()} + self.save() + + def note(self, phase, key, value): + require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing') + self.data['phases'][phase][key] = value + self.save() + + def finish(self, phase, result): + entry = self.data['phases'][phase] + require(entry['state'] == 'RUNNING', 'phase intent missing') + entry['result'] = result + entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN' + self.save() + + def close(self): + os.close(self.lock) diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json new file mode 100644 index 0000000..6e6ec08 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json @@ -0,0 +1,89 @@ +{ + "kind": "informed-decision.supervised-mechanical-release-plan", + "version": 2, + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "trial_id": "infd-purpose-20261011-r1", + "state": "prepared-unapproved", + "executor_files": { + "actuator.py": "86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2", + "authority_journal.py": "0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68", + "native_program.py": "788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91", + "receipt_safety.py": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + "case_files": { + "change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "sqlite_readonly.py": "9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509", + "preflight-inputs.json": "03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b", + "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", + "published-verification.json": "e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd", + "security-summary.json": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "original-approved-drill-backup.json": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "original-approved-drill-copy-failure.json": "fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56", + "original-journal-sanitized-anchor.json": "988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454" + }, + "owner_source_files": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "source_revision": "must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs", + "phases": [ + "drill-copy-rescue-r1", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "authorization": "fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant", + "execute_by": "2026-10-12T23:59:59Z", + "raw_output_withheld": true, + "native_data_or_workload_action_executed": false, + "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.", + "recovery": { + "original_anchor": { + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false + }, + "original_identity": { + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "memo_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937", + "plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + "new_journal": "rescue-execution-journal-r1.json", + "new_phase": "drill-copy-rescue-r1", + "old_uncertain_phase_overwrite_or_retry": false, + "new_snapshot_backup": false, + "snapshot_or_sidecar_mutation": false, + "mapping": "offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal" + }, + "source_memo_version": 2, + "native_review_memo_version": 1 +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py new file mode 100644 index 0000000..38f7c33 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py @@ -0,0 +1,2 @@ +"""Fixed version2 recovery remote source; requires fresh exact acceptance.""" +PROGRAM = '\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\nif sys.flags.optimize:raise RuntimeError(\'optimized interpreter refused\')\npayload=json.loads(__PAYLOAD__)\nexec(__GUARD__)\nphase=payload[\'phase\']\nif phase not in (\'cutover-backup\',\'drill-copy-rescue-r1\',\'cutover-copy\',\'release\',\'verify\',\'rollback\',\'rollback-verify\'):raise ValueError(\'fixed native phase required\')\ndeadline=datetime.datetime.fromisoformat(\'2026-10-12T23:59:59+00:00\')\ndef require(value,reason):\n if not value:raise ValueError(reason)\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\'drill-backup\' else 1)+16*1024**2,\'bounded native snapshot capacity required\')\n if action==\'drill-backup\':\n require(not os.path.lexists(folder),\'native case directory must be unique\')\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\n private(folder,True)\n filename=\'drill.sqlite\' if action==\'drill-backup\' else \'cutover.sqlite\';output=folder+\'/\'+filename\n require(not os.path.lexists(output),\'snapshot output must be unique\')\n admin=subprocess.run([\'informed-decision-admin\',\'backup\',\'--db\',db,\'--output\',output],capture_output=True,text=True,timeout=120)\n require(admin.returncode==0 and json.loads(admin.stdout)=={\'status\':\'backed_up\',\'consistent_snapshot\':True},\'backup completion not verified; do not retry\')\n private(output)\n for suffix in (\'-wal\',):\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\'snapshot has WAL frames; immutable read refused\')\n digest=hashlib.sha256()\n with open(output,\'rb\') as stream:\n for block in iter(lambda:stream.read(1024**2),b\'\'):digest.update(block)\n frozen_digest=digest.hexdigest()\n snapshot=counts(inspect_closed_snapshot(output,frozen_digest))\n size=os.stat(output).st_size;require(0 --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase.\n\nThe private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence.\n\nNew private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required.\n\nEvery phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions.\n\nExisting Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes.\n\nSixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof.\n\nAll phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance.\n\nThe initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred.\n" + }, + "actuator.py": { + "sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5", + "content": "\"\"\"One fixed supervised phase; never run this during source preparation.\"\"\"\nimport argparse\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport re\nimport selectors\nimport stat\nimport subprocess\nimport sys\nimport time\n\nif sys.flags.optimize:\n raise SystemExit('optimized interpreter refused')\n\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\nROOT = Path(__file__).resolve().parent\nCASE = ROOT.parent\nOWNER = Path('/home/worsch/informed-decision')\nCUSTODIAN = Path('/home/worsch/the-custodian')\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\nSOCKET = 'unix:///var/run/docker.sock'\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\nVOLUME = 'infd-purpose-r1-restore-20261011'\nMAX_BYTES = 512 * 1024**2\n\n\ndef run(argv, body=None, timeout=90):\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\n\n\ndef json_result(result):\n try:\n value = json.loads(result.stdout)\n except (ValueError, TypeError):\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\n 'phase did not verify complete; raw output withheld; no retry')\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\n require(set(value) <= permitted, 'unexpected output fields withheld')\n from receipt_safety import counts\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\n if name in value:\n counts(value[name])\n for name in ('snapshot_sha256', 'client_diff_sha256'):\n if name in value:\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\n if 'snapshot_bytes' in value:\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\n 'invalid output size withheld')\n if 'snapshot_file' in value:\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\n return value\n\n\ndef docker(argv, body=None, timeout=120):\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\n body=body, timeout=timeout)\n\n\ndef remote(phase, revision, approved):\n # Fixed module imported only after main verifies every executor source hash.\n from native_program import PROGRAM\n payload = {'phase': phase, 'source_revision': revision, 'approval': approved,\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\n\n\ndef copy_snapshot(phase, revision, approved, journal):\n metadata = remote(phase, revision, approved)\n backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup'\n prior = journal.data['phases'][backup_phase]['result']\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\n name = metadata['snapshot_file']\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\n 'fixed bounded snapshot required')\n pod = metadata['pod_name']\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\n local = CUSTODY / name\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\n # Snapshot schema/count metadata was validated before opening this destination.\n with os.fdopen(fd, 'wb') as destination:\n command = ('kubectl exec -n informed-decision ' + pod +\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\n stderr=subprocess.DEVNULL)\n selector = selectors.DefaultSelector()\n selector.register(transfer.stdout, selectors.EVENT_READ)\n deadline = time.monotonic() + 150\n received = 0\n try:\n while True:\n remaining = deadline - time.monotonic()\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\n block = os.read(transfer.stdout.fileno(), 1024**2)\n if not block:\n break\n received += len(block)\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\n 'private copy exceeds frozen snapshot size')\n destination.write(block)\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\n finally:\n selector.close()\n transfer.stdout.close()\n if transfer.poll() is None:\n transfer.kill()\n transfer.wait()\n destination.flush()\n os.fsync(destination.fileno())\n private(local)\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\n # Re-read identity/hash after transfer. This is verification, not a write retry.\n after = remote(phase, revision, approved)\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\n 'source identity/snapshot changed during transfer')\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\n\n\ndef offline_verify(journal):\n from receipt_safety import counts\n snapshot = CUSTODY / 'drill.sqlite'\n private(snapshot)\n previous = journal.data['phases']['drill-copy']['result']\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\n identity = docker(['info', '--format', '{{json .Name}}'])\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\n 'local offline Docker engine identity changed')\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\n 'disposable volume absence not verified')\n nonce = journal.data['phases']['offline-verify']['attempt_id']\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\n '--label', 'informed-decision.attempt=' + nonce,\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'new volume identity unavailable')\n volume = json.loads(inspected.stdout)\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\n journal.note('offline-verify', 'created_volume_identity', identity)\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\n # No host/live PVC/config/token mount exists; this detail needs packet review.\n initializer = \"\"\"import hashlib,os,stat,sys\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\nfolder='/restore';expected=EXPECTED\nif os.listdir(folder):raise ValueError('new empty private volume required')\nos.chmod(folder,0o700)\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\ndigest=hashlib.sha256();size=0\nwith os.fdopen(fd,'wb') as target:\n while True:\n block=sys.stdin.buffer.read(1024**2)\n if not block:break\n size+=len(block)\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\n target.write(block);digest.update(block)\n target.flush();os.fsync(target.fileno())\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\nprint('{\"all_checks_pass\":true,\"private_copy_verified\":true}')\n\"\"\".replace('EXPECTED', repr(previous['snapshot_sha256']))\n with snapshot.open('rb') as source:\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\n '--entrypoint', 'python', IMAGE, '-c', initializer]\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\n json_result(copied)\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\n checked = counts(json.loads(readonly.stdout))\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\n 'inspect', '--db', '/restore/review.sqlite'])\n require(admin.returncode == 0, 'offline admin result uncertain')\n admin_counts = json.loads(admin.stdout)\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\n 'offline admin changed frozen snapshot counters')\n # Admin Store construction must not silently alter schema/integrity/counters.\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\n (CASE / 'sqlite_readonly.py').read_text())\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\n post_checked = counts(json.loads(post.stdout))\n require(post_checked == checked == previous['snapshot_readonly'],\n 'offline admin altered frozen snapshot proof')\n private(snapshot)\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\n 'created_volume_identity': identity,\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\n\n\ndef cleanup_offline(journal):\n inspected = docker(['volume', 'inspect', VOLUME])\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\n value = json.loads(inspected.stdout)\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\n and not value[0].get('Options'), 'volume ownership/recreation changed')\n removed = docker(['volume', 'rm', VOLUME])\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\n 'cleanup outcome ambiguous; do not retry')\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\n 'native_and_offcluster_original_snapshots_retained': True}\n\n\ndef main():\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--phase', choices=PHASES, required=True)\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\n parser.add_argument('--root-native-outcome', type=Path, required=True)\n parser.add_argument('--source-revision', required=True)\n args = parser.parse_args()\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\n 'fixed supervised receipt paths required')\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\n # Verify all prepared executor/input bytes before reading authority or dispatching.\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\n 'fixed executor sources required')\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\n 'deploy/lifecycle/service.candidate.json',\n 'deploy/lifecycle/kustomization.yaml',\n 'deploy/lifecycle/registries.candidate.json'},\n 'fixed owner image sources required')\n for relative, digest in plan['executor_files'].items():\n target = ROOT / relative\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\n for relative, digest in plan['case_files'].items():\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\n 'case source path escaped')\n target = CASE / relative\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\n for relative, digest in plan['owner_source_files'].items():\n target = OWNER / relative\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\n capture_output=True)\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\n 'committed owner render source differs from approved inputs')\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\n from authority_journal import Journal, authority\n private(args.root_authority_receipt)\n private(args.root_native_outcome)\n receipt = json.loads(args.root_authority_receipt.read_text())\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\n 'root verified executor plan differs')\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\n args.source_revision, args.phase)\n parent = CUSTODY.parent\n private(parent, directory=True)\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\n if not CUSTODY.exists():\n require(args.phase == 'drill-backup', 'first approved phase must create unique private custody')\n os.mkdir(CUSTODY, 0o700)\n private(CUSTODY, directory=True)\n capacity = os.statvfs(CUSTODY)\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\n 'independent protected custody headroom insufficient')\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\n private(CUSTODY / 'empty-docker-config', directory=True)\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')})\n try:\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\n if args.phase in ('drill-copy', 'cutover-copy'):\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\n elif args.phase == 'offline-verify':\n result = offline_verify(journal)\n elif args.phase == 'cleanup-offline':\n result = cleanup_offline(journal)\n else:\n result = remote(args.phase, args.source_revision, approved)\n journal.finish(args.phase, result)\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\n except BaseException as error:\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\n 'raw_output_withheld': True}\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\n journal.finish(args.phase, safe)\n print(json.dumps(safe))\n raise SystemExit(1) from None\n finally:\n journal.close()\n\n\nif __name__ == '__main__':\n try:\n main()\n except Exception:\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\n" + }, + "authority_journal.py": { + "sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa", + "content": "\"\"\"Supervised receipt bookkeeping, not an authenticated approval provider.\"\"\"\nimport datetime\nimport fcntl\nimport hashlib\nimport json\nimport os\nimport re\nfrom pathlib import Path\nimport stat\nimport uuid\n\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\n\n\ndef require(value, reason):\n if not value:\n raise ValueError(reason)\n\n\ndef sha(path):\n digest = hashlib.sha256()\n with Path(path).open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n digest.update(block)\n return digest.hexdigest()\n\n\ndef private(path, directory=False):\n info = Path(path).lstat()\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\n and (directory or info.st_nlink == 1), 'private owned custody required')\n\n\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\n \"\"\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\n\n Receipt files/flags are not signed grants. This function checks the exact\n supervised receipt relation; existing harness/founder authority remains the\n actual permission boundary. It never authenticates a caller as human.\n \"\"\"\n now = now or datetime.datetime.now(datetime.timezone.utc)\n require(phase in PHASES, 'fixed phase required')\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\n and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha\n and receipt.get('source_revision') == source_revision\n and receipt.get('activation') == 'APPROVED'\n and receipt.get('authority_mode') == 'ADMINISTER'\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\n and receipt.get('runtime_authenticated_grant') is False,\n 'exact externally verified supervised receipt required')\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\n 'fresh root native readback required before every phase')\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\n require(now < deadline, 'approved execution window expired')\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\n review_id = outcome['review']['memo_id']\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\n accepted = [x for x in outcome.get('dispositions', [])\n if x.get('submission_state') == 'confirmed'\n and x.get('disposition', {}).get('verb') == 'accept'\n and x['disposition'].get('memo_version') == 1]\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\n accepted = accepted[0]['disposition']\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\n and accepted.get('approval_id') == receipt.get('approval_id')\n and accepted.get('id') == receipt.get('disposition_id')\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\n 'native disposition identifiers are malformed')\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\n\n\nclass Journal:\n def __init__(self, parent, identity):\n self.parent = Path(parent)\n private(self.parent, directory=True)\n self.path = self.parent / 'execution-journal.json'\n self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\n private(self.parent / 'execution.lock')\n if self.path.exists():\n private(self.path)\n self.data = json.loads(self.path.read_text())\n require(self.data['identity'] == identity, 'journal case/source identity changed')\n else:\n self.data = {'identity': identity, 'phases': {}}\n self.save()\n\n def save(self):\n temporary = self.parent / 'execution-journal.new'\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\n try:\n with os.fdopen(fd, 'w') as stream:\n json.dump(self.data, stream, indent=2)\n stream.write('\\n')\n stream.flush()\n os.fsync(stream.fileno())\n os.replace(temporary, self.path)\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\n try:\n os.fsync(directory)\n finally:\n os.close(directory)\n except BaseException:\n # Retain evidence rather than overwriting an uncertain durable intent.\n raise\n\n def start(self, phase, approval):\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\n predecessors = dict(zip(PHASES[1:8], PHASES[:7]))\n predecessors['rollback-verify'] = 'rollback'\n if phase in predecessors:\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\n 'preceding phase is not verified complete')\n if phase == 'rollback':\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\n 'attempt_id': str(uuid.uuid4()),\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\n self.save()\n\n def note(self, phase, key, value):\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\n self.data['phases'][phase][key] = value\n self.save()\n\n def finish(self, phase, result):\n entry = self.data['phases'][phase]\n require(entry['state'] == 'RUNNING', 'phase intent missing')\n entry['result'] = result\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\n self.save()\n\n def close(self):\n os.close(self.lock)\n" + }, + "execution-plan.json": { + "sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6", + "content": "{\n \"kind\": \"informed-decision.supervised-mechanical-release-plan\",\n \"version\": 1,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"executor_files\": {\n \"actuator.py\": \"6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5\",\n \"authority_journal.py\": \"74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa\",\n \"native_program.py\": \"349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde\",\n \"receipt_safety.py\": \"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\"\n },\n \"case_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\",\n \"preflight-inputs.json\": \"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"published-verification.json\": \"8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2\",\n \"security-summary.json\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"source_revision\": \"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\",\n \"phases\": [\n \"drill-backup\",\n \"drill-copy\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"authorization\": \"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\",\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"raw_output_withheld\": true,\n \"native_data_or_workload_action_executed\": false,\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\"\n}\n" + }, + "native_program.py": { + "sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde", + "content": "\"\"\"Fixed remote source, passed only after exact supervised approval.\"\"\"\nPROGRAM = '\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\nif sys.flags.optimize:raise RuntimeError(\\'optimized interpreter refused\\')\\npayload=json.loads(__PAYLOAD__)\\nexec(__GUARD__)\\nphase=payload[\\'phase\\']\\nif phase not in (\\'drill-backup\\',\\'cutover-backup\\',\\'drill-copy\\',\\'cutover-copy\\',\\'release\\',\\'verify\\',\\'rollback\\',\\'rollback-verify\\'):raise ValueError(\\'fixed native phase required\\')\\ndeadline=datetime.datetime.fromisoformat(\\'2026-10-12T23:59:59+00:00\\')\\ndef require(value,reason):\\n if not value:raise ValueError(reason)\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\'drill-backup\\' else 1)+16*1024**2,\\'bounded native snapshot capacity required\\')\\n if action==\\'drill-backup\\':\\n require(not os.path.lexists(folder),\\'native case directory must be unique\\')\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\n private(folder,True)\\n filename=\\'drill.sqlite\\' if action==\\'drill-backup\\' else \\'cutover.sqlite\\';output=folder+\\'/\\'+filename\\n require(not os.path.lexists(output),\\'snapshot output must be unique\\')\\n admin=subprocess.run([\\'informed-decision-admin\\',\\'backup\\',\\'--db\\',db,\\'--output\\',output],capture_output=True,text=True,timeout=120)\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\'status\\':\\'backed_up\\',\\'consistent_snapshot\\':True},\\'backup completion not verified; do not retry\\')\\n private(output)\\n for suffix in (\\'-wal\\',\\'-shm\\'):\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\'snapshot is not closed main-file custody\\')\\n snapshot=counts(inspect_readonly(output))\\n size=os.stat(output).st_size;require(0 10**12\n for number in value[group].values()):\n raise ValueError('count-only receipt values refused')\n return value\n" + }, + "root-authority-receipt-template.json": { + "sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"memo_id\": \"infd-20261011-purpose-overlay-r1\",\n \"memo_version\": 1,\n \"memo_sha256\": null,\n \"source_revision\": null,\n \"activation\": \"PENDING\",\n \"authority_mode\": \"ADMINISTER\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"verification_method\": \"root-fixed-origin-native-readback\",\n \"runtime_authenticated_grant\": false,\n \"verified_at\": null,\n \"accepted_at\": null,\n \"review_memo_id\": null,\n \"approval_id\": null,\n \"disposition_id\": null,\n \"native_outcome_sha256\": null,\n \"executor_plan_sha256\": \"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\"\n}\n" + }, + "test_execution.py": { + "sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48", + "content": "\"\"\"Synthetic custody/transport tests. No native data, Docker or cluster action.\"\"\"\nimport copy\nimport datetime\nimport io\nimport json\nimport os\nfrom pathlib import Path\nimport subprocess\nimport sys\nimport tempfile\nimport unittest\nfrom unittest.mock import patch\nfrom contextlib import redirect_stdout\n\nimport actuator\nfrom authority_journal import Journal, authority\nfrom native_program import PROGRAM\nfrom receipt_safety import counts\n\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\nREVISION = 'e' * 40\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\n\n\ndef accepted():\n approval = '11111111-1111-4111-8111-111111111111'\n review = 'review-22222222-2222-4222-8222-222222222222'\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1,\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False,\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\n 'approval_id': approval, 'id': disposition,\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\n 'at': receipt['accepted_at']}}]}\n return receipt, outcome\n\n\nclass AuthorityAndCustody(unittest.TestCase):\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\n receipt, outcome = accepted()\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW)\n self.assertEqual(result['approval_id'], receipt['approval_id'])\n\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\n mutations = [lambda r, o: r.update(activation='PENDING'),\n lambda r, o: r.update(memo_sha256='changed'),\n lambda r, o: r.update(source_revision='changed'),\n lambda r, o: r.update(target='other'),\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\n lambda r, o: r.update(verification_method='caller-asserted'),\n lambda r, o: r.update(runtime_authenticated_grant=True),\n lambda r, o: o['review'].update(stale=True),\n lambda r, o: o['review'].update(intake_state='pending'),\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2),\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n r, o = accepted()\n mutate(r, o)\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\n\n def test_expired_window_and_unknown_phase_refuse(self):\n r, o = accepted()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\n r['verified_at'] = late.isoformat()\n with self.assertRaises(ValueError):\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\n\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\n with tempfile.TemporaryDirectory() as directory:\n parent = Path(directory)\n os.chmod(parent, 0o700)\n journal = Journal(parent, {'case': 'fixture'})\n journal.start('drill-backup', {'approval_id': 'fixture'})\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING')\n journal.close() # simulated crash before result\n recovered = Journal(parent, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n recovered.start('drill-backup', {})\n with self.assertRaises(ValueError):\n recovered.start('drill-copy', {})\n recovered.close()\n\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\n with tempfile.TemporaryDirectory() as directory:\n os.chmod(directory, 0o700)\n j = Journal(directory, {'case': 'fixture'})\n with self.assertRaises(ValueError):\n j.start('release', {})\n for phase in actuator.PHASES[:6]:\n j.start(phase, {})\n j.finish(phase, {'all_checks_pass': True})\n j.start('release', {})\n j.finish('release', {'all_checks_pass': False})\n with self.assertRaises(ValueError):\n j.start('release', {})\n with self.assertRaises(ValueError):\n j.start('verify', {})\n j.start('rollback', {})\n j.finish('rollback', {'all_checks_pass': True})\n j.close()\n\n def test_secret_or_unknown_child_output_is_withheld(self):\n for body in ('not-json', '{\"all_checks_pass\":true,\"token\":\"private-value\"}',\n '{\"all_checks_pass\":true,\"snapshot_readonly\":{\"schema_version\":5}}'):\n with self.assertRaises(ValueError):\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\n wrong = copy.deepcopy(COUNT)\n wrong['outbox'] = {'private-row-value': 1}\n with self.assertRaises(ValueError):\n counts(wrong)\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\n\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\n blob = b'synthetic private fixture bytes'\n digest = __import__('hashlib').sha256(blob).hexdigest()\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\n journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})()\n real_popen = subprocess.Popen\n for extra in (b'', b'oversized'):\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\n os.chmod(folder, 0o700)\n output = io.StringIO()\n\n def child(*args, **kwargs):\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\n if extra:\n with self.assertRaises(ValueError):\n actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\n else:\n result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\n self.assertTrue(result['off_cluster_private_copy_verified'])\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\n self.assertEqual(output.getvalue(), '')\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\n\n def test_recreated_offline_volume_cannot_be_deleted(self):\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\n journal = type('FixtureJournal', (), {'data': {'phases': {\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\n with self.assertRaises(ValueError):\n actuator.cleanup_offline(journal)\n self.assertEqual(mocked.call_count, 1)\n\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\n for defect in ('none', 'post-integrity', 'original-hash'):\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\n folder=Path(directory);os.chmod(folder,0o700)\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\n digest=actuator.sha(snapshot)\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\n reads=[]\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\n def docker(argv, body=None, **kwargs):\n if argv[0]=='info':body=json.dumps('bnt-lap001')\n elif argv[:2]==['volume','ls']:body=''\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\n elif 'informed-decision-admin' in argv:\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\n elif '--entrypoint' in argv and 'python' in argv:\n reads.append(argv);proof=copy.deepcopy(COUNT)\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\n body=json.dumps(proof)\n else:raise AssertionError('unexpected offline command')\n return subprocess.CompletedProcess(argv,0,body,'')\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\"all_checks_pass\":true,\"private_copy_verified\":true}','')):\n if defect=='none':\n result=actuator.offline_verify(journal)\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\n self.assertTrue(result['original_snapshot_hash_unchanged'])\n else:\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\n self.assertEqual(len(reads),2)\n\n\nclass FixedNativeProgram(unittest.TestCase):\n def fixture(self):\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\n live = copy.deepcopy(sealed)\n live['metadata'].update(generation=42)\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\n cm = copy.deepcopy(dependencies['configmap'])\n cm.pop('canonical_data_sha256')\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\n pvc = copy.deepcopy(dependencies['pvc'])\n pvc['status'] = {'phase': 'Bound'}\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\n 'dependencies': dependencies, 'candidate': service,\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\n return objects, payload\n\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\n writes = []\n calls = []\n\n def fake(argv, input=None, **kwargs):\n calls.append(argv)\n if argv[:2] == ['kubectl', 'get']:\n kind = argv[2]\n if kind in objects:\n body = objects[kind]\n elif kind == 'pods':\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\n 'spec': objects['deployment']['spec']['template']['spec'],\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\n elif kind == 'replicaset':\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\n elif kind == 'nodes':\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\n else:\n raise AssertionError('unexpected fixed metadata route')\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\n if argv[:2] == ['kubectl', 'exec']:\n if schema_refused:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, json.dumps({\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\n if argv[:2] == ['kubectl', 'apply']:\n admitted = copy.deepcopy(payload['sealed'])\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\n if argv[:2] == ['kubectl', 'describe']:\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\n cpu 3460m (86%)\\n', '')\n if argv[:2] == ['kubectl', 'diff']:\n return subprocess.CompletedProcess(argv, 1, '-image: base\\n+image: candidate\\n', '')\n if argv[:2] == ['kubectl', 'patch']:\n if '--dry-run=server' not in argv:\n writes.append(json.loads(input))\n if ambiguous:\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\n', '')\n raise AssertionError('unexpected command')\n\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\n output = io.StringIO()\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\n try:\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\n except (ValueError, SystemExit):\n pass\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\n return receipt, writes, calls\n\n def test_only_existing_application_operation_and_deployment_are_requested(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n operation = writes[0][-1]['value']\n self.assertFalse(operation['sync']['prune'])\n self.assertEqual(operation['sync']['resources'], [\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\n\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\n lambda o: o['application']['spec'].update(sources=[{}]),\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\n for mutate in mutations:\n with self.subTest(mutate=mutate):\n objects, payload = self.fixture()\n mutate(objects)\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n def test_preopen_schema_refusal_prevents_image_operation(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(writes, [])\n\n\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\n objects, payload = self.fixture()\n payload['phase'] = 'rollback'\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\n objects['application']['spec']['source']['targetRevision'] = REVISION\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\n self.assertTrue(receipt['all_checks_pass'])\n self.assertFalse(receipt['rollout_verified'])\n self.assertEqual(len(writes), 1)\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\n\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\n for defect in ('cm', 'pvc', 'image'):\n with self.subTest(defect=defect):\n objects, payload = self.fixture();payload['phase'] = 'rollback'\n objects['deployment']['status']['readyReplicas'] = 0\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\n\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\n receipt, writes, calls = self.execute_fake(objects, payload)\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\n self.assertEqual(writes, [])\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\n objects['deployment']['status']['readyReplicas'] = 0\n receipt, writes, calls = self.execute_fake(objects,payload)\n self.assertFalse(receipt['all_checks_pass'])\n\n def test_ambiguous_patch_is_never_retried(self):\n objects, payload = self.fixture()\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\n self.assertFalse(receipt['all_checks_pass'])\n self.assertEqual(len(writes), 1)\n\n\nif __name__ == '__main__':\n unittest.main()\n" + }, + "validation.json": { + "sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28", + "content": "{\n \"tests\": 16,\n \"result\": \"passed\",\n \"synthetic_transport_only\": true,\n \"real_native_data_read\": false,\n \"native_backup_export_restore_executed\": false,\n \"native_workload_changed\": false,\n \"actual_founder_approval\": false,\n \"local_read_only_capability_checks\": [\n \"argocdCLI absent, existingApplication.operation path retained\",\n \"Dockerunixsocket engineName bnt-lap001\"\n ],\n \"case_source_commit_at_preparation\": \"e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)\",\n \"additional_regressions\": [\n \"Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation\",\n \"rollback still refuses CM/PVC or nonpair-image drift\",\n \"separate old-image Ready/schema5 recovery proof\",\n \"post-admin readonly integrity refusal and original snapshot tamper refusal\"\n ]\n}\n" + } + }, + "native_execution": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md new file mode 100644 index 0000000..b3c8083 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/README.md @@ -0,0 +1,21 @@ +# Supervised Informed Decision purpose release executor — unapproved preparation + +No native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor. + +Run one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion. + +Invocation after actual approval: `python3 execution/actuator.py --phase --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase. + +The private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence. + +New private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required. + +Every phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions. + +Existing Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes. + +Sixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof. + +All phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance. + +The initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py new file mode 100644 index 0000000..c5cb78f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/actuator.py @@ -0,0 +1,353 @@ +"""One fixed supervised phase; never run this during source preparation.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +import selectors +import stat +import subprocess +import sys +import time + +if sys.flags.optimize: + raise SystemExit('optimized interpreter refused') + +PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline', + 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') + + +def require(value, reason): + if not value: + raise ValueError(reason) + + +def sha(path): + digest = hashlib.sha256() + with Path(path).open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + digest.update(block) + return digest.hexdigest() + + +def private(path, directory=False): + info = Path(path).lstat() + require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode)) + and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600) + and (directory or info.st_nlink == 1), 'private owned custody required') + +ROOT = Path(__file__).resolve().parent +CASE = ROOT.parent +OWNER = Path('/home/worsch/informed-decision') +CUSTODIAN = Path('/home/worsch/the-custodian') +CUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1' +SOCKET = 'unix:///var/run/docker.sock' +IMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a' +VOLUME = 'infd-purpose-r1-restore-20261011' +MAX_BYTES = 512 * 1024**2 + + +def run(argv, body=None, timeout=90): + return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout) + + +def json_result(result): + try: + value = json.loads(result.stdout) + except (ValueError, TypeError): + raise ValueError('safe phase receipt unavailable; outcome uncertain') from None + require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True, + 'phase did not verify complete; raw output withheld; no retry') + permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root', + 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly', + 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private', + 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts', + 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision', + 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained', + 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained', + 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256', + 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'} + require(set(value) <= permitted, 'unexpected output fields withheld') + from receipt_safety import counts + for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'): + if name in value: + counts(value[name]) + for name in ('snapshot_sha256', 'client_diff_sha256'): + if name in value: + require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld') + if 'snapshot_bytes' in value: + require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES, + 'invalid output size withheld') + if 'snapshot_file' in value: + require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld') + return value + + +def docker(argv, body=None, timeout=120): + return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv, + body=body, timeout=timeout) + + +def remote(phase, revision, approved): + # Fixed module imported only after main verifies every executor source hash. + from native_program import PROGRAM + payload = {'phase': phase, 'source_revision': revision, 'approval': approved, + 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()), + 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()), + 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()), + 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()), + 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(), + 'purpose_checks': (CASE / 'check_installed.py').read_text(), + 'readonly': (CASE / 'sqlite_readonly.py').read_text()} + script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace( + '__GUARD__', repr((CASE / 'change_guard.py').read_text())) + return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200)) + + +def copy_snapshot(phase, revision, approved, journal): + metadata = remote(phase, revision, approved) + backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup' + prior = journal.data['phases'][backup_phase]['result'] + for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'): + require(metadata[key] == prior[key], 'closed frozen snapshot changed') + name = metadata['snapshot_file'] + require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES, + 'fixed bounded snapshot required') + pod = metadata['pod_name'] + require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required') + local = CUSTODY / name + fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600) + # Binary snapshot stdout goes only to a private file, never tool/chat/log output. + # Snapshot schema/count metadata was validated before opening this destination. + with os.fdopen(fd, 'wb') as destination: + command = ('kubectl exec -n informed-decision ' + pod + + ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name) + transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL) + selector = selectors.DefaultSelector() + selector.register(transfer.stdout, selectors.EVENT_READ) + deadline = time.monotonic() + 150 + received = 0 + try: + while True: + remaining = deadline - time.monotonic() + require(remaining > 0 and selector.select(remaining), 'private transfer timed out') + block = os.read(transfer.stdout.fileno(), 1024**2) + if not block: + break + received += len(block) + require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES, + 'private copy exceeds frozen snapshot size') + destination.write(block) + transfer.wait(timeout=max(1, deadline - time.monotonic())) + finally: + selector.close() + transfer.stdout.close() + if transfer.poll() is None: + transfer.kill() + transfer.wait() + destination.flush() + os.fsync(destination.fileno()) + private(local) + require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes'] + and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry') + # Re-read identity/hash after transfer. This is verification, not a write retry. + after = remote(phase, revision, approved) + require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'], + 'source identity/snapshot changed during transfer') + return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False} + + +def offline_verify(journal): + from receipt_safety import counts + snapshot = CUSTODY / 'drill.sqlite' + private(snapshot) + previous = journal.data['phases']['drill-copy']['result'] + require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed') + identity = docker(['info', '--format', '{{json .Name}}']) + require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001', + 'local offline Docker engine identity changed') + listed = docker(['volume', 'ls', '--format', '{{.Name}}']) + require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(), + 'disposable volume absence not verified') + nonce = journal.data['phases']['offline-verify']['attempt_id'] + labels = {'informed-decision.case': 'infd-purpose-20261011-r1', + 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce} + created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1', + '--label', 'informed-decision.attempt=' + nonce, + '--label', 'informed-decision.use=offline-restore-only', VOLUME]) + require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry') + inspected = docker(['volume', 'inspect', VOLUME]) + require(inspected.returncode == 0, 'new volume identity unavailable') + volume = json.loads(inspected.stdout) + require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels + and volume[0].get('Driver') == 'local' and not volume[0].get('Options') + and volume[0].get('Scope') == 'local', 'new isolated volume identity changed') + identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')} + journal.note('offline-verify', 'created_volume_identity', identity) + # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume. + # No host/live PVC/config/token mount exists; this detail needs packet review. + initializer = """import hashlib,os,stat,sys +if sys.flags.optimize:raise RuntimeError('optimized interpreter refused') +folder='/restore';expected=EXPECTED +if os.listdir(folder):raise ValueError('new empty private volume required') +os.chmod(folder,0o700) +fd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600) +digest=hashlib.sha256();size=0 +with os.fdopen(fd,'wb') as target: + while True: + block=sys.stdin.buffer.read(1024**2) + if not block:break + size+=len(block) + if size>512*1024**2:raise ValueError('private restore size exceeds bound') + target.write(block);digest.update(block) + target.flush();os.fsync(target.fileno()) +if digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs') +os.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001) +print('{"all_checks_pass":true,"private_copy_verified":true}') +""".replace('EXPECTED', repr(previous['snapshot_sha256'])) + with snapshot.open('rb') as source: + argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET, + 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m', + '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN', + '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore', + '--entrypoint', 'python', IMAGE, '-c', initializer] + copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150) + json_result(copied) + options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m', + '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges', + '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore'] + readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'], + (CASE / 'sqlite_readonly.py').read_text()) + require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store') + checked = counts(json.loads(readonly.stdout)) + require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ') + admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE, + 'inspect', '--db', '/restore/review.sqlite']) + require(admin.returncode == 0, 'offline admin result uncertain') + admin_counts = json.loads(admin.stdout) + require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')}, + 'offline admin changed frozen snapshot counters') + # Admin Store construction must not silently alter schema/integrity/counters. + post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'], + (CASE / 'sqlite_readonly.py').read_text()) + require(post.returncode == 0, 'offline post-admin readonly integrity gate refused') + post_checked = counts(json.loads(post.stdout)) + require(post_checked == checked == previous['snapshot_readonly'], + 'offline admin altered frozen snapshot proof') + private(snapshot) + require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill') + return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked, + 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True, + 'created_volume_identity': identity, + 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False, + 'service_entrypoint_started': False, 'original_snapshot_retained': True} + + +def cleanup_offline(journal): + inspected = docker(['volume', 'inspect', VOLUME]) + require(inspected.returncode == 0, 'owned disposable volume identity unverified') + value = json.loads(inspected.stdout) + expected = journal.data['phases']['offline-verify']['result']['created_volume_identity'] + require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected + and not value[0].get('Options'), 'volume ownership/recreation changed') + removed = docker(['volume', 'rm', VOLUME]) + require(removed.returncode == 0 and removed.stdout.strip() == VOLUME + and docker(['volume', 'inspect', VOLUME]).returncode != 0, + 'cleanup outcome ambiguous; do not retry') + return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME, + 'native_and_offcluster_original_snapshots_retained': True} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--phase', choices=PHASES, required=True) + parser.add_argument('--root-authority-receipt', type=Path, required=True) + parser.add_argument('--root-native-outcome', type=Path, required=True) + parser.add_argument('--source-revision', required=True) + args = parser.parse_args() + require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json') + and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'), + 'fixed supervised receipt paths required') + require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required') + # Verify all prepared executor/input bytes before reading authority or dispatching. + plan = json.loads((ROOT / 'execution-plan.json').read_text()) + require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'}, + 'fixed executor sources required') + require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json', + 'deploy/lifecycle/service.candidate.json', + 'deploy/lifecycle/kustomization.yaml', + 'deploy/lifecycle/registries.candidate.json'}, + 'fixed owner image sources required') + for relative, digest in plan['executor_files'].items(): + target = ROOT / relative + require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed') + for relative, digest in plan['case_files'].items(): + require(not Path(relative).is_absolute() and '..' not in Path(relative).parts, + 'case source path escaped') + target = CASE / relative + require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed') + for relative, digest in plan['owner_source_files'].items(): + target = OWNER / relative + require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed') + committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative], + capture_output=True) + require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest, + 'committed owner render source differs from approved inputs') + head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD']) + require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs') + from authority_journal import Journal, authority + private(args.root_authority_receipt) + private(args.root_native_outcome) + receipt = json.loads(args.root_authority_receipt.read_text()) + require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed') + require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'), + 'root verified executor plan differs') + approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'), + args.source_revision, args.phase) + parent = CUSTODY.parent + private(parent, directory=True) + ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')]) + require(ignored.returncode == 0, 'offcluster custody is not ignored') + if not CUSTODY.exists(): + require(args.phase == 'drill-backup', 'first approved phase must create unique private custody') + os.mkdir(CUSTODY, 0o700) + private(CUSTODY, directory=True) + capacity = os.statvfs(CUSTODY) + require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2, + 'independent protected custody headroom insufficient') + os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True) + private(CUSTODY / 'empty-docker-config', directory=True) + require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty') + journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision, + 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')}) + try: + journal.start(args.phase, approved) # fsynced RUNNING before any phase effect. + if args.phase in ('drill-copy', 'cutover-copy'): + result = copy_snapshot(args.phase, args.source_revision, approved, journal) + elif args.phase == 'offline-verify': + result = offline_verify(journal) + elif args.phase == 'cleanup-offline': + result = cleanup_offline(journal) + else: + result = remote(args.phase, args.source_revision, approved) + journal.finish(args.phase, result) + print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes. + except BaseException as error: + safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__, + 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry', + 'raw_output_withheld': True} + if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING': + journal.finish(args.phase, safe) + print(json.dumps(safe)) + raise SystemExit(1) from None + finally: + journal.close() + + +if __name__ == '__main__': + try: + main() + except Exception: + raise SystemExit('supervised execution refused before phase; raw output withheld') from None diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py new file mode 100644 index 0000000..00df0ec --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/authority_journal.py @@ -0,0 +1,147 @@ +"""Supervised receipt bookkeeping, not an authenticated approval provider.""" +import datetime +import fcntl +import hashlib +import json +import os +import re +from pathlib import Path +import stat +import uuid + +FOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'} +MEMO_ID = 'infd-20261011-purpose-overlay-r1' +PROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1' +PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline', + 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify') + + +def require(value, reason): + if not value: + raise ValueError(reason) + + +def sha(path): + digest = hashlib.sha256() + with Path(path).open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + digest.update(block) + return digest.hexdigest() + + +def private(path, directory=False): + info = Path(path).lstat() + require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode)) + and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600) + and (directory or info.st_nlink == 1), 'private owned custody required') + + +def authority(receipt, outcome, memo_sha, source_revision, phase, now=None): + """Root must freshly verify native outcome at fixed ORIGIN outside this helper. + + Receipt files/flags are not signed grants. This function checks the exact + supervised receipt relation; existing harness/founder authority remains the + actual permission boundary. It never authenticates a caller as human. + """ + now = now or datetime.datetime.now(datetime.timezone.utc) + require(phase in PHASES, 'fixed phase required') + require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID + and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha + and receipt.get('source_revision') == source_revision + and receipt.get('activation') == 'APPROVED' + and receipt.get('authority_mode') == 'ADMINISTER' + and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision' + and receipt.get('verification_method') == 'root-fixed-origin-native-readback' + and receipt.get('runtime_authenticated_grant') is False, + 'exact externally verified supervised receipt required') + verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00')) + require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120, + 'fresh root native readback required before every phase') + deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00') + require(now < deadline, 'approved execution window expired') + require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False + and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current') + review_id = outcome['review']['memo_id'] + require(review_id == receipt.get('review_memo_id'), 'native review identity changed') + accepted = [x for x in outcome.get('dispositions', []) + if x.get('submission_state') == 'confirmed' + and x.get('disposition', {}).get('verb') == 'accept' + and x['disposition'].get('memo_version') == 1] + require(len(accepted) == 1, 'one confirmed founder acceptance required') + accepted = accepted[0]['disposition'] + require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id + and accepted.get('approval_id') == receipt.get('approval_id') + and accepted.get('id') == receipt.get('disposition_id') + and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch') + require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None + and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None + and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None, + 'native disposition identifiers are malformed') + accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00')) + require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded') + return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')} + + +class Journal: + def __init__(self, parent, identity): + self.parent = Path(parent) + private(self.parent, directory=True) + self.path = self.parent / 'execution-journal.json' + self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600) + fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB) + private(self.parent / 'execution.lock') + if self.path.exists(): + private(self.path) + self.data = json.loads(self.path.read_text()) + require(self.data['identity'] == identity, 'journal case/source identity changed') + else: + self.data = {'identity': identity, 'phases': {}} + self.save() + + def save(self): + temporary = self.parent / 'execution-journal.new' + fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600) + try: + with os.fdopen(fd, 'w') as stream: + json.dump(self.data, stream, indent=2) + stream.write('\n') + stream.flush() + os.fsync(stream.fileno()) + os.replace(temporary, self.path) + directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY) + try: + os.fsync(directory) + finally: + os.close(directory) + except BaseException: + # Retain evidence rather than overwriting an uncertain durable intent. + raise + + def start(self, phase, approval): + require(phase not in self.data['phases'], 'already attempted phase; no retry') + predecessors = dict(zip(PHASES[1:8], PHASES[:7])) + predecessors['rollback-verify'] = 'rollback' + if phase in predecessors: + require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE', + 'preceding phase is not verified complete') + if phase == 'rollback': + require('release' in self.data['phases'], 'rollback requires a recorded release attempt') + self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval, + 'attempt_id': str(uuid.uuid4()), + 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()} + self.save() + + def note(self, phase, key, value): + require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing') + self.data['phases'][phase][key] = value + self.save() + + def finish(self, phase, result): + entry = self.data['phases'][phase] + require(entry['state'] == 'RUNNING', 'phase intent missing') + entry['result'] = result + entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN' + self.save() + + def close(self): + os.close(self.lock) diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json new file mode 100644 index 0000000..521898f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/execution-plan.json @@ -0,0 +1,51 @@ +{ + "kind": "informed-decision.supervised-mechanical-release-plan", + "version": 1, + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "trial_id": "infd-purpose-20261011-r1", + "state": "prepared-unapproved", + "executor_files": { + "actuator.py": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5", + "authority_journal.py": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa", + "native_program.py": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde", + "receipt_safety.py": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + "case_files": { + "change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "preflight-inputs.json": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", + "published-verification.json": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "security-summary.json": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + "owner_source_files": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "source_revision": "must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs", + "phases": [ + "drill-backup", + "drill-copy", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "authorization": "fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant", + "execute_by": "2026-10-12T23:59:59Z", + "raw_output_withheld": true, + "native_data_or_workload_action_executed": false, + "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window." +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py new file mode 100644 index 0000000..f46d24c --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/native_program.py @@ -0,0 +1,2 @@ +"""Fixed remote source, passed only after exact supervised approval.""" +PROGRAM = '\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\nif sys.flags.optimize:raise RuntimeError(\'optimized interpreter refused\')\npayload=json.loads(__PAYLOAD__)\nexec(__GUARD__)\nphase=payload[\'phase\']\nif phase not in (\'drill-backup\',\'cutover-backup\',\'drill-copy\',\'cutover-copy\',\'release\',\'verify\',\'rollback\',\'rollback-verify\'):raise ValueError(\'fixed native phase required\')\ndeadline=datetime.datetime.fromisoformat(\'2026-10-12T23:59:59+00:00\')\ndef require(value,reason):\n if not value:raise ValueError(reason)\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\'drill-backup\' else 1)+16*1024**2,\'bounded native snapshot capacity required\')\n if action==\'drill-backup\':\n require(not os.path.lexists(folder),\'native case directory must be unique\')\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\n private(folder,True)\n filename=\'drill.sqlite\' if action==\'drill-backup\' else \'cutover.sqlite\';output=folder+\'/\'+filename\n require(not os.path.lexists(output),\'snapshot output must be unique\')\n admin=subprocess.run([\'informed-decision-admin\',\'backup\',\'--db\',db,\'--output\',output],capture_output=True,text=True,timeout=120)\n require(admin.returncode==0 and json.loads(admin.stdout)=={\'status\':\'backed_up\',\'consistent_snapshot\':True},\'backup completion not verified; do not retry\')\n private(output)\n for suffix in (\'-wal\',\'-shm\'):\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\'snapshot is not closed main-file custody\')\n snapshot=counts(inspect_readonly(output))\n size=os.stat(output).st_size;require(0 10**12 + for number in value[group].values()): + raise ValueError('count-only receipt values refused') + return value diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json new file mode 100644 index 0000000..3f22cb3 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/root-authority-receipt-template.json @@ -0,0 +1,19 @@ +{ + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "memo_id": "infd-20261011-purpose-overlay-r1", + "memo_version": 1, + "memo_sha256": null, + "source_revision": null, + "activation": "PENDING", + "authority_mode": "ADMINISTER", + "target": "realm:kubernetes/railiance01/informed-decision", + "verification_method": "root-fixed-origin-native-readback", + "runtime_authenticated_grant": false, + "verified_at": null, + "accepted_at": null, + "review_memo_id": null, + "approval_id": null, + "disposition_id": null, + "native_outcome_sha256": null, + "executor_plan_sha256": "4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py new file mode 100644 index 0000000..965cceb --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/test_execution.py @@ -0,0 +1,367 @@ +"""Synthetic custody/transport tests. No native data, Docker or cluster action.""" +import copy +import datetime +import io +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest +from unittest.mock import patch +from contextlib import redirect_stdout + +import actuator +from authority_journal import Journal, authority +from native_program import PROGRAM +from receipt_safety import counts + +CASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release') +NOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc) +REVISION = 'e' * 40 +COUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False, + 'lifecycle': {'records': 3, 'events': 8, 'pending': 1}, + 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}} + + +def accepted(): + approval = '11111111-1111-4111-8111-111111111111' + review = 'review-22222222-2222-4222-8222-222222222222' + disposition = 'disp-33333333-3333-4333-8333-333333333333' + receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1', + 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1, + 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED', + 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision', + 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False, + 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z', + 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition} + outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'}, + 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed', + 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review, + 'approval_id': approval, 'id': disposition, + 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}, + 'at': receipt['accepted_at']}}]} + return receipt, outcome + + +class AuthorityAndCustody(unittest.TestCase): + def test_exact_nested_founder_receipt_not_top_level_approval(self): + receipt, outcome = accepted() + result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW) + self.assertEqual(result['approval_id'], receipt['approval_id']) + + def test_pending_stale_wrong_actor_version_and_binding_refuse(self): + mutations = [lambda r, o: r.update(activation='PENDING'), + lambda r, o: r.update(memo_sha256='changed'), + lambda r, o: r.update(source_revision='changed'), + lambda r, o: r.update(target='other'), + lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'), + lambda r, o: r.update(verification_method='caller-asserted'), + lambda r, o: r.update(runtime_authenticated_grant=True), + lambda r, o: o['review'].update(stale=True), + lambda r, o: o['review'].update(intake_state='pending'), + lambda r, o: o['dispositions'][0].update(submission_state='unresolved'), + lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2), + lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}), + lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))] + for mutate in mutations: + with self.subTest(mutate=mutate): + r, o = accepted() + mutate(r, o) + with self.assertRaises(ValueError): + authority(r, o, 'a' * 64, REVISION, 'release', NOW) + + def test_expired_window_and_unknown_phase_refuse(self): + r, o = accepted() + with self.assertRaises(ValueError): + authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW) + late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc) + r['verified_at'] = late.isoformat() + with self.assertRaises(ValueError): + authority(r, o, 'a' * 64, REVISION, 'rollback', late) + + def test_durable_intent_precedes_dispatch_and_never_retries(self): + with tempfile.TemporaryDirectory() as directory: + parent = Path(directory) + os.chmod(parent, 0o700) + journal = Journal(parent, {'case': 'fixture'}) + journal.start('drill-backup', {'approval_id': 'fixture'}) + self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING') + journal.close() # simulated crash before result + recovered = Journal(parent, {'case': 'fixture'}) + with self.assertRaises(ValueError): + recovered.start('drill-backup', {}) + with self.assertRaises(ValueError): + recovered.start('drill-copy', {}) + recovered.close() + + def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self): + with tempfile.TemporaryDirectory() as directory: + os.chmod(directory, 0o700) + j = Journal(directory, {'case': 'fixture'}) + with self.assertRaises(ValueError): + j.start('release', {}) + for phase in actuator.PHASES[:6]: + j.start(phase, {}) + j.finish(phase, {'all_checks_pass': True}) + j.start('release', {}) + j.finish('release', {'all_checks_pass': False}) + with self.assertRaises(ValueError): + j.start('release', {}) + with self.assertRaises(ValueError): + j.start('verify', {}) + j.start('rollback', {}) + j.finish('rollback', {'all_checks_pass': True}) + j.close() + + def test_secret_or_unknown_child_output_is_withheld(self): + for body in ('not-json', '{"all_checks_pass":true,"token":"private-value"}', + '{"all_checks_pass":true,"snapshot_readonly":{"schema_version":5}}'): + with self.assertRaises(ValueError): + actuator.json_result(subprocess.CompletedProcess([], 0, body, '')) + wrong = copy.deepcopy(COUNT) + wrong['outbox'] = {'private-row-value': 1} + with self.assertRaises(ValueError): + counts(wrong) + counts(COUNT) # blocked/unresolved counts are not required to be zero. + + def test_binary_copy_is_bounded_private_and_never_echoed(self): + blob = b'synthetic private fixture bytes' + digest = __import__('hashlib').sha256(blob).hexdigest() + metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob), + 'snapshot_sha256': digest, 'snapshot_readonly': COUNT, + 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'} + journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})() + real_popen = subprocess.Popen + for extra in (b'', b'oversized'): + with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder: + os.chmod(folder, 0o700) + output = io.StringIO() + + def child(*args, **kwargs): + return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'], + stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + + with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \ + patch('subprocess.Popen', side_effect=child), redirect_stdout(output): + if extra: + with self.assertRaises(ValueError): + actuator.copy_snapshot('drill-copy', REVISION, {}, journal) + else: + result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal) + self.assertTrue(result['off_cluster_private_copy_verified']) + self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob) + self.assertEqual(output.getvalue(), '') + self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600) + + def test_recreated_offline_volume_cannot_be_deleted(self): + identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'} + journal = type('FixtureJournal', (), {'data': {'phases': { + 'offline-verify': {'result': {'created_volume_identity': identity}}}}})() + inspected = [{**identity, 'CreatedAt': 'recreated'}] + with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked: + with self.assertRaises(ValueError): + actuator.cleanup_offline(journal) + self.assertEqual(mocked.call_count, 1) + + def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self): + for defect in ('none', 'post-integrity', 'original-hash'): + with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory: + folder=Path(directory);os.chmod(folder,0o700) + snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600) + digest=actuator.sha(snapshot) + prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT} + journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})() + reads=[] + volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None} + def docker(argv, body=None, **kwargs): + if argv[0]=='info':body=json.dumps('bnt-lap001') + elif argv[:2]==['volume','ls']:body='' + elif argv[:2]==['volume','create']:body=actuator.VOLUME + elif argv[:2]==['volume','inspect']:body=json.dumps([volume]) + elif 'informed-decision-admin' in argv: + body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')}) + if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original') + elif '--entrypoint' in argv and 'python' in argv: + reads.append(argv);proof=copy.deepcopy(COUNT) + if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt' + body=json.dumps(proof) + else:raise AssertionError('unexpected offline command') + return subprocess.CompletedProcess(argv,0,body,'') + with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{"all_checks_pass":true,"private_copy_verified":true}','')): + if defect=='none': + result=actuator.offline_verify(journal) + self.assertEqual(result['offline_post_admin_readonly'],COUNT) + self.assertTrue(result['original_snapshot_hash_unchanged']) + else: + with self.assertRaises(ValueError):actuator.offline_verify(journal) + self.assertEqual(len(reads),2) + + +class FixedNativeProgram(unittest.TestCase): + def fixture(self): + sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text()) + live = copy.deepcopy(sealed) + live['metadata'].update(generation=42) + live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42} + dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text()) + cm = copy.deepcopy(dependencies['configmap']) + cm.pop('canonical_data_sha256') + service = json.loads((CASE / 'candidate-deployment.json').read_text()) + source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text()) + cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data'] + pvc = copy.deepcopy(dependencies['pvc']) + pvc['status'] = {'phase': 'Bound'} + app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'}, + 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git', + 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'}, + 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}} + objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app} + payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed, + 'dependencies': dependencies, 'candidate': service, + 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()), + 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(), + 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()} + return objects, payload + + def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False): + writes = [] + calls = [] + + def fake(argv, input=None, **kwargs): + calls.append(argv) + if argv[:2] == ['kubectl', 'get']: + kind = argv[2] + if kind in objects: + body = objects[kind] + elif kind == 'pods': + body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid', + 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]}, + 'spec': objects['deployment']['spec']['template']['spec'], + 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]} + elif kind == 'replicaset': + body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [ + {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}} + elif kind == 'nodes': + body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': { + 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'}, + 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'} + for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]} + else: + raise AssertionError('unexpected fixed metadata route') + return subprocess.CompletedProcess(argv, 0, json.dumps(body), '') + if argv[:2] == ['kubectl', 'exec']: + if schema_refused: + return subprocess.CompletedProcess(argv, 1, '', 'withheld') + return subprocess.CompletedProcess(argv, 0, json.dumps({ + 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '') + if argv[:2] == ['kubectl', 'apply']: + admitted = copy.deepcopy(payload['sealed']) + admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image']) + return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '') + if argv[:2] == ['kubectl', 'describe']: + return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\n cpu 3460m (86%)\n', '') + if argv[:2] == ['kubectl', 'diff']: + return subprocess.CompletedProcess(argv, 1, '-image: base\n+image: candidate\n', '') + if argv[:2] == ['kubectl', 'patch']: + if '--dry-run=server' not in argv: + writes.append(json.loads(input)) + if ambiguous: + return subprocess.CompletedProcess(argv, 1, '', 'withheld') + return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\n', '') + raise AssertionError('unexpected command') + + source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace( + '__GUARD__', repr((CASE / 'change_guard.py').read_text())) + output = io.StringIO() + with patch('subprocess.run', side_effect=fake), redirect_stdout(output): + try: + exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'}) + except (ValueError, SystemExit): + pass + receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False} + return receipt, writes, calls + + def test_only_existing_application_operation_and_deployment_are_requested(self): + objects, payload = self.fixture() + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertTrue(receipt['all_checks_pass']) + self.assertFalse(receipt['rollout_verified']) + self.assertEqual(len(writes), 1) + operation = writes[0][-1]['value'] + self.assertFalse(operation['sync']['prune']) + self.assertEqual(operation['sync']['resources'], [ + {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}]) + self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls)) + self.assertEqual(writes[0][0]['path'], '/metadata/uid') + + def test_source_overrides_automation_and_custody_drift_stop_before_write(self): + mutations = [lambda o: o['application']['metadata'].update(uid='recreated'), + lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}), + lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}), + lambda o: o['application']['spec'].update(sources=[{}]), + lambda o: o['configmap']['metadata'].update(uid='recreated'), + lambda o: o['pvc']['spec'].update(volumeName='replaced'), + lambda o: o['deployment']['status'].update(readyReplicas=0)] + for mutate in mutations: + with self.subTest(mutate=mutate): + objects, payload = self.fixture() + mutate(objects) + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertFalse(receipt['all_checks_pass']) + self.assertEqual(writes, []) + + def test_preopen_schema_refusal_prevents_image_operation(self): + objects, payload = self.fixture() + receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True) + self.assertFalse(receipt['all_checks_pass']) + self.assertEqual(writes, []) + + + def test_rollback_unready_candidate_never_reads_pod_or_database(self): + objects, payload = self.fixture() + payload['phase'] = 'rollback' + objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0) + objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE + objects['application']['spec']['source']['targetRevision'] = REVISION + receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True) + self.assertTrue(receipt['all_checks_pass']) + self.assertFalse(receipt['rollout_verified']) + self.assertEqual(len(writes), 1) + self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls)) + self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf') + + def test_rollback_still_refuses_custody_or_nonpair_image_drift(self): + for defect in ('cm', 'pvc', 'image'): + with self.subTest(defect=defect): + objects, payload = self.fixture();payload['phase'] = 'rollback' + objects['deployment']['status']['readyReplicas'] = 0 + if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated' + elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced' + else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image' + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, []) + + def test_recovery_verification_is_separate_ready_old_image_schema_proof(self): + objects, payload = self.fixture();payload['phase'] = 'rollback-verify' + objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': { + 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False, + 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}} + receipt, writes, calls = self.execute_fake(objects, payload) + self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification']) + self.assertEqual(writes, []) + self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls)) + objects['deployment']['status']['readyReplicas'] = 0 + receipt, writes, calls = self.execute_fake(objects,payload) + self.assertFalse(receipt['all_checks_pass']) + + def test_ambiguous_patch_is_never_retried(self): + objects, payload = self.fixture() + receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True) + self.assertFalse(receipt['all_checks_pass']) + self.assertEqual(len(writes), 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json new file mode 100644 index 0000000..321f6fa --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/execution/validation.json @@ -0,0 +1,20 @@ +{ + "tests": 16, + "result": "passed", + "synthetic_transport_only": true, + "real_native_data_read": false, + "native_backup_export_restore_executed": false, + "native_workload_changed": false, + "actual_founder_approval": false, + "local_read_only_capability_checks": [ + "argocdCLI absent, existingApplication.operation path retained", + "Dockerunixsocket engineName bnt-lap001" + ], + "case_source_commit_at_preparation": "e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)", + "additional_regressions": [ + "Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation", + "rollback still refuses CM/PVC or nonpair-image drift", + "separate old-image Ready/schema5 recovery proof", + "post-admin readonly integrity refusal and original snapshot tamper refusal" + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json new file mode 100644 index 0000000..1fc30be --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/fresh-preflight-validation.json @@ -0,0 +1,50 @@ +{ + "node_allocatable_cpu_m": 4000, + "node_requested_cpu_m": 3460, + "captured_at": "2026-10-11T01:39:14.234277+00:00", + "native_workload_changed": false, + "native_backup_restore_executed": false, + "argo": { + "uid": "499868f2-eabc-4df4-ae31-b89ce58d750d", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "path": "deploy/lifecycle", + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "automated": false, + "sync": { + "comparedTo": { + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "source": { + "path": "deploy/lifecycle", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf" + } + }, + "revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "status": "OutOfSync" + }, + "health": { + "lastTransitionTime": "2026-10-10T23:14:52Z", + "status": "Healthy" + } + }, + "native_dependencies_checked": true, + "configmap_uid": "90113d2d-54d9-4e82-b1d3-90b49ebed2b5", + "pvc_uid": "d80b25b1-141a-441b-b205-98fa2fd98b7c", + "live_ready_replicas": 1, + "admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92", + "server_dry_run_passed": true, + "admitted_spec_exactly_live_plus_image": true, + "client_diff_exit": 1, + "client_diff_sha256": "840769c7d2a9c1655c40a3259f833d1fc8f69950ceb3bedb707a955fed711566", + "node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)", + "all_checks_pass": true, + "sealed_preflight_inputs_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "fresh_execution_receipt": true +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json new file mode 100644 index 0000000..f0fa85b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/inherited-vulnerability-follow-through.json @@ -0,0 +1,21 @@ +{ + "id": "INFD-RISK-20261011-ZLIB-85091", + "kind": "owner-vulnerability-follow-through", + "owner": "informed-decision", + "task": "INFD-WP-0009-T05", + "status": "open", + "created": "2026-10-11", + "review_due": "2026-10-18", + "finding": "CVE-2026-85091", + "scanner_severity": "MEDIUM", + "estate_risk_grade": null, + "affected_package": "zlib", + "installed": "1.3.2-r0", + "fixed": "1.3.2-r1", + "actual_current_base_and_candidate_findings_identical": true, + "source_evidence": "security-summary.json, trivy-full.json, base-trivy-full.json", + "human_temporary_disposition": "pending", + "follow_through": "Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload", + "manual_review_expiry": "Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed", + "close_condition": "Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json new file mode 100644 index 0000000..243335c --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/intake.json @@ -0,0 +1,261 @@ +{ + "kind": "informed-decision.memo-intake", + "version": 1, + "idempotency_key": "infd-20261011-purpose-overlay-r1-v1", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "drafted_by": "custodian-codex", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + }, + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 1, + "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "packet": [ + { + "item_id": "decision-packet-md", + "media_type": "text/markdown", + "content": "# Informed Decision purpose overlay release\n\n## Requested decision\n\nApprove the exact purpose-only image rollout and protected real-data backup/restore protocol for the existing Informed Decision service on railiance01. This request is separate from the already approved config-only repair. Only the existing Deployment image changes through the owner's manual Argo workflow, with prune disabled. Runtime ConfigMap `informed-decision-runtime-6c221878d051`, schema5, PVC, credentials, audience, policies, registries, access, replica1 and Recreate strategy remain fixed. Execute by 2026-10-12T23:59:59Z, after refreshed sealed-source/UID/configuration checks and backup/restore gates. All phases, including recovery and verification, must begin before this deadline. If the window is exhausted, stop and obtain a fresh founder decision; this may delay recovery. No timer/controller automatically changes the released image.\n\n## Artifact and known finding\n\nActual owner CI task11484/run3 published immutable image `sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a` from source `3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168`. Anonymous registry verification preserves all eight base compressed blobs/rootfs layers and adds only policy.py with exact source hash and mode0644. Legacy-builder media-type/default config serialization differences are recorded; the runtime semantics remain unchanged. Pulled published image executes as UID10001/GID10001 and passes ten installed checks: two supported binding forms, eight advisory/malformed refusals. Tests use synthetic transport and do not claim new native PDP authorization proof. The two failed CI attempts remain in the same trial history.\n\nActual unfiltered pinned scanner/DB evidence covers44packages: zero HIGH/CRITICAL, **one fixable MEDIUM**, CVE-2026-85091, zlib1.3.2-r0 fixed in1.3.2-r1. Actual current-base scan has the identical finding. Approving this packet explicitly permits this inherited finding during this narrow purpose release; it is not a RiskNexus estate risk grade or zero-CVE claim. Owner record INFD-RISK-20261011-ZLIB-85091 and live task INFD-WP-0009-T05 require separate base refresh and native approval, reviewed by2026-10-18. That review date is manual follow-through, with no auto-controller claim. Scanner notes Alpine3.24 absent EOL list; OS vulnerability detection ran against38OSpackages. Unknown vulnerabilities remain outside snapshot knowledge.\n\n## Native baseline and gates\n\nOriginal read-only capture01:25:38Z: existing Deployment UIDa588e10a, Ready1, image7f5c, unchanged runtime6c; native admission preserves the full configuration plus exactly the proposed image. Clientdiff returns1. Requests3460/4000mCPU86%, memory9472Mi59%; refresh before release. Existing Argo Application UID499868f2 is manual, target7db8485, Healthy with pre-existing OutOfSync status. Do not treat a scoped Deployment release as full-app reconciliation. Preserve its tracking-id; no unrelated resource sync/prune/adoption.\n\nThe refined read-only helper binds original source/helper/render/baseline hashes and actual immutable ConfigMap/PVC UIDs, runtime-data checksum and bound volume identity, explicitly refuses optimized interpreters, checks exact fresh live UID/configuration and admission, and writes a separate execution receipt outside this sealed packet. Failed initial raw Kustomize metadata check is retained: direct kubectl apply would drop Argo tracking-id. The reviewed selected Deployment explicitly retains that existing ID, matching Argo ownership. Any unrelated drift, different UID, altered admission, unavailable protected backup capacity, uncertain backup, restore mismatch or unhealthy baseline stops the release.\n\n## Protected backup and release\n\nBefore **any** native source or offline-restored Store/admin open, use the attached stdlib SQLite mode=ro/query_only checker to require schema5, integrity=ok and count-only baseline. The admin automatically migrates oldschemas, so a post-open report alone cannot prove no migration. Refuse other schemas before admin. Then use the existing owner admin's SQLite backup API, not a raw copy of the live database/WAL. Protect directories0700/files0600, owned by10001. Retain independently protected off-cluster snapshot custody and only count/hash receipts. No database contents, caller tokens, requester Secret or runtime credential files enter Git, State Hub, logs or this packet. Native backup and offline real-data restore have not yet occurred. Use an isolated private disposable copy, networknone and no runtime config/token mounts, run the pre-open checker and exact offline `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite` after it passes, comparing frozen snapshot counts without service startup, then clean only the disposable restored copy. Retain the original snapshot. The attached protocol binds case-specific paths and fail-closed capacity/custody checks.\n\nRefresh a consistent online snapshot immediately before image-only cutover. This protocol does not assert traffic/dispatcher quiescence. Current and candidate share schema5 and unchanged store code; rollback retains the latest live database and all new/uncertain evidence. Stop the old writer before the new one with existing Recreate and single-writer lock. Do not restore an older snapshot over later writes, discard unresolved external effects, scale other workloads, change policies/identity/custody, or create human dispositions to make checks green.\n\nPin the existing Application to the exact owner commit containing the approved candidate source hashes, and manually sync only Deployment/informed-decision with prune=false. Verify actualimage/module/mode/UID, health/readiness and installed purpose refusals on the real placement; explicitly distinguish synthetic-transport checks from actual provider evidence. Existing native binding/lifecycle behavior must remain available. If unhealthy or verification fails, return Application source to7db8485 and scoped-sync prior same-schema image7f5c, preserving current evidence database; retain failed outcomes. Any data recovery beyond this same-schema image rollback is a separate founder decision.\n\n## Alternatives and estimates\n\nProceed with this narrow release plus explicit inherited-medium follow-through, or defer and prepare a separate base/dependency refresh before any release. No additional recurring hosting is proposed: estimated incremental infrastructure EUR0, with private storage and attended engineering/recovery time unpriced. Risks include a brief Recreate interruption, private backup custody errors, caller refusal when advisory responses were improperly treated as binding, and the disclosed inherited finding. This decision does not promote agent autonomy or grant unrelated work.\n\n## Independent review refinements\n\nThe initial36path/20document packet at manifest7c6738b3 and submissionac41c8ae is preserved in source preparation evidence, with the failed/conditional review. Independent Platform review identified admin auto-migration, optimization bypass, and actual same-name ConfigMap/PVC replacement gaps. The amended packet adds pre-open stdlib read-only schema/integrity/count gates, explicit local/remote optimization refusal, and independently sealed actual native config/PVC custody checks. These are refinements in the same proposal/trial, with no original or amended founder approval claimed.\n\n## Mechanically bound helper and recovery refinement\n\nThe directly attached execution-bundle.json binds exact supervised helper sources, plan, tests and PENDING authority template. It verifies all four committed owner Kustomize inputs and rejects present automated:{} as well as source overrides. Root must freshly authenticate the exact founder native disposition before every phase; receipt bookkeeping is not an autonomous signed grant. The same proposal/trial preserves the earlier36path7c packet, amended78pathb1 packet and original11file653 helper plus conditional review findings.\n\nThe offline copy uses one UID0/CAP_CHOWN-only initializer confined to the NEW nonce-bound local volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/livePVC/config/token mounts. All following pre-open/admin/post-open checks are UID10001. Post-admin readonly schema5/integrity/counts must match the frozen snapshot and original snapshot SHA must remain unchanged. Rollback dispatch never requires the failing candidate to be Ready or opens its database; seals/source/image pair/admission CAS still gate it. A separate rollback-verify proves recovered old-image Ready1/scoped operation/schema5 retained-current-DB integrity. Same-phase retries are refused after ambiguous outcomes.\n\nRaw scan/SBOM/base-scan bytes remain retained unchanged, hash-bound by the directly attached published-verification receipt; the bundle replaces only the direct raw scan attachment to stay within twenty documents. Known fixable inherited MEDIUM and T05 follow-through remain visible. Ten installed synthetic checks, including those later on actual placement, explicitly have native_provider=false. Actual provider/PDP authority evidence is a distinct T04 completion gate and is not supplied by these checks. Source preparation basis e0359bcb6cdfad9ab3e868054121fe0cebec2d68 plus9268c9ac0bbee508fe35c0b90dcefef4c24da2f5 is recorded; the final applied owner commit must be pinned before execution.\n" + }, + { + "item_id": "proposal-json", + "media_type": "application/json", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"authority\": \"ADMINISTER; activation APPROVED only upon exact founder disposition\",\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"published_source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"prior_argo_revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"native_object\": {\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"namespace\": \"informed-decision\",\n \"name\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"argo_application_uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"source_gate\": \"All four exact committed owner Kustomize input blobs in execution-plan.json and clean current owner HEAD must match; source preparation is not native approval\",\n \"sync_scope\": [\n \"apps:Deployment:informed-decision\"\n ],\n \"prune\": false,\n \"automated_sync\": false,\n \"runtime_configmap\": \"informed-decision-runtime-6c221878d051\",\n \"schema\": 5,\n \"requested_operations\": [\n \"Protected SQLite-consistent native backup and independently protected off-cluster custody\",\n \"Offline restore/integrity/count comparison on a private disposable volume with exact candidate, no runtime tokens/config/network\",\n \"Refresh a consistent pre-cutover snapshot, retain private copies and count-only/hash receipts\",\n \"Pin existing manual Argo Application to exact approved owner source and manually sync only existing Deployment image\",\n \"Verify health/readiness/image/module/installed fail-closed purpose checks and retained schema/count evidence; recover to prior same-schema image if needed\"\n ],\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"temporary_vulnerability_review_due\": \"2026-10-18\",\n \"known_scan_findings\": \"0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical\",\n \"vulnerability_record\": \"INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05\",\n \"cost_estimate_EUR\": 0,\n \"cost_limits\": \"No new recurring infrastructure; private backup storage and attended engineering/recovery time unpriced, not an autopilot cost grant\",\n \"risk_estimates\": [\n \"Brief Recreate service interruption; no concurrent new writer/surge\",\n \"Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence\",\n \"Candidate purpose refusal may expose callers relying on advisory results as binding\",\n \"Inherited known fixable MEDIUM remains until separately approved owner remediation\",\n \"Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted\",\n \"All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller.\"\n ],\n \"rollback\": \"Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes\",\n \"native_executed\": false,\n \"human_approval\": false,\n \"refinement_of_manifest\": \"7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300\",\n \"mandatory_pre_open_gate\": \"stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration\",\n \"optimized_interpreters\": \"local+remote explicitlyrefused beforeassert gates\",\n \"native_dependency_gate\": \"sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads\",\n \"live_counts\": \"Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained\",\n \"source_basis\": {\n \"reviewed_protocol_commit\": \"e0359bcb6cdfad9ab3e868054121fe0cebec2d68\",\n \"owner_followthrough_commit\": \"9268c9ac0bbee508fe35c0b90dcefef4c24da2f5\",\n \"final_execution_source\": \"exact subsequent root-applied source commit must be bound by founder receipt and verified against four approved Git blobs\"\n },\n \"approved_owner_render_blob_sha256\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"execution_bundle_sha256\": \"27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d\",\n \"execution_helper_manifest_sha256\": \"f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c\",\n \"execution_plan_sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\",\n \"execution_phases\": [\n \"drill-backup\",\n \"drill-copy\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\",\n \"offline_initializer\": \"One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.\",\n \"rollback_dispatch\": \"Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.\",\n \"purpose_proof_limit\": \"Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.\",\n \"refinement_of_amended_manifest\": \"b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033\"\n}\n" + }, + { + "item_id": "candidate-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "rollback-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "candidate-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "rollback-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "published-verification-json", + "media_type": "application/json", + "content": "{\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"observed_at\": \"2026-10-11T01:24:01.985128+00:00\",\n \"native_owner_publication_job\": {\n \"id\": 11484,\n \"name\": \"publish-candidate\",\n \"head_branch\": \"main\",\n \"head_sha\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"run_number\": 3,\n \"event\": \"push\",\n \"display_title\": \"Prepare readable overlay context with the admitted legacy builder\",\n \"status\": \"success\",\n \"workflow_id\": \"purpose-overlay-image.yaml\",\n \"url\": \"https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3\",\n \"created_at\": \"2026-10-11T01:20:59Z\",\n \"updated_at\": \"2026-10-11T01:21:08Z\",\n \"run_started_at\": \"2026-10-11T01:20:59Z\"\n },\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"registry_proof_sha256\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"source_render_change_only\": \"Deployment/informed-decision spec.template.spec.containers[0].image\",\n \"runtime_configmap_unchanged\": \"informed-decision-runtime-6c221878d051\",\n \"installed_image_execution\": {\n \"immutable_registry_artifact_pulled_anonymously\": true,\n \"UID\": 10001,\n \"GID\": 10001,\n \"policy_file_UID\": 0,\n \"policy_file_mode\": \"0644\",\n \"purpose_variants\": 10,\n \"binding_forms_allowed\": 2,\n \"advisory_or_malformed_refused\": 8,\n \"network\": \"none\",\n \"read_only\": true,\n \"synthetic_transport\": true,\n \"native_PDP_test\": false\n },\n \"scan_summary_sha256\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\",\n \"historical_failed_runs_retained\": [\n \"f66de505/task11482/run1\",\n \"acecad887/task11483/run2\"\n ],\n \"native_hosting_changed\": false,\n \"native_backup_restore_executed\": false,\n \"human_approval\": false,\n \"evidence_file_sha256\": {\n \"image-manifest.json\": \"978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb\",\n \"image-config.json\": \"4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10\",\n \"base-image-config.json\": \"b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00\",\n \"registry-proof.json\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"trivy-full.json\": \"f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e\",\n \"sbom.cdx.json\": \"a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d\",\n \"base-trivy-full.json\": \"d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"verify_registry.py\": \"413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4\",\n \"sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"review-refinement.json\": \"ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75\",\n \"test_change_guard.py\": \"da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f\",\n \"test_sqlite_readonly.py\": \"c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323\",\n \"test_preflight_optimization.py\": \"a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d\"\n }\n}\n" + }, + { + "item_id": "registry-proof-json", + "media_type": "application/json", + "content": "{\n \"image_digest\": \"sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"base_image_digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"base_layer_bytes_identical\": true,\n \"layer_media_type_conversion\": \"OCI gzip to Docker gzip, same digest and size\",\n \"base_runtime_config_semantics_identical\": true,\n \"legacy_builder_config_additions\": {\n \"Hostname\": \"\",\n \"Domainname\": \"\",\n \"AttachStdin\": false,\n \"AttachStdout\": false,\n \"AttachStderr\": false,\n \"Tty\": false,\n \"OpenStdin\": false,\n \"StdinOnce\": false,\n \"Cmd\": null,\n \"Volumes\": null,\n \"OnBuild\": null,\n \"Image\": \"sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883\"\n },\n \"base_rootfs_prefix_identical\": true,\n \"overlay_regular_files\": [\n \"opt/venv/lib/python3.12/site-packages/informed_decision/policy.py\"\n ],\n \"overlay_directories\": [\n \"opt\",\n \"opt/venv\",\n \"opt/venv/lib\",\n \"opt/venv/lib/python3.12\",\n \"opt/venv/lib/python3.12/site-packages\",\n \"opt/venv/lib/python3.12/site-packages/informed_decision\"\n ],\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"policy_mode\": \"0644\",\n \"base_user\": \"10001:10001\",\n \"source_scope_labels\": {\n \"org.opencontainers.image.revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"org.opencontainers.image.base.digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"social.coulomb.source.policy.sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"social.coulomb.release.scope\": \"INFD-WP-0009-T04/purpose-overlay-v1\"\n },\n \"registry_read_route\": \"anonymous public scoped bearer challenge, no token retention\",\n \"image_executed\": false,\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false\n}\n" + }, + { + "item_id": "security-summary-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"scanner\": \"aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969\",\n \"version\": \"0.74.0\",\n \"db_metadata\": {\n \"Version\": 2,\n \"NextUpdate\": \"2026-10-11T18:59:50.889010572Z\",\n \"UpdatedAt\": \"2026-10-10T18:59:50.889010923Z\",\n \"DownloadedAt\": \"2026-10-10T23:32:32.380033131Z\"\n },\n \"suppression\": false,\n \"ignore_unfixed\": false,\n \"severity_filter\": null,\n \"package_count\": 44,\n \"findings_by_severity\": {\n \"MEDIUM\": 1\n },\n \"findings\": [\n {\n \"id\": \"CVE-2026-85091\",\n \"package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"severity\": \"MEDIUM\"\n }\n ],\n \"coverage_limits\": [\n \"Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages\",\n \"Known findings asof pinnedDB, not claim absence of unknown vulnerabilities\"\n ],\n \"high_critical\": 0,\n \"same_scanner_actual_base_scan_findings_identical\": true,\n \"base_scan_file\": \"base-trivy-full.json\"\n}\n" + }, + { + "item_id": "execution-bundle-json", + "media_type": "application/json", + "content": "{\n \"kind\": \"informed-decision.execution-source-bundle\",\n \"version\": 1,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"files\": {\n \"README.md\": {\n \"sha256\": \"a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2\",\n \"content\": \"# Supervised Informed Decision purpose release executor — unapproved preparation\\n\\nNo native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor.\\n\\nRun one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion.\\n\\nInvocation after actual approval: `python3 execution/actuator.py --phase --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision `. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase.\\n\\nThe private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence.\\n\\nNew private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required.\\n\\nEvery phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions.\\n\\nExisting Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes.\\n\\nSixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof.\\n\\nAll phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance.\\n\\nThe initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred.\\n\"\n },\n \"actuator.py\": {\n \"sha256\": \"6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5\",\n \"content\": \"\\\"\\\"\\\"One fixed supervised phase; never run this during source preparation.\\\"\\\"\\\"\\nimport argparse\\nimport hashlib\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport re\\nimport selectors\\nimport stat\\nimport subprocess\\nimport sys\\nimport time\\n\\nif sys.flags.optimize:\\n raise SystemExit('optimized interpreter refused')\\n\\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\nROOT = Path(__file__).resolve().parent\\nCASE = ROOT.parent\\nOWNER = Path('/home/worsch/informed-decision')\\nCUSTODIAN = Path('/home/worsch/the-custodian')\\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\\nSOCKET = 'unix:///var/run/docker.sock'\\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\\nVOLUME = 'infd-purpose-r1-restore-20261011'\\nMAX_BYTES = 512 * 1024**2\\n\\n\\ndef run(argv, body=None, timeout=90):\\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\\n\\n\\ndef json_result(result):\\n try:\\n value = json.loads(result.stdout)\\n except (ValueError, TypeError):\\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\\n 'phase did not verify complete; raw output withheld; no retry')\\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\\n require(set(value) <= permitted, 'unexpected output fields withheld')\\n from receipt_safety import counts\\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\\n if name in value:\\n counts(value[name])\\n for name in ('snapshot_sha256', 'client_diff_sha256'):\\n if name in value:\\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\\n if 'snapshot_bytes' in value:\\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\\n 'invalid output size withheld')\\n if 'snapshot_file' in value:\\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\\n return value\\n\\n\\ndef docker(argv, body=None, timeout=120):\\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\\n body=body, timeout=timeout)\\n\\n\\ndef remote(phase, revision, approved):\\n # Fixed module imported only after main verifies every executor source hash.\\n from native_program import PROGRAM\\n payload = {'phase': phase, 'source_revision': revision, 'approval': approved,\\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\\n\\n\\ndef copy_snapshot(phase, revision, approved, journal):\\n metadata = remote(phase, revision, approved)\\n backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup'\\n prior = journal.data['phases'][backup_phase]['result']\\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\\n name = metadata['snapshot_file']\\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\\n 'fixed bounded snapshot required')\\n pod = metadata['pod_name']\\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\\n local = CUSTODY / name\\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\\n # Snapshot schema/count metadata was validated before opening this destination.\\n with os.fdopen(fd, 'wb') as destination:\\n command = ('kubectl exec -n informed-decision ' + pod +\\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\\n stderr=subprocess.DEVNULL)\\n selector = selectors.DefaultSelector()\\n selector.register(transfer.stdout, selectors.EVENT_READ)\\n deadline = time.monotonic() + 150\\n received = 0\\n try:\\n while True:\\n remaining = deadline - time.monotonic()\\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\\n block = os.read(transfer.stdout.fileno(), 1024**2)\\n if not block:\\n break\\n received += len(block)\\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\\n 'private copy exceeds frozen snapshot size')\\n destination.write(block)\\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\\n finally:\\n selector.close()\\n transfer.stdout.close()\\n if transfer.poll() is None:\\n transfer.kill()\\n transfer.wait()\\n destination.flush()\\n os.fsync(destination.fileno())\\n private(local)\\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\\n # Re-read identity/hash after transfer. This is verification, not a write retry.\\n after = remote(phase, revision, approved)\\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\\n 'source identity/snapshot changed during transfer')\\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\\n\\n\\ndef offline_verify(journal):\\n from receipt_safety import counts\\n snapshot = CUSTODY / 'drill.sqlite'\\n private(snapshot)\\n previous = journal.data['phases']['drill-copy']['result']\\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\\n identity = docker(['info', '--format', '{{json .Name}}'])\\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\\n 'local offline Docker engine identity changed')\\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\\n 'disposable volume absence not verified')\\n nonce = journal.data['phases']['offline-verify']['attempt_id']\\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\\n '--label', 'informed-decision.attempt=' + nonce,\\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'new volume identity unavailable')\\n volume = json.loads(inspected.stdout)\\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\\n journal.note('offline-verify', 'created_volume_identity', identity)\\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\\n # No host/live PVC/config/token mount exists; this detail needs packet review.\\n initializer = \\\"\\\"\\\"import hashlib,os,stat,sys\\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\\nfolder='/restore';expected=EXPECTED\\nif os.listdir(folder):raise ValueError('new empty private volume required')\\nos.chmod(folder,0o700)\\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\\ndigest=hashlib.sha256();size=0\\nwith os.fdopen(fd,'wb') as target:\\n while True:\\n block=sys.stdin.buffer.read(1024**2)\\n if not block:break\\n size+=len(block)\\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\\n target.write(block);digest.update(block)\\n target.flush();os.fsync(target.fileno())\\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\\nprint('{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}')\\n\\\"\\\"\\\".replace('EXPECTED', repr(previous['snapshot_sha256']))\\n with snapshot.open('rb') as source:\\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\\n '--entrypoint', 'python', IMAGE, '-c', initializer]\\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\\n json_result(copied)\\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\\n checked = counts(json.loads(readonly.stdout))\\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\\n 'inspect', '--db', '/restore/review.sqlite'])\\n require(admin.returncode == 0, 'offline admin result uncertain')\\n admin_counts = json.loads(admin.stdout)\\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\\n 'offline admin changed frozen snapshot counters')\\n # Admin Store construction must not silently alter schema/integrity/counters.\\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\\n post_checked = counts(json.loads(post.stdout))\\n require(post_checked == checked == previous['snapshot_readonly'],\\n 'offline admin altered frozen snapshot proof')\\n private(snapshot)\\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\\n 'created_volume_identity': identity,\\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\\n\\n\\ndef cleanup_offline(journal):\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\\n value = json.loads(inspected.stdout)\\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\\n and not value[0].get('Options'), 'volume ownership/recreation changed')\\n removed = docker(['volume', 'rm', VOLUME])\\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\\n 'cleanup outcome ambiguous; do not retry')\\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\\n 'native_and_offcluster_original_snapshots_retained': True}\\n\\n\\ndef main():\\n parser = argparse.ArgumentParser(description=__doc__)\\n parser.add_argument('--phase', choices=PHASES, required=True)\\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\\n parser.add_argument('--root-native-outcome', type=Path, required=True)\\n parser.add_argument('--source-revision', required=True)\\n args = parser.parse_args()\\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\\n 'fixed supervised receipt paths required')\\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\\n # Verify all prepared executor/input bytes before reading authority or dispatching.\\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\\n 'fixed executor sources required')\\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\\n 'deploy/lifecycle/service.candidate.json',\\n 'deploy/lifecycle/kustomization.yaml',\\n 'deploy/lifecycle/registries.candidate.json'},\\n 'fixed owner image sources required')\\n for relative, digest in plan['executor_files'].items():\\n target = ROOT / relative\\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\\n for relative, digest in plan['case_files'].items():\\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\\n 'case source path escaped')\\n target = CASE / relative\\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\\n for relative, digest in plan['owner_source_files'].items():\\n target = OWNER / relative\\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\\n capture_output=True)\\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\\n 'committed owner render source differs from approved inputs')\\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\\n from authority_journal import Journal, authority\\n private(args.root_authority_receipt)\\n private(args.root_native_outcome)\\n receipt = json.loads(args.root_authority_receipt.read_text())\\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\\n 'root verified executor plan differs')\\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\\n args.source_revision, args.phase)\\n parent = CUSTODY.parent\\n private(parent, directory=True)\\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\\n if not CUSTODY.exists():\\n require(args.phase == 'drill-backup', 'first approved phase must create unique private custody')\\n os.mkdir(CUSTODY, 0o700)\\n private(CUSTODY, directory=True)\\n capacity = os.statvfs(CUSTODY)\\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\\n 'independent protected custody headroom insufficient')\\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\\n private(CUSTODY / 'empty-docker-config', directory=True)\\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')})\\n try:\\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\\n if args.phase in ('drill-copy', 'cutover-copy'):\\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\\n elif args.phase == 'offline-verify':\\n result = offline_verify(journal)\\n elif args.phase == 'cleanup-offline':\\n result = cleanup_offline(journal)\\n else:\\n result = remote(args.phase, args.source_revision, approved)\\n journal.finish(args.phase, result)\\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\\n except BaseException as error:\\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\\n 'raw_output_withheld': True}\\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\\n journal.finish(args.phase, safe)\\n print(json.dumps(safe))\\n raise SystemExit(1) from None\\n finally:\\n journal.close()\\n\\n\\nif __name__ == '__main__':\\n try:\\n main()\\n except Exception:\\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\\n\"\n },\n \"authority_journal.py\": {\n \"sha256\": \"74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa\",\n \"content\": \"\\\"\\\"\\\"Supervised receipt bookkeeping, not an authenticated approval provider.\\\"\\\"\\\"\\nimport datetime\\nimport fcntl\\nimport hashlib\\nimport json\\nimport os\\nimport re\\nfrom pathlib import Path\\nimport stat\\nimport uuid\\n\\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\\nPHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\n\\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\\n \\\"\\\"\\\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\\n\\n Receipt files/flags are not signed grants. This function checks the exact\\n supervised receipt relation; existing harness/founder authority remains the\\n actual permission boundary. It never authenticates a caller as human.\\n \\\"\\\"\\\"\\n now = now or datetime.datetime.now(datetime.timezone.utc)\\n require(phase in PHASES, 'fixed phase required')\\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\\n and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha\\n and receipt.get('source_revision') == source_revision\\n and receipt.get('activation') == 'APPROVED'\\n and receipt.get('authority_mode') == 'ADMINISTER'\\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\\n and receipt.get('runtime_authenticated_grant') is False,\\n 'exact externally verified supervised receipt required')\\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\\n 'fresh root native readback required before every phase')\\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\\n require(now < deadline, 'approved execution window expired')\\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\\n review_id = outcome['review']['memo_id']\\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\\n accepted = [x for x in outcome.get('dispositions', [])\\n if x.get('submission_state') == 'confirmed'\\n and x.get('disposition', {}).get('verb') == 'accept'\\n and x['disposition'].get('memo_version') == 1]\\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\\n accepted = accepted[0]['disposition']\\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\\n and accepted.get('approval_id') == receipt.get('approval_id')\\n and accepted.get('id') == receipt.get('disposition_id')\\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\\n 'native disposition identifiers are malformed')\\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\\n\\n\\nclass Journal:\\n def __init__(self, parent, identity):\\n self.parent = Path(parent)\\n private(self.parent, directory=True)\\n self.path = self.parent / 'execution-journal.json'\\n self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\\n private(self.parent / 'execution.lock')\\n if self.path.exists():\\n private(self.path)\\n self.data = json.loads(self.path.read_text())\\n require(self.data['identity'] == identity, 'journal case/source identity changed')\\n else:\\n self.data = {'identity': identity, 'phases': {}}\\n self.save()\\n\\n def save(self):\\n temporary = self.parent / 'execution-journal.new'\\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\\n try:\\n with os.fdopen(fd, 'w') as stream:\\n json.dump(self.data, stream, indent=2)\\n stream.write('\\\\n')\\n stream.flush()\\n os.fsync(stream.fileno())\\n os.replace(temporary, self.path)\\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\\n try:\\n os.fsync(directory)\\n finally:\\n os.close(directory)\\n except BaseException:\\n # Retain evidence rather than overwriting an uncertain durable intent.\\n raise\\n\\n def start(self, phase, approval):\\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\\n predecessors = dict(zip(PHASES[1:8], PHASES[:7]))\\n predecessors['rollback-verify'] = 'rollback'\\n if phase in predecessors:\\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\\n 'preceding phase is not verified complete')\\n if phase == 'rollback':\\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\\n 'attempt_id': str(uuid.uuid4()),\\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\\n self.save()\\n\\n def note(self, phase, key, value):\\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\\n self.data['phases'][phase][key] = value\\n self.save()\\n\\n def finish(self, phase, result):\\n entry = self.data['phases'][phase]\\n require(entry['state'] == 'RUNNING', 'phase intent missing')\\n entry['result'] = result\\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\\n self.save()\\n\\n def close(self):\\n os.close(self.lock)\\n\"\n },\n \"execution-plan.json\": {\n \"sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\",\n \"content\": \"{\\n \\\"kind\\\": \\\"informed-decision.supervised-mechanical-release-plan\\\",\\n \\\"version\\\": 1,\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"trial_id\\\": \\\"infd-purpose-20261011-r1\\\",\\n \\\"state\\\": \\\"prepared-unapproved\\\",\\n \\\"executor_files\\\": {\\n \\\"actuator.py\\\": \\\"6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5\\\",\\n \\\"authority_journal.py\\\": \\\"74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa\\\",\\n \\\"native_program.py\\\": \\\"349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde\\\",\\n \\\"receipt_safety.py\\\": \\\"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\\\"\\n },\\n \\\"case_files\\\": {\\n \\\"change_guard.py\\\": \\\"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\\\",\\n \\\"sqlite_readonly.py\\\": \\\"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\\\",\\n \\\"preflight-inputs.json\\\": \\\"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\\\",\\n \\\"sealed-live-deployment.json\\\": \\\"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\\\",\\n \\\"sealed-native-dependencies.json\\\": \\\"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\\\",\\n \\\"candidate-deployment.json\\\": \\\"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\\\",\\n \\\"rollback-deployment.json\\\": \\\"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\\\",\\n \\\"check_installed.py\\\": \\\"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\\\",\\n \\\"published-verification.json\\\": \\\"8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2\\\",\\n \\\"security-summary.json\\\": \\\"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\\\"\\n },\\n \\\"owner_source_files\\\": {\\n \\\"deploy/lifecycle/admission.candidate.json\\\": \\\"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\\\",\\n \\\"deploy/lifecycle/service.candidate.json\\\": \\\"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\\\",\\n \\\"deploy/lifecycle/kustomization.yaml\\\": \\\"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\\\",\\n \\\"deploy/lifecycle/registries.candidate.json\\\": \\\"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\\\"\\n },\\n \\\"candidate_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\\\",\\n \\\"prior_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\\",\\n \\\"source_revision\\\": \\\"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\\\",\\n \\\"phases\\\": [\\n \\\"drill-backup\\\",\\n \\\"drill-copy\\\",\\n \\\"offline-verify\\\",\\n \\\"cleanup-offline\\\",\\n \\\"cutover-backup\\\",\\n \\\"cutover-copy\\\",\\n \\\"release\\\",\\n \\\"verify\\\",\\n \\\"rollback\\\",\\n \\\"rollback-verify\\\"\\n ],\\n \\\"authorization\\\": \\\"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\\\",\\n \\\"execute_by\\\": \\\"2026-10-12T23:59:59Z\\\",\\n \\\"raw_output_withheld\\\": true,\\n \\\"native_data_or_workload_action_executed\\\": false,\\n \\\"deadline_semantics\\\": \\\"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\\\"\\n}\\n\"\n },\n \"native_program.py\": {\n \"sha256\": \"349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde\",\n \"content\": \"\\\"\\\"\\\"Fixed remote source, passed only after exact supervised approval.\\\"\\\"\\\"\\nPROGRAM = '\\\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\\\nif sys.flags.optimize:raise RuntimeError(\\\\'optimized interpreter refused\\\\')\\\\npayload=json.loads(__PAYLOAD__)\\\\nexec(__GUARD__)\\\\nphase=payload[\\\\'phase\\\\']\\\\nif phase not in (\\\\'drill-backup\\\\',\\\\'cutover-backup\\\\',\\\\'drill-copy\\\\',\\\\'cutover-copy\\\\',\\\\'release\\\\',\\\\'verify\\\\',\\\\'rollback\\\\',\\\\'rollback-verify\\\\'):raise ValueError(\\\\'fixed native phase required\\\\')\\\\ndeadline=datetime.datetime.fromisoformat(\\\\'2026-10-12T23:59:59+00:00\\\\')\\\\ndef require(value,reason):\\\\n if not value:raise ValueError(reason)\\\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\\\'drill-backup\\\\' else 1)+16*1024**2,\\\\'bounded native snapshot capacity required\\\\')\\\\n if action==\\\\'drill-backup\\\\':\\\\n require(not os.path.lexists(folder),\\\\'native case directory must be unique\\\\')\\\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\\\n private(folder,True)\\\\n filename=\\\\'drill.sqlite\\\\' if action==\\\\'drill-backup\\\\' else \\\\'cutover.sqlite\\\\';output=folder+\\\\'/\\\\'+filename\\\\n require(not os.path.lexists(output),\\\\'snapshot output must be unique\\\\')\\\\n admin=subprocess.run([\\\\'informed-decision-admin\\\\',\\\\'backup\\\\',\\\\'--db\\\\',db,\\\\'--output\\\\',output],capture_output=True,text=True,timeout=120)\\\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\\\'status\\\\':\\\\'backed_up\\\\',\\\\'consistent_snapshot\\\\':True},\\\\'backup completion not verified; do not retry\\\\')\\\\n private(output)\\\\n for suffix in (\\\\'-wal\\\\',\\\\'-shm\\\\'):\\\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\\\'snapshot is not closed main-file custody\\\\')\\\\n snapshot=counts(inspect_readonly(output))\\\\n size=os.stat(output).st_size;require(0 10**12\\n for number in value[group].values()):\\n raise ValueError('count-only receipt values refused')\\n return value\\n\"\n },\n \"root-authority-receipt-template.json\": {\n \"sha256\": \"15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813\",\n \"content\": \"{\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"memo_id\\\": \\\"infd-20261011-purpose-overlay-r1\\\",\\n \\\"memo_version\\\": 1,\\n \\\"memo_sha256\\\": null,\\n \\\"source_revision\\\": null,\\n \\\"activation\\\": \\\"PENDING\\\",\\n \\\"authority_mode\\\": \\\"ADMINISTER\\\",\\n \\\"target\\\": \\\"realm:kubernetes/railiance01/informed-decision\\\",\\n \\\"verification_method\\\": \\\"root-fixed-origin-native-readback\\\",\\n \\\"runtime_authenticated_grant\\\": false,\\n \\\"verified_at\\\": null,\\n \\\"accepted_at\\\": null,\\n \\\"review_memo_id\\\": null,\\n \\\"approval_id\\\": null,\\n \\\"disposition_id\\\": null,\\n \\\"native_outcome_sha256\\\": null,\\n \\\"executor_plan_sha256\\\": \\\"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\\\"\\n}\\n\"\n },\n \"test_execution.py\": {\n \"sha256\": \"9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48\",\n \"content\": \"\\\"\\\"\\\"Synthetic custody/transport tests. No native data, Docker or cluster action.\\\"\\\"\\\"\\nimport copy\\nimport datetime\\nimport io\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport subprocess\\nimport sys\\nimport tempfile\\nimport unittest\\nfrom unittest.mock import patch\\nfrom contextlib import redirect_stdout\\n\\nimport actuator\\nfrom authority_journal import Journal, authority\\nfrom native_program import PROGRAM\\nfrom receipt_safety import counts\\n\\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\\nREVISION = 'e' * 40\\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\\n\\n\\ndef accepted():\\n approval = '11111111-1111-4111-8111-111111111111'\\n review = 'review-22222222-2222-4222-8222-222222222222'\\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1,\\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False,\\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\\n 'approval_id': approval, 'id': disposition,\\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\\n 'at': receipt['accepted_at']}}]}\\n return receipt, outcome\\n\\n\\nclass AuthorityAndCustody(unittest.TestCase):\\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\\n receipt, outcome = accepted()\\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW)\\n self.assertEqual(result['approval_id'], receipt['approval_id'])\\n\\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\\n mutations = [lambda r, o: r.update(activation='PENDING'),\\n lambda r, o: r.update(memo_sha256='changed'),\\n lambda r, o: r.update(source_revision='changed'),\\n lambda r, o: r.update(target='other'),\\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\\n lambda r, o: r.update(verification_method='caller-asserted'),\\n lambda r, o: r.update(runtime_authenticated_grant=True),\\n lambda r, o: o['review'].update(stale=True),\\n lambda r, o: o['review'].update(intake_state='pending'),\\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2),\\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n r, o = accepted()\\n mutate(r, o)\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\\n\\n def test_expired_window_and_unknown_phase_refuse(self):\\n r, o = accepted()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\\n r['verified_at'] = late.isoformat()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\\n\\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\\n with tempfile.TemporaryDirectory() as directory:\\n parent = Path(directory)\\n os.chmod(parent, 0o700)\\n journal = Journal(parent, {'case': 'fixture'})\\n journal.start('drill-backup', {'approval_id': 'fixture'})\\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING')\\n journal.close() # simulated crash before result\\n recovered = Journal(parent, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-backup', {})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-copy', {})\\n recovered.close()\\n\\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\\n with tempfile.TemporaryDirectory() as directory:\\n os.chmod(directory, 0o700)\\n j = Journal(directory, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n for phase in actuator.PHASES[:6]:\\n j.start(phase, {})\\n j.finish(phase, {'all_checks_pass': True})\\n j.start('release', {})\\n j.finish('release', {'all_checks_pass': False})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n with self.assertRaises(ValueError):\\n j.start('verify', {})\\n j.start('rollback', {})\\n j.finish('rollback', {'all_checks_pass': True})\\n j.close()\\n\\n def test_secret_or_unknown_child_output_is_withheld(self):\\n for body in ('not-json', '{\\\"all_checks_pass\\\":true,\\\"token\\\":\\\"private-value\\\"}',\\n '{\\\"all_checks_pass\\\":true,\\\"snapshot_readonly\\\":{\\\"schema_version\\\":5}}'):\\n with self.assertRaises(ValueError):\\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\\n wrong = copy.deepcopy(COUNT)\\n wrong['outbox'] = {'private-row-value': 1}\\n with self.assertRaises(ValueError):\\n counts(wrong)\\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\\n\\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\\n blob = b'synthetic private fixture bytes'\\n digest = __import__('hashlib').sha256(blob).hexdigest()\\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\\n journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})()\\n real_popen = subprocess.Popen\\n for extra in (b'', b'oversized'):\\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\\n os.chmod(folder, 0o700)\\n output = io.StringIO()\\n\\n def child(*args, **kwargs):\\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\\n\\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\\\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\\n if extra:\\n with self.assertRaises(ValueError):\\n actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\\n else:\\n result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal)\\n self.assertTrue(result['off_cluster_private_copy_verified'])\\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\\n self.assertEqual(output.getvalue(), '')\\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\\n\\n def test_recreated_offline_volume_cannot_be_deleted(self):\\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\\n journal = type('FixtureJournal', (), {'data': {'phases': {\\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\\n with self.assertRaises(ValueError):\\n actuator.cleanup_offline(journal)\\n self.assertEqual(mocked.call_count, 1)\\n\\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\\n for defect in ('none', 'post-integrity', 'original-hash'):\\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\\n folder=Path(directory);os.chmod(folder,0o700)\\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\\n digest=actuator.sha(snapshot)\\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\\n reads=[]\\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\\n def docker(argv, body=None, **kwargs):\\n if argv[0]=='info':body=json.dumps('bnt-lap001')\\n elif argv[:2]==['volume','ls']:body=''\\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\\n elif 'informed-decision-admin' in argv:\\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\\n elif '--entrypoint' in argv and 'python' in argv:\\n reads.append(argv);proof=copy.deepcopy(COUNT)\\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\\n body=json.dumps(proof)\\n else:raise AssertionError('unexpected offline command')\\n return subprocess.CompletedProcess(argv,0,body,'')\\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}','')):\\n if defect=='none':\\n result=actuator.offline_verify(journal)\\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\\n self.assertTrue(result['original_snapshot_hash_unchanged'])\\n else:\\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\\n self.assertEqual(len(reads),2)\\n\\n\\nclass FixedNativeProgram(unittest.TestCase):\\n def fixture(self):\\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\\n live = copy.deepcopy(sealed)\\n live['metadata'].update(generation=42)\\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\\n cm = copy.deepcopy(dependencies['configmap'])\\n cm.pop('canonical_data_sha256')\\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\\n pvc = copy.deepcopy(dependencies['pvc'])\\n pvc['status'] = {'phase': 'Bound'}\\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\\n 'dependencies': dependencies, 'candidate': service,\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\\n return objects, payload\\n\\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\\n writes = []\\n calls = []\\n\\n def fake(argv, input=None, **kwargs):\\n calls.append(argv)\\n if argv[:2] == ['kubectl', 'get']:\\n kind = argv[2]\\n if kind in objects:\\n body = objects[kind]\\n elif kind == 'pods':\\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\\n 'spec': objects['deployment']['spec']['template']['spec'],\\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\\n elif kind == 'replicaset':\\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\\n elif kind == 'nodes':\\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\\n else:\\n raise AssertionError('unexpected fixed metadata route')\\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\\n if argv[:2] == ['kubectl', 'exec']:\\n if schema_refused:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, json.dumps({\\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\\n if argv[:2] == ['kubectl', 'apply']:\\n admitted = copy.deepcopy(payload['sealed'])\\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\\n if argv[:2] == ['kubectl', 'describe']:\\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\\\n cpu 3460m (86%)\\\\n', '')\\n if argv[:2] == ['kubectl', 'diff']:\\n return subprocess.CompletedProcess(argv, 1, '-image: base\\\\n+image: candidate\\\\n', '')\\n if argv[:2] == ['kubectl', 'patch']:\\n if '--dry-run=server' not in argv:\\n writes.append(json.loads(input))\\n if ambiguous:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\\\n', '')\\n raise AssertionError('unexpected command')\\n\\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n output = io.StringIO()\\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\\n try:\\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\\n except (ValueError, SystemExit):\\n pass\\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\\n return receipt, writes, calls\\n\\n def test_only_existing_application_operation_and_deployment_are_requested(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n operation = writes[0][-1]['value']\\n self.assertFalse(operation['sync']['prune'])\\n self.assertEqual(operation['sync']['resources'], [\\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\\n\\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\\n lambda o: o['application']['spec'].update(sources=[{}]),\\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n objects, payload = self.fixture()\\n mutate(objects)\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n def test_preopen_schema_refusal_prevents_image_operation(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n\\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\\n objects, payload = self.fixture()\\n payload['phase'] = 'rollback'\\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\\n objects['application']['spec']['source']['targetRevision'] = REVISION\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\\n\\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\\n for defect in ('cm', 'pvc', 'image'):\\n with self.subTest(defect=defect):\\n objects, payload = self.fixture();payload['phase'] = 'rollback'\\n objects['deployment']['status']['readyReplicas'] = 0\\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\\n\\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\\n self.assertEqual(writes, [])\\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\\n objects['deployment']['status']['readyReplicas'] = 0\\n receipt, writes, calls = self.execute_fake(objects,payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n\\n def test_ambiguous_patch_is_never_retried(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(len(writes), 1)\\n\\n\\nif __name__ == '__main__':\\n unittest.main()\\n\"\n },\n \"validation.json\": {\n \"sha256\": \"26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28\",\n \"content\": \"{\\n \\\"tests\\\": 16,\\n \\\"result\\\": \\\"passed\\\",\\n \\\"synthetic_transport_only\\\": true,\\n \\\"real_native_data_read\\\": false,\\n \\\"native_backup_export_restore_executed\\\": false,\\n \\\"native_workload_changed\\\": false,\\n \\\"actual_founder_approval\\\": false,\\n \\\"local_read_only_capability_checks\\\": [\\n \\\"argocdCLI absent, existingApplication.operation path retained\\\",\\n \\\"Dockerunixsocket engineName bnt-lap001\\\"\\n ],\\n \\\"case_source_commit_at_preparation\\\": \\\"e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)\\\",\\n \\\"additional_regressions\\\": [\\n \\\"Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation\\\",\\n \\\"rollback still refuses CM/PVC or nonpair-image drift\\\",\\n \\\"separate old-image Ready/schema5 recovery proof\\\",\\n \\\"post-admin readonly integrity refusal and original snapshot tamper refusal\\\"\\n ]\\n}\\n\"\n }\n },\n \"native_execution\": false\n}\n" + }, + { + "item_id": "sqlite-readonly-py", + "media_type": "text/plain", + "content": "\"\"\"Pre-open schema/integrity/count proof; stdlib only, never constructs Store.\"\"\"\nimport argparse\nimport json\nfrom pathlib import Path\nimport sqlite3\n\n\ndef inspect_readonly(path):\n path = Path(path)\n if not path.is_file() or path.is_symlink():\n raise ValueError('existing nonsymlink private database required')\n with sqlite3.connect(path.resolve().as_uri() + '?mode=ro', uri=True, timeout=5) as db:\n db.execute('PRAGMA query_only=ON')\n db.execute('BEGIN')\n version = db.execute('PRAGMA user_version').fetchone()[0]\n if version != 5:\n raise ValueError('pre-open database is not schema5; refuse migration')\n if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]:\n raise ValueError('read-only integrity check refused')\n lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0]\n for name, table in (('records', 'lifecycle_records'),\n ('events', 'lifecycle_events'),\n ('pending', 'lifecycle_pending'))}\n result = {'schema_version': version, 'lifecycle': lifecycle,\n 'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')),\n 'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')),\n 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False}\n db.rollback()\n return result\n\n\nif __name__ == '__main__':\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--db', type=Path, required=True)\n args = parser.parse_args()\n try:\n print(json.dumps(inspect_readonly(args.db), sort_keys=True))\n except Exception:\n raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None\n" + }, + { + "item_id": "sealed-native-dependencies-json", + "media_type": "application/json", + "content": "{\n \"configmap\": {\n \"apiVersion\": \"v1\",\n \"immutable\": true,\n \"kind\": \"ConfigMap\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/ConfigMap:informed-decision/informed-decision-runtime-6c221878d051\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision-runtime-6c221878d051\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\"\n },\n \"canonical_data_sha256\": \"8ec462d12347548f506eeebf1e3c7cc47648019c8a783804d09bcc79b0f22af6\"\n },\n \"pvc\": {\n \"apiVersion\": \"v1\",\n \"kind\": \"PersistentVolumeClaim\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/PersistentVolumeClaim:informed-decision/informed-decision-data\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"pv.kubernetes.io/bind-completed\": \"yes\",\n \"pv.kubernetes.io/bound-by-controller\": \"yes\",\n \"volume.beta.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\",\n \"volume.kubernetes.io/selected-node\": \"239.62.205.92.host.secureserver.net\",\n \"volume.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\"\n },\n \"finalizers\": [\n \"kubernetes.io/pvc-protection\"\n ],\n \"name\": \"informed-decision-data\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n },\n \"spec\": {\n \"accessModes\": [\n \"ReadWriteOnce\"\n ],\n \"resources\": {\n \"requests\": {\n \"storage\": \"1Gi\"\n }\n },\n \"storageClassName\": \"local-path\",\n \"volumeMode\": \"Filesystem\",\n \"volumeName\": \"pvc-d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n }\n },\n \"pvc_phase\": \"Bound\"\n}\n" + }, + { + "item_id": "native-backup-restore-protocol-md", + "media_type": "text/markdown", + "content": "# Protected native backup/restore and image-only release protocol\n\nPrepared protocol for `INFD-WP-0009-T04/purpose-overlay-v1`. No actual native backup, data export, restore, workload change or approval is recorded here. Candidate registry image identity remains a prerequisite; only after actual artifact proof may the founder approve one exact conditional protocol/rollout packet. The config-only7db8485 approval is outside this scope.\n\n## Preconditions and protected custody\n\nFreeze exact candidate and prior7f5c6cb image digests, source/installed policy hashes, current manually managed Argo Application/revision, runtime ConfigMap6c221878d051, Deployment UID/template/spec, schema5, policy package pins, database path `/data/private/review.sqlite`, PVC binding, replicas1/Recreate and stable keys for intended verification. Confirm no concurrent writer or custody change. Use fixed metadata; never fetch Secret objects or token values. A changed image/config/schema/owner invalidates the packet. Fresh resources/headroom and exact source/native server-dry-run/diff remain required.\n\nBackups are private evidence containing real decision records, not logs or packet attachments. Allocate a unique backup directory under existing protected PVC custody, owned10001, mode0700, snapshot file0600, no symlink/hardlink/reused output path. An off-cluster copy belongs only in the already established ignored `.private-backups/` custody with0700/0600 permissions; no Git, StateHub, public object store or terminal-content dump. Record only schema, integrity pass/fail, bounded table/state counts and protected receipt identifier; retain byte digests in protected custody if needed for internal copy identity. No credential, record payload or token fingerprint enters public evidence.\n\n## Approved online compatibility drill\n\nWithin the explicit founder-approved action, run the existing base image's `informed-decision-admin backup --db /data/private/review.sqlite --output ` in the actual serving workload. This uses SQLite's backup API for a transactionally consistent snapshot; copying a live main database while ignoring WAL is prohibited. Suppress raw failures/output and retain only sanitized status. Observe schema/integrity and count-only metadata from the resulting snapshot, not record content.\n\nTransfer that consistent snapshot only into protected off-cluster custody through the existing authorized operator lane. The copy is real production data even in build mode. Verify private permissions, unique identity and protected internal digest agreement. Do not export mounted workload credentials or directory trees; copy only the exact snapshot.\n\nCreate a separate private disposable restore volume/directory; retain the original snapshot unchanged. Run the exact published candidate with network disabled, no production ConfigMap/token mounts, read-only image and only that isolated volume writable. Override the service entrypoint with the owner's count-only administrative inspection/integrity check; do not start HTTP listeners, audit delivery, requester exchanges or approval operations. The current candidate changes policy.py only and retains the schema/store module bytes; still prove schema5, SQLite integrity and exact bounded counts before/after opening the restored copy. Refuse any migration/downgrade, lost/changed counts, unexpected write class or unknown outcome. Keep pending/uncertain submission and outbox states; never replay, discard or mark them delivered to green the drill. Cleanup only the disposable copy/volume after verified receipt; retain the original protected backup for the approved recovery interval.\n\nThis step is actual native-data compatibility evidence once performed. Its previous synthetic fixture checks remain mechanism evidence and cannot be renamed native success. A failed drill stops rollout and remains a failed/unverified outcome in the same trial.\n\n## Fresh cutover snapshot and single-writer rollout\n\nAfter successful actual-data compatibility checks, create another unique SQLite-consistent online snapshot immediately before the image cutover, retaining its point-in-time schema/integrity/count receipt. This is an online transactional snapshot, not a claim that dispatchers or human writes were quiesced. Every later committed record remains in the live database; same-schema rollback retains that database and never restores the earlier snapshot over it. The narrow image-only update does not need dispatcher/configuration/PVC/temporary-pod changes or a schema cutover. If fresh verification shows a migration or any data-restoration requirement, stop and refine the proposal rather than applying this protocol.\n\nThe existing Recreate rollout drains/stops the single old writer before starting the new image on the same PVC; the inherited single-writer lock independently refuses concurrent serving processes. Do not add an admin pod, scale-to-zero, dispatcher stop, network-policy rewrite or snapshot overwrite as an improvised image-only step. The existing owner admin backup operation runs inside the admitted serving workload, and its separate protected restore drill runs off-cluster with network disabled and no workload credentials. Those exact custody operations must be enumerated in the founder packet alongside the one Deployment image change.\n\nOnce backup/compatibility/preflight gates pass, manually pin the existing Argo Application to the exact reviewed source revision and sync only Deployment/informed-decision with prune false, keeping the current immutable runtime ConfigMap and all other resources. The source patch changes only the image in admission/rendered Deployment; no Secret, PVC, policy, database or dispatcher change is included unless separately enumerated in the final proposal. Observe five-minute readiness and exact image/config/schema/pins. Run the ten installed purpose variants on the actual native placement using synthetic transport; they prove exact installed module refusal behavior and explicitly report native_provider=false. They do not prove an actual provider response, PDP authority or native lifecycle binding; any required actual-provider proof remains a distinct T04 completion gate with separate authorized preparation, and must not be claimed by this helper. Do not contaminate the live PDP, create human approvals, read credentials through CLI, or replay unknown external outcomes for testing.\n\n## Same-schema rollback and evidence retention\n\nOn startup/readiness/binding/refusal failure, retain current database, cutover backup and every post-cutover evidence/uncertain outcome. Restore only the prior7f5c6cb image through the same manual Argo owner path, retaining schema5 and current DB/configuration; never restore an old snapshot over current live evidence just to roll the image back. Verify old image/Ready1, same schema/counts and prior behavior, and reconcile any external effects using existing lifecycle/audit ownership. The narrow overlay's identical store/schema/dependency bytes permit this image-only rollback; it is not permission for a schema downgrade or data loss.\n\nRecord original/approved/executed source and image revisions, backup/drill/cutover/rollout timestamps, exact disposition and sanitized outcomes in the existing supervised trial receipt. EUR0 incremental infrastructure estimate uses existing service/storage/operator lane; protected temporary copy/storage consumption and15–30minute recovery time remain operational costs. No EUR incident-loss cap or autonomy grant is inferred. TaskT04 cannot close until actual published image, approved native compatibility and release plus post-release refusal/binding evidence all exist.\n\n## Exact release case identifiers\n\nProposal `INFD-WP-0009-T04/purpose-overlay-v1`, trial `infd-purpose-20261011-r1`.\nProtected native parent `/data/private/purpose-overlay-r1` must be unique/non-symlink, owned10001 and0700. The drill snapshot is `drill.sqlite`, the refreshed pre-cutover snapshot `cutover.sqlite`, each new0600 file; refuse any existing output. Off-cluster custody is the existing ignored Custodian `.private-backups/20261011-infd-purpose-r1` parent0700, files0600; no snapshot is an evidence attachment. Check owner UID, no symlinks, ignored status and free capacity for both native snapshots plus independently protected copies before making any snapshot.\n\nThe disposable offline restore volume is `infd-purpose-r1-restore-20261011`; refuse an existing volume, copy only the selected frozen snapshot, and run exact published candidate763c with networknone/read-only image,128MiB/core1 and no runtime config/token mounts. SQLite `PRAGMA integrity_check` must return `ok`, `PRAGMA user_version`/Store inspection must agree with actual schema5 semantics, and installed admin count-only inspection must match the frozen snapshot. Validate the actual schema representation rather than assume PRAGMA user_version is the schema authority. No synthetic restoration is reported as native restoration. Native original/off-cluster copies remain retained; only the disposable restore copy/volume may be removed under the exact approved cleanup scope.\n\n## Mandatory pre-open schema gate and offline command\n\n`informed-decision-admin inspect` and `backup` construct Store, which can migrate schemas1–4 to5. Therefore **before any Store/admin open**, run the exact attached stdlib-only `sqlite_readonly.py` against the native source database using SQLite URI mode=ro, query_only and one read transaction. Require PRAGMA user_version5, integrity_check=ok and retain count-only baseline. Refuse any other/unknown schema or incomplete integrity/count check before constructing Store; do not infer no migration from a post-open admin report. This native gate has not been executed in this source-preparation stage. Repeat before each native backup/admin operation.\n\nAfter copying the selected consistent snapshot to the isolated restored private path `/restore/review.sqlite`, run the same read-only checker **before** any offline candidate admin/Store opens that copy. Frozen snapshot and restored-copy schema/integrity/count reports must agree exactly; the copied main-file digest must match the selected closed snapshot. Reject oldschema fixtures rather than allow migration. Only after this pre-open gate may the offline candidate admin inspect run.\n\nOffline command vectors use exactimage `forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a`, `--network none --read-only --cpus 1 --memory 128m`, private restored volume mounted at `/restore`, and **no runtime config/credential/token mounts**. First override entrypoint to `python`, arguments `- --db /restore/review.sqlite`, streaming only the verified attached checker on stdin. Then override entrypoint to **`informed-decision-admin`**, arguments **`inspect --db /restore/review.sqlite`**. This does not start `informed-decision-container`, the HTTP service, dispatcher or delivery workers. Compare the admin's schema/lifecycle/outbox/submission counters to the frozen pre-open snapshot report; integrity and migration-free pre-open proof come from the stdlib checker, not admin output alone.\n\nLive reads and online snapshots may legitimately differ because reviews, intake and delivery can commit concurrently. Exact counter equality is required between the frozen selected snapshot and its offline restored clone; it is **not** required between a running post-cutover/rollback database and an earlier snapshot. Live count changes must be accounted for as legitimate committed records/state transitions; preserve all current and uncertain entries. Do not discard new commits or restore the old snapshot to force equality. Same-schema image rollback keeps the current live DB, followed by read-only schema5/integrity and count-only health checks; any unexplained evidence loss or required data recovery stops and requires a separate founder decision.\n\nThe fresh preflight also independently reads the actual immutable nonsecret ConfigMap and bound PVC: compares sealed UIDs/fullmetadata/PVCspec+volumeName and canonical runtime data checksum, returning no raw runtime data. Same-name deletion/recreation or content/custody drift stops before admission. Secret values remain excluded. Both local and remote optimized Python interpreters are explicitly refused before assertion-based gates.\n\n## Exact supervised mechanical execution refinement\n\nThe directly attached `execution-bundle.json` contains the exact helper source, plan, tests and PENDING receipt template. It replaces the direct raw scan attachment within the twenty-document limit; `published-verification.json` still binds the unchanged actual unfiltered raw scan, raw SBOM and base scan SHA256 values, retained in the owner evidence package. The known inherited fixable MEDIUM remains explicit, with owner T05/risk follow-through. Neither archive nor technical agreement supplies human approval.\n\nThe reviewed protocol basis is owner commit e0359bcb6cdfad9ab3e868054121fe0cebec2d68, with source follow-through9268c9ac0bbee508fe35c0b90dcefef4c24da2f5. The subsequent exact applied helper/packet owner commit must be named in the externally verified founder receipt before execution. Verify the four committed Git blobs (admission.candidate.json, service.candidate.json, kustomization.yaml, registries.candidate.json) against execution-plan.json as well as current worktree/HEAD; reject overrides/plugins/multiple Application sources and any present automated configuration, including automated:{}.\n\nRoot freshly authenticates the exact confirmed founder person/platform-root ACCEPT of this stable memo/version1 at the fixed native Informed Decision origin before each phase, and supplies protected0600 receipt/outcome files. The helper checks their exact relation and freshness120seconds; these files are supervised bookkeeping, not signed authenticated grants, a human-provider implementation, or autonomous agent authority. Do not derive them from technical reviews or caller assertions.\n\nFixed order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. A separate recorded release attempt permits rollback → rollback-verify. Every phase fsyncs an attempt nonce/RUNNING journal before effects. Failure/interruption/ambiguous actuation stays UNCERTAIN and the same phase cannot be retried. No improvised adapter or whole-Application sync is permitted.\n\nThe NEW nonce-labelled local volume requires one explicit isolated initializer as UID0:0 with only CAP_CHOWN, exact763c image, --network none --read-only --cpus 1 --memory 128m --cap-drop ALL --cap-add CHOWN --security-opt no-new-privileges. Its only mount is that new named volume at /restore; no host mount, native PVC, runtime config or token mount. Protected snapshot stdin goes only to a unique0600 main file with exact digest, and directory/file custody is set0700/0600 UID/GID10001. Then all pre-open, admin and post-admin checks run UID10001:10001, capabilities dropped, networknone. The second stdlib readonly schema5/integrity/count proof after admin must exactly equal the frozen snapshot proof; independently recheck the retained original protected snapshot SHA. No service startup occurs.\n\nRollback dispatch must be available if the candidate is unready or cannot start: it checks sealed Deployment/CM/PVC custody, only prior/candidate source/image pair, node health/headroom and fresh old-image server admission plus Application UID/resourceVersion/source CAS, with no failing candidate Pod/exec/database prerequisite. Dispatch acknowledgment is not recovered health. `rollback-verify` separately requires old image Ready1, succeeded exact Deployment-only/prune=false operation and readonly schema5/integrity/count proof of the latest retained live database. No snapshot replaces the current database.\n\n**Deadline refinement:** all phases, including rollback and verification, must begin before2026-10-12T23:59:59Z. The earlier amended packet described unstarted-release expiry; this exact helper also bounds recovery/verification. Start early enough to complete the bounded drill and any recovery within the window. If exhausted, stop and obtain a fresh founder decision rather than silently extend a grant. This may delay recovery and is an explicit operational risk. No timer/controller automatically rolls back or changes service at expiry.\n" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "media_type": "application/json", + "content": "{\n \"id\": \"INFD-RISK-20261011-ZLIB-85091\",\n \"kind\": \"owner-vulnerability-follow-through\",\n \"owner\": \"informed-decision\",\n \"task\": \"INFD-WP-0009-T05\",\n \"status\": \"open\",\n \"created\": \"2026-10-11\",\n \"review_due\": \"2026-10-18\",\n \"finding\": \"CVE-2026-85091\",\n \"scanner_severity\": \"MEDIUM\",\n \"estate_risk_grade\": null,\n \"affected_package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"actual_current_base_and_candidate_findings_identical\": true,\n \"source_evidence\": \"security-summary.json, trivy-full.json, base-trivy-full.json\",\n \"human_temporary_disposition\": \"pending\",\n \"follow_through\": \"Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload\",\n \"manual_review_expiry\": \"Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed\",\n \"close_condition\": \"Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition\"\n}\n" + }, + { + "item_id": "native-preflight-json", + "media_type": "application/json", + "content": "{\n \"captured_at\": \"2026-10-11T01:25:38.793555+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true\n}\n" + }, + { + "item_id": "sealed-live-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"revisionHistoryLimit\": 10,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"imagePullPolicy\": \"IfNotPresent\",\n \"livenessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\",\n \"protocol\": \"TCP\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\",\n \"protocol\": \"TCP\"\n }\n ],\n \"readinessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"terminationMessagePath\": \"/dev/termination-log\",\n \"terminationMessagePolicy\": \"File\",\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"dnsPolicy\": \"ClusterFirst\",\n \"restartPolicy\": \"Always\",\n \"schedulerName\": \"default-scheduler\",\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccount\": \"review\",\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "change-guard-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only exact Deployment and admission boundaries; no mutation authority.\"\"\"\nimport copy\nimport hashlib\nimport json\n\nBASE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'\nCANDIDATE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\n\n\ndef dependency_projection(configmap, pvc):\n if (configmap.get('kind') != 'ConfigMap' or configmap.get('immutable') is not True\n or configmap['metadata']['namespace'] != 'informed-decision'\n or configmap['metadata']['name'] != 'informed-decision-runtime-6c221878d051'\n or set(configmap.get('data', {})) != {'runtime.json'}\n or configmap.get('binaryData')):\n raise ValueError('unexpected immutable runtime config identity')\n if (pvc.get('kind') != 'PersistentVolumeClaim'\n or pvc['metadata']['namespace'] != 'informed-decision'\n or pvc['metadata']['name'] != 'informed-decision-data'\n or pvc.get('status', {}).get('phase') != 'Bound'\n or not pvc.get('spec', {}).get('volumeName')):\n raise ValueError('unexpected bound PVC custody')\n config = projection(configmap)\n config.pop('data')\n config['canonical_data_sha256'] = hashlib.sha256(json.dumps(\n configmap['data'], sort_keys=True, separators=(',', ':')).encode()).hexdigest()\n return {'configmap': config, 'pvc': projection(pvc), 'pvc_phase': 'Bound'}\n\n\ndef check_dependencies(configmap, pvc, sealed):\n if dependency_projection(configmap, pvc) != sealed:\n raise ValueError('runtime config or PVC identity/custody changed')\n\n\ndef projection(value):\n value = copy.deepcopy(value)\n value.pop('status', None)\n for key in ('resourceVersion', 'generation', 'creationTimestamp', 'managedFields'):\n value['metadata'].pop(key, None)\n for key in ('kubectl.kubernetes.io/last-applied-configuration', 'deployment.kubernetes.io/revision'):\n value['metadata'].get('annotations', {}).pop(key, None)\n return value\n\n\ndef check_current(current, sealed):\n if projection(current) != sealed:\n raise ValueError('sealed live UID or configuration changed')\n\n\ndef check_admitted(admitted, sealed):\n expected = copy.deepcopy(sealed)\n containers = expected['spec']['template']['spec']['containers']\n if len(containers) != 1 or containers[0]['name'] != 'informed-decision' or containers[0]['image'] != BASE:\n raise ValueError('unexpected baseline container identity')\n containers[0]['image'] = CANDIDATE\n if projection(admitted) != expected:\n raise ValueError('admission changed configuration beyond the sole image pin')\n\n\ndef transport_result(exit_code, output):\n import json\n try:\n value = json.loads(output)\n except (ValueError, TypeError):\n return {'all_checks_pass': False, 'reason': 'invalid transport result'}\n if exit_code != 0 or not isinstance(value, dict) or value.get('all_checks_pass') is not True:\n return {'all_checks_pass': False, 'reason': 'read-only preflight refused'}\n return value\n" + }, + { + "item_id": "preflight-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only refresh; exact original capture remains immutable; never execute cutover.\"\"\"\nimport argparse,hashlib,json,subprocess,sys\nfrom pathlib import Path\nif sys.flags.optimize:\n raise SystemExit(\"optimized interpreter refused before source/transport execution\")\nROOT=Path(__file__).resolve().parent\np=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args()\nout=a.receipt_output.resolve()\nif not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists():\n raise SystemExit('unique execution receipt must be outside the sealed packet')\ninputs=json.loads((ROOT/'preflight-inputs.json').read_text())\nfor relative,digest in inputs['packet_files'].items():\n path=ROOT/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed')\nfor relative,digest in inputs['owner_source_files'].items():\n path=a.source_root/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed')\nfrom change_guard import transport_result\nprogram='import subprocess,json,hashlib,datetime,sys,copy,re\\nif sys.flags.optimize:raise RuntimeError(\"optimized interpreter refused\")\\ncandidate=json.loads(CANDIDATE_LITERAL)\\nsealed_dependencies=json.loads(DEPENDENCIES_LITERAL)\\nsealed_baseline=json.loads(SEALED_LITERAL)\\nexec(GUARD_LITERAL)\\ndef run(args,data=None):\\n p=subprocess.run(args,input=data,text=True,capture_output=True)\\n if p.returncode: raise ValueError(\\'read-only command failed: \\'+args[1]+\\' \\'+args[2])\\n return p.stdout\\nlive=json.loads(run([\\'kubectl\\',\\'get\\',\\'deployment\\',\\'informed-decision\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncm=json.loads(run([\\'kubectl\\',\\'get\\',\\'configmap\\',\\'informed-decision-runtime-6c221878d051\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\npvc=json.loads(run([\\'kubectl\\',\\'get\\',\\'pvc\\',\\'informed-decision-data\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncheck_dependencies(cm,pvc,sealed_dependencies)\\ncheck_current(live,sealed_baseline)\\nspec=live[\\'spec\\']; cs=spec[\\'template\\'][\\'spec\\'][\\'containers\\'];assert len(cs)==1 and cs[0][\\'name\\']==\\'informed-decision\\'\\nexpected_env={\\'INFD_KEYCAPE_ISSUER\\':\\'https://kc.coulomb.social\\',\\'INFD_CONTAINER_CONFIG\\':\\'/configuration/runtime.json\\'}\\nassert cs[0].get(\\'env\\')==[{\\'name\\':\\'INFD_KEYCAPE_ISSUER\\',\\'value\\':expected_env[\\'INFD_KEYCAPE_ISSUER\\']},{\\'name\\':\\'INFD_CONTAINER_CONFIG\\',\\'value\\':expected_env[\\'INFD_CONTAINER_CONFIG\\']}]\\nassert cs[0][\\'image\\']==\\'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\'\\nassert spec[\\'replicas\\']==1 and spec[\\'strategy\\']=={\\'type\\':\\'Recreate\\'}\\nassert next(v for v in spec[\\'template\\'][\\'spec\\'][\\'volumes\\'] if v[\\'name\\']==\\'configuration\\')[\\'configMap\\'][\\'name\\']==\\'informed-decision-runtime-6c221878d051\\'\\nassert live[\\'status\\'].get(\\'readyReplicas\\')==1 and live[\\'status\\'].get(\\'updatedReplicas\\')==1\\nsealed={\\'apiVersion\\':live[\\'apiVersion\\'],\\'kind\\':live[\\'kind\\'],\\'metadata\\':{k:copy.deepcopy(v) for k,v in live[\\'metadata\\'].items() if k not in (\\'resourceVersion\\',\\'generation\\',\\'creationTimestamp\\',\\'managedFields\\')},\\'spec\\':copy.deepcopy(spec)}\\nfor key in (\\'kubectl.kubernetes.io/last-applied-configuration\\',\\'deployment.kubernetes.io/revision\\'):sealed[\\'metadata\\'].get(\\'annotations\\',{}).pop(key,None)\\nadmitted=json.loads(run([\\'kubectl\\',\\'apply\\',\\'--dry-run=server\\',\\'-f\\',\\'-\\',\\'-o\\',\\'json\\'],json.dumps(candidate)))\\ncheck_admitted(admitted,sealed_baseline)\\napp=json.loads(run([\\'kubectl\\',\\'get\\',\\'application\\',\\'informed-decision\\',\\'-n\\',\\'argocd\\',\\'-o\\',\\'json\\']))\\nassert app[\\'spec\\'][\\'source\\'][\\'path\\']==\\'deploy/lifecycle\\' and not app[\\'spec\\'].get(\\'syncPolicy\\',{}).get(\\'automated\\')\\nargo={\\'uid\\':app[\\'metadata\\'][\\'uid\\'],\\'repoURL\\':app[\\'spec\\'][\\'source\\'][\\'repoURL\\'],\\'targetRevision\\':app[\\'spec\\'][\\'source\\'][\\'targetRevision\\'],\\'path\\':app[\\'spec\\'][\\'source\\'][\\'path\\'],\\'destination\\':app[\\'spec\\'][\\'destination\\'],\\'automated\\':False,\\'sync\\':app.get(\\'status\\',{}).get(\\'sync\\'),\\'health\\':app.get(\\'status\\',{}).get(\\'health\\')}\\nexpected_argo=json.loads(ARGO_LITERAL)\\nfor key in (\\'uid\\',\\'repoURL\\',\\'targetRevision\\',\\'path\\',\\'destination\\',\\'automated\\'):\\n assert argo[key]==expected_argo[key]\\nassert argo[\\'health\\'][\\'status\\']==\\'Healthy\\'\\ndiff=subprocess.run([\\'kubectl\\',\\'diff\\',\\'-f\\',\\'-\\'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\\nnode=run([\\'kubectl\\',\\'describe\\',\\'node\\']);allocated=re.search(r\\'Allocated resources:.*?CPU Requests|Allocated resources:\\',node,re.S)\\nsection=node.split(\\'Allocated resources:\\')[1].split(\\'Events:\\')[0] if \\'Allocated resources:\\' in node else \\'\\'\\nnodes=json.loads(run([\\'kubectl\\',\\'get\\',\\'nodes\\',\\'-o\\',\\'json\\']))[\\'items\\'];assert len(nodes)==1\\nalloc=nodes[0][\\'status\\'][\\'allocatable\\'];cpu=alloc[\\'cpu\\'];cpu_m=int(cpu[:-1]) if cpu.endswith(\\'m\\') else int(cpu)*1000\\nrequested=int(re.search(r\\'cpu\\\\s+(\\\\d+)m\\',section).group(1));assert requested<=cpu_m\\nreceipt={\\'node_allocatable_cpu_m\\':cpu_m,\\'node_requested_cpu_m\\':requested,\\'captured_at\\':datetime.datetime.now(datetime.timezone.utc).isoformat(),\\'native_workload_changed\\':False,\\'native_backup_restore_executed\\':False,\\'argo\\':argo,\\'native_dependencies_checked\\':True,\\'configmap_uid\\':cm[\\'metadata\\'][\\'uid\\'],\\'pvc_uid\\':pvc[\\'metadata\\'][\\'uid\\'],\\'live_ready_replicas\\':1,\\'admitted_uid\\':admitted[\\'metadata\\'][\\'uid\\'],\\'server_dry_run_passed\\':True,\\'admitted_spec_exactly_live_plus_image\\':True,\\'client_diff_exit\\':diff.returncode,\\'client_diff_sha256\\':hashlib.sha256(diff.stdout.encode()).hexdigest(),\\'node_allocated_resources\\':section.strip(),\\'all_checks_pass\\':True}\\nprint(json.dumps(receipt))\\n'\nfor marker,value in [('DEPENDENCIES_LITERAL',(ROOT/'sealed-native-dependencies.json').read_text()),('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]:\n program=program.replace(marker,repr(value))\nprogram='import traceback,json\\ntry:\\n'+''.join(' '+line+'\\n' for line in program.splitlines())+\"except Exception as error:\\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\\n\"\nr=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True)\nresult=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True\nout.write_text(json.dumps(result,indent=2)+'\\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1)\n" + }, + { + "item_id": "preflight-inputs-json", + "media_type": "application/json", + "content": "{\n \"packet_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"preflight.py\": \"6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"native-preflight.json\": \"eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\"\n }\n}\n" + }, + { + "item_id": "fresh-preflight-validation-json", + "media_type": "application/json", + "content": "{\n \"node_allocatable_cpu_m\": 4000,\n \"node_requested_cpu_m\": 3460,\n \"captured_at\": \"2026-10-11T01:39:14.234277+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"native_dependencies_checked\": true,\n \"configmap_uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\",\n \"pvc_uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\",\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"840769c7d2a9c1655c40a3259f833d1fc8f69950ceb3bedb707a955fed711566\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true,\n \"sealed_preflight_inputs_sha256\": \"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\",\n \"fresh_execution_receipt\": true\n}\n" + } + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json new file mode 100644 index 0000000..1df1d5b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/lifecycle-commands.json @@ -0,0 +1,277 @@ +[ + { + "id": "infd-20261011-purpose-overlay-r1", + "register": { + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 1, + "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "documents": [ + { + "digest": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6", + "media_type": "text/markdown", + "content_base64": "IyBJbmZvcm1lZCBEZWNpc2lvbiBwdXJwb3NlIG92ZXJsYXkgcmVsZWFzZQoKIyMgUmVxdWVzdGVkIGRlY2lzaW9uCgpBcHByb3ZlIHRoZSBleGFjdCBwdXJwb3NlLW9ubHkgaW1hZ2Ugcm9sbG91dCBhbmQgcHJvdGVjdGVkIHJlYWwtZGF0YSBiYWNrdXAvcmVzdG9yZSBwcm90b2NvbCBmb3IgdGhlIGV4aXN0aW5nIEluZm9ybWVkIERlY2lzaW9uIHNlcnZpY2Ugb24gcmFpbGlhbmNlMDEuIFRoaXMgcmVxdWVzdCBpcyBzZXBhcmF0ZSBmcm9tIHRoZSBhbHJlYWR5IGFwcHJvdmVkIGNvbmZpZy1vbmx5IHJlcGFpci4gT25seSB0aGUgZXhpc3RpbmcgRGVwbG95bWVudCBpbWFnZSBjaGFuZ2VzIHRocm91Z2ggdGhlIG93bmVyJ3MgbWFudWFsIEFyZ28gd29ya2Zsb3csIHdpdGggcHJ1bmUgZGlzYWJsZWQuIFJ1bnRpbWUgQ29uZmlnTWFwIGBpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MWAsIHNjaGVtYTUsIFBWQywgY3JlZGVudGlhbHMsIGF1ZGllbmNlLCBwb2xpY2llcywgcmVnaXN0cmllcywgYWNjZXNzLCByZXBsaWNhMSBhbmQgUmVjcmVhdGUgc3RyYXRlZ3kgcmVtYWluIGZpeGVkLiBFeGVjdXRlIGJ5IDIwMjYtMTAtMTJUMjM6NTk6NTlaLCBhZnRlciByZWZyZXNoZWQgc2VhbGVkLXNvdXJjZS9VSUQvY29uZmlndXJhdGlvbiBjaGVja3MgYW5kIGJhY2t1cC9yZXN0b3JlIGdhdGVzLiBBbGwgcGhhc2VzLCBpbmNsdWRpbmcgcmVjb3ZlcnkgYW5kIHZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUgdGhpcyBkZWFkbGluZS4gSWYgdGhlIHdpbmRvdyBpcyBleGhhdXN0ZWQsIHN0b3AgYW5kIG9idGFpbiBhIGZyZXNoIGZvdW5kZXIgZGVjaXNpb247IHRoaXMgbWF5IGRlbGF5IHJlY292ZXJ5LiBObyB0aW1lci9jb250cm9sbGVyIGF1dG9tYXRpY2FsbHkgY2hhbmdlcyB0aGUgcmVsZWFzZWQgaW1hZ2UuCgojIyBBcnRpZmFjdCBhbmQga25vd24gZmluZGluZwoKQWN0dWFsIG93bmVyIENJIHRhc2sxMTQ4NC9ydW4zIHB1Ymxpc2hlZCBpbW11dGFibGUgaW1hZ2UgYHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhYCBmcm9tIHNvdXJjZSBgM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OGAuIEFub255bW91cyByZWdpc3RyeSB2ZXJpZmljYXRpb24gcHJlc2VydmVzIGFsbCBlaWdodCBiYXNlIGNvbXByZXNzZWQgYmxvYnMvcm9vdGZzIGxheWVycyBhbmQgYWRkcyBvbmx5IHBvbGljeS5weSB3aXRoIGV4YWN0IHNvdXJjZSBoYXNoIGFuZCBtb2RlMDY0NC4gTGVnYWN5LWJ1aWxkZXIgbWVkaWEtdHlwZS9kZWZhdWx0IGNvbmZpZyBzZXJpYWxpemF0aW9uIGRpZmZlcmVuY2VzIGFyZSByZWNvcmRlZDsgdGhlIHJ1bnRpbWUgc2VtYW50aWNzIHJlbWFpbiB1bmNoYW5nZWQuIFB1bGxlZCBwdWJsaXNoZWQgaW1hZ2UgZXhlY3V0ZXMgYXMgVUlEMTAwMDEvR0lEMTAwMDEgYW5kIHBhc3NlcyB0ZW4gaW5zdGFsbGVkIGNoZWNrczogdHdvIHN1cHBvcnRlZCBiaW5kaW5nIGZvcm1zLCBlaWdodCBhZHZpc29yeS9tYWxmb3JtZWQgcmVmdXNhbHMuIFRlc3RzIHVzZSBzeW50aGV0aWMgdHJhbnNwb3J0IGFuZCBkbyBub3QgY2xhaW0gbmV3IG5hdGl2ZSBQRFAgYXV0aG9yaXphdGlvbiBwcm9vZi4gVGhlIHR3byBmYWlsZWQgQ0kgYXR0ZW1wdHMgcmVtYWluIGluIHRoZSBzYW1lIHRyaWFsIGhpc3RvcnkuCgpBY3R1YWwgdW5maWx0ZXJlZCBwaW5uZWQgc2Nhbm5lci9EQiBldmlkZW5jZSBjb3ZlcnM0NHBhY2thZ2VzOiB6ZXJvIEhJR0gvQ1JJVElDQUwsICoqb25lIGZpeGFibGUgTUVESVVNKiosIENWRS0yMDI2LTg1MDkxLCB6bGliMS4zLjItcjAgZml4ZWQgaW4xLjMuMi1yMS4gQWN0dWFsIGN1cnJlbnQtYmFzZSBzY2FuIGhhcyB0aGUgaWRlbnRpY2FsIGZpbmRpbmcuIEFwcHJvdmluZyB0aGlzIHBhY2tldCBleHBsaWNpdGx5IHBlcm1pdHMgdGhpcyBpbmhlcml0ZWQgZmluZGluZyBkdXJpbmcgdGhpcyBuYXJyb3cgcHVycG9zZSByZWxlYXNlOyBpdCBpcyBub3QgYSBSaXNrTmV4dXMgZXN0YXRlIHJpc2sgZ3JhZGUgb3IgemVyby1DVkUgY2xhaW0uIE93bmVyIHJlY29yZCBJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSBhbmQgbGl2ZSB0YXNrIElORkQtV1AtMDAwOS1UMDUgcmVxdWlyZSBzZXBhcmF0ZSBiYXNlIHJlZnJlc2ggYW5kIG5hdGl2ZSBhcHByb3ZhbCwgcmV2aWV3ZWQgYnkyMDI2LTEwLTE4LiBUaGF0IHJldmlldyBkYXRlIGlzIG1hbnVhbCBmb2xsb3ctdGhyb3VnaCwgd2l0aCBubyBhdXRvLWNvbnRyb2xsZXIgY2xhaW0uIFNjYW5uZXIgbm90ZXMgQWxwaW5lMy4yNCBhYnNlbnQgRU9MIGxpc3Q7IE9TIHZ1bG5lcmFiaWxpdHkgZGV0ZWN0aW9uIHJhbiBhZ2FpbnN0MzhPU3BhY2thZ2VzLiBVbmtub3duIHZ1bG5lcmFiaWxpdGllcyByZW1haW4gb3V0c2lkZSBzbmFwc2hvdCBrbm93bGVkZ2UuCgojIyBOYXRpdmUgYmFzZWxpbmUgYW5kIGdhdGVzCgpPcmlnaW5hbCByZWFkLW9ubHkgY2FwdHVyZTAxOjI1OjM4WjogZXhpc3RpbmcgRGVwbG95bWVudCBVSURhNTg4ZTEwYSwgUmVhZHkxLCBpbWFnZTdmNWMsIHVuY2hhbmdlZCBydW50aW1lNmM7IG5hdGl2ZSBhZG1pc3Npb24gcHJlc2VydmVzIHRoZSBmdWxsIGNvbmZpZ3VyYXRpb24gcGx1cyBleGFjdGx5IHRoZSBwcm9wb3NlZCBpbWFnZS4gQ2xpZW50ZGlmZiByZXR1cm5zMS4gUmVxdWVzdHMzNDYwLzQwMDBtQ1BVODYlLCBtZW1vcnk5NDcyTWk1OSU7IHJlZnJlc2ggYmVmb3JlIHJlbGVhc2UuIEV4aXN0aW5nIEFyZ28gQXBwbGljYXRpb24gVUlENDk5ODY4ZjIgaXMgbWFudWFsLCB0YXJnZXQ3ZGI4NDg1LCBIZWFsdGh5IHdpdGggcHJlLWV4aXN0aW5nIE91dE9mU3luYyBzdGF0dXMuIERvIG5vdCB0cmVhdCBhIHNjb3BlZCBEZXBsb3ltZW50IHJlbGVhc2UgYXMgZnVsbC1hcHAgcmVjb25jaWxpYXRpb24uIFByZXNlcnZlIGl0cyB0cmFja2luZy1pZDsgbm8gdW5yZWxhdGVkIHJlc291cmNlIHN5bmMvcHJ1bmUvYWRvcHRpb24uCgpUaGUgcmVmaW5lZCByZWFkLW9ubHkgaGVscGVyIGJpbmRzIG9yaWdpbmFsIHNvdXJjZS9oZWxwZXIvcmVuZGVyL2Jhc2VsaW5lIGhhc2hlcyBhbmQgYWN0dWFsIGltbXV0YWJsZSBDb25maWdNYXAvUFZDIFVJRHMsIHJ1bnRpbWUtZGF0YSBjaGVja3N1bSBhbmQgYm91bmQgdm9sdW1lIGlkZW50aXR5LCBleHBsaWNpdGx5IHJlZnVzZXMgb3B0aW1pemVkIGludGVycHJldGVycywgY2hlY2tzIGV4YWN0IGZyZXNoIGxpdmUgVUlEL2NvbmZpZ3VyYXRpb24gYW5kIGFkbWlzc2lvbiwgYW5kIHdyaXRlcyBhIHNlcGFyYXRlIGV4ZWN1dGlvbiByZWNlaXB0IG91dHNpZGUgdGhpcyBzZWFsZWQgcGFja2V0LiBGYWlsZWQgaW5pdGlhbCByYXcgS3VzdG9taXplIG1ldGFkYXRhIGNoZWNrIGlzIHJldGFpbmVkOiBkaXJlY3Qga3ViZWN0bCBhcHBseSB3b3VsZCBkcm9wIEFyZ28gdHJhY2tpbmctaWQuIFRoZSByZXZpZXdlZCBzZWxlY3RlZCBEZXBsb3ltZW50IGV4cGxpY2l0bHkgcmV0YWlucyB0aGF0IGV4aXN0aW5nIElELCBtYXRjaGluZyBBcmdvIG93bmVyc2hpcC4gQW55IHVucmVsYXRlZCBkcmlmdCwgZGlmZmVyZW50IFVJRCwgYWx0ZXJlZCBhZG1pc3Npb24sIHVuYXZhaWxhYmxlIHByb3RlY3RlZCBiYWNrdXAgY2FwYWNpdHksIHVuY2VydGFpbiBiYWNrdXAsIHJlc3RvcmUgbWlzbWF0Y2ggb3IgdW5oZWFsdGh5IGJhc2VsaW5lIHN0b3BzIHRoZSByZWxlYXNlLgoKIyMgUHJvdGVjdGVkIGJhY2t1cCBhbmQgcmVsZWFzZQoKQmVmb3JlICoqYW55KiogbmF0aXZlIHNvdXJjZSBvciBvZmZsaW5lLXJlc3RvcmVkIFN0b3JlL2FkbWluIG9wZW4sIHVzZSB0aGUgYXR0YWNoZWQgc3RkbGliIFNRTGl0ZSBtb2RlPXJvL3F1ZXJ5X29ubHkgY2hlY2tlciB0byByZXF1aXJlIHNjaGVtYTUsIGludGVncml0eT1vayBhbmQgY291bnQtb25seSBiYXNlbGluZS4gVGhlIGFkbWluIGF1dG9tYXRpY2FsbHkgbWlncmF0ZXMgb2xkc2NoZW1hcywgc28gYSBwb3N0LW9wZW4gcmVwb3J0IGFsb25lIGNhbm5vdCBwcm92ZSBubyBtaWdyYXRpb24uIFJlZnVzZSBvdGhlciBzY2hlbWFzIGJlZm9yZSBhZG1pbi4gVGhlbiB1c2UgdGhlIGV4aXN0aW5nIG93bmVyIGFkbWluJ3MgU1FMaXRlIGJhY2t1cCBBUEksIG5vdCBhIHJhdyBjb3B5IG9mIHRoZSBsaXZlIGRhdGFiYXNlL1dBTC4gUHJvdGVjdCBkaXJlY3RvcmllczA3MDAvZmlsZXMwNjAwLCBvd25lZCBieTEwMDAxLiBSZXRhaW4gaW5kZXBlbmRlbnRseSBwcm90ZWN0ZWQgb2ZmLWNsdXN0ZXIgc25hcHNob3QgY3VzdG9keSBhbmQgb25seSBjb3VudC9oYXNoIHJlY2VpcHRzLiBObyBkYXRhYmFzZSBjb250ZW50cywgY2FsbGVyIHRva2VucywgcmVxdWVzdGVyIFNlY3JldCBvciBydW50aW1lIGNyZWRlbnRpYWwgZmlsZXMgZW50ZXIgR2l0LCBTdGF0ZSBIdWIsIGxvZ3Mgb3IgdGhpcyBwYWNrZXQuIE5hdGl2ZSBiYWNrdXAgYW5kIG9mZmxpbmUgcmVhbC1kYXRhIHJlc3RvcmUgaGF2ZSBub3QgeWV0IG9jY3VycmVkLiBVc2UgYW4gaXNvbGF0ZWQgcHJpdmF0ZSBkaXNwb3NhYmxlIGNvcHksIG5ldHdvcmtub25lIGFuZCBubyBydW50aW1lIGNvbmZpZy90b2tlbiBtb3VudHMsIHJ1biB0aGUgcHJlLW9wZW4gY2hlY2tlciBhbmQgZXhhY3Qgb2ZmbGluZSBgLS1lbnRyeXBvaW50IGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGluc3BlY3QgLS1kYiAvcmVzdG9yZS9yZXZpZXcuc3FsaXRlYCBhZnRlciBpdCBwYXNzZXMsIGNvbXBhcmluZyBmcm96ZW4gc25hcHNob3QgY291bnRzIHdpdGhvdXQgc2VydmljZSBzdGFydHVwLCB0aGVuIGNsZWFuIG9ubHkgdGhlIGRpc3Bvc2FibGUgcmVzdG9yZWQgY29weS4gUmV0YWluIHRoZSBvcmlnaW5hbCBzbmFwc2hvdC4gVGhlIGF0dGFjaGVkIHByb3RvY29sIGJpbmRzIGNhc2Utc3BlY2lmaWMgcGF0aHMgYW5kIGZhaWwtY2xvc2VkIGNhcGFjaXR5L2N1c3RvZHkgY2hlY2tzLgoKUmVmcmVzaCBhIGNvbnNpc3RlbnQgb25saW5lIHNuYXBzaG90IGltbWVkaWF0ZWx5IGJlZm9yZSBpbWFnZS1vbmx5IGN1dG92ZXIuIFRoaXMgcHJvdG9jb2wgZG9lcyBub3QgYXNzZXJ0IHRyYWZmaWMvZGlzcGF0Y2hlciBxdWllc2NlbmNlLiBDdXJyZW50IGFuZCBjYW5kaWRhdGUgc2hhcmUgc2NoZW1hNSBhbmQgdW5jaGFuZ2VkIHN0b3JlIGNvZGU7IHJvbGxiYWNrIHJldGFpbnMgdGhlIGxhdGVzdCBsaXZlIGRhdGFiYXNlIGFuZCBhbGwgbmV3L3VuY2VydGFpbiBldmlkZW5jZS4gU3RvcCB0aGUgb2xkIHdyaXRlciBiZWZvcmUgdGhlIG5ldyBvbmUgd2l0aCBleGlzdGluZyBSZWNyZWF0ZSBhbmQgc2luZ2xlLXdyaXRlciBsb2NrLiBEbyBub3QgcmVzdG9yZSBhbiBvbGRlciBzbmFwc2hvdCBvdmVyIGxhdGVyIHdyaXRlcywgZGlzY2FyZCB1bnJlc29sdmVkIGV4dGVybmFsIGVmZmVjdHMsIHNjYWxlIG90aGVyIHdvcmtsb2FkcywgY2hhbmdlIHBvbGljaWVzL2lkZW50aXR5L2N1c3RvZHksIG9yIGNyZWF0ZSBodW1hbiBkaXNwb3NpdGlvbnMgdG8gbWFrZSBjaGVja3MgZ3JlZW4uCgpQaW4gdGhlIGV4aXN0aW5nIEFwcGxpY2F0aW9uIHRvIHRoZSBleGFjdCBvd25lciBjb21taXQgY29udGFpbmluZyB0aGUgYXBwcm92ZWQgY2FuZGlkYXRlIHNvdXJjZSBoYXNoZXMsIGFuZCBtYW51YWxseSBzeW5jIG9ubHkgRGVwbG95bWVudC9pbmZvcm1lZC1kZWNpc2lvbiB3aXRoIHBydW5lPWZhbHNlLiBWZXJpZnkgYWN0dWFsaW1hZ2UvbW9kdWxlL21vZGUvVUlELCBoZWFsdGgvcmVhZGluZXNzIGFuZCBpbnN0YWxsZWQgcHVycG9zZSByZWZ1c2FscyBvbiB0aGUgcmVhbCBwbGFjZW1lbnQ7IGV4cGxpY2l0bHkgZGlzdGluZ3Vpc2ggc3ludGhldGljLXRyYW5zcG9ydCBjaGVja3MgZnJvbSBhY3R1YWwgcHJvdmlkZXIgZXZpZGVuY2UuIEV4aXN0aW5nIG5hdGl2ZSBiaW5kaW5nL2xpZmVjeWNsZSBiZWhhdmlvciBtdXN0IHJlbWFpbiBhdmFpbGFibGUuIElmIHVuaGVhbHRoeSBvciB2ZXJpZmljYXRpb24gZmFpbHMsIHJldHVybiBBcHBsaWNhdGlvbiBzb3VyY2UgdG83ZGI4NDg1IGFuZCBzY29wZWQtc3luYyBwcmlvciBzYW1lLXNjaGVtYSBpbWFnZTdmNWMsIHByZXNlcnZpbmcgY3VycmVudCBldmlkZW5jZSBkYXRhYmFzZTsgcmV0YWluIGZhaWxlZCBvdXRjb21lcy4gQW55IGRhdGEgcmVjb3ZlcnkgYmV5b25kIHRoaXMgc2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sgaXMgYSBzZXBhcmF0ZSBmb3VuZGVyIGRlY2lzaW9uLgoKIyMgQWx0ZXJuYXRpdmVzIGFuZCBlc3RpbWF0ZXMKClByb2NlZWQgd2l0aCB0aGlzIG5hcnJvdyByZWxlYXNlIHBsdXMgZXhwbGljaXQgaW5oZXJpdGVkLW1lZGl1bSBmb2xsb3ctdGhyb3VnaCwgb3IgZGVmZXIgYW5kIHByZXBhcmUgYSBzZXBhcmF0ZSBiYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCBiZWZvcmUgYW55IHJlbGVhc2UuIE5vIGFkZGl0aW9uYWwgcmVjdXJyaW5nIGhvc3RpbmcgaXMgcHJvcG9zZWQ6IGVzdGltYXRlZCBpbmNyZW1lbnRhbCBpbmZyYXN0cnVjdHVyZSBFVVIwLCB3aXRoIHByaXZhdGUgc3RvcmFnZSBhbmQgYXR0ZW5kZWQgZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZC4gUmlza3MgaW5jbHVkZSBhIGJyaWVmIFJlY3JlYXRlIGludGVycnVwdGlvbiwgcHJpdmF0ZSBiYWNrdXAgY3VzdG9keSBlcnJvcnMsIGNhbGxlciByZWZ1c2FsIHdoZW4gYWR2aXNvcnkgcmVzcG9uc2VzIHdlcmUgaW1wcm9wZXJseSB0cmVhdGVkIGFzIGJpbmRpbmcsIGFuZCB0aGUgZGlzY2xvc2VkIGluaGVyaXRlZCBmaW5kaW5nLiBUaGlzIGRlY2lzaW9uIGRvZXMgbm90IHByb21vdGUgYWdlbnQgYXV0b25vbXkgb3IgZ3JhbnQgdW5yZWxhdGVkIHdvcmsuCgojIyBJbmRlcGVuZGVudCByZXZpZXcgcmVmaW5lbWVudHMKClRoZSBpbml0aWFsMzZwYXRoLzIwZG9jdW1lbnQgcGFja2V0IGF0IG1hbmlmZXN0N2M2NzM4YjMgYW5kIHN1Ym1pc3Npb25hYzQxYzhhZSBpcyBwcmVzZXJ2ZWQgaW4gc291cmNlIHByZXBhcmF0aW9uIGV2aWRlbmNlLCB3aXRoIHRoZSBmYWlsZWQvY29uZGl0aW9uYWwgcmV2aWV3LiBJbmRlcGVuZGVudCBQbGF0Zm9ybSByZXZpZXcgaWRlbnRpZmllZCBhZG1pbiBhdXRvLW1pZ3JhdGlvbiwgb3B0aW1pemF0aW9uIGJ5cGFzcywgYW5kIGFjdHVhbCBzYW1lLW5hbWUgQ29uZmlnTWFwL1BWQyByZXBsYWNlbWVudCBnYXBzLiBUaGUgYW1lbmRlZCBwYWNrZXQgYWRkcyBwcmUtb3BlbiBzdGRsaWIgcmVhZC1vbmx5IHNjaGVtYS9pbnRlZ3JpdHkvY291bnQgZ2F0ZXMsIGV4cGxpY2l0IGxvY2FsL3JlbW90ZSBvcHRpbWl6YXRpb24gcmVmdXNhbCwgYW5kIGluZGVwZW5kZW50bHkgc2VhbGVkIGFjdHVhbCBuYXRpdmUgY29uZmlnL1BWQyBjdXN0b2R5IGNoZWNrcy4gVGhlc2UgYXJlIHJlZmluZW1lbnRzIGluIHRoZSBzYW1lIHByb3Bvc2FsL3RyaWFsLCB3aXRoIG5vIG9yaWdpbmFsIG9yIGFtZW5kZWQgZm91bmRlciBhcHByb3ZhbCBjbGFpbWVkLgoKIyMgTWVjaGFuaWNhbGx5IGJvdW5kIGhlbHBlciBhbmQgcmVjb3ZlcnkgcmVmaW5lbWVudAoKVGhlIGRpcmVjdGx5IGF0dGFjaGVkIGV4ZWN1dGlvbi1idW5kbGUuanNvbiBiaW5kcyBleGFjdCBzdXBlcnZpc2VkIGhlbHBlciBzb3VyY2VzLCBwbGFuLCB0ZXN0cyBhbmQgUEVORElORyBhdXRob3JpdHkgdGVtcGxhdGUuIEl0IHZlcmlmaWVzIGFsbCBmb3VyIGNvbW1pdHRlZCBvd25lciBLdXN0b21pemUgaW5wdXRzIGFuZCByZWplY3RzIHByZXNlbnQgYXV0b21hdGVkOnt9IGFzIHdlbGwgYXMgc291cmNlIG92ZXJyaWRlcy4gUm9vdCBtdXN0IGZyZXNobHkgYXV0aGVudGljYXRlIHRoZSBleGFjdCBmb3VuZGVyIG5hdGl2ZSBkaXNwb3NpdGlvbiBiZWZvcmUgZXZlcnkgcGhhc2U7IHJlY2VpcHQgYm9va2tlZXBpbmcgaXMgbm90IGFuIGF1dG9ub21vdXMgc2lnbmVkIGdyYW50LiBUaGUgc2FtZSBwcm9wb3NhbC90cmlhbCBwcmVzZXJ2ZXMgdGhlIGVhcmxpZXIzNnBhdGg3YyBwYWNrZXQsIGFtZW5kZWQ3OHBhdGhiMSBwYWNrZXQgYW5kIG9yaWdpbmFsMTFmaWxlNjUzIGhlbHBlciBwbHVzIGNvbmRpdGlvbmFsIHJldmlldyBmaW5kaW5ncy4KClRoZSBvZmZsaW5lIGNvcHkgdXNlcyBvbmUgVUlEMC9DQVBfQ0hPV04tb25seSBpbml0aWFsaXplciBjb25maW5lZCB0byB0aGUgTkVXIG5vbmNlLWJvdW5kIGxvY2FsIHZvbHVtZSwgZXhhY3QgY2FuZGlkYXRlIGltYWdlLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pLCBubyBob3N0L2xpdmVQVkMvY29uZmlnL3Rva2VuIG1vdW50cy4gQWxsIGZvbGxvd2luZyBwcmUtb3Blbi9hZG1pbi9wb3N0LW9wZW4gY2hlY2tzIGFyZSBVSUQxMDAwMS4gUG9zdC1hZG1pbiByZWFkb25seSBzY2hlbWE1L2ludGVncml0eS9jb3VudHMgbXVzdCBtYXRjaCB0aGUgZnJvemVuIHNuYXBzaG90IGFuZCBvcmlnaW5hbCBzbmFwc2hvdCBTSEEgbXVzdCByZW1haW4gdW5jaGFuZ2VkLiBSb2xsYmFjayBkaXNwYXRjaCBuZXZlciByZXF1aXJlcyB0aGUgZmFpbGluZyBjYW5kaWRhdGUgdG8gYmUgUmVhZHkgb3Igb3BlbnMgaXRzIGRhdGFiYXNlOyBzZWFscy9zb3VyY2UvaW1hZ2UgcGFpci9hZG1pc3Npb24gQ0FTIHN0aWxsIGdhdGUgaXQuIEEgc2VwYXJhdGUgcm9sbGJhY2stdmVyaWZ5IHByb3ZlcyByZWNvdmVyZWQgb2xkLWltYWdlIFJlYWR5MS9zY29wZWQgb3BlcmF0aW9uL3NjaGVtYTUgcmV0YWluZWQtY3VycmVudC1EQiBpbnRlZ3JpdHkuIFNhbWUtcGhhc2UgcmV0cmllcyBhcmUgcmVmdXNlZCBhZnRlciBhbWJpZ3VvdXMgb3V0Y29tZXMuCgpSYXcgc2Nhbi9TQk9NL2Jhc2Utc2NhbiBieXRlcyByZW1haW4gcmV0YWluZWQgdW5jaGFuZ2VkLCBoYXNoLWJvdW5kIGJ5IHRoZSBkaXJlY3RseSBhdHRhY2hlZCBwdWJsaXNoZWQtdmVyaWZpY2F0aW9uIHJlY2VpcHQ7IHRoZSBidW5kbGUgcmVwbGFjZXMgb25seSB0aGUgZGlyZWN0IHJhdyBzY2FuIGF0dGFjaG1lbnQgdG8gc3RheSB3aXRoaW4gdHdlbnR5IGRvY3VtZW50cy4gS25vd24gZml4YWJsZSBpbmhlcml0ZWQgTUVESVVNIGFuZCBUMDUgZm9sbG93LXRocm91Z2ggcmVtYWluIHZpc2libGUuIFRlbiBpbnN0YWxsZWQgc3ludGhldGljIGNoZWNrcywgaW5jbHVkaW5nIHRob3NlIGxhdGVyIG9uIGFjdHVhbCBwbGFjZW1lbnQsIGV4cGxpY2l0bHkgaGF2ZSBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIEFjdHVhbCBwcm92aWRlci9QRFAgYXV0aG9yaXR5IGV2aWRlbmNlIGlzIGEgZGlzdGluY3QgVDA0IGNvbXBsZXRpb24gZ2F0ZSBhbmQgaXMgbm90IHN1cHBsaWVkIGJ5IHRoZXNlIGNoZWNrcy4gU291cmNlIHByZXBhcmF0aW9uIGJhc2lzIGUwMzU5YmNiNmNkZmFkOWFiM2U4NjgwNTQxMjFmZTBjZWJlYzJkNjggcGx1czkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUgaXMgcmVjb3JkZWQ7IHRoZSBmaW5hbCBhcHBsaWVkIG93bmVyIGNvbW1pdCBtdXN0IGJlIHBpbm5lZCBiZWZvcmUgZXhlY3V0aW9uLgo=" + }, + { + "digest": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbF9pZCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgInRyaWFsX2lkIjogImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMSIsCiAgInN0YXRlIjogInByZXBhcmVkLXVuYXBwcm92ZWQiLAogICJ0YXJnZXQiOiAicmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbiIsCiAgImF1dGhvcml0eSI6ICJBRE1JTklTVEVSOyBhY3RpdmF0aW9uIEFQUFJPVkVEIG9ubHkgdXBvbiBleGFjdCBmb3VuZGVyIGRpc3Bvc2l0aW9uIiwKICAiY2FuZGlkYXRlX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYSIsCiAgInB1Ymxpc2hlZF9zb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInByaW9yX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgInByaW9yX2FyZ29fcmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgIm5hdGl2ZV9vYmplY3QiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJhcHBzL3YxIiwKICAgICJraW5kIjogIkRlcGxveW1lbnQiLAogICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAidWlkIjogImE1ODhlMTBhLTkwZDItNDg4My05NzVlLTZkZDhiOGZlY2E5MiIKICB9LAogICJhcmdvX2FwcGxpY2F0aW9uX3VpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICJzb3VyY2VfZ2F0ZSI6ICJBbGwgZm91ciBleGFjdCBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGluIGV4ZWN1dGlvbi1wbGFuLmpzb24gYW5kIGNsZWFuIGN1cnJlbnQgb3duZXIgSEVBRCBtdXN0IG1hdGNoOyBzb3VyY2UgcHJlcGFyYXRpb24gaXMgbm90IG5hdGl2ZSBhcHByb3ZhbCIsCiAgInN5bmNfc2NvcGUiOiBbCiAgICAiYXBwczpEZXBsb3ltZW50OmluZm9ybWVkLWRlY2lzaW9uIgogIF0sCiAgInBydW5lIjogZmFsc2UsCiAgImF1dG9tYXRlZF9zeW5jIjogZmFsc2UsCiAgInJ1bnRpbWVfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAic2NoZW1hIjogNSwKICAicmVxdWVzdGVkX29wZXJhdGlvbnMiOiBbCiAgICAiUHJvdGVjdGVkIFNRTGl0ZS1jb25zaXN0ZW50IG5hdGl2ZSBiYWNrdXAgYW5kIGluZGVwZW5kZW50bHkgcHJvdGVjdGVkIG9mZi1jbHVzdGVyIGN1c3RvZHkiLAogICAgIk9mZmxpbmUgcmVzdG9yZS9pbnRlZ3JpdHkvY291bnQgY29tcGFyaXNvbiBvbiBhIHByaXZhdGUgZGlzcG9zYWJsZSB2b2x1bWUgd2l0aCBleGFjdCBjYW5kaWRhdGUsIG5vIHJ1bnRpbWUgdG9rZW5zL2NvbmZpZy9uZXR3b3JrIiwKICAgICJSZWZyZXNoIGEgY29uc2lzdGVudCBwcmUtY3V0b3ZlciBzbmFwc2hvdCwgcmV0YWluIHByaXZhdGUgY29waWVzIGFuZCBjb3VudC1vbmx5L2hhc2ggcmVjZWlwdHMiLAogICAgIlBpbiBleGlzdGluZyBtYW51YWwgQXJnbyBBcHBsaWNhdGlvbiB0byBleGFjdCBhcHByb3ZlZCBvd25lciBzb3VyY2UgYW5kIG1hbnVhbGx5IHN5bmMgb25seSBleGlzdGluZyBEZXBsb3ltZW50IGltYWdlIiwKICAgICJWZXJpZnkgaGVhbHRoL3JlYWRpbmVzcy9pbWFnZS9tb2R1bGUvaW5zdGFsbGVkIGZhaWwtY2xvc2VkIHB1cnBvc2UgY2hlY2tzIGFuZCByZXRhaW5lZCBzY2hlbWEvY291bnQgZXZpZGVuY2U7IHJlY292ZXIgdG8gcHJpb3Igc2FtZS1zY2hlbWEgaW1hZ2UgaWYgbmVlZGVkIgogIF0sCiAgImV4ZWN1dGVfYnkiOiAiMjAyNi0xMC0xMlQyMzo1OTo1OVoiLAogICJ0ZW1wb3JhcnlfdnVsbmVyYWJpbGl0eV9yZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJrbm93bl9zY2FuX2ZpbmRpbmdzIjogIjBISUdIL0NSSVRJQ0FMLDFmaXhhYmxlIGluaGVyaXRlZE1FRElVTSB6bGliLCBhY3R1YWwgY3VycmVudGJhc2UrY2FuZGlkYXRlIGZpbmRpbmdzIGlkZW50aWNhbCIsCiAgInZ1bG5lcmFiaWxpdHlfcmVjb3JkIjogIklORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxIC8gSU5GRC1XUC0wMDA5LVQwNSIsCiAgImNvc3RfZXN0aW1hdGVfRVVSIjogMCwKICAiY29zdF9saW1pdHMiOiAiTm8gbmV3IHJlY3VycmluZyBpbmZyYXN0cnVjdHVyZTsgcHJpdmF0ZSBiYWNrdXAgc3RvcmFnZSBhbmQgYXR0ZW5kZWQgZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZCwgbm90IGFuIGF1dG9waWxvdCBjb3N0IGdyYW50IiwKICAicmlza19lc3RpbWF0ZXMiOiBbCiAgICAiQnJpZWYgUmVjcmVhdGUgc2VydmljZSBpbnRlcnJ1cHRpb247IG5vIGNvbmN1cnJlbnQgbmV3IHdyaXRlci9zdXJnZSIsCiAgICAiUHJpdmF0ZSBldmlkZW5jZSBzbmFwc2hvdCBjdXN0b2R5IGFuZCBkaXNwb3NhbCBlcnJvcnM7IG5vIHNuYXBzaG90cy90b2tlbnMgaW4gcHVibGljIGV2aWRlbmNlIiwKICAgICJDYW5kaWRhdGUgcHVycG9zZSByZWZ1c2FsIG1heSBleHBvc2UgY2FsbGVycyByZWx5aW5nIG9uIGFkdmlzb3J5IHJlc3VsdHMgYXMgYmluZGluZyIsCiAgICAiSW5oZXJpdGVkIGtub3duIGZpeGFibGUgTUVESVVNIHJlbWFpbnMgdW50aWwgc2VwYXJhdGVseSBhcHByb3ZlZCBvd25lciByZW1lZGlhdGlvbiIsCiAgICAiRXhpc3RpbmcgQXJnbyBPdXRPZlN5bmMgYmFzZWxpbmUgaXMgcmV0YWluZWQ7IG5vIHdob2xlLWFwcCBzeW5jIG9yIHVucmVsYXRlZCByZXBhaXJzIHBlcm1pdHRlZCIsCiAgICAiQWxsIHBoYXNlcywgaW5jbHVkaW5nIHJlY292ZXJ5L3ZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUgT2N0MTIgZGVhZGxpbmU7IGlmIHJlY292ZXJ5IHdpbmRvdyBpcyBleGhhdXN0ZWQgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gTm8gYXV0b21hdGljIGV4cGlyeSBjb250cm9sbGVyLiIKICBdLAogICJyb2xsYmFjayI6ICJNYW51YWwgQXJnbyBzb3VyY2UgcGluIGJhY2sgdG83ZGI4NDg1IGFuZCBzY29wZWQgRGVwbG95bWVudC1vbmx5IHN5bmMgdG83ZjVjIGltYWdlOyByZXRhaW4gY3VycmVudCBzY2hlbWE1IGRhdGFiYXNlIGFuZCBhbGwgcG9zdC1jdXRvdmVyIGV2aWRlbmNlLCBuZXZlciByZXN0b3JlIG9sZGVyIHNuYXBzaG90IG92ZXIgbGl2ZSB3cml0ZXMiLAogICJuYXRpdmVfZXhlY3V0ZWQiOiBmYWxzZSwKICAiaHVtYW5fYXBwcm92YWwiOiBmYWxzZSwKICAicmVmaW5lbWVudF9vZl9tYW5pZmVzdCI6ICI3YzY3MzhiMzllYThlNTRlNjFjOGVkNjI1ZTk0YWQwYjI3NTVlNjcyZTE1NzZlZmNkZjg0YTFkNjY1YWMzMzAwIiwKICAibWFuZGF0b3J5X3ByZV9vcGVuX2dhdGUiOiAic3RkbGliU1FMaXRlIG1vZGU9cm8vcXVlcnlfb25seTogc2NoZW1hNStpbnRlZ3JpdHkrY291bnQgYmFzZWxpbmUgYmVmb3JlIEFOWSBTdG9yZS9hZG1pbiBvbiBuYXRpdmUgc291cmNlIG9yIHJlc3RvcmVkY29weTsgcmVmdXNlb2xkc2NoZW1hcyB3aXRob3V0IG1pZ3JhdGlvbiIsCiAgIm9wdGltaXplZF9pbnRlcnByZXRlcnMiOiAibG9jYWwrcmVtb3RlIGV4cGxpY2l0bHlyZWZ1c2VkIGJlZm9yZWFzc2VydCBnYXRlcyIsCiAgIm5hdGl2ZV9kZXBlbmRlbmN5X2dhdGUiOiAic2VhbGVkIGFjdHVhbENNIFVJRC9pbW11dGFibGUvY2Fub25pY2FsZGF0YWhhc2grUFZDIFVJRC9mdWxsc3BlYy9Cb3VuZC92b2x1bWVOYW1lLCBubyByYXdDTWRhdGEgb3JTZWNyZXQgcmVhZHMiLAogICJsaXZlX2NvdW50cyI6ICJGcm96ZW4gc25hcHNob3QvY2xvbmUgZXhhY3Rjb3VudGVyIGVxdWFsaXR5OyBwb3N0Y3V0b3Zlci9yb2xsYmFjayBsaXZlY291bnRlcmNoYW5nZXMgbWF5IHJlZmxlY3QgbGVnaXRpbWF0ZSBjb25jdXJyZW50Y29tbWl0cy9zdGF0ZSB0cmFuc2l0aW9ucywgbGF0ZXN0REIgYWx3YXlzcmV0YWluZWQiLAogICJzb3VyY2VfYmFzaXMiOiB7CiAgICAicmV2aWV3ZWRfcHJvdG9jb2xfY29tbWl0IjogImUwMzU5YmNiNmNkZmFkOWFiM2U4NjgwNTQxMjFmZTBjZWJlYzJkNjgiLAogICAgIm93bmVyX2ZvbGxvd3Rocm91Z2hfY29tbWl0IjogIjkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUiLAogICAgImZpbmFsX2V4ZWN1dGlvbl9zb3VyY2UiOiAiZXhhY3Qgc3Vic2VxdWVudCByb290LWFwcGxpZWQgc291cmNlIGNvbW1pdCBtdXN0IGJlIGJvdW5kIGJ5IGZvdW5kZXIgcmVjZWlwdCBhbmQgdmVyaWZpZWQgYWdhaW5zdCBmb3VyIGFwcHJvdmVkIEdpdCBibG9icyIKICB9LAogICJhcHByb3ZlZF9vd25lcl9yZW5kZXJfYmxvYl9zaGEyNTYiOiB7CiAgICAiZGVwbG95L2xpZmVjeWNsZS9hZG1pc3Npb24uY2FuZGlkYXRlLmpzb24iOiAiOTIzODJhNTZiMzQ5YzNiODk1ZTU4MDZlOTc1MDgyNTI3YmI5OWQxYTAwMTE0MGU2OWQ4NTdlNWIwMzkxZmE1NSIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uIjogIjM4Yjc4YjljYmVlNWFkZTc3NTBhNThkNTE1NmNhNGM1NzczMzUyZTk0N2FjYjMwNGVlNzE0YjU5ZTc0OWNlYjQiLAogICAgImRlcGxveS9saWZlY3ljbGUva3VzdG9taXphdGlvbi55YW1sIjogIjFiYmNlODFiYzY3NTg0MzQzNTQxNTdmODYwMTUzNDMyMGM1ZDAyOTA1ODc5MDhmZDE1YTZkMjVlM2ZhNTdmNDciLAogICAgImRlcGxveS9saWZlY3ljbGUvcmVnaXN0cmllcy5jYW5kaWRhdGUuanNvbiI6ICI5YmFkNmRiNWZiYzIxNzhkMzFiMDQxMjAwMTZhNDE4MzBjMzU1MmZiYjllMjUxN2I3MThmOWJiZTg3Y2Y2NDllIgogIH0sCiAgImV4ZWN1dGlvbl9idW5kbGVfc2hhMjU2IjogIjI3ZDZkNmQzMTMzYzk2M2RhMWRkZTkyZDQ5OGQ2MzY2MTczODdjMTZlODUwYTE3YzU5ODE0OGFiYzM1Yzc3NWQiLAogICJleGVjdXRpb25faGVscGVyX21hbmlmZXN0X3NoYTI1NiI6ICJmMmZhZDZjMjUxZmJiNDQyMGUwN2MxMzI5ODAyZjUyMWI1MTNiYmY2NmU1MWY2NGM1ZDY3M2VmMDRmMTYyODRjIiwKICAiZXhlY3V0aW9uX3BsYW5fc2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiLAogICJleGVjdXRpb25fcGhhc2VzIjogWwogICAgImRyaWxsLWJhY2t1cCIsCiAgICAiZHJpbGwtY29weSIsCiAgICAib2ZmbGluZS12ZXJpZnkiLAogICAgImNsZWFudXAtb2ZmbGluZSIsCiAgICAiY3V0b3Zlci1iYWNrdXAiLAogICAgImN1dG92ZXItY29weSIsCiAgICAicmVsZWFzZSIsCiAgICAidmVyaWZ5IiwKICAgICJyb2xsYmFjayIsCiAgICAicm9sbGJhY2stdmVyaWZ5IgogIF0sCiAgImRlYWRsaW5lX3NlbWFudGljcyI6ICJBbGwgcGhhc2VzIGluY2x1ZGluZyB2ZXJpZmljYXRpb24vcmVjb3ZlcnkgbXVzdCBiZWdpbiBiZWZvcmUgZXhlY3V0ZV9ieS4gTm8gZXh0ZW5zaW9uIG9yIGF1dG9tYXRpYyBlbWVyZ2VuY3kgZ3JhbnQ7IGJleW9uZCBkZWFkbGluZSBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBDb21wbGV0ZSB0aGUgYm91bmRlZCBkcmlsbCBhbmQgcm9sbG91dCBlYXJseSBlbm91Z2ggdG8gYWxsb3cgcmVjb3Zlcnkgd2l0aGluIHRoZSB3aW5kb3cuIiwKICAib2ZmbGluZV9pbml0aWFsaXplciI6ICJPbmUgaXNvbGF0ZWQgbG9jYWwgVUlEMDowL0NBUF9DSE9XTi1vbmx5IGluaXRpYWxpemVyIG9mIHRoZSBuZXdseSBjcmVhdGVkIG5vbmNlLWJvdW5kIGRpc3Bvc2FibGUgdm9sdW1lLCBleGFjdCBjYW5kaWRhdGUgaW1hZ2UsIG5ldHdvcmtub25lL3JlYWRvbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzL0NQVTEvMTI4TWk7IG5vIGhvc3QvbGl2ZVBWQy90b2tlbi9jb25maWcgbW91bnQuIFN1YnNlcXVlbnQgcHJlLW9wZW4vYWRtaW4vcG9zdC1vcGVuIGNoZWNrcyBVSUQxMDAwMToxMDAwMS4iLAogICJyb2xsYmFja19kaXNwYXRjaCI6ICJTZWFsZWQgRGVwbG95bWVudC9DTS9QVkMgYW5kIHNhbWUtc2NoZW1hIHNvdXJjZS9pbWFnZSBwYWlyIHBsdXMgYWRtaXNzaW9uIENBUzsgbm8gUmVhZHkgY2FuZGlkYXRlIG9yIFBvZC9kYXRhYmFzZSBleGVjIHByZXJlcXVpc2l0ZS4gcm9sbGJhY2stdmVyaWZ5IHNlcGFyYXRlbHkgcHJvdmVzIHJlY292ZXJlZCBvbGQgaW1hZ2UvUmVhZHkxL3Njb3BlZCBvcGVyYXRpb24gYW5kIHJlYWRvbmx5IGN1cnJlbnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzLiIsCiAgInB1cnBvc2VfcHJvb2ZfbGltaXQiOiAiVGVuIGluc3RhbGxlZCBzeW50aGV0aWMtdHJhbnNwb3J0IGNoZWNrcyBvbiBhY3R1YWwgcGxhY2VtZW50OyBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIE5vdCBhY3R1YWwgcHJvdmlkZXIvUERQIGF1dGhvcml0eSBwcm9vZiwgd2hpY2ggcmVtYWlucyBhIGRpc3RpbmN0IFQwNCBjb21wbGV0aW9uIGdhdGUuIiwKICAicmVmaW5lbWVudF9vZl9hbWVuZGVkX21hbmlmZXN0IjogImIxZTNlNjZiYzQwMjNkYzgwYzZlYTU5NTY0YzM1NTdjNzY1M2ZiM2MzMDdmNDZhMDQ5OTk3Yjc2MTk4YTkwMzMiCn0K" + }, + { + "digest": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgIm9ic2VydmVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjQ6MDEuOTg1MTI4KzAwOjAwIiwKICAibmF0aXZlX293bmVyX3B1YmxpY2F0aW9uX2pvYiI6IHsKICAgICJpZCI6IDExNDg0LAogICAgIm5hbWUiOiAicHVibGlzaC1jYW5kaWRhdGUiLAogICAgImhlYWRfYnJhbmNoIjogIm1haW4iLAogICAgImhlYWRfc2hhIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgInJ1bl9udW1iZXIiOiAzLAogICAgImV2ZW50IjogInB1c2giLAogICAgImRpc3BsYXlfdGl0bGUiOiAiUHJlcGFyZSByZWFkYWJsZSBvdmVybGF5IGNvbnRleHQgd2l0aCB0aGUgYWRtaXR0ZWQgbGVnYWN5IGJ1aWxkZXIiLAogICAgInN0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJ3b3JrZmxvd19pZCI6ICJwdXJwb3NlLW92ZXJsYXktaW1hZ2UueWFtbCIsCiAgICAidXJsIjogImh0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uL2FjdGlvbnMvcnVucy8zIiwKICAgICJjcmVhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjA6NTlaIiwKICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjE6MDhaIiwKICAgICJydW5fc3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjIwOjU5WiIKICB9LAogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInBvbGljeV9zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgInJlZ2lzdHJ5X3Byb29mX3NoYTI1NiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAic291cmNlX3JlbmRlcl9jaGFuZ2Vfb25seSI6ICJEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHNwZWMudGVtcGxhdGUuc3BlYy5jb250YWluZXJzWzBdLmltYWdlIiwKICAicnVudGltZV9jb25maWdtYXBfdW5jaGFuZ2VkIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAiaW5zdGFsbGVkX2ltYWdlX2V4ZWN1dGlvbiI6IHsKICAgICJpbW11dGFibGVfcmVnaXN0cnlfYXJ0aWZhY3RfcHVsbGVkX2Fub255bW91c2x5IjogdHJ1ZSwKICAgICJVSUQiOiAxMDAwMSwKICAgICJHSUQiOiAxMDAwMSwKICAgICJwb2xpY3lfZmlsZV9VSUQiOiAwLAogICAgInBvbGljeV9maWxlX21vZGUiOiAiMDY0NCIsCiAgICAicHVycG9zZV92YXJpYW50cyI6IDEwLAogICAgImJpbmRpbmdfZm9ybXNfYWxsb3dlZCI6IDIsCiAgICAiYWR2aXNvcnlfb3JfbWFsZm9ybWVkX3JlZnVzZWQiOiA4LAogICAgIm5ldHdvcmsiOiAibm9uZSIsCiAgICAicmVhZF9vbmx5IjogdHJ1ZSwKICAgICJzeW50aGV0aWNfdHJhbnNwb3J0IjogdHJ1ZSwKICAgICJuYXRpdmVfUERQX3Rlc3QiOiBmYWxzZQogIH0sCiAgInNjYW5fc3VtbWFyeV9zaGEyNTYiOiAiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NCIsCiAgImhpc3RvcmljYWxfZmFpbGVkX3J1bnNfcmV0YWluZWQiOiBbCiAgICAiZjY2ZGU1MDUvdGFzazExNDgyL3J1bjEiLAogICAgImFjZWNhZDg4Ny90YXNrMTE0ODMvcnVuMiIKICBdLAogICJuYXRpdmVfaG9zdGluZ19jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJodW1hbl9hcHByb3ZhbCI6IGZhbHNlLAogICJldmlkZW5jZV9maWxlX3NoYTI1NiI6IHsKICAgICJpbWFnZS1tYW5pZmVzdC5qc29uIjogIjk3OGM1NzVkM2M3YmYwZGUzOWRiZTRlOTU2N2MzOWNkMzZmNzBiN2U1NWJjMTczNTdiZGIwM2ZiM2I5NmIwZmIiLAogICAgImltYWdlLWNvbmZpZy5qc29uIjogIjRhZDcyNDljNzVmZDlmYzAzOWNlYjE4Njc3MjQxOWUxY2JhNWZkOTc1OWM0MDQ1NTY0NTljODBhMmQyODVkMTAiLAogICAgImJhc2UtaW1hZ2UtY29uZmlnLmpzb24iOiAiYjcwNmM5MjA5ZTMyNGYzOWE4NmZmY2RhMmEzZTlkOTRjOTI2NDk3MzlhZDViMjFmZTQ2MTEwMDZlMzZmNmYwMCIsCiAgICAicmVnaXN0cnktcHJvb2YuanNvbiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAgICJ0cml2eS1mdWxsLmpzb24iOiAiZjM4YThmN2U2YzQxOWVlZDkxNTRkNzc2MmY5MzJiOWRlYjY2ODBhNjIyMjQ3YjA4MTk2Yjc0NThiODkzNDM0ZSIsCiAgICAic2JvbS5jZHguanNvbiI6ICJhNDI1Mjk1MWUyMDI3NDcyYzI2ZDg2NzljYjU0M2UzMDk4MzE4MDgwOWQ2ZGQzYzdjOTRiODgzZDYyODAzZTVkIiwKICAgICJiYXNlLXRyaXZ5LWZ1bGwuanNvbiI6ICJkNDRjNTU1YWVjYmIxYTQ1MThmNDEyN2Q0ODAxNWVhNDU5MzI1YzkzZThiMDM3MTkxMGE1NWRlNDcyOTNjYTgwIiwKICAgICJjaGVja19pbnN0YWxsZWQucHkiOiAiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZCIsCiAgICAidmVyaWZ5X3JlZ2lzdHJ5LnB5IjogIjQxM2Y1NzVjMjFhMmJkMThhMzY5NmY4ZjJkOTM5ZWVhZGM1MmQ3NmYyODJjNDI4MTNmNzZiYjBlM2VlOGEyYTQiLAogICAgInNxbGl0ZV9yZWFkb25seS5weSI6ICJlZWY1M2RkMjMzZWVlNzRjMTdmMjA4MjNiZDdmNTc4N2M2MGNhZDc5YWM2NDgwMjFjOTQ3OTY0M2M2Y2U5ZTM4IiwKICAgICJzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uIjogIjA0MjMyN2EwMzZlZDI1NGNmOTVkYmViMGMwNTZhYzI1YjAzYTZhODQ0Yjk1YTMzMmM5OTJkZjI5NDM2OTEzNjkiLAogICAgInJldmlldy1yZWZpbmVtZW50Lmpzb24iOiAiZWE2Mjg0NWNlZTVlZTZmNGY2Y2I3ZjVkY2QwYWY2MDFiYTI5YTIxYzhmZjgwZWZiYmMwMmFkMTZlMzViZWE3NSIsCiAgICAidGVzdF9jaGFuZ2VfZ3VhcmQucHkiOiAiZGE1MzUwNDM3MzU3YmEzMjkyMzZjYzEzNzYxMGMwMzg1NmYzOGY4MzZkZGYyODU2MDI1YmMxMjAxMWZhZDA3ZiIsCiAgICAidGVzdF9zcWxpdGVfcmVhZG9ubHkucHkiOiAiYzdhOTFkMGM2YTM3M2Q3MzhjODhiYjgxN2Q5YmZiMmZmOGExNzliYzYxYjkzMDYzYjg5Njc3YjU2NjUyMDMyMyIsCiAgICAidGVzdF9wcmVmbGlnaHRfb3B0aW1pemF0aW9uLnB5IjogImEwYzRmYTE4YzVkNmMyMTQ3NmEwNmM2ZDA1ZmU3NjU2MjU5ZDIwNDI5OTEzODg1MTU5OWU5MjE0ZDkxMTIwNmQiCiAgfQp9Cg==" + }, + { + "digest": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZV9kaWdlc3QiOiAic2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgImJhc2VfaW1hZ2VfZGlnZXN0IjogInNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAiYmFzZV9sYXllcl9ieXRlc19pZGVudGljYWwiOiB0cnVlLAogICJsYXllcl9tZWRpYV90eXBlX2NvbnZlcnNpb24iOiAiT0NJIGd6aXAgdG8gRG9ja2VyIGd6aXAsIHNhbWUgZGlnZXN0IGFuZCBzaXplIiwKICAiYmFzZV9ydW50aW1lX2NvbmZpZ19zZW1hbnRpY3NfaWRlbnRpY2FsIjogdHJ1ZSwKICAibGVnYWN5X2J1aWxkZXJfY29uZmlnX2FkZGl0aW9ucyI6IHsKICAgICJIb3N0bmFtZSI6ICIiLAogICAgIkRvbWFpbm5hbWUiOiAiIiwKICAgICJBdHRhY2hTdGRpbiI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZG91dCI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZGVyciI6IGZhbHNlLAogICAgIlR0eSI6IGZhbHNlLAogICAgIk9wZW5TdGRpbiI6IGZhbHNlLAogICAgIlN0ZGluT25jZSI6IGZhbHNlLAogICAgIkNtZCI6IG51bGwsCiAgICAiVm9sdW1lcyI6IG51bGwsCiAgICAiT25CdWlsZCI6IG51bGwsCiAgICAiSW1hZ2UiOiAic2hhMjU2OjkwZjE1NzRmOWVkYTM1ZmE2Y2I5NzI5NjFiZWIyN2E3Y2I5MDRjMzY1NjBlMzgxOTMwYjBlMTQwNjVjMjM4ODMiCiAgfSwKICAiYmFzZV9yb290ZnNfcHJlZml4X2lkZW50aWNhbCI6IHRydWUsCiAgIm92ZXJsYXlfcmVndWxhcl9maWxlcyI6IFsKICAgICJvcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weSIKICBdLAogICJvdmVybGF5X2RpcmVjdG9yaWVzIjogWwogICAgIm9wdCIsCiAgICAib3B0L3ZlbnYiLAogICAgIm9wdC92ZW52L2xpYiIsCiAgICAib3B0L3ZlbnYvbGliL3B5dGhvbjMuMTIiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24iCiAgXSwKICAicG9saWN5X3NoYTI1NiI6ICI5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyIiwKICAicG9saWN5X21vZGUiOiAiMDY0NCIsCiAgImJhc2VfdXNlciI6ICIxMDAwMToxMDAwMSIsCiAgInNvdXJjZV9zY29wZV9sYWJlbHMiOiB7CiAgICAib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnJldmlzaW9uIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgIm9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5iYXNlLmRpZ2VzdCI6ICJzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgICAic29jaWFsLmNvdWxvbWIuc291cmNlLnBvbGljeS5zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgICAic29jaWFsLmNvdWxvbWIucmVsZWFzZS5zY29wZSI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIKICB9LAogICJyZWdpc3RyeV9yZWFkX3JvdXRlIjogImFub255bW91cyBwdWJsaWMgc2NvcGVkIGJlYXJlciBjaGFsbGVuZ2UsIG5vIHRva2VuIHJldGVudGlvbiIsCiAgImltYWdlX2V4ZWN1dGVkIjogZmFsc2UsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlCn0K" + }, + { + "digest": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInNjYW5uZXIiOiAiYXF1YXNlYy90cml2eUBzaGEyNTY6NjJiMWU2NWU4ODY5YmM0YjRjNmFhNGZhMmIyMTU5NTI1NmM3YzJmNjAxOGE5ZDlhZDYxY2FmODcxODdjMTk2OSIsCiAgInZlcnNpb24iOiAiMC43NC4wIiwKICAiZGJfbWV0YWRhdGEiOiB7CiAgICAiVmVyc2lvbiI6IDIsCiAgICAiTmV4dFVwZGF0ZSI6ICIyMDI2LTEwLTExVDE4OjU5OjUwLjg4OTAxMDU3MloiLAogICAgIlVwZGF0ZWRBdCI6ICIyMDI2LTEwLTEwVDE4OjU5OjUwLjg4OTAxMDkyM1oiLAogICAgIkRvd25sb2FkZWRBdCI6ICIyMDI2LTEwLTEwVDIzOjMyOjMyLjM4MDAzMzEzMVoiCiAgfSwKICAic3VwcHJlc3Npb24iOiBmYWxzZSwKICAiaWdub3JlX3VuZml4ZWQiOiBmYWxzZSwKICAic2V2ZXJpdHlfZmlsdGVyIjogbnVsbCwKICAicGFja2FnZV9jb3VudCI6IDQ0LAogICJmaW5kaW5nc19ieV9zZXZlcml0eSI6IHsKICAgICJNRURJVU0iOiAxCiAgfSwKICAiZmluZGluZ3MiOiBbCiAgICB7CiAgICAgICJpZCI6ICJDVkUtMjAyNi04NTA5MSIsCiAgICAgICJwYWNrYWdlIjogInpsaWIiLAogICAgICAiaW5zdGFsbGVkIjogIjEuMy4yLXIwIiwKICAgICAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAgICAgInNldmVyaXR5IjogIk1FRElVTSIKICAgIH0KICBdLAogICJjb3ZlcmFnZV9saW1pdHMiOiBbCiAgICAiQWxwaW5lMy4yNCBhYnNlbnQgc2Nhbm5lciBFT0wgbGlzdDsgT1MgZGV0ZWN0b3IgcmFuIGFnYWluc3QgQWxwaW5lMy4yNCByZXBvc2l0b3J5IG9uMzhPUyBwYWNrYWdlcyIsCiAgICAiS25vd24gZmluZGluZ3MgYXNvZiBwaW5uZWREQiwgbm90IGNsYWltIGFic2VuY2Ugb2YgdW5rbm93biB2dWxuZXJhYmlsaXRpZXMiCiAgXSwKICAiaGlnaF9jcml0aWNhbCI6IDAsCiAgInNhbWVfc2Nhbm5lcl9hY3R1YWxfYmFzZV9zY2FuX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgImJhc2Vfc2Nhbl9maWxlIjogImJhc2UtdHJpdnktZnVsbC5qc29uIgp9Cg==" + }, + { + "digest": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "media_type": "application/json", + "content_base64": "ewogICJraW5kIjogImluZm9ybWVkLWRlY2lzaW9uLmV4ZWN1dGlvbi1zb3VyY2UtYnVuZGxlIiwKICAidmVyc2lvbiI6IDEsCiAgInByb3Bvc2FsX2lkIjogIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxIiwKICAiZmlsZXMiOiB7CiAgICAiUkVBRE1FLm1kIjogewogICAgICAic2hhMjU2IjogImE2ZWNkYWJlYmNlMTJlZWFmZWE2MTE3M2VkYjZlNmQwZTM0OWE3NmUzNjY1NDY5NzhlMmVkMDJlN2IxMDlkZjIiLAogICAgICAiY29udGVudCI6ICIjIFN1cGVydmlzZWQgSW5mb3JtZWQgRGVjaXNpb24gcHVycG9zZSByZWxlYXNlIGV4ZWN1dG9yIOKAlCB1bmFwcHJvdmVkIHByZXBhcmF0aW9uXG5cbk5vIG5hdGl2ZSBkYXRhYmFzZSByZWFkLCBiYWNrdXAvZXhwb3J0L3Jlc3RvcmUgb3Igd29ya2xvYWQgYWN0aW9uIGhhcyBiZWVuIHJ1bi4gVGhpcyBzb3VyY2UgaW1wbGVtZW50cyB0aGUgcmV2aWV3ZWQgcHJvdG9jb2w7IGl0cyBhZGRpdGlvbmFsIG1lY2hhbmljYWwgZGV0YWlscyBuZWVkIHBlZXIgcmV2aWV3IGFuZCBhbiBhbWVuZGVkIGhhc2gtYm91bmQgcGFja2V0IGJlZm9yZSBmaXJzdCBodW1hbiBzdWJtaXNzaW9uLiBUaGUgb3JpZ2luYWw3OHBhdGggcGFja2V0L3Jldmlld3MgcmVtYWluIGhpc3RvcmljYWwgdGVjaG5pY2FsIGFncmVlbWVudCwgbm90IGZvdW5kZXIgYXBwcm92YWwgb2YgdGhpcyBleGVjdXRvci5cblxuUnVuIG9uZSBwaGFzZSBhdCBhIHRpbWUgb25seSBhZnRlciB0aGUgY29vcmRpbmF0b3IgaGFzIGZyZXNobHkgYXV0aGVudGljYXRlZCB0aGUgZXhhY3QgZm91bmRlciBkaXNwb3NpdGlvbiBhdCB0aGUgZXhpc3RpbmcgZml4ZWQgSW5mb3JtZWQgRGVjaXNpb24gb3JpZ2luLiBSb290IHdyaXRlcyB0aGUgcHJvdGVjdGVkMDYwMCBmaXhlZCBmaWxlcyBgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2Utcm9vdC1hdXRob3JpdHkuanNvbmAgYW5kIGAvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1uYXRpdmUtb3V0Y29tZS1sYXRlc3QuanNvbmAuIFRoZSByZWNlaXB0IHRlbXBsYXRlIGlzIFBFTkRJTkcgYW5kIGNhbm5vdCBhdXRob3JpemUgYW55dGhpbmcuIFRoZSBoZWxwZXIgY2hlY2tzIGV4YWN0IG5lc3RlZCBjb25maXJtZWQgcGVyc29uL3BsYXRmb3JtLXJvb3QgQUNDRVBUIHZlcnNpb24xLCBvcmlnaW5hbCBtZW1vIGlkZW50aXR5L2N1cnJlbnQgbWVtbyBTSEEsIHNvdXJjZSBjb21taXQsIHBsYW4gU0hBIGFuZCBmcmVzaG5lc3MxMjBzZWNvbmRzLiBUaGlzIGlzIHN1cGVydmlzZWQgcmVjZWlwdCBib29ra2VlcGluZywgbm90IGNyeXB0b2dyYXBoaWMgcHJvdmlkZXIgdmVyaWZpY2F0aW9uLCBhIHNpZ25lZCBncmFudCBvciBhZ2VudCBhdXRvbm9teSBwcm9tb3Rpb24uIFJvb3QvaGFybmVzcyBzdXBlcnZpc2lvbiByZW1haW5zIHRoZSBhdXRob3JpdHkgYm91bmRhcnkuIE5ldmVyIHN5bnRoZXNpemUgYW4gYXBwcm92YWwgcmVjZWlwdCBmcm9tIGEgdGVjaG5pY2FsIHJldmlldyBvciBjYWxsZXIgYXNzZXJ0aW9uLlxuXG5JbnZvY2F0aW9uIGFmdGVyIGFjdHVhbCBhcHByb3ZhbDogYHB5dGhvbjMgZXhlY3V0aW9uL2FjdHVhdG9yLnB5IC0tcGhhc2UgPGZpeGVkLXBoYXNlPiAtLXJvb3QtYXV0aG9yaXR5LXJlY2VpcHQgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2Utcm9vdC1hdXRob3JpdHkuanNvbiAtLXJvb3QtbmF0aXZlLW91dGNvbWUgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2UtbmF0aXZlLW91dGNvbWUtbGF0ZXN0Lmpzb24gLS1zb3VyY2UtcmV2aXNpb24gPGV4YWN0LWZpbmFsLW93bmVyLWNvbW1pdD5gLiBPcmRlcjogZHJpbGwtYmFja3VwIOKGkiBkcmlsbC1jb3B5IOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnkuIFJvbGxiYWNrIGlzIGEgZGlzdGluY3QgYXV0aG9yaXplZCByZWNvdmVyeSBhZnRlciBhIHJlY29yZGVkIHJlbGVhc2UgYXR0ZW1wdCwgZm9sbG93ZWQgYnkgcm9sbGJhY2stdmVyaWZ5LiBSb2xsYmFjayBkaXNwYXRjaCBuZWVkcyBubyBSZWFkeSBQb2Qgb3IgY2FuZGlkYXRlIGRhdGFiYXNlIGV4ZWM6IHNlYWxlZCBEZXBsb3ltZW50L0NNL1BWQy9zb3VyY2UvaW1hZ2UgcGFpciBhbmQgYWRtaXNzaW9uIENBUyByZW1haW4gbWFuZGF0b3J5LiBJdHMgYWNrbm93bGVkZ21lbnQgaXMgbm90IHJlY292ZXJ5IGNvbXBsZXRpb247IHJvbGxiYWNrLXZlcmlmeSBzZXBhcmF0ZWx5IHJlcXVpcmVzIFJlYWR5MSBvZiB0aGUgb2xkIGltYWdlLCBzdWNjZWVkZWQgZXhhY3Qgc2NvcGVkIG9wZXJhdGlvbiBhbmQgcmVhZG9ubHkgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnQgcHJvb2Ygb2YgdGhlIGN1cnJlbnQgcmV0YWluZWQgZGF0YWJhc2UuIFJvb3QgcmVmcmVzaGVzIGFjdHVhbCBuYXRpdmUgYWNjZXB0YW5jZSBpbW1lZGlhdGVseSBiZWZvcmUgZWFjaCBwaGFzZS5cblxuVGhlIHByaXZhdGUgaWdub3JlZCBDdXN0b2RpYW4gY3VzdG9keSBwYXJlbnQgYC5wcml2YXRlLWJhY2t1cHNgIG11c3QgYWxyZWFkeSBleGlzdCwwNzAwIG93bmVkIGJ5IHRoZSB3b3Jrc3RhdGlvbiBhZ2VudCB1c2VyOyB0aGUgZXhhY3QgY2FzZSBjaGlsZDIwMjYxMDExLWluZmQtcHVycG9zZS1yMSBpcyBjcmVhdGVkIG9ubHkgYWZ0ZXIgYXV0aG9yaXR5IGNoZWNrcy4gTmF0aXZlIHBhcmVudCBgL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjFgIGlzIHVuaXF1ZWx5IGNyZWF0ZWQgYnkgVUlEMTAwMDEgZm9yIGRyaWxsL2N1dG92ZXIgU1FMaXRlLWNvbnNpc3RlbnQgc25hcHNob3RzLCBlYWNoMDYwMC9ub25zeW1saW5rL3NpbmdsZS1saW5rLiBUaGUgYXR0YWNoZWQgc3RkbGliIHJlYWRvbmx5IGNoZWNrZXIgbXVzdCByZXBvcnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzIGJlZm9yZSBhbnkgU3RvcmUvYWRtaW4gb24gbmF0aXZlIHNvdXJjZSBvciBvZmZsaW5lY2xvbmUuIEludmFsaWQgc3RhdGVzL2NvdW50IHNoYXBlcyBhbmQgYWxsIHJhdyBjaGlsZCBvdXRwdXRzIGFyZSB3aXRoaGVsZC4gTWFpbi1vbmx5IHNuYXBzaG90IGNsb3N1cmUgaXMgdmVyaWZpZWQgYmVmb3JlIGJpbmFyeSB0cmFuc2Zlcjsgc3RkaW4vc3Rkb3V0IHNuYXBzaG90IGJ5dGVzIHJlYWNoIG9ubHkgcHJpdmF0ZSBmaWxlcyBvciB0aGUgaXNvbGF0ZWQgcmVzdG9yZSBjb3B5LCBuZXZlciB0b29sL2NoYXQvbG9nIG91dHB1dC4gU3RyZWFtcyBzdG9wIGJleW9uZCBmcm96ZW4gYnl0ZSBjb3VudC81MTJNaUI7IGZhaWx1cmVzIHJldGFpbiBwYXJ0aWFsIHByaXZhdGUgZXZpZGVuY2UuXG5cbk5ldyBwcml2YXRlIG9mZmxpbmUgdm9sdW1lIGBpbmZkLXB1cnBvc2UtcjEtcmVzdG9yZS0yMDI2MTAxMWAgaXMgY3JlYXRlZCBvbmx5IG9uIHRoZSBwaW5uZWQgbG9jYWwgd29ya3N0YXRpb24gRG9ja2VyIHNvY2tldC9lbmdpbmUgYm50LWxhcDAwMSwgd2l0aCBsb2NhbGRyaXZlci9ub29wdGlvbnMgYW5kIGF0dGVtcHRub25jZSBsYWJlbHMuIE9uZS10aW1lIGluaXRpYWxpemVyIHJ1bnMgZXhhY3Q3NjNjIGFzIFVJRDAgd2l0aCBvbmx5IENBUF9DSE9XTiwgbmV0d29ya25vbmUvcmVhZC1vbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzLCBvbmUgTkVXIG5hbWVkdm9sdW1lIG1vdW50LCBubyBob3N0L2xpdmVQVkMvY3JlZGVudGlhbC9jb25maWcgbW91bnRzLiBJdCByZWNlaXZlcyBvbmx5IHRoZSBwcm90ZWN0ZWQgc25hcHNob3Qgb24gc3RkaW4sIHZlcmlmaWVzIGJ5dGVzLCBzZXRzIGZvbGRlcjA3MDAvZmlsZTA2MDAgb3duZWQxMDAwMS4gVGhlbiBVSUQxMDAwMSBwZXJmb3JtcyByZWFkb25seSBwcmUtb3BlbiB2YWxpZGF0aW9uLCBgLS1lbnRyeXBvaW50IGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGluc3BlY3QgLS1kYiAvcmVzdG9yZS9yZXZpZXcuc3FsaXRlYCwgbmV2ZXIgdGhlIHNlcnZpY2UgZW50cnlwb2ludC4gQSBzZWNvbmQgVUlEMTAwMDEvbmV0d29yay1ub25lIHJlYWRvbmx5IGludGVncml0eS9zY2hlbWEvY291bnQgY2hlY2sgYWZ0ZXIgYWRtaW4gbXVzdCBleGFjdGx5IGVxdWFsIHRoZSBmcm96ZW4gc25hcHNob3QgcHJvb2YsIGFuZCB0aGUgb3JpZ2luYWwgcHJvdGVjdGVkIHNuYXBzaG90IFNIQSBtdXN0IHJlbWFpbiB1bmNoYW5nZWQuIENsZWFudXAgY29tcGFyZXMgZXhhY3Qgbm9uY2UvY3JlYXRpb24gaWRlbnRpdHkgYW5kIHJlbW92ZXMgb25seSB0aGlzIGNsb25lIHZvbHVtZSwgcmV0YWluaW5nIGFsbCBuYXRpdmUvb2ZmY2x1c3RlciBvcmlnaW5hbHMuIENQVTEvbWVtb3J5MTI4TWlCOyBwcml2YXRlIG9mZmNsdXN0ZXIgY2FwYWNpdHkgYXQgbGVhc3QxR2lCKzE2TWlCIGFuZCBuYXRpdmUgZXN0aW1hdGVkIHR3by9vbmUtc25hcHNob3QgaGVhZHJvb20gcmVxdWlyZWQuXG5cbkV2ZXJ5IHBoYXNlIGZzeW5jcyBSVU5OSU5HIGludGVudCBiZWZvcmUgZGlzcGF0Y2guIEFueSBmYWlsdXJlL2ludGVycnVwdGlvbi9hbWJpZ3VvdXMgcmVzdWx0IHJlbWFpbnMgVU5DRVJUQUlOOyBzYW1lLXBoYXNlIHJldHJ5IGlzIHJlZnVzZWQuIFNlcGFyYXRlIG9wZXJhdG9yIGRpYWdub3NpcyBhbmQgYW55IG5lZWRlZCByZWNvdmVyeSBhcmUgcmVjb3JkZWQ7IG5laXRoZXIgc25hcHNob3RzIG5vciB1bnJlc29sdmVkL25ldyByZWNvcmRzIGFyZSByZW1vdmVkIHRvIG1ha2UgY2hlY2tzIGdyZWVuLiBGcm96ZW4gc25hcHNob3QvY2xvbmUgY291bnRlcnMgbXVzdCBhZ3JlZTsgbGl2ZSBwb3N0LWN1dG92ZXIvcm9sbGJhY2sgY291bnRlcnMgY2FuIGluY2x1ZGUgbGVnaXRpbWF0ZSBjb25jdXJyZW50IGNvbW1pdHMvc3RhdGUgdHJhbnNpdGlvbnMuXG5cbkV4aXN0aW5nIEFwcGxpY2F0aW9uIFVJRCBhbmQgYWN0dWFsIERlcGxveW1lbnQvUG9kL0NNL1BWQyBjdXN0b2R5L3NvdXJjZSBhcmUgY2hlY2tlZC4gQWxsIGZvdXIgb3duZXIgcmVuZGVyIEdpdCBibG9icyBtdXN0IG1hdGNoOyBvdmVycmlkZXMvcGx1Z2lucy9tdWx0aXBsZSBzb3VyY2VzIGFuZCBldmVuIGF1dG9tYXRlZDp7fSBhcmUgcmVqZWN0ZWQuIFRoZSBleGlzdGluZyBBcHBsaWNhdGlvbi5vcGVyYXRpb24gQVBJIGlzIHVzZWQgKG5hdGl2ZSBhcmdvY2QgQ0xJIGlzIGFic2VudCksIHdpdGggc2VydmVyIGRyeS1ydW4sIHJlc291cmNlVmVyc2lvbi9VSUQvc291cmNlIHRlc3RzLCBvbmUgRGVwbG95bWVudCBvbmx5LCBwcnVuZT1mYWxzZS4gRGlzcGF0Y2ggYWNrbm93bGVkZ21lbnQgaXMgbm90IHJvbGxvdXQgY29tcGxldGlvbi4gVmVyaWZ5IHJlcXVpcmVzIGV4YWN0IHN1Y2NlZWRlZCBvcGVyYXRpb24vY29udHJvbGxlciBnZW5lcmF0aW9uL1JlYWR5MSwgc2FtZSBzY2hlbWE1IERCLCBhY3R1YWwgaW5zdGFsbGVkIGhhc2gvbW9kZS9VSUQgYW5kMTBwdXJwb3NlIGNoZWNrcyBwbHVzIGJvdW5kZWQgbG9jYWxob3N0aGVhbHRoL3JlYWRpbmVzcy4gUHVycG9zZSB0cmFuc3BvcnQgcmVtYWlucyBzeW50aGV0aWMgYW5kIGlzIGV4cGxpY2l0bHkgbm90IGEgbmF0aXZlIFBEUCBhdXRob3JpdHkgdGVzdC4gUm9sbGJhY2sgcGlucyBwcmlvcjdkYi83ZjUgdGhyb3VnaCB0aGUgc2FtZSBzY29wZWQgd29ya2Zsb3cgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQgbGl2ZSBkYXRhYmFzZTsgaXQgbmV2ZXIgcmVzdG9yZXMgYW4gb2xkZXIgc25hcHNob3Qgb3ZlciBsYXRlciB3cml0ZXMuXG5cblNpeHRlZW4gc3ludGhldGljIHRlc3RzIHBhc3MgYWdhaW5zdCBmcm96ZW4gY2FzZSBtZXRhZGF0YTogYXV0aG9yaXR5L2V4cGlyeS9hY3Rvci9hbWJpZ3VpdHkgcmVmdXNhbHMsIGNyYXNoIGludGVudC9ubyByZXRyeS9vcmRlciwgY3JlZGVudGlhbC1vdXRwdXQgd2l0aGhvbGRpbmcsIHByaXZhdGUgYm91bmRlZCBiaW5hcnljb3B5LCB2b2x1bWUgcmVjcmVhdGlvbiBjbGVhbnVwIHJlZnVzYWwsIHNvdXJjZS9hdXRvbWF0aW9uL0NNL1BWQy9SZWFkeSBkcmlmdCwgcHJlLW9wZW4gZ2F0ZSByZWZ1c2FsIGFuZCBleGFjdCBEZXBsb3ltZW50LW9ubHkgb3BlcmF0aW9uL2RyeS1ydW4uIFRoZXNlIGFyZSBzb3VyY2UgdGVzdHMsIG5vdCBuYXRpdmUgYmFja3VwIG9yIHJlbGVhc2UgcHJvb2YuXG5cbkFsbCBwaGFzZXMsIGluY2x1ZGluZyByZWNvdmVyeSBhbmQgdmVyaWZpY2F0aW9uLCBhcmUgYm91bmRlZCBieSAyMDI2LTEwLTEyVDIzOjU5OjU5Wi4gVGhpcyBleHBsaWNpdGx5IHJlZmluZXMgdGhlIGVhcmxpZXIgcGFja2V0IGRlYWRsaW5lIHdvcmRpbmcgZm9yIHVuc3RhcnRlZCByZWxlYXNlOiB0aGUgaGVscGVyIGRvZXMgbm90IGV4dGVuZCBhdXRob3JpdHkgcGFzdCB0aGUgZGVhZGxpbmUuIFN0YXJ0IHN1ZmZpY2llbnRseSBlYXJseSB0byBjb21wbGV0ZSBkcmlsbC9jdXRvdmVyL3JlY292ZXJ5OyBhZnRlciBleHBpcnkgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gVGhpcyBtYXkgZGVsYXkgcmVjb3ZlcnkgaWYgdGhlIHdpbmRvdyBpcyBleGhhdXN0ZWQsIGFuZCBtdXN0IGJlIGRpc2Nsb3NlZCBiZWZvcmUgYWNjZXB0YW5jZS5cblxuVGhlIGluaXRpYWwgMTEtZmlsZSBoZWxwZXIgZnJlZXplIFNIQTY1M2I2OGMzODkxYzA2NmY0MGQxMDRiZmM2N2EzNWRhNWU0MzY2MDVjZDk5YWZkNTJmYmFjNGI0N2E5NTUzZmUgYW5kIGluZGVwZW5kZW50IGNvbmRpdGlvbmFsIGZpbmRpbmdzIHJlbWFpbiBhcmNoaXZlZCB1bmRlciBleGVjdXRpb24taGlzdG9yeS9pbml0aWFsLTY1M2I2OGMzLiBUaGlzIHJlZmluZW1lbnQgaXMgdGhlIHNhbWUgcHJvcG9zYWwvdHJpYWw7IG5vIG5hdGl2ZSBleGVjdXRpb24gb3IgaHVtYW4gYWNjZXB0YW5jZSBoYXMgb2NjdXJyZWQuXG4iCiAgICB9LAogICAgImFjdHVhdG9yLnB5IjogewogICAgICAic2hhMjU2IjogIjZiOWQ2NDM5ODYyNDU0ZjI2MWVlNzdmMDViMjY1MTlmODEwOTU5OWIxZjY3MDc4YmM0ZTFmN2M3YzQwNjFiYTUiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmUgZml4ZWQgc3VwZXJ2aXNlZCBwaGFzZTsgbmV2ZXIgcnVuIHRoaXMgZHVyaW5nIHNvdXJjZSBwcmVwYXJhdGlvbi5cIlwiXCJcbmltcG9ydCBhcmdwYXJzZVxuaW1wb3J0IGhhc2hsaWJcbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHJlXG5pbXBvcnQgc2VsZWN0b3JzXG5pbXBvcnQgc3RhdFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0aW1lXG5cbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KCdvcHRpbWl6ZWQgaW50ZXJwcmV0ZXIgcmVmdXNlZCcpXG5cblBIQVNFUyA9ICgnZHJpbGwtYmFja3VwJywgJ2RyaWxsLWNvcHknLCAnb2ZmbGluZS12ZXJpZnknLCAnY2xlYW51cC1vZmZsaW5lJyxcbiAgICAgICAgICAnY3V0b3Zlci1iYWNrdXAnLCAnY3V0b3Zlci1jb3B5JywgJ3JlbGVhc2UnLCAndmVyaWZ5JywgJ3JvbGxiYWNrJywgJ3JvbGxiYWNrLXZlcmlmeScpXG5cblxuZGVmIHJlcXVpcmUodmFsdWUsIHJlYXNvbik6XG4gICAgaWYgbm90IHZhbHVlOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcblxuXG5kZWYgc2hhKHBhdGgpOlxuICAgIGRpZ2VzdCA9IGhhc2hsaWIuc2hhMjU2KClcbiAgICB3aXRoIFBhdGgocGF0aCkub3BlbigncmInKSBhcyBzdHJlYW06XG4gICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6XG4gICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJsb2NrKVxuICAgIHJldHVybiBkaWdlc3QuaGV4ZGlnZXN0KClcblxuXG5kZWYgcHJpdmF0ZShwYXRoLCBkaXJlY3Rvcnk9RmFsc2UpOlxuICAgIGluZm8gPSBQYXRoKHBhdGgpLmxzdGF0KClcbiAgICByZXF1aXJlKChzdGF0LlNfSVNESVIoaW5mby5zdF9tb2RlKSBpZiBkaXJlY3RvcnkgZWxzZSBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSlcbiAgICAgICAgICAgIGFuZCBpbmZvLnN0X3VpZCA9PSBvcy5nZXR1aWQoKSBhbmQgc3RhdC5TX0lNT0RFKGluZm8uc3RfbW9kZSkgPT0gKDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxuICAgICAgICAgICAgYW5kIChkaXJlY3Rvcnkgb3IgaW5mby5zdF9ubGluayA9PSAxKSwgJ3ByaXZhdGUgb3duZWQgY3VzdG9keSByZXF1aXJlZCcpXG5cblJPT1QgPSBQYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50XG5DQVNFID0gUk9PVC5wYXJlbnRcbk9XTkVSID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uJylcbkNVU1RPRElBTiA9IFBhdGgoJy9ob21lL3dvcnNjaC90aGUtY3VzdG9kaWFuJylcbkNVU1RPRFkgPSBDVVNUT0RJQU4gLyAnLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjEnXG5TT0NLRVQgPSAndW5peDovLy92YXIvcnVuL2RvY2tlci5zb2NrJ1xuSU1BR0UgPSAnZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhJ1xuVk9MVU1FID0gJ2luZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExJ1xuTUFYX0JZVEVTID0gNTEyICogMTAyNCoqMlxuXG5cbmRlZiBydW4oYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTkwKTpcbiAgICByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndiwgaW5wdXQ9Ym9keSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIGpzb25fcmVzdWx0KHJlc3VsdCk6XG4gICAgdHJ5OlxuICAgICAgICB2YWx1ZSA9IGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcbiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhZmUgcGhhc2UgcmVjZWlwdCB1bmF2YWlsYWJsZTsgb3V0Y29tZSB1bmNlcnRhaW4nKSBmcm9tIE5vbmVcbiAgICByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlID09IDAgYW5kIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIFRydWUsXG4gICAgICAgICAgICAncGhhc2UgZGlkIG5vdCB2ZXJpZnkgY29tcGxldGU7IHJhdyBvdXRwdXQgd2l0aGhlbGQ7IG5vIHJldHJ5JylcbiAgICBwZXJtaXR0ZWQgPSB7J3BoYXNlJywgJ2FsbF9jaGVja3NfcGFzcycsICdyYXdfb3V0cHV0X3dpdGhoZWxkJywgJ25hdGl2ZV9hcHByb3ZhbF92ZXJpZmllZF9ieV9yb290JyxcbiAgICAgICAgICAgICAgICAgJ25hdGl2ZV9hdXRoZW50aWNhdGVkX2dyYW50JywgJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZScsICdzbmFwc2hvdF9yZWFkb25seScsXG4gICAgICAgICAgICAgICAgICdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICduYXRpdmVfcGFyZW50X3ByaXZhdGUnLFxuICAgICAgICAgICAgICAgICAnbmF0aXZlX3VpZCcsICdwb2RfbmFtZScsICdwb2RfdWlkJywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnLFxuICAgICAgICAgICAgICAgICAnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzJywgJ29wZXJhdGlvbl9yZXF1ZXN0ZWQnLCAnc291cmNlX3JldmlzaW9uJyxcbiAgICAgICAgICAgICAgICAgJ3Jlc291cmNlcycsICdwcnVuZScsICdyb2xsb3V0X3ZlcmlmaWVkJywgJ2xhdGVzdF9saXZlX2RhdGFiYXNlX3JldGFpbmVkJyxcbiAgICAgICAgICAgICAgICAgJ2NsaWVudF9kaWZmX3NoYTI1NicsICduYXRpdmVfcm9sbG91dF92ZXJpZmllZCcsICdjdXJyZW50X3NjaGVtYTVfZGF0YWJhc2VfcmV0YWluZWQnLFxuICAgICAgICAgICAgICAgICAncHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJywgJ2luc3RhbGxlZF9wdXJwb3NlX2NoZWNrcycsICdwb2xpY3lfc2hhMjU2JyxcbiAgICAgICAgICAgICAgICAgJ3BvbGljeV9tb2RlJywgJ3BvbGljeV91aWQnLCAnaGVhbHRoX3N0YXR1c2VzJywgJ25hdGl2ZV9wcm92aWRlcl9wcm9iZScsICdyZWNvdmVyeV92ZXJpZmljYXRpb24nfVxuICAgIHJlcXVpcmUoc2V0KHZhbHVlKSA8PSBwZXJtaXR0ZWQsICd1bmV4cGVjdGVkIG91dHB1dCBmaWVsZHMgd2l0aGhlbGQnKVxuICAgIGZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuICAgIGZvciBuYW1lIGluICgnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lJywgJ3NuYXBzaG90X3JlYWRvbmx5JywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIGNvdW50cyh2YWx1ZVtuYW1lXSlcbiAgICBmb3IgbmFtZSBpbiAoJ3NuYXBzaG90X3NoYTI1NicsICdjbGllbnRfZGlmZl9zaGEyNTYnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOV17NjR9JywgdmFsdWVbbmFtZV0pIGlzIG5vdCBOb25lLCAnaW52YWxpZCBvdXRwdXQgZGlnZXN0IHdpdGhoZWxkJylcbiAgICBpZiAnc25hcHNob3RfYnl0ZXMnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHR5cGUodmFsdWVbJ3NuYXBzaG90X2J5dGVzJ10pIGlzIGludCBhbmQgMCA8IHZhbHVlWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAnaW52YWxpZCBvdXRwdXQgc2l6ZSB3aXRoaGVsZCcpXG4gICAgaWYgJ3NuYXBzaG90X2ZpbGUnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHZhbHVlWydzbmFwc2hvdF9maWxlJ10gaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSwgJ2ludmFsaWQgb3V0cHV0IGZpbGUgd2l0aGhlbGQnKVxuICAgIHJldHVybiB2YWx1ZVxuXG5cbmRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTEyMCk6XG4gICAgcmV0dXJuIHJ1bihbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVF0gKyBhcmd2LFxuICAgICAgICAgICAgICAgYm9keT1ib2R5LCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKTpcbiAgICAjIEZpeGVkIG1vZHVsZSBpbXBvcnRlZCBvbmx5IGFmdGVyIG1haW4gdmVyaWZpZXMgZXZlcnkgZXhlY3V0b3Igc291cmNlIGhhc2guXG4gICAgZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuICAgIHBheWxvYWQgPSB7J3BoYXNlJzogcGhhc2UsICdzb3VyY2VfcmV2aXNpb24nOiByZXZpc2lvbiwgJ2FwcHJvdmFsJzogYXBwcm92ZWQsXG4gICAgICAgICAgICAgICAnc2VhbGVkJzoganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJzoganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ2NhbmRpZGF0ZSc6IGpzb24ubG9hZHMoKENBU0UgLyAnY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdyb2xsYmFjayc6IGpzb24ubG9hZHMoKENBU0UgLyAncm9sbGJhY2stZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ3JlY2VpcHRfc2FmZXR5JzogKFJPT1QgLyAncmVjZWlwdF9zYWZldHkucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICdwdXJwb3NlX2NoZWNrcyc6IChDQVNFIC8gJ2NoZWNrX2luc3RhbGxlZC5weScpLnJlYWRfdGV4dCgpLFxuICAgICAgICAgICAgICAgJ3JlYWRvbmx5JzogKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCl9XG4gICAgc2NyaXB0ID0gUFJPR1JBTS5yZXBsYWNlKCdfX1BBWUxPQURfXycsIHJlcHIoanNvbi5kdW1wcyhwYXlsb2FkKSkpLnJlcGxhY2UoXG4gICAgICAgICdfX0dVQVJEX18nLCByZXByKChDQVNFIC8gJ2NoYW5nZV9ndWFyZC5weScpLnJlYWRfdGV4dCgpKSlcbiAgICByZXR1cm4ganNvbl9yZXN1bHQocnVuKFsnc3NoJywgJ3JhaWxpYW5jZTAxJywgJ3B5dGhvbjMgLSddLCBzY3JpcHQsIHRpbWVvdXQ9MjAwKSlcblxuXG5kZWYgY29weV9zbmFwc2hvdChwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkLCBqb3VybmFsKTpcbiAgICBtZXRhZGF0YSA9IHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKVxuICAgIGJhY2t1cF9waGFzZSA9ICdkcmlsbC1iYWNrdXAnIGlmIHBoYXNlID09ICdkcmlsbC1jb3B5JyBlbHNlICdjdXRvdmVyLWJhY2t1cCdcbiAgICBwcmlvciA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bYmFja3VwX3BoYXNlXVsncmVzdWx0J11cbiAgICBmb3Iga2V5IGluICgnc25hcHNob3Rfc2hhMjU2JywgJ3NuYXBzaG90X2J5dGVzJywgJ3NuYXBzaG90X2ZpbGUnLCAnc25hcHNob3RfcmVhZG9ubHknKTpcbiAgICAgICAgcmVxdWlyZShtZXRhZGF0YVtrZXldID09IHByaW9yW2tleV0sICdjbG9zZWQgZnJvemVuIHNuYXBzaG90IGNoYW5nZWQnKVxuICAgIG5hbWUgPSBtZXRhZGF0YVsnc25hcHNob3RfZmlsZSddXG4gICAgcmVxdWlyZShuYW1lIGluICgnZHJpbGwuc3FsaXRlJywgJ2N1dG92ZXIuc3FsaXRlJykgYW5kIDAgPCBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXSA8PSBNQVhfQllURVMsXG4gICAgICAgICAgICAnZml4ZWQgYm91bmRlZCBzbmFwc2hvdCByZXF1aXJlZCcpXG4gICAgcG9kID0gbWV0YWRhdGFbJ3BvZF9uYW1lJ11cbiAgICByZXF1aXJlKHJlLmZ1bGxtYXRjaChyJ1thLXowLTldKFstYS16MC05XSpbYS16MC05XSk/JywgcG9kKSBpcyBub3QgTm9uZSwgJ2ZpeGVkIG93bmVyIHBvZCBuYW1lIHJlcXVpcmVkJylcbiAgICBsb2NhbCA9IENVU1RPRFkgLyBuYW1lXG4gICAgZmQgPSBvcy5vcGVuKGxvY2FsLCBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX0VYQ0wgfCBvcy5PX05PRk9MTE9XLCAwbzYwMClcbiAgICAjIEJpbmFyeSBzbmFwc2hvdCBzdGRvdXQgZ29lcyBvbmx5IHRvIGEgcHJpdmF0ZSBmaWxlLCBuZXZlciB0b29sL2NoYXQvbG9nIG91dHB1dC5cbiAgICAjIFNuYXBzaG90IHNjaGVtYS9jb3VudCBtZXRhZGF0YSB3YXMgdmFsaWRhdGVkIGJlZm9yZSBvcGVuaW5nIHRoaXMgZGVzdGluYXRpb24uXG4gICAgd2l0aCBvcy5mZG9wZW4oZmQsICd3YicpIGFzIGRlc3RpbmF0aW9uOlxuICAgICAgICBjb21tYW5kID0gKCdrdWJlY3RsIGV4ZWMgLW4gaW5mb3JtZWQtZGVjaXNpb24gJyArIHBvZCArXG4gICAgICAgICAgICAgICAgICAgJyAtYyBpbmZvcm1lZC1kZWNpc2lvbiAtLSBjYXQgL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjEvJyArIG5hbWUpXG4gICAgICAgIHRyYW5zZmVyID0gc3VicHJvY2Vzcy5Qb3BlbihbJ3NzaCcsICdyYWlsaWFuY2UwMScsIGNvbW1hbmRdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTClcbiAgICAgICAgc2VsZWN0b3IgPSBzZWxlY3RvcnMuRGVmYXVsdFNlbGVjdG9yKClcbiAgICAgICAgc2VsZWN0b3IucmVnaXN0ZXIodHJhbnNmZXIuc3Rkb3V0LCBzZWxlY3RvcnMuRVZFTlRfUkVBRClcbiAgICAgICAgZGVhZGxpbmUgPSB0aW1lLm1vbm90b25pYygpICsgMTUwXG4gICAgICAgIHJlY2VpdmVkID0gMFxuICAgICAgICB0cnk6XG4gICAgICAgICAgICB3aGlsZSBUcnVlOlxuICAgICAgICAgICAgICAgIHJlbWFpbmluZyA9IGRlYWRsaW5lIC0gdGltZS5tb25vdG9uaWMoKVxuICAgICAgICAgICAgICAgIHJlcXVpcmUocmVtYWluaW5nID4gMCBhbmQgc2VsZWN0b3Iuc2VsZWN0KHJlbWFpbmluZyksICdwcml2YXRlIHRyYW5zZmVyIHRpbWVkIG91dCcpXG4gICAgICAgICAgICAgICAgYmxvY2sgPSBvcy5yZWFkKHRyYW5zZmVyLnN0ZG91dC5maWxlbm8oKSwgMTAyNCoqMilcbiAgICAgICAgICAgICAgICBpZiBub3QgYmxvY2s6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQgKz0gbGVuKGJsb2NrKVxuICAgICAgICAgICAgICAgIHJlcXVpcmUocmVjZWl2ZWQgPD0gbWV0YWRhdGFbJ3NuYXBzaG90X2J5dGVzJ10gYW5kIHJlY2VpdmVkIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdwcml2YXRlIGNvcHkgZXhjZWVkcyBmcm96ZW4gc25hcHNob3Qgc2l6ZScpXG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb24ud3JpdGUoYmxvY2spXG4gICAgICAgICAgICB0cmFuc2Zlci53YWl0KHRpbWVvdXQ9bWF4KDEsIGRlYWRsaW5lIC0gdGltZS5tb25vdG9uaWMoKSkpXG4gICAgICAgIGZpbmFsbHk6XG4gICAgICAgICAgICBzZWxlY3Rvci5jbG9zZSgpXG4gICAgICAgICAgICB0cmFuc2Zlci5zdGRvdXQuY2xvc2UoKVxuICAgICAgICAgICAgaWYgdHJhbnNmZXIucG9sbCgpIGlzIE5vbmU6XG4gICAgICAgICAgICAgICAgdHJhbnNmZXIua2lsbCgpXG4gICAgICAgICAgICAgICAgdHJhbnNmZXIud2FpdCgpXG4gICAgICAgIGRlc3RpbmF0aW9uLmZsdXNoKClcbiAgICAgICAgb3MuZnN5bmMoZGVzdGluYXRpb24uZmlsZW5vKCkpXG4gICAgcHJpdmF0ZShsb2NhbClcbiAgICByZXF1aXJlKHRyYW5zZmVyLnJldHVybmNvZGUgPT0gMCBhbmQgbG9jYWwuc3RhdCgpLnN0X3NpemUgPT0gbWV0YWRhdGFbJ3NuYXBzaG90X2J5dGVzJ11cbiAgICAgICAgICAgIGFuZCBzaGEobG9jYWwpID09IG1ldGFkYXRhWydzbmFwc2hvdF9zaGEyNTYnXSwgJ3ByaXZhdGUgY29weSBpbmNvbXBsZXRlL3VuY2VydGFpbjsgcmV0YWluLCBubyByZXRyeScpXG4gICAgIyBSZS1yZWFkIGlkZW50aXR5L2hhc2ggYWZ0ZXIgdHJhbnNmZXIuIFRoaXMgaXMgdmVyaWZpY2F0aW9uLCBub3QgYSB3cml0ZSByZXRyeS5cbiAgICBhZnRlciA9IHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKVxuICAgIHJlcXVpcmUoYWZ0ZXJbJ3BvZF91aWQnXSA9PSBtZXRhZGF0YVsncG9kX3VpZCddIGFuZCBhZnRlclsnc25hcHNob3Rfc2hhMjU2J10gPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLFxuICAgICAgICAgICAgJ3NvdXJjZSBpZGVudGl0eS9zbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyB0cmFuc2ZlcicpXG4gICAgcmV0dXJuIHsqKm1ldGFkYXRhLCAnb2ZmX2NsdXN0ZXJfcHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJzogVHJ1ZSwgJ3NuYXBzaG90X2NvbnRlbnRzX291dHB1dCc6IEZhbHNlfVxuXG5cbmRlZiBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKTpcbiAgICBmcm9tIHJlY2VpcHRfc2FmZXR5IGltcG9ydCBjb3VudHNcbiAgICBzbmFwc2hvdCA9IENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJ1xuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcHJldmlvdXMgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydkcmlsbC1jb3B5J11bJ3Jlc3VsdCddXG4gICAgcmVxdWlyZShzaGEoc25hcHNob3QpID09IHByZXZpb3VzWydzbmFwc2hvdF9zaGEyNTYnXSwgJ3Byb3RlY3RlZCBzbmFwc2hvdCBieXRlcyBjaGFuZ2VkJylcbiAgICBpZGVudGl0eSA9IGRvY2tlcihbJ2luZm8nLCAnLS1mb3JtYXQnLCAne3tqc29uIC5OYW1lfX0nXSlcbiAgICByZXF1aXJlKGlkZW50aXR5LnJldHVybmNvZGUgPT0gMCBhbmQganNvbi5sb2FkcyhpZGVudGl0eS5zdGRvdXQpID09ICdibnQtbGFwMDAxJyxcbiAgICAgICAgICAgICdsb2NhbCBvZmZsaW5lIERvY2tlciBlbmdpbmUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgbGlzdGVkID0gZG9ja2VyKFsndm9sdW1lJywgJ2xzJywgJy0tZm9ybWF0JywgJ3t7Lk5hbWV9fSddKVxuICAgIHJlcXVpcmUobGlzdGVkLnJldHVybmNvZGUgPT0gMCBhbmQgVk9MVU1FIG5vdCBpbiBsaXN0ZWQuc3Rkb3V0LnNwbGl0bGluZXMoKSxcbiAgICAgICAgICAgICdkaXNwb3NhYmxlIHZvbHVtZSBhYnNlbmNlIG5vdCB2ZXJpZmllZCcpXG4gICAgbm9uY2UgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydvZmZsaW5lLXZlcmlmeSddWydhdHRlbXB0X2lkJ11cbiAgICBsYWJlbHMgPSB7J2luZm9ybWVkLWRlY2lzaW9uLmNhc2UnOiAnaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxJyxcbiAgICAgICAgICAgICAgJ2luZm9ybWVkLWRlY2lzaW9uLnVzZSc6ICdvZmZsaW5lLXJlc3RvcmUtb25seScsICdpbmZvcm1lZC1kZWNpc2lvbi5hdHRlbXB0Jzogbm9uY2V9XG4gICAgY3JlYXRlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdjcmVhdGUnLCAnLS1kcml2ZXInLCAnbG9jYWwnLCAnLS1sYWJlbCcsICdpbmZvcm1lZC1kZWNpc2lvbi5jYXNlPWluZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsXG4gICAgICAgICAgICAgICAgICAgICAgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdD0nICsgbm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24udXNlPW9mZmxpbmUtcmVzdG9yZS1vbmx5JywgVk9MVU1FXSlcbiAgICByZXF1aXJlKGNyZWF0ZWQucmV0dXJuY29kZSA9PSAwIGFuZCBjcmVhdGVkLnN0ZG91dC5zdHJpcCgpID09IFZPTFVNRSwgJ3ZvbHVtZSBjcmVhdGlvbiB1bmNlcnRhaW47IG5vIHJldHJ5JylcbiAgICBpbnNwZWN0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnaW5zcGVjdCcsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShpbnNwZWN0ZWQucmV0dXJuY29kZSA9PSAwLCAnbmV3IHZvbHVtZSBpZGVudGl0eSB1bmF2YWlsYWJsZScpXG4gICAgdm9sdW1lID0ganNvbi5sb2FkcyhpbnNwZWN0ZWQuc3Rkb3V0KVxuICAgIHJlcXVpcmUobGVuKHZvbHVtZSkgPT0gMSBhbmQgdm9sdW1lWzBdWydOYW1lJ10gPT0gVk9MVU1FIGFuZCB2b2x1bWVbMF0uZ2V0KCdMYWJlbHMnKSA9PSBsYWJlbHNcbiAgICAgICAgICAgIGFuZCB2b2x1bWVbMF0uZ2V0KCdEcml2ZXInKSA9PSAnbG9jYWwnIGFuZCBub3Qgdm9sdW1lWzBdLmdldCgnT3B0aW9ucycpXG4gICAgICAgICAgICBhbmQgdm9sdW1lWzBdLmdldCgnU2NvcGUnKSA9PSAnbG9jYWwnLCAnbmV3IGlzb2xhdGVkIHZvbHVtZSBpZGVudGl0eSBjaGFuZ2VkJylcbiAgICBpZGVudGl0eSA9IHtrZXk6IHZvbHVtZVswXVtrZXldIGZvciBrZXkgaW4gKCdOYW1lJywgJ0xhYmVscycsICdEcml2ZXInLCAnU2NvcGUnLCAnQ3JlYXRlZEF0Jyl9XG4gICAgam91cm5hbC5ub3RlKCdvZmZsaW5lLXZlcmlmeScsICdjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eScsIGlkZW50aXR5KVxuICAgICMgT25lLXRpbWUgVUlEMC9DQVBfQ0hPV04gaW5pdGlhbGl6YXRpb24gaXMgaXNvbGF0ZWQgdG8gdGhlIE5FVyBuYW1lZCB2b2x1bWUuXG4gICAgIyBObyBob3N0L2xpdmUgUFZDL2NvbmZpZy90b2tlbiBtb3VudCBleGlzdHM7IHRoaXMgZGV0YWlsIG5lZWRzIHBhY2tldCByZXZpZXcuXG4gICAgaW5pdGlhbGl6ZXIgPSBcIlwiXCJpbXBvcnQgaGFzaGxpYixvcyxzdGF0LHN5c1xuaWYgc3lzLmZsYWdzLm9wdGltaXplOnJhaXNlIFJ1bnRpbWVFcnJvcignb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQnKVxuZm9sZGVyPScvcmVzdG9yZSc7ZXhwZWN0ZWQ9RVhQRUNURURcbmlmIG9zLmxpc3RkaXIoZm9sZGVyKTpyYWlzZSBWYWx1ZUVycm9yKCduZXcgZW1wdHkgcHJpdmF0ZSB2b2x1bWUgcmVxdWlyZWQnKVxub3MuY2htb2QoZm9sZGVyLDBvNzAwKVxuZmQ9b3Mub3Blbihmb2xkZXIrJy9yZXZpZXcuc3FsaXRlJyxvcy5PX0NSRUFUfG9zLk9fRVhDTHxvcy5PX05PRk9MTE9XfG9zLk9fV1JPTkxZLDBvNjAwKVxuZGlnZXN0PWhhc2hsaWIuc2hhMjU2KCk7c2l6ZT0wXG53aXRoIG9zLmZkb3BlbihmZCwnd2InKSBhcyB0YXJnZXQ6XG4gd2hpbGUgVHJ1ZTpcbiAgYmxvY2s9c3lzLnN0ZGluLmJ1ZmZlci5yZWFkKDEwMjQqKjIpXG4gIGlmIG5vdCBibG9jazpicmVha1xuICBzaXplKz1sZW4oYmxvY2spXG4gIGlmIHNpemU+NTEyKjEwMjQqKjI6cmFpc2UgVmFsdWVFcnJvcigncHJpdmF0ZSByZXN0b3JlIHNpemUgZXhjZWVkcyBib3VuZCcpXG4gIHRhcmdldC53cml0ZShibG9jayk7ZGlnZXN0LnVwZGF0ZShibG9jaylcbiB0YXJnZXQuZmx1c2goKTtvcy5mc3luYyh0YXJnZXQuZmlsZW5vKCkpXG5pZiBkaWdlc3QuaGV4ZGlnZXN0KCkhPWV4cGVjdGVkOnJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgY29waWVkIHNuYXBzaG90IGRpZmZlcnMnKVxub3MuY2hvd24oZm9sZGVyKycvcmV2aWV3LnNxbGl0ZScsMTAwMDEsMTAwMDEpO29zLmNob3duKGZvbGRlciwxMDAwMSwxMDAwMSlcbnByaW50KCd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwicHJpdmF0ZV9jb3B5X3ZlcmlmaWVkXCI6dHJ1ZX0nKVxuXCJcIlwiLnJlcGxhY2UoJ0VYUEVDVEVEJywgcmVwcihwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10pKVxuICAgIHdpdGggc25hcHNob3Qub3BlbigncmInKSBhcyBzb3VyY2U6XG4gICAgICAgIGFyZ3YgPSBbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVCxcbiAgICAgICAgICAgICAgICAncnVuJywgJy0tcm0nLCAnLWknLCAnLS1uZXR3b3JrJywgJ25vbmUnLCAnLS1yZWFkLW9ubHknLCAnLS1jcHVzJywgJzEnLCAnLS1tZW1vcnknLCAnMTI4bScsXG4gICAgICAgICAgICAgICAgJy0tdXNlcicsICcwOjAnLCAnLS1jYXAtZHJvcCcsICdBTEwnLCAnLS1jYXAtYWRkJywgJ0NIT1dOJyxcbiAgICAgICAgICAgICAgICAnLS1zZWN1cml0eS1vcHQnLCAnbm8tbmV3LXByaXZpbGVnZXMnLCAnLS1tb3VudCcsICd0eXBlPXZvbHVtZSxzcmM9JyArIFZPTFVNRSArICcsZHN0PS9yZXN0b3JlJyxcbiAgICAgICAgICAgICAgICAnLS1lbnRyeXBvaW50JywgJ3B5dGhvbicsIElNQUdFLCAnLWMnLCBpbml0aWFsaXplcl1cbiAgICAgICAgY29waWVkID0gc3VicHJvY2Vzcy5ydW4oYXJndiwgc3RkaW49c291cmNlLCB0ZXh0PVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRpbWVvdXQ9MTUwKVxuICAgIGpzb25fcmVzdWx0KGNvcGllZClcbiAgICBvcHRpb25zID0gWydydW4nLCAnLS1ybScsICctaScsICctLW5ldHdvcmsnLCAnbm9uZScsICctLXJlYWQtb25seScsICctLWNwdXMnLCAnMScsICctLW1lbW9yeScsICcxMjhtJyxcbiAgICAgICAgICAgICAgICctLXVzZXInLCAnMTAwMDE6MTAwMDEnLCAnLS1jYXAtZHJvcCcsICdBTEwnLCAnLS1zZWN1cml0eS1vcHQnLCAnbm8tbmV3LXByaXZpbGVnZXMnLFxuICAgICAgICAgICAgICAgJy0tbW91bnQnLCAndHlwZT12b2x1bWUsc3JjPScgKyBWT0xVTUUgKyAnLGRzdD0vcmVzdG9yZSddXG4gICAgcmVhZG9ubHkgPSBkb2NrZXIob3B0aW9ucyArIFsnLS1lbnRyeXBvaW50JywgJ3B5dGhvbicsIElNQUdFLCAnLScsICctLWRiJywgJy9yZXN0b3JlL3Jldmlldy5zcWxpdGUnXSxcbiAgICAgICAgICAgICAgICAgICAgICAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlYWRvbmx5LnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgcHJlLW9wZW4gc2NoZW1hL2ludGVncml0eSBnYXRlIHJlZnVzZWQ7IG5ldmVyIG9wZW4gU3RvcmUnKVxuICAgIGNoZWNrZWQgPSBjb3VudHMoanNvbi5sb2FkcyhyZWFkb25seS5zdGRvdXQpKVxuICAgIHJlcXVpcmUoY2hlY2tlZCA9PSBwcmV2aW91c1snc25hcHNob3RfcmVhZG9ubHknXSwgJ2Zyb3plbiBzbmFwc2hvdC9jbG9uZSByZWFkb25seSBjb3VudHMgZGlmZmVyJylcbiAgICBhZG1pbiA9IGRvY2tlcihvcHRpb25zICsgWyctLWVudHJ5cG9pbnQnLCAnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4nLCBJTUFHRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpbnNwZWN0JywgJy0tZGInLCAnL3Jlc3RvcmUvcmV2aWV3LnNxbGl0ZSddKVxuICAgIHJlcXVpcmUoYWRtaW4ucmV0dXJuY29kZSA9PSAwLCAnb2ZmbGluZSBhZG1pbiByZXN1bHQgdW5jZXJ0YWluJylcbiAgICBhZG1pbl9jb3VudHMgPSBqc29uLmxvYWRzKGFkbWluLnN0ZG91dClcbiAgICByZXF1aXJlKGFkbWluX2NvdW50cyA9PSB7a2V5OiBjaGVja2VkW2tleV0gZm9yIGtleSBpbiAoJ3NjaGVtYV92ZXJzaW9uJywgJ2xpZmVjeWNsZScsICdvdXRib3gnLCAnc3VibWlzc2lvbnMnKX0sXG4gICAgICAgICAgICAnb2ZmbGluZSBhZG1pbiBjaGFuZ2VkIGZyb3plbiBzbmFwc2hvdCBjb3VudGVycycpXG4gICAgIyBBZG1pbiBTdG9yZSBjb25zdHJ1Y3Rpb24gbXVzdCBub3Qgc2lsZW50bHkgYWx0ZXIgc2NoZW1hL2ludGVncml0eS9jb3VudGVycy5cbiAgICBwb3N0ID0gZG9ja2VyKG9wdGlvbnMgKyBbJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy0nLCAnLS1kYicsICcvcmVzdG9yZS9yZXZpZXcuc3FsaXRlJ10sXG4gICAgICAgICAgICAgICAgICAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHBvc3QucmV0dXJuY29kZSA9PSAwLCAnb2ZmbGluZSBwb3N0LWFkbWluIHJlYWRvbmx5IGludGVncml0eSBnYXRlIHJlZnVzZWQnKVxuICAgIHBvc3RfY2hlY2tlZCA9IGNvdW50cyhqc29uLmxvYWRzKHBvc3Quc3Rkb3V0KSlcbiAgICByZXF1aXJlKHBvc3RfY2hlY2tlZCA9PSBjaGVja2VkID09IHByZXZpb3VzWydzbmFwc2hvdF9yZWFkb25seSddLFxuICAgICAgICAgICAgJ29mZmxpbmUgYWRtaW4gYWx0ZXJlZCBmcm96ZW4gc25hcHNob3QgcHJvb2YnKVxuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcmVxdWlyZShzaGEoc25hcHNob3QpID09IHByZXZpb3VzWydzbmFwc2hvdF9zaGEyNTYnXSwgJ29yaWdpbmFsIHByb3RlY3RlZCBzbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyBkcmlsbCcpXG4gICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ29mZmxpbmVfdm9sdW1lJzogVk9MVU1FLCAnb2ZmbGluZV9yZWFkb25seSc6IGNoZWNrZWQsXG4gICAgICAgICAgICAnb2ZmbGluZV9wb3N0X2FkbWluX3JlYWRvbmx5JzogcG9zdF9jaGVja2VkLCAnb3JpZ2luYWxfc25hcHNob3RfaGFzaF91bmNoYW5nZWQnOiBUcnVlLFxuICAgICAgICAgICAgJ2NyZWF0ZWRfdm9sdW1lX2lkZW50aXR5JzogaWRlbnRpdHksXG4gICAgICAgICAgICAnYWRtaW5fY291bnRzJzogYWRtaW5fY291bnRzLCAnbmV0d29yayc6ICdub25lJywgJ3J1bnRpbWVfdG9rZW5zX29yX2NvbmZpZ19tb3VudGVkJzogRmFsc2UsXG4gICAgICAgICAgICAnc2VydmljZV9lbnRyeXBvaW50X3N0YXJ0ZWQnOiBGYWxzZSwgJ29yaWdpbmFsX3NuYXBzaG90X3JldGFpbmVkJzogVHJ1ZX1cblxuXG5kZWYgY2xlYW51cF9vZmZsaW5lKGpvdXJuYWwpOlxuICAgIGluc3BlY3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdpbnNwZWN0JywgVk9MVU1FXSlcbiAgICByZXF1aXJlKGluc3BlY3RlZC5yZXR1cm5jb2RlID09IDAsICdvd25lZCBkaXNwb3NhYmxlIHZvbHVtZSBpZGVudGl0eSB1bnZlcmlmaWVkJylcbiAgICB2YWx1ZSA9IGpzb24ubG9hZHMoaW5zcGVjdGVkLnN0ZG91dClcbiAgICBleHBlY3RlZCA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ29mZmxpbmUtdmVyaWZ5J11bJ3Jlc3VsdCddWydjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eSddXG4gICAgcmVxdWlyZShsZW4odmFsdWUpID09IDEgYW5kIHtrZXk6IHZhbHVlWzBdLmdldChrZXkpIGZvciBrZXkgaW4gZXhwZWN0ZWR9ID09IGV4cGVjdGVkXG4gICAgICAgICAgICBhbmQgbm90IHZhbHVlWzBdLmdldCgnT3B0aW9ucycpLCAndm9sdW1lIG93bmVyc2hpcC9yZWNyZWF0aW9uIGNoYW5nZWQnKVxuICAgIHJlbW92ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAncm0nLCBWT0xVTUVdKVxuICAgIHJlcXVpcmUocmVtb3ZlZC5yZXR1cm5jb2RlID09IDAgYW5kIHJlbW92ZWQuc3Rkb3V0LnN0cmlwKCkgPT0gVk9MVU1FXG4gICAgICAgICAgICBhbmQgZG9ja2VyKFsndm9sdW1lJywgJ2luc3BlY3QnLCBWT0xVTUVdKS5yZXR1cm5jb2RlICE9IDAsXG4gICAgICAgICAgICAnY2xlYW51cCBvdXRjb21lIGFtYmlndW91czsgZG8gbm90IHJldHJ5JylcbiAgICByZXR1cm4geydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlLCAnb25seV9kaXNwb3NhYmxlX29mZmxpbmVfdm9sdW1lX3JlbW92ZWQnOiBWT0xVTUUsXG4gICAgICAgICAgICAnbmF0aXZlX2FuZF9vZmZjbHVzdGVyX29yaWdpbmFsX3NuYXBzaG90c19yZXRhaW5lZCc6IFRydWV9XG5cblxuZGVmIG1haW4oKTpcbiAgICBwYXJzZXIgPSBhcmdwYXJzZS5Bcmd1bWVudFBhcnNlcihkZXNjcmlwdGlvbj1fX2RvY19fKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tcGhhc2UnLCBjaG9pY2VzPVBIQVNFUywgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXJvb3QtYXV0aG9yaXR5LXJlY2VpcHQnLCB0eXBlPVBhdGgsIHJlcXVpcmVkPVRydWUpXG4gICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1yb290LW5hdGl2ZS1vdXRjb21lJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tc291cmNlLXJldmlzaW9uJywgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBhcmdzID0gcGFyc2VyLnBhcnNlX2FyZ3MoKVxuICAgIHJlcXVpcmUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0ID09IFBhdGgoJy90bXAvc2VjdXJpdHktaW5mZC1wdXJwb3NlLXJvb3QtYXV0aG9yaXR5Lmpzb24nKVxuICAgICAgICAgICAgYW5kIGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZSA9PSBQYXRoKCcvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1uYXRpdmUtb3V0Y29tZS1sYXRlc3QuanNvbicpLFxuICAgICAgICAgICAgJ2ZpeGVkIHN1cGVydmlzZWQgcmVjZWlwdCBwYXRocyByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShyZS5mdWxsbWF0Y2gocidbMC05YS1mXXs0MH0nLCBhcmdzLnNvdXJjZV9yZXZpc2lvbikgaXMgbm90IE5vbmUsICdleGFjdCBzb3VyY2UgY29tbWl0IHJlcXVpcmVkJylcbiAgICAjIFZlcmlmeSBhbGwgcHJlcGFyZWQgZXhlY3V0b3IvaW5wdXQgYnl0ZXMgYmVmb3JlIHJlYWRpbmcgYXV0aG9yaXR5IG9yIGRpc3BhdGNoaW5nLlxuICAgIHBsYW4gPSBqc29uLmxvYWRzKChST09UIC8gJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHNldChwbGFuWydleGVjdXRvcl9maWxlcyddKSA9PSB7J2FjdHVhdG9yLnB5JywgJ2F1dGhvcml0eV9qb3VybmFsLnB5JywgJ25hdGl2ZV9wcm9ncmFtLnB5JywgJ3JlY2VpcHRfc2FmZXR5LnB5J30sXG4gICAgICAgICAgICAnZml4ZWQgZXhlY3V0b3Igc291cmNlcyByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShzZXQocGxhblsnb3duZXJfc291cmNlX2ZpbGVzJ10pID09IHsnZGVwbG95L2xpZmVjeWNsZS9hZG1pc3Npb24uY2FuZGlkYXRlLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL2t1c3RvbWl6YXRpb24ueWFtbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RlcGxveS9saWZlY3ljbGUvcmVnaXN0cmllcy5jYW5kaWRhdGUuanNvbid9LFxuICAgICAgICAgICAgJ2ZpeGVkIG93bmVyIGltYWdlIHNvdXJjZXMgcmVxdWlyZWQnKVxuICAgIGZvciByZWxhdGl2ZSwgZGlnZXN0IGluIHBsYW5bJ2V4ZWN1dG9yX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgdGFyZ2V0ID0gUk9PVCAvIHJlbGF0aXZlXG4gICAgICAgIHJlcXVpcmUobm90IHRhcmdldC5pc19zeW1saW5rKCkgYW5kIHNoYSh0YXJnZXQpID09IGRpZ2VzdCwgJ2V4ZWN1dG9yIHNvdXJjZSBieXRlcyBjaGFuZ2VkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydjYXNlX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgcmVxdWlyZShub3QgUGF0aChyZWxhdGl2ZSkuaXNfYWJzb2x1dGUoKSBhbmQgJy4uJyBub3QgaW4gUGF0aChyZWxhdGl2ZSkucGFydHMsXG4gICAgICAgICAgICAgICAgJ2Nhc2Ugc291cmNlIHBhdGggZXNjYXBlZCcpXG4gICAgICAgIHRhcmdldCA9IENBU0UgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdjYXNlIHNvdXJjZSBieXRlcyBjaGFuZ2VkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydvd25lcl9zb3VyY2VfZmlsZXMnXS5pdGVtcygpOlxuICAgICAgICB0YXJnZXQgPSBPV05FUiAvIHJlbGF0aXZlXG4gICAgICAgIHJlcXVpcmUobm90IHRhcmdldC5pc19zeW1saW5rKCkgYW5kIHNoYSh0YXJnZXQpID09IGRpZ2VzdCwgJ293bmVyIGltYWdlLW9ubHkgc291cmNlIGNoYW5nZWQnKVxuICAgICAgICBjb21taXR0ZWQgPSBzdWJwcm9jZXNzLnJ1bihbJ2dpdCcsICctQycsIHN0cihPV05FUiksICdzaG93JywgYXJncy5zb3VyY2VfcmV2aXNpb24gKyAnOicgKyByZWxhdGl2ZV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVfb3V0cHV0PVRydWUpXG4gICAgICAgIHJlcXVpcmUoY29tbWl0dGVkLnJldHVybmNvZGUgPT0gMCBhbmQgaGFzaGxpYi5zaGEyNTYoY29tbWl0dGVkLnN0ZG91dCkuaGV4ZGlnZXN0KCkgPT0gZGlnZXN0LFxuICAgICAgICAgICAgICAgICdjb21taXR0ZWQgb3duZXIgcmVuZGVyIHNvdXJjZSBkaWZmZXJzIGZyb20gYXBwcm92ZWQgaW5wdXRzJylcbiAgICBoZWFkID0gcnVuKFsnZ2l0JywgJy1DJywgc3RyKE9XTkVSKSwgJ3Jldi1wYXJzZScsICdIRUFEJ10pXG4gICAgcmVxdWlyZShoZWFkLnJldHVybmNvZGUgPT0gMCBhbmQgaGVhZC5zdGRvdXQuc3RyaXAoKSA9PSBhcmdzLnNvdXJjZV9yZXZpc2lvbiwgJ293bmVyIHNvdXJjZSBIRUFEIGRpZmZlcnMnKVxuICAgIGZyb20gYXV0aG9yaXR5X2pvdXJuYWwgaW1wb3J0IEpvdXJuYWwsIGF1dGhvcml0eVxuICAgIHByaXZhdGUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0KVxuICAgIHByaXZhdGUoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKVxuICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlY2VpcHQuZ2V0KCduYXRpdmVfb3V0Y29tZV9zaGEyNTYnKSA9PSBzaGEoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKSwgJ25hdGl2ZSBvdXRjb21lIGJ5dGVzIGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ2V4ZWN1dG9yX3BsYW5fc2hhMjU2JykgPT0gc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgJ3Jvb3QgdmVyaWZpZWQgZXhlY3V0b3IgcGxhbiBkaWZmZXJzJylcbiAgICBhcHByb3ZlZCA9IGF1dGhvcml0eShyZWNlaXB0LCBqc29uLmxvYWRzKGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZS5yZWFkX3RleHQoKSksIHNoYShDQVNFIC8gJ21lbW8uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcmdzLnBoYXNlKVxuICAgIHBhcmVudCA9IENVU1RPRFkucGFyZW50XG4gICAgcHJpdmF0ZShwYXJlbnQsIGRpcmVjdG9yeT1UcnVlKVxuICAgIGlnbm9yZWQgPSBydW4oWydnaXQnLCAnLUMnLCBzdHIoQ1VTVE9ESUFOKSwgJ2NoZWNrLWlnbm9yZScsICctLW5vLWluZGV4Jywgc3RyKENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJyldKVxuICAgIHJlcXVpcmUoaWdub3JlZC5yZXR1cm5jb2RlID09IDAsICdvZmZjbHVzdGVyIGN1c3RvZHkgaXMgbm90IGlnbm9yZWQnKVxuICAgIGlmIG5vdCBDVVNUT0RZLmV4aXN0cygpOlxuICAgICAgICByZXF1aXJlKGFyZ3MucGhhc2UgPT0gJ2RyaWxsLWJhY2t1cCcsICdmaXJzdCBhcHByb3ZlZCBwaGFzZSBtdXN0IGNyZWF0ZSB1bmlxdWUgcHJpdmF0ZSBjdXN0b2R5JylcbiAgICAgICAgb3MubWtkaXIoQ1VTVE9EWSwgMG83MDApXG4gICAgcHJpdmF0ZShDVVNUT0RZLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICBjYXBhY2l0eSA9IG9zLnN0YXR2ZnMoQ1VTVE9EWSlcbiAgICByZXF1aXJlKGNhcGFjaXR5LmZfYmF2YWlsICogY2FwYWNpdHkuZl9mcnNpemUgPj0gMiAqIE1BWF9CWVRFUyArIDE2ICogMTAyNCoqMixcbiAgICAgICAgICAgICdpbmRlcGVuZGVudCBwcm90ZWN0ZWQgY3VzdG9keSBoZWFkcm9vbSBpbnN1ZmZpY2llbnQnKVxuICAgIG9zLm1ha2VkaXJzKENVU1RPRFkgLyAnZW1wdHktZG9ja2VyLWNvbmZpZycsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpXG4gICAgcHJpdmF0ZShDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICByZXF1aXJlKG5vdCBsaXN0KChDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKS5pdGVyZGlyKCkpLCAncHVibGljIERvY2tlciByZWFkIGNvbmZpZyBtdXN0IHN0YXkgZW1wdHknKVxuICAgIGpvdXJuYWwgPSBKb3VybmFsKENVU1RPRFksIHsncHJvcG9zYWwnOiBwbGFuWydwcm9wb3NhbF9pZCddLCAnc291cmNlX3JldmlzaW9uJzogYXJncy5zb3VyY2VfcmV2aXNpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21lbW9fc2hhMjU2Jzogc2hhKENBU0UgLyAnbWVtby5qc29uJyksICdwbGFuX3NoYTI1Nic6IHNoYShST09UIC8gJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKX0pXG4gICAgdHJ5OlxuICAgICAgICBqb3VybmFsLnN0YXJ0KGFyZ3MucGhhc2UsIGFwcHJvdmVkKSAjIGZzeW5jZWQgUlVOTklORyBiZWZvcmUgYW55IHBoYXNlIGVmZmVjdC5cbiAgICAgICAgaWYgYXJncy5waGFzZSBpbiAoJ2RyaWxsLWNvcHknLCAnY3V0b3Zlci1jb3B5Jyk6XG4gICAgICAgICAgICByZXN1bHQgPSBjb3B5X3NuYXBzaG90KGFyZ3MucGhhc2UsIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcHByb3ZlZCwgam91cm5hbClcbiAgICAgICAgZWxpZiBhcmdzLnBoYXNlID09ICdvZmZsaW5lLXZlcmlmeSc6XG4gICAgICAgICAgICByZXN1bHQgPSBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKVxuICAgICAgICBlbGlmIGFyZ3MucGhhc2UgPT0gJ2NsZWFudXAtb2ZmbGluZSc6XG4gICAgICAgICAgICByZXN1bHQgPSBjbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgZWxzZTpcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlbW90ZShhcmdzLnBoYXNlLCBhcmdzLnNvdXJjZV9yZXZpc2lvbiwgYXBwcm92ZWQpXG4gICAgICAgIGpvdXJuYWwuZmluaXNoKGFyZ3MucGhhc2UsIHJlc3VsdClcbiAgICAgICAgcHJpbnQoanNvbi5kdW1wcyhyZXN1bHQpKSAjIE9ubHkgY291bnQvaGFzaC9pZGVudGl0eSByZWNlaXB0cywgbmV2ZXIgc25hcHNob3QgYnl0ZXMuXG4gICAgZXhjZXB0IEJhc2VFeGNlcHRpb24gYXMgZXJyb3I6XG4gICAgICAgIHNhZmUgPSB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncGhhc2UnOiBhcmdzLnBoYXNlLCAnZmFpbHVyZV9jbGFzcyc6IHR5cGUoZXJyb3IpLl9fbmFtZV9fLFxuICAgICAgICAgICAgICAgICdmYWlsdXJlJzogJ2ZpeGVkIHBoYXNlIG91dGNvbWUgdW5jZXJ0YWluOyBvcmlnaW5hbCBldmlkZW5jZSByZXRhaW5lZDsgbm8gcmV0cnknLFxuICAgICAgICAgICAgICAgICdyYXdfb3V0cHV0X3dpdGhoZWxkJzogVHJ1ZX1cbiAgICAgICAgaWYgam91cm5hbC5kYXRhWydwaGFzZXMnXS5nZXQoYXJncy5waGFzZSwge30pLmdldCgnc3RhdGUnKSA9PSAnUlVOTklORyc6XG4gICAgICAgICAgICBqb3VybmFsLmZpbmlzaChhcmdzLnBoYXNlLCBzYWZlKVxuICAgICAgICBwcmludChqc29uLmR1bXBzKHNhZmUpKVxuICAgICAgICByYWlzZSBTeXN0ZW1FeGl0KDEpIGZyb20gTm9uZVxuICAgIGZpbmFsbHk6XG4gICAgICAgIGpvdXJuYWwuY2xvc2UoKVxuXG5cbmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6XG4gICAgdHJ5OlxuICAgICAgICBtYWluKClcbiAgICBleGNlcHQgRXhjZXB0aW9uOlxuICAgICAgICByYWlzZSBTeXN0ZW1FeGl0KCdzdXBlcnZpc2VkIGV4ZWN1dGlvbiByZWZ1c2VkIGJlZm9yZSBwaGFzZTsgcmF3IG91dHB1dCB3aXRoaGVsZCcpIGZyb20gTm9uZVxuIgogICAgfSwKICAgICJhdXRob3JpdHlfam91cm5hbC5weSI6IHsKICAgICAgInNoYTI1NiI6ICI3NGQ2YTkxMTY5Mjk2YTk5ZmE3ZGFjMmQwOTAyNTY3MjgwZjkxMGFmNzQzNTgwZWM0YjQ1NGYyYWJmODM3NGFhIiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiU3VwZXJ2aXNlZCByZWNlaXB0IGJvb2trZWVwaW5nLCBub3QgYW4gYXV0aGVudGljYXRlZCBhcHByb3ZhbCBwcm92aWRlci5cIlwiXCJcbmltcG9ydCBkYXRldGltZVxuaW1wb3J0IGZjbnRsXG5pbXBvcnQgaGFzaGxpYlxuaW1wb3J0IGpzb25cbmltcG9ydCBvc1xuaW1wb3J0IHJlXG5mcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGhcbmltcG9ydCBzdGF0XG5pbXBvcnQgdXVpZFxuXG5GT1VOREVSID0geydraW5kJzogJ3BlcnNvbicsICdzdWInOiAndWlkPXBsYXRmb3JtLXJvb3Qsb3U9cGVvcGxlLGRjPW5ldGtpbmdkb20sZGM9bG9jYWwnfVxuTUVNT19JRCA9ICdpbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMSdcblBST1BPU0FMID0gJ0lORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxJ1xuUEhBU0VTID0gKCdkcmlsbC1iYWNrdXAnLCAnZHJpbGwtY29weScsICdvZmZsaW5lLXZlcmlmeScsICdjbGVhbnVwLW9mZmxpbmUnLFxuICAgICAgICAgICdjdXRvdmVyLWJhY2t1cCcsICdjdXRvdmVyLWNvcHknLCAncmVsZWFzZScsICd2ZXJpZnknLCAncm9sbGJhY2snLCAncm9sbGJhY2stdmVyaWZ5JylcblxuXG5kZWYgcmVxdWlyZSh2YWx1ZSwgcmVhc29uKTpcbiAgICBpZiBub3QgdmFsdWU6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IocmVhc29uKVxuXG5cbmRlZiBzaGEocGF0aCk6XG4gICAgZGlnZXN0ID0gaGFzaGxpYi5zaGEyNTYoKVxuICAgIHdpdGggUGF0aChwYXRoKS5vcGVuKCdyYicpIGFzIHN0cmVhbTpcbiAgICAgICAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOiBzdHJlYW0ucmVhZCgxMDI0KioyKSwgYicnKTpcbiAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUoYmxvY2spXG4gICAgcmV0dXJuIGRpZ2VzdC5oZXhkaWdlc3QoKVxuXG5cbmRlZiBwcml2YXRlKHBhdGgsIGRpcmVjdG9yeT1GYWxzZSk6XG4gICAgaW5mbyA9IFBhdGgocGF0aCkubHN0YXQoKVxuICAgIHJlcXVpcmUoKHN0YXQuU19JU0RJUihpbmZvLnN0X21vZGUpIGlmIGRpcmVjdG9yeSBlbHNlIHN0YXQuU19JU1JFRyhpbmZvLnN0X21vZGUpKVxuICAgICAgICAgICAgYW5kIGluZm8uc3RfdWlkID09IG9zLmdldHVpZCgpIGFuZCBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKSA9PSAoMG83MDAgaWYgZGlyZWN0b3J5IGVsc2UgMG82MDApXG4gICAgICAgICAgICBhbmQgKGRpcmVjdG9yeSBvciBpbmZvLnN0X25saW5rID09IDEpLCAncHJpdmF0ZSBvd25lZCBjdXN0b2R5IHJlcXVpcmVkJylcblxuXG5kZWYgYXV0aG9yaXR5KHJlY2VpcHQsIG91dGNvbWUsIG1lbW9fc2hhLCBzb3VyY2VfcmV2aXNpb24sIHBoYXNlLCBub3c9Tm9uZSk6XG4gICAgXCJcIlwiUm9vdCBtdXN0IGZyZXNobHkgdmVyaWZ5IG5hdGl2ZSBvdXRjb21lIGF0IGZpeGVkIE9SSUdJTiBvdXRzaWRlIHRoaXMgaGVscGVyLlxuXG4gICAgUmVjZWlwdCBmaWxlcy9mbGFncyBhcmUgbm90IHNpZ25lZCBncmFudHMuIFRoaXMgZnVuY3Rpb24gY2hlY2tzIHRoZSBleGFjdFxuICAgIHN1cGVydmlzZWQgcmVjZWlwdCByZWxhdGlvbjsgZXhpc3RpbmcgaGFybmVzcy9mb3VuZGVyIGF1dGhvcml0eSByZW1haW5zIHRoZVxuICAgIGFjdHVhbCBwZXJtaXNzaW9uIGJvdW5kYXJ5LiBJdCBuZXZlciBhdXRoZW50aWNhdGVzIGEgY2FsbGVyIGFzIGh1bWFuLlxuICAgIFwiXCJcIlxuICAgIG5vdyA9IG5vdyBvciBkYXRldGltZS5kYXRldGltZS5ub3coZGF0ZXRpbWUudGltZXpvbmUudXRjKVxuICAgIHJlcXVpcmUocGhhc2UgaW4gUEhBU0VTLCAnZml4ZWQgcGhhc2UgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ3Byb3Bvc2FsX2lkJykgPT0gUFJPUE9TQUwgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX2lkJykgPT0gTUVNT19JRFxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX3ZlcnNpb24nKSA9PSAxIGFuZCByZWNlaXB0LmdldCgnbWVtb19zaGEyNTYnKSA9PSBtZW1vX3NoYVxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdzb3VyY2VfcmV2aXNpb24nKSA9PSBzb3VyY2VfcmV2aXNpb25cbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgnYWN0aXZhdGlvbicpID09ICdBUFBST1ZFRCdcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgnYXV0aG9yaXR5X21vZGUnKSA9PSAnQURNSU5JU1RFUidcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgndGFyZ2V0JykgPT0gJ3JlYWxtOmt1YmVybmV0ZXMvcmFpbGlhbmNlMDEvaW5mb3JtZWQtZGVjaXNpb24nXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3ZlcmlmaWNhdGlvbl9tZXRob2QnKSA9PSAncm9vdC1maXhlZC1vcmlnaW4tbmF0aXZlLXJlYWRiYWNrJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdydW50aW1lX2F1dGhlbnRpY2F0ZWRfZ3JhbnQnKSBpcyBGYWxzZSxcbiAgICAgICAgICAgICdleGFjdCBleHRlcm5hbGx5IHZlcmlmaWVkIHN1cGVydmlzZWQgcmVjZWlwdCByZXF1aXJlZCcpXG4gICAgdmVyaWZpZWQgPSBkYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KHJlY2VpcHRbJ3ZlcmlmaWVkX2F0J10ucmVwbGFjZSgnWicsICcrMDA6MDAnKSlcbiAgICByZXF1aXJlKHZlcmlmaWVkLnR6aW5mbyBpcyBub3QgTm9uZSBhbmQgMCA8PSAobm93IC0gdmVyaWZpZWQpLnRvdGFsX3NlY29uZHMoKSA8PSAxMjAsXG4gICAgICAgICAgICAnZnJlc2ggcm9vdCBuYXRpdmUgcmVhZGJhY2sgcmVxdWlyZWQgYmVmb3JlIGV2ZXJ5IHBoYXNlJylcbiAgICBkZWFkbGluZSA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQoJzIwMjYtMTAtMTJUMjM6NTk6NTkrMDA6MDAnKVxuICAgIHJlcXVpcmUobm93IDwgZGVhZGxpbmUsICdhcHByb3ZlZCBleGVjdXRpb24gd2luZG93IGV4cGlyZWQnKVxuICAgIHJlcXVpcmUob3V0Y29tZS5nZXQoJ21lbW9faWQnKSA9PSBNRU1PX0lEIGFuZCBvdXRjb21lLmdldCgncmV2aWV3Jywge30pLmdldCgnc3RhbGUnKSBpcyBGYWxzZVxuICAgICAgICAgICAgYW5kIG91dGNvbWVbJ3JldmlldyddLmdldCgnaW50YWtlX3N0YXRlJykgPT0gJ3JlYWR5JywgJ25hdGl2ZSByZXZpZXcgaXMgbm90IHJlYWR5L2N1cnJlbnQnKVxuICAgIHJldmlld19pZCA9IG91dGNvbWVbJ3JldmlldyddWydtZW1vX2lkJ11cbiAgICByZXF1aXJlKHJldmlld19pZCA9PSByZWNlaXB0LmdldCgncmV2aWV3X21lbW9faWQnKSwgJ25hdGl2ZSByZXZpZXcgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgYWNjZXB0ZWQgPSBbeCBmb3IgeCBpbiBvdXRjb21lLmdldCgnZGlzcG9zaXRpb25zJywgW10pXG4gICAgICAgICAgICAgICAgaWYgeC5nZXQoJ3N1Ym1pc3Npb25fc3RhdGUnKSA9PSAnY29uZmlybWVkJ1xuICAgICAgICAgICAgICAgIGFuZCB4LmdldCgnZGlzcG9zaXRpb24nLCB7fSkuZ2V0KCd2ZXJiJykgPT0gJ2FjY2VwdCdcbiAgICAgICAgICAgICAgICBhbmQgeFsnZGlzcG9zaXRpb24nXS5nZXQoJ21lbW9fdmVyc2lvbicpID09IDFdXG4gICAgcmVxdWlyZShsZW4oYWNjZXB0ZWQpID09IDEsICdvbmUgY29uZmlybWVkIGZvdW5kZXIgYWNjZXB0YW5jZSByZXF1aXJlZCcpXG4gICAgYWNjZXB0ZWQgPSBhY2NlcHRlZFswXVsnZGlzcG9zaXRpb24nXVxuICAgIHJlcXVpcmUoYWNjZXB0ZWQuZ2V0KCdhY3RvcicpID09IEZPVU5ERVIgYW5kIGFjY2VwdGVkLmdldCgnbWVtb19pZCcpID09IHJldmlld19pZFxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnYXBwcm92YWxfaWQnKSA9PSByZWNlaXB0LmdldCgnYXBwcm92YWxfaWQnKVxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnaWQnKSA9PSByZWNlaXB0LmdldCgnZGlzcG9zaXRpb25faWQnKVxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnYXQnKSA9PSByZWNlaXB0LmdldCgnYWNjZXB0ZWRfYXQnKSwgJ2V4YWN0IGZvdW5kZXIgZGlzcG9zaXRpb24gbWlzbWF0Y2gnKVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOS1dezM2fScsIGFjY2VwdGVkWydhcHByb3ZhbF9pZCddKSBpcyBub3QgTm9uZVxuICAgICAgICAgICAgYW5kIHJlLmZ1bGxtYXRjaChyJ2Rpc3AtW2EtZjAtOS1dezM2fScsIGFjY2VwdGVkWydpZCddKSBpcyBub3QgTm9uZVxuICAgICAgICAgICAgYW5kIHJlLmZ1bGxtYXRjaChyJ3Jldmlldy1bYS1mMC05LV17MzZ9JywgcmV2aWV3X2lkKSBpcyBub3QgTm9uZSxcbiAgICAgICAgICAgICduYXRpdmUgZGlzcG9zaXRpb24gaWRlbnRpZmllcnMgYXJlIG1hbGZvcm1lZCcpXG4gICAgYWNjZXB0ZWRfYXQgPSBkYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KGFjY2VwdGVkWydhdCddLnJlcGxhY2UoJ1onLCAnKzAwOjAwJykpXG4gICAgcmVxdWlyZShhY2NlcHRlZF9hdC50emluZm8gaXMgbm90IE5vbmUgYW5kIGFjY2VwdGVkX2F0IDw9IHZlcmlmaWVkLCAnYWNjZXB0YW5jZSB0aW1lIG5vdCBib3VuZGVkJylcbiAgICByZXR1cm4ge2tleTogcmVjZWlwdFtrZXldIGZvciBrZXkgaW4gKCdhcHByb3ZhbF9pZCcsICdkaXNwb3NpdGlvbl9pZCcsICdhY2NlcHRlZF9hdCcsICd2ZXJpZmllZF9hdCcpfVxuXG5cbmNsYXNzIEpvdXJuYWw6XG4gICAgZGVmIF9faW5pdF9fKHNlbGYsIHBhcmVudCwgaWRlbnRpdHkpOlxuICAgICAgICBzZWxmLnBhcmVudCA9IFBhdGgocGFyZW50KVxuICAgICAgICBwcml2YXRlKHNlbGYucGFyZW50LCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICAgICAgc2VsZi5wYXRoID0gc2VsZi5wYXJlbnQgLyAnZXhlY3V0aW9uLWpvdXJuYWwuanNvbidcbiAgICAgICAgc2VsZi5sb2NrID0gb3Mub3BlbihzZWxmLnBhcmVudCAvICdleGVjdXRpb24ubG9jaycsIG9zLk9fQ1JFQVQgfCBvcy5PX05PRk9MTE9XIHwgb3MuT19SRFdSLCAwbzYwMClcbiAgICAgICAgZmNudGwuZmxvY2soc2VsZi5sb2NrLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQilcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCAvICdleGVjdXRpb24ubG9jaycpXG4gICAgICAgIGlmIHNlbGYucGF0aC5leGlzdHMoKTpcbiAgICAgICAgICAgIHByaXZhdGUoc2VsZi5wYXRoKVxuICAgICAgICAgICAgc2VsZi5kYXRhID0ganNvbi5sb2FkcyhzZWxmLnBhdGgucmVhZF90ZXh0KCkpXG4gICAgICAgICAgICByZXF1aXJlKHNlbGYuZGF0YVsnaWRlbnRpdHknXSA9PSBpZGVudGl0eSwgJ2pvdXJuYWwgY2FzZS9zb3VyY2UgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgICAgIGVsc2U6XG4gICAgICAgICAgICBzZWxmLmRhdGEgPSB7J2lkZW50aXR5JzogaWRlbnRpdHksICdwaGFzZXMnOiB7fX1cbiAgICAgICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgc2F2ZShzZWxmKTpcbiAgICAgICAgdGVtcG9yYXJ5ID0gc2VsZi5wYXJlbnQgLyAnZXhlY3V0aW9uLWpvdXJuYWwubmV3J1xuICAgICAgICBmZCA9IG9zLm9wZW4odGVtcG9yYXJ5LCBvcy5PX0NSRUFUIHwgb3MuT19FWENMIHwgb3MuT19OT0ZPTExPVyB8IG9zLk9fV1JPTkxZLCAwbzYwMClcbiAgICAgICAgdHJ5OlxuICAgICAgICAgICAgd2l0aCBvcy5mZG9wZW4oZmQsICd3JykgYXMgc3RyZWFtOlxuICAgICAgICAgICAgICAgIGpzb24uZHVtcChzZWxmLmRhdGEsIHN0cmVhbSwgaW5kZW50PTIpXG4gICAgICAgICAgICAgICAgc3RyZWFtLndyaXRlKCdcXG4nKVxuICAgICAgICAgICAgICAgIHN0cmVhbS5mbHVzaCgpXG4gICAgICAgICAgICAgICAgb3MuZnN5bmMoc3RyZWFtLmZpbGVubygpKVxuICAgICAgICAgICAgb3MucmVwbGFjZSh0ZW1wb3JhcnksIHNlbGYucGF0aClcbiAgICAgICAgICAgIGRpcmVjdG9yeSA9IG9zLm9wZW4oc2VsZi5wYXJlbnQsIG9zLk9fRElSRUNUT1JZIHwgb3MuT19SRE9OTFkpXG4gICAgICAgICAgICB0cnk6XG4gICAgICAgICAgICAgICAgb3MuZnN5bmMoZGlyZWN0b3J5KVxuICAgICAgICAgICAgZmluYWxseTpcbiAgICAgICAgICAgICAgICBvcy5jbG9zZShkaXJlY3RvcnkpXG4gICAgICAgIGV4Y2VwdCBCYXNlRXhjZXB0aW9uOlxuICAgICAgICAgICAgIyBSZXRhaW4gZXZpZGVuY2UgcmF0aGVyIHRoYW4gb3ZlcndyaXRpbmcgYW4gdW5jZXJ0YWluIGR1cmFibGUgaW50ZW50LlxuICAgICAgICAgICAgcmFpc2VcblxuICAgIGRlZiBzdGFydChzZWxmLCBwaGFzZSwgYXBwcm92YWwpOlxuICAgICAgICByZXF1aXJlKHBoYXNlIG5vdCBpbiBzZWxmLmRhdGFbJ3BoYXNlcyddLCAnYWxyZWFkeSBhdHRlbXB0ZWQgcGhhc2U7IG5vIHJldHJ5JylcbiAgICAgICAgcHJlZGVjZXNzb3JzID0gZGljdCh6aXAoUEhBU0VTWzE6OF0sIFBIQVNFU1s6N10pKVxuICAgICAgICBwcmVkZWNlc3NvcnNbJ3JvbGxiYWNrLXZlcmlmeSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICBpZiBwaGFzZSBpbiBwcmVkZWNlc3NvcnM6XG4gICAgICAgICAgICByZXF1aXJlKHNlbGYuZGF0YVsncGhhc2VzJ10uZ2V0KHByZWRlY2Vzc29yc1twaGFzZV0sIHt9KS5nZXQoJ3N0YXRlJykgPT0gJ0NPTVBMRVRFJyxcbiAgICAgICAgICAgICAgICAgICAgJ3ByZWNlZGluZyBwaGFzZSBpcyBub3QgdmVyaWZpZWQgY29tcGxldGUnKVxuICAgICAgICBpZiBwaGFzZSA9PSAncm9sbGJhY2snOlxuICAgICAgICAgICAgcmVxdWlyZSgncmVsZWFzZScgaW4gc2VsZi5kYXRhWydwaGFzZXMnXSwgJ3JvbGxiYWNrIHJlcXVpcmVzIGEgcmVjb3JkZWQgcmVsZWFzZSBhdHRlbXB0JylcbiAgICAgICAgc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV0gPSB7J3N0YXRlJzogJ1JVTk5JTkcnLCAnYXBwcm92YWwnOiBhcHByb3ZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2F0dGVtcHRfaWQnOiBzdHIodXVpZC51dWlkNCgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0YXJ0ZWRfYXQnOiBkYXRldGltZS5kYXRldGltZS5ub3coZGF0ZXRpbWUudGltZXpvbmUudXRjKS5pc29mb3JtYXQoKX1cbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBub3RlKHNlbGYsIHBoYXNlLCBrZXksIHZhbHVlKTpcbiAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVsnc3RhdGUnXSA9PSAnUlVOTklORycsICdwaGFzZSBpbnRlbnQgbWlzc2luZycpXG4gICAgICAgIHNlbGYuZGF0YVsncGhhc2VzJ11bcGhhc2VdW2tleV0gPSB2YWx1ZVxuICAgICAgICBzZWxmLnNhdmUoKVxuXG4gICAgZGVmIGZpbmlzaChzZWxmLCBwaGFzZSwgcmVzdWx0KTpcbiAgICAgICAgZW50cnkgPSBzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVxuICAgICAgICByZXF1aXJlKGVudHJ5WydzdGF0ZSddID09ICdSVU5OSU5HJywgJ3BoYXNlIGludGVudCBtaXNzaW5nJylcbiAgICAgICAgZW50cnlbJ3Jlc3VsdCddID0gcmVzdWx0XG4gICAgICAgIGVudHJ5WydzdGF0ZSddID0gJ0NPTVBMRVRFJyBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgJ1VOQ0VSVEFJTidcbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBjbG9zZShzZWxmKTpcbiAgICAgICAgb3MuY2xvc2Uoc2VsZi5sb2NrKVxuIgogICAgfSwKICAgICJleGVjdXRpb24tcGxhbi5qc29uIjogewogICAgICAic2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwia2luZFwiOiBcImluZm9ybWVkLWRlY2lzaW9uLnN1cGVydmlzZWQtbWVjaGFuaWNhbC1yZWxlYXNlLXBsYW5cIixcbiAgXCJ2ZXJzaW9uXCI6IDEsXG4gIFwicHJvcG9zYWxfaWRcIjogXCJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MVwiLFxuICBcInRyaWFsX2lkXCI6IFwiaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxXCIsXG4gIFwic3RhdGVcIjogXCJwcmVwYXJlZC11bmFwcHJvdmVkXCIsXG4gIFwiZXhlY3V0b3JfZmlsZXNcIjoge1xuICAgIFwiYWN0dWF0b3IucHlcIjogXCI2YjlkNjQzOTg2MjQ1NGYyNjFlZTc3ZjA1YjI2NTE5ZjgxMDk1OTliMWY2NzA3OGJjNGUxZjdjN2M0MDYxYmE1XCIsXG4gICAgXCJhdXRob3JpdHlfam91cm5hbC5weVwiOiBcIjc0ZDZhOTExNjkyOTZhOTlmYTdkYWMyZDA5MDI1NjcyODBmOTEwYWY3NDM1ODBlYzRiNDU0ZjJhYmY4Mzc0YWFcIixcbiAgICBcIm5hdGl2ZV9wcm9ncmFtLnB5XCI6IFwiMzQ5ZjUxNmE0ZTU1ZjdmYjQ3NDcwMTQ0Y2U3ODFhNjY1ZmIwMDNlYmZmMzgwZDA1NGY2NDJiMjIxMzNkMWNkZVwiLFxuICAgIFwicmVjZWlwdF9zYWZldHkucHlcIjogXCI1YzU0MzczZjJkYzRiMDY0MDA4MjI1YzE4NmVmYjFkNWFmZGVlYzM2ZDE1MzUwYmRhMGExMmRlZDk3NjAyZDFiXCJcbiAgfSxcbiAgXCJjYXNlX2ZpbGVzXCI6IHtcbiAgICBcImNoYW5nZV9ndWFyZC5weVwiOiBcImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmVcIixcbiAgICBcInNxbGl0ZV9yZWFkb25seS5weVwiOiBcImVlZjUzZGQyMzNlZWU3NGMxN2YyMDgyM2JkN2Y1Nzg3YzYwY2FkNzlhYzY0ODAyMWM5NDc5NjQzYzZjZTllMzhcIixcbiAgICBcInByZWZsaWdodC1pbnB1dHMuanNvblwiOiBcIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDZcIixcbiAgICBcInNlYWxlZC1saXZlLWRlcGxveW1lbnQuanNvblwiOiBcImQxOGQyNzA2M2QwNmY1MzVhZTg4NGVhMDFmOTY3NDdmZTMwMTY4NTUxOGFiOTRiMWNiYTA3MmExZTE1MTkzNjJcIixcbiAgICBcInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb25cIjogXCIwNDIzMjdhMDM2ZWQyNTRjZjk1ZGJlYjBjMDU2YWMyNWIwM2E2YTg0NGI5NWEzMzJjOTkyZGYyOTQzNjkxMzY5XCIsXG4gICAgXCJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uXCI6IFwiNzIyYThlMmRjNTJiZWMyMTdiZjk2MGUyM2IyZmRkZmM3YWMyN2QzNDNhYzg3NDM3OTBlMzE4M2RiODFhNmEwZVwiLFxuICAgIFwicm9sbGJhY2stZGVwbG95bWVudC5qc29uXCI6IFwiMzliM2Y0M2JiODRlZjQ5MjFjYzNhMWZiY2RjNDQ0NjEwNzQxZWQ4ODA5MTQ5ZDhmOGYxN2VkODA1ZjI2MjEyMVwiLFxuICAgIFwiY2hlY2tfaW5zdGFsbGVkLnB5XCI6IFwiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZFwiLFxuICAgIFwicHVibGlzaGVkLXZlcmlmaWNhdGlvbi5qc29uXCI6IFwiOGE2NzZjMzhmODlmOWNhNzYyYjhlYmU5NDViNWFjYjkwZDQ3YTRjYjM1MDY5MjY4N2FiYjk4NWJiYjJkOGFlMlwiLFxuICAgIFwic2VjdXJpdHktc3VtbWFyeS5qc29uXCI6IFwiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NFwiXG4gIH0sXG4gIFwib3duZXJfc291cmNlX2ZpbGVzXCI6IHtcbiAgICBcImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uXCI6IFwiOTIzODJhNTZiMzQ5YzNiODk1ZTU4MDZlOTc1MDgyNTI3YmI5OWQxYTAwMTE0MGU2OWQ4NTdlNWIwMzkxZmE1NVwiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uXCI6IFwiMzhiNzhiOWNiZWU1YWRlNzc1MGE1OGQ1MTU2Y2E0YzU3NzMzNTJlOTQ3YWNiMzA0ZWU3MTRiNTllNzQ5Y2ViNFwiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWxcIjogXCIxYmJjZTgxYmM2NzU4NDM0MzU0MTU3Zjg2MDE1MzQzMjBjNWQwMjkwNTg3OTA4ZmQxNWE2ZDI1ZTNmYTU3ZjQ3XCIsXG4gICAgXCJkZXBsb3kvbGlmZWN5Y2xlL3JlZ2lzdHJpZXMuY2FuZGlkYXRlLmpzb25cIjogXCI5YmFkNmRiNWZiYzIxNzhkMzFiMDQxMjAwMTZhNDE4MzBjMzU1MmZiYjllMjUxN2I3MThmOWJiZTg3Y2Y2NDllXCJcbiAgfSxcbiAgXCJjYW5kaWRhdGVfaW1hZ2VcIjogXCJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2FcIixcbiAgXCJwcmlvcl9pbWFnZVwiOiBcImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3M1wiLFxuICBcInNvdXJjZV9yZXZpc2lvblwiOiBcIm11c3QtYmUtZXhhY3QtZmluYWwtb3duZXItSEVBRC13aXRoLWFwcHJvdmVkLWZvdXItR2l0LWJsb2JzXCIsXG4gIFwicGhhc2VzXCI6IFtcbiAgICBcImRyaWxsLWJhY2t1cFwiLFxuICAgIFwiZHJpbGwtY29weVwiLFxuICAgIFwib2ZmbGluZS12ZXJpZnlcIixcbiAgICBcImNsZWFudXAtb2ZmbGluZVwiLFxuICAgIFwiY3V0b3Zlci1iYWNrdXBcIixcbiAgICBcImN1dG92ZXItY29weVwiLFxuICAgIFwicmVsZWFzZVwiLFxuICAgIFwidmVyaWZ5XCIsXG4gICAgXCJyb2xsYmFja1wiLFxuICAgIFwicm9sbGJhY2stdmVyaWZ5XCJcbiAgXSxcbiAgXCJhdXRob3JpemF0aW9uXCI6IFwiZnJlc2ggZXh0ZXJuYWxseSBhdXRoZW50aWNhdGVkIHJvb3QgZml4ZWQtb3JpZ2luIG5hdGl2ZSByZWFkYmFjayBiZWZvcmUgZWFjaCBwaGFzZTsgZXhhY3QgY29uZmlybWVkIHBsYXRmb3JtLXJvb3QgZGlzcG9zaXRpb24gYW5kIGN1cnJlbnQgcGFja2V0IFNIQS9zb3VyY2UgY29tbWl0OyByZWNlaXB0IGJvb2trZWVwaW5nIGlzIG5vdCBhbiBhdXRvbm9tb3VzIHNpZ25lZCBncmFudFwiLFxuICBcImV4ZWN1dGVfYnlcIjogXCIyMDI2LTEwLTEyVDIzOjU5OjU5WlwiLFxuICBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZSxcbiAgXCJuYXRpdmVfZGF0YV9vcl93b3JrbG9hZF9hY3Rpb25fZXhlY3V0ZWRcIjogZmFsc2UsXG4gIFwiZGVhZGxpbmVfc2VtYW50aWNzXCI6IFwiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LlwiXG59XG4iCiAgICB9LAogICAgIm5hdGl2ZV9wcm9ncmFtLnB5IjogewogICAgICAic2hhMjU2IjogIjM0OWY1MTZhNGU1NWY3ZmI0NzQ3MDE0NGNlNzgxYTY2NWZiMDAzZWJmZjM4MGQwNTRmNjQyYjIyMTMzZDFjZGUiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJGaXhlZCByZW1vdGUgc291cmNlLCBwYXNzZWQgb25seSBhZnRlciBleGFjdCBzdXBlcnZpc2VkIGFwcHJvdmFsLlwiXCJcIlxuUFJPR1JBTSA9ICdcXG5pbXBvcnQgY29weSxkYXRldGltZSxoYXNobGliLGpzb24sb3MscmUsc3VicHJvY2VzcyxzeXNcXG5pZiBzeXMuZmxhZ3Mub3B0aW1pemU6cmFpc2UgUnVudGltZUVycm9yKFxcJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkXFwnKVxcbnBheWxvYWQ9anNvbi5sb2FkcyhfX1BBWUxPQURfXylcXG5leGVjKF9fR1VBUkRfXylcXG5waGFzZT1wYXlsb2FkW1xcJ3BoYXNlXFwnXVxcbmlmIHBoYXNlIG5vdCBpbiAoXFwnZHJpbGwtYmFja3VwXFwnLFxcJ2N1dG92ZXItYmFja3VwXFwnLFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnLFxcJ3JlbGVhc2VcXCcsXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrXFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6cmFpc2UgVmFsdWVFcnJvcihcXCdmaXhlZCBuYXRpdmUgcGhhc2UgcmVxdWlyZWRcXCcpXFxuZGVhZGxpbmU9ZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdChcXCcyMDI2LTEwLTEyVDIzOjU5OjU5KzAwOjAwXFwnKVxcbmRlZiByZXF1aXJlKHZhbHVlLHJlYXNvbik6XFxuIGlmIG5vdCB2YWx1ZTpyYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcXG5yZXF1aXJlKGRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpPGRlYWRsaW5lLFxcJ2V4ZWN1dGlvbiB3aW5kb3cgZXhwaXJlZFxcJylcXG5lbnY9eyoqb3MuZW52aXJvbixcXCdLVUJFQ09ORklHXFwnOlxcJy9ldGMvcmFuY2hlci9rM3MvazNzLnlhbWxcXCd9XFxuZGVmIHJ1bihhcmd2LGJvZHk9Tm9uZSx0aW1lb3V0PTkwKTpcXG4gcmV0dXJuIHN1YnByb2Nlc3MucnVuKGFyZ3YsaW5wdXQ9Ym9keSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0aW1lb3V0PXRpbWVvdXQsZW52PWVudilcXG5kZWYgcmVhZChraW5kLG5hbWUsbmFtZXNwYWNlKTpcXG4gcmVzdWx0PXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsa2luZCxuYW1lLFxcJy1uXFwnLG5hbWVzcGFjZSxcXCctb1xcJyxcXCdqc29uXFwnXSlcXG4gcmVxdWlyZShyZXN1bHQucmV0dXJuY29kZT09MCxcXCdmaXhlZCBtZXRhZGF0YSByZWFkIHJlZnVzZWRcXCcpXFxuIHJldHVybiBqc29uLmxvYWRzKHJlc3VsdC5zdGRvdXQpXFxuc2VhbGVkPXBheWxvYWRbXFwnc2VhbGVkXFwnXTsgZGVwZW5kZW5jaWVzPXBheWxvYWRbXFwnZGVwZW5kZW5jaWVzXFwnXVxcbmxpdmU9cmVhZChcXCdkZXBsb3ltZW50XFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbmNtPXJlYWQoXFwnY29uZmlnbWFwXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbnB2Yz1yZWFkKFxcJ3B2Y1xcJyxcXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsZGVwZW5kZW5jaWVzKVxcbmFwcD1yZWFkKFxcJ2FwcGxpY2F0aW9uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ2FyZ29jZFxcJylcXG5yZXF1aXJlKGFwcFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09XFwnNDk5ODY4ZjItZWFiYy00ZGY0LWFlMzEtYjg5Y2U1OGQ3NTBkXFwnLFxcJ0FwcGxpY2F0aW9uIFVJRCBjaGFuZ2VkXFwnKVxcbnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwncmVwb1VSTFxcJ109PVxcJ2h0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uLmdpdFxcJ1xcbiBhbmQgYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwncGF0aFxcJ109PVxcJ2RlcGxveS9saWZlY3ljbGVcXCdcXG4gYW5kIGFwcFtcXCdzcGVjXFwnXVtcXCdkZXN0aW5hdGlvblxcJ109PXtcXCduYW1lc3BhY2VcXCc6XFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnc2VydmVyXFwnOlxcJ2h0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Y1xcJ31cXG4gYW5kIGFwcFtcXCdzcGVjXFwnXS5nZXQoXFwnc3luY1BvbGljeVxcJyx7fSkuZ2V0KFxcJ2F1dG9tYXRlZFxcJykgaXMgTm9uZVxcbiBhbmQgc2V0KGFwcFtcXCdzcGVjXFwnXVtcXCdzb3VyY2VcXCddKT09e1xcJ3JlcG9VUkxcXCcsXFwncGF0aFxcJyxcXCd0YXJnZXRSZXZpc2lvblxcJ30gYW5kIG5vdCBhcHBbXFwnc3BlY1xcJ10uZ2V0KFxcJ3NvdXJjZXNcXCcpLFxcJ0FwcGxpY2F0aW9uIG93bmVyL3Njb3BlIGNoYW5nZWRcXCcpXFxuZXhwZWN0ZWQ9Y29weS5kZWVwY29weShzZWFsZWQpXFxuaWYgcGhhc2U9PVxcJ3ZlcmlmeVxcJzpleHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddPUNBTkRJREFURVxcbmlmIHBoYXNlPT1cXCdyb2xsYmFja1xcJzpcXG4gaW1hZ2U9bGl2ZVtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddXFxuIHJlcXVpcmUoaW1hZ2UgaW4gKEJBU0UsQ0FORElEQVRFKSxcXCdyb2xsYmFjayBpbWFnZSBpcyBvdXRzaWRlIHNhbWUtc2NoZW1hIHBhaXJcXCcpXFxuIGV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109aW1hZ2VcXG5jaGVja19jdXJyZW50KGxpdmUsZXhwZWN0ZWQpXFxuaWYgcGhhc2UhPVxcJ3JvbGxiYWNrXFwnOlxcbiByZXF1aXJlKGxpdmUuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ3JlYWR5UmVwbGljYXNcXCcpPT0xXFxuICBhbmQgbGl2ZVtcXCdzdGF0dXNcXCddLmdldChcXCd1cGRhdGVkUmVwbGljYXNcXCcpPT0xXFxuICBhbmQgbGl2ZVtcXCdzdGF0dXNcXCddLmdldChcXCdvYnNlcnZlZEdlbmVyYXRpb25cXCcpPT1saXZlW1xcJ21ldGFkYXRhXFwnXVtcXCdnZW5lcmF0aW9uXFwnXSxcXCdzZXJ2aWNlIG5vdCBSZWFkeTFcXCcpXFxudGFyZ2V0PXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwndmVyaWZ5XFwnIGVsc2UgXFwnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZlxcJ1xcbmlmIHBoYXNlPT1cXCdyb2xsYmFja1xcJzpyZXF1aXJlKGFwcFtcXCdzcGVjXFwnXVtcXCdzb3VyY2VcXCddW1xcJ3RhcmdldFJldmlzaW9uXFwnXSBpbiAodGFyZ2V0LHBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSksXFwncm9sbGJhY2sgc291cmNlIGlzIG91dHNpZGUgcGFpclxcJylcXG5lbHNlOnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwndGFyZ2V0UmV2aXNpb25cXCddPT10YXJnZXQsXFwndW5leHBlY3RlZCBzb3VyY2UgcGluXFwnKVxcbnJlc3VsdD17XFwncGhhc2VcXCc6cGhhc2UsXFwnYWxsX2NoZWNrc19wYXNzXFwnOkZhbHNlLFxcJ3Jhd19vdXRwdXRfd2l0aGhlbGRcXCc6VHJ1ZSxcXG4gXFwnbmF0aXZlX2FwcHJvdmFsX3ZlcmlmaWVkX2J5X3Jvb3RcXCc6cGF5bG9hZFtcXCdhcHByb3ZhbFxcJ10sXFwnbmF0aXZlX2F1dGhlbnRpY2F0ZWRfZ3JhbnRcXCc6RmFsc2V9XFxudHJ5OlxcbiBpZiBwaGFzZSBpbiAoXFwnZHJpbGwtYmFja3VwXFwnLFxcJ2N1dG92ZXItYmFja3VwXFwnLFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnLFxcJ3JlbGVhc2VcXCcsXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBwb2RsaXN0PXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwncG9kc1xcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctbFxcJyxcXCdhcHAua3ViZXJuZXRlcy5pby9uYW1lPWluZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddKVxcbiAgcmVxdWlyZShwb2RsaXN0LnJldHVybmNvZGU9PTAsXFwncG9kIG1ldGFkYXRhIHF1ZXJ5IHJlZnVzZWRcXCcpXFxuICBwb2RzPVtwIGZvciBwIGluIGpzb24ubG9hZHMocG9kbGlzdC5zdGRvdXQpW1xcJ2l0ZW1zXFwnXSBpZiBub3QgcFtcXCdtZXRhZGF0YVxcJ10uZ2V0KFxcJ2RlbGV0aW9uVGltZXN0YW1wXFwnKV1cXG4gIHJlcXVpcmUobGVuKHBvZHMpPT0xLFxcJ2V4YWN0IHNpbmdsZSBsaXZlIG93bmVyIHBvZCByZXF1aXJlZFxcJyk7cG9kPXBvZHNbMF1cXG4gIHJlcXVpcmUocG9kW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ3BoYXNlXFwnKT09XFwnUnVubmluZ1xcJyBhbmQgbGVuKHBvZFtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXSk9PTFcXG4gICBhbmQgcG9kW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXT09ZXhwZWN0ZWRbXFwnc3BlY1xcJ11bXFwndGVtcGxhdGVcXCddW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXVxcbiAgIGFuZCBsZW4ocG9kW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ2NvbnRhaW5lclN0YXR1c2VzXFwnLFtdKSk9PTFcXG4gICBhbmQgcG9kW1xcJ3N0YXR1c1xcJ11bXFwnY29udGFpbmVyU3RhdHVzZXNcXCddWzBdLmdldChcXCduYW1lXFwnKT09XFwnaW5mb3JtZWQtZGVjaXNpb25cXCdcXG4gICBhbmQgcG9kW1xcJ3N0YXR1c1xcJ11bXFwnY29udGFpbmVyU3RhdHVzZXNcXCddWzBdLmdldChcXCdyZWFkeVxcJykgaXMgVHJ1ZSxcXCdvd25lciBwb2QgcmVhZGluZXNzL2ltYWdlIGNoYW5nZWRcXCcpXFxuICB0ZW1wbGF0ZT1leHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11cXG4gIGNvbnRyb2xsZWQ9c2V0KHRlbXBsYXRlKXx7XFwnaW5pdENvbnRhaW5lcnNcXCcsXFwnaG9zdE5ldHdvcmtcXCcsXFwnaG9zdFBJRFxcJyxcXCdob3N0SVBDXFwnLFxcJ3J1bnRpbWVDbGFzc05hbWVcXCcsXFwnc2hhcmVQcm9jZXNzTmFtZXNwYWNlXFwnfVxcbiAgcmVxdWlyZShhbGwocG9kW1xcJ3NwZWNcXCddLmdldChrZXkpPT10ZW1wbGF0ZS5nZXQoa2V5KSBmb3Iga2V5IGluIGNvbnRyb2xsZWQpLFxcJ2FjdHVhbCBvd25lciBQb2QgY29uZmlndXJhdGlvbiBkcmlmdGVkXFwnKVxcbiAgb3duZXJzPXBvZFtcXCdtZXRhZGF0YVxcJ10uZ2V0KFxcJ293bmVyUmVmZXJlbmNlc1xcJyxbXSk7cmVxdWlyZShsZW4ob3duZXJzKT09MSBhbmQgb3duZXJzWzBdW1xcJ2tpbmRcXCddPT1cXCdSZXBsaWNhU2V0XFwnLFxcJ3BvZCBvd25lciBjaGFpbiBjaGFuZ2VkXFwnKVxcbiAgcnM9cmVhZChcXCdyZXBsaWNhc2V0XFwnLG93bmVyc1swXVtcXCduYW1lXFwnXSxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJylcXG4gIHJlcXVpcmUocnNbXFwnbWV0YWRhdGFcXCddW1xcJ3VpZFxcJ109PW93bmVyc1swXVtcXCd1aWRcXCddIGFuZCBhbnkoby5nZXQoXFwndWlkXFwnKT09c2VhbGVkW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddXFxuICAgYW5kIG8uZ2V0KFxcJ2tpbmRcXCcpPT1cXCdEZXBsb3ltZW50XFwnIGZvciBvIGluIHJzW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnb3duZXJSZWZlcmVuY2VzXFwnLFtdKSksXFwnUmVwbGljYVNldCBvd25lcnNoaXAgY2hhbmdlZFxcJylcXG4gIGlubmVyPXJcIlwiXCJcXG5pbXBvcnQgaGFzaGxpYixqc29uLG9zLHN0YXQsc3VicHJvY2VzcyxzeXNcXG5pZiBzeXMuZmxhZ3Mub3B0aW1pemU6cmFpc2UgUnVudGltZUVycm9yKFxcJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkXFwnKVxcbmV4ZWMoX19SRUFET05MWV9fKVxcbmV4ZWMoX19TQUZFVFlfXylcXG5hY3Rpb249X19BQ1RJT05fXztkYj1cXCcvZGF0YS9wcml2YXRlL3Jldmlldy5zcWxpdGVcXCc7Zm9sZGVyPVxcJy9kYXRhL3ByaXZhdGUvcHVycG9zZS1vdmVybGF5LXIxXFwnXFxuZGVmIHJlcXVpcmUodixyKTpcXG4gaWYgbm90IHY6cmFpc2UgVmFsdWVFcnJvcihyKVxcbnJlcXVpcmUob3MuZ2V0dWlkKCk9PTEwMDAxIGFuZCBvcy5nZXRnaWQoKT09MTAwMDEsXFwnbmF0aXZlIG93bmVyIFVJRC9HSUQgcmVxdWlyZWRcXCcpXFxuZGVmIHByaXZhdGUocCxkaXJlY3Rvcnk9RmFsc2UpOlxcbiBzPW9zLmxzdGF0KHApO3JlcXVpcmUoKHN0YXQuU19JU0RJUihzLnN0X21vZGUpIGlmIGRpcmVjdG9yeSBlbHNlIHN0YXQuU19JU1JFRyhzLnN0X21vZGUpKVxcbiAgYW5kIHMuc3RfdWlkPT0xMDAwMSBhbmQgc3RhdC5TX0lNT0RFKHMuc3RfbW9kZSk9PSgwbzcwMCBpZiBkaXJlY3RvcnkgZWxzZSAwbzYwMClcXG4gIGFuZCAoZGlyZWN0b3J5IG9yIHMuc3Rfbmxpbms9PTEpLFxcJ3ByaXZhdGUgbmF0aXZlIGN1c3RvZHkgcmVxdWlyZWRcXCcpXFxucHJpdmF0ZShcXCcvZGF0YS9wcml2YXRlXFwnLFRydWUpO3ByaXZhdGUoZGIpXFxuYmFzZWxpbmU9Y291bnRzKGluc3BlY3RfcmVhZG9ubHkoZGIpKSAjIE1VU1QgcHJlY2VkZSBhbnkgU3RvcmUvYWRtaW4gb3Blbi5cXG5pZiBhY3Rpb24gaW4gKFxcJ2RyaWxsLWJhY2t1cFxcJyxcXCdjdXRvdmVyLWJhY2t1cFxcJyk6XFxuIHNpemU9b3Muc3RhdChkYikuc3Rfc2l6ZVxcbiBpZiBvcy5wYXRoLmV4aXN0cyhkYitcXCctd2FsXFwnKTpzaXplKz1vcy5zdGF0KGRiK1xcJy13YWxcXCcpLnN0X3NpemVcXG4gdj1vcy5zdGF0dmZzKFxcJy9kYXRhL3ByaXZhdGVcXCcpO2ZyZWU9di5mX2JhdmFpbCp2LmZfZnJzaXplXFxuIHJlcXVpcmUoc2l6ZT4wIGFuZCBzaXplPD01MTIqMTAyNCoqMiBhbmQgZnJlZT49c2l6ZSooMiBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJyBlbHNlIDEpKzE2KjEwMjQqKjIsXFwnYm91bmRlZCBuYXRpdmUgc25hcHNob3QgY2FwYWNpdHkgcmVxdWlyZWRcXCcpXFxuIGlmIGFjdGlvbj09XFwnZHJpbGwtYmFja3VwXFwnOlxcbiAgcmVxdWlyZShub3Qgb3MucGF0aC5sZXhpc3RzKGZvbGRlciksXFwnbmF0aXZlIGNhc2UgZGlyZWN0b3J5IG11c3QgYmUgdW5pcXVlXFwnKVxcbiAgb3MubWtkaXIoZm9sZGVyLDBvNzAwKTtvcy5jaG1vZChmb2xkZXIsMG83MDApXFxuIHByaXZhdGUoZm9sZGVyLFRydWUpXFxuIGZpbGVuYW1lPVxcJ2RyaWxsLnNxbGl0ZVxcJyBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJyBlbHNlIFxcJ2N1dG92ZXIuc3FsaXRlXFwnO291dHB1dD1mb2xkZXIrXFwnL1xcJytmaWxlbmFtZVxcbiByZXF1aXJlKG5vdCBvcy5wYXRoLmxleGlzdHMob3V0cHV0KSxcXCdzbmFwc2hvdCBvdXRwdXQgbXVzdCBiZSB1bmlxdWVcXCcpXFxuIGFkbWluPXN1YnByb2Nlc3MucnVuKFtcXCdpbmZvcm1lZC1kZWNpc2lvbi1hZG1pblxcJyxcXCdiYWNrdXBcXCcsXFwnLS1kYlxcJyxkYixcXCctLW91dHB1dFxcJyxvdXRwdXRdLGNhcHR1cmVfb3V0cHV0PVRydWUsdGV4dD1UcnVlLHRpbWVvdXQ9MTIwKVxcbiByZXF1aXJlKGFkbWluLnJldHVybmNvZGU9PTAgYW5kIGpzb24ubG9hZHMoYWRtaW4uc3Rkb3V0KT09e1xcJ3N0YXR1c1xcJzpcXCdiYWNrZWRfdXBcXCcsXFwnY29uc2lzdGVudF9zbmFwc2hvdFxcJzpUcnVlfSxcXCdiYWNrdXAgY29tcGxldGlvbiBub3QgdmVyaWZpZWQ7IGRvIG5vdCByZXRyeVxcJylcXG4gcHJpdmF0ZShvdXRwdXQpXFxuIGZvciBzdWZmaXggaW4gKFxcJy13YWxcXCcsXFwnLXNobVxcJyk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnc25hcHNob3QgaXMgbm90IGNsb3NlZCBtYWluLWZpbGUgY3VzdG9keVxcJylcXG4gc25hcHNob3Q9Y291bnRzKGluc3BlY3RfcmVhZG9ubHkob3V0cHV0KSlcXG4gc2l6ZT1vcy5zdGF0KG91dHB1dCkuc3Rfc2l6ZTtyZXF1aXJlKDA8c2l6ZTw9NTEyKjEwMjQqKjIsXFwnc25hcHNob3Qgb3V0c2lkZSBib3VuZGVkIGNvcHkgc2l6ZVxcJylcXG4gZGlnZXN0PWhhc2hsaWIuc2hhMjU2KClcXG4gd2l0aCBvcGVuKG91dHB1dCxcXCdyYlxcJykgYXMgc3RyZWFtOlxcbiAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOnN0cmVhbS5yZWFkKDEwMjQqKjIpLGJcXCdcXCcpOmRpZ2VzdC51cGRhdGUoYmxvY2spXFxuIHByaW50KGpzb24uZHVtcHMoe1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZVxcJzpiYXNlbGluZSxcXCdzbmFwc2hvdF9yZWFkb25seVxcJzpzbmFwc2hvdCxcXCdzbmFwc2hvdF9zaGEyNTZcXCc6ZGlnZXN0LmhleGRpZ2VzdCgpLFxcJ3NuYXBzaG90X2J5dGVzXFwnOnNpemUsXFwnc25hcHNob3RfZmlsZVxcJzpmaWxlbmFtZSxcXCduYXRpdmVfcGFyZW50X3ByaXZhdGVcXCc6VHJ1ZSxcXCduYXRpdmVfdWlkXFwnOm9zLmdldHVpZCgpfSkpXFxuZWxpZiBhY3Rpb24gaW4gKFxcJ3ZlcmlmeVxcJyxcXCdyZWxlYXNlXFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuIHByb29mPXtcXCdhbGxfY2hlY2tzX3Bhc3NcXCc6VHJ1ZSxcXCdsaXZlX3JlYWRvbmx5X3NjaGVtYV9pbnRlZ3JpdHlfY291bnRzXFwnOmJhc2VsaW5lLFxcJ2xpdmVfY291bnRzX21heV9pbmNsdWRlX2NvbmN1cnJlbnRfY29tbWl0c1xcJzpUcnVlfVxcbiBpZiBhY3Rpb249PVxcJ3ZlcmlmeVxcJzpcXG4gIGltcG9ydCB1cmxsaWIucmVxdWVzdFxcbiAgbW9kdWxlPVxcJy9vcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weVxcJztpbmZvPW9zLmxzdGF0KG1vZHVsZSlcXG4gIHJlcXVpcmUoc3RhdC5TX0lTUkVHKGluZm8uc3RfbW9kZSkgYW5kIGluZm8uc3RfdWlkPT0wIGFuZCBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKT09MG82NDQsXFwnaW5zdGFsbGVkIHBvbGljeSBtZXRhZGF0YSBkaWZmZXJzXFwnKVxcbiAgd2l0aCBvcGVuKG1vZHVsZSxcXCdyYlxcJykgYXMgc291cmNlOm1vZHVsZV9kaWdlc3Q9aGFzaGxpYi5zaGEyNTYoc291cmNlLnJlYWQoKSkuaGV4ZGlnZXN0KClcXG4gIHJlcXVpcmUobW9kdWxlX2RpZ2VzdD09XFwnOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MlxcJyxcXCdpbnN0YWxsZWQgc291cmNlIG1vZHVsZSBkaWZmZXJzXFwnKVxcbiAgcHVycG9zZT1zdWJwcm9jZXNzLnJ1bihbc3lzLmV4ZWN1dGFibGUsXFwnLVxcJ10saW5wdXQ9X19QVVJQT1NFX18sdGV4dD1UcnVlLGNhcHR1cmVfb3V0cHV0PVRydWUsdGltZW91dD0zMClcXG4gIHJlcXVpcmUocHVycG9zZS5yZXR1cm5jb2RlPT0wLFxcJ2luc3RhbGxlZCBuYXRpdmUtcGxhY2VtZW50IHB1cnBvc2UgY2hlY2tzIGZhaWxlZFxcJylcXG4gIHRlc3RlZD1qc29uLmxvYWRzKHB1cnBvc2Uuc3Rkb3V0KVxcbiAgcmVxdWlyZSh0ZXN0ZWQ9PXtcXCdpbnN0YWxsZWRfaW1hZ2VfcHVycG9zZV92YXJpYW50c1xcJzoxMCxcXCdiaW5kaW5nX2Zvcm1zX2FsbG93ZWRcXCc6MixcXCdhZHZpc29yeV9vcl9tYWxmb3JtZWRfcmVmdXNlZFxcJzo4LFxcJ3N5bnRoZXRpY19vbmx5XFwnOlRydWUsXFwnbmF0aXZlX3Byb3ZpZGVyXFwnOkZhbHNlfSxcXCdwdXJwb3NlIHJlc3VsdCBkaWZmZXJzXFwnKVxcbiAgY2xhc3MgTm9SZWRpcmVjdCh1cmxsaWIucmVxdWVzdC5IVFRQUmVkaXJlY3RIYW5kbGVyKTpcXG4gICBkZWYgcmVkaXJlY3RfcmVxdWVzdChzZWxmLCphcmdzLCoqa3dhcmdzKTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2hlYWx0aCByZWRpcmVjdCByZWZ1c2VkXFwnKVxcbiAgb3BlbmVyPXVybGxpYi5yZXF1ZXN0LmJ1aWxkX29wZW5lcihOb1JlZGlyZWN0KCkpO3N0YXR1c2VzPXt9XFxuICBmb3Igcm91dGUgaW4gKFxcJy9oZWFsdGh6XFwnLFxcJy9yZWFkeXpcXCcpOlxcbiAgIHdpdGggb3BlbmVyLm9wZW4oXFwnaHR0cDovLzEyNy4wLjAuMTo4MDgwXFwnK3JvdXRlLHRpbWVvdXQ9MTApIGFzIHJlc3BvbnNlOlxcbiAgICByZXF1aXJlKHJlc3BvbnNlLnN0YXR1cz09MjAwIGFuZCBsZW4ocmVzcG9uc2UucmVhZCg4MTkzKSk8PTgxOTIsXFwnYm91bmRlZCBoZWFsdGggY2hlY2sgcmVmdXNlZFxcJyk7c3RhdHVzZXNbcm91dGVdPTIwMFxcbiAgcHJvb2YudXBkYXRlKGluc3RhbGxlZF9wdXJwb3NlX2NoZWNrcz10ZXN0ZWQscG9saWN5X3NoYTI1Nj1tb2R1bGVfZGlnZXN0LHBvbGljeV9tb2RlPVxcJzA2NDRcXCcscG9saWN5X3VpZD0wLGhlYWx0aF9zdGF0dXNlcz1zdGF0dXNlcyxuYXRpdmVfcHJvdmlkZXJfcHJvYmU9RmFsc2UpXFxuIHByaW50KGpzb24uZHVtcHMocHJvb2YpKVxcbmVsaWYgYWN0aW9uIGluIChcXCdkcmlsbC1jb3B5XFwnLFxcJ2N1dG92ZXItY29weVxcJyk6XFxuIHByaXZhdGUoZm9sZGVyLFRydWUpO2ZpbGVuYW1lPVxcJ2RyaWxsLnNxbGl0ZVxcJyBpZiBhY3Rpb249PVxcJ2RyaWxsLWNvcHlcXCcgZWxzZSBcXCdjdXRvdmVyLnNxbGl0ZVxcJztvdXRwdXQ9Zm9sZGVyK1xcJy9cXCcrZmlsZW5hbWU7cHJpdmF0ZShvdXRwdXQpXFxuIGZvciBzdWZmaXggaW4gKFxcJy13YWxcXCcsXFwnLXNobVxcJyk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnY2xvc2VkIG1haW4gc25hcHNob3QgcmVxdWlyZWRcXCcpXFxuIHNuYXBzaG90PWNvdW50cyhpbnNwZWN0X3JlYWRvbmx5KG91dHB1dCkpO3NpemU9b3Muc3RhdChvdXRwdXQpLnN0X3NpemU7cmVxdWlyZSgwPHNpemU8PTUxMioxMDI0KioyLFxcJ3NuYXBzaG90IHNpemUgb3V0c2lkZSBib3VuZFxcJylcXG4gZGlnZXN0PWhhc2hsaWIuc2hhMjU2KClcXG4gd2l0aCBvcGVuKG91dHB1dCxcXCdyYlxcJykgYXMgc3RyZWFtOlxcbiAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOnN0cmVhbS5yZWFkKDEwMjQqKjIpLGJcXCdcXCcpOmRpZ2VzdC51cGRhdGUoYmxvY2spXFxuIHByaW50KGpzb24uZHVtcHMoe1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ3NuYXBzaG90X2ZpbGVcXCc6ZmlsZW5hbWUsXFwnc25hcHNob3RfYnl0ZXNcXCc6c2l6ZSxcXCdzbmFwc2hvdF9zaGEyNTZcXCc6ZGlnZXN0LmhleGRpZ2VzdCgpLFxcJ3NuYXBzaG90X3JlYWRvbmx5XFwnOnNuYXBzaG90fSkpXFxuZWxzZTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2ZpeGVkIG5hdGl2ZSBiYWNrdXAvdmVyaWZ5IHBoYXNlIHJlcXVpcmVkXFwnKVxcblwiXCJcIlxcbiAgIyBTdHJpcCB0aGUgQ0xJIGJyYW5jaDogZXhlYyBvbmx5IHRoZSB2ZXJpZmllZCBzdGRsaWIgZnVuY3Rpb24sIG5ldmVyIFN0b3JlLlxcbiAgcmVhZG9ubHk9cGF5bG9hZFtcXCdyZWFkb25seVxcJ10uc3BsaXQoXCJpZiBfX25hbWVfXyA9PSBcXCdfX21haW5fX1xcJzpcIiwxKVswXVxcbiAgaW5uZXI9aW5uZXIucmVwbGFjZShcXCdfX1JFQURPTkxZX19cXCcscmVwcihyZWFkb25seSkpLnJlcGxhY2UoXFwnX19TQUZFVFlfX1xcJyxyZXByKHBheWxvYWRbXFwncmVjZWlwdF9zYWZldHlcXCddKSkucmVwbGFjZShcXCdfX0FDVElPTl9fXFwnLHJlcHIocGhhc2UpKS5yZXBsYWNlKFxcJ19fUFVSUE9TRV9fXFwnLHJlcHIocGF5bG9hZFtcXCdwdXJwb3NlX2NoZWNrc1xcJ10pKVxcbiAgcD1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnZXhlY1xcJyxcXCctaVxcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxwb2RbXFwnbWV0YWRhdGFcXCddW1xcJ25hbWVcXCddLFxcJy1jXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy0tXFwnLFxcJ3B5dGhvblxcJyxcXCctXFwnXSxpbm5lciwxNTApXFxuICByZXF1aXJlKHAucmV0dXJuY29kZT09MCxcXCduYXRpdmUgcGhhc2Ugb3V0Y29tZSB1bnZlcmlmaWVkOyByYXcgb3V0cHV0IHdpdGhoZWxkLCBkbyBub3QgcmV0cnlcXCcpXFxuICBvdXRjb21lPWpzb24ubG9hZHMocC5zdGRvdXQpO3JlcXVpcmUob3V0Y29tZS5nZXQoXFwnYWxsX2NoZWNrc19wYXNzXFwnKSBpcyBUcnVlLFxcJ25hdGl2ZSBwaGFzZSBnYXRlIHJlZnVzZWRcXCcpXFxuICByZXN1bHQudXBkYXRlKG91dGNvbWUscG9kX25hbWU9cG9kW1xcJ21ldGFkYXRhXFwnXVtcXCduYW1lXFwnXSxwb2RfdWlkPXBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXSlcXG4gaWYgcGhhc2UgaW4gKFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2tcXCcpOlxcbiAgbm9kZV9yZWFkPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwnbm9kZXNcXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pO3JlcXVpcmUobm9kZV9yZWFkLnJldHVybmNvZGU9PTAsXFwnbm9kZSBtZXRhZGF0YSB1bmF2YWlsYWJsZVxcJylcXG4gIG5vZGVzPWpzb24ubG9hZHMobm9kZV9yZWFkLnN0ZG91dClbXFwnaXRlbXNcXCddO3JlcXVpcmUobGVuKG5vZGVzKT09MSxcXCdvbmUgdGFyZ2V0IG5vZGUgcmVxdWlyZWRcXCcpO25vZGU9bm9kZXNbMF1cXG4gIHJlcXVpcmUoYW55KGEuZ2V0KFxcJ2FkZHJlc3NcXCcpPT1cXCc5Mi4yMDUuNjIuMjM5XFwnIGZvciBhIGluIG5vZGVbXFwnc3RhdHVzXFwnXVtcXCdhZGRyZXNzZXNcXCddKSxcXCd0YXJnZXQgbm9kZSBhZGRyZXNzIGNoYW5nZWRcXCcpXFxuICBjb25kaXRpb25zPXtjW1xcJ3R5cGVcXCddOmNbXFwnc3RhdHVzXFwnXSBmb3IgYyBpbiBub2RlW1xcJ3N0YXR1c1xcJ11bXFwnY29uZGl0aW9uc1xcJ119XFxuICByZXF1aXJlKGNvbmRpdGlvbnMuZ2V0KFxcJ1JlYWR5XFwnKT09XFwnVHJ1ZVxcJyBhbmQgYWxsKGNvbmRpdGlvbnMuZ2V0KGspPT1cXCdGYWxzZVxcJyBmb3IgayBpbiAoXFwnTWVtb3J5UHJlc3N1cmVcXCcsXFwnRGlza1ByZXNzdXJlXFwnLFxcJ1BJRFByZXNzdXJlXFwnKSksXFwnbm9kZSB1bmhlYWx0aHkgb3IgcHJlc3N1cmVkXFwnKVxcbiAgZGVzY3JpcHRpb249cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2Rlc2NyaWJlXFwnLFxcJ25vZGVcXCcsbm9kZVtcXCdtZXRhZGF0YVxcJ11bXFwnbmFtZVxcJ11dKTtyZXF1aXJlKGRlc2NyaXB0aW9uLnJldHVybmNvZGU9PTAsXFwnaGVhZHJvb20gY2FwdHVyZSB1bmF2YWlsYWJsZVxcJylcXG4gIHRhYmxlPWRlc2NyaXB0aW9uLnN0ZG91dC5zcGxpdChcXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcJywxKVsxXTtyZXF1ZXN0ZWQ9aW50KHJlLnNlYXJjaChyXFwnY3B1XFxcXHMrKFxcXFxkKyltXFwnLHRhYmxlKS5ncm91cCgxKSk7YWxsb2M9bm9kZVtcXCdzdGF0dXNcXCddW1xcJ2FsbG9jYXRhYmxlXFwnXVtcXCdjcHVcXCddO2NhcGFjaXR5PWludChhbGxvY1s6LTFdKSBpZiBhbGxvYy5lbmRzd2l0aChcXCdtXFwnKSBlbHNlIGludChhbGxvYykqMTAwMFxcbiAgcmVxdWlyZShyZXF1ZXN0ZWQ8PWNhcGFjaXR5LFxcJ1JlY3JlYXRlIHJlcXVlc3RlZCBDUFUgZXhjZWVkcyBjYXBhY2l0eVxcJylcXG4gIHJlcXVpcmUobm90IGFwcC5nZXQoXFwnb3BlcmF0aW9uXFwnKSBhbmQgYXBwLmdldChcXCdzdGF0dXNcXCcse30pLmdldChcXCdvcGVyYXRpb25TdGF0ZVxcJyx7fSkuZ2V0KFxcJ3BoYXNlXFwnKSBub3QgaW4gKFxcJ1J1bm5pbmdcXCcsXFwnVGVybWluYXRpbmdcXCcpLFxcJ2V4aXN0aW5nIEFyZ28gb3BlcmF0aW9uIG11c3QgYmUgc2V0dGxlZFxcJylcXG4gIGRlc3RpbmF0aW9uPXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwncmVsZWFzZVxcJyBlbHNlIFxcJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmZcXCdcXG4gIGJvZHk9Y29weS5kZWVwY29weShwYXlsb2FkW1xcJ2NhbmRpZGF0ZVxcJ10gaWYgcGhhc2U9PVxcJ3JlbGVhc2VcXCcgZWxzZSBwYXlsb2FkW1xcJ3JvbGxiYWNrXFwnXSlcXG4gIGRyeT1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnYXBwbHlcXCcsXFwnLS1kcnktcnVuPXNlcnZlclxcJyxcXCctZlxcJyxcXCctXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddLGpzb24uZHVtcHMoYm9keSkpXFxuICByZXF1aXJlKGRyeS5yZXR1cm5jb2RlPT0wLFxcJ2ZyZXNoIG93bmVyIHNlcnZlciBhZG1pc3Npb24gcmVmdXNlZFxcJylcXG4gIGFkbWl0dGVkPWpzb24ubG9hZHMoZHJ5LnN0ZG91dCk7d2FudGVkPWNvcHkuZGVlcGNvcHkoc2VhbGVkKVxcbiAgd2FudGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFIGlmIHBoYXNlPT1cXCdyZWxlYXNlXFwnIGVsc2UgQkFTRVxcbiAgcmVxdWlyZShwcm9qZWN0aW9uKGFkbWl0dGVkKT09d2FudGVkLFxcJ2RyeS1ydW4gY2hhbmdlZCBhbnl0aGluZyBiZXlvbmQgZXhhY3QgaW1hZ2VcXCcpXFxuICBkaWZmPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdkaWZmXFwnLFxcJy1mXFwnLFxcJy1cXCddLGpzb24uZHVtcHMoYm9keSkpO3JlcXVpcmUoZGlmZi5yZXR1cm5jb2RlIGluICgwLDEpLFxcJ2NsaWVudCBkaWZmIHVuYXZhaWxhYmxlXFwnKVxcbiAgb3BlcmF0aW9uPXtcXCdpbml0aWF0ZWRCeVxcJzp7XFwndXNlcm5hbWVcXCc6XFwnY3VzdG9kaWFuLWNvZGV4XFwnfSxcXCdzeW5jXFwnOntcXCdyZXZpc2lvblxcJzpkZXN0aW5hdGlvbixcXCdwcnVuZVxcJzpGYWxzZSxcXG4gICBcXCdyZXNvdXJjZXNcXCc6W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dfX1cXG4gIHBhdGNoPVt7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS91aWRcXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS9yZXNvdXJjZVZlcnNpb25cXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCdyZXNvdXJjZVZlcnNpb25cXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9zcGVjL3NvdXJjZS90YXJnZXRSZXZpc2lvblxcJyxcXCd2YWx1ZVxcJzphcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ119LFxcbiAgIHtcXCdvcFxcJzpcXCdyZXBsYWNlXFwnLFxcJ3BhdGhcXCc6XFwnL3NwZWMvc291cmNlL3RhcmdldFJldmlzaW9uXFwnLFxcJ3ZhbHVlXFwnOmRlc3RpbmF0aW9ufSxcXG4gICB7XFwnb3BcXCc6XFwnYWRkXFwnLFxcJ3BhdGhcXCc6XFwnL29wZXJhdGlvblxcJyxcXCd2YWx1ZVxcJzpvcGVyYXRpb259XVxcbiAgYXJndj1bXFwna3ViZWN0bFxcJyxcXCdwYXRjaFxcJyxcXCdhcHBsaWNhdGlvblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctblxcJyxcXCdhcmdvY2RcXCcsXFwnLS10eXBlPWpzb25cXCcsXFwnLS1wYXRjaC1maWxlPS9kZXYvc3RkaW5cXCcsXFwnLW9cXCcsXFwnbmFtZVxcJ11cXG4gIHBhdGNoZHJ5PXJ1bihhcmd2K1tcXCctLWRyeS1ydW49c2VydmVyXFwnXSxqc29uLmR1bXBzKHBhdGNoKSk7cmVxdWlyZShwYXRjaGRyeS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIG9wZXJhdGlvbiBkcnktcnVuIHJlZnVzZWRcXCcpXFxuICBjaGFuZ2U9cnVuKGFyZ3YsanNvbi5kdW1wcyhwYXRjaCkpXFxuICByZXF1aXJlKGNoYW5nZS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIHBhdGNoIG91dGNvbWUgYW1iaWd1b3VzOyBkbyBub3QgcmV0cnlcXCcpXFxuICByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1UcnVlLG9wZXJhdGlvbl9yZXF1ZXN0ZWQ9VHJ1ZSxzb3VyY2VfcmV2aXNpb249ZGVzdGluYXRpb24sXFxuICAgcmVzb3VyY2VzPW9wZXJhdGlvbltcXCdzeW5jXFwnXVtcXCdyZXNvdXJjZXNcXCddLHBydW5lPUZhbHNlLHJvbGxvdXRfdmVyaWZpZWQ9RmFsc2UsXFxuICAgbGF0ZXN0X2xpdmVfZGF0YWJhc2VfcmV0YWluZWQ9VHJ1ZSxjbGllbnRfZGlmZl9zaGEyNTY9aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpKVxcbiBpZiBwaGFzZSBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBvcD1hcHAuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ29wZXJhdGlvblN0YXRlXFwnLHt9KTtzeW5jPW9wLmdldChcXCdvcGVyYXRpb25cXCcse30pLmdldChcXCdzeW5jXFwnLHt9KVxcbiAgcmVxdWlyZShvcC5nZXQoXFwncGhhc2VcXCcpPT1cXCdTdWNjZWVkZWRcXCcgYW5kIHN5bmMuZ2V0KFxcJ3JldmlzaW9uXFwnKT09dGFyZ2V0IGFuZCBzeW5jLmdldChcXCdwcnVuZVxcJykgaXMgRmFsc2VcXG4gICBhbmQgc3luYy5nZXQoXFwncmVzb3VyY2VzXFwnKT09W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dLFxcJ2V4YWN0IG5hdGl2ZSBBcmdvIG9wZXJhdGlvbiBjb21wbGV0aW9uIHVudmVyaWZpZWRcXCcpXFxuICByZXF1aXJlKGxpdmVbXFwnc3RhdHVzXFwnXS5nZXQoXFwnb2JzZXJ2ZWRHZW5lcmF0aW9uXFwnKT09bGl2ZVtcXCdtZXRhZGF0YVxcJ11bXFwnZ2VuZXJhdGlvblxcJ10sXFwnY29udHJvbGxlciBnZW5lcmF0aW9uIG5vdCBzZXR0bGVkXFwnKVxcbiAgcmVzdWx0LnVwZGF0ZShuYXRpdmVfcm9sbG91dF92ZXJpZmllZD1UcnVlLGN1cnJlbnRfc2NoZW1hNV9kYXRhYmFzZV9yZXRhaW5lZD1UcnVlLHJlY292ZXJ5X3ZlcmlmaWNhdGlvbj1waGFzZT09XFwncm9sbGJhY2stdmVyaWZ5XFwnKVxcbmV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGVycm9yOlxcbiByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1GYWxzZSxmYWlsdXJlX2NsYXNzPXR5cGUoZXJyb3IpLl9fbmFtZV9fLFxcbiAgZmFpbHVyZT1cXCdmaXhlZCBwaGFzZSBvdXRjb21lIHJlZnVzZWQgb3IgYW1iaWd1b3VzOyByYXcgb3V0cHV0IHdpdGhoZWxkOyBubyByZXRyeVxcJylcXG5wcmludChqc29uLmR1bXBzKHJlc3VsdCkpO3N5cy5leGl0KDAgaWYgcmVzdWx0LmdldChcXCdhbGxfY2hlY2tzX3Bhc3NcXCcpIGlzIFRydWUgZWxzZSAxKVxcbidcbiIKICAgIH0sCiAgICAicGFja2V0LXJlZmluZW1lbnQuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICJlZjM3MGE0OTE0NjhkZjI4NjgzZjMwMDJjYjZlOGJiYjdlNDdiNjVlOGU0ZDAyZmY0ZDA5ZTljMzlmMDIwYzhhIiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJwcmlvcl9yZXZpZXdlZF9wYWNrZXRfbWFuaWZlc3Rfc2hhMjU2XCI6IFwiYjFlM2U2NmJjNDAyM2RjODBjNmVhNTk1NjRjMzU1N2M3NjUzZmIzYzMwN2Y0NmEwNDk5OTdiNzYxOThhOTAzM1wiLFxuICBcImtpbmRcIjogXCJtZWNoYW5pY2FsLWFjdHVhdG9yLXBhY2tldC1yZWZpbmVtZW50LXJlcXVpcmVkLWJlZm9yZS1maXJzdC1odW1hbi1wb3N0XCIsXG4gIFwiY2hhbmdlc1wiOiBbXG4gICAgXCJIYXNoLWJpbmQgYWxsIGV4ZWN1dG9yIGJ5dGVzL2V4ZWN1dGlvbnBsYW4gaW4gYW1lbmRlZDIwZG9jIHBhY2tldCwgcHJlc2VydmUgcHJpb3I3OHBhdGggdGVjaG5pY2FsIHJldmlld3MgYXMgaGlzdG9yeVwiLFxuICAgIFwiUmVxdWlyZSBmcmVzaCByb290IGZpeGVkLW9yaWdpbiBjb25maXJtZWQgZm91bmRlciByZWNlaXB0IGJlZm9yZSBlYWNoIHBoYXNlLCBubyBzaWduZWQgYXV0b25vbW91cyBncmFudFwiLFxuICAgIFwiQmluZCBhbGwgZm91ciBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGFuZCByZWplY3QgQXBwbGljYXRpb24gc291cmNlIG92ZXJyaWRlcyBvciBhdXRvbWF0ZWQ6e31cIixcbiAgICBcIkV4cGxpY2l0IG5ldyBpc29sYXRlZCBvZmZsaW5lIHZvbHVtZSBVSUQwL0NBUF9DSE9XTiBpbml0aWFsaXplciwgbm8gaG9zdC9saXZlUFZDL3Rva2VuL2NvbmZpZyBtb3VudHMsIGJvdW5kZWQ1MTJNaUIgcHJpdmF0ZSBzbmFwc2hvdCBzdHJlYW0gYW5kIG5hbWVkVm9sdW1lIG5vbmNlIG93bmVyc2hpcFwiLFxuICAgIFwiRHVyYWJsZSBwZXItcGhhc2UgUlVOTklORyBiZWZvcmUgYWN0aW9uOyBubyBzYW1lLXBoYXNlIHJldHJpZXMgYWZ0ZXIgZmFpbHVyZXMvY3Jhc2gsIGRpc3RpbmN0IHN1cGVydmlzZWQgc2FtZS1zY2hlbWEgcm9sbGJhY2sgcmV0YWlucyBsYXRlc3REQlwiLFxuICAgIFwiQWN0dWFsIG5hdGl2ZSBwcmUtb3BlbiByZWFkb25seXNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgYmVmb3JlIGJhY2t1cC9hZG1pbiwgYWN0dWFsIFBvZC9DTS9QVkMvc291cmNlIHNlYWxzLCBvZmZsaW5lIHByZS1vcGVuIGNoZWNrIGJlZm9yZSBhZG1pbmluc3BlY3QsIG5hdGl2ZWluc3RhbGxlZDEwc3ludGhldGljcHVycG9zZSBjaGVja3MrYm91bmRlZGxvY2FsaG9zdGhlYWx0aCBhZnRlcmNvbnRyb2xsZXJjb21wbGV0aW9uXCJcbiAgXSxcbiAgXCJ1bmNoYW5nZWRcIjogW1xuICAgIFwiaW1tdXRhYmxlNzYzYyBwdXJwb3Nlb25seSBpbWFnZVwiLFxuICAgIFwiQ29uZmlnTWFwNmMvcnVudGltZS9wb2xpY3kgcGlucy9hdWRpZW5jZXMvY3JlZGVudGlhbHNcIixcbiAgICBcIkRlcGxveW1lbnQtb25seSBtYW51YWxBcmdvIHNjb3BlZCBvcGVyYXRpb24vcHJ1bmVmYWxzZVwiLFxuICAgIFwiZXhpc3RpbmdQVkMvc2luZ2xld3JpdGVyL1JlY3JlYXRlL3NjaGVtYTVcIixcbiAgICBcImV4cGxpY2l0IGluaGVyaXRlZDFmaXhhYmxlTUVEIG93bmVyVDA1IGZvbGxvdy10aHJvdWdoXCJcbiAgXSxcbiAgXCJuYXRpdmVfYWN0aW9uX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICBcImZvdW5kZXJfYXBwcm92YWxcIjogZmFsc2UsXG4gIFwibWVjaGFuaWNhbF9yZXZpZXdfcmVmaW5lbWVudFwiOiB7XG4gICAgXCJvcmlnaW5hbF9tYW5pZmVzdF9zaGEyNTZcIjogXCI2NTNiNjhjMzg5MWMwNjZmNDBkMTA0YmZjNjdhMzVkYTVlNDM2NjA1Y2Q5OWFmZDUyZmJhYzRiNDdhOTU1M2ZlXCIsXG4gICAgXCJhcmNoaXZlXCI6IFwiZXhlY3V0aW9uLWhpc3RvcnkvaW5pdGlhbC02NTNiNjhjM1wiLFxuICAgIFwiZmluZGluZ3NcIjogW1xuICAgICAgXCJyb2xsYmFjayBpbmNvcnJlY3RseSBkZXBlbmRlZCBvbiBSZWFkeSBjYW5kaWRhdGUgYW5kIGRhdGFiYXNlIGV4ZWNcIixcbiAgICAgIFwib2ZmbGluZSBhZG1pbiBsYWNrZWQgcG9zdC1vcGVuIHJlYWRvbmx5IGZ1bGwgcHJvb2YgYW5kIG9yaWdpbmFsIHNuYXBzaG90IFNIQSBjaGVja1wiLFxuICAgICAgXCJhbGwtcGhhc2UgaGVscGVyIGRlYWRsaW5lIHdhcyBub3QgZGlzY2xvc2VkIGJ5IHByaW9yIHVuc3RhcnRlZC1yZWxlYXNlIHBhY2tldCB3b3JkaW5nXCJcbiAgICBdLFxuICAgIFwicmVzb2x2ZWRfYnlcIjogW1xuICAgICAgXCJyb2xsYmFjayBkaXNwYXRjaCBleGNsdWRlcyBQb2QgbWV0YWRhdGEvZXhlYyBlbnRpcmVseTsgc2VwYXJhdGUgcm9sbGJhY2stdmVyaWZ5IHByb3ZlcyByZWNvdmVyZWQgb2xkLWltYWdlL3NjaGVtYTUgREJcIixcbiAgICAgIFwicG9zdC1hZG1pbiBVSUQxMDAwMSByZWFkb25seSBpbnRlZ3JpdHkvc2NoZW1hL2NvdW50IHByb29mIGVxdWFscyBmcm96ZW4gc25hcHNob3Q7IHJldGFpbmVkIG9yaWdpbmFsIFNIQSB1bmNoYW5nZWRcIixcbiAgICAgIFwiZXhwbGljaXQgYWxsLXBoYXNlIGluY2x1ZGluZyByZWNvdmVyeS92ZXJpZmljYXRpb24gZGVhZGxpbmUgYW5kIGZyZXNoLWZvdW5kZXItZGVjaXNpb24gcmVxdWlyZW1lbnQgYmV5b25kIGV4cGlyeVwiXG4gICAgXSxcbiAgICBcInNhbWVfcHJvcG9zYWxfdHJpYWxcIjogdHJ1ZSxcbiAgICBcIm5hdGl2ZV9hY3Rpb25zX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICAgIFwiaHVtYW5fYWNjZXB0YW5jZVwiOiBmYWxzZVxuICB9XG59XG4iCiAgICB9LAogICAgInJlY2VpcHRfc2FmZXR5LnB5IjogewogICAgICAic2hhMjU2IjogIjVjNTQzNzNmMmRjNGIwNjQwMDgyMjVjMTg2ZWZiMWQ1YWZkZWVjMzZkMTUzNTBiZGEwYTEyZGVkOTc2MDJkMWIiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmx5IHN0cnVjdHVyYWwgY291bnQvaGFzaCByZWNlaXB0cyBjYW4gbGVhdmUgdGhlIHByaXZhdGUgZXhlY3V0aW9uIHBoYXNlLlwiXCJcIlxuZGVmIGNvdW50cyh2YWx1ZSk6XG4gICAgaWYgKHNldCh2YWx1ZSkgIT0geydzY2hlbWFfdmVyc2lvbicsICdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJywgJ2ludGVncml0eScsXG4gICAgICAgICAgICAgICAgICAgICAgICdyZWFkX29ubHlfcHJlX29wZW4nLCAnc3RvcmVfY29uc3RydWN0ZWQnfVxuICAgICAgICAgICAgb3IgdmFsdWVbJ3NjaGVtYV92ZXJzaW9uJ10gIT0gNSBvciB2YWx1ZVsnaW50ZWdyaXR5J10gIT0gJ29rJ1xuICAgICAgICAgICAgb3IgdmFsdWVbJ3JlYWRfb25seV9wcmVfb3BlbiddIGlzIG5vdCBUcnVlIG9yIHZhbHVlWydzdG9yZV9jb25zdHJ1Y3RlZCddIGlzIG5vdCBGYWxzZVxuICAgICAgICAgICAgb3Igc2V0KHZhbHVlWydsaWZlY3ljbGUnXSkgIT0geydyZWNvcmRzJywgJ2V2ZW50cycsICdwZW5kaW5nJ31cbiAgICAgICAgICAgIG9yIG5vdCBzZXQodmFsdWVbJ291dGJveCddKSA8PSB7J3BlbmRpbmcnLCAnZGVsaXZlcmVkJywgJ2Jsb2NrZWQnfVxuICAgICAgICAgICAgb3Igbm90IHNldCh2YWx1ZVsnc3VibWlzc2lvbnMnXSkgPD0geydwcmVwYXJlZCcsICdpbl9mbGlnaHQnLCAnY29uZmlybWVkJywgJ3VucmVzb2x2ZWQnfSk6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ2NvdW50LW9ubHkgcmVjZWlwdCBzaGFwZS9zdGF0ZSByZWZ1c2VkOyB2YWx1ZXMgd2l0aGhlbGQnKVxuICAgIGZvciBncm91cCBpbiAoJ2xpZmVjeWNsZScsICdvdXRib3gnLCAnc3VibWlzc2lvbnMnKTpcbiAgICAgICAgaWYgYW55KHR5cGUobnVtYmVyKSBpcyBub3QgaW50IG9yIG51bWJlciA8IDAgb3IgbnVtYmVyID4gMTAqKjEyXG4gICAgICAgICAgICAgICBmb3IgbnVtYmVyIGluIHZhbHVlW2dyb3VwXS52YWx1ZXMoKSk6XG4gICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdjb3VudC1vbmx5IHJlY2VpcHQgdmFsdWVzIHJlZnVzZWQnKVxuICAgIHJldHVybiB2YWx1ZVxuIgogICAgfSwKICAgICJyb290LWF1dGhvcml0eS1yZWNlaXB0LXRlbXBsYXRlLmpzb24iOiB7CiAgICAgICJzaGEyNTYiOiAiMTU5NjZiN2M2ZjA4OGEwMzNiYWYxZmVmODc4ZGRiMzUxZGUyZmEyYWU0NmI1YmM3MTAyNjVlZDE3MmFiMjgxMyIsCiAgICAgICJjb250ZW50IjogIntcbiAgXCJwcm9wb3NhbF9pZFwiOiBcIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxXCIsXG4gIFwibWVtb19pZFwiOiBcImluZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxXCIsXG4gIFwibWVtb192ZXJzaW9uXCI6IDEsXG4gIFwibWVtb19zaGEyNTZcIjogbnVsbCxcbiAgXCJzb3VyY2VfcmV2aXNpb25cIjogbnVsbCxcbiAgXCJhY3RpdmF0aW9uXCI6IFwiUEVORElOR1wiLFxuICBcImF1dGhvcml0eV9tb2RlXCI6IFwiQURNSU5JU1RFUlwiLFxuICBcInRhcmdldFwiOiBcInJlYWxtOmt1YmVybmV0ZXMvcmFpbGlhbmNlMDEvaW5mb3JtZWQtZGVjaXNpb25cIixcbiAgXCJ2ZXJpZmljYXRpb25fbWV0aG9kXCI6IFwicm9vdC1maXhlZC1vcmlnaW4tbmF0aXZlLXJlYWRiYWNrXCIsXG4gIFwicnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50XCI6IGZhbHNlLFxuICBcInZlcmlmaWVkX2F0XCI6IG51bGwsXG4gIFwiYWNjZXB0ZWRfYXRcIjogbnVsbCxcbiAgXCJyZXZpZXdfbWVtb19pZFwiOiBudWxsLFxuICBcImFwcHJvdmFsX2lkXCI6IG51bGwsXG4gIFwiZGlzcG9zaXRpb25faWRcIjogbnVsbCxcbiAgXCJuYXRpdmVfb3V0Y29tZV9zaGEyNTZcIjogbnVsbCxcbiAgXCJleGVjdXRvcl9wbGFuX3NoYTI1NlwiOiBcIjRkNTUzMGU3NDE4ZjYzOGIxMGNjZmYwZTBkOWEwNzI3YWRjNjRhN2YzYTQ1OTA3ZjZkZWI1NzM5YWQyYWRjODVcIlxufVxuIgogICAgfSwKICAgICJ0ZXN0X2V4ZWN1dGlvbi5weSI6IHsKICAgICAgInNoYTI1NiI6ICI5Y2NmNmQ0MjFiZjIwZjBlODM1MGY2NzEzZDZkMWNlZTJiYTE5OWY0ODVkY2FmMjU1OGMzODc0MjFkOWEyYjQ4IiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiU3ludGhldGljIGN1c3RvZHkvdHJhbnNwb3J0IHRlc3RzLiBObyBuYXRpdmUgZGF0YSwgRG9ja2VyIG9yIGNsdXN0ZXIgYWN0aW9uLlwiXCJcIlxuaW1wb3J0IGNvcHlcbmltcG9ydCBkYXRldGltZVxuaW1wb3J0IGlvXG5pbXBvcnQganNvblxuaW1wb3J0IG9zXG5mcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGhcbmltcG9ydCBzdWJwcm9jZXNzXG5pbXBvcnQgc3lzXG5pbXBvcnQgdGVtcGZpbGVcbmltcG9ydCB1bml0dGVzdFxuZnJvbSB1bml0dGVzdC5tb2NrIGltcG9ydCBwYXRjaFxuZnJvbSBjb250ZXh0bGliIGltcG9ydCByZWRpcmVjdF9zdGRvdXRcblxuaW1wb3J0IGFjdHVhdG9yXG5mcm9tIGF1dGhvcml0eV9qb3VybmFsIGltcG9ydCBKb3VybmFsLCBhdXRob3JpdHlcbmZyb20gbmF0aXZlX3Byb2dyYW0gaW1wb3J0IFBST0dSQU1cbmZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuXG5DQVNFID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uL2RvY3MvZXZpZGVuY2UvMjAyNi0xMC0xMS1wdXJwb3NlLWltYWdlLXJlbGVhc2UnKVxuTk9XID0gZGF0ZXRpbWUuZGF0ZXRpbWUoMjAyNiwgMTAsIDExLCAyLCAwLCB0emluZm89ZGF0ZXRpbWUudGltZXpvbmUudXRjKVxuUkVWSVNJT04gPSAnZScgKiA0MFxuQ09VTlQgPSB7J3NjaGVtYV92ZXJzaW9uJzogNSwgJ2ludGVncml0eSc6ICdvaycsICdyZWFkX29ubHlfcHJlX29wZW4nOiBUcnVlLCAnc3RvcmVfY29uc3RydWN0ZWQnOiBGYWxzZSxcbiAgICAgICAgICdsaWZlY3ljbGUnOiB7J3JlY29yZHMnOiAzLCAnZXZlbnRzJzogOCwgJ3BlbmRpbmcnOiAxfSxcbiAgICAgICAgICdvdXRib3gnOiB7J3BlbmRpbmcnOiAyLCAnZGVsaXZlcmVkJzogMTB9LCAnc3VibWlzc2lvbnMnOiB7J2NvbmZpcm1lZCc6IDEsICd1bnJlc29sdmVkJzogMX19XG5cblxuZGVmIGFjY2VwdGVkKCk6XG4gICAgYXBwcm92YWwgPSAnMTExMTExMTEtMTExMS00MTExLTgxMTEtMTExMTExMTExMTExJ1xuICAgIHJldmlldyA9ICdyZXZpZXctMjIyMjIyMjItMjIyMi00MjIyLTgyMjItMjIyMjIyMjIyMjIyJ1xuICAgIGRpc3Bvc2l0aW9uID0gJ2Rpc3AtMzMzMzMzMzMtMzMzMy00MzMzLTgzMzMtMzMzMzMzMzMzMzMzJ1xuICAgIHJlY2VpcHQgPSB7J3Byb3Bvc2FsX2lkJzogJ0lORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxJyxcbiAgICAgICAgICAgICAgICdtZW1vX2lkJzogJ2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxJywgJ21lbW9fdmVyc2lvbic6IDEsXG4gICAgICAgICAgICAgICAnbWVtb19zaGEyNTYnOiAnYScgKiA2NCwgJ3NvdXJjZV9yZXZpc2lvbic6IFJFVklTSU9OLCAnYWN0aXZhdGlvbic6ICdBUFBST1ZFRCcsXG4gICAgICAgICAgICAgICAnYXV0aG9yaXR5X21vZGUnOiAnQURNSU5JU1RFUicsICd0YXJnZXQnOiAncmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbicsXG4gICAgICAgICAgICAgICAndmVyaWZpY2F0aW9uX21ldGhvZCc6ICdyb290LWZpeGVkLW9yaWdpbi1uYXRpdmUtcmVhZGJhY2snLCAncnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50JzogRmFsc2UsXG4gICAgICAgICAgICAgICAndmVyaWZpZWRfYXQnOiAnMjAyNi0xMC0xMVQwMjowMDowMFonLCAnYWNjZXB0ZWRfYXQnOiAnMjAyNi0xMC0xMVQwMTo1OTowMFonLFxuICAgICAgICAgICAgICAgJ3Jldmlld19tZW1vX2lkJzogcmV2aWV3LCAnYXBwcm92YWxfaWQnOiBhcHByb3ZhbCwgJ2Rpc3Bvc2l0aW9uX2lkJzogZGlzcG9zaXRpb259XG4gICAgb3V0Y29tZSA9IHsnbWVtb19pZCc6IHJlY2VpcHRbJ21lbW9faWQnXSwgJ3Jldmlldyc6IHsnbWVtb19pZCc6IHJldmlldywgJ3N0YWxlJzogRmFsc2UsICdpbnRha2Vfc3RhdGUnOiAncmVhZHknfSxcbiAgICAgICAgICAgICAgICdkaXNwb3NpdGlvbnMnOiBbeydhcHByb3ZhbF9pZCc6IE5vbmUsICdzdWJtaXNzaW9uX3N0YXRlJzogJ2NvbmZpcm1lZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGlzcG9zaXRpb24nOiB7J3ZlcmInOiAnYWNjZXB0JywgJ21lbW9fdmVyc2lvbic6IDEsICdtZW1vX2lkJzogcmV2aWV3LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhcHByb3ZhbF9pZCc6IGFwcHJvdmFsLCAnaWQnOiBkaXNwb3NpdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYWN0b3InOiB7J2tpbmQnOiAncGVyc29uJywgJ3N1Yic6ICd1aWQ9cGxhdGZvcm0tcm9vdCxvdT1wZW9wbGUsZGM9bmV0a2luZ2RvbSxkYz1sb2NhbCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhdCc6IHJlY2VpcHRbJ2FjY2VwdGVkX2F0J119fV19XG4gICAgcmV0dXJuIHJlY2VpcHQsIG91dGNvbWVcblxuXG5jbGFzcyBBdXRob3JpdHlBbmRDdXN0b2R5KHVuaXR0ZXN0LlRlc3RDYXNlKTpcbiAgICBkZWYgdGVzdF9leGFjdF9uZXN0ZWRfZm91bmRlcl9yZWNlaXB0X25vdF90b3BfbGV2ZWxfYXBwcm92YWwoc2VsZik6XG4gICAgICAgIHJlY2VpcHQsIG91dGNvbWUgPSBhY2NlcHRlZCgpXG4gICAgICAgIHJlc3VsdCA9IGF1dGhvcml0eShyZWNlaXB0LCBvdXRjb21lLCAnYScgKiA2NCwgUkVWSVNJT04sICdkcmlsbC1iYWNrdXAnLCBOT1cpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydhcHByb3ZhbF9pZCddLCByZWNlaXB0WydhcHByb3ZhbF9pZCddKVxuXG4gICAgZGVmIHRlc3RfcGVuZGluZ19zdGFsZV93cm9uZ19hY3Rvcl92ZXJzaW9uX2FuZF9iaW5kaW5nX3JlZnVzZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSByLCBvOiByLnVwZGF0ZShhY3RpdmF0aW9uPSdQRU5ESU5HJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUobWVtb19zaGEyNTY9J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZShzb3VyY2VfcmV2aXNpb249J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZSh0YXJnZXQ9J290aGVyJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpZWRfYXQ9JzIwMjYtMTAtMTFUMDE6MDA6MDBaJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpY2F0aW9uX21ldGhvZD0nY2FsbGVyLWFzc2VydGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUocnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50PVRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ3JldmlldyddLnVwZGF0ZShzdGFsZT1UcnVlKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydyZXZpZXcnXS51cGRhdGUoaW50YWtlX3N0YXRlPSdwZW5kaW5nJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ11bMF0udXBkYXRlKHN1Ym1pc3Npb25fc3RhdGU9J3VucmVzb2x2ZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydkaXNwb3NpdGlvbnMnXVswXVsnZGlzcG9zaXRpb24nXS51cGRhdGUobWVtb192ZXJzaW9uPTIpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddLnVwZGF0ZShhY3Rvcj17J2tpbmQnOiAnYWdlbnQnLCAnc3ViJzogJ3BsYXRmb3JtLXJvb3QnfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ10uYXBwZW5kKGNvcHkuZGVlcGNvcHkob1snZGlzcG9zaXRpb25zJ11bMF0pKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShyLCBvKVxuICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyZWxlYXNlJywgTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwaXJlZF93aW5kb3dfYW5kX3Vua25vd25fcGhhc2VfcmVmdXNlKHNlbGYpOlxuICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgYXV0aG9yaXR5KHIsIG8sICdhJyAqIDY0LCBSRVZJU0lPTiwgJ2FyYml0cmFyeScsIE5PVylcbiAgICAgICAgbGF0ZSA9IGRhdGV0aW1lLmRhdGV0aW1lKDIwMjYsIDEwLCAxMywgdHppbmZvPWRhdGV0aW1lLnRpbWV6b25lLnV0YylcbiAgICAgICAgclsndmVyaWZpZWRfYXQnXSA9IGxhdGUuaXNvZm9ybWF0KClcbiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyb2xsYmFjaycsIGxhdGUpXG5cbiAgICBkZWYgdGVzdF9kdXJhYmxlX2ludGVudF9wcmVjZWRlc19kaXNwYXRjaF9hbmRfbmV2ZXJfcmV0cmllcyhzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQgPSBQYXRoKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIG9zLmNobW9kKHBhcmVudCwgMG83MDApXG4gICAgICAgICAgICBqb3VybmFsID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICBqb3VybmFsLnN0YXJ0KCdkcmlsbC1iYWNrdXAnLCB7J2FwcHJvdmFsX2lkJzogJ2ZpeHR1cmUnfSlcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoanNvbi5sb2Fkcyhqb3VybmFsLnBhdGgucmVhZF90ZXh0KCkpWydwaGFzZXMnXVsnZHJpbGwtYmFja3VwJ11bJ3N0YXRlJ10sICdSVU5OSU5HJylcbiAgICAgICAgICAgIGpvdXJuYWwuY2xvc2UoKSAgIyBzaW11bGF0ZWQgY3Jhc2ggYmVmb3JlIHJlc3VsdFxuICAgICAgICAgICAgcmVjb3ZlcmVkID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtYmFja3VwJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtY29weScsIHt9KVxuICAgICAgICAgICAgcmVjb3ZlcmVkLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X3BoYXNlX29yZGVyX2FuZF91bmNlcnRhaW5fcmVsZWFzZV9hbGxvd3Nfb25seV9kaXN0aW5jdF9yZWNvdmVyeShzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBvcy5jaG1vZChkaXJlY3RvcnksIDBvNzAwKVxuICAgICAgICAgICAgaiA9IEpvdXJuYWwoZGlyZWN0b3J5LCB7J2Nhc2UnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICBmb3IgcGhhc2UgaW4gYWN0dWF0b3IuUEhBU0VTWzo2XTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KHBoYXNlLCB7fSlcbiAgICAgICAgICAgICAgICBqLmZpbmlzaChwaGFzZSwgeydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlfSlcbiAgICAgICAgICAgIGouc3RhcnQoJ3JlbGVhc2UnLCB7fSlcbiAgICAgICAgICAgIGouZmluaXNoKCdyZWxlYXNlJywgeydhbGxfY2hlY2tzX3Bhc3MnOiBGYWxzZX0pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGouc3RhcnQoJ3JlbGVhc2UnLCB7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgai5zdGFydCgndmVyaWZ5Jywge30pXG4gICAgICAgICAgICBqLnN0YXJ0KCdyb2xsYmFjaycsIHt9KVxuICAgICAgICAgICAgai5maW5pc2goJ3JvbGxiYWNrJywgeydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlfSlcbiAgICAgICAgICAgIGouY2xvc2UoKVxuXG4gICAgZGVmIHRlc3Rfc2VjcmV0X29yX3Vua25vd25fY2hpbGRfb3V0cHV0X2lzX3dpdGhoZWxkKHNlbGYpOlxuICAgICAgICBmb3IgYm9keSBpbiAoJ25vdC1qc29uJywgJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJ0b2tlblwiOlwicHJpdmF0ZS12YWx1ZVwifScsXG4gICAgICAgICAgICAgICAgICAgICAne1wiYWxsX2NoZWNrc19wYXNzXCI6dHJ1ZSxcInNuYXBzaG90X3JlYWRvbmx5XCI6e1wic2NoZW1hX3ZlcnNpb25cIjo1fX0nKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgYWN0dWF0b3IuanNvbl9yZXN1bHQoc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBib2R5LCAnJykpXG4gICAgICAgIHdyb25nID0gY29weS5kZWVwY29weShDT1VOVClcbiAgICAgICAgd3JvbmdbJ291dGJveCddID0geydwcml2YXRlLXJvdy12YWx1ZSc6IDF9XG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICBjb3VudHMod3JvbmcpXG4gICAgICAgIGNvdW50cyhDT1VOVCkgICMgYmxvY2tlZC91bnJlc29sdmVkIGNvdW50cyBhcmUgbm90IHJlcXVpcmVkIHRvIGJlIHplcm8uXG5cbiAgICBkZWYgdGVzdF9iaW5hcnlfY29weV9pc19ib3VuZGVkX3ByaXZhdGVfYW5kX25ldmVyX2VjaG9lZChzZWxmKTpcbiAgICAgICAgYmxvYiA9IGInc3ludGhldGljIHByaXZhdGUgZml4dHVyZSBieXRlcydcbiAgICAgICAgZGlnZXN0ID0gX19pbXBvcnRfXygnaGFzaGxpYicpLnNoYTI1NihibG9iKS5oZXhkaWdlc3QoKVxuICAgICAgICBtZXRhZGF0YSA9IHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ3NuYXBzaG90X2ZpbGUnOiAnZHJpbGwuc3FsaXRlJywgJ3NuYXBzaG90X2J5dGVzJzogbGVuKGJsb2IpLFxuICAgICAgICAgICAgICAgICAgICAnc25hcHNob3Rfc2hhMjU2JzogZGlnZXN0LCAnc25hcHNob3RfcmVhZG9ubHknOiBDT1VOVCxcbiAgICAgICAgICAgICAgICAgICAgJ3BvZF9uYW1lJzogJ2ZpeHR1cmUtcG9kJywgJ3BvZF91aWQnOiAnZml4dHVyZS11aWQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7J2RyaWxsLWJhY2t1cCc6IHsncmVzdWx0JzogbWV0YWRhdGF9fX19KSgpXG4gICAgICAgIHJlYWxfcG9wZW4gPSBzdWJwcm9jZXNzLlBvcGVuXG4gICAgICAgIGZvciBleHRyYSBpbiAoYicnLCBiJ292ZXJzaXplZCcpOlxuICAgICAgICAgICAgd2l0aCBzZWxmLnN1YlRlc3QoZXh0cmE9ZXh0cmEpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBmb2xkZXI6XG4gICAgICAgICAgICAgICAgb3MuY2htb2QoZm9sZGVyLCAwbzcwMClcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSBpby5TdHJpbmdJTygpXG5cbiAgICAgICAgICAgICAgICBkZWYgY2hpbGQoKmFyZ3MsICoqa3dhcmdzKTpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWxfcG9wZW4oW3N5cy5leGVjdXRhYmxlLCAnLWMnLCAnaW1wb3J0IHN5cztzeXMuc3Rkb3V0LmJ1ZmZlci53cml0ZSgnICsgcmVwcihibG9iICsgZXh0cmEpICsgJyknXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTClcblxuICAgICAgICAgICAgICAgIHdpdGggcGF0Y2gub2JqZWN0KGFjdHVhdG9yLCAnQ1VTVE9EWScsIFBhdGgoZm9sZGVyKSksIHBhdGNoLm9iamVjdChhY3R1YXRvciwgJ3JlbW90ZScsIHJldHVybl92YWx1ZT1tZXRhZGF0YSksIFxcXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRjaCgnc3VicHJvY2Vzcy5Qb3BlbicsIHNpZGVfZWZmZWN0PWNoaWxkKSwgcmVkaXJlY3Rfc3Rkb3V0KG91dHB1dCk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGV4dHJhOlxuICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YXRvci5jb3B5X3NuYXBzaG90KCdkcmlsbC1jb3B5JywgUkVWSVNJT04sIHt9LCBqb3VybmFsKVxuICAgICAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYWN0dWF0b3IuY29weV9zbmFwc2hvdCgnZHJpbGwtY29weScsIFJFVklTSU9OLCB7fSwgam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29mZl9jbHVzdGVyX3ByaXZhdGVfY29weV92ZXJpZmllZCddKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoUGF0aChmb2xkZXIpIC8gJ2RyaWxsLnNxbGl0ZScpLnJlYWRfYnl0ZXMoKSwgYmxvYilcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG91dHB1dC5nZXR2YWx1ZSgpLCAnJylcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKChQYXRoKGZvbGRlcikgLyAnZHJpbGwuc3FsaXRlJykuc3RhdCgpLnN0X21vZGUgJiAwbzc3NywgMG82MDApXG5cbiAgICBkZWYgdGVzdF9yZWNyZWF0ZWRfb2ZmbGluZV92b2x1bWVfY2Fubm90X2JlX2RlbGV0ZWQoc2VsZik6XG4gICAgICAgIGlkZW50aXR5ID0geydOYW1lJzogYWN0dWF0b3IuVk9MVU1FLCAnTGFiZWxzJzogeydub25jZSc6ICdvbGQnfSwgJ0NyZWF0ZWRBdCc6ICdvbGQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7XG4gICAgICAgICAgICAnb2ZmbGluZS12ZXJpZnknOiB7J3Jlc3VsdCc6IHsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknOiBpZGVudGl0eX19fX19KSgpXG4gICAgICAgIGluc3BlY3RlZCA9IFt7KippZGVudGl0eSwgJ0NyZWF0ZWRBdCc6ICdyZWNyZWF0ZWQnfV1cbiAgICAgICAgd2l0aCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdkb2NrZXInLCByZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBqc29uLmR1bXBzKGluc3BlY3RlZCksICcnKSkgYXMgbW9ja2VkOlxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBhY3R1YXRvci5jbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobW9ja2VkLmNhbGxfY291bnQsIDEpXG5cbiAgICBkZWYgdGVzdF9vZmZsaW5lX3Bvc3RfYWRtaW5faW50ZWdyaXR5X2FuZF9vcmlnaW5hbF9oYXNoX2FyZV9yZWNoZWNrZWQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdub25lJywgJ3Bvc3QtaW50ZWdyaXR5JywgJ29yaWdpbmFsLWhhc2gnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgZm9sZGVyPVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChmb2xkZXIsMG83MDApXG4gICAgICAgICAgICAgICAgc25hcHNob3Q9Zm9sZGVyLydkcmlsbC5zcWxpdGUnO3NuYXBzaG90LndyaXRlX2J5dGVzKGIncHJpdmF0ZSBzeW50aGV0aWMgc25hcHNob3QnKTtvcy5jaG1vZChzbmFwc2hvdCwwbzYwMClcbiAgICAgICAgICAgICAgICBkaWdlc3Q9YWN0dWF0b3Iuc2hhKHNuYXBzaG90KVxuICAgICAgICAgICAgICAgIHByaW9yPXsnc25hcHNob3Rfc2hhMjU2JzpkaWdlc3QsJ3NuYXBzaG90X3JlYWRvbmx5JzpDT1VOVH1cbiAgICAgICAgICAgICAgICBqb3VybmFsPXR5cGUoJ0ZpeHR1cmVKb3VybmFsJywoKSx7J2RhdGEnOnsncGhhc2VzJzp7J2RyaWxsLWNvcHknOnsncmVzdWx0Jzpwcmlvcn0sJ29mZmxpbmUtdmVyaWZ5Jzp7J2F0dGVtcHRfaWQnOidub25jZSd9fX0sJ25vdGUnOmxhbWJkYSAqYXJnczpOb25lfSkoKVxuICAgICAgICAgICAgICAgIHJlYWRzPVtdXG4gICAgICAgICAgICAgICAgdm9sdW1lPXsnTmFtZSc6YWN0dWF0b3IuVk9MVU1FLCdMYWJlbHMnOnsnaW5mb3JtZWQtZGVjaXNpb24uY2FzZSc6J2luZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsJ2luZm9ybWVkLWRlY2lzaW9uLnVzZSc6J29mZmxpbmUtcmVzdG9yZS1vbmx5JywnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdCc6J25vbmNlJ30sJ0RyaXZlcic6J2xvY2FsJywnU2NvcGUnOidsb2NhbCcsJ0NyZWF0ZWRBdCc6J2ZpeHR1cmUnLCdPcHRpb25zJzpOb25lfVxuICAgICAgICAgICAgICAgIGRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCAqKmt3YXJncyk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGFyZ3ZbMF09PSdpbmZvJzpib2R5PWpzb24uZHVtcHMoJ2JudC1sYXAwMDEnKVxuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2xzJ106Ym9keT0nJ1xuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2NyZWF0ZSddOmJvZHk9YWN0dWF0b3IuVk9MVU1FXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgYXJndls6Ml09PVsndm9sdW1lJywnaW5zcGVjdCddOmJvZHk9anNvbi5kdW1wcyhbdm9sdW1lXSlcbiAgICAgICAgICAgICAgICAgICAgZWxpZiAnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4nIGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5PWpzb24uZHVtcHMoe2tleTpDT1VOVFtrZXldIGZvciBrZXkgaW4gKCdzY2hlbWFfdmVyc2lvbicsJ2xpZmVjeWNsZScsJ291dGJveCcsJ3N1Ym1pc3Npb25zJyl9KVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgZGVmZWN0PT0nb3JpZ2luYWwtaGFzaCc6c25hcHNob3Qud3JpdGVfYnl0ZXMoYidjaGFuZ2VkIHN5bnRoZXRpYyBvcmlnaW5hbCcpXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgJy0tZW50cnlwb2ludCcgaW4gYXJndiBhbmQgJ3B5dGhvbicgaW4gYXJndjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRzLmFwcGVuZChhcmd2KTtwcm9vZj1jb3B5LmRlZXBjb3B5KENPVU5UKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKHJlYWRzKT09MiBhbmQgZGVmZWN0PT0ncG9zdC1pbnRlZ3JpdHknOnByb29mWydpbnRlZ3JpdHknXT0nY29ycnVwdCdcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk9anNvbi5kdW1wcyhwcm9vZilcbiAgICAgICAgICAgICAgICAgICAgZWxzZTpyYWlzZSBBc3NlcnRpb25FcnJvcigndW5leHBlY3RlZCBvZmZsaW5lIGNvbW1hbmQnKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsMCxib2R5LCcnKVxuICAgICAgICAgICAgICAgIHdpdGggcGF0Y2gub2JqZWN0KGFjdHVhdG9yLCdDVVNUT0RZJyxmb2xkZXIpLHBhdGNoLm9iamVjdChhY3R1YXRvciwnQ0FTRScsQ0FTRSkscGF0Y2gub2JqZWN0KGFjdHVhdG9yLCdkb2NrZXInLHNpZGVfZWZmZWN0PWRvY2tlcikscGF0Y2goJ3N1YnByb2Nlc3MucnVuJyxyZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLDAsJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJwcml2YXRlX2NvcHlfdmVyaWZpZWRcIjp0cnVlfScsJycpKTpcbiAgICAgICAgICAgICAgICAgICAgaWYgZGVmZWN0PT0nbm9uZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ9YWN0dWF0b3Iub2ZmbGluZV92ZXJpZnkoam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydvZmZsaW5lX3Bvc3RfYWRtaW5fcmVhZG9ubHknXSxDT1VOVClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29yaWdpbmFsX3NuYXBzaG90X2hhc2hfdW5jaGFuZ2VkJ10pXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmFjdHVhdG9yLm9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVhZHMpLDIpXG5cblxuY2xhc3MgRml4ZWROYXRpdmVQcm9ncmFtKHVuaXR0ZXN0LlRlc3RDYXNlKTpcbiAgICBkZWYgZml4dHVyZShzZWxmKTpcbiAgICAgICAgc2VhbGVkID0ganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgbGl2ZSA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKVxuICAgICAgICBsaXZlWydtZXRhZGF0YSddLnVwZGF0ZShnZW5lcmF0aW9uPTQyKVxuICAgICAgICBsaXZlWydzdGF0dXMnXSA9IHsncmVhZHlSZXBsaWNhcyc6IDEsICd1cGRhdGVkUmVwbGljYXMnOiAxLCAnb2JzZXJ2ZWRHZW5lcmF0aW9uJzogNDJ9XG4gICAgICAgIGRlcGVuZGVuY2llcyA9IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLW5hdGl2ZS1kZXBlbmRlbmNpZXMuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBjbSA9IGNvcHkuZGVlcGNvcHkoZGVwZW5kZW5jaWVzWydjb25maWdtYXAnXSlcbiAgICAgICAgY20ucG9wKCdjYW5vbmljYWxfZGF0YV9zaGEyNTYnKVxuICAgICAgICBzZXJ2aWNlID0ganNvbi5sb2FkcygoQ0FTRSAvICdjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgICAgIHNvdXJjZV9zZXJ2aWNlID0ganNvbi5sb2FkcygoQ0FTRS5wYXJlbnRzWzJdIC8gJ2RlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBjbVsnZGF0YSddID0gbmV4dCh4IGZvciB4IGluIHNvdXJjZV9zZXJ2aWNlWydpdGVtcyddIGlmIHhbJ2tpbmQnXSA9PSAnQ29uZmlnTWFwJylbJ2RhdGEnXVxuICAgICAgICBwdmMgPSBjb3B5LmRlZXBjb3B5KGRlcGVuZGVuY2llc1sncHZjJ10pXG4gICAgICAgIHB2Y1snc3RhdHVzJ10gPSB7J3BoYXNlJzogJ0JvdW5kJ31cbiAgICAgICAgYXBwID0geydtZXRhZGF0YSc6IHsndWlkJzogJzQ5OTg2OGYyLWVhYmMtNGRmNC1hZTMxLWI4OWNlNThkNzUwZCcsICdyZXNvdXJjZVZlcnNpb24nOiAnMTcnfSxcbiAgICAgICAgICAgICAgICdzcGVjJzogeydzb3VyY2UnOiB7J3JlcG9VUkwnOiAnaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhdGgnOiAnZGVwbG95L2xpZmVjeWNsZScsICd0YXJnZXRSZXZpc2lvbic6ICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGVzdGluYXRpb24nOiB7J25hbWVzcGFjZSc6ICdpbmZvcm1lZC1kZWNpc2lvbicsICdzZXJ2ZXInOiAnaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjJ319fVxuICAgICAgICBvYmplY3RzID0geydkZXBsb3ltZW50JzogbGl2ZSwgJ2NvbmZpZ21hcCc6IGNtLCAncHZjJzogcHZjLCAnYXBwbGljYXRpb24nOiBhcHB9XG4gICAgICAgIHBheWxvYWQgPSB7J3BoYXNlJzogJ3JlbGVhc2UnLCAnc291cmNlX3JldmlzaW9uJzogUkVWSVNJT04sICdhcHByb3ZhbCc6IHt9LCAnc2VhbGVkJzogc2VhbGVkLFxuICAgICAgICAgICAgICAgICAgICdkZXBlbmRlbmNpZXMnOiBkZXBlbmRlbmNpZXMsICdjYW5kaWRhdGUnOiBzZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICdyb2xsYmFjayc6IGpzb24ubG9hZHMoKENBU0UgLyAncm9sbGJhY2stZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgICAgICdyZWFkb25seSc6IChDQVNFIC8gJ3NxbGl0ZV9yZWFkb25seS5weScpLnJlYWRfdGV4dCgpLCdwdXJwb3NlX2NoZWNrcyc6KENBU0UvJ2NoZWNrX2luc3RhbGxlZC5weScpLnJlYWRfdGV4dCgpLFxuICAgICAgICAgICAgICAgICAgICdyZWNlaXB0X3NhZmV0eSc6IChQYXRoKF9fZmlsZV9fKS5wYXJlbnQgLyAncmVjZWlwdF9zYWZldHkucHknKS5yZWFkX3RleHQoKX1cbiAgICAgICAgcmV0dXJuIG9iamVjdHMsIHBheWxvYWRcblxuICAgIGRlZiBleGVjdXRlX2Zha2Uoc2VsZiwgb2JqZWN0cywgcGF5bG9hZCwgYW1iaWd1b3VzPUZhbHNlLCBzY2hlbWFfcmVmdXNlZD1GYWxzZSk6XG4gICAgICAgIHdyaXRlcyA9IFtdXG4gICAgICAgIGNhbGxzID0gW11cblxuICAgICAgICBkZWYgZmFrZShhcmd2LCBpbnB1dD1Ob25lLCAqKmt3YXJncyk6XG4gICAgICAgICAgICBjYWxscy5hcHBlbmQoYXJndilcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdnZXQnXTpcbiAgICAgICAgICAgICAgICBraW5kID0gYXJndlsyXVxuICAgICAgICAgICAgICAgIGlmIGtpbmQgaW4gb2JqZWN0czpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IG9iamVjdHNba2luZF1cbiAgICAgICAgICAgICAgICBlbGlmIGtpbmQgPT0gJ3BvZHMnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydpdGVtcyc6IFt7J21ldGFkYXRhJzogeyduYW1lJzogJ2ZpeHR1cmUtcG9kJywgJ3VpZCc6ICdwb2QtdWlkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvd25lclJlZmVyZW5jZXMnOiBbeydraW5kJzogJ1JlcGxpY2FTZXQnLCAnbmFtZSc6ICdmaXh0dXJlLXJzJywgJ3VpZCc6ICdycy11aWQnfV19LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BlYyc6IG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3BlYyddWyd0ZW1wbGF0ZSddWydzcGVjJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdGF0dXMnOiB7J3BoYXNlJzogJ1J1bm5pbmcnLCAnY29udGFpbmVyU3RhdHVzZXMnOiBbeyduYW1lJzonaW5mb3JtZWQtZGVjaXNpb24nLCdyZWFkeSc6IFRydWV9XX19XX1cbiAgICAgICAgICAgICAgICBlbGlmIGtpbmQgPT0gJ3JlcGxpY2FzZXQnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydtZXRhZGF0YSc6IHsndWlkJzogJ3JzLXVpZCcsICdvd25lclJlZmVyZW5jZXMnOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7J2tpbmQnOiAnRGVwbG95bWVudCcsICd1aWQnOiBwYXlsb2FkWydzZWFsZWQnXVsnbWV0YWRhdGEnXVsndWlkJ119XX19XG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdub2Rlcyc6XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSB7J2l0ZW1zJzogW3snbWV0YWRhdGEnOiB7J25hbWUnOiAnZml4dHVyZS1ub2RlJ30sICdzdGF0dXMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnYWRkcmVzc2VzJzogW3snYWRkcmVzcyc6ICc5Mi4yMDUuNjIuMjM5J31dLCAnYWxsb2NhdGFibGUnOiB7J2NwdSc6ICc0J30sXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZGl0aW9ucyc6IFt7J3R5cGUnOiBrZXksICdzdGF0dXMnOiAnVHJ1ZScgaWYga2V5ID09ICdSZWFkeScgZWxzZSAnRmFsc2UnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIGtleSBpbiAoJ1JlYWR5JywgJ01lbW9yeVByZXNzdXJlJywgJ0Rpc2tQcmVzc3VyZScsICdQSURQcmVzc3VyZScpXX19XX1cbiAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICByYWlzZSBBc3NlcnRpb25FcnJvcigndW5leHBlY3RlZCBmaXhlZCBtZXRhZGF0YSByb3V0ZScpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKGJvZHkpLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdleGVjJ106XG4gICAgICAgICAgICAgICAgaWYgc2NoZW1hX3JlZnVzZWQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJycsICd3aXRoaGVsZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKHtcbiAgICAgICAgICAgICAgICAgICAgJ2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdsaXZlX3JlYWRvbmx5X3NjaGVtYV9pbnRlZ3JpdHlfY291bnRzJzogQ09VTlR9KSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnYXBwbHknXTpcbiAgICAgICAgICAgICAgICBhZG1pdHRlZCA9IGNvcHkuZGVlcGNvcHkocGF5bG9hZFsnc2VhbGVkJ10pXG4gICAgICAgICAgICAgICAgYWRtaXR0ZWRbJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSAoYWN0dWF0b3IuSU1BR0UgaWYgcGF5bG9hZFsncGhhc2UnXT09J3JlbGVhc2UnIGVsc2UgcGF5bG9hZFsnc2VhbGVkJ11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKGFkbWl0dGVkKSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZGVzY3JpYmUnXTpcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDAsICdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcbiBjcHUgMzQ2MG0gKDg2JSlcXG4nLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdkaWZmJ106XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAxLCAnLWltYWdlOiBiYXNlXFxuK2ltYWdlOiBjYW5kaWRhdGVcXG4nLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdwYXRjaCddOlxuICAgICAgICAgICAgICAgIGlmICctLWRyeS1ydW49c2VydmVyJyBub3QgaW4gYXJndjpcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVzLmFwcGVuZChqc29uLmxvYWRzKGlucHV0KSlcbiAgICAgICAgICAgICAgICAgICAgaWYgYW1iaWd1b3VzOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAxLCAnJywgJ3dpdGhoZWxkJylcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDAsICdhcHBsaWNhdGlvbi5hcmdvcHJvai5pby9pbmZvcm1lZC1kZWNpc2lvblxcbicsICcnKVxuICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgY29tbWFuZCcpXG5cbiAgICAgICAgc291cmNlID0gUFJPR1JBTS5yZXBsYWNlKCdfX1BBWUxPQURfXycsIHJlcHIoanNvbi5kdW1wcyhwYXlsb2FkKSkpLnJlcGxhY2UoXG4gICAgICAgICAgICAnX19HVUFSRF9fJywgcmVwcigoQ0FTRSAvICdjaGFuZ2VfZ3VhcmQucHknKS5yZWFkX3RleHQoKSkpXG4gICAgICAgIG91dHB1dCA9IGlvLlN0cmluZ0lPKClcbiAgICAgICAgd2l0aCBwYXRjaCgnc3VicHJvY2Vzcy5ydW4nLCBzaWRlX2VmZmVjdD1mYWtlKSwgcmVkaXJlY3Rfc3Rkb3V0KG91dHB1dCk6XG4gICAgICAgICAgICB0cnk6XG4gICAgICAgICAgICAgICAgZXhlYyhjb21waWxlKHNvdXJjZSwgJ2ZpeGVkLW5hdGl2ZS1maXh0dXJlJywgJ2V4ZWMnKSwgeydfX25hbWVfXyc6ICdfX2ZpeHR1cmVfXyd9KVxuICAgICAgICAgICAgZXhjZXB0IChWYWx1ZUVycm9yLCBTeXN0ZW1FeGl0KTpcbiAgICAgICAgICAgICAgICBwYXNzXG4gICAgICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKG91dHB1dC5nZXR2YWx1ZSgpKSBpZiBvdXRwdXQuZ2V0dmFsdWUoKSBlbHNlIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2V9XG4gICAgICAgIHJldHVybiByZWNlaXB0LCB3cml0ZXMsIGNhbGxzXG5cbiAgICBkZWYgdGVzdF9vbmx5X2V4aXN0aW5nX2FwcGxpY2F0aW9uX29wZXJhdGlvbl9hbmRfZGVwbG95bWVudF9hcmVfcmVxdWVzdGVkKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0Wydyb2xsb3V0X3ZlcmlmaWVkJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHdyaXRlcyksIDEpXG4gICAgICAgIG9wZXJhdGlvbiA9IHdyaXRlc1swXVstMV1bJ3ZhbHVlJ11cbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShvcGVyYXRpb25bJ3N5bmMnXVsncHJ1bmUnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChvcGVyYXRpb25bJ3N5bmMnXVsncmVzb3VyY2VzJ10sIFtcbiAgICAgICAgICAgIHsnZ3JvdXAnOiAnYXBwcycsICdraW5kJzogJ0RlcGxveW1lbnQnLCAnbmFtZSc6ICdpbmZvcm1lZC1kZWNpc2lvbicsICduYW1lc3BhY2UnOiAnaW5mb3JtZWQtZGVjaXNpb24nfV0pXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShhbnkoJy0tZHJ5LXJ1bj1zZXJ2ZXInIGluIGFyZ3YgYW5kIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdwYXRjaCddIGZvciBhcmd2IGluIGNhbGxzKSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXNbMF1bMF1bJ3BhdGgnXSwgJy9tZXRhZGF0YS91aWQnKVxuXG4gICAgZGVmIHRlc3Rfc291cmNlX292ZXJyaWRlc19hdXRvbWF0aW9uX2FuZF9jdXN0b2R5X2RyaWZ0X3N0b3BfYmVmb3JlX3dyaXRlKHNlbGYpOlxuICAgICAgICBtdXRhdGlvbnMgPSBbbGFtYmRhIG86IG9bJ2FwcGxpY2F0aW9uJ11bJ21ldGFkYXRhJ10udXBkYXRlKHVpZD0ncmVjcmVhdGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddLnVwZGF0ZShzeW5jUG9saWN5PXsnYXV0b21hdGVkJzoge319KSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydzcGVjJ11bJ3NvdXJjZSddLnVwZGF0ZShrdXN0b21pemU9eydpbWFnZXMnOiBbJ290aGVyJ119KSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydzcGVjJ10udXBkYXRlKHNvdXJjZXM9W3t9XSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snY29uZmlnbWFwJ11bJ21ldGFkYXRhJ10udXBkYXRlKHVpZD0ncmVjcmVhdGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1sncHZjJ11bJ3NwZWMnXS51cGRhdGUodm9sdW1lTmFtZT0ncmVwbGFjZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydkZXBsb3ltZW50J11bJ3N0YXR1cyddLnVwZGF0ZShyZWFkeVJlcGxpY2FzPTApXVxuICAgICAgICBmb3IgbXV0YXRlIGluIG11dGF0aW9uczpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KG11dGF0ZT1tdXRhdGUpOlxuICAgICAgICAgICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShvYmplY3RzKVxuICAgICAgICAgICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuXG4gICAgZGVmIHRlc3RfcHJlb3Blbl9zY2hlbWFfcmVmdXNhbF9wcmV2ZW50c19pbWFnZV9vcGVyYXRpb24oc2VsZik6XG4gICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZCwgc2NoZW1hX3JlZnVzZWQ9VHJ1ZSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuXG5cbiAgICBkZWYgdGVzdF9yb2xsYmFja191bnJlYWR5X2NhbmRpZGF0ZV9uZXZlcl9yZWFkc19wb2Rfb3JfZGF0YWJhc2Uoc2VsZik6XG4gICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICBwYXlsb2FkWydwaGFzZSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddLnVwZGF0ZShyZWFkeVJlcGxpY2FzPTAsIHVwZGF0ZWRSZXBsaWNhcz0wKVxuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSBhY3R1YXRvci5JTUFHRVxuICAgICAgICBvYmplY3RzWydhcHBsaWNhdGlvbiddWydzcGVjJ11bJ3NvdXJjZSddWyd0YXJnZXRSZXZpc2lvbiddID0gUkVWSVNJT05cbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIHNjaGVtYV9yZWZ1c2VkPVRydWUpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0Wydyb2xsb3V0X3ZlcmlmaWVkJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHdyaXRlcyksIDEpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UoYW55KGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdleGVjJ10gb3IgYXJndls6M10gPT0gWydrdWJlY3RsJywgJ2dldCcsICdwb2RzJ10gZm9yIGFyZ3YgaW4gY2FsbHMpKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHdyaXRlc1swXVstMV1bJ3ZhbHVlJ11bJ3N5bmMnXVsncmV2aXNpb24nXSwgJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYnKVxuXG4gICAgZGVmIHRlc3Rfcm9sbGJhY2tfc3RpbGxfcmVmdXNlc19jdXN0b2R5X29yX25vbnBhaXJfaW1hZ2VfZHJpZnQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdjbScsICdwdmMnLCAnaW1hZ2UnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpOlxuICAgICAgICAgICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKTtwYXlsb2FkWydwaGFzZSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICAgICAgICAgIG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3RhdHVzJ11bJ3JlYWR5UmVwbGljYXMnXSA9IDBcbiAgICAgICAgICAgICAgICBpZiBkZWZlY3QgPT0gJ2NtJzpvYmplY3RzWydjb25maWdtYXAnXVsnbWV0YWRhdGEnXVsndWlkJ10gPSAncmVjcmVhdGVkJ1xuICAgICAgICAgICAgICAgIGVsaWYgZGVmZWN0ID09ICdwdmMnOm9iamVjdHNbJ3B2YyddWydzcGVjJ11bJ3ZvbHVtZU5hbWUnXSA9ICdyZXBsYWNlZCdcbiAgICAgICAgICAgICAgICBlbHNlOm9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3BlYyddWyd0ZW1wbGF0ZSddWydzcGVjJ11bJ2NvbnRhaW5lcnMnXVswXVsnaW1hZ2UnXSA9ICdmb3JlaWduLWltYWdlJ1xuICAgICAgICAgICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pO3NlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuICAgIGRlZiB0ZXN0X3JlY292ZXJ5X3ZlcmlmaWNhdGlvbl9pc19zZXBhcmF0ZV9yZWFkeV9vbGRfaW1hZ2Vfc2NoZW1hX3Byb29mKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKCk7cGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjay12ZXJpZnknXG4gICAgICAgIG9iamVjdHNbJ2FwcGxpY2F0aW9uJ11bJ3N0YXR1cyddID0geydvcGVyYXRpb25TdGF0ZSc6IHsncGhhc2UnOiAnU3VjY2VlZGVkJywgJ29wZXJhdGlvbic6IHsnc3luYyc6IHtcbiAgICAgICAgICAgICdyZXZpc2lvbic6ICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJywgJ3BydW5lJzogRmFsc2UsXG4gICAgICAgICAgICAncmVzb3VyY2VzJzogW3snZ3JvdXAnOidhcHBzJywna2luZCc6J0RlcGxveW1lbnQnLCduYW1lJzonaW5mb3JtZWQtZGVjaXNpb24nLCduYW1lc3BhY2UnOidpbmZvcm1lZC1kZWNpc2lvbid9XX19fX1cbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSk7c2VsZi5hc3NlcnRUcnVlKHJlY2VpcHRbJ3JlY292ZXJ5X3ZlcmlmaWNhdGlvbiddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHdyaXRlcywgW10pXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShhbnkoYXJndls6Ml09PVsna3ViZWN0bCcsJ2V4ZWMnXSBmb3IgYXJndiBpbiBjYWxscykpXG4gICAgICAgIG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3RhdHVzJ11bJ3JlYWR5UmVwbGljYXMnXSA9IDBcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMscGF5bG9hZClcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcblxuICAgIGRlZiB0ZXN0X2FtYmlndW91c19wYXRjaF9pc19uZXZlcl9yZXRyaWVkKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIGFtYmlndW91cz1UcnVlKVxuICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuXG5cbmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6XG4gICAgdW5pdHRlc3QubWFpbigpXG4iCiAgICB9LAogICAgInZhbGlkYXRpb24uanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIyNmM1YWNmYTZlMmVmNTkwOWZmOWYzZmM4MTljYTE3NjNiNzlmM2NiNjViM2M0MzM3MWY3OTQ0YTI4NGNkZTI4IiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInRlc3RzXCI6IDE2LFxuICBcInJlc3VsdFwiOiBcInBhc3NlZFwiLFxuICBcInN5bnRoZXRpY190cmFuc3BvcnRfb25seVwiOiB0cnVlLFxuICBcInJlYWxfbmF0aXZlX2RhdGFfcmVhZFwiOiBmYWxzZSxcbiAgXCJuYXRpdmVfYmFja3VwX2V4cG9ydF9yZXN0b3JlX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICBcIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkXCI6IGZhbHNlLFxuICBcImFjdHVhbF9mb3VuZGVyX2FwcHJvdmFsXCI6IGZhbHNlLFxuICBcImxvY2FsX3JlYWRfb25seV9jYXBhYmlsaXR5X2NoZWNrc1wiOiBbXG4gICAgXCJhcmdvY2RDTEkgYWJzZW50LCBleGlzdGluZ0FwcGxpY2F0aW9uLm9wZXJhdGlvbiBwYXRoIHJldGFpbmVkXCIsXG4gICAgXCJEb2NrZXJ1bml4c29ja2V0IGVuZ2luZU5hbWUgYm50LWxhcDAwMVwiXG4gIF0sXG4gIFwiY2FzZV9zb3VyY2VfY29tbWl0X2F0X3ByZXBhcmF0aW9uXCI6IFwiZTAzNTliYyAob3duZXIgb3JpZ2luYWw3OHNvdXJjZTsgZmluYWwgaGVscGVyY29tbWl0IG11c3RiZSBleHBsaWNpdGx5cGlubmVkKVwiLFxuICBcImFkZGl0aW9uYWxfcmVncmVzc2lvbnNcIjogW1xuICAgIFwiUmVhZHkwIGNhbmRpZGF0ZSByb2xsYmFjayBkaXNwYXRjaCBoYXMgbm8gUG9kIG1ldGFkYXRhL0RCIGV4ZWMgYW5kIG9uZSBzY29wZWQgQ0FTIG9wZXJhdGlvblwiLFxuICAgIFwicm9sbGJhY2sgc3RpbGwgcmVmdXNlcyBDTS9QVkMgb3Igbm9ucGFpci1pbWFnZSBkcmlmdFwiLFxuICAgIFwic2VwYXJhdGUgb2xkLWltYWdlIFJlYWR5L3NjaGVtYTUgcmVjb3ZlcnkgcHJvb2ZcIixcbiAgICBcInBvc3QtYWRtaW4gcmVhZG9ubHkgaW50ZWdyaXR5IHJlZnVzYWwgYW5kIG9yaWdpbmFsIHNuYXBzaG90IHRhbXBlciByZWZ1c2FsXCJcbiAgXVxufVxuIgogICAgfQogIH0sCiAgIm5hdGl2ZV9leGVjdXRpb24iOiBmYWxzZQp9Cg==" + }, + { + "digest": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "media_type": "text/plain", + "content_base64": "IiIiUHJlLW9wZW4gc2NoZW1hL2ludGVncml0eS9jb3VudCBwcm9vZjsgc3RkbGliIG9ubHksIG5ldmVyIGNvbnN0cnVjdHMgU3RvcmUuIiIiCmltcG9ydCBhcmdwYXJzZQppbXBvcnQganNvbgpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaW1wb3J0IHNxbGl0ZTMKCgpkZWYgaW5zcGVjdF9yZWFkb25seShwYXRoKToKICAgIHBhdGggPSBQYXRoKHBhdGgpCiAgICBpZiBub3QgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZXhpc3Rpbmcgbm9uc3ltbGluayBwcml2YXRlIGRhdGFiYXNlIHJlcXVpcmVkJykKICAgIHdpdGggc3FsaXRlMy5jb25uZWN0KHBhdGgucmVzb2x2ZSgpLmFzX3VyaSgpICsgJz9tb2RlPXJvJywgdXJpPVRydWUsIHRpbWVvdXQ9NSkgYXMgZGI6CiAgICAgICAgZGIuZXhlY3V0ZSgnUFJBR01BIHF1ZXJ5X29ubHk9T04nKQogICAgICAgIGRiLmV4ZWN1dGUoJ0JFR0lOJykKICAgICAgICB2ZXJzaW9uID0gZGIuZXhlY3V0ZSgnUFJBR01BIHVzZXJfdmVyc2lvbicpLmZldGNob25lKClbMF0KICAgICAgICBpZiB2ZXJzaW9uICE9IDU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3ByZS1vcGVuIGRhdGFiYXNlIGlzIG5vdCBzY2hlbWE1OyByZWZ1c2UgbWlncmF0aW9uJykKICAgICAgICBpZiBkYi5leGVjdXRlKCdQUkFHTUEgaW50ZWdyaXR5X2NoZWNrJykuZmV0Y2hhbGwoKSAhPSBbKCdvaycsKV06CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3JlYWQtb25seSBpbnRlZ3JpdHkgY2hlY2sgcmVmdXNlZCcpCiAgICAgICAgbGlmZWN5Y2xlID0ge25hbWU6IGRiLmV4ZWN1dGUoJ1NFTEVDVCBDT1VOVCgqKSBGUk9NICcgKyB0YWJsZSkuZmV0Y2hvbmUoKVswXQogICAgICAgICAgICAgICAgICAgICBmb3IgbmFtZSwgdGFibGUgaW4gKCgncmVjb3JkcycsICdsaWZlY3ljbGVfcmVjb3JkcycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgnZXZlbnRzJywgJ2xpZmVjeWNsZV9ldmVudHMnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJ3BlbmRpbmcnLCAnbGlmZWN5Y2xlX3BlbmRpbmcnKSl9CiAgICAgICAgcmVzdWx0ID0geydzY2hlbWFfdmVyc2lvbic6IHZlcnNpb24sICdsaWZlY3ljbGUnOiBsaWZlY3ljbGUsCiAgICAgICAgICAgICAgICAgICdvdXRib3gnOiBkaWN0KGRiLmV4ZWN1dGUoJ1NFTEVDVCBzdGF0ZSxDT1VOVCgqKSBGUk9NIG91dGJveCBHUk9VUCBCWSBzdGF0ZScpKSwKICAgICAgICAgICAgICAgICAgJ3N1Ym1pc3Npb25zJzogZGljdChkYi5leGVjdXRlKCdTRUxFQ1Qgc3RhdGUsQ09VTlQoKikgRlJPTSBzdWJtaXNzaW9ucyBHUk9VUCBCWSBzdGF0ZScpKSwKICAgICAgICAgICAgICAgICAgJ2ludGVncml0eSc6ICdvaycsICdyZWFkX29ubHlfcHJlX29wZW4nOiBUcnVlLCAnc3RvcmVfY29uc3RydWN0ZWQnOiBGYWxzZX0KICAgICAgICBkYi5yb2xsYmFjaygpCiAgICByZXR1cm4gcmVzdWx0CgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHBhcnNlciA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPV9fZG9jX18pCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWRiJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKICAgIHRyeToKICAgICAgICBwcmludChqc29uLmR1bXBzKGluc3BlY3RfcmVhZG9ubHkoYXJncy5kYiksIHNvcnRfa2V5cz1UcnVlKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmFpc2UgU3lzdGVtRXhpdCgncmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgcmVmdXNlZDsgbm8gU3RvcmUvYWRtaW4gb3BlbicpIGZyb20gTm9uZQo=" + }, + { + "digest": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "media_type": "application/json", + "content_base64": "ewogICJjb25maWdtYXAiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJ2MSIsCiAgICAiaW1tdXRhYmxlIjogdHJ1ZSwKICAgICJraW5kIjogIkNvbmZpZ01hcCIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOi9Db25maWdNYXA6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiLAogICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICB9LAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIsCiAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAidWlkIjogIjkwMTEzZDJkLTU0ZDktNGU4Mi1iMWQzLTkwYjQ5ZWJlZDJiNSIKICAgIH0sCiAgICAiY2Fub25pY2FsX2RhdGFfc2hhMjU2IjogIjhlYzQ2MmQxMjM0NzU0OGY1MDZlZWViZjFlM2M3Y2M0NzY0ODAxOWM4YTc4MzgwNGQwOWJjYzc5YjBmMjJhZjYiCiAgfSwKICAicHZjIjogewogICAgImFwaVZlcnNpb24iOiAidjEiLAogICAgImtpbmQiOiAiUGVyc2lzdGVudFZvbHVtZUNsYWltIiwKICAgICJtZXRhZGF0YSI6IHsKICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICJhcmdvY2QuYXJnb3Byb2ouaW8vdHJhY2tpbmctaWQiOiAiaW5mb3JtZWQtZGVjaXNpb246L1BlcnNpc3RlbnRWb2x1bWVDbGFpbTppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIsCiAgICAgICAgInB2Lmt1YmVybmV0ZXMuaW8vYmluZC1jb21wbGV0ZWQiOiAieWVzIiwKICAgICAgICAicHYua3ViZXJuZXRlcy5pby9ib3VuZC1ieS1jb250cm9sbGVyIjogInllcyIsCiAgICAgICAgInZvbHVtZS5iZXRhLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiLAogICAgICAgICJ2b2x1bWUua3ViZXJuZXRlcy5pby9zZWxlY3RlZC1ub2RlIjogIjIzOS42Mi4yMDUuOTIuaG9zdC5zZWN1cmVzZXJ2ZXIubmV0IiwKICAgICAgICAidm9sdW1lLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiCiAgICAgIH0sCiAgICAgICJmaW5hbGl6ZXJzIjogWwogICAgICAgICJrdWJlcm5ldGVzLmlvL3B2Yy1wcm90ZWN0aW9uIgogICAgICBdLAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICJ1aWQiOiAiZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfSwKICAgICJzcGVjIjogewogICAgICAiYWNjZXNzTW9kZXMiOiBbCiAgICAgICAgIlJlYWRXcml0ZU9uY2UiCiAgICAgIF0sCiAgICAgICJyZXNvdXJjZXMiOiB7CiAgICAgICAgInJlcXVlc3RzIjogewogICAgICAgICAgInN0b3JhZ2UiOiAiMUdpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInN0b3JhZ2VDbGFzc05hbWUiOiAibG9jYWwtcGF0aCIsCiAgICAgICJ2b2x1bWVNb2RlIjogIkZpbGVzeXN0ZW0iLAogICAgICAidm9sdW1lTmFtZSI6ICJwdmMtZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfQogIH0sCiAgInB2Y19waGFzZSI6ICJCb3VuZCIKfQo=" + }, + { + "digest": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478", + "media_type": "text/markdown", + "content_base64": "IyBQcm90ZWN0ZWQgbmF0aXZlIGJhY2t1cC9yZXN0b3JlIGFuZCBpbWFnZS1vbmx5IHJlbGVhc2UgcHJvdG9jb2wKClByZXBhcmVkIHByb3RvY29sIGZvciBgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFgLiBObyBhY3R1YWwgbmF0aXZlIGJhY2t1cCwgZGF0YSBleHBvcnQsIHJlc3RvcmUsIHdvcmtsb2FkIGNoYW5nZSBvciBhcHByb3ZhbCBpcyByZWNvcmRlZCBoZXJlLiBDYW5kaWRhdGUgcmVnaXN0cnkgaW1hZ2UgaWRlbnRpdHkgcmVtYWlucyBhIHByZXJlcXVpc2l0ZTsgb25seSBhZnRlciBhY3R1YWwgYXJ0aWZhY3QgcHJvb2YgbWF5IHRoZSBmb3VuZGVyIGFwcHJvdmUgb25lIGV4YWN0IGNvbmRpdGlvbmFsIHByb3RvY29sL3JvbGxvdXQgcGFja2V0LiBUaGUgY29uZmlnLW9ubHk3ZGI4NDg1IGFwcHJvdmFsIGlzIG91dHNpZGUgdGhpcyBzY29wZS4KCiMjIFByZWNvbmRpdGlvbnMgYW5kIHByb3RlY3RlZCBjdXN0b2R5CgpGcmVlemUgZXhhY3QgY2FuZGlkYXRlIGFuZCBwcmlvcjdmNWM2Y2IgaW1hZ2UgZGlnZXN0cywgc291cmNlL2luc3RhbGxlZCBwb2xpY3kgaGFzaGVzLCBjdXJyZW50IG1hbnVhbGx5IG1hbmFnZWQgQXJnbyBBcHBsaWNhdGlvbi9yZXZpc2lvbiwgcnVudGltZSBDb25maWdNYXA2YzIyMTg3OGQwNTEsIERlcGxveW1lbnQgVUlEL3RlbXBsYXRlL3NwZWMsIHNjaGVtYTUsIHBvbGljeSBwYWNrYWdlIHBpbnMsIGRhdGFiYXNlIHBhdGggYC9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZWAsIFBWQyBiaW5kaW5nLCByZXBsaWNhczEvUmVjcmVhdGUgYW5kIHN0YWJsZSBrZXlzIGZvciBpbnRlbmRlZCB2ZXJpZmljYXRpb24uIENvbmZpcm0gbm8gY29uY3VycmVudCB3cml0ZXIgb3IgY3VzdG9keSBjaGFuZ2UuIFVzZSBmaXhlZCBtZXRhZGF0YTsgbmV2ZXIgZmV0Y2ggU2VjcmV0IG9iamVjdHMgb3IgdG9rZW4gdmFsdWVzLiBBIGNoYW5nZWQgaW1hZ2UvY29uZmlnL3NjaGVtYS9vd25lciBpbnZhbGlkYXRlcyB0aGUgcGFja2V0LiBGcmVzaCByZXNvdXJjZXMvaGVhZHJvb20gYW5kIGV4YWN0IHNvdXJjZS9uYXRpdmUgc2VydmVyLWRyeS1ydW4vZGlmZiByZW1haW4gcmVxdWlyZWQuCgpCYWNrdXBzIGFyZSBwcml2YXRlIGV2aWRlbmNlIGNvbnRhaW5pbmcgcmVhbCBkZWNpc2lvbiByZWNvcmRzLCBub3QgbG9ncyBvciBwYWNrZXQgYXR0YWNobWVudHMuIEFsbG9jYXRlIGEgdW5pcXVlIGJhY2t1cCBkaXJlY3RvcnkgdW5kZXIgZXhpc3RpbmcgcHJvdGVjdGVkIFBWQyBjdXN0b2R5LCBvd25lZDEwMDAxLCBtb2RlMDcwMCwgc25hcHNob3QgZmlsZTA2MDAsIG5vIHN5bWxpbmsvaGFyZGxpbmsvcmV1c2VkIG91dHB1dCBwYXRoLiBBbiBvZmYtY2x1c3RlciBjb3B5IGJlbG9uZ3Mgb25seSBpbiB0aGUgYWxyZWFkeSBlc3RhYmxpc2hlZCBpZ25vcmVkIGAucHJpdmF0ZS1iYWNrdXBzLzx1bmlxdWUtdHJpYWwtZGlyZWN0b3J5PmAgY3VzdG9keSB3aXRoMDcwMC8wNjAwIHBlcm1pc3Npb25zOyBubyBHaXQsIFN0YXRlSHViLCBwdWJsaWMgb2JqZWN0IHN0b3JlIG9yIHRlcm1pbmFsLWNvbnRlbnQgZHVtcC4gUmVjb3JkIG9ubHkgc2NoZW1hLCBpbnRlZ3JpdHkgcGFzcy9mYWlsLCBib3VuZGVkIHRhYmxlL3N0YXRlIGNvdW50cyBhbmQgcHJvdGVjdGVkIHJlY2VpcHQgaWRlbnRpZmllcjsgcmV0YWluIGJ5dGUgZGlnZXN0cyBpbiBwcm90ZWN0ZWQgY3VzdG9keSBpZiBuZWVkZWQgZm9yIGludGVybmFsIGNvcHkgaWRlbnRpdHkuIE5vIGNyZWRlbnRpYWwsIHJlY29yZCBwYXlsb2FkIG9yIHRva2VuIGZpbmdlcnByaW50IGVudGVycyBwdWJsaWMgZXZpZGVuY2UuCgojIyBBcHByb3ZlZCBvbmxpbmUgY29tcGF0aWJpbGl0eSBkcmlsbAoKV2l0aGluIHRoZSBleHBsaWNpdCBmb3VuZGVyLWFwcHJvdmVkIGFjdGlvbiwgcnVuIHRoZSBleGlzdGluZyBiYXNlIGltYWdlJ3MgYGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGJhY2t1cCAtLWRiIC9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZSAtLW91dHB1dCA8bmV3LXByaXZhdGUtc25hcHNob3Q+YCBpbiB0aGUgYWN0dWFsIHNlcnZpbmcgd29ya2xvYWQuIFRoaXMgdXNlcyBTUUxpdGUncyBiYWNrdXAgQVBJIGZvciBhIHRyYW5zYWN0aW9uYWxseSBjb25zaXN0ZW50IHNuYXBzaG90OyBjb3B5aW5nIGEgbGl2ZSBtYWluIGRhdGFiYXNlIHdoaWxlIGlnbm9yaW5nIFdBTCBpcyBwcm9oaWJpdGVkLiBTdXBwcmVzcyByYXcgZmFpbHVyZXMvb3V0cHV0IGFuZCByZXRhaW4gb25seSBzYW5pdGl6ZWQgc3RhdHVzLiBPYnNlcnZlIHNjaGVtYS9pbnRlZ3JpdHkgYW5kIGNvdW50LW9ubHkgbWV0YWRhdGEgZnJvbSB0aGUgcmVzdWx0aW5nIHNuYXBzaG90LCBub3QgcmVjb3JkIGNvbnRlbnQuCgpUcmFuc2ZlciB0aGF0IGNvbnNpc3RlbnQgc25hcHNob3Qgb25seSBpbnRvIHByb3RlY3RlZCBvZmYtY2x1c3RlciBjdXN0b2R5IHRocm91Z2ggdGhlIGV4aXN0aW5nIGF1dGhvcml6ZWQgb3BlcmF0b3IgbGFuZS4gVGhlIGNvcHkgaXMgcmVhbCBwcm9kdWN0aW9uIGRhdGEgZXZlbiBpbiBidWlsZCBtb2RlLiBWZXJpZnkgcHJpdmF0ZSBwZXJtaXNzaW9ucywgdW5pcXVlIGlkZW50aXR5IGFuZCBwcm90ZWN0ZWQgaW50ZXJuYWwgZGlnZXN0IGFncmVlbWVudC4gRG8gbm90IGV4cG9ydCBtb3VudGVkIHdvcmtsb2FkIGNyZWRlbnRpYWxzIG9yIGRpcmVjdG9yeSB0cmVlczsgY29weSBvbmx5IHRoZSBleGFjdCBzbmFwc2hvdC4KCkNyZWF0ZSBhIHNlcGFyYXRlIHByaXZhdGUgZGlzcG9zYWJsZSByZXN0b3JlIHZvbHVtZS9kaXJlY3Rvcnk7IHJldGFpbiB0aGUgb3JpZ2luYWwgc25hcHNob3QgdW5jaGFuZ2VkLiBSdW4gdGhlIGV4YWN0IHB1Ymxpc2hlZCBjYW5kaWRhdGUgd2l0aCBuZXR3b3JrIGRpc2FibGVkLCBubyBwcm9kdWN0aW9uIENvbmZpZ01hcC90b2tlbiBtb3VudHMsIHJlYWQtb25seSBpbWFnZSBhbmQgb25seSB0aGF0IGlzb2xhdGVkIHZvbHVtZSB3cml0YWJsZS4gT3ZlcnJpZGUgdGhlIHNlcnZpY2UgZW50cnlwb2ludCB3aXRoIHRoZSBvd25lcidzIGNvdW50LW9ubHkgYWRtaW5pc3RyYXRpdmUgaW5zcGVjdGlvbi9pbnRlZ3JpdHkgY2hlY2s7IGRvIG5vdCBzdGFydCBIVFRQIGxpc3RlbmVycywgYXVkaXQgZGVsaXZlcnksIHJlcXVlc3RlciBleGNoYW5nZXMgb3IgYXBwcm92YWwgb3BlcmF0aW9ucy4gVGhlIGN1cnJlbnQgY2FuZGlkYXRlIGNoYW5nZXMgcG9saWN5LnB5IG9ubHkgYW5kIHJldGFpbnMgdGhlIHNjaGVtYS9zdG9yZSBtb2R1bGUgYnl0ZXM7IHN0aWxsIHByb3ZlIHNjaGVtYTUsIFNRTGl0ZSBpbnRlZ3JpdHkgYW5kIGV4YWN0IGJvdW5kZWQgY291bnRzIGJlZm9yZS9hZnRlciBvcGVuaW5nIHRoZSByZXN0b3JlZCBjb3B5LiBSZWZ1c2UgYW55IG1pZ3JhdGlvbi9kb3duZ3JhZGUsIGxvc3QvY2hhbmdlZCBjb3VudHMsIHVuZXhwZWN0ZWQgd3JpdGUgY2xhc3Mgb3IgdW5rbm93biBvdXRjb21lLiBLZWVwIHBlbmRpbmcvdW5jZXJ0YWluIHN1Ym1pc3Npb24gYW5kIG91dGJveCBzdGF0ZXM7IG5ldmVyIHJlcGxheSwgZGlzY2FyZCBvciBtYXJrIHRoZW0gZGVsaXZlcmVkIHRvIGdyZWVuIHRoZSBkcmlsbC4gQ2xlYW51cCBvbmx5IHRoZSBkaXNwb3NhYmxlIGNvcHkvdm9sdW1lIGFmdGVyIHZlcmlmaWVkIHJlY2VpcHQ7IHJldGFpbiB0aGUgb3JpZ2luYWwgcHJvdGVjdGVkIGJhY2t1cCBmb3IgdGhlIGFwcHJvdmVkIHJlY292ZXJ5IGludGVydmFsLgoKVGhpcyBzdGVwIGlzIGFjdHVhbCBuYXRpdmUtZGF0YSBjb21wYXRpYmlsaXR5IGV2aWRlbmNlIG9uY2UgcGVyZm9ybWVkLiBJdHMgcHJldmlvdXMgc3ludGhldGljIGZpeHR1cmUgY2hlY2tzIHJlbWFpbiBtZWNoYW5pc20gZXZpZGVuY2UgYW5kIGNhbm5vdCBiZSByZW5hbWVkIG5hdGl2ZSBzdWNjZXNzLiBBIGZhaWxlZCBkcmlsbCBzdG9wcyByb2xsb3V0IGFuZCByZW1haW5zIGEgZmFpbGVkL3VudmVyaWZpZWQgb3V0Y29tZSBpbiB0aGUgc2FtZSB0cmlhbC4KCiMjIEZyZXNoIGN1dG92ZXIgc25hcHNob3QgYW5kIHNpbmdsZS13cml0ZXIgcm9sbG91dAoKQWZ0ZXIgc3VjY2Vzc2Z1bCBhY3R1YWwtZGF0YSBjb21wYXRpYmlsaXR5IGNoZWNrcywgY3JlYXRlIGFub3RoZXIgdW5pcXVlIFNRTGl0ZS1jb25zaXN0ZW50IG9ubGluZSBzbmFwc2hvdCBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGltYWdlIGN1dG92ZXIsIHJldGFpbmluZyBpdHMgcG9pbnQtaW4tdGltZSBzY2hlbWEvaW50ZWdyaXR5L2NvdW50IHJlY2VpcHQuIFRoaXMgaXMgYW4gb25saW5lIHRyYW5zYWN0aW9uYWwgc25hcHNob3QsIG5vdCBhIGNsYWltIHRoYXQgZGlzcGF0Y2hlcnMgb3IgaHVtYW4gd3JpdGVzIHdlcmUgcXVpZXNjZWQuIEV2ZXJ5IGxhdGVyIGNvbW1pdHRlZCByZWNvcmQgcmVtYWlucyBpbiB0aGUgbGl2ZSBkYXRhYmFzZTsgc2FtZS1zY2hlbWEgcm9sbGJhY2sgcmV0YWlucyB0aGF0IGRhdGFiYXNlIGFuZCBuZXZlciByZXN0b3JlcyB0aGUgZWFybGllciBzbmFwc2hvdCBvdmVyIGl0LiBUaGUgbmFycm93IGltYWdlLW9ubHkgdXBkYXRlIGRvZXMgbm90IG5lZWQgZGlzcGF0Y2hlci9jb25maWd1cmF0aW9uL1BWQy90ZW1wb3JhcnktcG9kIGNoYW5nZXMgb3IgYSBzY2hlbWEgY3V0b3Zlci4gSWYgZnJlc2ggdmVyaWZpY2F0aW9uIHNob3dzIGEgbWlncmF0aW9uIG9yIGFueSBkYXRhLXJlc3RvcmF0aW9uIHJlcXVpcmVtZW50LCBzdG9wIGFuZCByZWZpbmUgdGhlIHByb3Bvc2FsIHJhdGhlciB0aGFuIGFwcGx5aW5nIHRoaXMgcHJvdG9jb2wuCgpUaGUgZXhpc3RpbmcgUmVjcmVhdGUgcm9sbG91dCBkcmFpbnMvc3RvcHMgdGhlIHNpbmdsZSBvbGQgd3JpdGVyIGJlZm9yZSBzdGFydGluZyB0aGUgbmV3IGltYWdlIG9uIHRoZSBzYW1lIFBWQzsgdGhlIGluaGVyaXRlZCBzaW5nbGUtd3JpdGVyIGxvY2sgaW5kZXBlbmRlbnRseSByZWZ1c2VzIGNvbmN1cnJlbnQgc2VydmluZyBwcm9jZXNzZXMuIERvIG5vdCBhZGQgYW4gYWRtaW4gcG9kLCBzY2FsZS10by16ZXJvLCBkaXNwYXRjaGVyIHN0b3AsIG5ldHdvcmstcG9saWN5IHJld3JpdGUgb3Igc25hcHNob3Qgb3ZlcndyaXRlIGFzIGFuIGltcHJvdmlzZWQgaW1hZ2Utb25seSBzdGVwLiBUaGUgZXhpc3Rpbmcgb3duZXIgYWRtaW4gYmFja3VwIG9wZXJhdGlvbiBydW5zIGluc2lkZSB0aGUgYWRtaXR0ZWQgc2VydmluZyB3b3JrbG9hZCwgYW5kIGl0cyBzZXBhcmF0ZSBwcm90ZWN0ZWQgcmVzdG9yZSBkcmlsbCBydW5zIG9mZi1jbHVzdGVyIHdpdGggbmV0d29yayBkaXNhYmxlZCBhbmQgbm8gd29ya2xvYWQgY3JlZGVudGlhbHMuIFRob3NlIGV4YWN0IGN1c3RvZHkgb3BlcmF0aW9ucyBtdXN0IGJlIGVudW1lcmF0ZWQgaW4gdGhlIGZvdW5kZXIgcGFja2V0IGFsb25nc2lkZSB0aGUgb25lIERlcGxveW1lbnQgaW1hZ2UgY2hhbmdlLgoKT25jZSBiYWNrdXAvY29tcGF0aWJpbGl0eS9wcmVmbGlnaHQgZ2F0ZXMgcGFzcywgbWFudWFsbHkgcGluIHRoZSBleGlzdGluZyBBcmdvIEFwcGxpY2F0aW9uIHRvIHRoZSBleGFjdCByZXZpZXdlZCBzb3VyY2UgcmV2aXNpb24gYW5kIHN5bmMgb25seSBEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHdpdGggcHJ1bmUgZmFsc2UsIGtlZXBpbmcgdGhlIGN1cnJlbnQgaW1tdXRhYmxlIHJ1bnRpbWUgQ29uZmlnTWFwIGFuZCBhbGwgb3RoZXIgcmVzb3VyY2VzLiBUaGUgc291cmNlIHBhdGNoIGNoYW5nZXMgb25seSB0aGUgaW1hZ2UgaW4gYWRtaXNzaW9uL3JlbmRlcmVkIERlcGxveW1lbnQ7IG5vIFNlY3JldCwgUFZDLCBwb2xpY3ksIGRhdGFiYXNlIG9yIGRpc3BhdGNoZXIgY2hhbmdlIGlzIGluY2x1ZGVkIHVubGVzcyBzZXBhcmF0ZWx5IGVudW1lcmF0ZWQgaW4gdGhlIGZpbmFsIHByb3Bvc2FsLiBPYnNlcnZlIGZpdmUtbWludXRlIHJlYWRpbmVzcyBhbmQgZXhhY3QgaW1hZ2UvY29uZmlnL3NjaGVtYS9waW5zLiBSdW4gdGhlIHRlbiBpbnN0YWxsZWQgcHVycG9zZSB2YXJpYW50cyBvbiB0aGUgYWN0dWFsIG5hdGl2ZSBwbGFjZW1lbnQgdXNpbmcgc3ludGhldGljIHRyYW5zcG9ydDsgdGhleSBwcm92ZSBleGFjdCBpbnN0YWxsZWQgbW9kdWxlIHJlZnVzYWwgYmVoYXZpb3IgYW5kIGV4cGxpY2l0bHkgcmVwb3J0IG5hdGl2ZV9wcm92aWRlcj1mYWxzZS4gVGhleSBkbyBub3QgcHJvdmUgYW4gYWN0dWFsIHByb3ZpZGVyIHJlc3BvbnNlLCBQRFAgYXV0aG9yaXR5IG9yIG5hdGl2ZSBsaWZlY3ljbGUgYmluZGluZzsgYW55IHJlcXVpcmVkIGFjdHVhbC1wcm92aWRlciBwcm9vZiByZW1haW5zIGEgZGlzdGluY3QgVDA0IGNvbXBsZXRpb24gZ2F0ZSB3aXRoIHNlcGFyYXRlIGF1dGhvcml6ZWQgcHJlcGFyYXRpb24sIGFuZCBtdXN0IG5vdCBiZSBjbGFpbWVkIGJ5IHRoaXMgaGVscGVyLiBEbyBub3QgY29udGFtaW5hdGUgdGhlIGxpdmUgUERQLCBjcmVhdGUgaHVtYW4gYXBwcm92YWxzLCByZWFkIGNyZWRlbnRpYWxzIHRocm91Z2ggQ0xJLCBvciByZXBsYXkgdW5rbm93biBleHRlcm5hbCBvdXRjb21lcyBmb3IgdGVzdGluZy4KCiMjIFNhbWUtc2NoZW1hIHJvbGxiYWNrIGFuZCBldmlkZW5jZSByZXRlbnRpb24KCk9uIHN0YXJ0dXAvcmVhZGluZXNzL2JpbmRpbmcvcmVmdXNhbCBmYWlsdXJlLCByZXRhaW4gY3VycmVudCBkYXRhYmFzZSwgY3V0b3ZlciBiYWNrdXAgYW5kIGV2ZXJ5IHBvc3QtY3V0b3ZlciBldmlkZW5jZS91bmNlcnRhaW4gb3V0Y29tZS4gUmVzdG9yZSBvbmx5IHRoZSBwcmlvcjdmNWM2Y2IgaW1hZ2UgdGhyb3VnaCB0aGUgc2FtZSBtYW51YWwgQXJnbyBvd25lciBwYXRoLCByZXRhaW5pbmcgc2NoZW1hNSBhbmQgY3VycmVudCBEQi9jb25maWd1cmF0aW9uOyBuZXZlciByZXN0b3JlIGFuIG9sZCBzbmFwc2hvdCBvdmVyIGN1cnJlbnQgbGl2ZSBldmlkZW5jZSBqdXN0IHRvIHJvbGwgdGhlIGltYWdlIGJhY2suIFZlcmlmeSBvbGQgaW1hZ2UvUmVhZHkxLCBzYW1lIHNjaGVtYS9jb3VudHMgYW5kIHByaW9yIGJlaGF2aW9yLCBhbmQgcmVjb25jaWxlIGFueSBleHRlcm5hbCBlZmZlY3RzIHVzaW5nIGV4aXN0aW5nIGxpZmVjeWNsZS9hdWRpdCBvd25lcnNoaXAuIFRoZSBuYXJyb3cgb3ZlcmxheSdzIGlkZW50aWNhbCBzdG9yZS9zY2hlbWEvZGVwZW5kZW5jeSBieXRlcyBwZXJtaXQgdGhpcyBpbWFnZS1vbmx5IHJvbGxiYWNrOyBpdCBpcyBub3QgcGVybWlzc2lvbiBmb3IgYSBzY2hlbWEgZG93bmdyYWRlIG9yIGRhdGEgbG9zcy4KClJlY29yZCBvcmlnaW5hbC9hcHByb3ZlZC9leGVjdXRlZCBzb3VyY2UgYW5kIGltYWdlIHJldmlzaW9ucywgYmFja3VwL2RyaWxsL2N1dG92ZXIvcm9sbG91dCB0aW1lc3RhbXBzLCBleGFjdCBkaXNwb3NpdGlvbiBhbmQgc2FuaXRpemVkIG91dGNvbWVzIGluIHRoZSBleGlzdGluZyBzdXBlcnZpc2VkIHRyaWFsIHJlY2VpcHQuIEVVUjAgaW5jcmVtZW50YWwgaW5mcmFzdHJ1Y3R1cmUgZXN0aW1hdGUgdXNlcyBleGlzdGluZyBzZXJ2aWNlL3N0b3JhZ2Uvb3BlcmF0b3IgbGFuZTsgcHJvdGVjdGVkIHRlbXBvcmFyeSBjb3B5L3N0b3JhZ2UgY29uc3VtcHRpb24gYW5kMTXigJMzMG1pbnV0ZSByZWNvdmVyeSB0aW1lIHJlbWFpbiBvcGVyYXRpb25hbCBjb3N0cy4gTm8gRVVSIGluY2lkZW50LWxvc3MgY2FwIG9yIGF1dG9ub215IGdyYW50IGlzIGluZmVycmVkLiBUYXNrVDA0IGNhbm5vdCBjbG9zZSB1bnRpbCBhY3R1YWwgcHVibGlzaGVkIGltYWdlLCBhcHByb3ZlZCBuYXRpdmUgY29tcGF0aWJpbGl0eSBhbmQgcmVsZWFzZSBwbHVzIHBvc3QtcmVsZWFzZSByZWZ1c2FsL2JpbmRpbmcgZXZpZGVuY2UgYWxsIGV4aXN0LgoKIyMgRXhhY3QgcmVsZWFzZSBjYXNlIGlkZW50aWZpZXJzCgpQcm9wb3NhbCBgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFgLCB0cmlhbCBgaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxYC4KUHJvdGVjdGVkIG5hdGl2ZSBwYXJlbnQgYC9kYXRhL3ByaXZhdGUvcHVycG9zZS1vdmVybGF5LXIxYCBtdXN0IGJlIHVuaXF1ZS9ub24tc3ltbGluaywgb3duZWQxMDAwMSBhbmQwNzAwLiBUaGUgZHJpbGwgc25hcHNob3QgaXMgYGRyaWxsLnNxbGl0ZWAsIHRoZSByZWZyZXNoZWQgcHJlLWN1dG92ZXIgc25hcHNob3QgYGN1dG92ZXIuc3FsaXRlYCwgZWFjaCBuZXcwNjAwIGZpbGU7IHJlZnVzZSBhbnkgZXhpc3Rpbmcgb3V0cHV0LiBPZmYtY2x1c3RlciBjdXN0b2R5IGlzIHRoZSBleGlzdGluZyBpZ25vcmVkIEN1c3RvZGlhbiBgLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjFgIHBhcmVudDA3MDAsIGZpbGVzMDYwMDsgbm8gc25hcHNob3QgaXMgYW4gZXZpZGVuY2UgYXR0YWNobWVudC4gQ2hlY2sgb3duZXIgVUlELCBubyBzeW1saW5rcywgaWdub3JlZCBzdGF0dXMgYW5kIGZyZWUgY2FwYWNpdHkgZm9yIGJvdGggbmF0aXZlIHNuYXBzaG90cyBwbHVzIGluZGVwZW5kZW50bHkgcHJvdGVjdGVkIGNvcGllcyBiZWZvcmUgbWFraW5nIGFueSBzbmFwc2hvdC4KClRoZSBkaXNwb3NhYmxlIG9mZmxpbmUgcmVzdG9yZSB2b2x1bWUgaXMgYGluZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExYDsgcmVmdXNlIGFuIGV4aXN0aW5nIHZvbHVtZSwgY29weSBvbmx5IHRoZSBzZWxlY3RlZCBmcm96ZW4gc25hcHNob3QsIGFuZCBydW4gZXhhY3QgcHVibGlzaGVkIGNhbmRpZGF0ZTc2M2Mgd2l0aCBuZXR3b3Jrbm9uZS9yZWFkLW9ubHkgaW1hZ2UsMTI4TWlCL2NvcmUxIGFuZCBubyBydW50aW1lIGNvbmZpZy90b2tlbiBtb3VudHMuIFNRTGl0ZSBgUFJBR01BIGludGVncml0eV9jaGVja2AgbXVzdCByZXR1cm4gYG9rYCwgYFBSQUdNQSB1c2VyX3ZlcnNpb25gL1N0b3JlIGluc3BlY3Rpb24gbXVzdCBhZ3JlZSB3aXRoIGFjdHVhbCBzY2hlbWE1IHNlbWFudGljcywgYW5kIGluc3RhbGxlZCBhZG1pbiBjb3VudC1vbmx5IGluc3BlY3Rpb24gbXVzdCBtYXRjaCB0aGUgZnJvemVuIHNuYXBzaG90LiBWYWxpZGF0ZSB0aGUgYWN0dWFsIHNjaGVtYSByZXByZXNlbnRhdGlvbiByYXRoZXIgdGhhbiBhc3N1bWUgUFJBR01BIHVzZXJfdmVyc2lvbiBpcyB0aGUgc2NoZW1hIGF1dGhvcml0eS4gTm8gc3ludGhldGljIHJlc3RvcmF0aW9uIGlzIHJlcG9ydGVkIGFzIG5hdGl2ZSByZXN0b3JhdGlvbi4gTmF0aXZlIG9yaWdpbmFsL29mZi1jbHVzdGVyIGNvcGllcyByZW1haW4gcmV0YWluZWQ7IG9ubHkgdGhlIGRpc3Bvc2FibGUgcmVzdG9yZSBjb3B5L3ZvbHVtZSBtYXkgYmUgcmVtb3ZlZCB1bmRlciB0aGUgZXhhY3QgYXBwcm92ZWQgY2xlYW51cCBzY29wZS4KCiMjIE1hbmRhdG9yeSBwcmUtb3BlbiBzY2hlbWEgZ2F0ZSBhbmQgb2ZmbGluZSBjb21tYW5kCgpgaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4gaW5zcGVjdGAgYW5kIGBiYWNrdXBgIGNvbnN0cnVjdCBTdG9yZSwgd2hpY2ggY2FuIG1pZ3JhdGUgc2NoZW1hczHigJM0IHRvNS4gVGhlcmVmb3JlICoqYmVmb3JlIGFueSBTdG9yZS9hZG1pbiBvcGVuKiosIHJ1biB0aGUgZXhhY3QgYXR0YWNoZWQgc3RkbGliLW9ubHkgYHNxbGl0ZV9yZWFkb25seS5weWAgYWdhaW5zdCB0aGUgbmF0aXZlIHNvdXJjZSBkYXRhYmFzZSB1c2luZyBTUUxpdGUgVVJJIG1vZGU9cm8sIHF1ZXJ5X29ubHkgYW5kIG9uZSByZWFkIHRyYW5zYWN0aW9uLiBSZXF1aXJlIFBSQUdNQSB1c2VyX3ZlcnNpb241LCBpbnRlZ3JpdHlfY2hlY2s9b2sgYW5kIHJldGFpbiBjb3VudC1vbmx5IGJhc2VsaW5lLiBSZWZ1c2UgYW55IG90aGVyL3Vua25vd24gc2NoZW1hIG9yIGluY29tcGxldGUgaW50ZWdyaXR5L2NvdW50IGNoZWNrIGJlZm9yZSBjb25zdHJ1Y3RpbmcgU3RvcmU7IGRvIG5vdCBpbmZlciBubyBtaWdyYXRpb24gZnJvbSBhIHBvc3Qtb3BlbiBhZG1pbiByZXBvcnQuIFRoaXMgbmF0aXZlIGdhdGUgaGFzIG5vdCBiZWVuIGV4ZWN1dGVkIGluIHRoaXMgc291cmNlLXByZXBhcmF0aW9uIHN0YWdlLiBSZXBlYXQgYmVmb3JlIGVhY2ggbmF0aXZlIGJhY2t1cC9hZG1pbiBvcGVyYXRpb24uCgpBZnRlciBjb3B5aW5nIHRoZSBzZWxlY3RlZCBjb25zaXN0ZW50IHNuYXBzaG90IHRvIHRoZSBpc29sYXRlZCByZXN0b3JlZCBwcml2YXRlIHBhdGggYC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgLCBydW4gdGhlIHNhbWUgcmVhZC1vbmx5IGNoZWNrZXIgKipiZWZvcmUqKiBhbnkgb2ZmbGluZSBjYW5kaWRhdGUgYWRtaW4vU3RvcmUgb3BlbnMgdGhhdCBjb3B5LiBGcm96ZW4gc25hcHNob3QgYW5kIHJlc3RvcmVkLWNvcHkgc2NoZW1hL2ludGVncml0eS9jb3VudCByZXBvcnRzIG11c3QgYWdyZWUgZXhhY3RseTsgdGhlIGNvcGllZCBtYWluLWZpbGUgZGlnZXN0IG11c3QgbWF0Y2ggdGhlIHNlbGVjdGVkIGNsb3NlZCBzbmFwc2hvdC4gUmVqZWN0IG9sZHNjaGVtYSBmaXh0dXJlcyByYXRoZXIgdGhhbiBhbGxvdyBtaWdyYXRpb24uIE9ubHkgYWZ0ZXIgdGhpcyBwcmUtb3BlbiBnYXRlIG1heSB0aGUgb2ZmbGluZSBjYW5kaWRhdGUgYWRtaW4gaW5zcGVjdCBydW4uCgpPZmZsaW5lIGNvbW1hbmQgdmVjdG9ycyB1c2UgZXhhY3RpbWFnZSBgZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhYCwgYC0tbmV0d29yayBub25lIC0tcmVhZC1vbmx5IC0tY3B1cyAxIC0tbWVtb3J5IDEyOG1gLCBwcml2YXRlIHJlc3RvcmVkIHZvbHVtZSBtb3VudGVkIGF0IGAvcmVzdG9yZWAsIGFuZCAqKm5vIHJ1bnRpbWUgY29uZmlnL2NyZWRlbnRpYWwvdG9rZW4gbW91bnRzKiouIEZpcnN0IG92ZXJyaWRlIGVudHJ5cG9pbnQgdG8gYHB5dGhvbmAsIGFyZ3VtZW50cyBgLSAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgLCBzdHJlYW1pbmcgb25seSB0aGUgdmVyaWZpZWQgYXR0YWNoZWQgY2hlY2tlciBvbiBzdGRpbi4gVGhlbiBvdmVycmlkZSBlbnRyeXBvaW50IHRvICoqYGluZm9ybWVkLWRlY2lzaW9uLWFkbWluYCoqLCBhcmd1bWVudHMgKipgaW5zcGVjdCAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgKiouIFRoaXMgZG9lcyBub3Qgc3RhcnQgYGluZm9ybWVkLWRlY2lzaW9uLWNvbnRhaW5lcmAsIHRoZSBIVFRQIHNlcnZpY2UsIGRpc3BhdGNoZXIgb3IgZGVsaXZlcnkgd29ya2Vycy4gQ29tcGFyZSB0aGUgYWRtaW4ncyBzY2hlbWEvbGlmZWN5Y2xlL291dGJveC9zdWJtaXNzaW9uIGNvdW50ZXJzIHRvIHRoZSBmcm96ZW4gcHJlLW9wZW4gc25hcHNob3QgcmVwb3J0OyBpbnRlZ3JpdHkgYW5kIG1pZ3JhdGlvbi1mcmVlIHByZS1vcGVuIHByb29mIGNvbWUgZnJvbSB0aGUgc3RkbGliIGNoZWNrZXIsIG5vdCBhZG1pbiBvdXRwdXQgYWxvbmUuCgpMaXZlIHJlYWRzIGFuZCBvbmxpbmUgc25hcHNob3RzIG1heSBsZWdpdGltYXRlbHkgZGlmZmVyIGJlY2F1c2UgcmV2aWV3cywgaW50YWtlIGFuZCBkZWxpdmVyeSBjYW4gY29tbWl0IGNvbmN1cnJlbnRseS4gRXhhY3QgY291bnRlciBlcXVhbGl0eSBpcyByZXF1aXJlZCBiZXR3ZWVuIHRoZSBmcm96ZW4gc2VsZWN0ZWQgc25hcHNob3QgYW5kIGl0cyBvZmZsaW5lIHJlc3RvcmVkIGNsb25lOyBpdCBpcyAqKm5vdCoqIHJlcXVpcmVkIGJldHdlZW4gYSBydW5uaW5nIHBvc3QtY3V0b3Zlci9yb2xsYmFjayBkYXRhYmFzZSBhbmQgYW4gZWFybGllciBzbmFwc2hvdC4gTGl2ZSBjb3VudCBjaGFuZ2VzIG11c3QgYmUgYWNjb3VudGVkIGZvciBhcyBsZWdpdGltYXRlIGNvbW1pdHRlZCByZWNvcmRzL3N0YXRlIHRyYW5zaXRpb25zOyBwcmVzZXJ2ZSBhbGwgY3VycmVudCBhbmQgdW5jZXJ0YWluIGVudHJpZXMuIERvIG5vdCBkaXNjYXJkIG5ldyBjb21taXRzIG9yIHJlc3RvcmUgdGhlIG9sZCBzbmFwc2hvdCB0byBmb3JjZSBlcXVhbGl0eS4gU2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sga2VlcHMgdGhlIGN1cnJlbnQgbGl2ZSBEQiwgZm9sbG93ZWQgYnkgcmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5IGFuZCBjb3VudC1vbmx5IGhlYWx0aCBjaGVja3M7IGFueSB1bmV4cGxhaW5lZCBldmlkZW5jZSBsb3NzIG9yIHJlcXVpcmVkIGRhdGEgcmVjb3Zlcnkgc3RvcHMgYW5kIHJlcXVpcmVzIGEgc2VwYXJhdGUgZm91bmRlciBkZWNpc2lvbi4KClRoZSBmcmVzaCBwcmVmbGlnaHQgYWxzbyBpbmRlcGVuZGVudGx5IHJlYWRzIHRoZSBhY3R1YWwgaW1tdXRhYmxlIG5vbnNlY3JldCBDb25maWdNYXAgYW5kIGJvdW5kIFBWQzogY29tcGFyZXMgc2VhbGVkIFVJRHMvZnVsbG1ldGFkYXRhL1BWQ3NwZWMrdm9sdW1lTmFtZSBhbmQgY2Fub25pY2FsIHJ1bnRpbWUgZGF0YSBjaGVja3N1bSwgcmV0dXJuaW5nIG5vIHJhdyBydW50aW1lIGRhdGEuIFNhbWUtbmFtZSBkZWxldGlvbi9yZWNyZWF0aW9uIG9yIGNvbnRlbnQvY3VzdG9keSBkcmlmdCBzdG9wcyBiZWZvcmUgYWRtaXNzaW9uLiBTZWNyZXQgdmFsdWVzIHJlbWFpbiBleGNsdWRlZC4gQm90aCBsb2NhbCBhbmQgcmVtb3RlIG9wdGltaXplZCBQeXRob24gaW50ZXJwcmV0ZXJzIGFyZSBleHBsaWNpdGx5IHJlZnVzZWQgYmVmb3JlIGFzc2VydGlvbi1iYXNlZCBnYXRlcy4KCiMjIEV4YWN0IHN1cGVydmlzZWQgbWVjaGFuaWNhbCBleGVjdXRpb24gcmVmaW5lbWVudAoKVGhlIGRpcmVjdGx5IGF0dGFjaGVkIGBleGVjdXRpb24tYnVuZGxlLmpzb25gIGNvbnRhaW5zIHRoZSBleGFjdCBoZWxwZXIgc291cmNlLCBwbGFuLCB0ZXN0cyBhbmQgUEVORElORyByZWNlaXB0IHRlbXBsYXRlLiBJdCByZXBsYWNlcyB0aGUgZGlyZWN0IHJhdyBzY2FuIGF0dGFjaG1lbnQgd2l0aGluIHRoZSB0d2VudHktZG9jdW1lbnQgbGltaXQ7IGBwdWJsaXNoZWQtdmVyaWZpY2F0aW9uLmpzb25gIHN0aWxsIGJpbmRzIHRoZSB1bmNoYW5nZWQgYWN0dWFsIHVuZmlsdGVyZWQgcmF3IHNjYW4sIHJhdyBTQk9NIGFuZCBiYXNlIHNjYW4gU0hBMjU2IHZhbHVlcywgcmV0YWluZWQgaW4gdGhlIG93bmVyIGV2aWRlbmNlIHBhY2thZ2UuIFRoZSBrbm93biBpbmhlcml0ZWQgZml4YWJsZSBNRURJVU0gcmVtYWlucyBleHBsaWNpdCwgd2l0aCBvd25lciBUMDUvcmlzayBmb2xsb3ctdGhyb3VnaC4gTmVpdGhlciBhcmNoaXZlIG5vciB0ZWNobmljYWwgYWdyZWVtZW50IHN1cHBsaWVzIGh1bWFuIGFwcHJvdmFsLgoKVGhlIHJldmlld2VkIHByb3RvY29sIGJhc2lzIGlzIG93bmVyIGNvbW1pdCBlMDM1OWJjYjZjZGZhZDlhYjNlODY4MDU0MTIxZmUwY2ViZWMyZDY4LCB3aXRoIHNvdXJjZSBmb2xsb3ctdGhyb3VnaDkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUuIFRoZSBzdWJzZXF1ZW50IGV4YWN0IGFwcGxpZWQgaGVscGVyL3BhY2tldCBvd25lciBjb21taXQgbXVzdCBiZSBuYW1lZCBpbiB0aGUgZXh0ZXJuYWxseSB2ZXJpZmllZCBmb3VuZGVyIHJlY2VpcHQgYmVmb3JlIGV4ZWN1dGlvbi4gVmVyaWZ5IHRoZSBmb3VyIGNvbW1pdHRlZCBHaXQgYmxvYnMgKGFkbWlzc2lvbi5jYW5kaWRhdGUuanNvbiwgc2VydmljZS5jYW5kaWRhdGUuanNvbiwga3VzdG9taXphdGlvbi55YW1sLCByZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uKSBhZ2FpbnN0IGV4ZWN1dGlvbi1wbGFuLmpzb24gYXMgd2VsbCBhcyBjdXJyZW50IHdvcmt0cmVlL0hFQUQ7IHJlamVjdCBvdmVycmlkZXMvcGx1Z2lucy9tdWx0aXBsZSBBcHBsaWNhdGlvbiBzb3VyY2VzIGFuZCBhbnkgcHJlc2VudCBhdXRvbWF0ZWQgY29uZmlndXJhdGlvbiwgaW5jbHVkaW5nIGF1dG9tYXRlZDp7fS4KClJvb3QgZnJlc2hseSBhdXRoZW50aWNhdGVzIHRoZSBleGFjdCBjb25maXJtZWQgZm91bmRlciBwZXJzb24vcGxhdGZvcm0tcm9vdCBBQ0NFUFQgb2YgdGhpcyBzdGFibGUgbWVtby92ZXJzaW9uMSBhdCB0aGUgZml4ZWQgbmF0aXZlIEluZm9ybWVkIERlY2lzaW9uIG9yaWdpbiBiZWZvcmUgZWFjaCBwaGFzZSwgYW5kIHN1cHBsaWVzIHByb3RlY3RlZDA2MDAgcmVjZWlwdC9vdXRjb21lIGZpbGVzLiBUaGUgaGVscGVyIGNoZWNrcyB0aGVpciBleGFjdCByZWxhdGlvbiBhbmQgZnJlc2huZXNzMTIwc2Vjb25kczsgdGhlc2UgZmlsZXMgYXJlIHN1cGVydmlzZWQgYm9va2tlZXBpbmcsIG5vdCBzaWduZWQgYXV0aGVudGljYXRlZCBncmFudHMsIGEgaHVtYW4tcHJvdmlkZXIgaW1wbGVtZW50YXRpb24sIG9yIGF1dG9ub21vdXMgYWdlbnQgYXV0aG9yaXR5LiBEbyBub3QgZGVyaXZlIHRoZW0gZnJvbSB0ZWNobmljYWwgcmV2aWV3cyBvciBjYWxsZXIgYXNzZXJ0aW9ucy4KCkZpeGVkIG9yZGVyOiBkcmlsbC1iYWNrdXAg4oaSIGRyaWxsLWNvcHkg4oaSIG9mZmxpbmUtdmVyaWZ5IOKGkiBjbGVhbnVwLW9mZmxpbmUg4oaSIGN1dG92ZXItYmFja3VwIOKGkiBjdXRvdmVyLWNvcHkg4oaSIHJlbGVhc2Ug4oaSIHZlcmlmeS4gQSBzZXBhcmF0ZSByZWNvcmRlZCByZWxlYXNlIGF0dGVtcHQgcGVybWl0cyByb2xsYmFjayDihpIgcm9sbGJhY2stdmVyaWZ5LiBFdmVyeSBwaGFzZSBmc3luY3MgYW4gYXR0ZW1wdCBub25jZS9SVU5OSU5HIGpvdXJuYWwgYmVmb3JlIGVmZmVjdHMuIEZhaWx1cmUvaW50ZXJydXB0aW9uL2FtYmlndW91cyBhY3R1YXRpb24gc3RheXMgVU5DRVJUQUlOIGFuZCB0aGUgc2FtZSBwaGFzZSBjYW5ub3QgYmUgcmV0cmllZC4gTm8gaW1wcm92aXNlZCBhZGFwdGVyIG9yIHdob2xlLUFwcGxpY2F0aW9uIHN5bmMgaXMgcGVybWl0dGVkLgoKVGhlIE5FVyBub25jZS1sYWJlbGxlZCBsb2NhbCB2b2x1bWUgcmVxdWlyZXMgb25lIGV4cGxpY2l0IGlzb2xhdGVkIGluaXRpYWxpemVyIGFzIFVJRDA6MCB3aXRoIG9ubHkgQ0FQX0NIT1dOLCBleGFjdDc2M2MgaW1hZ2UsIC0tbmV0d29yayBub25lIC0tcmVhZC1vbmx5IC0tY3B1cyAxIC0tbWVtb3J5IDEyOG0gLS1jYXAtZHJvcCBBTEwgLS1jYXAtYWRkIENIT1dOIC0tc2VjdXJpdHktb3B0IG5vLW5ldy1wcml2aWxlZ2VzLiBJdHMgb25seSBtb3VudCBpcyB0aGF0IG5ldyBuYW1lZCB2b2x1bWUgYXQgL3Jlc3RvcmU7IG5vIGhvc3QgbW91bnQsIG5hdGl2ZSBQVkMsIHJ1bnRpbWUgY29uZmlnIG9yIHRva2VuIG1vdW50LiBQcm90ZWN0ZWQgc25hcHNob3Qgc3RkaW4gZ29lcyBvbmx5IHRvIGEgdW5pcXVlMDYwMCBtYWluIGZpbGUgd2l0aCBleGFjdCBkaWdlc3QsIGFuZCBkaXJlY3RvcnkvZmlsZSBjdXN0b2R5IGlzIHNldDA3MDAvMDYwMCBVSUQvR0lEMTAwMDEuIFRoZW4gYWxsIHByZS1vcGVuLCBhZG1pbiBhbmQgcG9zdC1hZG1pbiBjaGVja3MgcnVuIFVJRDEwMDAxOjEwMDAxLCBjYXBhYmlsaXRpZXMgZHJvcHBlZCwgbmV0d29ya25vbmUuIFRoZSBzZWNvbmQgc3RkbGliIHJlYWRvbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IHByb29mIGFmdGVyIGFkbWluIG11c3QgZXhhY3RseSBlcXVhbCB0aGUgZnJvemVuIHNuYXBzaG90IHByb29mOyBpbmRlcGVuZGVudGx5IHJlY2hlY2sgdGhlIHJldGFpbmVkIG9yaWdpbmFsIHByb3RlY3RlZCBzbmFwc2hvdCBTSEEuIE5vIHNlcnZpY2Ugc3RhcnR1cCBvY2N1cnMuCgpSb2xsYmFjayBkaXNwYXRjaCBtdXN0IGJlIGF2YWlsYWJsZSBpZiB0aGUgY2FuZGlkYXRlIGlzIHVucmVhZHkgb3IgY2Fubm90IHN0YXJ0OiBpdCBjaGVja3Mgc2VhbGVkIERlcGxveW1lbnQvQ00vUFZDIGN1c3RvZHksIG9ubHkgcHJpb3IvY2FuZGlkYXRlIHNvdXJjZS9pbWFnZSBwYWlyLCBub2RlIGhlYWx0aC9oZWFkcm9vbSBhbmQgZnJlc2ggb2xkLWltYWdlIHNlcnZlciBhZG1pc3Npb24gcGx1cyBBcHBsaWNhdGlvbiBVSUQvcmVzb3VyY2VWZXJzaW9uL3NvdXJjZSBDQVMsIHdpdGggbm8gZmFpbGluZyBjYW5kaWRhdGUgUG9kL2V4ZWMvZGF0YWJhc2UgcHJlcmVxdWlzaXRlLiBEaXNwYXRjaCBhY2tub3dsZWRnbWVudCBpcyBub3QgcmVjb3ZlcmVkIGhlYWx0aC4gYHJvbGxiYWNrLXZlcmlmeWAgc2VwYXJhdGVseSByZXF1aXJlcyBvbGQgaW1hZ2UgUmVhZHkxLCBzdWNjZWVkZWQgZXhhY3QgRGVwbG95bWVudC1vbmx5L3BydW5lPWZhbHNlIG9wZXJhdGlvbiBhbmQgcmVhZG9ubHkgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnQgcHJvb2Ygb2YgdGhlIGxhdGVzdCByZXRhaW5lZCBsaXZlIGRhdGFiYXNlLiBObyBzbmFwc2hvdCByZXBsYWNlcyB0aGUgY3VycmVudCBkYXRhYmFzZS4KCioqRGVhZGxpbmUgcmVmaW5lbWVudDoqKiBhbGwgcGhhc2VzLCBpbmNsdWRpbmcgcm9sbGJhY2sgYW5kIHZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUyMDI2LTEwLTEyVDIzOjU5OjU5Wi4gVGhlIGVhcmxpZXIgYW1lbmRlZCBwYWNrZXQgZGVzY3JpYmVkIHVuc3RhcnRlZC1yZWxlYXNlIGV4cGlyeTsgdGhpcyBleGFjdCBoZWxwZXIgYWxzbyBib3VuZHMgcmVjb3ZlcnkvdmVyaWZpY2F0aW9uLiBTdGFydCBlYXJseSBlbm91Z2ggdG8gY29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIGFueSByZWNvdmVyeSB3aXRoaW4gdGhlIHdpbmRvdy4gSWYgZXhoYXVzdGVkLCBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uIHJhdGhlciB0aGFuIHNpbGVudGx5IGV4dGVuZCBhIGdyYW50LiBUaGlzIG1heSBkZWxheSByZWNvdmVyeSBhbmQgaXMgYW4gZXhwbGljaXQgb3BlcmF0aW9uYWwgcmlzay4gTm8gdGltZXIvY29udHJvbGxlciBhdXRvbWF0aWNhbGx5IHJvbGxzIGJhY2sgb3IgY2hhbmdlcyBzZXJ2aWNlIGF0IGV4cGlyeS4K" + }, + { + "digest": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101", + "media_type": "application/json", + "content_base64": "ewogICJpZCI6ICJJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSIsCiAgImtpbmQiOiAib3duZXItdnVsbmVyYWJpbGl0eS1mb2xsb3ctdGhyb3VnaCIsCiAgIm93bmVyIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAidGFzayI6ICJJTkZELVdQLTAwMDktVDA1IiwKICAic3RhdHVzIjogIm9wZW4iLAogICJjcmVhdGVkIjogIjIwMjYtMTAtMTEiLAogICJyZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJmaW5kaW5nIjogIkNWRS0yMDI2LTg1MDkxIiwKICAic2Nhbm5lcl9zZXZlcml0eSI6ICJNRURJVU0iLAogICJlc3RhdGVfcmlza19ncmFkZSI6IG51bGwsCiAgImFmZmVjdGVkX3BhY2thZ2UiOiAiemxpYiIsCiAgImluc3RhbGxlZCI6ICIxLjMuMi1yMCIsCiAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAiYWN0dWFsX2N1cnJlbnRfYmFzZV9hbmRfY2FuZGlkYXRlX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgInNvdXJjZV9ldmlkZW5jZSI6ICJzZWN1cml0eS1zdW1tYXJ5Lmpzb24sIHRyaXZ5LWZ1bGwuanNvbiwgYmFzZS10cml2eS1mdWxsLmpzb24iLAogICJodW1hbl90ZW1wb3JhcnlfZGlzcG9zaXRpb24iOiAicGVuZGluZyIsCiAgImZvbGxvd190aHJvdWdoIjogIlByZXBhcmUgYSBzZXBhcmF0ZWx5IHNvdXJjZS1ib3VuZCBvZmZpY2lhbC1iYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCB0aHJvdWdoIG5vcm1hbCBvd25lciBDSSwgdmVyaWZ5IGZ1bGwgc2NhbiBhbmQgcnVudGltZSBjb21wYXRpYmlsaXR5LCBvYnRhaW4gZGlzdGluY3QgbmF0aXZlIHJlbGVhc2UgYXBwcm92YWwgYmVmb3JlIHVwZGF0aW5nIHRoaXMgd29ya2xvYWQiLAogICJtYW51YWxfcmV2aWV3X2V4cGlyeSI6ICJEdWUgZGF0ZSByZXF1aXJlcyBvd25lciByZXZpZXcvZXNjYWxhdGlvbiBpZiB1bnJlc29sdmVkOyBubyBhdXRvbWF0aWMgcm9sbGJhY2svY29udHJvbGxlciBpcyBpbnN0YWxsZWQiLAogICJjbG9zZV9jb25kaXRpb24iOiAiVmVyaWZpZWQgaW5zdGFsbGVkIG5hdGl2ZSBmaXhlZCBwYWNrYWdlIGFuZCBmdWxsIHVuZmlsdGVyZWQgcmVzY2FuOyBwcmVzZXJ2ZSBvcmlnaW5hbCBkZXRlY3Rpb24gYW5kIGFueSBodW1hbiBkaXNwb3NpdGlvbiIKfQo=" + }, + { + "digest": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "media_type": "application/json", + "content_base64": "ewogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjI1OjM4Ljc5MzU1NSswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibGl2ZV9yZWFkeV9yZXBsaWNhcyI6IDEsCiAgImFkbWl0dGVkX3VpZCI6ICJhNTg4ZTEwYS05MGQyLTQ4ODMtOTc1ZS02ZGQ4YjhmZWNhOTIiLAogICJzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWQiOiB0cnVlLAogICJhZG1pdHRlZF9zcGVjX2V4YWN0bHlfbGl2ZV9wbHVzX2ltYWdlIjogdHJ1ZSwKICAiY2xpZW50X2RpZmZfZXhpdCI6IDEsCiAgImNsaWVudF9kaWZmX3NoYTI1NiI6ICJhNGJjMDI0YThjZWM2NThmODM1Mjg1ZWQ1MTk2NGUyZTA4NGVkYmFmMTAzZDQ1YTQ4Yjg5YzA5NTBiY2QzZTdkIiwKICAibm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzIjogIihUb3RhbCBsaW1pdHMgbWF5IGJlIG92ZXIgMTAwIHBlcmNlbnQsIGkuZS4sIG92ZXJjb21taXR0ZWQuKVxuICBSZXNvdXJjZSAgICAgICAgICAgUmVxdWVzdHMgICAgICBMaW1pdHNcbiAgLS0tLS0tLS0gICAgICAgICAgIC0tLS0tLS0tICAgICAgLS0tLS0tXG4gIGNwdSAgICAgICAgICAgICAgICAzNDYwbSAoODYlKSAgIDM2MjAwbSAoOTA1JSlcbiAgbWVtb3J5ICAgICAgICAgICAgIDk0NzJNaSAoNTklKSAgMzI4OThNaSAoMjA1JSlcbiAgZXBoZW1lcmFsLXN0b3JhZ2UgIDAgKDAlKSAgICAgICAgMCAoMCUpXG4gIGh1Z2VwYWdlcy0xR2kgICAgICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMk1pICAgICAgMCAoMCUpICAgICAgICAwICgwJSkiLAogICJhbGxfY2hlY2tzX3Bhc3MiOiB0cnVlCn0K" + }, + { + "digest": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImFyZ29jZC5hcmdvcHJvai5pby90cmFja2luZy1pZCI6ICJpbmZvcm1lZC1kZWNpc2lvbjphcHBzL0RlcGxveW1lbnQ6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICJ1aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInJldmlzaW9uSGlzdG9yeUxpbWl0IjogMTAsCiAgICAic2VsZWN0b3IiOiB7CiAgICAgICJtYXRjaExhYmVscyI6IHsKICAgICAgICAiYXBwLmt1YmVybmV0ZXMuaW8vbmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIKICAgICAgfQogICAgfSwKICAgICJzdHJhdGVneSI6IHsKICAgICAgInR5cGUiOiAiUmVjcmVhdGUiCiAgICB9LAogICAgInRlbXBsYXRlIjogewogICAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiCiAgICAgICAgfSwKICAgICAgICAibGFiZWxzIjogewogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ICJyZXZpZXciLAogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgICAgfQogICAgICB9LAogICAgICAic3BlYyI6IHsKICAgICAgICAiYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbiI6IGZhbHNlLAogICAgICAgICJjb250YWluZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiZW52IjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIklORkRfS0VZQ0FQRV9JU1NVRVIiLAogICAgICAgICAgICAgICAgInZhbHVlIjogImh0dHBzOi8va2MuY291bG9tYi5zb2NpYWwiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0NPTlRBSU5FUl9DT05GSUciLAogICAgICAgICAgICAgICAgInZhbHVlIjogIi9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvbiIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICAgICAgICAgICAiaW1hZ2VQdWxsUG9saWN5IjogIklmTm90UHJlc2VudCIsCiAgICAgICAgICAgICJsaXZlbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICAgICAgICJwb3J0cyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODAsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJodHRwIiwKICAgICAgICAgICAgICAgICJwcm90b2NvbCI6ICJUQ1AiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIsCiAgICAgICAgICAgICAgICAicHJvdG9jb2wiOiAiVENQIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlYWRpbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVzb3VyY2VzIjogewogICAgICAgICAgICAgICJsaW1pdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjUwMG0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICIyNTZNaSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZXF1ZXN0cyI6IHsKICAgICAgICAgICAgICAgICJjcHUiOiAiNW0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICI2NE1pIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInNlY3VyaXR5Q29udGV4dCI6IHsKICAgICAgICAgICAgICAiYWxsb3dQcml2aWxlZ2VFc2NhbGF0aW9uIjogZmFsc2UsCiAgICAgICAgICAgICAgImNhcGFiaWxpdGllcyI6IHsKICAgICAgICAgICAgICAgICJkcm9wIjogWwogICAgICAgICAgICAgICAgICAiQUxMIgogICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInJlYWRPbmx5Um9vdEZpbGVzeXN0ZW0iOiB0cnVlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzdGFydHVwUHJvYmUiOiB7CiAgICAgICAgICAgICAgImZhaWx1cmVUaHJlc2hvbGQiOiAxMiwKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAidGVybWluYXRpb25NZXNzYWdlUGF0aCI6ICIvZGV2L3Rlcm1pbmF0aW9uLWxvZyIsCiAgICAgICAgICAgICJ0ZXJtaW5hdGlvbk1lc3NhZ2VQb2xpY3kiOiAiRmlsZSIsCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJkbnNQb2xpY3kiOiAiQ2x1c3RlckZpcnN0IiwKICAgICAgICAicmVzdGFydFBvbGljeSI6ICJBbHdheXMiLAogICAgICAgICJzY2hlZHVsZXJOYW1lIjogImRlZmF1bHQtc2NoZWR1bGVyIiwKICAgICAgICAic2VjdXJpdHlDb250ZXh0IjogewogICAgICAgICAgImZzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJmc0dyb3VwQ2hhbmdlUG9saWN5IjogIk9uUm9vdE1pc21hdGNoIiwKICAgICAgICAgICJydW5Bc0dyb3VwIjogMTAwMDEsCiAgICAgICAgICAicnVuQXNOb25Sb290IjogdHJ1ZSwKICAgICAgICAgICJydW5Bc1VzZXIiOiAxMDAwMSwKICAgICAgICAgICJzZWNjb21wUHJvZmlsZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiUnVudGltZURlZmF1bHQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic2VydmljZUFjY291bnQiOiAicmV2aWV3IiwKICAgICAgICAic2VydmljZUFjY291bnROYW1lIjogInJldmlldyIsCiAgICAgICAgInRlcm1pbmF0aW9uR3JhY2VQZXJpb2RTZWNvbmRzIjogNDUsCiAgICAgICAgInZvbHVtZXMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImRhdGEiLAogICAgICAgICAgICAicGVyc2lzdGVudFZvbHVtZUNsYWltIjogewogICAgICAgICAgICAgICJjbGFpbU5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tZGF0YSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImVtcHR5RGlyIjogewogICAgICAgICAgICAgICJtZWRpdW0iOiAiTWVtb3J5IiwKICAgICAgICAgICAgICAic2l6ZUxpbWl0IjogIjE2TWkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImNvbmZpZ3VyYXRpb24iCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJjYWxsZXIiLAogICAgICAgICAgICAicHJvamVjdGVkIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAic291cmNlcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgInNlcnZpY2VBY2NvdW50VG9rZW4iOiB7CiAgICAgICAgICAgICAgICAgICAgImF1ZGllbmNlIjogImZsZXgtYXV0aCIsCiAgICAgICAgICAgICAgICAgICAgImV4cGlyYXRpb25TZWNvbmRzIjogMzYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiYXVkaXQiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAidG9rZW4iLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJzZWNyZXROYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLWF1ZGl0IgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiA2MDAsCiAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAidG9rZW4iCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAia2V5IjogImNhLmNydCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXRoIjogImNhLmNydCIKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICJuYW1lIjogImt1YmUtcm9vdC1jYS5jcnQiCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjkyLAogICAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgInNlY3JldCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAia2V5IjogImNsaWVudC1zZWNyZXQiLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJjbGllbnQtc2VjcmV0IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm9wdGlvbmFsIjogZmFsc2UsCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy1yZXF1ZXN0ZXIiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0KICAgIH0KICB9Cn0K" + }, + { + "digest": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IGV4YWN0IERlcGxveW1lbnQgYW5kIGFkbWlzc2lvbiBib3VuZGFyaWVzOyBubyBtdXRhdGlvbiBhdXRob3JpdHkuIiIiCmltcG9ydCBjb3B5CmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCgpCQVNFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MycKQ0FORElEQVRFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYScKCgpkZWYgZGVwZW5kZW5jeV9wcm9qZWN0aW9uKGNvbmZpZ21hcCwgcHZjKToKICAgIGlmIChjb25maWdtYXAuZ2V0KCdraW5kJykgIT0gJ0NvbmZpZ01hcCcgb3IgY29uZmlnbWFwLmdldCgnaW1tdXRhYmxlJykgaXMgbm90IFRydWUKICAgICAgICAgICAgb3IgY29uZmlnbWFwWydtZXRhZGF0YSddWyduYW1lc3BhY2UnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24nCiAgICAgICAgICAgIG9yIGNvbmZpZ21hcFsnbWV0YWRhdGEnXVsnbmFtZSddICE9ICdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MScKICAgICAgICAgICAgb3Igc2V0KGNvbmZpZ21hcC5nZXQoJ2RhdGEnLCB7fSkpICE9IHsncnVudGltZS5qc29uJ30KICAgICAgICAgICAgb3IgY29uZmlnbWFwLmdldCgnYmluYXJ5RGF0YScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGltbXV0YWJsZSBydW50aW1lIGNvbmZpZyBpZGVudGl0eScpCiAgICBpZiAocHZjLmdldCgna2luZCcpICE9ICdQZXJzaXN0ZW50Vm9sdW1lQ2xhaW0nCiAgICAgICAgICAgIG9yIHB2Y1snbWV0YWRhdGEnXVsnbmFtZXNwYWNlJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJwogICAgICAgICAgICBvciBwdmNbJ21ldGFkYXRhJ11bJ25hbWUnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24tZGF0YScKICAgICAgICAgICAgb3IgcHZjLmdldCgnc3RhdHVzJywge30pLmdldCgncGhhc2UnKSAhPSAnQm91bmQnCiAgICAgICAgICAgIG9yIG5vdCBwdmMuZ2V0KCdzcGVjJywge30pLmdldCgndm9sdW1lTmFtZScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGJvdW5kIFBWQyBjdXN0b2R5JykKICAgIGNvbmZpZyA9IHByb2plY3Rpb24oY29uZmlnbWFwKQogICAgY29uZmlnLnBvcCgnZGF0YScpCiAgICBjb25maWdbJ2Nhbm9uaWNhbF9kYXRhX3NoYTI1NiddID0gaGFzaGxpYi5zaGEyNTYoanNvbi5kdW1wcygKICAgICAgICBjb25maWdtYXBbJ2RhdGEnXSwgc29ydF9rZXlzPVRydWUsIHNlcGFyYXRvcnM9KCcsJywgJzonKSkuZW5jb2RlKCkpLmhleGRpZ2VzdCgpCiAgICByZXR1cm4geydjb25maWdtYXAnOiBjb25maWcsICdwdmMnOiBwcm9qZWN0aW9uKHB2YyksICdwdmNfcGhhc2UnOiAnQm91bmQnfQoKCmRlZiBjaGVja19kZXBlbmRlbmNpZXMoY29uZmlnbWFwLCBwdmMsIHNlYWxlZCk6CiAgICBpZiBkZXBlbmRlbmN5X3Byb2plY3Rpb24oY29uZmlnbWFwLCBwdmMpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdydW50aW1lIGNvbmZpZyBvciBQVkMgaWRlbnRpdHkvY3VzdG9keSBjaGFuZ2VkJykKCgpkZWYgcHJvamVjdGlvbih2YWx1ZSk6CiAgICB2YWx1ZSA9IGNvcHkuZGVlcGNvcHkodmFsdWUpCiAgICB2YWx1ZS5wb3AoJ3N0YXR1cycsIE5vbmUpCiAgICBmb3Iga2V5IGluICgncmVzb3VyY2VWZXJzaW9uJywgJ2dlbmVyYXRpb24nLCAnY3JlYXRpb25UaW1lc3RhbXAnLCAnbWFuYWdlZEZpZWxkcycpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLnBvcChrZXksIE5vbmUpCiAgICBmb3Iga2V5IGluICgna3ViZWN0bC5rdWJlcm5ldGVzLmlvL2xhc3QtYXBwbGllZC1jb25maWd1cmF0aW9uJywgJ2RlcGxveW1lbnQua3ViZXJuZXRlcy5pby9yZXZpc2lvbicpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLmdldCgnYW5ub3RhdGlvbnMnLCB7fSkucG9wKGtleSwgTm9uZSkKICAgIHJldHVybiB2YWx1ZQoKCmRlZiBjaGVja19jdXJyZW50KGN1cnJlbnQsIHNlYWxlZCk6CiAgICBpZiBwcm9qZWN0aW9uKGN1cnJlbnQpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzZWFsZWQgbGl2ZSBVSUQgb3IgY29uZmlndXJhdGlvbiBjaGFuZ2VkJykKCgpkZWYgY2hlY2tfYWRtaXR0ZWQoYWRtaXR0ZWQsIHNlYWxlZCk6CiAgICBleHBlY3RlZCA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKQogICAgY29udGFpbmVycyA9IGV4cGVjdGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddCiAgICBpZiBsZW4oY29udGFpbmVycykgIT0gMSBvciBjb250YWluZXJzWzBdWyduYW1lJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJyBvciBjb250YWluZXJzWzBdWydpbWFnZSddICE9IEJBU0U6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigndW5leHBlY3RlZCBiYXNlbGluZSBjb250YWluZXIgaWRlbnRpdHknKQogICAgY29udGFpbmVyc1swXVsnaW1hZ2UnXSA9IENBTkRJREFURQogICAgaWYgcHJvamVjdGlvbihhZG1pdHRlZCkgIT0gZXhwZWN0ZWQ6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignYWRtaXNzaW9uIGNoYW5nZWQgY29uZmlndXJhdGlvbiBiZXlvbmQgdGhlIHNvbGUgaW1hZ2UgcGluJykKCgpkZWYgdHJhbnNwb3J0X3Jlc3VsdChleGl0X2NvZGUsIG91dHB1dCk6CiAgICBpbXBvcnQganNvbgogICAgdHJ5OgogICAgICAgIHZhbHVlID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6CiAgICAgICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdyZWFzb24nOiAnaW52YWxpZCB0cmFuc3BvcnQgcmVzdWx0J30KICAgIGlmIGV4aXRfY29kZSAhPSAwIG9yIG5vdCBpc2luc3RhbmNlKHZhbHVlLCBkaWN0KSBvciB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIG5vdCBUcnVlOgogICAgICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncmVhc29uJzogJ3JlYWQtb25seSBwcmVmbGlnaHQgcmVmdXNlZCd9CiAgICByZXR1cm4gdmFsdWUK" + }, + { + "digest": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IHJlZnJlc2g7IGV4YWN0IG9yaWdpbmFsIGNhcHR1cmUgcmVtYWlucyBpbW11dGFibGU7IG5ldmVyIGV4ZWN1dGUgY3V0b3Zlci4iIiIKaW1wb3J0IGFyZ3BhcnNlLGhhc2hsaWIsanNvbixzdWJwcm9jZXNzLHN5cwpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaWYgc3lzLmZsYWdzLm9wdGltaXplOgogcmFpc2UgU3lzdGVtRXhpdCgib3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQgYmVmb3JlIHNvdXJjZS90cmFuc3BvcnQgZXhlY3V0aW9uIikKUk9PVD1QYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50CnA9YXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKTtwLmFkZF9hcmd1bWVudCgnLS1yZWNlaXB0LW91dHB1dCcsdHlwZT1QYXRoLHJlcXVpcmVkPVRydWUpO3AuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yb290Jyx0eXBlPVBhdGgsZGVmYXVsdD1QYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24nKSk7YT1wLnBhcnNlX2FyZ3MoKQpvdXQ9YS5yZWNlaXB0X291dHB1dC5yZXNvbHZlKCkKaWYgbm90IGEucmVjZWlwdF9vdXRwdXQuaXNfYWJzb2x1dGUoKSBvciBvdXQ9PVJPT1Qgb3IgUk9PVCBpbiBvdXQucGFyZW50cyBvciBvdXQ9PWEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIG9yIGEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIGluIG91dC5wYXJlbnRzIG9yIG91dC5leGlzdHMoKToKIHJhaXNlIFN5c3RlbUV4aXQoJ3VuaXF1ZSBleGVjdXRpb24gcmVjZWlwdCBtdXN0IGJlIG91dHNpZGUgdGhlIHNlYWxlZCBwYWNrZXQnKQppbnB1dHM9anNvbi5sb2FkcygoUk9PVC8ncHJlZmxpZ2h0LWlucHV0cy5qc29uJykucmVhZF90ZXh0KCkpCmZvciByZWxhdGl2ZSxkaWdlc3QgaW4gaW5wdXRzWydwYWNrZXRfZmlsZXMnXS5pdGVtcygpOgogcGF0aD1ST09UL3JlbGF0aXZlCiBpZiBwYXRoLmlzX3N5bWxpbmsoKSBvciBoYXNobGliLnNoYTI1NihwYXRoLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCkhPWRpZ2VzdDpyYWlzZSBTeXN0ZW1FeGl0KCdzZWFsZWQgaGVscGVyL2lucHV0IGJ5dGVzIGNoYW5nZWQnKQpmb3IgcmVsYXRpdmUsZGlnZXN0IGluIGlucHV0c1snb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKToKIHBhdGg9YS5zb3VyY2Vfcm9vdC9yZWxhdGl2ZQogaWYgcGF0aC5pc19zeW1saW5rKCkgb3IgaGFzaGxpYi5zaGEyNTYocGF0aC5yZWFkX2J5dGVzKCkpLmhleGRpZ2VzdCgpIT1kaWdlc3Q6cmFpc2UgU3lzdGVtRXhpdCgnb3duZXIgc291cmNlIGJ5dGVzIGNoYW5nZWQnKQpmcm9tIGNoYW5nZV9ndWFyZCBpbXBvcnQgdHJhbnNwb3J0X3Jlc3VsdApwcm9ncmFtPSdpbXBvcnQgc3VicHJvY2Vzcyxqc29uLGhhc2hsaWIsZGF0ZXRpbWUsc3lzLGNvcHkscmVcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoIm9wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkIilcbmNhbmRpZGF0ZT1qc29uLmxvYWRzKENBTkRJREFURV9MSVRFUkFMKVxuc2VhbGVkX2RlcGVuZGVuY2llcz1qc29uLmxvYWRzKERFUEVOREVOQ0lFU19MSVRFUkFMKVxuc2VhbGVkX2Jhc2VsaW5lPWpzb24ubG9hZHMoU0VBTEVEX0xJVEVSQUwpXG5leGVjKEdVQVJEX0xJVEVSQUwpXG5kZWYgcnVuKGFyZ3MsZGF0YT1Ob25lKTpcbiBwPXN1YnByb2Nlc3MucnVuKGFyZ3MsaW5wdXQ9ZGF0YSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSlcbiBpZiBwLnJldHVybmNvZGU6IHJhaXNlIFZhbHVlRXJyb3IoXCdyZWFkLW9ubHkgY29tbWFuZCBmYWlsZWQ6IFwnK2FyZ3NbMV0rXCcgXCcrYXJnc1syXSlcbiByZXR1cm4gcC5zdGRvdXRcbmxpdmU9anNvbi5sb2FkcyhydW4oW1wna3ViZWN0bFwnLFwnZ2V0XCcsXCdkZXBsb3ltZW50XCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2luZm9ybWVkLWRlY2lzaW9uXCcsXCctb1wnLFwnanNvblwnXSkpXG5jbT1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2NvbmZpZ21hcFwnLFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcJyxcJy1uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW9cJyxcJ2pzb25cJ10pKVxucHZjPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwncHZjXCcsXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXCcsXCctblwnLFwnaW5mb3JtZWQtZGVjaXNpb25cJyxcJy1vXCcsXCdqc29uXCddKSlcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsc2VhbGVkX2RlcGVuZGVuY2llcylcbmNoZWNrX2N1cnJlbnQobGl2ZSxzZWFsZWRfYmFzZWxpbmUpXG5zcGVjPWxpdmVbXCdzcGVjXCddOyBjcz1zcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wnY29udGFpbmVyc1wnXTthc3NlcnQgbGVuKGNzKT09MSBhbmQgY3NbMF1bXCduYW1lXCddPT1cJ2luZm9ybWVkLWRlY2lzaW9uXCdcbmV4cGVjdGVkX2Vudj17XCdJTkZEX0tFWUNBUEVfSVNTVUVSXCc6XCdodHRwczovL2tjLmNvdWxvbWIuc29jaWFsXCcsXCdJTkZEX0NPTlRBSU5FUl9DT05GSUdcJzpcJy9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvblwnfVxuYXNzZXJ0IGNzWzBdLmdldChcJ2VudlwnKT09W3tcJ25hbWVcJzpcJ0lORkRfS0VZQ0FQRV9JU1NVRVJcJyxcJ3ZhbHVlXCc6ZXhwZWN0ZWRfZW52W1wnSU5GRF9LRVlDQVBFX0lTU1VFUlwnXX0se1wnbmFtZVwnOlwnSU5GRF9DT05UQUlORVJfQ09ORklHXCcsXCd2YWx1ZVwnOmV4cGVjdGVkX2VudltcJ0lORkRfQ09OVEFJTkVSX0NPTkZJR1wnXX1dXG5hc3NlcnQgY3NbMF1bXCdpbWFnZVwnXT09XCdmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcJ1xuYXNzZXJ0IHNwZWNbXCdyZXBsaWNhc1wnXT09MSBhbmQgc3BlY1tcJ3N0cmF0ZWd5XCddPT17XCd0eXBlXCc6XCdSZWNyZWF0ZVwnfVxuYXNzZXJ0IG5leHQodiBmb3IgdiBpbiBzcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wndm9sdW1lc1wnXSBpZiB2W1wnbmFtZVwnXT09XCdjb25maWd1cmF0aW9uXCcpW1wnY29uZmlnTWFwXCddW1wnbmFtZVwnXT09XCdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MVwnXG5hc3NlcnQgbGl2ZVtcJ3N0YXR1c1wnXS5nZXQoXCdyZWFkeVJlcGxpY2FzXCcpPT0xIGFuZCBsaXZlW1wnc3RhdHVzXCddLmdldChcJ3VwZGF0ZWRSZXBsaWNhc1wnKT09MVxuc2VhbGVkPXtcJ2FwaVZlcnNpb25cJzpsaXZlW1wnYXBpVmVyc2lvblwnXSxcJ2tpbmRcJzpsaXZlW1wna2luZFwnXSxcJ21ldGFkYXRhXCc6e2s6Y29weS5kZWVwY29weSh2KSBmb3Igayx2IGluIGxpdmVbXCdtZXRhZGF0YVwnXS5pdGVtcygpIGlmIGsgbm90IGluIChcJ3Jlc291cmNlVmVyc2lvblwnLFwnZ2VuZXJhdGlvblwnLFwnY3JlYXRpb25UaW1lc3RhbXBcJyxcJ21hbmFnZWRGaWVsZHNcJyl9LFwnc3BlY1wnOmNvcHkuZGVlcGNvcHkoc3BlYyl9XG5mb3Iga2V5IGluIChcJ2t1YmVjdGwua3ViZXJuZXRlcy5pby9sYXN0LWFwcGxpZWQtY29uZmlndXJhdGlvblwnLFwnZGVwbG95bWVudC5rdWJlcm5ldGVzLmlvL3JldmlzaW9uXCcpOnNlYWxlZFtcJ21ldGFkYXRhXCddLmdldChcJ2Fubm90YXRpb25zXCcse30pLnBvcChrZXksTm9uZSlcbmFkbWl0dGVkPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2FwcGx5XCcsXCctLWRyeS1ydW49c2VydmVyXCcsXCctZlwnLFwnLVwnLFwnLW9cJyxcJ2pzb25cJ10sanNvbi5kdW1wcyhjYW5kaWRhdGUpKSlcbmNoZWNrX2FkbWl0dGVkKGFkbWl0dGVkLHNlYWxlZF9iYXNlbGluZSlcbmFwcD1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2FwcGxpY2F0aW9uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2FyZ29jZFwnLFwnLW9cJyxcJ2pzb25cJ10pKVxuYXNzZXJ0IGFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCdwYXRoXCddPT1cJ2RlcGxveS9saWZlY3ljbGVcJyBhbmQgbm90IGFwcFtcJ3NwZWNcJ10uZ2V0KFwnc3luY1BvbGljeVwnLHt9KS5nZXQoXCdhdXRvbWF0ZWRcJylcbmFyZ289e1wndWlkXCc6YXBwW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdyZXBvVVJMXCc6YXBwW1wnc3BlY1wnXVtcJ3NvdXJjZVwnXVtcJ3JlcG9VUkxcJ10sXCd0YXJnZXRSZXZpc2lvblwnOmFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCd0YXJnZXRSZXZpc2lvblwnXSxcJ3BhdGhcJzphcHBbXCdzcGVjXCddW1wnc291cmNlXCddW1wncGF0aFwnXSxcJ2Rlc3RpbmF0aW9uXCc6YXBwW1wnc3BlY1wnXVtcJ2Rlc3RpbmF0aW9uXCddLFwnYXV0b21hdGVkXCc6RmFsc2UsXCdzeW5jXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdzeW5jXCcpLFwnaGVhbHRoXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdoZWFsdGhcJyl9XG5leHBlY3RlZF9hcmdvPWpzb24ubG9hZHMoQVJHT19MSVRFUkFMKVxuZm9yIGtleSBpbiAoXCd1aWRcJyxcJ3JlcG9VUkxcJyxcJ3RhcmdldFJldmlzaW9uXCcsXCdwYXRoXCcsXCdkZXN0aW5hdGlvblwnLFwnYXV0b21hdGVkXCcpOlxuIGFzc2VydCBhcmdvW2tleV09PWV4cGVjdGVkX2FyZ29ba2V5XVxuYXNzZXJ0IGFyZ29bXCdoZWFsdGhcJ11bXCdzdGF0dXNcJ109PVwnSGVhbHRoeVwnXG5kaWZmPXN1YnByb2Nlc3MucnVuKFtcJ2t1YmVjdGxcJyxcJ2RpZmZcJyxcJy1mXCcsXCctXCddLGlucHV0PWpzb24uZHVtcHMoY2FuZGlkYXRlKSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSk7YXNzZXJ0IGRpZmYucmV0dXJuY29kZSBpbiAoMCwxKVxuIyBEaWZmIGNhbiBjb250YWluIG9ubHkgbm9uc2VjcmV0IERlcGxveW1lbnQgcmVmZXJlbmNlczsgcHJlc2VydmUgZGlnZXN0IHJhdGhlciB0aGFuIHJhdyBzdGRvdXQuXG5ub2RlPXJ1bihbXCdrdWJlY3RsXCcsXCdkZXNjcmliZVwnLFwnbm9kZVwnXSk7YWxsb2NhdGVkPXJlLnNlYXJjaChyXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOi4qP0NQVSBSZXF1ZXN0c3xBbGxvY2F0ZWQgcmVzb3VyY2VzOlwnLG5vZGUscmUuUylcbnNlY3Rpb249bm9kZS5zcGxpdChcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcpWzFdLnNwbGl0KFwnRXZlbnRzOlwnKVswXSBpZiBcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcgaW4gbm9kZSBlbHNlIFwnXCdcbm5vZGVzPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwnbm9kZXNcJyxcJy1vXCcsXCdqc29uXCddKSlbXCdpdGVtc1wnXTthc3NlcnQgbGVuKG5vZGVzKT09MVxuYWxsb2M9bm9kZXNbMF1bXCdzdGF0dXNcJ11bXCdhbGxvY2F0YWJsZVwnXTtjcHU9YWxsb2NbXCdjcHVcJ107Y3B1X209aW50KGNwdVs6LTFdKSBpZiBjcHUuZW5kc3dpdGgoXCdtXCcpIGVsc2UgaW50KGNwdSkqMTAwMFxucmVxdWVzdGVkPWludChyZS5zZWFyY2goclwnY3B1XFxzKyhcXGQrKW1cJyxzZWN0aW9uKS5ncm91cCgxKSk7YXNzZXJ0IHJlcXVlc3RlZDw9Y3B1X21cbnJlY2VpcHQ9e1wnbm9kZV9hbGxvY2F0YWJsZV9jcHVfbVwnOmNwdV9tLFwnbm9kZV9yZXF1ZXN0ZWRfY3B1X21cJzpyZXF1ZXN0ZWQsXCdjYXB0dXJlZF9hdFwnOmRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpLmlzb2Zvcm1hdCgpLFwnbmF0aXZlX3dvcmtsb2FkX2NoYW5nZWRcJzpGYWxzZSxcJ25hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZFwnOkZhbHNlLFwnYXJnb1wnOmFyZ28sXCduYXRpdmVfZGVwZW5kZW5jaWVzX2NoZWNrZWRcJzpUcnVlLFwnY29uZmlnbWFwX3VpZFwnOmNtW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdwdmNfdWlkXCc6cHZjW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdsaXZlX3JlYWR5X3JlcGxpY2FzXCc6MSxcJ2FkbWl0dGVkX3VpZFwnOmFkbWl0dGVkW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWRcJzpUcnVlLFwnYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZVwnOlRydWUsXCdjbGllbnRfZGlmZl9leGl0XCc6ZGlmZi5yZXR1cm5jb2RlLFwnY2xpZW50X2RpZmZfc2hhMjU2XCc6aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpLFwnbm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzXCc6c2VjdGlvbi5zdHJpcCgpLFwnYWxsX2NoZWNrc19wYXNzXCc6VHJ1ZX1cbnByaW50KGpzb24uZHVtcHMocmVjZWlwdCkpXG4nCmZvciBtYXJrZXIsdmFsdWUgaW4gWygnREVQRU5ERU5DSUVTX0xJVEVSQUwnLChST09ULydzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLCgnQ0FORElEQVRFX0xJVEVSQUwnLChST09ULydjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLCgnU0VBTEVEX0xJVEVSQUwnLChST09ULydzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksKCdHVUFSRF9MSVRFUkFMJywoUk9PVC8nY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpLCgnQVJHT19MSVRFUkFMJyxqc29uLmR1bXBzKGpzb24ubG9hZHMoKFJPT1QvJ25hdGl2ZS1wcmVmbGlnaHQuanNvbicpLnJlYWRfdGV4dCgpKVsnYXJnbyddKSldOgogcHJvZ3JhbT1wcm9ncmFtLnJlcGxhY2UobWFya2VyLHJlcHIodmFsdWUpKQpwcm9ncmFtPSdpbXBvcnQgdHJhY2ViYWNrLGpzb25cbnRyeTpcbicrJycuam9pbignICAgICcrbGluZSsnXG4nIGZvciBsaW5lIGluIHByb2dyYW0uc3BsaXRsaW5lcygpKSsiZXhjZXB0IEV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICBwcmludChqc29uLmR1bXBzKHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZSwnZXhjZXB0aW9uX3R5cGUnOnR5cGUoZXJyb3IpLl9fbmFtZV9fLCdleGNlcHRpb25fbGluZSc6dHJhY2ViYWNrLmV4dHJhY3RfdGIoZXJyb3IuX190cmFjZWJhY2tfXylbLTFdLmxpbmVub30pKVxuIgpyPXN1YnByb2Nlc3MucnVuKFsnc3NoJywncmFpbGlhbmNlMDEnLCdweXRob24zIC0nXSxpbnB1dD1wcm9ncmFtLHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlKQpyZXN1bHQ9dHJhbnNwb3J0X3Jlc3VsdChyLnJldHVybmNvZGUsci5zdGRvdXQpO3Jlc3VsdFsnc2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2J109aGFzaGxpYi5zaGEyNTYoKFJPT1QvJ3ByZWZsaWdodC1pbnB1dHMuanNvbicpLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCk7cmVzdWx0WydmcmVzaF9leGVjdXRpb25fcmVjZWlwdCddPVRydWUKb3V0LndyaXRlX3RleHQoanNvbi5kdW1wcyhyZXN1bHQsaW5kZW50PTIpKydcbicpO3ByaW50KGpzb24uZHVtcHMocmVzdWx0LGluZGVudD0yKSk7c3lzLmV4aXQoMCBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgMSkK" + }, + { + "digest": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "media_type": "application/json", + "content_base64": "ewogICJwYWNrZXRfZmlsZXMiOiB7CiAgICAiY2hhbmdlX2d1YXJkLnB5IjogImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmUiLAogICAgInByZWZsaWdodC5weSI6ICI2YjRjNjVmNzA4MjM4YzlhOWQxN2ZkMDY1ODc2YzdhMDBlMWYxNzQ1OTI2Zjk5MGExZGQ1ZTY2NzI5ODM0MGNkIiwKICAgICJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uIjogIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGUiLAogICAgInJvbGxiYWNrLWRlcGxveW1lbnQuanNvbiI6ICIzOWIzZjQzYmI4NGVmNDkyMWNjM2ExZmJjZGM0NDQ2MTA3NDFlZDg4MDkxNDlkOGY4ZjE3ZWQ4MDVmMjYyMTIxIiwKICAgICJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24iOiAiZDE4ZDI3MDYzZDA2ZjUzNWFlODg0ZWEwMWY5Njc0N2ZlMzAxNjg1NTE4YWI5NGIxY2JhMDcyYTFlMTUxOTM2MiIsCiAgICAibmF0aXZlLXByZWZsaWdodC5qc29uIjogImViNWY0MWFlZmI5NzY2NmJiMGMxMjc5NjE3ZTk1YTdjMDUwMTdhNjA5NDE1NjI0ZGFlZTcyNGM0OGI5MGQyNjIiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAic3FsaXRlX3JlYWRvbmx5LnB5IjogImVlZjUzZGQyMzNlZWU3NGMxN2YyMDgyM2JkN2Y1Nzg3YzYwY2FkNzlhYzY0ODAyMWM5NDc5NjQzYzZjZTllMzgiCiAgfSwKICAib3duZXJfc291cmNlX2ZpbGVzIjogewogICAgImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uIjogIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTUiLAogICAgImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbiI6ICIzOGI3OGI5Y2JlZTVhZGU3NzUwYTU4ZDUxNTZjYTRjNTc3MzM1MmU5NDdhY2IzMDRlZTcxNGI1OWU3NDljZWI0IgogIH0KfQo=" + }, + { + "digest": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7", + "media_type": "application/json", + "content_base64": "ewogICJub2RlX2FsbG9jYXRhYmxlX2NwdV9tIjogNDAwMCwKICAibm9kZV9yZXF1ZXN0ZWRfY3B1X20iOiAzNDYwLAogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjM5OjE0LjIzNDI3NyswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibmF0aXZlX2RlcGVuZGVuY2llc19jaGVja2VkIjogdHJ1ZSwKICAiY29uZmlnbWFwX3VpZCI6ICI5MDExM2QyZC01NGQ5LTRlODItYjFkMy05MGI0OWViZWQyYjUiLAogICJwdmNfdWlkIjogImQ4MGIyNWIxLTE0MWEtNDQxYi1iMjA1LTk4ZmEyZmQ5OGI3YyIsCiAgImxpdmVfcmVhZHlfcmVwbGljYXMiOiAxLAogICJhZG1pdHRlZF91aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIiwKICAic2VydmVyX2RyeV9ydW5fcGFzc2VkIjogdHJ1ZSwKICAiYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZSI6IHRydWUsCiAgImNsaWVudF9kaWZmX2V4aXQiOiAxLAogICJjbGllbnRfZGlmZl9zaGEyNTYiOiAiODQwNzY5YzdkMmE5YzE2NTVjNDBhMzI1OWY4MzNkMWZjOGY2OTk1MGNlYjNiZWRiNzA3YTk1NWZlZDcxMTU2NiIsCiAgIm5vZGVfYWxsb2NhdGVkX3Jlc291cmNlcyI6ICIoVG90YWwgbGltaXRzIG1heSBiZSBvdmVyIDEwMCBwZXJjZW50LCBpLmUuLCBvdmVyY29tbWl0dGVkLilcbiAgUmVzb3VyY2UgICAgICAgICAgIFJlcXVlc3RzICAgICAgTGltaXRzXG4gIC0tLS0tLS0tICAgICAgICAgICAtLS0tLS0tLSAgICAgIC0tLS0tLVxuICBjcHUgICAgICAgICAgICAgICAgMzQ2MG0gKDg2JSkgICAzNjIwMG0gKDkwNSUpXG4gIG1lbW9yeSAgICAgICAgICAgICA5NDcyTWkgKDU5JSkgIDMyODk4TWkgKDIwNSUpXG4gIGVwaGVtZXJhbC1zdG9yYWdlICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMUdpICAgICAgMCAoMCUpICAgICAgICAwICgwJSlcbiAgaHVnZXBhZ2VzLTJNaSAgICAgIDAgKDAlKSAgICAgICAgMCAoMCUpIiwKICAiYWxsX2NoZWNrc19wYXNzIjogdHJ1ZSwKICAic2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2IjogIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDYiLAogICJmcmVzaF9leGVjdXRpb25fcmVjZWlwdCI6IHRydWUKfQo=" + } + ] + }, + "publish": { + "version": 1, + "audience": { + "subjects": [], + "groups": [ + "net-kingdom-admins" + ] + } + }, + "review": { + "version": 1, + "options": { + "submitter": "state-hub", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + } + } + } + } +] diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json new file mode 100644 index 0000000..f83c393 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/memo.json @@ -0,0 +1,141 @@ +{ + "id": "infd-20261011-purpose-overlay-r1", + "version": 1, + "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md new file mode 100644 index 0000000..e9374f6 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-backup-restore-protocol.md @@ -0,0 +1,68 @@ +# Protected native backup/restore and image-only release protocol + +Prepared protocol for `INFD-WP-0009-T04/purpose-overlay-v1`. No actual native backup, data export, restore, workload change or approval is recorded here. Candidate registry image identity remains a prerequisite; only after actual artifact proof may the founder approve one exact conditional protocol/rollout packet. The config-only7db8485 approval is outside this scope. + +## Preconditions and protected custody + +Freeze exact candidate and prior7f5c6cb image digests, source/installed policy hashes, current manually managed Argo Application/revision, runtime ConfigMap6c221878d051, Deployment UID/template/spec, schema5, policy package pins, database path `/data/private/review.sqlite`, PVC binding, replicas1/Recreate and stable keys for intended verification. Confirm no concurrent writer or custody change. Use fixed metadata; never fetch Secret objects or token values. A changed image/config/schema/owner invalidates the packet. Fresh resources/headroom and exact source/native server-dry-run/diff remain required. + +Backups are private evidence containing real decision records, not logs or packet attachments. Allocate a unique backup directory under existing protected PVC custody, owned10001, mode0700, snapshot file0600, no symlink/hardlink/reused output path. An off-cluster copy belongs only in the already established ignored `.private-backups/` custody with0700/0600 permissions; no Git, StateHub, public object store or terminal-content dump. Record only schema, integrity pass/fail, bounded table/state counts and protected receipt identifier; retain byte digests in protected custody if needed for internal copy identity. No credential, record payload or token fingerprint enters public evidence. + +## Approved online compatibility drill + +Within the explicit founder-approved action, run the existing base image's `informed-decision-admin backup --db /data/private/review.sqlite --output ` in the actual serving workload. This uses SQLite's backup API for a transactionally consistent snapshot; copying a live main database while ignoring WAL is prohibited. Suppress raw failures/output and retain only sanitized status. Observe schema/integrity and count-only metadata from the resulting snapshot, not record content. + +Transfer that consistent snapshot only into protected off-cluster custody through the existing authorized operator lane. The copy is real production data even in build mode. Verify private permissions, unique identity and protected internal digest agreement. Do not export mounted workload credentials or directory trees; copy only the exact snapshot. + +Create a separate private disposable restore volume/directory; retain the original snapshot unchanged. Run the exact published candidate with network disabled, no production ConfigMap/token mounts, read-only image and only that isolated volume writable. Override the service entrypoint with the owner's count-only administrative inspection/integrity check; do not start HTTP listeners, audit delivery, requester exchanges or approval operations. The current candidate changes policy.py only and retains the schema/store module bytes; still prove schema5, SQLite integrity and exact bounded counts before/after opening the restored copy. Refuse any migration/downgrade, lost/changed counts, unexpected write class or unknown outcome. Keep pending/uncertain submission and outbox states; never replay, discard or mark them delivered to green the drill. Cleanup only the disposable copy/volume after verified receipt; retain the original protected backup for the approved recovery interval. + +This step is actual native-data compatibility evidence once performed. Its previous synthetic fixture checks remain mechanism evidence and cannot be renamed native success. A failed drill stops rollout and remains a failed/unverified outcome in the same trial. + +## Fresh cutover snapshot and single-writer rollout + +After successful actual-data compatibility checks, create another unique SQLite-consistent online snapshot immediately before the image cutover, retaining its point-in-time schema/integrity/count receipt. This is an online transactional snapshot, not a claim that dispatchers or human writes were quiesced. Every later committed record remains in the live database; same-schema rollback retains that database and never restores the earlier snapshot over it. The narrow image-only update does not need dispatcher/configuration/PVC/temporary-pod changes or a schema cutover. If fresh verification shows a migration or any data-restoration requirement, stop and refine the proposal rather than applying this protocol. + +The existing Recreate rollout drains/stops the single old writer before starting the new image on the same PVC; the inherited single-writer lock independently refuses concurrent serving processes. Do not add an admin pod, scale-to-zero, dispatcher stop, network-policy rewrite or snapshot overwrite as an improvised image-only step. The existing owner admin backup operation runs inside the admitted serving workload, and its separate protected restore drill runs off-cluster with network disabled and no workload credentials. Those exact custody operations must be enumerated in the founder packet alongside the one Deployment image change. + +Once backup/compatibility/preflight gates pass, manually pin the existing Argo Application to the exact reviewed source revision and sync only Deployment/informed-decision with prune false, keeping the current immutable runtime ConfigMap and all other resources. The source patch changes only the image in admission/rendered Deployment; no Secret, PVC, policy, database or dispatcher change is included unless separately enumerated in the final proposal. Observe five-minute readiness and exact image/config/schema/pins. Run the ten installed purpose variants on the actual native placement using synthetic transport; they prove exact installed module refusal behavior and explicitly report native_provider=false. They do not prove an actual provider response, PDP authority or native lifecycle binding; any required actual-provider proof remains a distinct T04 completion gate with separate authorized preparation, and must not be claimed by this helper. Do not contaminate the live PDP, create human approvals, read credentials through CLI, or replay unknown external outcomes for testing. + +## Same-schema rollback and evidence retention + +On startup/readiness/binding/refusal failure, retain current database, cutover backup and every post-cutover evidence/uncertain outcome. Restore only the prior7f5c6cb image through the same manual Argo owner path, retaining schema5 and current DB/configuration; never restore an old snapshot over current live evidence just to roll the image back. Verify old image/Ready1, same schema/counts and prior behavior, and reconcile any external effects using existing lifecycle/audit ownership. The narrow overlay's identical store/schema/dependency bytes permit this image-only rollback; it is not permission for a schema downgrade or data loss. + +Record original/approved/executed source and image revisions, backup/drill/cutover/rollout timestamps, exact disposition and sanitized outcomes in the existing supervised trial receipt. EUR0 incremental infrastructure estimate uses existing service/storage/operator lane; protected temporary copy/storage consumption and15–30minute recovery time remain operational costs. No EUR incident-loss cap or autonomy grant is inferred. TaskT04 cannot close until actual published image, approved native compatibility and release plus post-release refusal/binding evidence all exist. + +## Exact release case identifiers + +Proposal `INFD-WP-0009-T04/purpose-overlay-v1`, trial `infd-purpose-20261011-r1`. +Protected native parent `/data/private/purpose-overlay-r1` must be unique/non-symlink, owned10001 and0700. The drill snapshot is `drill.sqlite`, the refreshed pre-cutover snapshot `cutover.sqlite`, each new0600 file; refuse any existing output. Off-cluster custody is the existing ignored Custodian `.private-backups/20261011-infd-purpose-r1` parent0700, files0600; no snapshot is an evidence attachment. Check owner UID, no symlinks, ignored status and free capacity for both native snapshots plus independently protected copies before making any snapshot. + +The disposable offline restore volume is `infd-purpose-r1-restore-20261011`; refuse an existing volume, copy only the selected frozen snapshot, and run exact published candidate763c with networknone/read-only image,128MiB/core1 and no runtime config/token mounts. SQLite `PRAGMA integrity_check` must return `ok`, `PRAGMA user_version`/Store inspection must agree with actual schema5 semantics, and installed admin count-only inspection must match the frozen snapshot. Validate the actual schema representation rather than assume PRAGMA user_version is the schema authority. No synthetic restoration is reported as native restoration. Native original/off-cluster copies remain retained; only the disposable restore copy/volume may be removed under the exact approved cleanup scope. + +## Mandatory pre-open schema gate and offline command + +`informed-decision-admin inspect` and `backup` construct Store, which can migrate schemas1–4 to5. Therefore **before any Store/admin open**, run the exact attached stdlib-only `sqlite_readonly.py` against the native source database using SQLite URI mode=ro, query_only and one read transaction. Require PRAGMA user_version5, integrity_check=ok and retain count-only baseline. Refuse any other/unknown schema or incomplete integrity/count check before constructing Store; do not infer no migration from a post-open admin report. This native gate has not been executed in this source-preparation stage. Repeat before each native backup/admin operation. + +After copying the selected consistent snapshot to the isolated restored private path `/restore/review.sqlite`, run the same read-only checker **before** any offline candidate admin/Store opens that copy. Frozen snapshot and restored-copy schema/integrity/count reports must agree exactly; the copied main-file digest must match the selected closed snapshot. Reject oldschema fixtures rather than allow migration. Only after this pre-open gate may the offline candidate admin inspect run. + +Offline command vectors use exactimage `forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a`, `--network none --read-only --cpus 1 --memory 128m`, private restored volume mounted at `/restore`, and **no runtime config/credential/token mounts**. First override entrypoint to `python`, arguments `- --db /restore/review.sqlite`, streaming only the verified attached checker on stdin. Then override entrypoint to **`informed-decision-admin`**, arguments **`inspect --db /restore/review.sqlite`**. This does not start `informed-decision-container`, the HTTP service, dispatcher or delivery workers. Compare the admin's schema/lifecycle/outbox/submission counters to the frozen pre-open snapshot report; integrity and migration-free pre-open proof come from the stdlib checker, not admin output alone. + +Live reads and online snapshots may legitimately differ because reviews, intake and delivery can commit concurrently. Exact counter equality is required between the frozen selected snapshot and its offline restored clone; it is **not** required between a running post-cutover/rollback database and an earlier snapshot. Live count changes must be accounted for as legitimate committed records/state transitions; preserve all current and uncertain entries. Do not discard new commits or restore the old snapshot to force equality. Same-schema image rollback keeps the current live DB, followed by read-only schema5/integrity and count-only health checks; any unexplained evidence loss or required data recovery stops and requires a separate founder decision. + +The fresh preflight also independently reads the actual immutable nonsecret ConfigMap and bound PVC: compares sealed UIDs/fullmetadata/PVCspec+volumeName and canonical runtime data checksum, returning no raw runtime data. Same-name deletion/recreation or content/custody drift stops before admission. Secret values remain excluded. Both local and remote optimized Python interpreters are explicitly refused before assertion-based gates. + +## Exact supervised mechanical execution refinement + +The directly attached `execution-bundle.json` contains the exact helper source, plan, tests and PENDING receipt template. It replaces the direct raw scan attachment within the twenty-document limit; `published-verification.json` still binds the unchanged actual unfiltered raw scan, raw SBOM and base scan SHA256 values, retained in the owner evidence package. The known inherited fixable MEDIUM remains explicit, with owner T05/risk follow-through. Neither archive nor technical agreement supplies human approval. + +The reviewed protocol basis is owner commit e0359bcb6cdfad9ab3e868054121fe0cebec2d68, with source follow-through9268c9ac0bbee508fe35c0b90dcefef4c24da2f5. The subsequent exact applied helper/packet owner commit must be named in the externally verified founder receipt before execution. Verify the four committed Git blobs (admission.candidate.json, service.candidate.json, kustomization.yaml, registries.candidate.json) against execution-plan.json as well as current worktree/HEAD; reject overrides/plugins/multiple Application sources and any present automated configuration, including automated:{}. + +Root freshly authenticates the exact confirmed founder person/platform-root ACCEPT of this stable memo/version1 at the fixed native Informed Decision origin before each phase, and supplies protected0600 receipt/outcome files. The helper checks their exact relation and freshness120seconds; these files are supervised bookkeeping, not signed authenticated grants, a human-provider implementation, or autonomous agent authority. Do not derive them from technical reviews or caller assertions. + +Fixed order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. A separate recorded release attempt permits rollback → rollback-verify. Every phase fsyncs an attempt nonce/RUNNING journal before effects. Failure/interruption/ambiguous actuation stays UNCERTAIN and the same phase cannot be retried. No improvised adapter or whole-Application sync is permitted. + +The NEW nonce-labelled local volume requires one explicit isolated initializer as UID0:0 with only CAP_CHOWN, exact763c image, --network none --read-only --cpus 1 --memory 128m --cap-drop ALL --cap-add CHOWN --security-opt no-new-privileges. Its only mount is that new named volume at /restore; no host mount, native PVC, runtime config or token mount. Protected snapshot stdin goes only to a unique0600 main file with exact digest, and directory/file custody is set0700/0600 UID/GID10001. Then all pre-open, admin and post-admin checks run UID10001:10001, capabilities dropped, networknone. The second stdlib readonly schema5/integrity/count proof after admin must exactly equal the frozen snapshot proof; independently recheck the retained original protected snapshot SHA. No service startup occurs. + +Rollback dispatch must be available if the candidate is unready or cannot start: it checks sealed Deployment/CM/PVC custody, only prior/candidate source/image pair, node health/headroom and fresh old-image server admission plus Application UID/resourceVersion/source CAS, with no failing candidate Pod/exec/database prerequisite. Dispatch acknowledgment is not recovered health. `rollback-verify` separately requires old image Ready1, succeeded exact Deployment-only/prune=false operation and readonly schema5/integrity/count proof of the latest retained live database. No snapshot replaces the current database. + +**Deadline refinement:** all phases, including rollback and verification, must begin before2026-10-12T23:59:59Z. The earlier amended packet described unstarted-release expiry; this exact helper also bounds recovery/verification. Start early enough to complete the bounded drill and any recovery within the window. If exhausted, stop and obtain a fresh founder decision rather than silently extend a grant. This may delay recovery and is an explicit operational risk. No timer/controller automatically rolls back or changes service at expiry. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json new file mode 100644 index 0000000..10603b4 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/native-preflight.json @@ -0,0 +1,43 @@ +{ + "captured_at": "2026-10-11T01:25:38.793555+00:00", + "native_workload_changed": false, + "native_backup_restore_executed": false, + "argo": { + "uid": "499868f2-eabc-4df4-ae31-b89ce58d750d", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "path": "deploy/lifecycle", + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "automated": false, + "sync": { + "comparedTo": { + "destination": { + "namespace": "informed-decision", + "server": "https://kubernetes.default.svc" + }, + "source": { + "path": "deploy/lifecycle", + "repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git", + "targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf" + } + }, + "revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "status": "OutOfSync" + }, + "health": { + "lastTransitionTime": "2026-10-10T23:14:52Z", + "status": "Healthy" + } + }, + "live_ready_replicas": 1, + "admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92", + "server_dry_run_passed": true, + "admitted_spec_exactly_live_plus_image": true, + "client_diff_exit": 1, + "client_diff_sha256": "a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d", + "node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)", + "all_checks_pass": true +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json new file mode 100644 index 0000000..8fd7728 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/original-source-manifest.json @@ -0,0 +1,786 @@ +[ + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/README.md", + "original_sha256": "ca2c34727a462c63f017700f703324d934f5fa3adc858c2756d62096b119c40c", + "staged_sha256": "c866ca0d026e25612f5c8404a7668ea7142d19065c93d33dec996f5821e53af1" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/combined-source-boundary-validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/combined-source-boundary-validation.json", + "original_sha256": null, + "staged_sha256": "877f93485c1a6817bdfde257051f202d33e14f0ee54e03e597043c8924723337" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "original_sha256": "23da78cf998a32af0481e68567db94bb40781cc18f147461f779d40ebd329fd1", + "staged_sha256": "a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/README.md", + "original_sha256": null, + "staged_sha256": "a6ecdabebce12eeafea61173edb6e6d0e349a76e366546978e2ed02e7b109df2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py", + "original_sha256": null, + "staged_sha256": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py", + "original_sha256": null, + "staged_sha256": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json", + "original_sha256": null, + "staged_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py", + "original_sha256": null, + "staged_sha256": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json", + "original_sha256": null, + "staged_sha256": "ef370a491468df28683f3002cb6e8bbb7e47b65e8e4d02ff4d09e9c39f020c8a" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/receipt_safety.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/receipt_safety.py", + "original_sha256": null, + "staged_sha256": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json", + "original_sha256": null, + "staged_sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py", + "original_sha256": null, + "staged_sha256": "9ccf6d421bf20f0e8350f6713d6d1cee2ba199f485dcaf2558c387421d9a2b48" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/validation.json", + "original_sha256": null, + "staged_sha256": "26c5acfa6e2ef5909ff9f3fc819ca1763b79f3cb65b3c43371f7944a284cde28" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json", + "original_sha256": null, + "staged_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/README.md", + "original_sha256": null, + "staged_sha256": "91d7b3c36498629bb4632b2a45cd75b67bf3a8ce8ab924d6a754a67410fadf6f" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/actuator.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/actuator.py", + "original_sha256": null, + "staged_sha256": "faf019cd011dee1032d3f309e85b1f1b0bf5f333d6e279701c3f7e233d54fe23" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/authority_journal.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/authority_journal.py", + "original_sha256": null, + "staged_sha256": "55e441b1af7288540c31ea4733c3471559a2100a26fae8b6b0ed415e04d469a5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/execution-plan.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/execution-plan.json", + "original_sha256": null, + "staged_sha256": "4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/native_program.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/native_program.py", + "original_sha256": null, + "staged_sha256": "3ad4fe28d0556a001f6334f3f8267d1e21d76e17db9765d3cc35b679a9db9ec5" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/packet-refinement.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/packet-refinement.json", + "original_sha256": null, + "staged_sha256": "003f08e4ff4abe96478f1db9d5b13e4a49a16cdc724090ba0d40a9f7e8440624" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/receipt_safety.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/receipt_safety.py", + "original_sha256": null, + "staged_sha256": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/root-authority-receipt-template.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/root-authority-receipt-template.json", + "original_sha256": null, + "staged_sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/test_execution.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/test_execution.py", + "original_sha256": null, + "staged_sha256": "d4f20fba850f0303a87971d2498bccc894ab39b7584ce98756e1c536e517fb18" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution/validation.json", + "original_sha256": null, + "staged_sha256": "abefda88f48ae455205cf6c27033fa81f99e89baea9ffffb8c26749a53815a39" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution-bundle.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/execution-bundle.json", + "original_sha256": null, + "staged_sha256": "0a79eda40fe0954fd3828bf06fd6ccf149e294ac194bc6fe605e585b878fa8d3" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/original-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-history/initial-653b68c3/original-manifest.json", + "original_sha256": null, + "staged_sha256": "653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/archive-map.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/archive-map.json", + "original_sha256": null, + "staged_sha256": "7b3ddb4cf2b459676f744bc8312ced37be76356f9acbdbe5e7e92c2b137e7b62" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/original-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/original-manifest.json", + "original_sha256": null, + "staged_sha256": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/service.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/deploy/lifecycle/service.candidate.json", + "original_sha256": null, + "staged_sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "original_sha256": null, + "staged_sha256": "ca2c34727a462c63f017700f703324d934f5fa3adc858c2756d62096b119c40c" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "original_sha256": null, + "staged_sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "original_sha256": null, + "staged_sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "original_sha256": null, + "staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "original_sha256": null, + "staged_sha256": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "original_sha256": null, + "staged_sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "original_sha256": null, + "staged_sha256": "23da78cf998a32af0481e68567db94bb40781cc18f147461f779d40ebd329fd1" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "original_sha256": null, + "staged_sha256": "2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "original_sha256": null, + "staged_sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "original_sha256": null, + "staged_sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "original_sha256": null, + "staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json", + "original_sha256": null, + "staged_sha256": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json", + "original_sha256": null, + "staged_sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md", + "original_sha256": null, + "staged_sha256": "f88a79a93fff34a1b438e2dc0344cad88d6c7960dde04bc7f3c04ac1fbb992c7" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json", + "original_sha256": null, + "staged_sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json", + "original_sha256": null, + "staged_sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json", + "original_sha256": null, + "staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json", + "original_sha256": null, + "staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py", + "original_sha256": null, + "staged_sha256": "830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py", + "original_sha256": null, + "staged_sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md", + "original_sha256": null, + "staged_sha256": "7f6d8987f65dff479eeead67b7ca940ef44c22c1cdbdd6ca33fd732b824c8f02" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json", + "original_sha256": null, + "staged_sha256": "aa1d494e42491f0619f731a836c597df9178409887d734c166a8df81f8807a27" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json", + "original_sha256": null, + "staged_sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json", + "original_sha256": null, + "staged_sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json", + "original_sha256": null, + "staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "original_sha256": null, + "staged_sha256": "9a39631362f20168da409cef74f7690f3aa1b8f841fc96ecd8770f73a1f954ac" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "original_sha256": null, + "staged_sha256": "b6210dcd34e5485c94e35f4bdd3329fb72c1d40fa9357caf40ac42b4f8afa5c2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "original_sha256": null, + "staged_sha256": "06530425dd9634182f70a65dd2da56cbad3da967bc842b3c7b01c30542222128" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "original_sha256": null, + "staged_sha256": "aa9758d4de587d14c6ce0fdaccd84002c5c5099425b9169ca7c972a86e9d3dec" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "original_sha256": null, + "staged_sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "original_sha256": null, + "staged_sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "original_sha256": null, + "staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "original_sha256": null, + "staged_sha256": "0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "original_sha256": null, + "staged_sha256": "c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "original_sha256": null, + "staged_sha256": "08c5573eaad05efd24b6df6737d33e7189543eb621f21704e38bab4326094914" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "original_sha256": null, + "staged_sha256": "e304dd29571bf7d7b9f1db2ade0163dd39cfec012a5ce6986139f019f37e65a2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "original_sha256": null, + "staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "original_sha256": null, + "staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "original_sha256": null, + "staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "original_sha256": null, + "staged_sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "original_sha256": null, + "staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "original_sha256": null, + "staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "original_sha256": null, + "staged_sha256": "b7cd28b2ada33004c9264cb54c9749fa501f60166638f926e50e264ddebe037d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "original_sha256": null, + "staged_sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "original_sha256": null, + "staged_sha256": "3b57f525bbbb1db9dc46bcc6b0057a8dd9f45c461fad0a8dea5391ca78038c36" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "original_sha256": null, + "staged_sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt", + "original_sha256": null, + "staged_sha256": "18205c0c7aa8f3460d78e3b7ad9dddd9e361395f9a28d93a7a384c29c9602d36" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "original_sha256": null, + "staged_sha256": "f61da7bf60e42728c2ef2f98838f310e9f97765096015492917ef8e9cab2d000" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "original_sha256": null, + "staged_sha256": "c25d47a084401aafe4f17b9e9ac87bf099d7c9f423bd181509617314884bd28a" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "original_sha256": null, + "staged_sha256": "33a321fe0c276733034288e7395496cb52c8eaf7730da880637cfa379276978c" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "original_sha256": null, + "staged_sha256": "2f8d4894c2861b34977ec020593b7515a8ee35a43ce2e6aef2d96a6d34a94ddc" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json", + "original_sha256": null, + "staged_sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json", + "original_sha256": null, + "staged_sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json", + "original_sha256": null, + "staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json", + "original_sha256": null, + "staged_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py", + "original_sha256": null, + "staged_sha256": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "original_sha256": null, + "staged_sha256": "a59bcddc6c79e3ba8265a95b4b68facda2683abda8e47e5bb48ce402b9e1fa82" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json", + "original_sha256": null, + "staged_sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json", + "original_sha256": null, + "staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/review-refinement.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/review-refinement.json", + "original_sha256": null, + "staged_sha256": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json", + "original_sha256": null, + "staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json", + "original_sha256": null, + "staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json", + "original_sha256": null, + "staged_sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json", + "original_sha256": null, + "staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json", + "original_sha256": null, + "staged_sha256": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json", + "original_sha256": null, + "staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py", + "original_sha256": null, + "staged_sha256": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py", + "original_sha256": null, + "staged_sha256": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py", + "original_sha256": null, + "staged_sha256": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py", + "original_sha256": null, + "staged_sha256": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json", + "original_sha256": null, + "staged_sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "original_sha256": null, + "staged_sha256": "303490dd5a89da0ea2ea92149cfa7cd580e8f3270d3db42edae1c59e4aaf42ca" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py", + "original_sha256": null, + "staged_sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.source.txt", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-b1e3e66b/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.source.txt", + "original_sha256": null, + "staged_sha256": "24e4b022f17ca041ccfbfb11d6de6373c90f4e790690e1cd4cf00e84fde6b838" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/intake.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/intake.json", + "original_sha256": "f61da7bf60e42728c2ef2f98838f310e9f97765096015492917ef8e9cab2d000", + "staged_sha256": "4947868e1bf7ac07ff7cb00d29188e591adcc7faad74a5d1b24a38656210cc3e" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json", + "original_sha256": "c25d47a084401aafe4f17b9e9ac87bf099d7c9f423bd181509617314884bd28a", + "staged_sha256": "de159c1ef1bb3fc4fea9bbc1deae14d03ecd2f891d608a5dfb78f00799337574" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/memo.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/memo.json", + "original_sha256": "33a321fe0c276733034288e7395496cb52c8eaf7730da880637cfa379276978c", + "staged_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md", + "original_sha256": "2f8d4894c2861b34977ec020593b7515a8ee35a43ce2e6aef2d96a6d34a94ddc", + "staged_sha256": "440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/proposal.json", + "original_sha256": "a59bcddc6c79e3ba8265a95b4b68facda2683abda8e47e5bb48ce402b9e1fa82", + "staged_sha256": "7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + }, + { + "repo": "informed-decision", + "path": "docs/evidence/2026-10-11-purpose-image-release/validation.json", + "staged_path": "/tmp/infd-purpose-combined-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/validation.json", + "original_sha256": "303490dd5a89da0ea2ea92149cfa7cd580e8f3270d3db42edae1c59e4aaf42ca", + "staged_sha256": "044775a8cbdf9c7c2fdc9e020b33a90d5366d60584807b87604df2b2a9f88638" + } +] diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json new file mode 100644 index 0000000..d7ded46 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight-inputs.json @@ -0,0 +1,16 @@ +{ + "packet_files": { + "change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "preflight.py": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "native-preflight.json": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + "owner_source_files": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4" + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py new file mode 100644 index 0000000..e7d6e22 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/preflight.py @@ -0,0 +1,25 @@ +"""Read-only refresh; exact original capture remains immutable; never execute cutover.""" +import argparse,hashlib,json,subprocess,sys +from pathlib import Path +if sys.flags.optimize: + raise SystemExit("optimized interpreter refused before source/transport execution") +ROOT=Path(__file__).resolve().parent +p=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args() +out=a.receipt_output.resolve() +if not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists(): + raise SystemExit('unique execution receipt must be outside the sealed packet') +inputs=json.loads((ROOT/'preflight-inputs.json').read_text()) +for relative,digest in inputs['packet_files'].items(): + path=ROOT/relative + if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed') +for relative,digest in inputs['owner_source_files'].items(): + path=a.source_root/relative + if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed') +from change_guard import transport_result +program='import subprocess,json,hashlib,datetime,sys,copy,re\nif sys.flags.optimize:raise RuntimeError("optimized interpreter refused")\ncandidate=json.loads(CANDIDATE_LITERAL)\nsealed_dependencies=json.loads(DEPENDENCIES_LITERAL)\nsealed_baseline=json.loads(SEALED_LITERAL)\nexec(GUARD_LITERAL)\ndef run(args,data=None):\n p=subprocess.run(args,input=data,text=True,capture_output=True)\n if p.returncode: raise ValueError(\'read-only command failed: \'+args[1]+\' \'+args[2])\n return p.stdout\nlive=json.loads(run([\'kubectl\',\'get\',\'deployment\',\'informed-decision\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\ncm=json.loads(run([\'kubectl\',\'get\',\'configmap\',\'informed-decision-runtime-6c221878d051\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\npvc=json.loads(run([\'kubectl\',\'get\',\'pvc\',\'informed-decision-data\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\ncheck_dependencies(cm,pvc,sealed_dependencies)\ncheck_current(live,sealed_baseline)\nspec=live[\'spec\']; cs=spec[\'template\'][\'spec\'][\'containers\'];assert len(cs)==1 and cs[0][\'name\']==\'informed-decision\'\nexpected_env={\'INFD_KEYCAPE_ISSUER\':\'https://kc.coulomb.social\',\'INFD_CONTAINER_CONFIG\':\'/configuration/runtime.json\'}\nassert cs[0].get(\'env\')==[{\'name\':\'INFD_KEYCAPE_ISSUER\',\'value\':expected_env[\'INFD_KEYCAPE_ISSUER\']},{\'name\':\'INFD_CONTAINER_CONFIG\',\'value\':expected_env[\'INFD_CONTAINER_CONFIG\']}]\nassert cs[0][\'image\']==\'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\'\nassert spec[\'replicas\']==1 and spec[\'strategy\']=={\'type\':\'Recreate\'}\nassert next(v for v in spec[\'template\'][\'spec\'][\'volumes\'] if v[\'name\']==\'configuration\')[\'configMap\'][\'name\']==\'informed-decision-runtime-6c221878d051\'\nassert live[\'status\'].get(\'readyReplicas\')==1 and live[\'status\'].get(\'updatedReplicas\')==1\nsealed={\'apiVersion\':live[\'apiVersion\'],\'kind\':live[\'kind\'],\'metadata\':{k:copy.deepcopy(v) for k,v in live[\'metadata\'].items() if k not in (\'resourceVersion\',\'generation\',\'creationTimestamp\',\'managedFields\')},\'spec\':copy.deepcopy(spec)}\nfor key in (\'kubectl.kubernetes.io/last-applied-configuration\',\'deployment.kubernetes.io/revision\'):sealed[\'metadata\'].get(\'annotations\',{}).pop(key,None)\nadmitted=json.loads(run([\'kubectl\',\'apply\',\'--dry-run=server\',\'-f\',\'-\',\'-o\',\'json\'],json.dumps(candidate)))\ncheck_admitted(admitted,sealed_baseline)\napp=json.loads(run([\'kubectl\',\'get\',\'application\',\'informed-decision\',\'-n\',\'argocd\',\'-o\',\'json\']))\nassert app[\'spec\'][\'source\'][\'path\']==\'deploy/lifecycle\' and not app[\'spec\'].get(\'syncPolicy\',{}).get(\'automated\')\nargo={\'uid\':app[\'metadata\'][\'uid\'],\'repoURL\':app[\'spec\'][\'source\'][\'repoURL\'],\'targetRevision\':app[\'spec\'][\'source\'][\'targetRevision\'],\'path\':app[\'spec\'][\'source\'][\'path\'],\'destination\':app[\'spec\'][\'destination\'],\'automated\':False,\'sync\':app.get(\'status\',{}).get(\'sync\'),\'health\':app.get(\'status\',{}).get(\'health\')}\nexpected_argo=json.loads(ARGO_LITERAL)\nfor key in (\'uid\',\'repoURL\',\'targetRevision\',\'path\',\'destination\',\'automated\'):\n assert argo[key]==expected_argo[key]\nassert argo[\'health\'][\'status\']==\'Healthy\'\ndiff=subprocess.run([\'kubectl\',\'diff\',\'-f\',\'-\'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\nnode=run([\'kubectl\',\'describe\',\'node\']);allocated=re.search(r\'Allocated resources:.*?CPU Requests|Allocated resources:\',node,re.S)\nsection=node.split(\'Allocated resources:\')[1].split(\'Events:\')[0] if \'Allocated resources:\' in node else \'\'\nnodes=json.loads(run([\'kubectl\',\'get\',\'nodes\',\'-o\',\'json\']))[\'items\'];assert len(nodes)==1\nalloc=nodes[0][\'status\'][\'allocatable\'];cpu=alloc[\'cpu\'];cpu_m=int(cpu[:-1]) if cpu.endswith(\'m\') else int(cpu)*1000\nrequested=int(re.search(r\'cpu\\s+(\\d+)m\',section).group(1));assert requested<=cpu_m\nreceipt={\'node_allocatable_cpu_m\':cpu_m,\'node_requested_cpu_m\':requested,\'captured_at\':datetime.datetime.now(datetime.timezone.utc).isoformat(),\'native_workload_changed\':False,\'native_backup_restore_executed\':False,\'argo\':argo,\'native_dependencies_checked\':True,\'configmap_uid\':cm[\'metadata\'][\'uid\'],\'pvc_uid\':pvc[\'metadata\'][\'uid\'],\'live_ready_replicas\':1,\'admitted_uid\':admitted[\'metadata\'][\'uid\'],\'server_dry_run_passed\':True,\'admitted_spec_exactly_live_plus_image\':True,\'client_diff_exit\':diff.returncode,\'client_diff_sha256\':hashlib.sha256(diff.stdout.encode()).hexdigest(),\'node_allocated_resources\':section.strip(),\'all_checks_pass\':True}\nprint(json.dumps(receipt))\n' +for marker,value in [('DEPENDENCIES_LITERAL',(ROOT/'sealed-native-dependencies.json').read_text()),('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]: + program=program.replace(marker,repr(value)) +program='import traceback,json\ntry:\n'+''.join(' '+line+'\n' for line in program.splitlines())+"except Exception as error:\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\n" +r=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True) +result=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True +out.write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1) diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json new file mode 100644 index 0000000..3dcc48a --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/proposal.json @@ -0,0 +1,87 @@ +{ + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "trial_id": "infd-purpose-20261011-r1", + "state": "prepared-unapproved", + "target": "realm:kubernetes/railiance01/informed-decision", + "authority": "ADMINISTER; activation APPROVED only upon exact founder disposition", + "candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "published_source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "prior_argo_revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "native_object": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "namespace": "informed-decision", + "name": "informed-decision", + "uid": "a588e10a-90d2-4883-975e-6dd8b8feca92" + }, + "argo_application_uid": "499868f2-eabc-4df4-ae31-b89ce58d750d", + "source_gate": "All four exact committed owner Kustomize input blobs in execution-plan.json and clean current owner HEAD must match; source preparation is not native approval", + "sync_scope": [ + "apps:Deployment:informed-decision" + ], + "prune": false, + "automated_sync": false, + "runtime_configmap": "informed-decision-runtime-6c221878d051", + "schema": 5, + "requested_operations": [ + "Protected SQLite-consistent native backup and independently protected off-cluster custody", + "Offline restore/integrity/count comparison on a private disposable volume with exact candidate, no runtime tokens/config/network", + "Refresh a consistent pre-cutover snapshot, retain private copies and count-only/hash receipts", + "Pin existing manual Argo Application to exact approved owner source and manually sync only existing Deployment image", + "Verify health/readiness/image/module/installed fail-closed purpose checks and retained schema/count evidence; recover to prior same-schema image if needed" + ], + "execute_by": "2026-10-12T23:59:59Z", + "temporary_vulnerability_review_due": "2026-10-18", + "known_scan_findings": "0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical", + "vulnerability_record": "INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05", + "cost_estimate_EUR": 0, + "cost_limits": "No new recurring infrastructure; private backup storage and attended engineering/recovery time unpriced, not an autopilot cost grant", + "risk_estimates": [ + "Brief Recreate service interruption; no concurrent new writer/surge", + "Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence", + "Candidate purpose refusal may expose callers relying on advisory results as binding", + "Inherited known fixable MEDIUM remains until separately approved owner remediation", + "Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted", + "All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller." + ], + "rollback": "Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes", + "native_executed": false, + "human_approval": false, + "refinement_of_manifest": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300", + "mandatory_pre_open_gate": "stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration", + "optimized_interpreters": "local+remote explicitlyrefused beforeassert gates", + "native_dependency_gate": "sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads", + "live_counts": "Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained", + "source_basis": { + "reviewed_protocol_commit": "e0359bcb6cdfad9ab3e868054121fe0cebec2d68", + "owner_followthrough_commit": "9268c9ac0bbee508fe35c0b90dcefef4c24da2f5", + "final_execution_source": "exact subsequent root-applied source commit must be bound by founder receipt and verified against four approved Git blobs" + }, + "approved_owner_render_blob_sha256": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "execution_bundle_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "execution_helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", + "execution_plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6", + "execution_phases": [ + "drill-backup", + "drill-copy", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.", + "offline_initializer": "One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.", + "rollback_dispatch": "Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.", + "purpose_proof_limit": "Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.", + "refinement_of_amended_manifest": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json new file mode 100644 index 0000000..5db68f7 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/published-verification.json @@ -0,0 +1,64 @@ +{ + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "observed_at": "2026-10-11T01:24:01.985128+00:00", + "native_owner_publication_job": { + "id": 11484, + "name": "publish-candidate", + "head_branch": "main", + "head_sha": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "run_number": 3, + "event": "push", + "display_title": "Prepare readable overlay context with the admitted legacy builder", + "status": "success", + "workflow_id": "purpose-overlay-image.yaml", + "url": "https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3", + "created_at": "2026-10-11T01:20:59Z", + "updated_at": "2026-10-11T01:21:08Z", + "run_started_at": "2026-10-11T01:20:59Z" + }, + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62", + "registry_proof_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "source_render_change_only": "Deployment/informed-decision spec.template.spec.containers[0].image", + "runtime_configmap_unchanged": "informed-decision-runtime-6c221878d051", + "installed_image_execution": { + "immutable_registry_artifact_pulled_anonymously": true, + "UID": 10001, + "GID": 10001, + "policy_file_UID": 0, + "policy_file_mode": "0644", + "purpose_variants": 10, + "binding_forms_allowed": 2, + "advisory_or_malformed_refused": 8, + "network": "none", + "read_only": true, + "synthetic_transport": true, + "native_PDP_test": false + }, + "scan_summary_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "historical_failed_runs_retained": [ + "f66de505/task11482/run1", + "acecad887/task11483/run2" + ], + "native_hosting_changed": false, + "native_backup_restore_executed": false, + "human_approval": false, + "evidence_file_sha256": { + "image-manifest.json": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb", + "image-config.json": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10", + "base-image-config.json": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00", + "registry-proof.json": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "trivy-full.json": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e", + "sbom.cdx.json": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d", + "base-trivy-full.json": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80", + "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", + "verify_registry.py": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4", + "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "review-refinement.json": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75", + "test_change_guard.py": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f", + "test_sqlite_readonly.py": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323", + "test_preflight_optimization.py": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d" + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json new file mode 100644 index 0000000..918ff6d --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/registry-proof.json @@ -0,0 +1,47 @@ +{ + "image_digest": "sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "base_image_digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "base_layer_bytes_identical": true, + "layer_media_type_conversion": "OCI gzip to Docker gzip, same digest and size", + "base_runtime_config_semantics_identical": true, + "legacy_builder_config_additions": { + "Hostname": "", + "Domainname": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Cmd": null, + "Volumes": null, + "OnBuild": null, + "Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883" + }, + "base_rootfs_prefix_identical": true, + "overlay_regular_files": [ + "opt/venv/lib/python3.12/site-packages/informed_decision/policy.py" + ], + "overlay_directories": [ + "opt", + "opt/venv", + "opt/venv/lib", + "opt/venv/lib/python3.12", + "opt/venv/lib/python3.12/site-packages", + "opt/venv/lib/python3.12/site-packages/informed_decision" + ], + "policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62", + "policy_mode": "0644", + "base_user": "10001:10001", + "source_scope_labels": { + "org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62", + "social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1" + }, + "registry_read_route": "anonymous public scoped bearer challenge, no token retention", + "image_executed": false, + "native_workload_changed": false, + "native_backup_restore_executed": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json new file mode 100644 index 0000000..a474665 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-admission.json @@ -0,0 +1,52 @@ +{ + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "policy": { + "origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080", + "package": "informed-decision.compact-sitting", + "version": "v13", + "package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873", + "pod_name": "flex-auth-informed-decision-sitting" + }, + "keycape_egress_ips": [ + "92.205.62.239" + ], + "storage_class": "local-path", + "ordinary_approval_ids": [ + "2ce76d7f-01c3-4b63-8476-8d1230679769", + "c2af4bcf-15b4-4305-aac1-acc7e4dcb099", + "dc22666a-d5d7-46bc-9490-ebe9fe09dc38" + ], + "lifecycle_policy": { + "package": "informed-decision.lifecycle", + "version": "v2", + "package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c", + "origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080", + "pod_name": "flex-auth-informed-decision-lifecycle" + }, + "lifecycle_delivery": true, + "intake_attributes": true, + "intake_delivery": { + "hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000" + }, + "workload_api": { + "registries_configmap": "informed-decision-workload-registry", + "peers": [ + { + "namespace": "state-hub", + "app": "state-hub" + } + ], + "api_egress": [ + { + "ip": "10.43.0.1", + "port": 443 + }, + { + "ip": "92.205.62.239", + "port": 6443 + } + ], + "intake": true, + "lifecycle": true + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json new file mode 100644 index 0000000..7459f8f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/rollback-deployment.json @@ -0,0 +1,267 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "annotations": { + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover", + "argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision" + }, + "name": "informed-decision", + "namespace": "informed-decision" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 1, + "selector": { + "matchLabels": { + "app.kubernetes.io/name": "informed-decision" + } + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "annotations": { + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "labels": { + "app.kubernetes.io/component": "review", + "app.kubernetes.io/name": "informed-decision" + } + }, + "spec": { + "automountServiceAccountToken": false, + "containers": [ + { + "env": [ + { + "name": "INFD_KEYCAPE_ISSUER", + "value": "https://kc.coulomb.social" + }, + { + "name": "INFD_CONTAINER_CONFIG", + "value": "/configuration/runtime.json" + } + ], + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "livenessProbe": { + "httpGet": { + "path": "/healthz", + "port": "http" + }, + "periodSeconds": 10, + "timeoutSeconds": 2 + }, + "name": "informed-decision", + "ports": [ + { + "containerPort": 8080, + "name": "http" + }, + { + "containerPort": 8081, + "name": "workload" + } + ], + "readinessProbe": { + "httpGet": { + "path": "/healthz", + "port": "http" + }, + "periodSeconds": 10, + "timeoutSeconds": 2 + }, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "5m", + "memory": "64Mi" + } + }, + "securityContext": { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + }, + "readOnlyRootFilesystem": true + }, + "startupProbe": { + "failureThreshold": 12, + "httpGet": { + "path": "/healthz", + "port": "http" + }, + "periodSeconds": 10, + "timeoutSeconds": 2 + }, + "volumeMounts": [ + { + "mountPath": "/data", + "name": "data" + }, + { + "mountPath": "/run/informed-decision", + "name": "runtime" + }, + { + "mountPath": "/tmp", + "name": "tmp" + }, + { + "mountPath": "/configuration", + "name": "configuration", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/policy", + "name": "caller", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/audit", + "name": "audit", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/kubernetes", + "name": "kubernetes-api", + "readOnly": true + }, + { + "mountPath": "/workload-registry", + "name": "workload-registry", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/requester", + "name": "sitting-requester", + "readOnly": true + } + ] + } + ], + "securityContext": { + "fsGroup": 10001, + "fsGroupChangePolicy": "OnRootMismatch", + "runAsGroup": 10001, + "runAsNonRoot": true, + "runAsUser": 10001, + "seccompProfile": { + "type": "RuntimeDefault" + } + }, + "serviceAccountName": "review", + "terminationGracePeriodSeconds": 45, + "volumes": [ + { + "name": "data", + "persistentVolumeClaim": { + "claimName": "informed-decision-data" + } + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "runtime" + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "tmp" + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-runtime-6c221878d051" + }, + "name": "configuration" + }, + { + "name": "caller", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "audience": "flex-auth", + "expirationSeconds": 3600, + "path": "token" + } + } + ] + } + }, + { + "name": "audit", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "token", + "path": "token" + } + ], + "secretName": "informed-decision-audit" + } + }, + { + "name": "kubernetes-api", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "expirationSeconds": 600, + "path": "token" + } + }, + { + "configMap": { + "items": [ + { + "key": "ca.crt", + "path": "ca.crt" + } + ], + "name": "kube-root-ca.crt" + } + } + ] + } + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-workload-registry" + }, + "name": "workload-registry" + }, + { + "name": "sitting-requester", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "client-secret", + "path": "client-secret" + } + ], + "optional": false, + "secretName": "informed-decision-sitting-requester" + } + } + ] + } + } + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json new file mode 100644 index 0000000..f6f812d --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-live-deployment.json @@ -0,0 +1,286 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "annotations": { + "argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision", + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "name": "informed-decision", + "namespace": "informed-decision", + "uid": "a588e10a-90d2-4883-975e-6dd8b8feca92" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 1, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app.kubernetes.io/name": "informed-decision" + } + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "annotations": { + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "labels": { + "app.kubernetes.io/component": "review", + "app.kubernetes.io/name": "informed-decision" + } + }, + "spec": { + "automountServiceAccountToken": false, + "containers": [ + { + "env": [ + { + "name": "INFD_KEYCAPE_ISSUER", + "value": "https://kc.coulomb.social" + }, + { + "name": "INFD_CONTAINER_CONFIG", + "value": "/configuration/runtime.json" + } + ], + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "imagePullPolicy": "IfNotPresent", + "livenessProbe": { + "failureThreshold": 3, + "httpGet": { + "path": "/healthz", + "port": "http", + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 2 + }, + "name": "informed-decision", + "ports": [ + { + "containerPort": 8080, + "name": "http", + "protocol": "TCP" + }, + { + "containerPort": 8081, + "name": "workload", + "protocol": "TCP" + } + ], + "readinessProbe": { + "failureThreshold": 3, + "httpGet": { + "path": "/healthz", + "port": "http", + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 2 + }, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "5m", + "memory": "64Mi" + } + }, + "securityContext": { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + }, + "readOnlyRootFilesystem": true + }, + "startupProbe": { + "failureThreshold": 12, + "httpGet": { + "path": "/healthz", + "port": "http", + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 2 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/data", + "name": "data" + }, + { + "mountPath": "/run/informed-decision", + "name": "runtime" + }, + { + "mountPath": "/tmp", + "name": "tmp" + }, + { + "mountPath": "/configuration", + "name": "configuration", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/policy", + "name": "caller", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/audit", + "name": "audit", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/kubernetes", + "name": "kubernetes-api", + "readOnly": true + }, + { + "mountPath": "/workload-registry", + "name": "workload-registry", + "readOnly": true + }, + { + "mountPath": "/var/run/secrets/informed-decision/requester", + "name": "sitting-requester", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": { + "fsGroup": 10001, + "fsGroupChangePolicy": "OnRootMismatch", + "runAsGroup": 10001, + "runAsNonRoot": true, + "runAsUser": 10001, + "seccompProfile": { + "type": "RuntimeDefault" + } + }, + "serviceAccount": "review", + "serviceAccountName": "review", + "terminationGracePeriodSeconds": 45, + "volumes": [ + { + "name": "data", + "persistentVolumeClaim": { + "claimName": "informed-decision-data" + } + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "runtime" + }, + { + "emptyDir": { + "medium": "Memory", + "sizeLimit": "16Mi" + }, + "name": "tmp" + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-runtime-6c221878d051" + }, + "name": "configuration" + }, + { + "name": "caller", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "audience": "flex-auth", + "expirationSeconds": 3600, + "path": "token" + } + } + ] + } + }, + { + "name": "audit", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "token", + "path": "token" + } + ], + "secretName": "informed-decision-audit" + } + }, + { + "name": "kubernetes-api", + "projected": { + "defaultMode": 288, + "sources": [ + { + "serviceAccountToken": { + "expirationSeconds": 600, + "path": "token" + } + }, + { + "configMap": { + "items": [ + { + "key": "ca.crt", + "path": "ca.crt" + } + ], + "name": "kube-root-ca.crt" + } + } + ] + } + }, + { + "configMap": { + "defaultMode": 292, + "name": "informed-decision-workload-registry" + }, + "name": "workload-registry" + }, + { + "name": "sitting-requester", + "secret": { + "defaultMode": 288, + "items": [ + { + "key": "client-secret", + "path": "client-secret" + } + ], + "optional": false, + "secretName": "informed-decision-sitting-requester" + } + } + ] + } + } + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json new file mode 100644 index 0000000..8490089 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sealed-native-dependencies.json @@ -0,0 +1,52 @@ +{ + "configmap": { + "apiVersion": "v1", + "immutable": true, + "kind": "ConfigMap", + "metadata": { + "annotations": { + "argocd.argoproj.io/tracking-id": "informed-decision:/ConfigMap:informed-decision/informed-decision-runtime-6c221878d051", + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover" + }, + "name": "informed-decision-runtime-6c221878d051", + "namespace": "informed-decision", + "uid": "90113d2d-54d9-4e82-b1d3-90b49ebed2b5" + }, + "canonical_data_sha256": "8ec462d12347548f506eeebf1e3c7cc47648019c8a783804d09bcc79b0f22af6" + }, + "pvc": { + "apiVersion": "v1", + "kind": "PersistentVolumeClaim", + "metadata": { + "annotations": { + "argocd.argoproj.io/tracking-id": "informed-decision:/PersistentVolumeClaim:informed-decision/informed-decision-data", + "informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover", + "pv.kubernetes.io/bind-completed": "yes", + "pv.kubernetes.io/bound-by-controller": "yes", + "volume.beta.kubernetes.io/storage-provisioner": "rancher.io/local-path", + "volume.kubernetes.io/selected-node": "239.62.205.92.host.secureserver.net", + "volume.kubernetes.io/storage-provisioner": "rancher.io/local-path" + }, + "finalizers": [ + "kubernetes.io/pvc-protection" + ], + "name": "informed-decision-data", + "namespace": "informed-decision", + "uid": "d80b25b1-141a-441b-b205-98fa2fd98b7c" + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "1Gi" + } + }, + "storageClassName": "local-path", + "volumeMode": "Filesystem", + "volumeName": "pvc-d80b25b1-141a-441b-b205-98fa2fd98b7c" + } + }, + "pvc_phase": "Bound" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json new file mode 100644 index 0000000..48926d3 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/security-summary.json @@ -0,0 +1,35 @@ +{ + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "scanner": "aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969", + "version": "0.74.0", + "db_metadata": { + "Version": 2, + "NextUpdate": "2026-10-11T18:59:50.889010572Z", + "UpdatedAt": "2026-10-10T18:59:50.889010923Z", + "DownloadedAt": "2026-10-10T23:32:32.380033131Z" + }, + "suppression": false, + "ignore_unfixed": false, + "severity_filter": null, + "package_count": 44, + "findings_by_severity": { + "MEDIUM": 1 + }, + "findings": [ + { + "id": "CVE-2026-85091", + "package": "zlib", + "installed": "1.3.2-r0", + "fixed": "1.3.2-r1", + "severity": "MEDIUM" + } + ], + "coverage_limits": [ + "Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages", + "Known findings asof pinnedDB, not claim absence of unknown vulnerabilities" + ], + "high_critical": 0, + "same_scanner_actual_base_scan_findings_identical": true, + "base_scan_file": "base-trivy-full.json" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py new file mode 100644 index 0000000..833721b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/sqlite_readonly.py @@ -0,0 +1,39 @@ +"""Pre-open schema/integrity/count proof; stdlib only, never constructs Store.""" +import argparse +import json +from pathlib import Path +import sqlite3 + + +def inspect_readonly(path): + path = Path(path) + if not path.is_file() or path.is_symlink(): + raise ValueError('existing nonsymlink private database required') + with sqlite3.connect(path.resolve().as_uri() + '?mode=ro', uri=True, timeout=5) as db: + db.execute('PRAGMA query_only=ON') + db.execute('BEGIN') + version = db.execute('PRAGMA user_version').fetchone()[0] + if version != 5: + raise ValueError('pre-open database is not schema5; refuse migration') + if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]: + raise ValueError('read-only integrity check refused') + lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0] + for name, table in (('records', 'lifecycle_records'), + ('events', 'lifecycle_events'), + ('pending', 'lifecycle_pending'))} + result = {'schema_version': version, 'lifecycle': lifecycle, + 'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')), + 'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')), + 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False} + db.rollback() + return result + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--db', type=Path, required=True) + args = parser.parse_args() + try: + print(json.dumps(inspect_readonly(args.db), sort_keys=True)) + except Exception: + raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json new file mode 100644 index 0000000..957926b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-approved-bc6494cd/validation.json @@ -0,0 +1,57 @@ +{ + "intake_valid_offline": true, + "typed_memo_valid": true, + "lifecycle_documents_valid": 20, + "packet_actual_file_bytes_verified": true, + "submission_digest": "sha256:fd78d486174670e12efb2f812bac02e68f294e7791b9302d0d458c053240f5a9", + "offline_constructed_grant": "state-hub/decision-record/net-kingdom-admins", + "deployed_submitter_admission_verified": false, + "human_approval": false, + "live_submitted": false, + "native_backup_restore_executed": false, + "native_workload_changed": false, + "packet_bytes_total": 171910, + "guard_tests": 11, + "guard_drift_negative_assertions": 28, + "transport_negative_cases": 6, + "fresh_readonly_preflight_all_checks_pass": true, + "fresh_readonly_capture": "2026-10-11T01:39:14Z", + "original_capture_bytes_preserved": true, + "pre_open_old_unknown_schema_negative_cases": 6, + "optimized_interpreter_negative_cases": 2, + "native_dependencies_checked": true, + "native_pre_open_schema_checked": false, + "original36path_snapshot_preserved": true, + "refinement_same_proposal_trial": true, + "register_json_bytes": 238209, + "mechanical_helper_tests": 16, + "mechanical_review_manifest_sha256": "80fd16e0f5841b83a012ce195b28ebf5b0dad37c87d1efa5d8cbfd219a780824", + "helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", + "execution_bundle_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "combined_source_negative_cases": [ + { + "case": "document-content-changed", + "refused": true + }, + { + "case": "helper-hash-changed", + "refused": true + }, + { + "case": "duplicate-document-identity", + "refused": true + }, + { + "case": "typed-source-bytes-changed", + "refused": true + }, + { + "case": "typed-duplicate-digest", + "refused": true + } + ], + "original78path_snapshot_preserved": true, + "actual_provider_probe": false, + "source_hash_negative_refusals_before_authority_or_dispatch": 4, + "source_boundary_receipt_sha256": "877f93485c1a6817bdfde257051f202d33e14f0ee54e03e597043c8924723337" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json new file mode 100644 index 0000000..c33c54f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json @@ -0,0 +1,279 @@ +[ + { + "id": "infd-20261011-purpose-overlay-r1", + "publish": { + "version": 2, + "audience": { + "subjects": [], + "groups": [ + "net-kingdom-admins" + ] + } + }, + "review": { + "version": 2, + "options": { + "submitter": "state-hub", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + } + } + }, + "revise": { + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "expected_version": 1, + "summary": "Same supervised trial: retain original approvedbackup and UNCERTAINcopy; correct explicitSQLiteclose/frozenimmutable reads and introduce exact named existing-snapshot rescue with separate hash-linked journal, fresh human review, unchanged image/scope.", + "documents": [ + { + "digest": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024", + "media_type": "text/markdown", + "content_base64": "IyBJbmZvcm1lZCBEZWNpc2lvbiB2ZXJzaW9uMiBleGlzdGluZy1zbmFwc2hvdCByZXNjdWUgYW5kIGltYWdlIHJlbGVhc2UKCkFwcHJvdmUgdGhlIGV4YWN0IHNvdXJjZS1yZWZpbmVkIHJlY292ZXJ5IG9mIHRoZSBmYWlsZWQgZHJpbGwtY29weSBhbmQgY29uZGl0aW9uYWwgcmVtYWluaW5nIGJhY2t1cC9kcmlsbC9EZXBsb3ltZW50LW9ubHkgaW1hZ2Ugcm9sbG91dC4gVGhpcyBpcyBtZW1vIHZlcnNpb24yIGluIHRoZSBzYW1lIHByb3Bvc2FsL3RyaWFsLCByZXF1aXJpbmcgTkVXIGZvdW5kZXIgYWNjZXB0YW5jZTsgb3JpZ2luYWwgdmVyc2lvbjEgYWNjZXB0YW5jZSBpcyByZXRhaW5lZCBhbmQgY2Fubm90IGF1dGhvcml6ZSBjaGFuZ2VkIGhlbHBlcmJ5dGVzLgoKT3JpZ2luYWwgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCB0aGUgcHJvdGVjdGVkIG5hdGl2ZSBkcmlsbC1iYWNrdXAsIHRoZW4gY29weSBmYWlsZWQgYmVmb3JlIGFueSBsb2NhbGZpbGUuIE1ldGFkYXRhLW9ubHkgdmVyaWZpY2F0aW9uIHByb3ZlcyB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMC9wcml2YXRlU0hNMzI3NjguIFRoZSBvcmlnaW5hbCByZWFkZXIgY291bGQgbGVhdmUgU0hNIGluZGV4aW5nIGJlY2F1c2UgaXRzIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgY2xvc2UuIFRoZSBjb3JyZWN0aW9uIGV4cGxpY2l0bHljbG9zZXMgYWxsIHJlYWRlcnMgYW5kIHVzZXMgaW1tdXRhYmxlIHJlYWRzIE9OTFkgZm9yIGEgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbm90IGxpdmUgb3Igd3JpdGFibGVjbG9uZS4gU0hNIHN0YXlzIHVuY2hhbmdlZDsgbm9uemVyb1dBTC9oYXNoL2lkZW50aXR5IGRyaWZ0IHN0b3BzIHJlc2N1ZS4KCkRpc3RpbmN0IGRyaWxsLWNvcHktcmVzY3VlLXIxL25ld2xpbmtlZGpvdXJuYWwgcHJlc2VydmVzIG9yaWdpbmFsIFVOQ0VSVEFJTmNvcHkgYW5kIGV4YWN0IGpvdXJuYWxoYXNoL2F0dGVtcHRzLiBObyBvbGRyZXRyeS9vdmVyd3JpdGUsIG5vIG5ld2RyaWxsYmFja3VwLiBSZXF1aXJlIG9yaWdpbmFsQ09NUExFVEViYWNrdXAvVU5DRVJUQUlOY29weSBvbmx5LCBhYnNlbnRsb2NhbGZpbGVzL3Jlc3RvcmV2b2x1bWUsIG9yaWdpbmFsbmF0aXZlUG9kVUlEL2N1cnJlbnRvbGRpbWFnZStzb3VyY2VwaW4gYW5kIGFsbENNL1BWQy9EZXBsb3ltZW50IHNlYWxzLiBDb3B5IHNuYXBzaG90Ynl0ZXMgb25seSBpbnRvIGEgbmV3cHJpdmF0ZTA2MDBmaWxlLiBSZW1haW5pbmdvcmRlcmVkcGhhc2VzIGV4cGxpY2l0bHkgY29uc3VtZSBDT01QTEVURXJlc2N1ZXJlc3VsdDsgb25lIGlzb2xhdGVkIFVJRDAvQ0FQX0NIT1dOLW9ubHkgTkVXdm9sdW1lIGluaXRpYWxpemVyIHRoZW4gVUlEMTAwMDEgcHJlLW9wZW4vYWRtaW4vcG9zdC1hZG1pbiBjaGVja3MgcHJvdmVzIHJlYWwtZGF0YSBjb21wYXRpYmlsaXR5IGJlZm9yZSBjdXRvdmVyLiBObyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50czsgbm8gc2VydmljZSBzdGFydHVwLiBBbnkgYXR0ZW1wdGVkIGZhaWx1cmUvYW1iaWd1aXR5IGlzIGR1cmFibGUgYW5kIGNhbm5vdHJldHJ5LgoKSW1hZ2U3NjNjIGZyb20gYWN0dWFsQ0kzZTRiY2IyNiByZW1haW5zIHVuY2hhbmdlZDhiYXNlIGxheWVycyBwbHVzcG9saWN5LnB5OyBsZWdhY3lzZXJpYWxpemF0aW9uIGRpZmZlcmVuY2VzIGRpc2Nsb3NlZC4gQWN0dWFsaW5zdGFsbGVkVUlEMTAwMDEvMTBwdXJwb3NldmFyaWFudHMgcGFzczsgbmF0aXZlX3Byb3ZpZGVyPWZhbHNlL3N5bnRoZXRpY3RyYW5zcG9ydCBpcyBub3QgYWN0dWFsUERQYXV0aG9yaXR5IHByb29mLCB3aGljaCByZW1haW5zIHNlcGFyYXRlVDA0Z2F0ZS4gQWN0dWFsZnVsbDQ0cGFja2FnZXNjYW4wSElHSC9DUklUSUNBTCwgT05FZml4YWJsZWluaGVyaXRlZE1FRElVTXpsaWJDVkUtMjAyNi04NTA5MSgxLjMuMi1yMOKGknIxKSwgaWRlbnRpY2FsYmFzZWZpbmRpbmcuIEV4cGxpY2l0dGVtcG9yYXJ5cGVybWlzc2lvbiBmb3IgdGhpcyBmaW5kaW5nIGlzIHJlcXVlc3RlZCBhZ2Fpbiwgd2l0aCBvd25lclQwNS9yaXNrcmVjb3JkZHVlT2N0MTg7IG5vIHplcm8tQ1ZFL1Jpc2tOZXh1c2dyYWRlY2xhaW0uIFJhd3NjYW4vU0JPTS9iYXNlIHNjYW4gc3RheSB1bmNoYW5nZWRoYXNoYm91bmQgdmlhIHB1Ymxpc2hlZHJlY2VpcHQ7IGV4YWN0aGVscGVyYW5kb3JpZ2luYWxjb3VudC1vbmx5cmVjZWlwdHMgZGlyZWN0bHlidW5kbGUtYm91bmQgd2l0aGluMjBkb2NzLgoKQWZ0ZXIgcmVzY3VlK29mZmxpbmVnYXRlcywgZGlzdGluY3RjdXRvdmVyYmFja3VwL2NvcHkgYW5kIG1hbnVhbEFyZ29EZXBsb3ltZW50LW9ubHkgaW1hZ2U3NjNjL3BydW5lPWZhbHNlIHJlbWFpbiBjb25kaXRpb25hbC4gRm91cmNvbW1pdHRlZEt1c3RvbWl6ZWJsb2JzL2N1cnJlbnRmaW5hbHNvdXJjZUhFQUQvaGVscGVycy9jYXNlaGFzaGVzIG1hdGNoOyBhdXRvbWF0ZWR7fSBvciBvdmVycmlkZXMgcmVmdXNlLiBDb25maWc2Yy9zY2hlbWE1L1BWQy9pZGVudGl0eS9wb2xpY2llcy9yZXBsaWNhMVJlY3JlYXRlIHN0YXlmaXhlZC4gUm9sbGJhY2tkb2Vzbm90bmVlZCBSZWFkeWNhbmRpZGF0ZSBvciBpdHNEQmV4ZWM7IG9sZGltYWdlUmVhZHkvc2NvcGVkb3BlcmF0aW9uL3NjaGVtYTVjdXJyZW50REIgaXMgYSBzZXBhcmF0ZXByb29mLiBQcmVzZXJ2ZSBsYXRlc3RsaXZlREIvYWxsbmV3Y29tbWl0cyBhbmQgYWxsdW5jZXJ0YWlub3V0Y29tZXM7IG5ldmVycmVzdG9yZW9sZGVyYmFja3VwIG92ZXJsYXRlcnJlY29yZHMuCgpBbGxwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZS9yZWNvdmVyeS92ZXJpZnkgbXVzdGJlZ2luIGJlZm9yZU9jdDEyIDIzOjU5OjU5WjsgZXhwaXJ5cmVxdWlyZXNuZXdkZWNpc2lvbiBhbmQgbWF5ZGVsYXlyZWNvdmVyeS4gTm8gYXV0b21hdGljZXhwaXJ5Y29udHJvbGxlci4gRnJlc2hyb290LWF1dGhlbnRpY2F0ZWQgbmF0aXZlZm91bmRlcmFjY2VwdGFuY2UgdmVyc2lvbjIgYmVmb3JlZWFjaHBoYXNlOyByZWNlaXB0cyBhcmUgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3RzaWduZWRncmFudC9hdXRvbm9teS4gRVVSMCByZWN1cnJpbmdpbmZyYSwgZXhpc3Rpbmdwcml2YXRlY29weS9zdG9yYWdlL2F0dGVuZGVkdGltZSB1bnByaWNlZDsgbm8gc2Vjb25kbmF0aXZlIGRyaWxsYmFja3VwLiBFeGFjdG9yaWdpbmFsYXBwcm92ZWRwYWNrZXQvZmFpbHVyZS90ZWNobmljYWxyZWZpbmVtZW50cyBwcmVzZXJ2ZWQgc2FtZXByb3Bvc2FsL3RyaWFsLiBObyB2ZXJzaW9uMm5hdGl2ZW9wZXJhdGlvbiB5ZXQuCg==" + }, + { + "digest": "sha256:34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbF9pZCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgInRyaWFsX2lkIjogImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMSIsCiAgInN0YXRlIjogInByZXBhcmVkLXVuYXBwcm92ZWQiLAogICJ0YXJnZXQiOiAicmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbiIsCiAgImF1dGhvcml0eSI6ICJBRE1JTklTVEVSOyBhY3RpdmF0aW9uIEFQUFJPVkVEIG9ubHkgdXBvbiBleGFjdCBmb3VuZGVyIGRpc3Bvc2l0aW9uIiwKICAiY2FuZGlkYXRlX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYSIsCiAgInB1Ymxpc2hlZF9zb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInByaW9yX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgInByaW9yX2FyZ29fcmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgIm5hdGl2ZV9vYmplY3QiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJhcHBzL3YxIiwKICAgICJraW5kIjogIkRlcGxveW1lbnQiLAogICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAidWlkIjogImE1ODhlMTBhLTkwZDItNDg4My05NzVlLTZkZDhiOGZlY2E5MiIKICB9LAogICJhcmdvX2FwcGxpY2F0aW9uX3VpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICJzb3VyY2VfZ2F0ZSI6ICJBbGwgZm91ciBleGFjdCBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGluIGV4ZWN1dGlvbi1wbGFuLmpzb24gYW5kIGNsZWFuIGN1cnJlbnQgb3duZXIgSEVBRCBtdXN0IG1hdGNoOyBzb3VyY2UgcHJlcGFyYXRpb24gaXMgbm90IG5hdGl2ZSBhcHByb3ZhbCIsCiAgInN5bmNfc2NvcGUiOiBbCiAgICAiYXBwczpEZXBsb3ltZW50OmluZm9ybWVkLWRlY2lzaW9uIgogIF0sCiAgInBydW5lIjogZmFsc2UsCiAgImF1dG9tYXRlZF9zeW5jIjogZmFsc2UsCiAgInJ1bnRpbWVfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAic2NoZW1hIjogNSwKICAicmVxdWVzdGVkX29wZXJhdGlvbnMiOiBbCiAgICAiUmVhZC1vbmx5IGltbXV0YWJsZSB2YWxpZGF0aW9uIG9mIGV4aXN0aW5nIGZyb3plbjE5NTM3OTIwYnl0ZSBuYXRpdmUgZHJpbGwgc25hcHNob3QsIFNIQTg3NTYuLi4sIHByaXZhdGVjdXN0b2R5L25vLXdyaXRlci96ZXJvV0FML3N0YWxlU0hNIHJldGFpbmVkIiwKICAgICJEaXN0aW5jdCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBiaW5hcnljb3B5IGludG8gYWJzZW50MDYwMHByb3RlY3RlZCBsb2NhbCBkZXN0aW5hdGlvbiwgbmV3IGhhc2gtbGlua2VkIHJlc2N1ZSBqb3VybmFsIHByZXNlcnZpbmcgb2xkIFVOQ0VSVEFJTiBjb3B5IiwKICAgICJFeGlzdGluZyBpc29sYXRlZCBvZmZsaW5lIHByZS1vcGVuL2FkbWluL3Bvc3Qtb3BlbiBjb21wYXRpYmlsaXR5IGRyaWxsIGFuZCBkaXNwb3NhYmxlLXZvbHVtZSBjbGVhbnVwIHVzaW5nIHJlc2N1ZWQgcmVzdWx0IiwKICAgICJEaXN0aW5jdCBjb25zaXN0ZW50IGN1dG92ZXIgc25hcHNob3QgcGx1cyBwcm90ZWN0ZWRjb3B5LCBmb2xsb3dlZCBvbmx5IGFmdGVyIGFsbGdhdGVzIGJ5IERlcGxveW1lbnQtb25seSBpbWFnZSByZWxlYXNlL3ZlcmlmeTsgc2FtZS1zY2hlbWEgcm9sbGJhY2svcmVjb3ZlcnkgcHJvb2YgaWYgbmVlZGVkIgogIF0sCiAgImV4ZWN1dGVfYnkiOiAiMjAyNi0xMC0xMlQyMzo1OTo1OVoiLAogICJ0ZW1wb3JhcnlfdnVsbmVyYWJpbGl0eV9yZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJrbm93bl9zY2FuX2ZpbmRpbmdzIjogIjBISUdIL0NSSVRJQ0FMLDFmaXhhYmxlIGluaGVyaXRlZE1FRElVTSB6bGliLCBhY3R1YWwgY3VycmVudGJhc2UrY2FuZGlkYXRlIGZpbmRpbmdzIGlkZW50aWNhbCIsCiAgInZ1bG5lcmFiaWxpdHlfcmVjb3JkIjogIklORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxIC8gSU5GRC1XUC0wMDA5LVQwNSIsCiAgImNvc3RfZXN0aW1hdGVfRVVSIjogMCwKICAiY29zdF9saW1pdHMiOiAiTm8gYWRkaXRpb25hbCByZWN1cnJpbmcgaW5mcmFzdHJ1Y3R1cmUgb3Igc2Vjb25kIGRyaWxsIGJhY2t1cC4gRXhpc3RpbmcgbmF0aXZlIHNuYXBzaG90MTk1Mzc5MjBieXRlcyByZXRhaW5lZDsgcHJvdGVjdGVkIGxvY2FsY29weS9vZmZsaW5lY2xvbmUgcGx1cyBkaXN0aW5jdCBjdXRvdmVyIHNuYXBzaG90cyBjb25zdW1lIGJvdW5kZWRleGlzdGluZ3N0b3JhZ2UuIEF0dGVuZGVkZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZDsgbm8gYXV0b3BpbG90IGdyYW50LiIsCiAgInJpc2tfZXN0aW1hdGVzIjogWwogICAgIkJyaWVmIFJlY3JlYXRlIHNlcnZpY2UgaW50ZXJydXB0aW9uOyBubyBjb25jdXJyZW50IG5ldyB3cml0ZXIvc3VyZ2UiLAogICAgIlByaXZhdGUgZXZpZGVuY2Ugc25hcHNob3QgY3VzdG9keSBhbmQgZGlzcG9zYWwgZXJyb3JzOyBubyBzbmFwc2hvdHMvdG9rZW5zIGluIHB1YmxpYyBldmlkZW5jZSIsCiAgICAiQ2FuZGlkYXRlIHB1cnBvc2UgcmVmdXNhbCBtYXkgZXhwb3NlIGNhbGxlcnMgcmVseWluZyBvbiBhZHZpc29yeSByZXN1bHRzIGFzIGJpbmRpbmciLAogICAgIkluaGVyaXRlZCBrbm93biBmaXhhYmxlIE1FRElVTSByZW1haW5zIHVudGlsIHNlcGFyYXRlbHkgYXBwcm92ZWQgb3duZXIgcmVtZWRpYXRpb24iLAogICAgIkV4aXN0aW5nIEFyZ28gT3V0T2ZTeW5jIGJhc2VsaW5lIGlzIHJldGFpbmVkOyBubyB3aG9sZS1hcHAgc3luYyBvciB1bnJlbGF0ZWQgcmVwYWlycyBwZXJtaXR0ZWQiLAogICAgIkFsbCBwaGFzZXMsIGluY2x1ZGluZyByZWNvdmVyeS92ZXJpZmljYXRpb24sIG11c3QgYmVnaW4gYmVmb3JlIE9jdDEyIGRlYWRsaW5lOyBpZiByZWNvdmVyeSB3aW5kb3cgaXMgZXhoYXVzdGVkIHN0b3AgYW5kIG9idGFpbiBhIGZyZXNoIGZvdW5kZXIgZGVjaXNpb24uIE5vIGF1dG9tYXRpYyBleHBpcnkgY29udHJvbGxlci4iCiAgXSwKICAicm9sbGJhY2siOiAiTWFudWFsIEFyZ28gc291cmNlIHBpbiBiYWNrIHRvN2RiODQ4NSBhbmQgc2NvcGVkIERlcGxveW1lbnQtb25seSBzeW5jIHRvN2Y1YyBpbWFnZTsgcmV0YWluIGN1cnJlbnQgc2NoZW1hNSBkYXRhYmFzZSBhbmQgYWxsIHBvc3QtY3V0b3ZlciBldmlkZW5jZSwgbmV2ZXIgcmVzdG9yZSBvbGRlciBzbmFwc2hvdCBvdmVyIGxpdmUgd3JpdGVzIiwKICAibmF0aXZlX2V4ZWN1dGVkIjogIk9yaWdpbmFsIGRyaWxsLWJhY2t1cCBleGVjdXRlZDsgb3JpZ2luYWwgZHJpbGwtY29weSBmYWlsZWQuIE5vIHZlcnNpb24yIGFjdGlvbiBleGVjdXRlZC4iLAogICJodW1hbl9hcHByb3ZhbCI6ICJWZXJzaW9uMSBhY2NlcHRlZCBvcmlnaW5hbHNvdXJjZTsgdmVyc2lvbjIgcmVxdWlyZXMgZnJlc2ggZXhhY3QgYWNjZXB0YW5jZS4iLAogICJyZWZpbmVtZW50X29mX21hbmlmZXN0IjogIjdjNjczOGIzOWVhOGU1NGU2MWM4ZWQ2MjVlOTRhZDBiMjc1NWU2NzJlMTU3NmVmY2RmODRhMWQ2NjVhYzMzMDAiLAogICJtYW5kYXRvcnlfcHJlX29wZW5fZ2F0ZSI6ICJzdGRsaWJTUUxpdGUgbW9kZT1yby9xdWVyeV9vbmx5OiBzY2hlbWE1K2ludGVncml0eStjb3VudCBiYXNlbGluZSBiZWZvcmUgQU5ZIFN0b3JlL2FkbWluIG9uIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5OyByZWZ1c2VvbGRzY2hlbWFzIHdpdGhvdXQgbWlncmF0aW9uIiwKICAib3B0aW1pemVkX2ludGVycHJldGVycyI6ICJsb2NhbCtyZW1vdGUgZXhwbGljaXRseXJlZnVzZWQgYmVmb3JlYXNzZXJ0IGdhdGVzIiwKICAibmF0aXZlX2RlcGVuZGVuY3lfZ2F0ZSI6ICJzZWFsZWQgYWN0dWFsQ00gVUlEL2ltbXV0YWJsZS9jYW5vbmljYWxkYXRhaGFzaCtQVkMgVUlEL2Z1bGxzcGVjL0JvdW5kL3ZvbHVtZU5hbWUsIG5vIHJhd0NNZGF0YSBvclNlY3JldCByZWFkcyIsCiAgImxpdmVfY291bnRzIjogIkZyb3plbiBzbmFwc2hvdC9jbG9uZSBleGFjdGNvdW50ZXIgZXF1YWxpdHk7IHBvc3RjdXRvdmVyL3JvbGxiYWNrIGxpdmVjb3VudGVyY2hhbmdlcyBtYXkgcmVmbGVjdCBsZWdpdGltYXRlIGNvbmN1cnJlbnRjb21taXRzL3N0YXRlIHRyYW5zaXRpb25zLCBsYXRlc3REQiBhbHdheXNyZXRhaW5lZCIsCiAgInNvdXJjZV9iYXNpcyI6IHsKICAgICJvcmlnaW5hbF9hcHByb3ZlZF9zb3VyY2UiOiAiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMCIsCiAgICAiZmluYWxfcmVjb3Zlcnlfc291cmNlIjogImV4YWN0IGZpbmFsIHJvb3QtYXBwbGllZCBvd25lciBIRUFEIHdpdGggYXBwcm92ZWQgZm91ciByZW5kZXIgYmxvYnMgbXVzdCBiZSBib3VuZCBieSBuZXcgZm91bmRlciByZWNlaXB0IgogIH0sCiAgImFwcHJvdmVkX293bmVyX3JlbmRlcl9ibG9iX3NoYTI1NiI6IHsKICAgICJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvbiI6ICI5MjM4MmE1NmIzNDljM2I4OTVlNTgwNmU5NzUwODI1MjdiYjk5ZDFhMDAxMTQwZTY5ZDg1N2U1YjAzOTFmYTU1IiwKICAgICJkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24iOiAiMzhiNzhiOWNiZWU1YWRlNzc1MGE1OGQ1MTU2Y2E0YzU3NzMzNTJlOTQ3YWNiMzA0ZWU3MTRiNTllNzQ5Y2ViNCIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwiOiAiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0NyIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uIjogIjliYWQ2ZGI1ZmJjMjE3OGQzMWIwNDEyMDAxNmE0MTgzMGMzNTUyZmJiOWUyNTE3YjcxOGY5YmJlODdjZjY0OWUiCiAgfSwKICAiZXhlY3V0aW9uX2J1bmRsZV9zaGEyNTYiOiAiNDljOWNiNzBmMzZmNmNlYjdiMGQyMjQwMGIyZWM5MjMyYTVlMWE4YTAwZDE3ZTkyYjkyZmUzNjdjOThlZmZiNSIsCiAgImV4ZWN1dGlvbl9oZWxwZXJfbWFuaWZlc3Rfc2hhMjU2IjogImYyZmFkNmMyNTFmYmI0NDIwZTA3YzEzMjk4MDJmNTIxYjUxM2JiZjY2ZTUxZjY0YzVkNjczZWYwNGYxNjI4NGMiLAogICJleGVjdXRpb25fcGxhbl9zaGEyNTYiOiAiOWNlNTcyOGE1NjFlNmQzOGY4NDk3MjAxYmFhMmI4NDBkMTE0NDRhMGFmOGFkNjIzNGRmYzM3NDI4MTEzZjI1OCIsCiAgImV4ZWN1dGlvbl9waGFzZXMiOiBbCiAgICAiZHJpbGwtY29weS1yZXNjdWUtcjEiLAogICAgIm9mZmxpbmUtdmVyaWZ5IiwKICAgICJjbGVhbnVwLW9mZmxpbmUiLAogICAgImN1dG92ZXItYmFja3VwIiwKICAgICJjdXRvdmVyLWNvcHkiLAogICAgInJlbGVhc2UiLAogICAgInZlcmlmeSIsCiAgICAicm9sbGJhY2siLAogICAgInJvbGxiYWNrLXZlcmlmeSIKICBdLAogICJkZWFkbGluZV9zZW1hbnRpY3MiOiAiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LiIsCiAgIm9mZmxpbmVfaW5pdGlhbGl6ZXIiOiAiT25lIGlzb2xhdGVkIGxvY2FsIFVJRDA6MC9DQVBfQ0hPV04tb25seSBpbml0aWFsaXplciBvZiB0aGUgbmV3bHkgY3JlYXRlZCBub25jZS1ib3VuZCBkaXNwb3NhYmxlIHZvbHVtZSwgZXhhY3QgY2FuZGlkYXRlIGltYWdlLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pOyBubyBob3N0L2xpdmVQVkMvdG9rZW4vY29uZmlnIG1vdW50LiBTdWJzZXF1ZW50IHByZS1vcGVuL2FkbWluL3Bvc3Qtb3BlbiBjaGVja3MgVUlEMTAwMDE6MTAwMDEuIiwKICAicm9sbGJhY2tfZGlzcGF0Y2giOiAiU2VhbGVkIERlcGxveW1lbnQvQ00vUFZDIGFuZCBzYW1lLXNjaGVtYSBzb3VyY2UvaW1hZ2UgcGFpciBwbHVzIGFkbWlzc2lvbiBDQVM7IG5vIFJlYWR5IGNhbmRpZGF0ZSBvciBQb2QvZGF0YWJhc2UgZXhlYyBwcmVyZXF1aXNpdGUuIHJvbGxiYWNrLXZlcmlmeSBzZXBhcmF0ZWx5IHByb3ZlcyByZWNvdmVyZWQgb2xkIGltYWdlL1JlYWR5MS9zY29wZWQgb3BlcmF0aW9uIGFuZCByZWFkb25seSBjdXJyZW50IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50cy4iLAogICJwdXJwb3NlX3Byb29mX2xpbWl0IjogIlRlbiBpbnN0YWxsZWQgc3ludGhldGljLXRyYW5zcG9ydCBjaGVja3Mgb24gYWN0dWFsIHBsYWNlbWVudDsgbmF0aXZlX3Byb3ZpZGVyPWZhbHNlLiBOb3QgYWN0dWFsIHByb3ZpZGVyL1BEUCBhdXRob3JpdHkgcHJvb2YsIHdoaWNoIHJlbWFpbnMgYSBkaXN0aW5jdCBUMDQgY29tcGxldGlvbiBnYXRlLiIsCiAgInJlZmluZW1lbnRfb2ZfYW1lbmRlZF9tYW5pZmVzdCI6ICJiMWUzZTY2YmM0MDIzZGM4MGM2ZWE1OTU2NGMzNTU3Yzc2NTNmYjNjMzA3ZjQ2YTA0OTk5N2I3NjE5OGE5MDMzIiwKICAibWVtb192ZXJzaW9uIjogMiwKICAicmVjb3ZlcnkiOiB7CiAgICAib3JpZ2luYWxfYW5jaG9yIjogewogICAgICAib3JpZ2luYWxfam91cm5hbF9zaGEyNTYiOiAiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMSIsCiAgICAgICJwaGFzZV9tZXRhZGF0YSI6IHsKICAgICAgICAiZHJpbGwtYmFja3VwIjogewogICAgICAgICAgInN0YXRlIjogIkNPTVBMRVRFIiwKICAgICAgICAgICJhdHRlbXB0X2lkIjogImQ2MzE4MmE3LWUxYTUtNGU4ZS1hNWYxLTJiZjMzMzNjZjE1MyIsCiAgICAgICAgICAic3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAyOjM4OjQ1LjMxMDY1MyswMDowMCIKICAgICAgICB9LAogICAgICAgICJkcmlsbC1jb3B5IjogewogICAgICAgICAgInN0YXRlIjogIlVOQ0VSVEFJTiIsCiAgICAgICAgICAiYXR0ZW1wdF9pZCI6ICIzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2MiLAogICAgICAgICAgInN0YXJ0ZWRfYXQiOiAiMjAyNi0xMC0xMVQwMjozOTo1MC4xOTg3NDArMDA6MDAiCiAgICAgICAgfQogICAgICB9LAogICAgICAiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NiI6ICIwMjVkZGRmMWU5MzkzNmYzMWU5OGI5ZmJmYTg0YWEyYmRhYWEzMzU3M2Y5ZDNiMGUzMmQ5NDdmZDI4NmIxNzBlIiwKICAgICAgInNuYXBzaG90X3NoYTI1NiI6ICI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzIiwKICAgICAgInNuYXBzaG90X2J5dGVzIjogMTk1Mzc5MjAsCiAgICAgICJvZmZfY2x1c3Rlcl9maWxlX2V4aXN0cyI6IGZhbHNlLAogICAgICAib2xkX3VuY2VydGFpbl9yZXRyeV9hdXRob3JpemVkIjogZmFsc2UKICAgIH0sCiAgICAib3JpZ2luYWxfaWRlbnRpdHkiOiB7CiAgICAgICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgICAgICJzb3VyY2VfcmV2aXNpb24iOiAiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMCIsCiAgICAgICJtZW1vX3NoYTI1NiI6ICI1MDZkMzk1NmJlYjdjNjJhYjJiYmRmZGE3ODNjMDU5MDVkMTgzNDUyYTFmNjdhMTgxN2YzZmI4YzJlNTIyOTM3IiwKICAgICAgInBsYW5fc2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiCiAgICB9LAogICAgIm5ld19qb3VybmFsIjogInJlc2N1ZS1leGVjdXRpb24tam91cm5hbC1yMS5qc29uIiwKICAgICJuZXdfcGhhc2UiOiAiZHJpbGwtY29weS1yZXNjdWUtcjEiLAogICAgIm9sZF91bmNlcnRhaW5fcGhhc2Vfb3ZlcndyaXRlX29yX3JldHJ5IjogZmFsc2UsCiAgICAibmV3X3NuYXBzaG90X2JhY2t1cCI6IGZhbHNlLAogICAgInNuYXBzaG90X29yX3NpZGVjYXJfbXV0YXRpb24iOiBmYWxzZSwKICAgICJtYXBwaW5nIjogIm9mZmxpbmUtdmVyaWZ5IGNvbnN1bWVzIENPTVBMRVRFIGRyaWxsLWNvcHktcmVzY3VlLXIxIHJlc3VsdDsgYWxsIGxhdGVyIHBoYXNlcyBvcmRlcmVkIG9ubHkgaW4gbmV3IGhhc2gtbGlua2VkIHJlY292ZXJ5IGpvdXJuYWwiCiAgfSwKICAib3JpZ2luYWxfbmF0aXZlX291dGNvbWUiOiB7CiAgICAiZHJpbGwtYmFja3VwIjogIkNPTVBMRVRFIiwKICAgICJkcmlsbC1jb3B5IjogIlVOQ0VSVEFJTiBiZWZvcmUgbG9jYWxmaWxlIGNyZWF0aW9uIiwKICAgICJuYXRpdmVfaW1hZ2UiOiAidW5jaGFuZ2VkN2Y1OyBubyByb2xsb3V0IiwKICAgICJvcmlnaW5hbF9qb3VybmFsX2FuZF9zaWRlY2FycyI6ICJyZXRhaW5lZCB1bmNoYW5nZWQiCiAgfSwKICAicmVzY3VlX2xpbWl0cyI6ICJObyBsaXZlREJ3cml0ZXMgZHVyaW5nIHJlc2N1ZSBpbnNwZWN0aW9uL2NvcHksIG5vIHNpZGVjYXIgZGVsZXRpb24vY2hlY2twb2ludCwgbm8gcmV0cnkvb3ZlcndyaXRlIG9yaWdpbmFsIFVOQ0VSVEFJTiBwaGFzZS4gTGF0ZXIgZXhpc3RpbmcgYWRtaW4gb2ZmbGluZWluc3BlY3QvY3V0b3ZlcmJhY2t1cCBhbmQgaW1hZ2UgYWN0aW9ucyBuZWVkIG5ldyBleGFjdHZlcnNpb24yIGFjY2VwdGFuY2UgYW5kb3JkZXJlZGd1YXJkcy4iLAogICJzdWJtaXNzaW9uX3JvdXRlIjogIlBPU1QgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMgQ0FTIGV4cGVjdGVkX3ZlcnNpb24xOyBzb3VyY2UgbXVzdCByZW1haW4gdW5ib3VuZDsgcHVibGlzaC9yZXZpZXcgc291cmNldmVyc2lvbjIsIHJlc3VsdGluZyBodW1hbiByZXZpZXcgb3dudmVyc2lvbjEiCn0K" + }, + { + "digest": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgIm9ic2VydmVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjQ6MDEuOTg1MTI4KzAwOjAwIiwKICAibmF0aXZlX293bmVyX3B1YmxpY2F0aW9uX2pvYiI6IHsKICAgICJpZCI6IDExNDg0LAogICAgIm5hbWUiOiAicHVibGlzaC1jYW5kaWRhdGUiLAogICAgImhlYWRfYnJhbmNoIjogIm1haW4iLAogICAgImhlYWRfc2hhIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgInJ1bl9udW1iZXIiOiAzLAogICAgImV2ZW50IjogInB1c2giLAogICAgImRpc3BsYXlfdGl0bGUiOiAiUHJlcGFyZSByZWFkYWJsZSBvdmVybGF5IGNvbnRleHQgd2l0aCB0aGUgYWRtaXR0ZWQgbGVnYWN5IGJ1aWxkZXIiLAogICAgInN0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJ3b3JrZmxvd19pZCI6ICJwdXJwb3NlLW92ZXJsYXktaW1hZ2UueWFtbCIsCiAgICAidXJsIjogImh0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uL2FjdGlvbnMvcnVucy8zIiwKICAgICJjcmVhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjA6NTlaIiwKICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjE6MDhaIiwKICAgICJydW5fc3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjIwOjU5WiIKICB9LAogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInBvbGljeV9zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgInJlZ2lzdHJ5X3Byb29mX3NoYTI1NiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAic291cmNlX3JlbmRlcl9jaGFuZ2Vfb25seSI6ICJEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHNwZWMudGVtcGxhdGUuc3BlYy5jb250YWluZXJzWzBdLmltYWdlIiwKICAicnVudGltZV9jb25maWdtYXBfdW5jaGFuZ2VkIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAiaW5zdGFsbGVkX2ltYWdlX2V4ZWN1dGlvbiI6IHsKICAgICJpbW11dGFibGVfcmVnaXN0cnlfYXJ0aWZhY3RfcHVsbGVkX2Fub255bW91c2x5IjogdHJ1ZSwKICAgICJVSUQiOiAxMDAwMSwKICAgICJHSUQiOiAxMDAwMSwKICAgICJwb2xpY3lfZmlsZV9VSUQiOiAwLAogICAgInBvbGljeV9maWxlX21vZGUiOiAiMDY0NCIsCiAgICAicHVycG9zZV92YXJpYW50cyI6IDEwLAogICAgImJpbmRpbmdfZm9ybXNfYWxsb3dlZCI6IDIsCiAgICAiYWR2aXNvcnlfb3JfbWFsZm9ybWVkX3JlZnVzZWQiOiA4LAogICAgIm5ldHdvcmsiOiAibm9uZSIsCiAgICAicmVhZF9vbmx5IjogdHJ1ZSwKICAgICJzeW50aGV0aWNfdHJhbnNwb3J0IjogdHJ1ZSwKICAgICJuYXRpdmVfUERQX3Rlc3QiOiBmYWxzZQogIH0sCiAgInNjYW5fc3VtbWFyeV9zaGEyNTYiOiAiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NCIsCiAgImhpc3RvcmljYWxfZmFpbGVkX3J1bnNfcmV0YWluZWQiOiBbCiAgICAiZjY2ZGU1MDUvdGFzazExNDgyL3J1bjEiLAogICAgImFjZWNhZDg4Ny90YXNrMTE0ODMvcnVuMiIKICBdLAogICJuYXRpdmVfaG9zdGluZ19jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJodW1hbl9hcHByb3ZhbCI6IGZhbHNlLAogICJldmlkZW5jZV9maWxlX3NoYTI1NiI6IHsKICAgICJpbWFnZS1tYW5pZmVzdC5qc29uIjogIjk3OGM1NzVkM2M3YmYwZGUzOWRiZTRlOTU2N2MzOWNkMzZmNzBiN2U1NWJjMTczNTdiZGIwM2ZiM2I5NmIwZmIiLAogICAgImltYWdlLWNvbmZpZy5qc29uIjogIjRhZDcyNDljNzVmZDlmYzAzOWNlYjE4Njc3MjQxOWUxY2JhNWZkOTc1OWM0MDQ1NTY0NTljODBhMmQyODVkMTAiLAogICAgImJhc2UtaW1hZ2UtY29uZmlnLmpzb24iOiAiYjcwNmM5MjA5ZTMyNGYzOWE4NmZmY2RhMmEzZTlkOTRjOTI2NDk3MzlhZDViMjFmZTQ2MTEwMDZlMzZmNmYwMCIsCiAgICAicmVnaXN0cnktcHJvb2YuanNvbiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAgICJ0cml2eS1mdWxsLmpzb24iOiAiZjM4YThmN2U2YzQxOWVlZDkxNTRkNzc2MmY5MzJiOWRlYjY2ODBhNjIyMjQ3YjA4MTk2Yjc0NThiODkzNDM0ZSIsCiAgICAic2JvbS5jZHguanNvbiI6ICJhNDI1Mjk1MWUyMDI3NDcyYzI2ZDg2NzljYjU0M2UzMDk4MzE4MDgwOWQ2ZGQzYzdjOTRiODgzZDYyODAzZTVkIiwKICAgICJiYXNlLXRyaXZ5LWZ1bGwuanNvbiI6ICJkNDRjNTU1YWVjYmIxYTQ1MThmNDEyN2Q0ODAxNWVhNDU5MzI1YzkzZThiMDM3MTkxMGE1NWRlNDcyOTNjYTgwIiwKICAgICJjaGVja19pbnN0YWxsZWQucHkiOiAiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZCIsCiAgICAidmVyaWZ5X3JlZ2lzdHJ5LnB5IjogIjQxM2Y1NzVjMjFhMmJkMThhMzY5NmY4ZjJkOTM5ZWVhZGM1MmQ3NmYyODJjNDI4MTNmNzZiYjBlM2VlOGEyYTQiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAicmV2aWV3LXJlZmluZW1lbnQuanNvbiI6ICJlYTYyODQ1Y2VlNWVlNmY0ZjZjYjdmNWRjZDBhZjYwMWJhMjlhMjFjOGZmODBlZmJiYzAyYWQxNmUzNWJlYTc1IiwKICAgICJ0ZXN0X2NoYW5nZV9ndWFyZC5weSI6ICJkYTUzNTA0MzczNTdiYTMyOTIzNmNjMTM3NjEwYzAzODU2ZjM4ZjgzNmRkZjI4NTYwMjViYzEyMDExZmFkMDdmIiwKICAgICJ0ZXN0X3NxbGl0ZV9yZWFkb25seS5weSI6ICJjN2E5MWQwYzZhMzczZDczOGM4OGJiODE3ZDliZmIyZmY4YTE3OWJjNjFiOTMwNjNiODk2NzdiNTY2NTIwMzIzIiwKICAgICJ0ZXN0X3ByZWZsaWdodF9vcHRpbWl6YXRpb24ucHkiOiAiYTBjNGZhMThjNWQ2YzIxNDc2YTA2YzZkMDVmZTc2NTYyNTlkMjA0Mjk5MTM4ODUxNTk5ZTkyMTRkOTExMjA2ZCIsCiAgICAiaW5pdGlhbC1hcHByb3ZlZC1iYzY0OTRjZC9zcWxpdGVfcmVhZG9ubHkucHkiOiAiZWVmNTNkZDIzM2VlZTc0YzE3ZjIwODIzYmQ3ZjU3ODdjNjBjYWQ3OWFjNjQ4MDIxYzk0Nzk2NDNjNmNlOWUzOCIKICB9LAogICJ2ZXJzaW9uMl9zb3VyY2VfcG9pbnRlcl9yZWZpbmVtZW50IjogewogICAgIm9yaWdpbmFsX3JlY2VpcHRfc2hhMjU2IjogIjhhNjc2YzM4Zjg5ZjljYTc2MmI4ZWJlOTQ1YjVhY2I5MGQ0N2E0Y2IzNTA2OTI2ODdhYmI5ODViYmIyZDhhZTIiLAogICAgIm9yaWdpbmFsX3JlY2VpcHRfYXJjaGl2ZSI6ICJpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkL3B1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvbiIsCiAgICAicmVhc29uIjogIktlZXAgaGlzdG9yaWNhbCBvcmlnaW5hbCBwcmUtb3BlbiBjaGVja2VyIGhhc2ggYm91bmQgdG8gZXhhY3QgYXJjaGl2ZWQgb3JpZ2luYWwgYnl0ZXM7IGN1cnJlbnQgdmVyc2lvbjIgY2hlY2tlciBpcyBpbmRlcGVuZGVudGx5IGRpcmVjdC1wYWNrZXQvcGxhbiBib3VuZC4gQWN0dWFsIGltYWdlL3JlZ2lzdHJ5L3NjYW4vU0JPTSBwcm9vZiB1bmNoYW5nZWQ7IG5vIG5ldyBhcnRpZmFjdCB2ZXJpZmljYXRpb24gb3IgbmF0aXZlIHZlcnNpb24yIGFjdGlvbiBjbGFpbWVkLiIKICB9Cn0K" + }, + { + "digest": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZV9kaWdlc3QiOiAic2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgImJhc2VfaW1hZ2VfZGlnZXN0IjogInNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAiYmFzZV9sYXllcl9ieXRlc19pZGVudGljYWwiOiB0cnVlLAogICJsYXllcl9tZWRpYV90eXBlX2NvbnZlcnNpb24iOiAiT0NJIGd6aXAgdG8gRG9ja2VyIGd6aXAsIHNhbWUgZGlnZXN0IGFuZCBzaXplIiwKICAiYmFzZV9ydW50aW1lX2NvbmZpZ19zZW1hbnRpY3NfaWRlbnRpY2FsIjogdHJ1ZSwKICAibGVnYWN5X2J1aWxkZXJfY29uZmlnX2FkZGl0aW9ucyI6IHsKICAgICJIb3N0bmFtZSI6ICIiLAogICAgIkRvbWFpbm5hbWUiOiAiIiwKICAgICJBdHRhY2hTdGRpbiI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZG91dCI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZGVyciI6IGZhbHNlLAogICAgIlR0eSI6IGZhbHNlLAogICAgIk9wZW5TdGRpbiI6IGZhbHNlLAogICAgIlN0ZGluT25jZSI6IGZhbHNlLAogICAgIkNtZCI6IG51bGwsCiAgICAiVm9sdW1lcyI6IG51bGwsCiAgICAiT25CdWlsZCI6IG51bGwsCiAgICAiSW1hZ2UiOiAic2hhMjU2OjkwZjE1NzRmOWVkYTM1ZmE2Y2I5NzI5NjFiZWIyN2E3Y2I5MDRjMzY1NjBlMzgxOTMwYjBlMTQwNjVjMjM4ODMiCiAgfSwKICAiYmFzZV9yb290ZnNfcHJlZml4X2lkZW50aWNhbCI6IHRydWUsCiAgIm92ZXJsYXlfcmVndWxhcl9maWxlcyI6IFsKICAgICJvcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weSIKICBdLAogICJvdmVybGF5X2RpcmVjdG9yaWVzIjogWwogICAgIm9wdCIsCiAgICAib3B0L3ZlbnYiLAogICAgIm9wdC92ZW52L2xpYiIsCiAgICAib3B0L3ZlbnYvbGliL3B5dGhvbjMuMTIiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24iCiAgXSwKICAicG9saWN5X3NoYTI1NiI6ICI5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyIiwKICAicG9saWN5X21vZGUiOiAiMDY0NCIsCiAgImJhc2VfdXNlciI6ICIxMDAwMToxMDAwMSIsCiAgInNvdXJjZV9zY29wZV9sYWJlbHMiOiB7CiAgICAib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnJldmlzaW9uIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgIm9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5iYXNlLmRpZ2VzdCI6ICJzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgICAic29jaWFsLmNvdWxvbWIuc291cmNlLnBvbGljeS5zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgICAic29jaWFsLmNvdWxvbWIucmVsZWFzZS5zY29wZSI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIKICB9LAogICJyZWdpc3RyeV9yZWFkX3JvdXRlIjogImFub255bW91cyBwdWJsaWMgc2NvcGVkIGJlYXJlciBjaGFsbGVuZ2UsIG5vIHRva2VuIHJldGVudGlvbiIsCiAgImltYWdlX2V4ZWN1dGVkIjogZmFsc2UsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlCn0K" + }, + { + "digest": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInNjYW5uZXIiOiAiYXF1YXNlYy90cml2eUBzaGEyNTY6NjJiMWU2NWU4ODY5YmM0YjRjNmFhNGZhMmIyMTU5NTI1NmM3YzJmNjAxOGE5ZDlhZDYxY2FmODcxODdjMTk2OSIsCiAgInZlcnNpb24iOiAiMC43NC4wIiwKICAiZGJfbWV0YWRhdGEiOiB7CiAgICAiVmVyc2lvbiI6IDIsCiAgICAiTmV4dFVwZGF0ZSI6ICIyMDI2LTEwLTExVDE4OjU5OjUwLjg4OTAxMDU3MloiLAogICAgIlVwZGF0ZWRBdCI6ICIyMDI2LTEwLTEwVDE4OjU5OjUwLjg4OTAxMDkyM1oiLAogICAgIkRvd25sb2FkZWRBdCI6ICIyMDI2LTEwLTEwVDIzOjMyOjMyLjM4MDAzMzEzMVoiCiAgfSwKICAic3VwcHJlc3Npb24iOiBmYWxzZSwKICAiaWdub3JlX3VuZml4ZWQiOiBmYWxzZSwKICAic2V2ZXJpdHlfZmlsdGVyIjogbnVsbCwKICAicGFja2FnZV9jb3VudCI6IDQ0LAogICJmaW5kaW5nc19ieV9zZXZlcml0eSI6IHsKICAgICJNRURJVU0iOiAxCiAgfSwKICAiZmluZGluZ3MiOiBbCiAgICB7CiAgICAgICJpZCI6ICJDVkUtMjAyNi04NTA5MSIsCiAgICAgICJwYWNrYWdlIjogInpsaWIiLAogICAgICAiaW5zdGFsbGVkIjogIjEuMy4yLXIwIiwKICAgICAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAgICAgInNldmVyaXR5IjogIk1FRElVTSIKICAgIH0KICBdLAogICJjb3ZlcmFnZV9saW1pdHMiOiBbCiAgICAiQWxwaW5lMy4yNCBhYnNlbnQgc2Nhbm5lciBFT0wgbGlzdDsgT1MgZGV0ZWN0b3IgcmFuIGFnYWluc3QgQWxwaW5lMy4yNCByZXBvc2l0b3J5IG9uMzhPUyBwYWNrYWdlcyIsCiAgICAiS25vd24gZmluZGluZ3MgYXNvZiBwaW5uZWREQiwgbm90IGNsYWltIGFic2VuY2Ugb2YgdW5rbm93biB2dWxuZXJhYmlsaXRpZXMiCiAgXSwKICAiaGlnaF9jcml0aWNhbCI6IDAsCiAgInNhbWVfc2Nhbm5lcl9hY3R1YWxfYmFzZV9zY2FuX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgImJhc2Vfc2Nhbl9maWxlIjogImJhc2UtdHJpdnktZnVsbC5qc29uIgp9Cg==" + }, + { + "digest": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5", + "media_type": "application/json", + "content_base64": "ewogICJraW5kIjogImluZm9ybWVkLWRlY2lzaW9uLnN1cGVydmlzZWQtZXhlY3V0aW9uLXNvdXJjZS1idW5kbGUiLAogICJ2ZXJzaW9uIjogMiwKICAicHJvcG9zYWxfaWQiOiAiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEiLAogICJmaWxlcyI6IHsKICAgICJSRUFETUUubWQiOiB7CiAgICAgICJzaGEyNTYiOiAiNTFiNTZjOGVjMmYzMGFkNjJmNmNkMDk3MzJjMGY3M2RkN2I1ZWJmMjA4MTMyMDIyM2M4NWJiY2JmMDBkMTVhOSIsCiAgICAgICJjb250ZW50IjogIiMgVmVyc2lvbjIgcHJvdGVjdGVkIGV4aXN0aW5nLXNuYXBzaG90IHJlc2N1ZSDigJQgcHJlcGFyZWQsIHVuYXBwcm92ZWRcblxuT3JpZ2luYWwgYXBwcm92ZWQgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCBkcmlsbC1iYWNrdXAsIHRoZW4gZHJpbGwtY29weSBmYWlsZWQgYmVmb3JlIGNyZWF0aW5nIGEgbG9jYWwgc25hcHNob3QuIE9yaWdpbmFsIGpvdXJuYWwgZHJpbGwtY29weSByZW1haW5zIFVOQ0VSVEFJTi4gTWV0YWRhdGEtb25seSBjYXB0dXJlIHByb3ZlcyBleGFjdCB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMCBhbmQgcHJpdmF0ZVNITTMyNzY4LiBTb3VyY2UgY2xvc2VzIFNRTGl0ZSBjb25uZWN0aW9ucyBleHBsaWNpdGx5OyBpbW11dGFibGUgcmVhZHMgYXJlIG9ubHkgZm9yIHRoZSBmcm96ZW4gbWFpbiBzbmFwc2hvdCB3aXRoIGV4YWN0IHByaW9yIGRpZ2VzdC9zaXplL3ByaXZhdGUgaWRlbnRpdHkgYW5kIG5vIFdBTCBmcmFtZXMuIExpdmUgc291cmNlIGFuZCBvZmZsaW5lIHByZS9wb3N0LWFkbWluIHJlYWRzIHJlbWFpbiBtb2RlPXJvL3F1ZXJ5X29ubHkgV0FMLWF3YXJlOyBpbW11dGFibGUgaXMgbmV2ZXIgYSBsaXZlIERCIG9yIHNjaGVtYS1taWdyYXRpb24gc2hvcnRjdXQuIFNpZGVjYXJzIHJlbWFpbiByZXRhaW5lZCwgbmV2ZXIgZGVsZXRlZC9jaGVja3BvaW50ZWQuXG5cbkZyZXNoIGZvdW5kZXIgYWNjZXB0YW5jZSBvZiB0aGUgZXhhY3QgbWVtbyB2ZXJzaW9uMiBpcyByZXF1aXJlZCBiZWZvcmUgYW55IHJlc2N1ZSBvciBjb250aW51YXRpb24uIE9sZCB2ZXJzaW9uMSBhY2NlcHRhbmNlIGNhbm5vdCBwYXNzIGF1dGhvcml0eSBjaGVja3MuIFJvb3QgbXVzdCBmcmVzaGx5IGF1dGhlbnRpY2F0ZSBhY3R1YWwgY29uZmlybWVkIHBlcnNvbi9wbGF0Zm9ybS1yb290IEFDQ0VQVCBhdCB0aGUgZml4ZWQgbmF0aXZlIG9yaWdpbiBiZWZvcmUgZWFjaCBwaGFzZTsgcHJvdGVjdGVkIHJlY2VpcHQgY2hlY2tpbmcgaXMgc3VwZXJ2aXNlZCBib29ra2VlcGluZywgbm90IGFuIGF1dGhlbnRpY2F0ZWQgc2lnbmVkL2F1dG9ub21vdXMgZ3JhbnQuIE5vIG5ldyBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4gaW4gdGhpcyBwcmVwYXJhdGlvbi5cblxuRml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnk7IHJvbGxiYWNrIOKGkiByb2xsYmFjay12ZXJpZnkgb25seSBhZnRlciByZWNvcmRlZCBuZXcgcmVsZWFzZSBhdHRlbXB0LiBOZXcgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24gYW5kIHJlc2N1ZS1leGVjdXRpb24tcjEubG9jayBjb2V4aXN0IHdpdGggdGhlIHVuY2hhbmdlZCBvcmlnaW5hbCBleGVjdXRpb24tam91cm5hbC5qc29uLiBUaGV5IGhhc2gtbGluayBpdHMgZXhhY3Qgb3JpZ2luYWwgYXBwcm92ZWQgaWRlbnRpdHksIENPTVBMRVRFIGJhY2t1cCBhbmQgVU5DRVJUQUlOIGNvcHkgYXR0ZW1wdCBJRHMvcmVzdWx0cy4gTm8gZXh0cmEgb3JpZ2luYWwgcGhhc2Ugb3IgcmVsZWFzZSBpcyBhbGxvd2VkOyBvcmlnaW5hbCBqb3VybmFsIGhhc2ggaXMgY2hlY2tlZCBiZWZvcmUgYW5kIGFmdGVyIGVhY2ggbmV3IHBoYXNlLiBObyBvbGQgZHJpbGwtY29weSByZXRyeS9vdmVyd3JpdGUgb3Igc3ludGhlc2l6ZWQgY29tcGxldGVkIHBoYXNlLlxuXG5CZWZvcmUgcmVzY3VlLCBvcmlnaW5hbCBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgbXVzdCBiZSBhYnNlbnQsIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50LCBhbmQgbG9jYWwgZW5naW5lIGJudC1sYXAwMDEvY3VycmVudCBuYXRpdmUgb2xkaW1hZ2U3ZjUvc291cmNlN2RiL3NlYWxlZERlcGxveW1lbnQrQ00vUFZDL29yaWdpbmFsUG9kVUlEIG11c3QgbWF0Y2guIFRoZSBvbGQgYmFja3VwIGFkbWluIGFscmVhZHkgZXhpdGVkIGFmdGVyIHVuaXF1ZWx5IGNyZWF0aW5nIHRoZSBwcml2YXRlIGZpeGVkIHNuYXBzaG90IHBhdGg7IHRoZSBvbmx5IGxhdGVyIG9yaWdpbmFsIGFjY2VzcyB3YXMgV0FMLWF3YXJlIHJlYWRvbmx5IGluc3BlY3Rpb24sIHdpdGggbm8gc25hcHNob3Qgd3JpdGVyLiBNYWluIGhhc2gsIHByaXZhdGUgaWRlbnRpdGllcyBhbmQgYWJzZW50L3plcm8gV0FMIGFyZSBjaGVja2VkIGJlZm9yZS9hZnRlciBpbW11dGFibGUgaW5zcGVjdGlvbiBhbmQgY29weS4gT3JpZ2luYWwgcHJpdmF0ZSBTSE0gaXMgaW5kZXhpbmcgYW5kIGlzIHJldGFpbmVkIHVuY2hhbmdlZC4gTm9uZW1wdHkgV0FMLCBjaGFuZ2VkIGhhc2gvbWV0YWRhdGEsIG1pc3NpbmcgZmFpbGVkIGpvdXJuYWwsIG1pc3Npbmcgb3JpZ2luIG9yIGFueSB1bnZlcmlmaWVkIG91dGNvbWUgc3RvcHMgcmVzY3VlLiBObyBuZXcgbmF0aXZlIGJhY2t1cCBpcyBtYWRlIGZvciB0aGUgZHJpbGwuIEJpbmFyeSBzbmFwc2hvdCBieXRlcyBmbG93IG9ubHkgaW50byBhIG5ldzA2MDAgbG9jYWxmaWxlLCBuZXZlciBjaGF0L2xvZy9wYWNrZXQuIFNhbWUgcmVzY3VlLXBoYXNlIHJldHJ5IGlzIHJlZnVzZWQgYWZ0ZXIgYW55IGF0dGVtcHRlZCBvdXRjb21lLlxuXG5PZmZsaW5lIHZlcmlmaWNhdGlvbiBleHBsaWNpdGx5IGNvbnN1bWVzIENPTVBMRVRFIGRyaWxsLWNvcHktcmVzY3VlLXIxIHJlc3VsdCwgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGV4YWN0IGlzb2xhdGVkIG5ldy12b2x1bWUgVUlEMC9DQVBfQ0hPV04gaW5pdGlhbGl6ZXIsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHJlYWRvbmx5L2FkbWluL3Bvc3QtYWRtaW4gY2hlY2tzIGFuZCByZXRhaW5lZCBvcmlnaW5hbCBTSEEsIHJlbWFpbnMgYm91bmRlZCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3QvQ1BVMS8xMjhNaSB3aXRoIG5vIGhvc3QvbmF0aXZlUFZDL3J1bnRpbWVjb25maWcvdG9rZW4gbW91bnRzLiBPbmx5IHRoZSBkaXNwb3NhYmxlIGNvcHkgdm9sdW1lIGNhbiBiZSByZW1vdmVkLiBDdXRvdmVyIHNuYXBzaG90IGlzIHRoZSBkaXN0aW5jdCBhbHJlYWR5LXNjb3BlZCBuZXcgY3V0b3Zlci5zcWxpdGU7IHJlc2N1ZSBuZXZlciBvdmVyd3JpdGVzIGRyaWxsLnNxbGl0ZSBvciBjcmVhdGVzIGFub3RoZXIgZHJpbGwgYmFja3VwLlxuXG5Gb3VyIGNvbW1pdHRlZCBvd25lciByZW5kZXIgR2l0IGJsb2JzIGFuZCBoZWxwZXIvY2FzZSBoYXNoZXMgbXVzdCBtYXRjaCBleGFjdCBmaW5hbCBzb3VyY2UgSEVBRC4gTWFudWFsQXBwbGljYXRpb24gcmVqZWN0cyBhbnkgYXV0b21hdGVkIGNvbmZpZ3VyYXRpb24gaW5jbHVkaW5nIHt9IG9yIHNvdXJjZSBvdmVycmlkZXMuIFNvdXJjZS1waW4gQXBwbGljYXRpb24ub3BlcmF0aW9uIHVzZXMgc2VydmVyIGRyeS1ydW4gYW5kIFVJRC9yZXNvdXJjZVZlcnNpb24vc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5L3BydW5lPWZhbHNlOyBubyB3aG9sZS1hcHAgc3luYy4gUm9sbGJhY2sgZGlzcGF0Y2ggaGFzIG5vIGZhaWxpbmctY2FuZGlkYXRlIFBvZC9EQiBkZXBlbmRlbmN5OyBzZXBhcmF0ZSByZWNvdmVyeSBwcm9vZiBjaGVja3Mgb2xkaW1hZ2UgUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9zY2hlbWE1IHJldGFpbmVkbGF0ZXN0REIuIEFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlY292ZXJ5L3ZlcmlmaWNhdGlvbiBtdXN0IGJlZ2luIGJ5MjAyNi0xMC0xMlQyMzo1OTo1OVo7IGFmdGVyIGV4cGlyeSBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBObyBleHBpcnkgY29udHJvbGxlciBvciBpbXBsaWNpdCBleHRlbnNpb24uXG5cbkltYWdlNzYzYy9wb2xpY3k5ZDdjIGFuZCBrbm93biBpbmhlcml0ZWQgZml4YWJsZSBNRURJVU0gcmVtYWluIHVuY2hhbmdlZDsgb3duZXIgVDA1IGR1ZU9jdDE4LiBUZW4gaW5zdGFsbGVkIGNoZWNrcyB1c2Ugc3ludGhldGljIHRyYW5zcG9ydC9uYXRpdmVfcHJvdmlkZXI9ZmFsc2UgYW5kIGRvIG5vdCBmdWxmaWxsIHNlcGFyYXRlIGFjdHVhbC1wcm92aWRlciBUMDQgZ2F0ZS4gUHJlc2VydmUgb3JpZ2luYWwgYWNjZXB0YW5jZS9iYWNrdXAvZmFpbHVyZS9oaXN0b3J5IGluIHRoaXMgc2FtZSB0cmlhbC4gVHdlbnR5LXNpeCBtb2NrZWQvc291cmNlIGV4ZWN1dG9yIHJlZ3Jlc3Npb25zIHBhc3M7IG5vIGFjdHVhbCBEQi9hZG1pbi9uYXRpdmUgY29tbWFuZCBkdXJpbmcgdGVzdHMvcHJlcGFyYXRpb24uXG5cbk5hdGl2ZSBwdWJsaWNhdGlvbiByb3V0ZTogUE9TVCBleGlzdGluZyBzb3VyY2UgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMgd2l0aCBleHBlY3RlZF92ZXJzaW9uMSBhbmQgZXhhY3QgbWVtbzIvZG9jdW1lbnRzL3N1bW1hcnksIHRoZW4gcHVibGljYXRpb25zL3Jldmlldy1yZXF1ZXN0cyB2ZXJzaW9uMi4gRnJlc2ggc291cmNlIHJlYWRiYWNrIG11c3QgcHJvdmUgY3VycmVudHZlcnNpb24xIGlzIHVuYm91bmQgYmVmb3JlIHJldmlzaW9uOyBib3VuZC9kaWZmZXJlbnQgc291cmNlIHN0b3BzLiBJbnRha2UvcmVnaXN0ZXIgcmVmdXNlIHZlcnNpb24yIGFzIGRlc2lnbmVkIGFuZCBhcmUgbm90IHVzZWQuIFJldmlldyBpbnRlZ3JhdGlvbiBjcmVhdGVzIGEgTkVXIHJldmlldy1JRCBhdCBpdHMgb3duIHZlcnNpb24xOyBmb3VuZGVyIGRpc3Bvc2l0aW9uIG1lbW9fdmVyc2lvbjEgYmVsb25ncyB0byB0aGF0IG5ldyByZXZpZXcuIFJvb3QgZnJlc2ggb3V0Y29tZXMgbXVzdCBiZSBxdWVyaWVkIGZvciBTT1VSQ0UgdmVyc2lvbjIsIGV4YWN0IG5ld3Jldmlld0lEL21lbW9TSEEgYW5kIGNvbmZpcm1lZCBuZXN0ZWQgcGVyc29uYXBwcm92YWwuIFJlY2VpcHQgb3V0Y29tZV9xdWVyeSBwaW5zIHRoYXQgc291cmNldmVyc2lvbjIgcm91dGU7IGl0IGRvZXMgbm90IGF1dGhlbnRpY2F0ZSBieSBpdHNlbGYuXG4iCiAgICB9LAogICAgImFjdHVhdG9yLnB5IjogewogICAgICAic2hhMjU2IjogIjg2YjY3ZDFhYmFkNmFmMmE4YzQ5NTI4ZmUxMjVhNWJhYjk0NDk3NWQzZTgwMTgyNmM1MTFlZTg4ODQ2NTcxYjIiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmUgZml4ZWQgc3VwZXJ2aXNlZCBwaGFzZTsgbmV2ZXIgcnVuIHRoaXMgZHVyaW5nIHNvdXJjZSBwcmVwYXJhdGlvbi5cIlwiXCJcbmltcG9ydCBhcmdwYXJzZVxuaW1wb3J0IGhhc2hsaWJcbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHJlXG5pbXBvcnQgc2VsZWN0b3JzXG5pbXBvcnQgc3RhdFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0aW1lXG5cbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KCdvcHRpbWl6ZWQgaW50ZXJwcmV0ZXIgcmVmdXNlZCcpXG5cblBIQVNFUyA9ICgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCAnb2ZmbGluZS12ZXJpZnknLCAnY2xlYW51cC1vZmZsaW5lJyxcbiAgICAgICAgICAnY3V0b3Zlci1iYWNrdXAnLCAnY3V0b3Zlci1jb3B5JywgJ3JlbGVhc2UnLCAndmVyaWZ5JywgJ3JvbGxiYWNrJywgJ3JvbGxiYWNrLXZlcmlmeScpXG5cblxuZGVmIHJlcXVpcmUodmFsdWUsIHJlYXNvbik6XG4gICAgaWYgbm90IHZhbHVlOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcblxuXG5kZWYgc2hhKHBhdGgpOlxuICAgIGRpZ2VzdCA9IGhhc2hsaWIuc2hhMjU2KClcbiAgICB3aXRoIFBhdGgocGF0aCkub3BlbigncmInKSBhcyBzdHJlYW06XG4gICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6XG4gICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJsb2NrKVxuICAgIHJldHVybiBkaWdlc3QuaGV4ZGlnZXN0KClcblxuXG5kZWYgcHJpdmF0ZShwYXRoLCBkaXJlY3Rvcnk9RmFsc2UpOlxuICAgIGluZm8gPSBQYXRoKHBhdGgpLmxzdGF0KClcbiAgICByZXF1aXJlKChzdGF0LlNfSVNESVIoaW5mby5zdF9tb2RlKSBpZiBkaXJlY3RvcnkgZWxzZSBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSlcbiAgICAgICAgICAgIGFuZCBpbmZvLnN0X3VpZCA9PSBvcy5nZXR1aWQoKSBhbmQgc3RhdC5TX0lNT0RFKGluZm8uc3RfbW9kZSkgPT0gKDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxuICAgICAgICAgICAgYW5kIChkaXJlY3Rvcnkgb3IgaW5mby5zdF9ubGluayA9PSAxKSwgJ3ByaXZhdGUgb3duZWQgY3VzdG9keSByZXF1aXJlZCcpXG5cblJPT1QgPSBQYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50XG5DQVNFID0gUk9PVC5wYXJlbnRcbk9XTkVSID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uJylcbkNVU1RPRElBTiA9IFBhdGgoJy9ob21lL3dvcnNjaC90aGUtY3VzdG9kaWFuJylcbkNVU1RPRFkgPSBDVVNUT0RJQU4gLyAnLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjEnXG5TT0NLRVQgPSAndW5peDovLy92YXIvcnVuL2RvY2tlci5zb2NrJ1xuSU1BR0UgPSAnZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhJ1xuVk9MVU1FID0gJ2luZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExJ1xuTUFYX0JZVEVTID0gNTEyICogMTAyNCoqMlxuXG5cbmRlZiBydW4oYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTkwKTpcbiAgICByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndiwgaW5wdXQ9Ym9keSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIGpzb25fcmVzdWx0KHJlc3VsdCk6XG4gICAgdHJ5OlxuICAgICAgICB2YWx1ZSA9IGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcbiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhZmUgcGhhc2UgcmVjZWlwdCB1bmF2YWlsYWJsZTsgb3V0Y29tZSB1bmNlcnRhaW4nKSBmcm9tIE5vbmVcbiAgICByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlID09IDAgYW5kIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIFRydWUsXG4gICAgICAgICAgICAncGhhc2UgZGlkIG5vdCB2ZXJpZnkgY29tcGxldGU7IHJhdyBvdXRwdXQgd2l0aGhlbGQ7IG5vIHJldHJ5JylcbiAgICBwZXJtaXR0ZWQgPSB7J3BoYXNlJywgJ2FsbF9jaGVja3NfcGFzcycsICdyYXdfb3V0cHV0X3dpdGhoZWxkJywgJ25hdGl2ZV9hcHByb3ZhbF92ZXJpZmllZF9ieV9yb290JyxcbiAgICAgICAgICAgICAgICAgJ25hdGl2ZV9hdXRoZW50aWNhdGVkX2dyYW50JywgJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZScsICdzbmFwc2hvdF9yZWFkb25seScsXG4gICAgICAgICAgICAgICAgICdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICduYXRpdmVfcGFyZW50X3ByaXZhdGUnLFxuICAgICAgICAgICAgICAgICAnbmF0aXZlX3VpZCcsICdwb2RfbmFtZScsICdwb2RfdWlkJywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnLFxuICAgICAgICAgICAgICAgICAnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzJywgJ29wZXJhdGlvbl9yZXF1ZXN0ZWQnLCAnc291cmNlX3JldmlzaW9uJyxcbiAgICAgICAgICAgICAgICAgJ3Jlc291cmNlcycsICdwcnVuZScsICdyb2xsb3V0X3ZlcmlmaWVkJywgJ2xhdGVzdF9saXZlX2RhdGFiYXNlX3JldGFpbmVkJyxcbiAgICAgICAgICAgICAgICAgJ2NsaWVudF9kaWZmX3NoYTI1NicsICduYXRpdmVfcm9sbG91dF92ZXJpZmllZCcsICdjdXJyZW50X3NjaGVtYTVfZGF0YWJhc2VfcmV0YWluZWQnLFxuICAgICAgICAgICAgICAgICAncHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJywgJ2luc3RhbGxlZF9wdXJwb3NlX2NoZWNrcycsICdwb2xpY3lfc2hhMjU2JyxcbiAgICAgICAgICAgICAgICAgJ3BvbGljeV9tb2RlJywgJ3BvbGljeV91aWQnLCAnaGVhbHRoX3N0YXR1c2VzJywgJ25hdGl2ZV9wcm92aWRlcl9wcm9iZScsICdyZWNvdmVyeV92ZXJpZmljYXRpb24nfVxuICAgIHJlcXVpcmUoc2V0KHZhbHVlKSA8PSBwZXJtaXR0ZWQsICd1bmV4cGVjdGVkIG91dHB1dCBmaWVsZHMgd2l0aGhlbGQnKVxuICAgIGZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuICAgIGZvciBuYW1lIGluICgnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lJywgJ3NuYXBzaG90X3JlYWRvbmx5JywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIGNvdW50cyh2YWx1ZVtuYW1lXSlcbiAgICBmb3IgbmFtZSBpbiAoJ3NuYXBzaG90X3NoYTI1NicsICdjbGllbnRfZGlmZl9zaGEyNTYnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOV17NjR9JywgdmFsdWVbbmFtZV0pIGlzIG5vdCBOb25lLCAnaW52YWxpZCBvdXRwdXQgZGlnZXN0IHdpdGhoZWxkJylcbiAgICBpZiAnc25hcHNob3RfYnl0ZXMnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHR5cGUodmFsdWVbJ3NuYXBzaG90X2J5dGVzJ10pIGlzIGludCBhbmQgMCA8IHZhbHVlWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAnaW52YWxpZCBvdXRwdXQgc2l6ZSB3aXRoaGVsZCcpXG4gICAgaWYgJ3NuYXBzaG90X2ZpbGUnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHZhbHVlWydzbmFwc2hvdF9maWxlJ10gaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSwgJ2ludmFsaWQgb3V0cHV0IGZpbGUgd2l0aGhlbGQnKVxuICAgIHJldHVybiB2YWx1ZVxuXG5cbmRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTEyMCk6XG4gICAgcmV0dXJuIHJ1bihbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVF0gKyBhcmd2LFxuICAgICAgICAgICAgICAgYm9keT1ib2R5LCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkLCBzbmFwc2hvdF9pZGVudGl0eT1Ob25lKTpcbiAgICAjIEZpeGVkIG1vZHVsZSBpbXBvcnRlZCBvbmx5IGFmdGVyIG1haW4gdmVyaWZpZXMgZXZlcnkgZXhlY3V0b3Igc291cmNlIGhhc2guXG4gICAgZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuICAgIHBheWxvYWQgPSB7J3NuYXBzaG90X2lkZW50aXR5Jzogc25hcHNob3RfaWRlbnRpdHksICdwaGFzZSc6IHBoYXNlLCAnc291cmNlX3JldmlzaW9uJzogcmV2aXNpb24sICdhcHByb3ZhbCc6IGFwcHJvdmVkLFxuICAgICAgICAgICAgICAgJ3NlYWxlZCc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ2RlcGVuZGVuY2llcyc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLW5hdGl2ZS1kZXBlbmRlbmNpZXMuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdjYW5kaWRhdGUnOiBqc29uLmxvYWRzKChDQVNFIC8gJ2NhbmRpZGF0ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdyZWNlaXB0X3NhZmV0eSc6IChST09UIC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCksXG4gICAgICAgICAgICAgICAncHVycG9zZV9jaGVja3MnOiAoQ0FTRSAvICdjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICdyZWFkb25seSc6IChDQVNFIC8gJ3NxbGl0ZV9yZWFkb25seS5weScpLnJlYWRfdGV4dCgpfVxuICAgIHNjcmlwdCA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAnX19HVUFSRF9fJywgcmVwcigoQ0FTRSAvICdjaGFuZ2VfZ3VhcmQucHknKS5yZWFkX3RleHQoKSkpXG4gICAgcmV0dXJuIGpzb25fcmVzdWx0KHJ1bihbJ3NzaCcsICdyYWlsaWFuY2UwMScsICdweXRob24zIC0nXSwgc2NyaXB0LCB0aW1lb3V0PTIwMCkpXG5cblxuZGVmIGNvcHlfc25hcHNob3QocGhhc2UsIHJldmlzaW9uLCBhcHByb3ZlZCwgam91cm5hbCk6XG4gICAgcHJpb3IgPSAoam91cm5hbC5kYXRhWydpZGVudGl0eSddWydyZWNvdmVyeV9hbmNob3InXVsnYmFja3VwX3Jlc3VsdCddXG4gICAgICAgICAgICAgaWYgcGhhc2UgPT0gJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyBlbHNlIGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2N1dG92ZXItYmFja3VwJ11bJ3Jlc3VsdCddKVxuICAgIG1ldGFkYXRhID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIGZvciBrZXkgaW4gKCdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICdzbmFwc2hvdF9yZWFkb25seScpOlxuICAgICAgICByZXF1aXJlKG1ldGFkYXRhW2tleV0gPT0gcHJpb3Jba2V5XSwgJ2Nsb3NlZCBmcm96ZW4gc25hcHNob3QgY2hhbmdlZCcpXG4gICAgbmFtZSA9IG1ldGFkYXRhWydzbmFwc2hvdF9maWxlJ11cbiAgICByZXF1aXJlKG5hbWUgaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSBhbmQgMCA8IG1ldGFkYXRhWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICdmaXhlZCBib3VuZGVkIHNuYXBzaG90IHJlcXVpcmVkJylcbiAgICBwb2QgPSBtZXRhZGF0YVsncG9kX25hbWUnXVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtejAtOV0oWy1hLXowLTldKlthLXowLTldKT8nLCBwb2QpIGlzIG5vdCBOb25lLCAnZml4ZWQgb3duZXIgcG9kIG5hbWUgcmVxdWlyZWQnKVxuICAgIGxvY2FsID0gQ1VTVE9EWSAvIG5hbWVcbiAgICBmZCA9IG9zLm9wZW4obG9jYWwsIG9zLk9fV1JPTkxZIHwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1csIDBvNjAwKVxuICAgICMgQmluYXJ5IHNuYXBzaG90IHN0ZG91dCBnb2VzIG9ubHkgdG8gYSBwcml2YXRlIGZpbGUsIG5ldmVyIHRvb2wvY2hhdC9sb2cgb3V0cHV0LlxuICAgICMgU25hcHNob3Qgc2NoZW1hL2NvdW50IG1ldGFkYXRhIHdhcyB2YWxpZGF0ZWQgYmVmb3JlIG9wZW5pbmcgdGhpcyBkZXN0aW5hdGlvbi5cbiAgICB3aXRoIG9zLmZkb3BlbihmZCwgJ3diJykgYXMgZGVzdGluYXRpb246XG4gICAgICAgIGNvbW1hbmQgPSAoJ2t1YmVjdGwgZXhlYyAtbiBpbmZvcm1lZC1kZWNpc2lvbiAnICsgcG9kICtcbiAgICAgICAgICAgICAgICAgICAnIC1jIGluZm9ybWVkLWRlY2lzaW9uIC0tIGNhdCAvZGF0YS9wcml2YXRlL3B1cnBvc2Utb3ZlcmxheS1yMS8nICsgbmFtZSlcbiAgICAgICAgdHJhbnNmZXIgPSBzdWJwcm9jZXNzLlBvcGVuKFsnc3NoJywgJ3JhaWxpYW5jZTAxJywgY29tbWFuZF0sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRlcnI9c3VicHJvY2Vzcy5ERVZOVUxMKVxuICAgICAgICBzZWxlY3RvciA9IHNlbGVjdG9ycy5EZWZhdWx0U2VsZWN0b3IoKVxuICAgICAgICBzZWxlY3Rvci5yZWdpc3Rlcih0cmFuc2Zlci5zdGRvdXQsIHNlbGVjdG9ycy5FVkVOVF9SRUFEKVxuICAgICAgICBkZWFkbGluZSA9IHRpbWUubW9ub3RvbmljKCkgKyAxNTBcbiAgICAgICAgcmVjZWl2ZWQgPSAwXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdoaWxlIFRydWU6XG4gICAgICAgICAgICAgICAgcmVtYWluaW5nID0gZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZW1haW5pbmcgPiAwIGFuZCBzZWxlY3Rvci5zZWxlY3QocmVtYWluaW5nKSwgJ3ByaXZhdGUgdHJhbnNmZXIgdGltZWQgb3V0JylcbiAgICAgICAgICAgICAgICBibG9jayA9IG9zLnJlYWQodHJhbnNmZXIuc3Rkb3V0LmZpbGVubygpLCAxMDI0KioyKVxuICAgICAgICAgICAgICAgIGlmIG5vdCBibG9jazpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICByZWNlaXZlZCArPSBsZW4oYmxvY2spXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZWNlaXZlZCA8PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXSBhbmQgcmVjZWl2ZWQgPD0gTUFYX0JZVEVTLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3ByaXZhdGUgY29weSBleGNlZWRzIGZyb3plbiBzbmFwc2hvdCBzaXplJylcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbi53cml0ZShibG9jaylcbiAgICAgICAgICAgIHRyYW5zZmVyLndhaXQodGltZW91dD1tYXgoMSwgZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpKSlcbiAgICAgICAgZmluYWxseTpcbiAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKClcbiAgICAgICAgICAgIHRyYW5zZmVyLnN0ZG91dC5jbG9zZSgpXG4gICAgICAgICAgICBpZiB0cmFuc2Zlci5wb2xsKCkgaXMgTm9uZTpcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci5raWxsKClcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci53YWl0KClcbiAgICAgICAgZGVzdGluYXRpb24uZmx1c2goKVxuICAgICAgICBvcy5mc3luYyhkZXN0aW5hdGlvbi5maWxlbm8oKSlcbiAgICBwcml2YXRlKGxvY2FsKVxuICAgIHJlcXVpcmUodHJhbnNmZXIucmV0dXJuY29kZSA9PSAwIGFuZCBsb2NhbC5zdGF0KCkuc3Rfc2l6ZSA9PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIHNoYShsb2NhbCkgPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLCAncHJpdmF0ZSBjb3B5IGluY29tcGxldGUvdW5jZXJ0YWluOyByZXRhaW4sIG5vIHJldHJ5JylcbiAgICAjIFJlLXJlYWQgaWRlbnRpdHkvaGFzaCBhZnRlciB0cmFuc2Zlci4gVGhpcyBpcyB2ZXJpZmljYXRpb24sIG5vdCBhIHdyaXRlIHJldHJ5LlxuICAgIGFmdGVyID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIHJlcXVpcmUoYWZ0ZXJbJ3BvZF91aWQnXSA9PSBtZXRhZGF0YVsncG9kX3VpZCddIGFuZCBhZnRlclsnc25hcHNob3Rfc2hhMjU2J10gPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLFxuICAgICAgICAgICAgJ3NvdXJjZSBpZGVudGl0eS9zbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyB0cmFuc2ZlcicpXG4gICAgcmV0dXJuIHsqKm1ldGFkYXRhLCAnb2ZmX2NsdXN0ZXJfcHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJzogVHJ1ZSwgJ3NuYXBzaG90X2NvbnRlbnRzX291dHB1dCc6IEZhbHNlfVxuXG5cbmRlZiBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKTpcbiAgICBmcm9tIHJlY2VpcHRfc2FmZXR5IGltcG9ydCBjb3VudHNcbiAgICBzbmFwc2hvdCA9IENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJ1xuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcHJldmlvdXMgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydyZXN1bHQnXVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdwcm90ZWN0ZWQgc25hcHNob3QgYnl0ZXMgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgcmVxdWlyZShpZGVudGl0eS5yZXR1cm5jb2RlID09IDAgYW5kIGpzb24ubG9hZHMoaWRlbnRpdHkuc3Rkb3V0KSA9PSAnYm50LWxhcDAwMScsXG4gICAgICAgICAgICAnbG9jYWwgb2ZmbGluZSBEb2NrZXIgZW5naW5lIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICByZXF1aXJlKGxpc3RlZC5yZXR1cm5jb2RlID09IDAgYW5kIFZPTFVNRSBub3QgaW4gbGlzdGVkLnN0ZG91dC5zcGxpdGxpbmVzKCksXG4gICAgICAgICAgICAnZGlzcG9zYWJsZSB2b2x1bWUgYWJzZW5jZSBub3QgdmVyaWZpZWQnKVxuICAgIG5vbmNlID0gam91cm5hbC5kYXRhWydwaGFzZXMnXVsnb2ZmbGluZS12ZXJpZnknXVsnYXR0ZW1wdF9pZCddXG4gICAgbGFiZWxzID0geydpbmZvcm1lZC1kZWNpc2lvbi5jYXNlJzogJ2luZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsXG4gICAgICAgICAgICAgICdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOiAnb2ZmbGluZS1yZXN0b3JlLW9ubHknLCAnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdCc6IG5vbmNlfVxuICAgIGNyZWF0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnY3JlYXRlJywgJy0tZHJpdmVyJywgJ2xvY2FsJywgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24uY2FzZT1pbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQ9JyArIG5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLnVzZT1vZmZsaW5lLXJlc3RvcmUtb25seScsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShjcmVhdGVkLnJldHVybmNvZGUgPT0gMCBhbmQgY3JlYXRlZC5zdGRvdXQuc3RyaXAoKSA9PSBWT0xVTUUsICd2b2x1bWUgY3JlYXRpb24gdW5jZXJ0YWluOyBubyByZXRyeScpXG4gICAgaW5zcGVjdGVkID0gZG9ja2VyKFsndm9sdW1lJywgJ2luc3BlY3QnLCBWT0xVTUVdKVxuICAgIHJlcXVpcmUoaW5zcGVjdGVkLnJldHVybmNvZGUgPT0gMCwgJ25ldyB2b2x1bWUgaWRlbnRpdHkgdW5hdmFpbGFibGUnKVxuICAgIHZvbHVtZSA9IGpzb24ubG9hZHMoaW5zcGVjdGVkLnN0ZG91dClcbiAgICByZXF1aXJlKGxlbih2b2x1bWUpID09IDEgYW5kIHZvbHVtZVswXVsnTmFtZSddID09IFZPTFVNRSBhbmQgdm9sdW1lWzBdLmdldCgnTGFiZWxzJykgPT0gbGFiZWxzXG4gICAgICAgICAgICBhbmQgdm9sdW1lWzBdLmdldCgnRHJpdmVyJykgPT0gJ2xvY2FsJyBhbmQgbm90IHZvbHVtZVswXS5nZXQoJ09wdGlvbnMnKVxuICAgICAgICAgICAgYW5kIHZvbHVtZVswXS5nZXQoJ1Njb3BlJykgPT0gJ2xvY2FsJywgJ25ldyBpc29sYXRlZCB2b2x1bWUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSB7a2V5OiB2b2x1bWVbMF1ba2V5XSBmb3Iga2V5IGluICgnTmFtZScsICdMYWJlbHMnLCAnRHJpdmVyJywgJ1Njb3BlJywgJ0NyZWF0ZWRBdCcpfVxuICAgIGpvdXJuYWwubm90ZSgnb2ZmbGluZS12ZXJpZnknLCAnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknLCBpZGVudGl0eSlcbiAgICAjIE9uZS10aW1lIFVJRDAvQ0FQX0NIT1dOIGluaXRpYWxpemF0aW9uIGlzIGlzb2xhdGVkIHRvIHRoZSBORVcgbmFtZWQgdm9sdW1lLlxuICAgICMgTm8gaG9zdC9saXZlIFBWQy9jb25maWcvdG9rZW4gbW91bnQgZXhpc3RzOyB0aGlzIGRldGFpbCBuZWVkcyBwYWNrZXQgcmV2aWV3LlxuICAgIGluaXRpYWxpemVyID0gXCJcIlwiaW1wb3J0IGhhc2hsaWIsb3Msc3RhdCxzeXNcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkJylcbmZvbGRlcj0nL3Jlc3RvcmUnO2V4cGVjdGVkPUVYUEVDVEVEXG5pZiBvcy5saXN0ZGlyKGZvbGRlcik6cmFpc2UgVmFsdWVFcnJvcignbmV3IGVtcHR5IHByaXZhdGUgdm9sdW1lIHJlcXVpcmVkJylcbm9zLmNobW9kKGZvbGRlciwwbzcwMClcbmZkPW9zLm9wZW4oZm9sZGVyKycvcmV2aWV3LnNxbGl0ZScsb3MuT19DUkVBVHxvcy5PX0VYQ0x8b3MuT19OT0ZPTExPV3xvcy5PX1dST05MWSwwbzYwMClcbmRpZ2VzdD1oYXNobGliLnNoYTI1NigpO3NpemU9MFxud2l0aCBvcy5mZG9wZW4oZmQsJ3diJykgYXMgdGFyZ2V0OlxuIHdoaWxlIFRydWU6XG4gIGJsb2NrPXN5cy5zdGRpbi5idWZmZXIucmVhZCgxMDI0KioyKVxuICBpZiBub3QgYmxvY2s6YnJlYWtcbiAgc2l6ZSs9bGVuKGJsb2NrKVxuICBpZiBzaXplPjUxMioxMDI0KioyOnJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgcmVzdG9yZSBzaXplIGV4Y2VlZHMgYm91bmQnKVxuICB0YXJnZXQud3JpdGUoYmxvY2spO2RpZ2VzdC51cGRhdGUoYmxvY2spXG4gdGFyZ2V0LmZsdXNoKCk7b3MuZnN5bmModGFyZ2V0LmZpbGVubygpKVxuaWYgZGlnZXN0LmhleGRpZ2VzdCgpIT1leHBlY3RlZDpyYWlzZSBWYWx1ZUVycm9yKCdwcml2YXRlIGNvcGllZCBzbmFwc2hvdCBkaWZmZXJzJylcbm9zLmNob3duKGZvbGRlcisnL3Jldmlldy5zcWxpdGUnLDEwMDAxLDEwMDAxKTtvcy5jaG93bihmb2xkZXIsMTAwMDEsMTAwMDEpXG5wcmludCgne1wiYWxsX2NoZWNrc19wYXNzXCI6dHJ1ZSxcInByaXZhdGVfY29weV92ZXJpZmllZFwiOnRydWV9JylcblwiXCJcIi5yZXBsYWNlKCdFWFBFQ1RFRCcsIHJlcHIocHJldmlvdXNbJ3NuYXBzaG90X3NoYTI1NiddKSlcbiAgICB3aXRoIHNuYXBzaG90Lm9wZW4oJ3JiJykgYXMgc291cmNlOlxuICAgICAgICBhcmd2ID0gWydkb2NrZXInLCAnLS1jb25maWcnLCBzdHIoQ1VTVE9EWSAvICdlbXB0eS1kb2NrZXItY29uZmlnJyksICctLWhvc3QnLCBTT0NLRVQsXG4gICAgICAgICAgICAgICAgJ3J1bicsICctLXJtJywgJy1pJywgJy0tbmV0d29yaycsICdub25lJywgJy0tcmVhZC1vbmx5JywgJy0tY3B1cycsICcxJywgJy0tbWVtb3J5JywgJzEyOG0nLFxuICAgICAgICAgICAgICAgICctLXVzZXInLCAnMDowJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tY2FwLWFkZCcsICdDSE9XTicsXG4gICAgICAgICAgICAgICAgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJywgJy0tbW91bnQnLCAndHlwZT12b2x1bWUsc3JjPScgKyBWT0xVTUUgKyAnLGRzdD0vcmVzdG9yZScsXG4gICAgICAgICAgICAgICAgJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy1jJywgaW5pdGlhbGl6ZXJdXG4gICAgICAgIGNvcGllZCA9IHN1YnByb2Nlc3MucnVuKGFyZ3YsIHN0ZGluPXNvdXJjZSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PTE1MClcbiAgICBqc29uX3Jlc3VsdChjb3BpZWQpXG4gICAgb3B0aW9ucyA9IFsncnVuJywgJy0tcm0nLCAnLWknLCAnLS1uZXR3b3JrJywgJ25vbmUnLCAnLS1yZWFkLW9ubHknLCAnLS1jcHVzJywgJzEnLCAnLS1tZW1vcnknLCAnMTI4bScsXG4gICAgICAgICAgICAgICAnLS11c2VyJywgJzEwMDAxOjEwMDAxJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJyxcbiAgICAgICAgICAgICAgICctLW1vdW50JywgJ3R5cGU9dm9sdW1lLHNyYz0nICsgVk9MVU1FICsgJyxkc3Q9L3Jlc3RvcmUnXVxuICAgIHJlYWRvbmx5ID0gZG9ja2VyKG9wdGlvbnMgKyBbJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy0nLCAnLS1kYicsICcvcmVzdG9yZS9yZXZpZXcuc3FsaXRlJ10sXG4gICAgICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShyZWFkb25seS5yZXR1cm5jb2RlID09IDAsICdvZmZsaW5lIHByZS1vcGVuIHNjaGVtYS9pbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkOyBuZXZlciBvcGVuIFN0b3JlJylcbiAgICBjaGVja2VkID0gY291bnRzKGpzb24ubG9hZHMocmVhZG9ubHkuc3Rkb3V0KSlcbiAgICByZXF1aXJlKGNoZWNrZWQgPT0gcHJldmlvdXNbJ3NuYXBzaG90X3JlYWRvbmx5J10sICdmcm96ZW4gc25hcHNob3QvY2xvbmUgcmVhZG9ubHkgY291bnRzIGRpZmZlcicpXG4gICAgYWRtaW4gPSBkb2NrZXIob3B0aW9ucyArIFsnLS1lbnRyeXBvaW50JywgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJywgSU1BR0UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaW5zcGVjdCcsICctLWRiJywgJy9yZXN0b3JlL3Jldmlldy5zcWxpdGUnXSlcbiAgICByZXF1aXJlKGFkbWluLnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgYWRtaW4gcmVzdWx0IHVuY2VydGFpbicpXG4gICAgYWRtaW5fY291bnRzID0ganNvbi5sb2FkcyhhZG1pbi5zdGRvdXQpXG4gICAgcmVxdWlyZShhZG1pbl9jb3VudHMgPT0ge2tleTogY2hlY2tlZFtrZXldIGZvciBrZXkgaW4gKCdzY2hlbWFfdmVyc2lvbicsICdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyl9LFxuICAgICAgICAgICAgJ29mZmxpbmUgYWRtaW4gY2hhbmdlZCBmcm96ZW4gc25hcHNob3QgY291bnRlcnMnKVxuICAgICMgQWRtaW4gU3RvcmUgY29uc3RydWN0aW9uIG11c3Qgbm90IHNpbGVudGx5IGFsdGVyIHNjaGVtYS9pbnRlZ3JpdHkvY291bnRlcnMuXG4gICAgcG9zdCA9IGRvY2tlcihvcHRpb25zICsgWyctLWVudHJ5cG9pbnQnLCAncHl0aG9uJywgSU1BR0UsICctJywgJy0tZGInLCAnL3Jlc3RvcmUvcmV2aWV3LnNxbGl0ZSddLFxuICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShwb3N0LnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgcG9zdC1hZG1pbiByZWFkb25seSBpbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkJylcbiAgICBwb3N0X2NoZWNrZWQgPSBjb3VudHMoanNvbi5sb2Fkcyhwb3N0LnN0ZG91dCkpXG4gICAgcmVxdWlyZShwb3N0X2NoZWNrZWQgPT0gY2hlY2tlZCA9PSBwcmV2aW91c1snc25hcHNob3RfcmVhZG9ubHknXSxcbiAgICAgICAgICAgICdvZmZsaW5lIGFkbWluIGFsdGVyZWQgZnJvemVuIHNuYXBzaG90IHByb29mJylcbiAgICBwcml2YXRlKHNuYXBzaG90KVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdvcmlnaW5hbCBwcm90ZWN0ZWQgc25hcHNob3QgY2hhbmdlZCBkdXJpbmcgZHJpbGwnKVxuICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdvZmZsaW5lX3ZvbHVtZSc6IFZPTFVNRSwgJ29mZmxpbmVfcmVhZG9ubHknOiBjaGVja2VkLFxuICAgICAgICAgICAgJ29mZmxpbmVfcG9zdF9hZG1pbl9yZWFkb25seSc6IHBvc3RfY2hlY2tlZCwgJ29yaWdpbmFsX3NuYXBzaG90X2hhc2hfdW5jaGFuZ2VkJzogVHJ1ZSxcbiAgICAgICAgICAgICdjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eSc6IGlkZW50aXR5LFxuICAgICAgICAgICAgJ2FkbWluX2NvdW50cyc6IGFkbWluX2NvdW50cywgJ25ldHdvcmsnOiAnbm9uZScsICdydW50aW1lX3Rva2Vuc19vcl9jb25maWdfbW91bnRlZCc6IEZhbHNlLFxuICAgICAgICAgICAgJ3NlcnZpY2VfZW50cnlwb2ludF9zdGFydGVkJzogRmFsc2UsICdvcmlnaW5hbF9zbmFwc2hvdF9yZXRhaW5lZCc6IFRydWV9XG5cblxuZGVmIGNsZWFudXBfb2ZmbGluZShqb3VybmFsKTpcbiAgICBpbnNwZWN0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnaW5zcGVjdCcsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShpbnNwZWN0ZWQucmV0dXJuY29kZSA9PSAwLCAnb3duZWQgZGlzcG9zYWJsZSB2b2x1bWUgaWRlbnRpdHkgdW52ZXJpZmllZCcpXG4gICAgdmFsdWUgPSBqc29uLmxvYWRzKGluc3BlY3RlZC5zdGRvdXQpXG4gICAgZXhwZWN0ZWQgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydvZmZsaW5lLXZlcmlmeSddWydyZXN1bHQnXVsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknXVxuICAgIHJlcXVpcmUobGVuKHZhbHVlKSA9PSAxIGFuZCB7a2V5OiB2YWx1ZVswXS5nZXQoa2V5KSBmb3Iga2V5IGluIGV4cGVjdGVkfSA9PSBleHBlY3RlZFxuICAgICAgICAgICAgYW5kIG5vdCB2YWx1ZVswXS5nZXQoJ09wdGlvbnMnKSwgJ3ZvbHVtZSBvd25lcnNoaXAvcmVjcmVhdGlvbiBjaGFuZ2VkJylcbiAgICByZW1vdmVkID0gZG9ja2VyKFsndm9sdW1lJywgJ3JtJywgVk9MVU1FXSlcbiAgICByZXF1aXJlKHJlbW92ZWQucmV0dXJuY29kZSA9PSAwIGFuZCByZW1vdmVkLnN0ZG91dC5zdHJpcCgpID09IFZPTFVNRVxuICAgICAgICAgICAgYW5kIGRvY2tlcihbJ3ZvbHVtZScsICdpbnNwZWN0JywgVk9MVU1FXSkucmV0dXJuY29kZSAhPSAwLFxuICAgICAgICAgICAgJ2NsZWFudXAgb3V0Y29tZSBhbWJpZ3VvdXM7IGRvIG5vdCByZXRyeScpXG4gICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ29ubHlfZGlzcG9zYWJsZV9vZmZsaW5lX3ZvbHVtZV9yZW1vdmVkJzogVk9MVU1FLFxuICAgICAgICAgICAgJ25hdGl2ZV9hbmRfb2ZmY2x1c3Rlcl9vcmlnaW5hbF9zbmFwc2hvdHNfcmV0YWluZWQnOiBUcnVlfVxuXG5cbmRlZiBtYWluKCk6XG4gICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249X19kb2NfXylcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXBoYXNlJywgY2hvaWNlcz1QSEFTRVMsIHJlcXVpcmVkPVRydWUpXG4gICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1yb290LWF1dGhvcml0eS1yZWNlaXB0JywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tcm9vdC1uYXRpdmUtb3V0Y29tZScsIHR5cGU9UGF0aCwgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yZXZpc2lvbicsIHJlcXVpcmVkPVRydWUpXG4gICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKClcbiAgICByZXF1aXJlKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdCA9PSBQYXRoKCcvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1yb290LWF1dGhvcml0eS5qc29uJylcbiAgICAgICAgICAgIGFuZCBhcmdzLnJvb3RfbmF0aXZlX291dGNvbWUgPT0gUGF0aCgnL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2UtbmF0aXZlLW91dGNvbWUtbGF0ZXN0Lmpzb24nKSxcbiAgICAgICAgICAgICdmaXhlZCBzdXBlcnZpc2VkIHJlY2VpcHQgcGF0aHMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInWzAtOWEtZl17NDB9JywgYXJncy5zb3VyY2VfcmV2aXNpb24pIGlzIG5vdCBOb25lLCAnZXhhY3Qgc291cmNlIGNvbW1pdCByZXF1aXJlZCcpXG4gICAgIyBWZXJpZnkgYWxsIHByZXBhcmVkIGV4ZWN1dG9yL2lucHV0IGJ5dGVzIGJlZm9yZSByZWFkaW5nIGF1dGhvcml0eSBvciBkaXNwYXRjaGluZy5cbiAgICBwbGFuID0ganNvbi5sb2FkcygoUk9PVCAvICdleGVjdXRpb24tcGxhbi5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShzZXQocGxhblsnZXhlY3V0b3JfZmlsZXMnXSkgPT0geydhY3R1YXRvci5weScsICdhdXRob3JpdHlfam91cm5hbC5weScsICduYXRpdmVfcHJvZ3JhbS5weScsICdyZWNlaXB0X3NhZmV0eS5weSd9LFxuICAgICAgICAgICAgJ2ZpeGVkIGV4ZWN1dG9yIHNvdXJjZXMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUoc2V0KHBsYW5bJ293bmVyX3NvdXJjZV9maWxlcyddKSA9PSB7J2RlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL3JlZ2lzdHJpZXMuY2FuZGlkYXRlLmpzb24nfSxcbiAgICAgICAgICAgICdmaXhlZCBvd25lciBpbWFnZSBzb3VyY2VzIHJlcXVpcmVkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydleGVjdXRvcl9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHRhcmdldCA9IFJPT1QgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdleGVjdXRvciBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnY2FzZV9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUobm90IFBhdGgocmVsYXRpdmUpLmlzX2Fic29sdXRlKCkgYW5kICcuLicgbm90IGluIFBhdGgocmVsYXRpdmUpLnBhcnRzLFxuICAgICAgICAgICAgICAgICdjYXNlIHNvdXJjZSBwYXRoIGVzY2FwZWQnKVxuICAgICAgICB0YXJnZXQgPSBDQVNFIC8gcmVsYXRpdmVcbiAgICAgICAgcmVxdWlyZShub3QgdGFyZ2V0LmlzX3N5bWxpbmsoKSBhbmQgc2hhKHRhcmdldCkgPT0gZGlnZXN0LCAnY2FzZSBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgdGFyZ2V0ID0gT1dORVIgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdvd25lciBpbWFnZS1vbmx5IHNvdXJjZSBjaGFuZ2VkJylcbiAgICAgICAgY29tbWl0dGVkID0gc3VicHJvY2Vzcy5ydW4oWydnaXQnLCAnLUMnLCBzdHIoT1dORVIpLCAnc2hvdycsIGFyZ3Muc291cmNlX3JldmlzaW9uICsgJzonICsgcmVsYXRpdmVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlKVxuICAgICAgICByZXF1aXJlKGNvbW1pdHRlZC5yZXR1cm5jb2RlID09IDAgYW5kIGhhc2hsaWIuc2hhMjU2KGNvbW1pdHRlZC5zdGRvdXQpLmhleGRpZ2VzdCgpID09IGRpZ2VzdCxcbiAgICAgICAgICAgICAgICAnY29tbWl0dGVkIG93bmVyIHJlbmRlciBzb3VyY2UgZGlmZmVycyBmcm9tIGFwcHJvdmVkIGlucHV0cycpXG4gICAgaGVhZCA9IHJ1bihbJ2dpdCcsICctQycsIHN0cihPV05FUiksICdyZXYtcGFyc2UnLCAnSEVBRCddKVxuICAgIHJlcXVpcmUoaGVhZC5yZXR1cm5jb2RlID09IDAgYW5kIGhlYWQuc3Rkb3V0LnN0cmlwKCkgPT0gYXJncy5zb3VyY2VfcmV2aXNpb24sICdvd25lciBzb3VyY2UgSEVBRCBkaWZmZXJzJylcbiAgICBmcm9tIGF1dGhvcml0eV9qb3VybmFsIGltcG9ydCBKb3VybmFsLCBhdXRob3JpdHksIG9yaWdpbmFsX2FuY2hvclxuICAgIHByaXZhdGUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0KVxuICAgIHByaXZhdGUoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKVxuICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlY2VpcHQuZ2V0KCduYXRpdmVfb3V0Y29tZV9zaGEyNTYnKSA9PSBzaGEoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKSwgJ25hdGl2ZSBvdXRjb21lIGJ5dGVzIGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ2V4ZWN1dG9yX3BsYW5fc2hhMjU2JykgPT0gc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgJ3Jvb3QgdmVyaWZpZWQgZXhlY3V0b3IgcGxhbiBkaWZmZXJzJylcbiAgICBhcHByb3ZlZCA9IGF1dGhvcml0eShyZWNlaXB0LCBqc29uLmxvYWRzKGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZS5yZWFkX3RleHQoKSksIHNoYShDQVNFIC8gJ21lbW8uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcmdzLnBoYXNlKVxuICAgIHBhcmVudCA9IENVU1RPRFkucGFyZW50XG4gICAgcHJpdmF0ZShwYXJlbnQsIGRpcmVjdG9yeT1UcnVlKVxuICAgIGlnbm9yZWQgPSBydW4oWydnaXQnLCAnLUMnLCBzdHIoQ1VTVE9ESUFOKSwgJ2NoZWNrLWlnbm9yZScsICctLW5vLWluZGV4Jywgc3RyKENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJyldKVxuICAgIHJlcXVpcmUoaWdub3JlZC5yZXR1cm5jb2RlID09IDAsICdvZmZjbHVzdGVyIGN1c3RvZHkgaXMgbm90IGlnbm9yZWQnKVxuICAgIHJlcXVpcmUoQ1VTVE9EWS5leGlzdHMoKSwgJ29yaWdpbmFsIHByb3RlY3RlZCBjdXN0b2R5IG11c3QgYWxyZWFkeSBleGlzdCcpXG4gICAgcHJpdmF0ZShDVVNUT0RZLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICBjYXBhY2l0eSA9IG9zLnN0YXR2ZnMoQ1VTVE9EWSlcbiAgICByZXF1aXJlKGNhcGFjaXR5LmZfYmF2YWlsICogY2FwYWNpdHkuZl9mcnNpemUgPj0gMiAqIE1BWF9CWVRFUyArIDE2ICogMTAyNCoqMixcbiAgICAgICAgICAgICdpbmRlcGVuZGVudCBwcm90ZWN0ZWQgY3VzdG9keSBoZWFkcm9vbSBpbnN1ZmZpY2llbnQnKVxuICAgIG9zLm1ha2VkaXJzKENVU1RPRFkgLyAnZW1wdHktZG9ja2VyLWNvbmZpZycsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpXG4gICAgcHJpdmF0ZShDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICByZXF1aXJlKG5vdCBsaXN0KChDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKS5pdGVyZGlyKCkpLCAncHVibGljIERvY2tlciByZWFkIGNvbmZpZyBtdXN0IHN0YXkgZW1wdHknKVxuICAgIGFuY2hvciA9IG9yaWdpbmFsX2FuY2hvcihDVVNUT0RZLCBwbGFuWydyZWNvdmVyeSddWydvcmlnaW5hbF9hbmNob3InXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5sb2FkcygoQ0FTRSAvICdvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcbiAgICBpZiBhcmdzLnBoYXNlID09ICdkcmlsbC1jb3B5LXJlc2N1ZS1yMSc6XG4gICAgICAgIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXG4gICAgICAgICAgICAgICAgYW5kIG5vdCBvcy5wYXRoLmxleGlzdHMoQ1VTVE9EWSAvICdjdXRvdmVyLnNxbGl0ZScpLCAncmVzY3VlIGRlc3RpbmF0aW9uIG11c3QgYmUgYWJzZW50JylcbiAgICAgICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgICAgIHJlcXVpcmUoaWRlbnRpdHkucmV0dXJuY29kZSA9PSAwIGFuZCBqc29uLmxvYWRzKGlkZW50aXR5LnN0ZG91dCkgPT0gJ2JudC1sYXAwMDEnLFxuICAgICAgICAgICAgICAgICdsb2NhbCBlbmdpbmUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICAgICAgcmVxdWlyZShsaXN0ZWQucmV0dXJuY29kZSA9PSAwIGFuZCBWT0xVTUUgbm90IGluIGxpc3RlZC5zdGRvdXQuc3BsaXRsaW5lcygpLFxuICAgICAgICAgICAgICAgICdleGlzdGluZyByZXN0b3JlIHZvbHVtZSBmb3JiaWRzIHJlc2N1ZScpXG4gICAgam91cm5hbCA9IEpvdXJuYWwoQ1VTVE9EWSwgeydwcm9wb3NhbCc6IHBsYW5bJ3Byb3Bvc2FsX2lkJ10sICdzb3VyY2VfcmV2aXNpb24nOiBhcmdzLnNvdXJjZV9yZXZpc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWVtb19zaGEyNTYnOiBzaGEoQ0FTRSAvICdtZW1vLmpzb24nKSwgJ3BsYW5fc2hhMjU2Jzogc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZWNvdmVyeV9hbmNob3InOiBhbmNob3J9KVxuICAgIHRyeTpcbiAgICAgICAgam91cm5hbC5zdGFydChhcmdzLnBoYXNlLCBhcHByb3ZlZCkgIyBmc3luY2VkIFJVTk5JTkcgYmVmb3JlIGFueSBwaGFzZSBlZmZlY3QuXG4gICAgICAgIGlmIGFyZ3MucGhhc2UgaW4gKCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsICdjdXRvdmVyLWNvcHknKTpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNvcHlfc25hcHNob3QoYXJncy5waGFzZSwgYXJncy5zb3VyY2VfcmV2aXNpb24sIGFwcHJvdmVkLCBqb3VybmFsKVxuICAgICAgICBlbGlmIGFyZ3MucGhhc2UgPT0gJ29mZmxpbmUtdmVyaWZ5JzpcbiAgICAgICAgICAgIHJlc3VsdCA9IG9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgIGVsaWYgYXJncy5waGFzZSA9PSAnY2xlYW51cC1vZmZsaW5lJzpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNsZWFudXBfb2ZmbGluZShqb3VybmFsKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgcmVzdWx0ID0gcmVtb3RlKGFyZ3MucGhhc2UsIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcHByb3ZlZClcbiAgICAgICAgcmVxdWlyZShvcmlnaW5hbF9hbmNob3IoQ1VTVE9EWSwgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubG9hZHMoKENBU0UgLyAnb3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtYmFja3VwLmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYW5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10pID09IGFuY2hvcixcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkIGpvdXJuYWwgY2hhbmdlZCBkdXJpbmcgbmV3IHBoYXNlJylcbiAgICAgICAgam91cm5hbC5maW5pc2goYXJncy5waGFzZSwgcmVzdWx0KVxuICAgICAgICBwcmludChqc29uLmR1bXBzKHJlc3VsdCkpICMgT25seSBjb3VudC9oYXNoL2lkZW50aXR5IHJlY2VpcHRzLCBuZXZlciBzbmFwc2hvdCBieXRlcy5cbiAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICAgICAgc2FmZSA9IHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdwaGFzZSc6IGFyZ3MucGhhc2UsICdmYWlsdXJlX2NsYXNzJzogdHlwZShlcnJvcikuX19uYW1lX18sXG4gICAgICAgICAgICAgICAgJ2ZhaWx1cmUnOiAnZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeScsXG4gICAgICAgICAgICAgICAgJ3Jhd19vdXRwdXRfd2l0aGhlbGQnOiBUcnVlfVxuICAgICAgICBpZiBqb3VybmFsLmRhdGFbJ3BoYXNlcyddLmdldChhcmdzLnBoYXNlLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdSVU5OSU5HJzpcbiAgICAgICAgICAgIGpvdXJuYWwuZmluaXNoKGFyZ3MucGhhc2UsIHNhZmUpXG4gICAgICAgIHByaW50KGpzb24uZHVtcHMoc2FmZSkpXG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoMSkgZnJvbSBOb25lXG4gICAgZmluYWxseTpcbiAgICAgICAgam91cm5hbC5jbG9zZSgpXG5cblxuaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzpcbiAgICB0cnk6XG4gICAgICAgIG1haW4oKVxuICAgIGV4Y2VwdCBFeGNlcHRpb246XG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoJ3N1cGVydmlzZWQgZXhlY3V0aW9uIHJlZnVzZWQgYmVmb3JlIHBoYXNlOyByYXcgb3V0cHV0IHdpdGhoZWxkJykgZnJvbSBOb25lXG4iCiAgICB9LAogICAgImF1dGhvcml0eV9qb3VybmFsLnB5IjogewogICAgICAic2hhMjU2IjogIjA1MzU5NzVhZTYzMTIxOWY5MGZjZTdlNTJmOGI1NGU2MWU4YWZkNGVmNjhiYjc0NzM4NjM0NzhmMGY1MTlmNjgiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTdXBlcnZpc2VkIHJlY2VpcHQgYm9va2tlZXBpbmcsIG5vdCBhbiBhdXRoZW50aWNhdGVkIGFwcHJvdmFsIHByb3ZpZGVyLlwiXCJcIlxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgZmNudGxcbmltcG9ydCBoYXNobGliXG5pbXBvcnQganNvblxuaW1wb3J0IG9zXG5pbXBvcnQgcmVcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN0YXRcbmltcG9ydCB1dWlkXG5cbkZPVU5ERVIgPSB7J2tpbmQnOiAncGVyc29uJywgJ3N1Yic6ICd1aWQ9cGxhdGZvcm0tcm9vdCxvdT1wZW9wbGUsZGM9bmV0a2luZ2RvbSxkYz1sb2NhbCd9XG5NRU1PX0lEID0gJ2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxJ1xuUFJPUE9TQUwgPSAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnXG5QSEFTRVMgPSAoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywgJ29mZmxpbmUtdmVyaWZ5JywgJ2NsZWFudXAtb2ZmbGluZScsXG4gICAgICAgICAgJ2N1dG92ZXItYmFja3VwJywgJ2N1dG92ZXItY29weScsICdyZWxlYXNlJywgJ3ZlcmlmeScsICdyb2xsYmFjaycsICdyb2xsYmFjay12ZXJpZnknKVxuXG5cbmRlZiByZXF1aXJlKHZhbHVlLCByZWFzb24pOlxuICAgIGlmIG5vdCB2YWx1ZTpcbiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcihyZWFzb24pXG5cblxuZGVmIHNoYShwYXRoKTpcbiAgICBkaWdlc3QgPSBoYXNobGliLnNoYTI1NigpXG4gICAgd2l0aCBQYXRoKHBhdGgpLm9wZW4oJ3JiJykgYXMgc3RyZWFtOlxuICAgICAgICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6IHN0cmVhbS5yZWFkKDEwMjQqKjIpLCBiJycpOlxuICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZShibG9jaylcbiAgICByZXR1cm4gZGlnZXN0LmhleGRpZ2VzdCgpXG5cblxuZGVmIHByaXZhdGUocGF0aCwgZGlyZWN0b3J5PUZhbHNlKTpcbiAgICBpbmZvID0gUGF0aChwYXRoKS5sc3RhdCgpXG4gICAgcmVxdWlyZSgoc3RhdC5TX0lTRElSKGluZm8uc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKGluZm8uc3RfbW9kZSkpXG4gICAgICAgICAgICBhbmQgaW5mby5zdF91aWQgPT0gb3MuZ2V0dWlkKCkgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpID09ICgwbzcwMCBpZiBkaXJlY3RvcnkgZWxzZSAwbzYwMClcbiAgICAgICAgICAgIGFuZCAoZGlyZWN0b3J5IG9yIGluZm8uc3RfbmxpbmsgPT0gMSksICdwcml2YXRlIG93bmVkIGN1c3RvZHkgcmVxdWlyZWQnKVxuXG5cbmRlZiBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgbWVtb19zaGEsIHNvdXJjZV9yZXZpc2lvbiwgcGhhc2UsIG5vdz1Ob25lKTpcbiAgICBcIlwiXCJSb290IG11c3QgZnJlc2hseSB2ZXJpZnkgbmF0aXZlIG91dGNvbWUgYXQgZml4ZWQgT1JJR0lOIG91dHNpZGUgdGhpcyBoZWxwZXIuXG5cbiAgICBSZWNlaXB0IGZpbGVzL2ZsYWdzIGFyZSBub3Qgc2lnbmVkIGdyYW50cy4gVGhpcyBmdW5jdGlvbiBjaGVja3MgdGhlIGV4YWN0XG4gICAgc3VwZXJ2aXNlZCByZWNlaXB0IHJlbGF0aW9uOyBleGlzdGluZyBoYXJuZXNzL2ZvdW5kZXIgYXV0aG9yaXR5IHJlbWFpbnMgdGhlXG4gICAgYWN0dWFsIHBlcm1pc3Npb24gYm91bmRhcnkuIEl0IG5ldmVyIGF1dGhlbnRpY2F0ZXMgYSBjYWxsZXIgYXMgaHVtYW4uXG4gICAgXCJcIlwiXG4gICAgbm93ID0gbm93IG9yIGRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpXG4gICAgcmVxdWlyZShwaGFzZSBpbiBQSEFTRVMsICdmaXhlZCBwaGFzZSByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShyZWNlaXB0LmdldCgncHJvcG9zYWxfaWQnKSA9PSBQUk9QT1NBTCBhbmQgcmVjZWlwdC5nZXQoJ21lbW9faWQnKSA9PSBNRU1PX0lEXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ21lbW9fdmVyc2lvbicpID09IDIgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX3NoYTI1NicpID09IG1lbW9fc2hhXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3NvdXJjZV9yZXZpc2lvbicpID09IHNvdXJjZV9yZXZpc2lvblxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhY3RpdmF0aW9uJykgPT0gJ0FQUFJPVkVEJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhdXRob3JpdHlfbW9kZScpID09ICdBRE1JTklTVEVSJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCd0YXJnZXQnKSA9PSAncmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbidcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgndmVyaWZpY2F0aW9uX21ldGhvZCcpID09ICdyb290LWZpeGVkLW9yaWdpbi1uYXRpdmUtcmVhZGJhY2snXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3J1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudCcpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ291dGNvbWVfcXVlcnknKSA9PSAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgJ2V4YWN0IGV4dGVybmFsbHkgdmVyaWZpZWQgc3VwZXJ2aXNlZCByZWNlaXB0IHJlcXVpcmVkJylcbiAgICB2ZXJpZmllZCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQocmVjZWlwdFsndmVyaWZpZWRfYXQnXS5yZXBsYWNlKCdaJywgJyswMDowMCcpKVxuICAgIHJlcXVpcmUodmVyaWZpZWQudHppbmZvIGlzIG5vdCBOb25lIGFuZCAwIDw9IChub3cgLSB2ZXJpZmllZCkudG90YWxfc2Vjb25kcygpIDw9IDEyMCxcbiAgICAgICAgICAgICdmcmVzaCByb290IG5hdGl2ZSByZWFkYmFjayByZXF1aXJlZCBiZWZvcmUgZXZlcnkgcGhhc2UnKVxuICAgIGRlYWRsaW5lID0gZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdCgnMjAyNi0xMC0xMlQyMzo1OTo1OSswMDowMCcpXG4gICAgcmVxdWlyZShub3cgPCBkZWFkbGluZSwgJ2FwcHJvdmVkIGV4ZWN1dGlvbiB3aW5kb3cgZXhwaXJlZCcpXG4gICAgcmVxdWlyZShvdXRjb21lLmdldCgnbWVtb19pZCcpID09IE1FTU9fSUQgYW5kIG91dGNvbWUuZ2V0KCdyZXZpZXcnLCB7fSkuZ2V0KCdzdGFsZScpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgb3V0Y29tZVsncmV2aWV3J10uZ2V0KCdpbnRha2Vfc3RhdGUnKSA9PSAncmVhZHknLCAnbmF0aXZlIHJldmlldyBpcyBub3QgcmVhZHkvY3VycmVudCcpXG4gICAgcmV2aWV3X2lkID0gb3V0Y29tZVsncmV2aWV3J11bJ21lbW9faWQnXVxuICAgIHJlcXVpcmUocmV2aWV3X2lkID09IHJlY2VpcHQuZ2V0KCdyZXZpZXdfbWVtb19pZCcpLCAnbmF0aXZlIHJldmlldyBpZGVudGl0eSBjaGFuZ2VkJylcbiAgICBhY2NlcHRlZCA9IFt4IGZvciB4IGluIG91dGNvbWUuZ2V0KCdkaXNwb3NpdGlvbnMnLCBbXSlcbiAgICAgICAgICAgICAgICBpZiB4LmdldCgnc3VibWlzc2lvbl9zdGF0ZScpID09ICdjb25maXJtZWQnXG4gICAgICAgICAgICAgICAgYW5kIHguZ2V0KCdkaXNwb3NpdGlvbicsIHt9KS5nZXQoJ3ZlcmInKSA9PSAnYWNjZXB0J1xuICAgICAgICAgICAgICAgIGFuZCB4WydkaXNwb3NpdGlvbiddLmdldCgnbWVtb192ZXJzaW9uJykgPT0gMV1cbiAgICByZXF1aXJlKGxlbihhY2NlcHRlZCkgPT0gMSwgJ29uZSBjb25maXJtZWQgZm91bmRlciBhY2NlcHRhbmNlIHJlcXVpcmVkJylcbiAgICBhY2NlcHRlZCA9IGFjY2VwdGVkWzBdWydkaXNwb3NpdGlvbiddXG4gICAgcmVxdWlyZShhY2NlcHRlZC5nZXQoJ2FjdG9yJykgPT0gRk9VTkRFUiBhbmQgYWNjZXB0ZWQuZ2V0KCdtZW1vX2lkJykgPT0gcmV2aWV3X2lkXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhcHByb3ZhbF9pZCcpID09IHJlY2VpcHQuZ2V0KCdhcHByb3ZhbF9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdpZCcpID09IHJlY2VpcHQuZ2V0KCdkaXNwb3NpdGlvbl9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhdCcpID09IHJlY2VpcHQuZ2V0KCdhY2NlcHRlZF9hdCcpLCAnZXhhY3QgZm91bmRlciBkaXNwb3NpdGlvbiBtaXNtYXRjaCcpXG4gICAgcmVxdWlyZShyZS5mdWxsbWF0Y2gocidbYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2FwcHJvdmFsX2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHInZGlzcC1bYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHIncmV2aWV3LVthLWYwLTktXXszNn0nLCByZXZpZXdfaWQpIGlzIG5vdCBOb25lLFxuICAgICAgICAgICAgJ25hdGl2ZSBkaXNwb3NpdGlvbiBpZGVudGlmaWVycyBhcmUgbWFsZm9ybWVkJylcbiAgICBhY2NlcHRlZF9hdCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQoYWNjZXB0ZWRbJ2F0J10ucmVwbGFjZSgnWicsICcrMDA6MDAnKSlcbiAgICByZXF1aXJlKGFjY2VwdGVkX2F0LnR6aW5mbyBpcyBub3QgTm9uZSBhbmQgYWNjZXB0ZWRfYXQgPD0gdmVyaWZpZWQsICdhY2NlcHRhbmNlIHRpbWUgbm90IGJvdW5kZWQnKVxuICAgIHJldHVybiB7a2V5OiByZWNlaXB0W2tleV0gZm9yIGtleSBpbiAoJ2FwcHJvdmFsX2lkJywgJ2Rpc3Bvc2l0aW9uX2lkJywgJ2FjY2VwdGVkX2F0JywgJ3ZlcmlmaWVkX2F0Jyl9XG5cblxuZGVmIG9yaWdpbmFsX2FuY2hvcihwYXJlbnQsIGV4cGVjdGVkLCBiYWNrdXBfcmVzdWx0LCBvcmlnaW5hbF9pZGVudGl0eSk6XG4gICAgXCJcIlwiUmVhZCBvbmx5IHNhbml0aXplZCBvcmlnaW5hbCBqb3VybmFsOyBuZXZlciByZXdyaXRlL3N5bnRoZXNpemUgaXRzIHBoYXNlcy5cIlwiXCJcbiAgICBwYXRoID0gUGF0aChwYXJlbnQpIC8gJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nXG4gICAgcHJpdmF0ZShwYXRoKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBieXRlcyBjaGFuZ2VkJylcbiAgICBvcmlnaW5hbCA9IGpzb24ubG9hZHMocGF0aC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKG9yaWdpbmFsLmdldCgnaWRlbnRpdHknKSA9PSBvcmlnaW5hbF9pZGVudGl0eSwgJ29yaWdpbmFsIGFwcHJvdmVkIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHBoYXNlcyA9IG9yaWdpbmFsLmdldCgncGhhc2VzJywge30pXG4gICAgcmVxdWlyZShzZXQocGhhc2VzKSA9PSB7J2RyaWxsLWJhY2t1cCcsICdkcmlsbC1jb3B5J30sICd1bmV4cGVjdGVkIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0JylcbiAgICBmb3IgbmFtZSwgZmllbGRzIGluIGV4cGVjdGVkWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUoYWxsKHBoYXNlc1tuYW1lXS5nZXQoa2V5KSA9PSB2YWx1ZSBmb3Iga2V5LHZhbHVlIGluIGZpZWxkcy5pdGVtcygpKSxcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkL2NvbXBsZXRlZCBhdHRlbXB0IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocGhhc2VzWydkcmlsbC1iYWNrdXAnXS5nZXQoJ3Jlc3VsdCcpID09IGJhY2t1cF9yZXN1bHRcbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZVxuICAgICAgICAgICAgYW5kIHBoYXNlc1snZHJpbGwtY29weSddLmdldCgncmVzdWx0Jywge30pLmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgRmFsc2UsXG4gICAgICAgICAgICAnb3JpZ2luYWwgYmFja3VwL2NvcHkgb3V0Y29tZSBjaGFuZ2VkJylcbiAgICByZXF1aXJlKGJhY2t1cF9yZXN1bHQuZ2V0KCdzbmFwc2hvdF9zaGEyNTYnKSA9PSBleHBlY3RlZFsnc25hcHNob3Rfc2hhMjU2J11cbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnc25hcHNob3RfYnl0ZXMnKSA9PSBleHBlY3RlZFsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIGJhY2t1cF9yZXN1bHQuZ2V0KCdwb2RfdWlkJykgPT0gJ2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNycsXG4gICAgICAgICAgICAnb3JpZ2luYWwgZnJvemVuIHNuYXBzaG90IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBjaGFuZ2VkIGR1cmluZyByZWFkJylcbiAgICByZXR1cm4geydvcmlnaW5hbF9qb3VybmFsX3NoYTI1Nic6IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLFxuICAgICAgICAgICAgJ29yaWdpbmFsX2NvcHlfYXR0ZW1wdF9pZCc6IHBoYXNlc1snZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnb3JpZ2luYWxfYmFja3VwX2F0dGVtcHRfaWQnOiBwaGFzZXNbJ2RyaWxsLWJhY2t1cCddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnYmFja3VwX3Jlc3VsdCc6IGJhY2t1cF9yZXN1bHQsICdvbGRfdW5jZXJ0YWluX3BoYXNlX3JldGFpbmVkJzogVHJ1ZX1cblxuXG5jbGFzcyBKb3VybmFsOlxuICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXJlbnQsIGlkZW50aXR5KTpcbiAgICAgICAgc2VsZi5wYXJlbnQgPSBQYXRoKHBhcmVudClcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCwgZGlyZWN0b3J5PVRydWUpXG4gICAgICAgIHNlbGYucGF0aCA9IHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tam91cm5hbC1yMS5qc29uJ1xuICAgICAgICBzZWxmLmxvY2sgPSBvcy5vcGVuKHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tcjEubG9jaycsIG9zLk9fQ1JFQVQgfCBvcy5PX05PRk9MTE9XIHwgb3MuT19SRFdSLCAwbzYwMClcbiAgICAgICAgZmNudGwuZmxvY2soc2VsZi5sb2NrLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQilcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCAvICdyZXNjdWUtZXhlY3V0aW9uLXIxLmxvY2snKVxuICAgICAgICBpZiBzZWxmLnBhdGguZXhpc3RzKCk6XG4gICAgICAgICAgICBwcml2YXRlKHNlbGYucGF0aClcbiAgICAgICAgICAgIHNlbGYuZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5wYXRoLnJlYWRfdGV4dCgpKVxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ2lkZW50aXR5J10gPT0gaWRlbnRpdHksICdqb3VybmFsIGNhc2Uvc291cmNlIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgc2VsZi5kYXRhID0geydpZGVudGl0eSc6IGlkZW50aXR5LCAncGhhc2VzJzoge319XG4gICAgICAgICAgICBzZWxmLnNhdmUoKVxuXG4gICAgZGVmIHNhdmUoc2VsZik6XG4gICAgICAgIHRlbXBvcmFyeSA9IHNlbGYucGFyZW50IC8gJ2V4ZWN1dGlvbi1qb3VybmFsLm5ldydcbiAgICAgICAgZmQgPSBvcy5vcGVuKHRlbXBvcmFyeSwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1cgfCBvcy5PX1dST05MWSwgMG82MDApXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAndycpIGFzIHN0cmVhbTpcbiAgICAgICAgICAgICAgICBqc29uLmR1bXAoc2VsZi5kYXRhLCBzdHJlYW0sIGluZGVudD0yKVxuICAgICAgICAgICAgICAgIHN0cmVhbS53cml0ZSgnXFxuJylcbiAgICAgICAgICAgICAgICBzdHJlYW0uZmx1c2goKVxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKHN0cmVhbS5maWxlbm8oKSlcbiAgICAgICAgICAgIG9zLnJlcGxhY2UodGVtcG9yYXJ5LCBzZWxmLnBhdGgpXG4gICAgICAgICAgICBkaXJlY3RvcnkgPSBvcy5vcGVuKHNlbGYucGFyZW50LCBvcy5PX0RJUkVDVE9SWSB8IG9zLk9fUkRPTkxZKVxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIGZpbmFsbHk6XG4gICAgICAgICAgICAgICAgb3MuY2xvc2UoZGlyZWN0b3J5KVxuICAgICAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbjpcbiAgICAgICAgICAgICMgUmV0YWluIGV2aWRlbmNlIHJhdGhlciB0aGFuIG92ZXJ3cml0aW5nIGFuIHVuY2VydGFpbiBkdXJhYmxlIGludGVudC5cbiAgICAgICAgICAgIHJhaXNlXG5cbiAgICBkZWYgc3RhcnQoc2VsZiwgcGhhc2UsIGFwcHJvdmFsKTpcbiAgICAgICAgcmVxdWlyZShwaGFzZSBub3QgaW4gc2VsZi5kYXRhWydwaGFzZXMnXSwgJ2FscmVhZHkgYXR0ZW1wdGVkIHBoYXNlOyBubyByZXRyeScpXG4gICAgICAgIHJlcXVpcmUocGhhc2UgaW4gUEhBU0VTLCAnZml4ZWQgcmVzY3VlIG9yIHJlbWFpbmluZyBwaGFzZSByZXF1aXJlZCcpXG4gICAgICAgIHByZWRlY2Vzc29ycyA9IGRpY3QoemlwKFBIQVNFU1sxOjddLCBQSEFTRVNbOjZdKSlcbiAgICAgICAgcHJlZGVjZXNzb3JzWydyb2xsYmFjay12ZXJpZnknXSA9ICdyb2xsYmFjaydcbiAgICAgICAgaWYgcGhhc2UgaW4gcHJlZGVjZXNzb3JzOlxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ3BoYXNlcyddLmdldChwcmVkZWNlc3NvcnNbcGhhc2VdLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdDT01QTEVURScsXG4gICAgICAgICAgICAgICAgICAgICdwcmVjZWRpbmcgcGhhc2UgaXMgbm90IHZlcmlmaWVkIGNvbXBsZXRlJylcbiAgICAgICAgaWYgcGhhc2UgPT0gJ3JvbGxiYWNrJzpcbiAgICAgICAgICAgIHJlcXVpcmUoJ3JlbGVhc2UnIGluIHNlbGYuZGF0YVsncGhhc2VzJ10sICdyb2xsYmFjayByZXF1aXJlcyBhIHJlY29yZGVkIHJlbGVhc2UgYXR0ZW1wdCcpXG4gICAgICAgIHNlbGYuZGF0YVsncGhhc2VzJ11bcGhhc2VdID0geydzdGF0ZSc6ICdSVU5OSU5HJywgJ2FwcHJvdmFsJzogYXBwcm92YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhdHRlbXB0X2lkJzogc3RyKHV1aWQudXVpZDQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdGFydGVkX2F0JzogZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0YykuaXNvZm9ybWF0KCl9XG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgbm90ZShzZWxmLCBwaGFzZSwga2V5LCB2YWx1ZSk6XG4gICAgICAgIHJlcXVpcmUoc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1bJ3N0YXRlJ10gPT0gJ1JVTk5JTkcnLCAncGhhc2UgaW50ZW50IG1pc3NpbmcnKVxuICAgICAgICBzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVtrZXldID0gdmFsdWVcbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBmaW5pc2goc2VsZiwgcGhhc2UsIHJlc3VsdCk6XG4gICAgICAgIGVudHJ5ID0gc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1cbiAgICAgICAgcmVxdWlyZShlbnRyeVsnc3RhdGUnXSA9PSAnUlVOTklORycsICdwaGFzZSBpbnRlbnQgbWlzc2luZycpXG4gICAgICAgIGVudHJ5WydyZXN1bHQnXSA9IHJlc3VsdFxuICAgICAgICBlbnRyeVsnc3RhdGUnXSA9ICdDT01QTEVURScgaWYgcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZSBlbHNlICdVTkNFUlRBSU4nXG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgY2xvc2Uoc2VsZik6XG4gICAgICAgIG9zLmNsb3NlKHNlbGYubG9jaylcbiIKICAgIH0sCiAgICAiZXhlY3V0aW9uLXBsYW4uanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICI5Y2U1NzI4YTU2MWU2ZDM4Zjg0OTcyMDFiYWEyYjg0MGQxMTQ0NGEwYWY4YWQ2MjM0ZGZjMzc0MjgxMTNmMjU4IiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcImtpbmRcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi5zdXBlcnZpc2VkLW1lY2hhbmljYWwtcmVsZWFzZS1wbGFuXCIsXG4gIFwidmVyc2lvblwiOiAyLFxuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcInN0YXRlXCI6IFwicHJlcGFyZWQtdW5hcHByb3ZlZFwiLFxuICBcImV4ZWN1dG9yX2ZpbGVzXCI6IHtcbiAgICBcImFjdHVhdG9yLnB5XCI6IFwiODZiNjdkMWFiYWQ2YWYyYThjNDk1MjhmZTEyNWE1YmFiOTQ0OTc1ZDNlODAxODI2YzUxMWVlODg4NDY1NzFiMlwiLFxuICAgIFwiYXV0aG9yaXR5X2pvdXJuYWwucHlcIjogXCIwNTM1OTc1YWU2MzEyMTlmOTBmY2U3ZTUyZjhiNTRlNjFlOGFmZDRlZjY4YmI3NDczODYzNDc4ZjBmNTE5ZjY4XCIsXG4gICAgXCJuYXRpdmVfcHJvZ3JhbS5weVwiOiBcIjc4OGRjOTlmN2VkZmJmZDU0MmEzYmIwOGZjMzFmNjBjYWY0ZjhmZDVkNjU0YTZhOTFiNDVlMTk3ZWNmZjlmOTFcIixcbiAgICBcInJlY2VpcHRfc2FmZXR5LnB5XCI6IFwiNWM1NDM3M2YyZGM0YjA2NDAwODIyNWMxODZlZmIxZDVhZmRlZWMzNmQxNTM1MGJkYTBhMTJkZWQ5NzYwMmQxYlwiXG4gIH0sXG4gIFwiY2FzZV9maWxlc1wiOiB7XG4gICAgXCJjaGFuZ2VfZ3VhcmQucHlcIjogXCJmMzQ4ZTQ0OWM0OWY0ZDllNDlhZjllODJlMDE3NjRlNzE5NzgzN2ZkM2RmOWQ3NTZmNTg5MWQ5YjhkOWIzOGJlXCIsXG4gICAgXCJzcWxpdGVfcmVhZG9ubHkucHlcIjogXCI5MDkzYzY0ZjdmMGUzOWIyNDlkYTlmZWZkZjVhYWY0ZTQyNThiYzMxZTdhMjdmZDg4ODQ3OWNlMzI5YTIwNTA5XCIsXG4gICAgXCJwcmVmbGlnaHQtaW5wdXRzLmpzb25cIjogXCIwM2JiNGI0MmZlMWFhNTFiODQ2ZTk1N2E5ZTIzOTI2ZmFlNzJmMDJhMmNiNWUyOTczNjgwNDdmYjI1YzE3ZTliXCIsXG4gICAgXCJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb25cIjogXCJkMThkMjcwNjNkMDZmNTM1YWU4ODRlYTAxZjk2NzQ3ZmUzMDE2ODU1MThhYjk0YjFjYmEwNzJhMWUxNTE5MzYyXCIsXG4gICAgXCJzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uXCI6IFwiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OVwiLFxuICAgIFwiY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvblwiOiBcIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGVcIixcbiAgICBcInJvbGxiYWNrLWRlcGxveW1lbnQuanNvblwiOiBcIjM5YjNmNDNiYjg0ZWY0OTIxY2MzYTFmYmNkYzQ0NDYxMDc0MWVkODgwOTE0OWQ4ZjhmMTdlZDgwNWYyNjIxMjFcIixcbiAgICBcImNoZWNrX2luc3RhbGxlZC5weVwiOiBcImEzNGE1MWJlOWM5ZjJiMTZhMDZhODgxNzNiNWM2YzQ5MmM5OTU3ZmUwMjFjZjQxMmE4NmExNzM3NzMwNjQwYWRcIixcbiAgICBcInB1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvblwiOiBcImU1OWFiNDRiMWFhZjI4MTQwNTA5NTkzYWFlNGFiOWI5N2FiNjJjYzhiNTg5ZTNmMTU1MmJhYzc4NjE4ODk2ZGRcIixcbiAgICBcInNlY3VyaXR5LXN1bW1hcnkuanNvblwiOiBcIjBlZTU2NDAwZGM3MDNmN2M5OTY4YzJhMGEzZWEwMzkwZDgzNjJmOGQwYmJmODAwMmEyYmQ3ZmE1OGYxOWNiNDRcIixcbiAgICBcIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWJhY2t1cC5qc29uXCI6IFwiMDI1ZGRkZjFlOTM5MzZmMzFlOThiOWZiZmE4NGFhMmJkYWFhMzM1NzNmOWQzYjBlMzJkOTQ3ZmQyODZiMTcwZVwiLFxuICAgIFwib3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtY29weS1mYWlsdXJlLmpzb25cIjogXCJmYjc4ZmIyZThjM2Q0MTY0OTBjZjBmNTU5YjJmNWJkMDE5NDA2YTQ5MGY4ZjVmYTZmNTkzMjQyMWYwYjFhYzU2XCIsXG4gICAgXCJvcmlnaW5hbC1qb3VybmFsLXNhbml0aXplZC1hbmNob3IuanNvblwiOiBcIjk4OGZjYTYxYWQ4ZWI5ZDQzZDkzMzkwYTgzNTMyM2Y5NTIxOTZiYmNlOGNjMGJkZTUxYzQyYTE3ZDQxMWY0NTRcIlxuICB9LFxuICBcIm93bmVyX3NvdXJjZV9maWxlc1wiOiB7XG4gICAgXCJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvblwiOiBcIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTVcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvblwiOiBcIjM4Yjc4YjljYmVlNWFkZTc3NTBhNThkNTE1NmNhNGM1NzczMzUyZTk0N2FjYjMwNGVlNzE0YjU5ZTc0OWNlYjRcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUva3VzdG9taXphdGlvbi55YW1sXCI6IFwiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0N1wiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uXCI6IFwiOWJhZDZkYjVmYmMyMTc4ZDMxYjA0MTIwMDE2YTQxODMwYzM1NTJmYmI5ZTI1MTdiNzE4ZjliYmU4N2NmNjQ5ZVwiXG4gIH0sXG4gIFwiY2FuZGlkYXRlX2ltYWdlXCI6IFwiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhXCIsXG4gIFwicHJpb3JfaW1hZ2VcIjogXCJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcIixcbiAgXCJzb3VyY2VfcmV2aXNpb25cIjogXCJtdXN0LWJlLWV4YWN0LWZpbmFsLW93bmVyLUhFQUQtd2l0aC1hcHByb3ZlZC1mb3VyLUdpdC1ibG9ic1wiLFxuICBcInBoYXNlc1wiOiBbXG4gICAgXCJkcmlsbC1jb3B5LXJlc2N1ZS1yMVwiLFxuICAgIFwib2ZmbGluZS12ZXJpZnlcIixcbiAgICBcImNsZWFudXAtb2ZmbGluZVwiLFxuICAgIFwiY3V0b3Zlci1iYWNrdXBcIixcbiAgICBcImN1dG92ZXItY29weVwiLFxuICAgIFwicmVsZWFzZVwiLFxuICAgIFwidmVyaWZ5XCIsXG4gICAgXCJyb2xsYmFja1wiLFxuICAgIFwicm9sbGJhY2stdmVyaWZ5XCJcbiAgXSxcbiAgXCJhdXRob3JpemF0aW9uXCI6IFwiZnJlc2ggZXh0ZXJuYWxseSBhdXRoZW50aWNhdGVkIHJvb3QgZml4ZWQtb3JpZ2luIG5hdGl2ZSByZWFkYmFjayBiZWZvcmUgZWFjaCBwaGFzZTsgZXhhY3QgY29uZmlybWVkIHBsYXRmb3JtLXJvb3QgZGlzcG9zaXRpb24gYW5kIGN1cnJlbnQgcGFja2V0IFNIQS9zb3VyY2UgY29tbWl0OyByZWNlaXB0IGJvb2trZWVwaW5nIGlzIG5vdCBhbiBhdXRvbm9tb3VzIHNpZ25lZCBncmFudFwiLFxuICBcImV4ZWN1dGVfYnlcIjogXCIyMDI2LTEwLTEyVDIzOjU5OjU5WlwiLFxuICBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZSxcbiAgXCJuYXRpdmVfZGF0YV9vcl93b3JrbG9hZF9hY3Rpb25fZXhlY3V0ZWRcIjogZmFsc2UsXG4gIFwiZGVhZGxpbmVfc2VtYW50aWNzXCI6IFwiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LlwiLFxuICBcInJlY292ZXJ5XCI6IHtcbiAgICBcIm9yaWdpbmFsX2FuY2hvclwiOiB7XG4gICAgICBcIm9yaWdpbmFsX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICAgICAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgICAgIFwiZHJpbGwtYmFja3VwXCI6IHtcbiAgICAgICAgICBcInN0YXRlXCI6IFwiQ09NUExFVEVcIixcbiAgICAgICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgICAgICBcInN0YXJ0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM4OjQ1LjMxMDY1MyswMDowMFwiXG4gICAgICAgIH0sXG4gICAgICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICAgICAgXCJzdGF0ZVwiOiBcIlVOQ0VSVEFJTlwiLFxuICAgICAgICAgIFwiYXR0ZW1wdF9pZFwiOiBcIjMyOWVmMTkwLTE2OTItNDI0Ni1iOTUzLWU2YTU5NjY0YWJjY1wiLFxuICAgICAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgICAgIFwic25hcHNob3Rfc2hhMjU2XCI6IFwiODc1NmNmODI1ZGY5ZTdiNWI3NGJiNGEwMTA2YTUwMjdmNWNmZjJjNTlmZjQ1ZDdiNDhlZWQ4NTIyYTdkMzNmM1wiLFxuICAgICAgXCJzbmFwc2hvdF9ieXRlc1wiOiAxOTUzNzkyMCxcbiAgICAgIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gICAgICBcIm9sZF91bmNlcnRhaW5fcmV0cnlfYXV0aG9yaXplZFwiOiBmYWxzZVxuICAgIH0sXG4gICAgXCJvcmlnaW5hbF9pZGVudGl0eVwiOiB7XG4gICAgICBcInByb3Bvc2FsXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgICAgIFwic291cmNlX3JldmlzaW9uXCI6IFwiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMFwiLFxuICAgICAgXCJtZW1vX3NoYTI1NlwiOiBcIjUwNmQzOTU2YmViN2M2MmFiMmJiZGZkYTc4M2MwNTkwNWQxODM0NTJhMWY2N2ExODE3ZjNmYjhjMmU1MjI5MzdcIixcbiAgICAgIFwicGxhbl9zaGEyNTZcIjogXCJmNWU1ZmE5MDZmZjE5ZDNhNDVkMTBkY2RiMjgxMDM3M2FlMjFmOWNmNDRjMDQ3MmZmMmJkNDdkM2JjMzMyOGQ2XCJcbiAgICB9LFxuICAgIFwibmV3X2pvdXJuYWxcIjogXCJyZXNjdWUtZXhlY3V0aW9uLWpvdXJuYWwtcjEuanNvblwiLFxuICAgIFwibmV3X3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgICBcIm9sZF91bmNlcnRhaW5fcGhhc2Vfb3ZlcndyaXRlX29yX3JldHJ5XCI6IGZhbHNlLFxuICAgIFwibmV3X3NuYXBzaG90X2JhY2t1cFwiOiBmYWxzZSxcbiAgICBcInNuYXBzaG90X29yX3NpZGVjYXJfbXV0YXRpb25cIjogZmFsc2UsXG4gICAgXCJtYXBwaW5nXCI6IFwib2ZmbGluZS12ZXJpZnkgY29uc3VtZXMgQ09NUExFVEUgZHJpbGwtY29weS1yZXNjdWUtcjEgcmVzdWx0OyBhbGwgbGF0ZXIgcGhhc2VzIG9yZGVyZWQgb25seSBpbiBuZXcgaGFzaC1saW5rZWQgcmVjb3Zlcnkgam91cm5hbFwiXG4gIH0sXG4gIFwic291cmNlX21lbW9fdmVyc2lvblwiOiAyLFxuICBcIm5hdGl2ZV9yZXZpZXdfbWVtb192ZXJzaW9uXCI6IDFcbn1cbiIKICAgIH0sCiAgICAibmF0aXZlX3Byb2dyYW0ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiNzg4ZGM5OWY3ZWRmYmZkNTQyYTNiYjA4ZmMzMWY2MGNhZjRmOGZkNWQ2NTRhNmE5MWI0NWUxOTdlY2ZmOWY5MSIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIkZpeGVkIHZlcnNpb24yIHJlY292ZXJ5IHJlbW90ZSBzb3VyY2U7IHJlcXVpcmVzIGZyZXNoIGV4YWN0IGFjY2VwdGFuY2UuXCJcIlwiXG5QUk9HUkFNID0gJ1xcbmltcG9ydCBjb3B5LGRhdGV0aW1lLGhhc2hsaWIsanNvbixvcyxyZSxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxucGF5bG9hZD1qc29uLmxvYWRzKF9fUEFZTE9BRF9fKVxcbmV4ZWMoX19HVUFSRF9fKVxcbnBoYXNlPXBheWxvYWRbXFwncGhhc2VcXCddXFxuaWYgcGhhc2Ugbm90IGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2tcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2ZpeGVkIG5hdGl2ZSBwaGFzZSByZXF1aXJlZFxcJylcXG5kZWFkbGluZT1kYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KFxcJzIwMjYtMTAtMTJUMjM6NTk6NTkrMDA6MDBcXCcpXFxuZGVmIHJlcXVpcmUodmFsdWUscmVhc29uKTpcXG4gaWYgbm90IHZhbHVlOnJhaXNlIFZhbHVlRXJyb3IocmVhc29uKVxcbnJlcXVpcmUoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0Yyk8ZGVhZGxpbmUsXFwnZXhlY3V0aW9uIHdpbmRvdyBleHBpcmVkXFwnKVxcbmVudj17Kipvcy5lbnZpcm9uLFxcJ0tVQkVDT05GSUdcXCc6XFwnL2V0Yy9yYW5jaGVyL2szcy9rM3MueWFtbFxcJ31cXG5kZWYgcnVuKGFyZ3YsYm9keT1Ob25lLHRpbWVvdXQ9OTApOlxcbiByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndixpbnB1dD1ib2R5LHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlLHRpbWVvdXQ9dGltZW91dCxlbnY9ZW52KVxcbmRlZiByZWFkKGtpbmQsbmFtZSxuYW1lc3BhY2UpOlxcbiByZXN1bHQ9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxraW5kLG5hbWUsXFwnLW5cXCcsbmFtZXNwYWNlLFxcJy1vXFwnLFxcJ2pzb25cXCddKVxcbiByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlPT0wLFxcJ2ZpeGVkIG1ldGFkYXRhIHJlYWQgcmVmdXNlZFxcJylcXG4gcmV0dXJuIGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcXG5zZWFsZWQ9cGF5bG9hZFtcXCdzZWFsZWRcXCddOyBkZXBlbmRlbmNpZXM9cGF5bG9hZFtcXCdkZXBlbmRlbmNpZXNcXCddXFxubGl2ZT1yZWFkKFxcJ2RlcGxveW1lbnRcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY209cmVhZChcXCdjb25maWdtYXBcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxucHZjPXJlYWQoXFwncHZjXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uLWRhdGFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY2hlY2tfZGVwZW5kZW5jaWVzKGNtLHB2YyxkZXBlbmRlbmNpZXMpXFxuYXBwPXJlYWQoXFwnYXBwbGljYXRpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnYXJnb2NkXFwnKVxcbnJlcXVpcmUoYXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddPT1cXCc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGRcXCcsXFwnQXBwbGljYXRpb24gVUlEIGNoYW5nZWRcXCcpXFxucmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdyZXBvVVJMXFwnXT09XFwnaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0XFwnXFxuIGFuZCBhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdwYXRoXFwnXT09XFwnZGVwbG95L2xpZmVjeWNsZVxcJ1xcbiBhbmQgYXBwW1xcJ3NwZWNcXCddW1xcJ2Rlc3RpbmF0aW9uXFwnXT09e1xcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCdzZXJ2ZXJcXCc6XFwnaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjXFwnfVxcbiBhbmQgYXBwW1xcJ3NwZWNcXCddLmdldChcXCdzeW5jUG9saWN5XFwnLHt9KS5nZXQoXFwnYXV0b21hdGVkXFwnKSBpcyBOb25lXFxuIGFuZCBzZXQoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ10pPT17XFwncmVwb1VSTFxcJyxcXCdwYXRoXFwnLFxcJ3RhcmdldFJldmlzaW9uXFwnfSBhbmQgbm90IGFwcFtcXCdzcGVjXFwnXS5nZXQoXFwnc291cmNlc1xcJyksXFwnQXBwbGljYXRpb24gb3duZXIvc2NvcGUgY2hhbmdlZFxcJylcXG5leHBlY3RlZD1jb3B5LmRlZXBjb3B5KHNlYWxlZClcXG5pZiBwaGFzZT09XFwndmVyaWZ5XFwnOmV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOlxcbiBpbWFnZT1saXZlW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ11cXG4gcmVxdWlyZShpbWFnZSBpbiAoQkFTRSxDQU5ESURBVEUpLFxcJ3JvbGxiYWNrIGltYWdlIGlzIG91dHNpZGUgc2FtZS1zY2hlbWEgcGFpclxcJylcXG4gZXhwZWN0ZWRbXFwnc3BlY1xcJ11bXFwndGVtcGxhdGVcXCddW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXT1pbWFnZVxcbmNoZWNrX2N1cnJlbnQobGl2ZSxleHBlY3RlZClcXG5pZiBwaGFzZSE9XFwncm9sbGJhY2tcXCc6XFxuIHJlcXVpcmUobGl2ZS5nZXQoXFwnc3RhdHVzXFwnLHt9KS5nZXQoXFwncmVhZHlSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ3VwZGF0ZWRSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ29ic2VydmVkR2VuZXJhdGlvblxcJyk9PWxpdmVbXFwnbWV0YWRhdGFcXCddW1xcJ2dlbmVyYXRpb25cXCddLFxcJ3NlcnZpY2Ugbm90IFJlYWR5MVxcJylcXG50YXJnZXQ9cGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddIGlmIHBoYXNlPT1cXCd2ZXJpZnlcXCcgZWxzZSBcXCc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmXFwnXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwndGFyZ2V0UmV2aXNpb25cXCddIGluICh0YXJnZXQscGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddKSxcXCdyb2xsYmFjayBzb3VyY2UgaXMgb3V0c2lkZSBwYWlyXFwnKVxcbmVsc2U6cmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ109PXRhcmdldCxcXCd1bmV4cGVjdGVkIHNvdXJjZSBwaW5cXCcpXFxucmVzdWx0PXtcXCdwaGFzZVxcJzpwaGFzZSxcXCdhbGxfY2hlY2tzX3Bhc3NcXCc6RmFsc2UsXFwncmF3X291dHB1dF93aXRoaGVsZFxcJzpUcnVlLFxcbiBcXCduYXRpdmVfYXBwcm92YWxfdmVyaWZpZWRfYnlfcm9vdFxcJzpwYXlsb2FkW1xcJ2FwcHJvdmFsXFwnXSxcXCduYXRpdmVfYXV0aGVudGljYXRlZF9ncmFudFxcJzpGYWxzZX1cXG50cnk6XFxuIGlmIHBoYXNlIGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gIHBvZGxpc3Q9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxcXCdwb2RzXFwnLFxcJy1uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy1sXFwnLFxcJ2FwcC5rdWJlcm5ldGVzLmlvL25hbWU9aW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pXFxuICByZXF1aXJlKHBvZGxpc3QucmV0dXJuY29kZT09MCxcXCdwb2QgbWV0YWRhdGEgcXVlcnkgcmVmdXNlZFxcJylcXG4gIHBvZHM9W3AgZm9yIHAgaW4ganNvbi5sb2Fkcyhwb2RsaXN0LnN0ZG91dClbXFwnaXRlbXNcXCddIGlmIG5vdCBwW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnZGVsZXRpb25UaW1lc3RhbXBcXCcpXVxcbiAgcmVxdWlyZShsZW4ocG9kcyk9PTEsXFwnZXhhY3Qgc2luZ2xlIGxpdmUgb3duZXIgcG9kIHJlcXVpcmVkXFwnKTtwb2Q9cG9kc1swXVxcbiAgcmVxdWlyZShwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwncGhhc2VcXCcpPT1cXCdSdW5uaW5nXFwnIGFuZCBsZW4ocG9kW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddKT09MVxcbiAgIGFuZCBwb2RbXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddPT1leHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddXFxuICAgYW5kIGxlbihwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwnY29udGFpbmVyU3RhdHVzZXNcXCcsW10pKT09MVxcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ25hbWVcXCcpPT1cXCdpbmZvcm1lZC1kZWNpc2lvblxcJ1xcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ3JlYWR5XFwnKSBpcyBUcnVlLFxcJ293bmVyIHBvZCByZWFkaW5lc3MvaW1hZ2UgY2hhbmdlZFxcJylcXG4gIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJzpyZXF1aXJlKHBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09XFwnZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XFwnLFxcJ29yaWdpbmFsIGJhY2t1cCBQb2QgaWRlbnRpdHkgY2hhbmdlZFxcJylcXG4gIHRlbXBsYXRlPWV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVxcbiAgY29udHJvbGxlZD1zZXQodGVtcGxhdGUpfHtcXCdpbml0Q29udGFpbmVyc1xcJyxcXCdob3N0TmV0d29ya1xcJyxcXCdob3N0UElEXFwnLFxcJ2hvc3RJUENcXCcsXFwncnVudGltZUNsYXNzTmFtZVxcJyxcXCdzaGFyZVByb2Nlc3NOYW1lc3BhY2VcXCd9XFxuICByZXF1aXJlKGFsbChwb2RbXFwnc3BlY1xcJ10uZ2V0KGtleSk9PXRlbXBsYXRlLmdldChrZXkpIGZvciBrZXkgaW4gY29udHJvbGxlZCksXFwnYWN0dWFsIG93bmVyIFBvZCBjb25maWd1cmF0aW9uIGRyaWZ0ZWRcXCcpXFxuICBvd25lcnM9cG9kW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnb3duZXJSZWZlcmVuY2VzXFwnLFtdKTtyZXF1aXJlKGxlbihvd25lcnMpPT0xIGFuZCBvd25lcnNbMF1bXFwna2luZFxcJ109PVxcJ1JlcGxpY2FTZXRcXCcsXFwncG9kIG93bmVyIGNoYWluIGNoYW5nZWRcXCcpXFxuICBycz1yZWFkKFxcJ3JlcGxpY2FzZXRcXCcsb3duZXJzWzBdW1xcJ25hbWVcXCddLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbiAgcmVxdWlyZShyc1tcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09b3duZXJzWzBdW1xcJ3VpZFxcJ10gYW5kIGFueShvLmdldChcXCd1aWRcXCcpPT1zZWFsZWRbXFwnbWV0YWRhdGFcXCddW1xcJ3VpZFxcJ11cXG4gICBhbmQgby5nZXQoXFwna2luZFxcJyk9PVxcJ0RlcGxveW1lbnRcXCcgZm9yIG8gaW4gcnNbXFwnbWV0YWRhdGFcXCddLmdldChcXCdvd25lclJlZmVyZW5jZXNcXCcsW10pKSxcXCdSZXBsaWNhU2V0IG93bmVyc2hpcCBjaGFuZ2VkXFwnKVxcbiAgaW5uZXI9clwiXCJcIlxcbmltcG9ydCBoYXNobGliLGpzb24sb3Msc3RhdCxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxuZXhlYyhfX1JFQURPTkxZX18pXFxuZXhlYyhfX1NBRkVUWV9fKVxcbmFjdGlvbj1fX0FDVElPTl9fO2RiPVxcJy9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZVxcJztmb2xkZXI9XFwnL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjFcXCdcXG5kZWYgcmVxdWlyZSh2LHIpOlxcbiBpZiBub3QgdjpyYWlzZSBWYWx1ZUVycm9yKHIpXFxucmVxdWlyZShvcy5nZXR1aWQoKT09MTAwMDEgYW5kIG9zLmdldGdpZCgpPT0xMDAwMSxcXCduYXRpdmUgb3duZXIgVUlEL0dJRCByZXF1aXJlZFxcJylcXG5kZWYgcHJpdmF0ZShwLGRpcmVjdG9yeT1GYWxzZSk6XFxuIHM9b3MubHN0YXQocCk7cmVxdWlyZSgoc3RhdC5TX0lTRElSKHMuc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKHMuc3RfbW9kZSkpXFxuICBhbmQgcy5zdF91aWQ9PTEwMDAxIGFuZCBzdGF0LlNfSU1PREUocy5zdF9tb2RlKT09KDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxcbiAgYW5kIChkaXJlY3Rvcnkgb3Igcy5zdF9ubGluaz09MSksXFwncHJpdmF0ZSBuYXRpdmUgY3VzdG9keSByZXF1aXJlZFxcJylcXG5wcml2YXRlKFxcJy9kYXRhL3ByaXZhdGVcXCcsVHJ1ZSk7cHJpdmF0ZShkYilcXG5iYXNlbGluZT1jb3VudHMoaW5zcGVjdF9yZWFkb25seShkYikpICMgTVVTVCBwcmVjZWRlIGFueSBTdG9yZS9hZG1pbiBvcGVuLlxcbmlmIGFjdGlvbiBpbiAoXFwnY3V0b3Zlci1iYWNrdXBcXCcpOlxcbiBzaXplPW9zLnN0YXQoZGIpLnN0X3NpemVcXG4gaWYgb3MucGF0aC5leGlzdHMoZGIrXFwnLXdhbFxcJyk6c2l6ZSs9b3Muc3RhdChkYitcXCctd2FsXFwnKS5zdF9zaXplXFxuIHY9b3Muc3RhdHZmcyhcXCcvZGF0YS9wcml2YXRlXFwnKTtmcmVlPXYuZl9iYXZhaWwqdi5mX2Zyc2l6ZVxcbiByZXF1aXJlKHNpemU+MCBhbmQgc2l6ZTw9NTEyKjEwMjQqKjIgYW5kIGZyZWU+PXNpemUqKDIgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSAxKSsxNioxMDI0KioyLFxcJ2JvdW5kZWQgbmF0aXZlIHNuYXBzaG90IGNhcGFjaXR5IHJlcXVpcmVkXFwnKVxcbiBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJzpcXG4gIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhmb2xkZXIpLFxcJ25hdGl2ZSBjYXNlIGRpcmVjdG9yeSBtdXN0IGJlIHVuaXF1ZVxcJylcXG4gIG9zLm1rZGlyKGZvbGRlciwwbzcwMCk7b3MuY2htb2QoZm9sZGVyLDBvNzAwKVxcbiBwcml2YXRlKGZvbGRlcixUcnVlKVxcbiBmaWxlbmFtZT1cXCdkcmlsbC5zcWxpdGVcXCcgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSBcXCdjdXRvdmVyLnNxbGl0ZVxcJztvdXRwdXQ9Zm9sZGVyK1xcJy9cXCcrZmlsZW5hbWVcXG4gcmVxdWlyZShub3Qgb3MucGF0aC5sZXhpc3RzKG91dHB1dCksXFwnc25hcHNob3Qgb3V0cHV0IG11c3QgYmUgdW5pcXVlXFwnKVxcbiBhZG1pbj1zdWJwcm9jZXNzLnJ1bihbXFwnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW5cXCcsXFwnYmFja3VwXFwnLFxcJy0tZGJcXCcsZGIsXFwnLS1vdXRwdXRcXCcsb3V0cHV0XSxjYXB0dXJlX291dHB1dD1UcnVlLHRleHQ9VHJ1ZSx0aW1lb3V0PTEyMClcXG4gcmVxdWlyZShhZG1pbi5yZXR1cm5jb2RlPT0wIGFuZCBqc29uLmxvYWRzKGFkbWluLnN0ZG91dCk9PXtcXCdzdGF0dXNcXCc6XFwnYmFja2VkX3VwXFwnLFxcJ2NvbnNpc3RlbnRfc25hcHNob3RcXCc6VHJ1ZX0sXFwnYmFja3VwIGNvbXBsZXRpb24gbm90IHZlcmlmaWVkOyBkbyBub3QgcmV0cnlcXCcpXFxuIHByaXZhdGUob3V0cHV0KVxcbiBmb3Igc3VmZml4IGluIChcXCctd2FsXFwnLCk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnc25hcHNob3QgaGFzIFdBTCBmcmFtZXM7IGltbXV0YWJsZSByZWFkIHJlZnVzZWRcXCcpXFxuIGRpZ2VzdD1oYXNobGliLnNoYTI1NigpXFxuIHdpdGggb3BlbihvdXRwdXQsXFwncmJcXCcpIGFzIHN0cmVhbTpcXG4gIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTpzdHJlYW0ucmVhZCgxMDI0KioyKSxiXFwnXFwnKTpkaWdlc3QudXBkYXRlKGJsb2NrKVxcbiBmcm96ZW5fZGlnZXN0PWRpZ2VzdC5oZXhkaWdlc3QoKVxcbiBzbmFwc2hvdD1jb3VudHMoaW5zcGVjdF9jbG9zZWRfc25hcHNob3Qob3V0cHV0LGZyb3plbl9kaWdlc3QpKVxcbiBzaXplPW9zLnN0YXQob3V0cHV0KS5zdF9zaXplO3JlcXVpcmUoMDxzaXplPD01MTIqMTAyNCoqMixcXCdzbmFwc2hvdCBvdXRzaWRlIGJvdW5kZWQgY29weSBzaXplXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXFwnOmJhc2VsaW5lLFxcJ3NuYXBzaG90X3JlYWRvbmx5XFwnOnNuYXBzaG90LFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfYnl0ZXNcXCc6c2l6ZSxcXCdzbmFwc2hvdF9maWxlXFwnOmZpbGVuYW1lLFxcJ25hdGl2ZV9wYXJlbnRfcHJpdmF0ZVxcJzpUcnVlLFxcJ25hdGl2ZV91aWRcXCc6b3MuZ2V0dWlkKCl9KSlcXG5lbGlmIGFjdGlvbiBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gcHJvb2Y9e1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHNcXCc6YmFzZWxpbmUsXFwnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzXFwnOlRydWV9XFxuIGlmIGFjdGlvbj09XFwndmVyaWZ5XFwnOlxcbiAgaW1wb3J0IHVybGxpYi5yZXF1ZXN0XFxuICBtb2R1bGU9XFwnL29wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24vcG9saWN5LnB5XFwnO2luZm89b3MubHN0YXQobW9kdWxlKVxcbiAgcmVxdWlyZShzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBhbmQgaW5mby5zdF91aWQ9PTAgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpPT0wbzY0NCxcXCdpbnN0YWxsZWQgcG9saWN5IG1ldGFkYXRhIGRpZmZlcnNcXCcpXFxuICB3aXRoIG9wZW4obW9kdWxlLFxcJ3JiXFwnKSBhcyBzb3VyY2U6bW9kdWxlX2RpZ2VzdD1oYXNobGliLnNoYTI1Nihzb3VyY2UucmVhZCgpKS5oZXhkaWdlc3QoKVxcbiAgcmVxdWlyZShtb2R1bGVfZGlnZXN0PT1cXCc5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyXFwnLFxcJ2luc3RhbGxlZCBzb3VyY2UgbW9kdWxlIGRpZmZlcnNcXCcpXFxuICBwdXJwb3NlPXN1YnByb2Nlc3MucnVuKFtzeXMuZXhlY3V0YWJsZSxcXCctXFwnXSxpbnB1dD1fX1BVUlBPU0VfXyx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0aW1lb3V0PTMwKVxcbiAgcmVxdWlyZShwdXJwb3NlLnJldHVybmNvZGU9PTAsXFwnaW5zdGFsbGVkIG5hdGl2ZS1wbGFjZW1lbnQgcHVycG9zZSBjaGVja3MgZmFpbGVkXFwnKVxcbiAgdGVzdGVkPWpzb24ubG9hZHMocHVycG9zZS5zdGRvdXQpXFxuICByZXF1aXJlKHRlc3RlZD09e1xcJ2luc3RhbGxlZF9pbWFnZV9wdXJwb3NlX3ZhcmlhbnRzXFwnOjEwLFxcJ2JpbmRpbmdfZm9ybXNfYWxsb3dlZFxcJzoyLFxcJ2Fkdmlzb3J5X29yX21hbGZvcm1lZF9yZWZ1c2VkXFwnOjgsXFwnc3ludGhldGljX29ubHlcXCc6VHJ1ZSxcXCduYXRpdmVfcHJvdmlkZXJcXCc6RmFsc2V9LFxcJ3B1cnBvc2UgcmVzdWx0IGRpZmZlcnNcXCcpXFxuICBjbGFzcyBOb1JlZGlyZWN0KHVybGxpYi5yZXF1ZXN0LkhUVFBSZWRpcmVjdEhhbmRsZXIpOlxcbiAgIGRlZiByZWRpcmVjdF9yZXF1ZXN0KHNlbGYsKmFyZ3MsKiprd2FyZ3MpOnJhaXNlIFZhbHVlRXJyb3IoXFwnaGVhbHRoIHJlZGlyZWN0IHJlZnVzZWRcXCcpXFxuICBvcGVuZXI9dXJsbGliLnJlcXVlc3QuYnVpbGRfb3BlbmVyKE5vUmVkaXJlY3QoKSk7c3RhdHVzZXM9e31cXG4gIGZvciByb3V0ZSBpbiAoXFwnL2hlYWx0aHpcXCcsXFwnL3JlYWR5elxcJyk6XFxuICAgd2l0aCBvcGVuZXIub3BlbihcXCdodHRwOi8vMTI3LjAuMC4xOjgwODBcXCcrcm91dGUsdGltZW91dD0xMCkgYXMgcmVzcG9uc2U6XFxuICAgIHJlcXVpcmUocmVzcG9uc2Uuc3RhdHVzPT0yMDAgYW5kIGxlbihyZXNwb25zZS5yZWFkKDgxOTMpKTw9ODE5MixcXCdib3VuZGVkIGhlYWx0aCBjaGVjayByZWZ1c2VkXFwnKTtzdGF0dXNlc1tyb3V0ZV09MjAwXFxuICBwcm9vZi51cGRhdGUoaW5zdGFsbGVkX3B1cnBvc2VfY2hlY2tzPXRlc3RlZCxwb2xpY3lfc2hhMjU2PW1vZHVsZV9kaWdlc3QscG9saWN5X21vZGU9XFwnMDY0NFxcJyxwb2xpY3lfdWlkPTAsaGVhbHRoX3N0YXR1c2VzPXN0YXR1c2VzLG5hdGl2ZV9wcm92aWRlcl9wcm9iZT1GYWxzZSlcXG4gcHJpbnQoanNvbi5kdW1wcyhwcm9vZikpXFxuZWxpZiBhY3Rpb24gaW4gKFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnKTpcXG4gcHJpdmF0ZShmb2xkZXIsVHJ1ZSk7ZmlsZW5hbWU9XFwnZHJpbGwuc3FsaXRlXFwnIGlmIGFjdGlvbj09XFwnZHJpbGwtY29weVxcJyBlbHNlIFxcJ2N1dG92ZXIuc3FsaXRlXFwnO291dHB1dD1mb2xkZXIrXFwnL1xcJytmaWxlbmFtZTtwcml2YXRlKG91dHB1dClcXG4gaWRlbnRpdHk9X19TTkFQU0hPVF9fO3JlcXVpcmUoaXNpbnN0YW5jZShpZGVudGl0eSxkaWN0KSBhbmQgaWRlbnRpdHkuZ2V0KFxcJ3NuYXBzaG90X2ZpbGVcXCcpPT1maWxlbmFtZSxcXCdyZWNvcmRlZCBvcmlnaW5hbCBmcm96ZW4gc25hcHNob3QgaWRlbnRpdHkgcmVxdWlyZWRcXCcpXFxuIHNuYXBzaG90PWNvdW50cyhpbnNwZWN0X2Nsb3NlZF9zbmFwc2hvdChvdXRwdXQsaWRlbnRpdHlbXFwnc25hcHNob3Rfc2hhMjU2XFwnXSkpO3NpemU9b3Muc3RhdChvdXRwdXQpLnN0X3NpemU7cmVxdWlyZShzaXplPT1pZGVudGl0eVtcXCdzbmFwc2hvdF9ieXRlc1xcJ10gYW5kIDA8c2l6ZTw9NTEyKjEwMjQqKjIsXFwnc25hcHNob3Qgc2l6ZSBvdXRzaWRlIGZyb3plbiBib3VuZFxcJylcXG4gcmVxdWlyZShzbmFwc2hvdD09aWRlbnRpdHlbXFwnc25hcHNob3RfcmVhZG9ubHlcXCddLFxcJ2Zyb3plbiBzbmFwc2hvdCBwcm9vZiBkaWZmZXJzXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc25hcHNob3RfZmlsZVxcJzpmaWxlbmFtZSxcXCdzbmFwc2hvdF9ieXRlc1xcJzpzaXplLFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfcmVhZG9ubHlcXCc6c25hcHNob3R9KSlcXG5lbHNlOnJhaXNlIFZhbHVlRXJyb3IoXFwnZml4ZWQgbmF0aXZlIGJhY2t1cC92ZXJpZnkgcGhhc2UgcmVxdWlyZWRcXCcpXFxuXCJcIlwiXFxuICAjIFN0cmlwIHRoZSBDTEkgYnJhbmNoOiBleGVjIG9ubHkgdGhlIHZlcmlmaWVkIHN0ZGxpYiBmdW5jdGlvbiwgbmV2ZXIgU3RvcmUuXFxuICByZWFkb25seT1wYXlsb2FkW1xcJ3JlYWRvbmx5XFwnXS5zcGxpdChcImlmIF9fbmFtZV9fID09IFxcJ19fbWFpbl9fXFwnOlwiLDEpWzBdXFxuICBpbm5lcj1pbm5lci5yZXBsYWNlKFxcJ19fUkVBRE9OTFlfX1xcJyxyZXByKHJlYWRvbmx5KSkucmVwbGFjZShcXCdfX1NBRkVUWV9fXFwnLHJlcHIocGF5bG9hZFtcXCdyZWNlaXB0X3NhZmV0eVxcJ10pKS5yZXBsYWNlKFxcJ19fQUNUSU9OX19cXCcscmVwcihcXCdkcmlsbC1jb3B5XFwnIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyBlbHNlIHBoYXNlKSkucmVwbGFjZShcXCdfX1BVUlBPU0VfX1xcJyxyZXByKHBheWxvYWRbXFwncHVycG9zZV9jaGVja3NcXCddKSkucmVwbGFjZShcXCdfX1NOQVBTSE9UX19cXCcscmVwcihwYXlsb2FkLmdldChcXCdzbmFwc2hvdF9pZGVudGl0eVxcJykpKVxcbiAgcD1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnZXhlY1xcJyxcXCctaVxcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxwb2RbXFwnbWV0YWRhdGFcXCddW1xcJ25hbWVcXCddLFxcJy1jXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy0tXFwnLFxcJ3B5dGhvblxcJyxcXCctXFwnXSxpbm5lciwxNTApXFxuICByZXF1aXJlKHAucmV0dXJuY29kZT09MCxcXCduYXRpdmUgcGhhc2Ugb3V0Y29tZSB1bnZlcmlmaWVkOyByYXcgb3V0cHV0IHdpdGhoZWxkLCBkbyBub3QgcmV0cnlcXCcpXFxuICBvdXRjb21lPWpzb24ubG9hZHMocC5zdGRvdXQpO3JlcXVpcmUob3V0Y29tZS5nZXQoXFwnYWxsX2NoZWNrc19wYXNzXFwnKSBpcyBUcnVlLFxcJ25hdGl2ZSBwaGFzZSBnYXRlIHJlZnVzZWRcXCcpXFxuICByZXN1bHQudXBkYXRlKG91dGNvbWUscG9kX25hbWU9cG9kW1xcJ21ldGFkYXRhXFwnXVtcXCduYW1lXFwnXSxwb2RfdWlkPXBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXSlcXG4gaWYgcGhhc2UgaW4gKFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2tcXCcpOlxcbiAgbm9kZV9yZWFkPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwnbm9kZXNcXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pO3JlcXVpcmUobm9kZV9yZWFkLnJldHVybmNvZGU9PTAsXFwnbm9kZSBtZXRhZGF0YSB1bmF2YWlsYWJsZVxcJylcXG4gIG5vZGVzPWpzb24ubG9hZHMobm9kZV9yZWFkLnN0ZG91dClbXFwnaXRlbXNcXCddO3JlcXVpcmUobGVuKG5vZGVzKT09MSxcXCdvbmUgdGFyZ2V0IG5vZGUgcmVxdWlyZWRcXCcpO25vZGU9bm9kZXNbMF1cXG4gIHJlcXVpcmUoYW55KGEuZ2V0KFxcJ2FkZHJlc3NcXCcpPT1cXCc5Mi4yMDUuNjIuMjM5XFwnIGZvciBhIGluIG5vZGVbXFwnc3RhdHVzXFwnXVtcXCdhZGRyZXNzZXNcXCddKSxcXCd0YXJnZXQgbm9kZSBhZGRyZXNzIGNoYW5nZWRcXCcpXFxuICBjb25kaXRpb25zPXtjW1xcJ3R5cGVcXCddOmNbXFwnc3RhdHVzXFwnXSBmb3IgYyBpbiBub2RlW1xcJ3N0YXR1c1xcJ11bXFwnY29uZGl0aW9uc1xcJ119XFxuICByZXF1aXJlKGNvbmRpdGlvbnMuZ2V0KFxcJ1JlYWR5XFwnKT09XFwnVHJ1ZVxcJyBhbmQgYWxsKGNvbmRpdGlvbnMuZ2V0KGspPT1cXCdGYWxzZVxcJyBmb3IgayBpbiAoXFwnTWVtb3J5UHJlc3N1cmVcXCcsXFwnRGlza1ByZXNzdXJlXFwnLFxcJ1BJRFByZXNzdXJlXFwnKSksXFwnbm9kZSB1bmhlYWx0aHkgb3IgcHJlc3N1cmVkXFwnKVxcbiAgZGVzY3JpcHRpb249cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2Rlc2NyaWJlXFwnLFxcJ25vZGVcXCcsbm9kZVtcXCdtZXRhZGF0YVxcJ11bXFwnbmFtZVxcJ11dKTtyZXF1aXJlKGRlc2NyaXB0aW9uLnJldHVybmNvZGU9PTAsXFwnaGVhZHJvb20gY2FwdHVyZSB1bmF2YWlsYWJsZVxcJylcXG4gIHRhYmxlPWRlc2NyaXB0aW9uLnN0ZG91dC5zcGxpdChcXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcJywxKVsxXTtyZXF1ZXN0ZWQ9aW50KHJlLnNlYXJjaChyXFwnY3B1XFxcXHMrKFxcXFxkKyltXFwnLHRhYmxlKS5ncm91cCgxKSk7YWxsb2M9bm9kZVtcXCdzdGF0dXNcXCddW1xcJ2FsbG9jYXRhYmxlXFwnXVtcXCdjcHVcXCddO2NhcGFjaXR5PWludChhbGxvY1s6LTFdKSBpZiBhbGxvYy5lbmRzd2l0aChcXCdtXFwnKSBlbHNlIGludChhbGxvYykqMTAwMFxcbiAgcmVxdWlyZShyZXF1ZXN0ZWQ8PWNhcGFjaXR5LFxcJ1JlY3JlYXRlIHJlcXVlc3RlZCBDUFUgZXhjZWVkcyBjYXBhY2l0eVxcJylcXG4gIHJlcXVpcmUobm90IGFwcC5nZXQoXFwnb3BlcmF0aW9uXFwnKSBhbmQgYXBwLmdldChcXCdzdGF0dXNcXCcse30pLmdldChcXCdvcGVyYXRpb25TdGF0ZVxcJyx7fSkuZ2V0KFxcJ3BoYXNlXFwnKSBub3QgaW4gKFxcJ1J1bm5pbmdcXCcsXFwnVGVybWluYXRpbmdcXCcpLFxcJ2V4aXN0aW5nIEFyZ28gb3BlcmF0aW9uIG11c3QgYmUgc2V0dGxlZFxcJylcXG4gIGRlc3RpbmF0aW9uPXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwncmVsZWFzZVxcJyBlbHNlIFxcJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmZcXCdcXG4gIGJvZHk9Y29weS5kZWVwY29weShwYXlsb2FkW1xcJ2NhbmRpZGF0ZVxcJ10gaWYgcGhhc2U9PVxcJ3JlbGVhc2VcXCcgZWxzZSBwYXlsb2FkW1xcJ3JvbGxiYWNrXFwnXSlcXG4gIGRyeT1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnYXBwbHlcXCcsXFwnLS1kcnktcnVuPXNlcnZlclxcJyxcXCctZlxcJyxcXCctXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddLGpzb24uZHVtcHMoYm9keSkpXFxuICByZXF1aXJlKGRyeS5yZXR1cm5jb2RlPT0wLFxcJ2ZyZXNoIG93bmVyIHNlcnZlciBhZG1pc3Npb24gcmVmdXNlZFxcJylcXG4gIGFkbWl0dGVkPWpzb24ubG9hZHMoZHJ5LnN0ZG91dCk7d2FudGVkPWNvcHkuZGVlcGNvcHkoc2VhbGVkKVxcbiAgd2FudGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFIGlmIHBoYXNlPT1cXCdyZWxlYXNlXFwnIGVsc2UgQkFTRVxcbiAgcmVxdWlyZShwcm9qZWN0aW9uKGFkbWl0dGVkKT09d2FudGVkLFxcJ2RyeS1ydW4gY2hhbmdlZCBhbnl0aGluZyBiZXlvbmQgZXhhY3QgaW1hZ2VcXCcpXFxuICBkaWZmPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdkaWZmXFwnLFxcJy1mXFwnLFxcJy1cXCddLGpzb24uZHVtcHMoYm9keSkpO3JlcXVpcmUoZGlmZi5yZXR1cm5jb2RlIGluICgwLDEpLFxcJ2NsaWVudCBkaWZmIHVuYXZhaWxhYmxlXFwnKVxcbiAgb3BlcmF0aW9uPXtcXCdpbml0aWF0ZWRCeVxcJzp7XFwndXNlcm5hbWVcXCc6XFwnY3VzdG9kaWFuLWNvZGV4XFwnfSxcXCdzeW5jXFwnOntcXCdyZXZpc2lvblxcJzpkZXN0aW5hdGlvbixcXCdwcnVuZVxcJzpGYWxzZSxcXG4gICBcXCdyZXNvdXJjZXNcXCc6W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dfX1cXG4gIHBhdGNoPVt7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS91aWRcXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS9yZXNvdXJjZVZlcnNpb25cXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCdyZXNvdXJjZVZlcnNpb25cXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9zcGVjL3NvdXJjZS90YXJnZXRSZXZpc2lvblxcJyxcXCd2YWx1ZVxcJzphcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ119LFxcbiAgIHtcXCdvcFxcJzpcXCdyZXBsYWNlXFwnLFxcJ3BhdGhcXCc6XFwnL3NwZWMvc291cmNlL3RhcmdldFJldmlzaW9uXFwnLFxcJ3ZhbHVlXFwnOmRlc3RpbmF0aW9ufSxcXG4gICB7XFwnb3BcXCc6XFwnYWRkXFwnLFxcJ3BhdGhcXCc6XFwnL29wZXJhdGlvblxcJyxcXCd2YWx1ZVxcJzpvcGVyYXRpb259XVxcbiAgYXJndj1bXFwna3ViZWN0bFxcJyxcXCdwYXRjaFxcJyxcXCdhcHBsaWNhdGlvblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctblxcJyxcXCdhcmdvY2RcXCcsXFwnLS10eXBlPWpzb25cXCcsXFwnLS1wYXRjaC1maWxlPS9kZXYvc3RkaW5cXCcsXFwnLW9cXCcsXFwnbmFtZVxcJ11cXG4gIHBhdGNoZHJ5PXJ1bihhcmd2K1tcXCctLWRyeS1ydW49c2VydmVyXFwnXSxqc29uLmR1bXBzKHBhdGNoKSk7cmVxdWlyZShwYXRjaGRyeS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIG9wZXJhdGlvbiBkcnktcnVuIHJlZnVzZWRcXCcpXFxuICBjaGFuZ2U9cnVuKGFyZ3YsanNvbi5kdW1wcyhwYXRjaCkpXFxuICByZXF1aXJlKGNoYW5nZS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIHBhdGNoIG91dGNvbWUgYW1iaWd1b3VzOyBkbyBub3QgcmV0cnlcXCcpXFxuICByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1UcnVlLG9wZXJhdGlvbl9yZXF1ZXN0ZWQ9VHJ1ZSxzb3VyY2VfcmV2aXNpb249ZGVzdGluYXRpb24sXFxuICAgcmVzb3VyY2VzPW9wZXJhdGlvbltcXCdzeW5jXFwnXVtcXCdyZXNvdXJjZXNcXCddLHBydW5lPUZhbHNlLHJvbGxvdXRfdmVyaWZpZWQ9RmFsc2UsXFxuICAgbGF0ZXN0X2xpdmVfZGF0YWJhc2VfcmV0YWluZWQ9VHJ1ZSxjbGllbnRfZGlmZl9zaGEyNTY9aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpKVxcbiBpZiBwaGFzZSBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBvcD1hcHAuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ29wZXJhdGlvblN0YXRlXFwnLHt9KTtzeW5jPW9wLmdldChcXCdvcGVyYXRpb25cXCcse30pLmdldChcXCdzeW5jXFwnLHt9KVxcbiAgcmVxdWlyZShvcC5nZXQoXFwncGhhc2VcXCcpPT1cXCdTdWNjZWVkZWRcXCcgYW5kIHN5bmMuZ2V0KFxcJ3JldmlzaW9uXFwnKT09dGFyZ2V0IGFuZCBzeW5jLmdldChcXCdwcnVuZVxcJykgaXMgRmFsc2VcXG4gICBhbmQgc3luYy5nZXQoXFwncmVzb3VyY2VzXFwnKT09W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dLFxcJ2V4YWN0IG5hdGl2ZSBBcmdvIG9wZXJhdGlvbiBjb21wbGV0aW9uIHVudmVyaWZpZWRcXCcpXFxuICByZXF1aXJlKGxpdmVbXFwnc3RhdHVzXFwnXS5nZXQoXFwnb2JzZXJ2ZWRHZW5lcmF0aW9uXFwnKT09bGl2ZVtcXCdtZXRhZGF0YVxcJ11bXFwnZ2VuZXJhdGlvblxcJ10sXFwnY29udHJvbGxlciBnZW5lcmF0aW9uIG5vdCBzZXR0bGVkXFwnKVxcbiAgcmVzdWx0LnVwZGF0ZShuYXRpdmVfcm9sbG91dF92ZXJpZmllZD1UcnVlLGN1cnJlbnRfc2NoZW1hNV9kYXRhYmFzZV9yZXRhaW5lZD1UcnVlLHJlY292ZXJ5X3ZlcmlmaWNhdGlvbj1waGFzZT09XFwncm9sbGJhY2stdmVyaWZ5XFwnKVxcbmV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGVycm9yOlxcbiByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1GYWxzZSxmYWlsdXJlX2NsYXNzPXR5cGUoZXJyb3IpLl9fbmFtZV9fLFxcbiAgZmFpbHVyZT1cXCdmaXhlZCBwaGFzZSBvdXRjb21lIHJlZnVzZWQgb3IgYW1iaWd1b3VzOyByYXcgb3V0cHV0IHdpdGhoZWxkOyBubyByZXRyeVxcJylcXG5wcmludChqc29uLmR1bXBzKHJlc3VsdCkpO3N5cy5leGl0KDAgaWYgcmVzdWx0LmdldChcXCdhbGxfY2hlY2tzX3Bhc3NcXCcpIGlzIFRydWUgZWxzZSAxKVxcbidcbiIKICAgIH0sCiAgICAicGFja2V0LXJlZmluZW1lbnQuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIzMWI3MThhNDllZDQ3NTg2NWVkZWExYjJmNmQ3NDlhNTBhM2U2NmY1NmRiYzRmYTliNWZmMTE1OGFjYWVmNTYzIiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm9yaWdpbmFsX2FwcHJvdmVkX3NvdXJjZVwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIixcbiAgXCJvcmlnaW5hbF9wYWNrZXRfYXJjaGl2ZVwiOiBcImluaXRpYWwtYXBwcm92ZWQtYmM2NDk0Y2RcIixcbiAgXCJvcmlnaW5hbF9hcHByb3ZlZF9zdWJtaXNzaW9uX2RpZ2VzdFwiOiBcInNoYTI1NjpmZDc4ZDQ4NjE3NDY3MGUxMmVmYjJmODEyYmFjMDJlNjhmMjk0ZTc3OTFiOTMwMmQwZDQ1OGMwNTMyNDBmNWE5XCIsXG4gIFwib3JpZ2luYWxfZmFpbGVkX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICBcIm9yaWdpbmFsX29sZF91bmNlcnRhaW5fcmV0cnlcIjogZmFsc2UsXG4gIFwicmVzY3VlX3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgXCJyZWZpbmVtZW50c1wiOiBbXG4gICAgXCJleHBsaWNpdGNsb3NlIGxpdmUgV0FMLWF3YXJlIGluc3BlY3RvclwiLFxuICAgIFwiaW1tdXRhYmxlIGZpeGVkIGhhc2gtYm91bmQgZnJvemVuIHNuYXBzaG90IGFsbG93aW5nIHJldGFpbmVkIHN0YWxlU0hNIG9ubHkgd2l0aCB6ZXJvV0FMXCIsXG4gICAgXCJuZXcgc2VwYXJhdGVseSBsaW5rZWQgam91cm5hbCBhbmQgZGlzdGluY3QgbmFtZWQgcmVzY3VlLWNvcHkgYXR0ZW1wdFwiLFxuICAgIFwicmVtYWluaW5nIHBoYXNlIGlucHV0IGV4cGxpY2l0bHkgcmVzY3VlZCByZXN1bHRcIlxuICBdLFxuICBcIm5ld19uYXRpdmVfYWN0aW9uc1wiOiBmYWxzZSxcbiAgXCJuZXdfZm91bmRlcl9hcHByb3ZhbFwiOiBmYWxzZVxufVxuIgogICAgfSwKICAgICJyZWNlaXB0X3NhZmV0eS5weSI6IHsKICAgICAgInNoYTI1NiI6ICI1YzU0MzczZjJkYzRiMDY0MDA4MjI1YzE4NmVmYjFkNWFmZGVlYzM2ZDE1MzUwYmRhMGExMmRlZDk3NjAyZDFiIiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiT25seSBzdHJ1Y3R1cmFsIGNvdW50L2hhc2ggcmVjZWlwdHMgY2FuIGxlYXZlIHRoZSBwcml2YXRlIGV4ZWN1dGlvbiBwaGFzZS5cIlwiXCJcbmRlZiBjb3VudHModmFsdWUpOlxuICAgIGlmIChzZXQodmFsdWUpICE9IHsnc2NoZW1hX3ZlcnNpb24nLCAnbGlmZWN5Y2xlJywgJ291dGJveCcsICdzdWJtaXNzaW9ucycsICdpbnRlZ3JpdHknLFxuICAgICAgICAgICAgICAgICAgICAgICAncmVhZF9vbmx5X3ByZV9vcGVuJywgJ3N0b3JlX2NvbnN0cnVjdGVkJ31cbiAgICAgICAgICAgIG9yIHZhbHVlWydzY2hlbWFfdmVyc2lvbiddICE9IDUgb3IgdmFsdWVbJ2ludGVncml0eSddICE9ICdvaydcbiAgICAgICAgICAgIG9yIHZhbHVlWydyZWFkX29ubHlfcHJlX29wZW4nXSBpcyBub3QgVHJ1ZSBvciB2YWx1ZVsnc3RvcmVfY29uc3RydWN0ZWQnXSBpcyBub3QgRmFsc2VcbiAgICAgICAgICAgIG9yIHNldCh2YWx1ZVsnbGlmZWN5Y2xlJ10pICE9IHsncmVjb3JkcycsICdldmVudHMnLCAncGVuZGluZyd9XG4gICAgICAgICAgICBvciBub3Qgc2V0KHZhbHVlWydvdXRib3gnXSkgPD0geydwZW5kaW5nJywgJ2RlbGl2ZXJlZCcsICdibG9ja2VkJ31cbiAgICAgICAgICAgIG9yIG5vdCBzZXQodmFsdWVbJ3N1Ym1pc3Npb25zJ10pIDw9IHsncHJlcGFyZWQnLCAnaW5fZmxpZ2h0JywgJ2NvbmZpcm1lZCcsICd1bnJlc29sdmVkJ30pOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdjb3VudC1vbmx5IHJlY2VpcHQgc2hhcGUvc3RhdGUgcmVmdXNlZDsgdmFsdWVzIHdpdGhoZWxkJylcbiAgICBmb3IgZ3JvdXAgaW4gKCdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyk6XG4gICAgICAgIGlmIGFueSh0eXBlKG51bWJlcikgaXMgbm90IGludCBvciBudW1iZXIgPCAwIG9yIG51bWJlciA+IDEwKioxMlxuICAgICAgICAgICAgICAgZm9yIG51bWJlciBpbiB2YWx1ZVtncm91cF0udmFsdWVzKCkpOlxuICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignY291bnQtb25seSByZWNlaXB0IHZhbHVlcyByZWZ1c2VkJylcbiAgICByZXR1cm4gdmFsdWVcbiIKICAgIH0sCiAgICAicm9vdC1hdXRob3JpdHktcmVjZWlwdC10ZW1wbGF0ZS5qc29uIjogewogICAgICAic2hhMjU2IjogImRiMjhkMDNlM2M0NmI0ZGU1MmRjNDA0YzkxMjA1NDQ4M2Y0YTJhYWE2YzRmNDc2Yjc4OTJjYWIyYTVmNDA4ZDQiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwicHJvcG9zYWxfaWRcIjogXCJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MVwiLFxuICBcIm1lbW9faWRcIjogXCJpbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm1lbW9fc2hhMjU2XCI6IG51bGwsXG4gIFwic291cmNlX3JldmlzaW9uXCI6IG51bGwsXG4gIFwiYWN0aXZhdGlvblwiOiBcIlBFTkRJTkdcIixcbiAgXCJhdXRob3JpdHlfbW9kZVwiOiBcIkFETUlOSVNURVJcIixcbiAgXCJ0YXJnZXRcIjogXCJyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uXCIsXG4gIFwidmVyaWZpY2F0aW9uX21ldGhvZFwiOiBcInJvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFja1wiLFxuICBcInJ1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudFwiOiBmYWxzZSxcbiAgXCJ2ZXJpZmllZF9hdFwiOiBudWxsLFxuICBcImFjY2VwdGVkX2F0XCI6IG51bGwsXG4gIFwicmV2aWV3X21lbW9faWRcIjogbnVsbCxcbiAgXCJhcHByb3ZhbF9pZFwiOiBudWxsLFxuICBcImRpc3Bvc2l0aW9uX2lkXCI6IG51bGwsXG4gIFwibmF0aXZlX291dGNvbWVfc2hhMjU2XCI6IG51bGwsXG4gIFwiZXhlY3V0b3JfcGxhbl9zaGEyNTZcIjogXCI0ZDU1MzBlNzQxOGY2MzhiMTBjY2ZmMGUwZDlhMDcyN2FkYzY0YTdmM2E0NTkwN2Y2ZGViNTczOWFkMmFkYzg1XCIsXG4gIFwib3V0Y29tZV9xdWVyeVwiOiBcIi9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0yXCIsXG4gIFwicmV2aWV3X21lbW9fdmVyc2lvblwiOiAxXG59XG4iCiAgICB9LAogICAgInRlc3RfZXhlY3V0aW9uLnB5IjogewogICAgICAic2hhMjU2IjogImIyNTA0NDEyODI1MTM4NjJlZWI5OTBiMThkMDFiYjFlYWZlNzg3YjkzNGQ2NzBhNzVhMmJmYWE5ZjVjZmI4OWMiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTeW50aGV0aWMgY3VzdG9keS90cmFuc3BvcnQgdGVzdHMuIE5vIG5hdGl2ZSBkYXRhLCBEb2NrZXIgb3IgY2x1c3RlciBhY3Rpb24uXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaW9cbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0ZW1wZmlsZVxuaW1wb3J0IHVuaXR0ZXN0XG5mcm9tIHVuaXR0ZXN0Lm1vY2sgaW1wb3J0IHBhdGNoXG5mcm9tIGNvbnRleHRsaWIgaW1wb3J0IHJlZGlyZWN0X3N0ZG91dFxuXG5pbXBvcnQgYWN0dWF0b3JcbmZyb20gYXV0aG9yaXR5X2pvdXJuYWwgaW1wb3J0IEpvdXJuYWwsIGF1dGhvcml0eVxuZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuZnJvbSByZWNlaXB0X3NhZmV0eSBpbXBvcnQgY291bnRzXG5cbkNBU0UgPSBQYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24vZG9jcy9ldmlkZW5jZS8yMDI2LTEwLTExLXB1cnBvc2UtaW1hZ2UtcmVsZWFzZScpXG5OT1cgPSBkYXRldGltZS5kYXRldGltZSgyMDI2LCAxMCwgMTEsIDIsIDAsIHR6aW5mbz1kYXRldGltZS50aW1lem9uZS51dGMpXG5SRVZJU0lPTiA9ICdlJyAqIDQwXG5DT1VOVCA9IHsnc2NoZW1hX3ZlcnNpb24nOiA1LCAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlLFxuICAgICAgICAgJ2xpZmVjeWNsZSc6IHsncmVjb3Jkcyc6IDMsICdldmVudHMnOiA4LCAncGVuZGluZyc6IDF9LFxuICAgICAgICAgJ291dGJveCc6IHsncGVuZGluZyc6IDIsICdkZWxpdmVyZWQnOiAxMH0sICdzdWJtaXNzaW9ucyc6IHsnY29uZmlybWVkJzogMSwgJ3VucmVzb2x2ZWQnOiAxfX1cblxuXG5kZWYgYWNjZXB0ZWQoKTpcbiAgICBhcHByb3ZhbCA9ICcxMTExMTExMS0xMTExLTQxMTEtODExMS0xMTExMTExMTExMTEnXG4gICAgcmV2aWV3ID0gJ3Jldmlldy0yMjIyMjIyMi0yMjIyLTQyMjItODIyMi0yMjIyMjIyMjIyMjInXG4gICAgZGlzcG9zaXRpb24gPSAnZGlzcC0zMzMzMzMzMy0zMzMzLTQzMzMtODMzMy0zMzMzMzMzMzMzMzMnXG4gICAgcmVjZWlwdCA9IHsncHJvcG9zYWxfaWQnOiAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnLFxuICAgICAgICAgICAgICAgJ21lbW9faWQnOiAnaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEnLCAnbWVtb192ZXJzaW9uJzogMixcbiAgICAgICAgICAgICAgICdtZW1vX3NoYTI1Nic6ICdhJyAqIDY0LCAnc291cmNlX3JldmlzaW9uJzogUkVWSVNJT04sICdhY3RpdmF0aW9uJzogJ0FQUFJPVkVEJyxcbiAgICAgICAgICAgICAgICdhdXRob3JpdHlfbW9kZSc6ICdBRE1JTklTVEVSJywgJ3RhcmdldCc6ICdyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uJyxcbiAgICAgICAgICAgICAgICd2ZXJpZmljYXRpb25fbWV0aG9kJzogJ3Jvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFjaycsICdydW50aW1lX2F1dGhlbnRpY2F0ZWRfZ3JhbnQnOiBGYWxzZSwgJ291dGNvbWVfcXVlcnknOiAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgICAgJ3ZlcmlmaWVkX2F0JzogJzIwMjYtMTAtMTFUMDI6MDA6MDBaJywgJ2FjY2VwdGVkX2F0JzogJzIwMjYtMTAtMTFUMDE6NTk6MDBaJyxcbiAgICAgICAgICAgICAgICdyZXZpZXdfbWVtb19pZCc6IHJldmlldywgJ2FwcHJvdmFsX2lkJzogYXBwcm92YWwsICdkaXNwb3NpdGlvbl9pZCc6IGRpc3Bvc2l0aW9ufVxuICAgIG91dGNvbWUgPSB7J21lbW9faWQnOiByZWNlaXB0WydtZW1vX2lkJ10sICdyZXZpZXcnOiB7J21lbW9faWQnOiByZXZpZXcsICdzdGFsZSc6IEZhbHNlLCAnaW50YWtlX3N0YXRlJzogJ3JlYWR5J30sXG4gICAgICAgICAgICAgICAnZGlzcG9zaXRpb25zJzogW3snYXBwcm92YWxfaWQnOiBOb25lLCAnc3VibWlzc2lvbl9zdGF0ZSc6ICdjb25maXJtZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Rpc3Bvc2l0aW9uJzogeyd2ZXJiJzogJ2FjY2VwdCcsICdtZW1vX3ZlcnNpb24nOiAxLCAnbWVtb19pZCc6IHJldmlldyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXBwcm92YWxfaWQnOiBhcHByb3ZhbCwgJ2lkJzogZGlzcG9zaXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FjdG9yJzogeydraW5kJzogJ3BlcnNvbicsICdzdWInOiAndWlkPXBsYXRmb3JtLXJvb3Qsb3U9cGVvcGxlLGRjPW5ldGtpbmdkb20sZGM9bG9jYWwnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXQnOiByZWNlaXB0WydhY2NlcHRlZF9hdCddfX1dfVxuICAgIHJldHVybiByZWNlaXB0LCBvdXRjb21lXG5cblxuY2xhc3MgQXV0aG9yaXR5QW5kQ3VzdG9keSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIHRlc3RfZXhhY3RfbmVzdGVkX2ZvdW5kZXJfcmVjZWlwdF9ub3RfdG9wX2xldmVsX2FwcHJvdmFsKHNlbGYpOlxuICAgICAgICByZWNlaXB0LCBvdXRjb21lID0gYWNjZXB0ZWQoKVxuICAgICAgICByZXN1bHQgPSBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgJ2EnICogNjQsIFJFVklTSU9OLCAnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBOT1cpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydhcHByb3ZhbF9pZCddLCByZWNlaXB0WydhcHByb3ZhbF9pZCddKVxuXG4gICAgZGVmIHRlc3RfcGVuZGluZ19zdGFsZV93cm9uZ19hY3Rvcl92ZXJzaW9uX2FuZF9iaW5kaW5nX3JlZnVzZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSByLCBvOiByLnVwZGF0ZShhY3RpdmF0aW9uPSdQRU5ESU5HJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUobWVtb19zaGEyNTY9J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZShzb3VyY2VfcmV2aXNpb249J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZSh0YXJnZXQ9J290aGVyJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpZWRfYXQ9JzIwMjYtMTAtMTFUMDE6MDA6MDBaJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpY2F0aW9uX21ldGhvZD0nY2FsbGVyLWFzc2VydGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUocnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50PVRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ3JldmlldyddLnVwZGF0ZShzdGFsZT1UcnVlKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydyZXZpZXcnXS51cGRhdGUoaW50YWtlX3N0YXRlPSdwZW5kaW5nJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ11bMF0udXBkYXRlKHN1Ym1pc3Npb25fc3RhdGU9J3VucmVzb2x2ZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydkaXNwb3NpdGlvbnMnXVswXVsnZGlzcG9zaXRpb24nXS51cGRhdGUobWVtb192ZXJzaW9uPTMpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddLnVwZGF0ZShhY3Rvcj17J2tpbmQnOiAnYWdlbnQnLCAnc3ViJzogJ3BsYXRmb3JtLXJvb3QnfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ10uYXBwZW5kKGNvcHkuZGVlcGNvcHkob1snZGlzcG9zaXRpb25zJ11bMF0pKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShyLCBvKVxuICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyZWxlYXNlJywgTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwaXJlZF93aW5kb3dfYW5kX3Vua25vd25fcGhhc2VfcmVmdXNlKHNlbGYpOlxuICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgYXV0aG9yaXR5KHIsIG8sICdhJyAqIDY0LCBSRVZJU0lPTiwgJ2FyYml0cmFyeScsIE5PVylcbiAgICAgICAgbGF0ZSA9IGRhdGV0aW1lLmRhdGV0aW1lKDIwMjYsIDEwLCAxMywgdHppbmZvPWRhdGV0aW1lLnRpbWV6b25lLnV0YylcbiAgICAgICAgclsndmVyaWZpZWRfYXQnXSA9IGxhdGUuaXNvZm9ybWF0KClcbiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyb2xsYmFjaycsIGxhdGUpXG5cbiAgICBkZWYgdGVzdF9kdXJhYmxlX2ludGVudF9wcmVjZWRlc19kaXNwYXRjaF9hbmRfbmV2ZXJfcmV0cmllcyhzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQgPSBQYXRoKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIG9zLmNobW9kKHBhcmVudCwgMG83MDApXG4gICAgICAgICAgICBqb3VybmFsID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICBqb3VybmFsLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIHsnYXBwcm92YWxfaWQnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChqc29uLmxvYWRzKGpvdXJuYWwucGF0aC5yZWFkX3RleHQoKSlbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydzdGF0ZSddLCAnUlVOTklORycpXG4gICAgICAgICAgICBqb3VybmFsLmNsb3NlKCkgICMgc2ltdWxhdGVkIGNyYXNoIGJlZm9yZSByZXN1bHRcbiAgICAgICAgICAgIHJlY292ZXJlZCA9IEpvdXJuYWwocGFyZW50LCB7J2Nhc2UnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICByZWNvdmVyZWQuc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCB7fSlcbiAgICAgICAgICAgIHJlY292ZXJlZC5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9waGFzZV9vcmRlcl9hbmRfdW5jZXJ0YWluX3JlbGVhc2VfYWxsb3dzX29ubHlfZGlzdGluY3RfcmVjb3Zlcnkoc2VsZik6XG4gICAgICAgIHdpdGggdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZGlyZWN0b3J5OlxuICAgICAgICAgICAgb3MuY2htb2QoZGlyZWN0b3J5LCAwbzcwMClcbiAgICAgICAgICAgIGogPSBKb3VybmFsKGRpcmVjdG9yeSwgeydjYXNlJzogJ2ZpeHR1cmUnfSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgai5zdGFydCgncmVsZWFzZScsIHt9KVxuICAgICAgICAgICAgZm9yIHBoYXNlIGluIGFjdHVhdG9yLlBIQVNFU1s6NV06XG4gICAgICAgICAgICAgICAgai5zdGFydChwaGFzZSwge30pXG4gICAgICAgICAgICAgICAgai5maW5pc2gocGhhc2UsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICBqLmZpbmlzaCgncmVsZWFzZScsIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2V9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGouc3RhcnQoJ3ZlcmlmeScsIHt9KVxuICAgICAgICAgICAgai5zdGFydCgncm9sbGJhY2snLCB7fSlcbiAgICAgICAgICAgIGouZmluaXNoKCdyb2xsYmFjaycsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X3NlY3JldF9vcl91bmtub3duX2NoaWxkX291dHB1dF9pc193aXRoaGVsZChzZWxmKTpcbiAgICAgICAgZm9yIGJvZHkgaW4gKCdub3QtanNvbicsICd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwidG9rZW5cIjpcInByaXZhdGUtdmFsdWVcIn0nLFxuICAgICAgICAgICAgICAgICAgICAgJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJzbmFwc2hvdF9yZWFkb25seVwiOntcInNjaGVtYV92ZXJzaW9uXCI6NX19Jyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGFjdHVhdG9yLmpzb25fcmVzdWx0KHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwgMCwgYm9keSwgJycpKVxuICAgICAgICB3cm9uZyA9IGNvcHkuZGVlcGNvcHkoQ09VTlQpXG4gICAgICAgIHdyb25nWydvdXRib3gnXSA9IHsncHJpdmF0ZS1yb3ctdmFsdWUnOiAxfVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgY291bnRzKHdyb25nKVxuICAgICAgICBjb3VudHMoQ09VTlQpICAjIGJsb2NrZWQvdW5yZXNvbHZlZCBjb3VudHMgYXJlIG5vdCByZXF1aXJlZCB0byBiZSB6ZXJvLlxuXG4gICAgZGVmIHRlc3RfYmluYXJ5X2NvcHlfaXNfYm91bmRlZF9wcml2YXRlX2FuZF9uZXZlcl9lY2hvZWQoc2VsZik6XG4gICAgICAgIGJsb2IgPSBiJ3N5bnRoZXRpYyBwcml2YXRlIGZpeHR1cmUgYnl0ZXMnXG4gICAgICAgIGRpZ2VzdCA9IF9faW1wb3J0X18oJ2hhc2hsaWInKS5zaGEyNTYoYmxvYikuaGV4ZGlnZXN0KClcbiAgICAgICAgbWV0YWRhdGEgPSB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdzbmFwc2hvdF9maWxlJzogJ2RyaWxsLnNxbGl0ZScsICdzbmFwc2hvdF9ieXRlcyc6IGxlbihibG9iKSxcbiAgICAgICAgICAgICAgICAgICAgJ3NuYXBzaG90X3NoYTI1Nic6IGRpZ2VzdCwgJ3NuYXBzaG90X3JlYWRvbmx5JzogQ09VTlQsXG4gICAgICAgICAgICAgICAgICAgICdwb2RfbmFtZSc6ICdmaXh0dXJlLXBvZCcsICdwb2RfdWlkJzogJ2ZpeHR1cmUtdWlkJ31cbiAgICAgICAgam91cm5hbCA9IHR5cGUoJ0ZpeHR1cmVKb3VybmFsJywgKCksIHsnZGF0YSc6IHsnaWRlbnRpdHknOiB7J3JlY292ZXJ5X2FuY2hvcic6IHsnYmFja3VwX3Jlc3VsdCc6IG1ldGFkYXRhfX19fSkoKVxuICAgICAgICByZWFsX3BvcGVuID0gc3VicHJvY2Vzcy5Qb3BlblxuICAgICAgICBmb3IgZXh0cmEgaW4gKGInJywgYidvdmVyc2l6ZWQnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGV4dHJhPWV4dHJhKSwgdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZm9sZGVyOlxuICAgICAgICAgICAgICAgIG9zLmNobW9kKGZvbGRlciwgMG83MDApXG4gICAgICAgICAgICAgICAgb3V0cHV0ID0gaW8uU3RyaW5nSU8oKVxuXG4gICAgICAgICAgICAgICAgZGVmIGNoaWxkKCphcmdzLCAqKmt3YXJncyk6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFsX3BvcGVuKFtzeXMuZXhlY3V0YWJsZSwgJy1jJywgJ2ltcG9ydCBzeXM7c3lzLnN0ZG91dC5idWZmZXIud3JpdGUoJyArIHJlcHIoYmxvYiArIGV4dHJhKSArICcpJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwpXG5cbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwgJ0NVU1RPRFknLCBQYXRoKGZvbGRlcikpLCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdyZW1vdGUnLCByZXR1cm5fdmFsdWU9bWV0YWRhdGEpLCBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2goJ3N1YnByb2Nlc3MuUG9wZW4nLCBzaWRlX2VmZmVjdD1jaGlsZCksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgICAgICAgICBpZiBleHRyYTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWF0b3IuY29weV9zbmFwc2hvdCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBSRVZJU0lPTiwge30sIGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBhY3R1YXRvci5jb3B5X3NuYXBzaG90KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIFJFVklTSU9OLCB7fSwgam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29mZl9jbHVzdGVyX3ByaXZhdGVfY29weV92ZXJpZmllZCddKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoUGF0aChmb2xkZXIpIC8gJ2RyaWxsLnNxbGl0ZScpLnJlYWRfYnl0ZXMoKSwgYmxvYilcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG91dHB1dC5nZXR2YWx1ZSgpLCAnJylcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKChQYXRoKGZvbGRlcikgLyAnZHJpbGwuc3FsaXRlJykuc3RhdCgpLnN0X21vZGUgJiAwbzc3NywgMG82MDApXG5cbiAgICBkZWYgdGVzdF9yZWNyZWF0ZWRfb2ZmbGluZV92b2x1bWVfY2Fubm90X2JlX2RlbGV0ZWQoc2VsZik6XG4gICAgICAgIGlkZW50aXR5ID0geydOYW1lJzogYWN0dWF0b3IuVk9MVU1FLCAnTGFiZWxzJzogeydub25jZSc6ICdvbGQnfSwgJ0NyZWF0ZWRBdCc6ICdvbGQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7XG4gICAgICAgICAgICAnb2ZmbGluZS12ZXJpZnknOiB7J3Jlc3VsdCc6IHsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknOiBpZGVudGl0eX19fX19KSgpXG4gICAgICAgIGluc3BlY3RlZCA9IFt7KippZGVudGl0eSwgJ0NyZWF0ZWRBdCc6ICdyZWNyZWF0ZWQnfV1cbiAgICAgICAgd2l0aCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdkb2NrZXInLCByZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBqc29uLmR1bXBzKGluc3BlY3RlZCksICcnKSkgYXMgbW9ja2VkOlxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBhY3R1YXRvci5jbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobW9ja2VkLmNhbGxfY291bnQsIDEpXG5cbiAgICBkZWYgdGVzdF9vZmZsaW5lX3Bvc3RfYWRtaW5faW50ZWdyaXR5X2FuZF9vcmlnaW5hbF9oYXNoX2FyZV9yZWNoZWNrZWQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdub25lJywgJ3Bvc3QtaW50ZWdyaXR5JywgJ29yaWdpbmFsLWhhc2gnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgZm9sZGVyPVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChmb2xkZXIsMG83MDApXG4gICAgICAgICAgICAgICAgc25hcHNob3Q9Zm9sZGVyLydkcmlsbC5zcWxpdGUnO3NuYXBzaG90LndyaXRlX2J5dGVzKGIncHJpdmF0ZSBzeW50aGV0aWMgc25hcHNob3QnKTtvcy5jaG1vZChzbmFwc2hvdCwwbzYwMClcbiAgICAgICAgICAgICAgICBkaWdlc3Q9YWN0dWF0b3Iuc2hhKHNuYXBzaG90KVxuICAgICAgICAgICAgICAgIHByaW9yPXsnc25hcHNob3Rfc2hhMjU2JzpkaWdlc3QsJ3NuYXBzaG90X3JlYWRvbmx5JzpDT1VOVH1cbiAgICAgICAgICAgICAgICBqb3VybmFsPXR5cGUoJ0ZpeHR1cmVKb3VybmFsJywoKSx7J2RhdGEnOnsncGhhc2VzJzp7J2RyaWxsLWNvcHktcmVzY3VlLXIxJzp7J3Jlc3VsdCc6cHJpb3J9LCdvZmZsaW5lLXZlcmlmeSc6eydhdHRlbXB0X2lkJzonbm9uY2UnfX19LCdub3RlJzpsYW1iZGEgKmFyZ3M6Tm9uZX0pKClcbiAgICAgICAgICAgICAgICByZWFkcz1bXVxuICAgICAgICAgICAgICAgIHZvbHVtZT17J05hbWUnOmFjdHVhdG9yLlZPTFVNRSwnTGFiZWxzJzp7J2luZm9ybWVkLWRlY2lzaW9uLmNhc2UnOidpbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLCdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOidvZmZsaW5lLXJlc3RvcmUtb25seScsJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQnOidub25jZSd9LCdEcml2ZXInOidsb2NhbCcsJ1Njb3BlJzonbG9jYWwnLCdDcmVhdGVkQXQnOidmaXh0dXJlJywnT3B0aW9ucyc6Tm9uZX1cbiAgICAgICAgICAgICAgICBkZWYgZG9ja2VyKGFyZ3YsIGJvZHk9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgICAgICAgICBpZiBhcmd2WzBdPT0naW5mbyc6Ym9keT1qc29uLmR1bXBzKCdibnQtbGFwMDAxJylcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdscyddOmJvZHk9JydcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdjcmVhdGUnXTpib2R5PWFjdHVhdG9yLlZPTFVNRVxuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2luc3BlY3QnXTpib2R5PWpzb24uZHVtcHMoW3ZvbHVtZV0pXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJyBpbiBhcmd2OlxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keT1qc29uLmR1bXBzKHtrZXk6Q09VTlRba2V5XSBmb3Iga2V5IGluICgnc2NoZW1hX3ZlcnNpb24nLCdsaWZlY3ljbGUnLCdvdXRib3gnLCdzdWJtaXNzaW9ucycpfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J29yaWdpbmFsLWhhc2gnOnNuYXBzaG90LndyaXRlX2J5dGVzKGInY2hhbmdlZCBzeW50aGV0aWMgb3JpZ2luYWwnKVxuICAgICAgICAgICAgICAgICAgICBlbGlmICctLWVudHJ5cG9pbnQnIGluIGFyZ3YgYW5kICdweXRob24nIGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkcy5hcHBlbmQoYXJndik7cHJvb2Y9Y29weS5kZWVwY29weShDT1VOVClcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihyZWFkcyk9PTIgYW5kIGRlZmVjdD09J3Bvc3QtaW50ZWdyaXR5Jzpwcm9vZlsnaW50ZWdyaXR5J109J2NvcnJ1cHQnXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5PWpzb24uZHVtcHMocHJvb2YpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6cmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgb2ZmbGluZSBjb21tYW5kJylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LDAsYm9keSwnJylcbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwnQ1VTVE9EWScsZm9sZGVyKSxwYXRjaC5vYmplY3QoYWN0dWF0b3IsJ0NBU0UnLENBU0UpLHBhdGNoLm9iamVjdChhY3R1YXRvciwnZG9ja2VyJyxzaWRlX2VmZmVjdD1kb2NrZXIpLHBhdGNoKCdzdWJwcm9jZXNzLnJ1bicscmV0dXJuX3ZhbHVlPXN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwwLCd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwicHJpdmF0ZV9jb3B5X3ZlcmlmaWVkXCI6dHJ1ZX0nLCcnKSk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J25vbmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0PWFjdHVhdG9yLm9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlc3VsdFsnb2ZmbGluZV9wb3N0X2FkbWluX3JlYWRvbmx5J10sQ09VTlQpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydFRydWUocmVzdWx0WydvcmlnaW5hbF9zbmFwc2hvdF9oYXNoX3VuY2hhbmdlZCddKVxuICAgICAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTphY3R1YXRvci5vZmZsaW5lX3ZlcmlmeShqb3VybmFsKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlYWRzKSwyKVxuXG5cbmNsYXNzIEZpeGVkTmF0aXZlUHJvZ3JhbSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIGZpeHR1cmUoc2VsZik6XG4gICAgICAgIHNlYWxlZCA9IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgICAgIGxpdmUgPSBjb3B5LmRlZXBjb3B5KHNlYWxlZClcbiAgICAgICAgbGl2ZVsnbWV0YWRhdGEnXS51cGRhdGUoZ2VuZXJhdGlvbj00MilcbiAgICAgICAgbGl2ZVsnc3RhdHVzJ10gPSB7J3JlYWR5UmVwbGljYXMnOiAxLCAndXBkYXRlZFJlcGxpY2FzJzogMSwgJ29ic2VydmVkR2VuZXJhdGlvbic6IDQyfVxuICAgICAgICBkZXBlbmRlbmNpZXMgPSBqc29uLmxvYWRzKChDQVNFIC8gJ3NlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY20gPSBjb3B5LmRlZXBjb3B5KGRlcGVuZGVuY2llc1snY29uZmlnbWFwJ10pXG4gICAgICAgIGNtLnBvcCgnY2Fub25pY2FsX2RhdGFfc2hhMjU2JylcbiAgICAgICAgc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UgLyAnY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBzb3VyY2Vfc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UucGFyZW50c1syXSAvICdkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY21bJ2RhdGEnXSA9IG5leHQoeCBmb3IgeCBpbiBzb3VyY2Vfc2VydmljZVsnaXRlbXMnXSBpZiB4WydraW5kJ10gPT0gJ0NvbmZpZ01hcCcpWydkYXRhJ11cbiAgICAgICAgcHZjID0gY29weS5kZWVwY29weShkZXBlbmRlbmNpZXNbJ3B2YyddKVxuICAgICAgICBwdmNbJ3N0YXR1cyddID0geydwaGFzZSc6ICdCb3VuZCd9XG4gICAgICAgIGFwcCA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQnLCAncmVzb3VyY2VWZXJzaW9uJzogJzE3J30sXG4gICAgICAgICAgICAgICAnc3BlYyc6IHsnc291cmNlJzogeydyZXBvVVJMJzogJ2h0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uLmdpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYXRoJzogJ2RlcGxveS9saWZlY3ljbGUnLCAndGFyZ2V0UmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZid9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2Rlc3RpbmF0aW9uJzogeyduYW1lc3BhY2UnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnc2VydmVyJzogJ2h0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yyd9fX1cbiAgICAgICAgb2JqZWN0cyA9IHsnZGVwbG95bWVudCc6IGxpdmUsICdjb25maWdtYXAnOiBjbSwgJ3B2Yyc6IHB2YywgJ2FwcGxpY2F0aW9uJzogYXBwfVxuICAgICAgICBwYXlsb2FkID0geydwaGFzZSc6ICdyZWxlYXNlJywgJ3NvdXJjZV9yZXZpc2lvbic6IFJFVklTSU9OLCAnYXBwcm92YWwnOiB7fSwgJ3NlYWxlZCc6IHNlYWxlZCxcbiAgICAgICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJzogZGVwZW5kZW5jaWVzLCAnY2FuZGlkYXRlJzogc2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAncmVhZG9ubHknOiAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSwncHVycG9zZV9jaGVja3MnOihDQVNFLydjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICAgICAncmVjZWlwdF9zYWZldHknOiAoUGF0aChfX2ZpbGVfXykucGFyZW50IC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCl9XG4gICAgICAgIHJldHVybiBvYmplY3RzLCBwYXlsb2FkXG5cbiAgICBkZWYgZXhlY3V0ZV9mYWtlKHNlbGYsIG9iamVjdHMsIHBheWxvYWQsIGFtYmlndW91cz1GYWxzZSwgc2NoZW1hX3JlZnVzZWQ9RmFsc2UpOlxuICAgICAgICB3cml0ZXMgPSBbXVxuICAgICAgICBjYWxscyA9IFtdXG5cbiAgICAgICAgZGVmIGZha2UoYXJndiwgaW5wdXQ9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgY2FsbHMuYXBwZW5kKGFyZ3YpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZ2V0J106XG4gICAgICAgICAgICAgICAga2luZCA9IGFyZ3ZbMl1cbiAgICAgICAgICAgICAgICBpZiBraW5kIGluIG9iamVjdHM6XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSBvYmplY3RzW2tpbmRdXG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdwb2RzJzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnaXRlbXMnOiBbeydtZXRhZGF0YSc6IHsnbmFtZSc6ICdmaXh0dXJlLXBvZCcsICd1aWQnOiAncG9kLXVpZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnb3duZXJSZWZlcmVuY2VzJzogW3sna2luZCc6ICdSZXBsaWNhU2V0JywgJ25hbWUnOiAnZml4dHVyZS1ycycsICd1aWQnOiAncnMtdWlkJ31dfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwZWMnOiBvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RhdHVzJzogeydwaGFzZSc6ICdSdW5uaW5nJywgJ2NvbnRhaW5lclN0YXR1c2VzJzogW3snbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywncmVhZHknOiBUcnVlfV19fV19XG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdyZXBsaWNhc2V0JzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICdycy11aWQnLCAnb3duZXJSZWZlcmVuY2VzJzogW1xuICAgICAgICAgICAgICAgICAgICAgICAgeydraW5kJzogJ0RlcGxveW1lbnQnLCAndWlkJzogcGF5bG9hZFsnc2VhbGVkJ11bJ21ldGFkYXRhJ11bJ3VpZCddfV19fVxuICAgICAgICAgICAgICAgIGVsaWYga2luZCA9PSAnbm9kZXMnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydpdGVtcyc6IFt7J21ldGFkYXRhJzogeyduYW1lJzogJ2ZpeHR1cmUtbm9kZSd9LCAnc3RhdHVzJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FkZHJlc3Nlcyc6IFt7J2FkZHJlc3MnOiAnOTIuMjA1LjYyLjIzOSd9XSwgJ2FsbG9jYXRhYmxlJzogeydjcHUnOiAnNCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbmRpdGlvbnMnOiBbeyd0eXBlJzoga2V5LCAnc3RhdHVzJzogJ1RydWUnIGlmIGtleSA9PSAnUmVhZHknIGVsc2UgJ0ZhbHNlJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBrZXkgaW4gKCdSZWFkeScsICdNZW1vcnlQcmVzc3VyZScsICdEaXNrUHJlc3N1cmUnLCAnUElEUHJlc3N1cmUnKV19fV19XG4gICAgICAgICAgICAgICAgZWxzZTpcbiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgZml4ZWQgbWV0YWRhdGEgcm91dGUnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhib2R5KSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddOlxuICAgICAgICAgICAgICAgIGlmIHNjaGVtYV9yZWZ1c2VkOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDEsICcnLCAnd2l0aGhlbGQnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyh7XG4gICAgICAgICAgICAgICAgICAgICdhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlLCAnbGl2ZV9yZWFkb25seV9zY2hlbWFfaW50ZWdyaXR5X2NvdW50cyc6IENPVU5UfSksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2FwcGx5J106XG4gICAgICAgICAgICAgICAgYWRtaXR0ZWQgPSBjb3B5LmRlZXBjb3B5KHBheWxvYWRbJ3NlYWxlZCddKVxuICAgICAgICAgICAgICAgIGFkbWl0dGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gKGFjdHVhdG9yLklNQUdFIGlmIHBheWxvYWRbJ3BoYXNlJ109PSdyZWxlYXNlJyBlbHNlIHBheWxvYWRbJ3NlYWxlZCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhhZG1pdHRlZCksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2Rlc2NyaWJlJ106XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnQWxsb2NhdGVkIHJlc291cmNlczpcXG4gY3B1IDM0NjBtICg4NiUpXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZGlmZiddOlxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJy1pbWFnZTogYmFzZVxcbitpbWFnZTogY2FuZGlkYXRlXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXTpcbiAgICAgICAgICAgICAgICBpZiAnLS1kcnktcnVuPXNlcnZlcicgbm90IGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgIHdyaXRlcy5hcHBlbmQoanNvbi5sb2FkcyhpbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIGlmIGFtYmlndW91czpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJycsICd3aXRoaGVsZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnYXBwbGljYXRpb24uYXJnb3Byb2ouaW8vaW5mb3JtZWQtZGVjaXNpb25cXG4nLCAnJylcbiAgICAgICAgICAgIHJhaXNlIEFzc2VydGlvbkVycm9yKCd1bmV4cGVjdGVkIGNvbW1hbmQnKVxuXG4gICAgICAgIHNvdXJjZSA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAgICAgJ19fR1VBUkRfXycsIHJlcHIoKENBU0UgLyAnY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpKVxuICAgICAgICBvdXRwdXQgPSBpby5TdHJpbmdJTygpXG4gICAgICAgIHdpdGggcGF0Y2goJ3N1YnByb2Nlc3MucnVuJywgc2lkZV9lZmZlY3Q9ZmFrZSksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIGV4ZWMoY29tcGlsZShzb3VyY2UsICdmaXhlZC1uYXRpdmUtZml4dHVyZScsICdleGVjJyksIHsnX19uYW1lX18nOiAnX19maXh0dXJlX18nfSlcbiAgICAgICAgICAgIGV4Y2VwdCAoVmFsdWVFcnJvciwgU3lzdGVtRXhpdCk6XG4gICAgICAgICAgICAgICAgcGFzc1xuICAgICAgICByZWNlaXB0ID0ganNvbi5sb2FkcyhvdXRwdXQuZ2V0dmFsdWUoKSkgaWYgb3V0cHV0LmdldHZhbHVlKCkgZWxzZSB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlfVxuICAgICAgICByZXR1cm4gcmVjZWlwdCwgd3JpdGVzLCBjYWxsc1xuXG4gICAgZGVmIHRlc3Rfb25seV9leGlzdGluZ19hcHBsaWNhdGlvbl9vcGVyYXRpb25fYW5kX2RlcGxveW1lbnRfYXJlX3JlcXVlc3RlZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBvcGVyYXRpb24gPSB3cml0ZXNbMF1bLTFdWyd2YWx1ZSddXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2Uob3BlcmF0aW9uWydzeW5jJ11bJ3BydW5lJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwob3BlcmF0aW9uWydzeW5jJ11bJ3Jlc291cmNlcyddLCBbXG4gICAgICAgICAgICB7J2dyb3VwJzogJ2FwcHMnLCAna2luZCc6ICdEZXBsb3ltZW50JywgJ25hbWUnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnbmFtZXNwYWNlJzogJ2luZm9ybWVkLWRlY2lzaW9uJ31dKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KCctLWRyeS1ydW49c2VydmVyJyBpbiBhcmd2IGFuZCBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXSBmb3IgYXJndiBpbiBjYWxscykpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzWzBdWzBdWydwYXRoJ10sICcvbWV0YWRhdGEvdWlkJylcblxuICAgIGRlZiB0ZXN0X3NvdXJjZV9vdmVycmlkZXNfYXV0b21hdGlvbl9hbmRfY3VzdG9keV9kcmlmdF9zdG9wX2JlZm9yZV93cml0ZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2FwcGxpY2F0aW9uJ11bJ3NwZWMnXS51cGRhdGUoc3luY1BvbGljeT17J2F1dG9tYXRlZCc6IHt9fSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXS51cGRhdGUoa3VzdG9taXplPXsnaW1hZ2VzJzogWydvdGhlciddfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddLnVwZGF0ZShzb3VyY2VzPVt7fV0pLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2NvbmZpZ21hcCddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ3B2YyddWydzcGVjJ10udXBkYXRlKHZvbHVtZU5hbWU9J3JlcGxhY2VkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgICAgICAgICBtdXRhdGUob2JqZWN0cylcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuICAgIGRlZiB0ZXN0X3ByZW9wZW5fc2NoZW1hX3JlZnVzYWxfcHJldmVudHNfaW1hZ2Vfb3BlcmF0aW9uKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIHNjaGVtYV9yZWZ1c2VkPVRydWUpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuXG4gICAgZGVmIHRlc3Rfcm9sbGJhY2tfdW5yZWFkeV9jYW5kaWRhdGVfbmV2ZXJfcmVhZHNfcG9kX29yX2RhdGFiYXNlKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wLCB1cGRhdGVkUmVwbGljYXM9MClcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gYWN0dWF0b3IuSU1BR0VcbiAgICAgICAgb2JqZWN0c1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXVsndGFyZ2V0UmV2aXNpb24nXSA9IFJFVklTSU9OXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBzY2hlbWFfcmVmdXNlZD1UcnVlKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBzZWxmLmFzc2VydEZhbHNlKGFueShhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddIG9yIGFyZ3ZbOjNdID09IFsna3ViZWN0bCcsICdnZXQnLCAncG9kcyddIGZvciBhcmd2IGluIGNhbGxzKSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXNbMF1bLTFdWyd2YWx1ZSddWydzeW5jJ11bJ3JldmlzaW9uJ10sICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJylcblxuICAgIGRlZiB0ZXN0X3JvbGxiYWNrX3N0aWxsX3JlZnVzZXNfY3VzdG9keV9vcl9ub25wYWlyX2ltYWdlX2RyaWZ0KHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnY20nLCAncHZjJywgJ2ltYWdlJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKCk7cGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgICAgICAgICAgaWYgZGVmZWN0ID09ICdjbSc6b2JqZWN0c1snY29uZmlnbWFwJ11bJ21ldGFkYXRhJ11bJ3VpZCddID0gJ3JlY3JlYXRlZCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdCA9PSAncHZjJzpvYmplY3RzWydwdmMnXVsnc3BlYyddWyd2b2x1bWVOYW1lJ10gPSAncmVwbGFjZWQnXG4gICAgICAgICAgICAgICAgZWxzZTpvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSAnZm9yZWlnbi1pbWFnZSdcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKTtzZWxmLmFzc2VydEVxdWFsKHdyaXRlcywgW10pXG5cbiAgICBkZWYgdGVzdF9yZWNvdmVyeV92ZXJpZmljYXRpb25faXNfc2VwYXJhdGVfcmVhZHlfb2xkX2ltYWdlX3NjaGVtYV9wcm9vZihzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpO3BheWxvYWRbJ3BoYXNlJ10gPSAncm9sbGJhY2stdmVyaWZ5J1xuICAgICAgICBvYmplY3RzWydhcHBsaWNhdGlvbiddWydzdGF0dXMnXSA9IHsnb3BlcmF0aW9uU3RhdGUnOiB7J3BoYXNlJzogJ1N1Y2NlZWRlZCcsICdvcGVyYXRpb24nOiB7J3N5bmMnOiB7XG4gICAgICAgICAgICAncmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZicsICdwcnVuZSc6IEZhbHNlLFxuICAgICAgICAgICAgJ3Jlc291cmNlcyc6IFt7J2dyb3VwJzonYXBwcycsJ2tpbmQnOidEZXBsb3ltZW50JywnbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywnbmFtZXNwYWNlJzonaW5mb3JtZWQtZGVjaXNpb24nfV19fX19XG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pO3NlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydyZWNvdmVyeV92ZXJpZmljYXRpb24nXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KGFyZ3ZbOjJdPT1bJ2t1YmVjdGwnLCdleGVjJ10gZm9yIGFyZ3YgaW4gY2FsbHMpKVxuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG5cbiAgICBkZWYgdGVzdF9hbWJpZ3VvdXNfcGF0Y2hfaXNfbmV2ZXJfcmV0cmllZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBhbWJpZ3VvdXM9VHJ1ZSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4od3JpdGVzKSwgMSlcblxuXG5pZiBfX25hbWVfXyA9PSAnX19tYWluX18nOlxuICAgIHVuaXR0ZXN0Lm1haW4oKVxuIgogICAgfSwKICAgICJ0ZXN0X3Jlc2N1ZV9leGVjdXRpb24ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiOGVjYmIwMjYwYTg3YTdhMTJiZDVjNGM5Njc4ZmIyYTlkNDNhNGVhNzMyMjEyOTczNGJjMjFmOGVlMzgzY2Q3MCIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIlN5bnRoZXRpYyByZWNvdmVyeSBndWFyZHM7IG5vIGFjdHVhbCBwcml2YXRlIGpvdXJuYWwvREIvbmF0aXZlIGNvbW1hbmQuXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaGFzaGxpYlxuaW1wb3J0IGpzb25cbmltcG9ydCBvc1xuZnJvbSBwYXRobGliIGltcG9ydCBQYXRoXG5pbXBvcnQgdGVtcGZpbGVcbmltcG9ydCB1bml0dGVzdFxuZnJvbSBhdXRob3JpdHlfam91cm5hbCBpbXBvcnQgSm91cm5hbCwgYXV0aG9yaXR5LCBvcmlnaW5hbF9hbmNob3JcbmZyb20gdGVzdF9leGVjdXRpb24gaW1wb3J0IGFjY2VwdGVkLCBOT1csIFJFVklTSU9OXG5cblJPT1Q9UGF0aChfX2ZpbGVfXykucGFyZW50XG5QTEFOPWpzb24ubG9hZHMoKFJPT1QvJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKS5yZWFkX3RleHQoKSlcbkNBU0U9Uk9PVC5wYXJlbnRcbkJBQ0tVUD1qc29uLmxvYWRzKChDQVNFLydvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKVxuXG5jbGFzcyBSZXNjdWVHdWFyZHModW5pdHRlc3QuVGVzdENhc2UpOlxuICAgIGRlZiBvcmlnaW5hbChzZWxmLHBhcmVudCk6XG4gICAgICAgIG9yaWdpbmFsPXsnaWRlbnRpdHknOlBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10sJ3BoYXNlcyc6e319XG4gICAgICAgIGZvciBuYW1lLG1ldGFkYXRhIGluIFBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2FuY2hvciddWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgICAgICBvcmlnaW5hbFsncGhhc2VzJ11bbmFtZV09eyoqbWV0YWRhdGEsJ3Jlc3VsdCc6QkFDS1VQIGlmIG5hbWU9PSdkcmlsbC1iYWNrdXAnIGVsc2UgeydhbGxfY2hlY2tzX3Bhc3MnOkZhbHNlfX1cbiAgICAgICAgcD1wYXJlbnQvJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nO3Aud3JpdGVfdGV4dChqc29uLmR1bXBzKG9yaWdpbmFsKSk7b3MuY2htb2QocCwwbzYwMClcbiAgICAgICAgYW5jaG9yPWNvcHkuZGVlcGNvcHkoUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10pO2FuY2hvclsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgcmV0dXJuIHAsb3JpZ2luYWwsYW5jaG9yXG5cbiAgICBkZWYgdGVzdF9leGFjdF9vcmlnaW5hbF9mYWlsZWRfam91cm5hbF9pc19saW5rZWRfd2l0aG91dF9tdXRhdGlvbihzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQ9UGF0aChkaXJlY3RvcnkpO29zLmNobW9kKHBhcmVudCwwbzcwMCk7cCxvcmlnaW5hbCxleHBlY3RlZD1zZWxmLm9yaWdpbmFsKHBhcmVudCk7YmVmb3JlPXAucmVhZF9ieXRlcygpXG4gICAgICAgICAgICBhbmNob3I9b3JpZ2luYWxfYW5jaG9yKHBhcmVudCxleHBlY3RlZCxCQUNLVVAsb3JpZ2luYWxbJ2lkZW50aXR5J10pXG4gICAgICAgICAgICBqPUpvdXJuYWwocGFyZW50LHsnZml4dHVyZSc6VHJ1ZSwncmVjb3ZlcnlfYW5jaG9yJzphbmNob3J9KTtqLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScse30pXG4gICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHAucmVhZF9ieXRlcygpLGJlZm9yZSk7c2VsZi5hc3NlcnRFcXVhbChqLnBhdGgubmFtZSwncmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24nKVxuICAgICAgICAgICAgai5maW5pc2goJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7J2FsbF9jaGVja3NfcGFzcyc6VHJ1ZX0pO2ouc3RhcnQoJ29mZmxpbmUtdmVyaWZ5Jyx7fSlcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocC5yZWFkX2J5dGVzKCksYmVmb3JlKTtqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X29yaWdpbmFsX21pc3NpbmdfdW5jZXJ0YWluX3JlY3JlYXRlZF9hdHRlbXB0X29yX3JvbGxvdXRfcmVmdXNlKHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnbWlzc2luZycsJ2NvbXBsZXRlJywnYXR0ZW1wdCcsJ3JvbGxvdXQnLCdoYXNoJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KSx0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgcGFyZW50PVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChwYXJlbnQsMG83MDApO3AsbyxlPXNlbGYub3JpZ2luYWwocGFyZW50KVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J21pc3NpbmcnOm9bJ3BoYXNlcyddLnBvcCgnZHJpbGwtY29weScpXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdjb21wbGV0ZSc6b1sncGhhc2VzJ11bJ2RyaWxsLWNvcHknXVsnc3RhdGUnXT0nQ09NUExFVEUnXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdhdHRlbXB0JzpvWydwaGFzZXMnXVsnZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ109J2RpZmZlcmVudCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdD09J3JvbGxvdXQnOm9bJ3BoYXNlcyddWydyZWxlYXNlJ109eydzdGF0ZSc6J1JVTk5JTkcnfVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdCE9J2hhc2gnOlxuICAgICAgICAgICAgICAgICAgICBwLndyaXRlX3RleHQoanNvbi5kdW1wcyhvKSk7ZVsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgICAgICAgICBlbHNlOmVbJ29yaWdpbmFsX2pvdXJuYWxfc2hhMjU2J109JzAnKjY0XG4gICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcygoVmFsdWVFcnJvcixLZXlFcnJvcikpOm9yaWdpbmFsX2FuY2hvcihwYXJlbnQsZSxCQUNLVVAsUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcblxuICAgIGRlZiB0ZXN0X3Jlc2N1ZV9yZXBsYXlfcmVmdXNlZF9hbmRfb2xkX3BoYXNlX25ldmVyX2FkbWl0dGVkKHNlbGYpOlxuICAgICAgICB3aXRoIHRlbXBmaWxlLlRlbXBvcmFyeURpcmVjdG9yeSgpIGFzIGRpcmVjdG9yeTpcbiAgICAgICAgICAgIG9zLmNobW9kKGRpcmVjdG9yeSwwbzcwMCk7aj1Kb3VybmFsKGRpcmVjdG9yeSx7J2ZpeHR1cmUnOlRydWV9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpqLnN0YXJ0KCdkcmlsbC1jb3B5Jyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnZHJpbGwtYmFja3VwJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHt9KTtqLmZpbmlzaCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZX0pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmouc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9uZXdfYXV0aG9yaXR5X3JlcXVpcmVzX3ZlcnNpb24yX29sZF9hcHByb3ZhbF9yZWZ1c2VzKHNlbGYpOlxuICAgICAgICByZWNlaXB0LG91dGNvbWU9YWNjZXB0ZWQoKTtyZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0yO291dGNvbWVbJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddWydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIGF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuICAgICAgICByZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyxOT1cpXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHknLE5PVylcbiAgICAgICAgcmVjZWlwdFsnbWVtb192ZXJzaW9uJ109MjtyZWNlaXB0WydvdXRjb21lX3F1ZXJ5J109Jy9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0xJ1xuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwbGljaXRfb2ZmbGluZV9pbnB1dF9tYXBwaW5nX2FuZF9hYnNlbmNlX2d1YXJkcyhzZWxmKTpcbiAgICAgICAgc291cmNlPShST09ULydhY3R1YXRvci5weScpLnJlYWRfdGV4dCgpXG4gICAgICAgIHNlbGYuYXNzZXJ0SW4oXCJwcmV2aW91cyA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2RyaWxsLWNvcHktcmVzY3VlLXIxJ11bJ3Jlc3VsdCddXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwibm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwiVk9MVU1FIG5vdCBpbiBsaXN0ZWQuc3Rkb3V0LnNwbGl0bGluZXMoKVwiLHNvdXJjZSlcbiAgICAgICAgc2VsZi5hc3NlcnROb3RJbihcIm9zLm1rZGlyKENVU1RPRFlcIixzb3VyY2UpXG4gICAgICAgIGltcG9ydCBhc3RcbiAgICAgICAgcHJvZ3JhbT1hc3QubGl0ZXJhbF9ldmFsKG5leHQobi52YWx1ZSBmb3IgbiBpbiBhc3QucGFyc2UoKFJPT1QvJ25hdGl2ZV9wcm9ncmFtLnB5JykucmVhZF90ZXh0KCkpLmJvZHkgaWYgaXNpbnN0YW5jZShuLGFzdC5Bc3NpZ24pKSlcbiAgICAgICAgY29tcGlsZShwcm9ncmFtLCduYXRpdmUtcmVzY3VlLWZpeHR1cmUnLCdleGVjJylcbiAgICAgICAgc2VsZi5hc3NlcnRJbihcInBoYXNlPT0nZHJpbGwtY29weS1yZXNjdWUtcjEnOnJlcXVpcmUocG9kWydtZXRhZGF0YSddWyd1aWQnXT09J2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNydcIixwcm9ncmFtKVxuXG5pZiBfX25hbWVfXz09J19fbWFpbl9fJzp1bml0dGVzdC5tYWluKClcbiIKICAgIH0sCiAgICAidmFsaWRhdGlvbi5qc29uIjogewogICAgICAic2hhMjU2IjogIjZmMzM3OWY2Mzk2OGU5YTAyOTRhYmE3YjViNTdlYTQ2NjJhZGRhNmIxZmExYjM3ZWZmMTFjMmY3MmE1ODkzMWYiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwic3RhdGVcIjogXCJwcmVwYXJlZC11bmFwcHJvdmVkLXZlcnNpb24yXCIsXG4gIFwiZXhlY3V0b3JfdGVzdHNcIjogMjEsXG4gIFwic25hcHNob3RfbW9ja190ZXN0c1wiOiA1LFxuICBcIm5hdGl2ZV9hY3Rpb25zXCI6IGZhbHNlLFxuICBcImRhdGFiYXNlX2FkbWluX2NvbW1hbmRzX2luX3ByZXBhcmF0aW9uXCI6IGZhbHNlLFxuICBcIm9sZF9qb3VybmFsX21vZGlmaWVkXCI6IGZhbHNlLFxuICBcIm9sZF9mYWlsZWRfcGhhc2VfcmV0cmllZFwiOiBmYWxzZSxcbiAgXCJvd25lcl9oZWFkX3VuY2hhbmdlZFwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIlxufVxuIgogICAgfQogIH0sCiAgIm5hdGl2ZV9leGVjdXRpb24iOiBmYWxzZSwKICAiY2FzZV9ldmlkZW5jZSI6IHsKICAgICJvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIwMjVkZGRmMWU5MzkzNmYzMWU5OGI5ZmJmYTg0YWEyYmRhYWEzMzU3M2Y5ZDNiMGUzMmQ5NDdmZDI4NmIxNzBlIiwKICAgICAgImNvbnRlbnQiOiAie1wicGhhc2VcIjogXCJkcmlsbC1iYWNrdXBcIiwgXCJhbGxfY2hlY2tzX3Bhc3NcIjogdHJ1ZSwgXCJyYXdfb3V0cHV0X3dpdGhoZWxkXCI6IHRydWUsIFwibmF0aXZlX2FwcHJvdmFsX3ZlcmlmaWVkX2J5X3Jvb3RcIjoge1wiYXBwcm92YWxfaWRcIjogXCJlYzkyODA2YS05YWE2LTQ5NGYtYTc2Yi0wMzg1ZjM5YmE2MDlcIiwgXCJkaXNwb3NpdGlvbl9pZFwiOiBcImRpc3AtMDk2ODM3M2QtMjk0ZC00MmJmLTg5NzktMzZhN2M1ZGQzOGNmXCIsIFwiYWNjZXB0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM0OjIwWlwiLCBcInZlcmlmaWVkX2F0XCI6IFwiMjAyNi0xMC0xMVQwMjozODo0MS43Nzc5NDkrMDA6MDBcIn0sIFwibmF0aXZlX2F1dGhlbnRpY2F0ZWRfZ3JhbnRcIjogZmFsc2UsIFwic291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXCI6IHtcInNjaGVtYV92ZXJzaW9uXCI6IDUsIFwibGlmZWN5Y2xlXCI6IHtcInJlY29yZHNcIjogMTUsIFwiZXZlbnRzXCI6IDUwLCBcInBlbmRpbmdcIjogMH0sIFwib3V0Ym94XCI6IHtcImRlbGl2ZXJlZFwiOiAzMjB9LCBcInN1Ym1pc3Npb25zXCI6IHtcImNvbmZpcm1lZFwiOiA0MX0sIFwiaW50ZWdyaXR5XCI6IFwib2tcIiwgXCJyZWFkX29ubHlfcHJlX29wZW5cIjogdHJ1ZSwgXCJzdG9yZV9jb25zdHJ1Y3RlZFwiOiBmYWxzZX0sIFwic25hcHNob3RfcmVhZG9ubHlcIjoge1wic2NoZW1hX3ZlcnNpb25cIjogNSwgXCJsaWZlY3ljbGVcIjoge1wicmVjb3Jkc1wiOiAxNSwgXCJldmVudHNcIjogNTAsIFwicGVuZGluZ1wiOiAwfSwgXCJvdXRib3hcIjoge1wiZGVsaXZlcmVkXCI6IDMyMH0sIFwic3VibWlzc2lvbnNcIjoge1wiY29uZmlybWVkXCI6IDQxfSwgXCJpbnRlZ3JpdHlcIjogXCJva1wiLCBcInJlYWRfb25seV9wcmVfb3BlblwiOiB0cnVlLCBcInN0b3JlX2NvbnN0cnVjdGVkXCI6IGZhbHNlfSwgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsIFwic25hcHNob3RfZmlsZVwiOiBcImRyaWxsLnNxbGl0ZVwiLCBcIm5hdGl2ZV9wYXJlbnRfcHJpdmF0ZVwiOiB0cnVlLCBcIm5hdGl2ZV91aWRcIjogMTAwMDEsIFwicG9kX25hbWVcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi1mNTU3NTU2ZGYtbXdwejdcIiwgXCJwb2RfdWlkXCI6IFwiZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XCJ9XG4iCiAgICB9LAogICAgIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWNvcHktZmFpbHVyZS5qc29uIjogewogICAgICAic2hhMjU2IjogImZiNzhmYjJlOGMzZDQxNjQ5MGNmMGY1NTliMmY1YmQwMTk0MDZhNDkwZjhmNWZhNmY1OTMyNDIxZjBiMWFjNTYiLAogICAgICAiY29udGVudCI6ICJ7XCJhbGxfY2hlY2tzX3Bhc3NcIjogZmFsc2UsIFwicGhhc2VcIjogXCJkcmlsbC1jb3B5XCIsIFwiZmFpbHVyZV9jbGFzc1wiOiBcIlZhbHVlRXJyb3JcIiwgXCJmYWlsdXJlXCI6IFwiZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeVwiLCBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZX1cbiIKICAgIH0sCiAgICAib3JpZ2luYWwtam91cm5hbC1zYW5pdGl6ZWQtYW5jaG9yLmpzb24iOiB7CiAgICAgICJzaGEyNTYiOiAiOTg4ZmNhNjFhZDhlYjlkNDNkOTMzOTBhODM1MzIzZjk1MjE5NmJiY2U4Y2MwYmRlNTFjNDJhMTdkNDExZjQ1NCIsCiAgICAgICJjb250ZW50IjogIntcbiAgXCJvcmlnaW5hbF9qb3VybmFsX3NoYTI1NlwiOiBcImQxODdiMDJkOThkNmU5NzQyOWZlMjBiNGZiZTFkMzA5YTZjNmM0YjU1MjMyYjRhZTEzYWMzOTg3MzAzOWYxYzFcIixcbiAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgXCJkcmlsbC1iYWNrdXBcIjoge1xuICAgICAgXCJzdGF0ZVwiOiBcIkNPTVBMRVRFXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzg6NDUuMzEwNjUzKzAwOjAwXCJcbiAgICB9LFxuICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICBcInN0YXRlXCI6IFwiVU5DRVJUQUlOXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCIzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2NcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICB9XG4gIH0sXG4gIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsXG4gIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsXG4gIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gIFwib2xkX3VuY2VydGFpbl9yZXRyeV9hdXRob3JpemVkXCI6IGZhbHNlXG59XG4iCiAgICB9CiAgfQp9Cg==" + }, + { + "digest": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509", + "media_type": "text/plain", + "content_base64": "IiIiUHJlLW9wZW4gc2NoZW1hL2ludGVncml0eS9jb3VudCBwcm9vZjsgc3RkbGliIG9ubHksIG5ldmVyIGNvbnN0cnVjdHMgU3RvcmUuIiIiCmltcG9ydCBhcmdwYXJzZQpmcm9tIGNvbnRleHRsaWIgaW1wb3J0IGNsb3NpbmcKaW1wb3J0IGhhc2hsaWIKaW1wb3J0IG9zCmltcG9ydCByZQppbXBvcnQgc3RhdAppbXBvcnQganNvbgpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaW1wb3J0IHNxbGl0ZTMKCgpkZWYgaW5zcGVjdF9yZWFkb25seShwYXRoLCAqLCBfY2xvc2VkX3NuYXBzaG90PUZhbHNlKToKICAgIHBhdGggPSBQYXRoKHBhdGgpCiAgICBpZiBub3QgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZXhpc3Rpbmcgbm9uc3ltbGluayBwcml2YXRlIGRhdGFiYXNlIHJlcXVpcmVkJykKICAgIHVyaSA9IHBhdGgucmVzb2x2ZSgpLmFzX3VyaSgpICsgJz9tb2RlPXJvJyArICgnJmltbXV0YWJsZT0xJyBpZiBfY2xvc2VkX3NuYXBzaG90IGVsc2UgJycpCiAgICAjIHNxbGl0ZTMuQ29ubmVjdGlvbiBjb250ZXh0IG1hbmFnZW1lbnQgZW5kcyB0cmFuc2FjdGlvbnM7IGl0IGRvZXMgbm90IGNsb3NlLgogICAgd2l0aCBjbG9zaW5nKHNxbGl0ZTMuY29ubmVjdCh1cmksIHVyaT1UcnVlLCB0aW1lb3V0PTUpKSBhcyBkYjoKICAgICAgICBkYi5leGVjdXRlKCdQUkFHTUEgcXVlcnlfb25seT1PTicpCiAgICAgICAgZGIuZXhlY3V0ZSgnQkVHSU4nKQogICAgICAgIHZlcnNpb24gPSBkYi5leGVjdXRlKCdQUkFHTUEgdXNlcl92ZXJzaW9uJykuZmV0Y2hvbmUoKVswXQogICAgICAgIGlmIHZlcnNpb24gIT0gNToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncHJlLW9wZW4gZGF0YWJhc2UgaXMgbm90IHNjaGVtYTU7IHJlZnVzZSBtaWdyYXRpb24nKQogICAgICAgIGlmIGRiLmV4ZWN1dGUoJ1BSQUdNQSBpbnRlZ3JpdHlfY2hlY2snKS5mZXRjaGFsbCgpICE9IFsoJ29rJywpXToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncmVhZC1vbmx5IGludGVncml0eSBjaGVjayByZWZ1c2VkJykKICAgICAgICBsaWZlY3ljbGUgPSB7bmFtZTogZGIuZXhlY3V0ZSgnU0VMRUNUIENPVU5UKCopIEZST00gJyArIHRhYmxlKS5mZXRjaG9uZSgpWzBdCiAgICAgICAgICAgICAgICAgICAgIGZvciBuYW1lLCB0YWJsZSBpbiAoKCdyZWNvcmRzJywgJ2xpZmVjeWNsZV9yZWNvcmRzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCdldmVudHMnLCAnbGlmZWN5Y2xlX2V2ZW50cycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgncGVuZGluZycsICdsaWZlY3ljbGVfcGVuZGluZycpKX0KICAgICAgICByZXN1bHQgPSB7J3NjaGVtYV92ZXJzaW9uJzogdmVyc2lvbiwgJ2xpZmVjeWNsZSc6IGxpZmVjeWNsZSwKICAgICAgICAgICAgICAgICAgJ291dGJveCc6IGRpY3QoZGIuZXhlY3V0ZSgnU0VMRUNUIHN0YXRlLENPVU5UKCopIEZST00gb3V0Ym94IEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnc3VibWlzc2lvbnMnOiBkaWN0KGRiLmV4ZWN1dGUoJ1NFTEVDVCBzdGF0ZSxDT1VOVCgqKSBGUk9NIHN1Ym1pc3Npb25zIEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlfQogICAgICAgIGRiLnJvbGxiYWNrKCkKICAgIHJldHVybiByZXN1bHQKCgpkZWYgaW5zcGVjdF9jbG9zZWRfc25hcHNob3QocGF0aCwgZXhwZWN0ZWRfc2hhMjU2KToKICAgICIiIk9ubHkgYSBwcml2YXRlbHkgcmV0YWluZWQsIGZyb3plbiBtYWluLWZpbGUgc25hcHNob3Qgd2l0aCBubyBXQUwgZnJhbWVzLgoKICAgIENhbGxlciBtdXN0IGVzdGFibGlzaCBleGNsdXNpdmUgc25hcHNob3QgY3JlYXRpb24vYWRtaW4gZXhpdC9ubyB3cml0ZXIsIGFuZAogICAgc3VwcGx5IHRoZSByZWNvcmRlZCBmcm96ZW4gbWFpbiBkaWdlc3QuIE5ldmVyIHVzZSBmb3IgdGhlIGxpdmUgZGF0YWJhc2UuCiAgICBJbW11dGFibGUgU1FMaXRlIHJlYWRzIGlnbm9yZSBzdGFsZSBTSE0gYW5kIG5ldmVyIGNyZWF0ZS9jaGFuZ2Ugc2lkZWNhcnMuCiAgICBFeGlzdGluZyBzaWRlY2FycyByZW1haW4gY3VzdG9keSBldmlkZW5jZTsgbm90aGluZyBpcyBkZWxldGVkL2NoZWNrcG9pbnRlZC4KICAgICIiIgogICAgcGF0aCA9IFBhdGgocGF0aCkKICAgIGlmIHJlLmZ1bGxtYXRjaChyJ1swLTlhLWZdezY0fScsIGV4cGVjdGVkX3NoYTI1NikgaXMgTm9uZToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdleGFjdCBmcm96ZW4gc25hcHNob3QgZGlnZXN0IHJlcXVpcmVkJykKICAgIGRlZiBtZXRhZGF0YSh0YXJnZXQpOgogICAgICAgIGluZm8gPSB0YXJnZXQubHN0YXQoKQogICAgICAgIGlmIG5vdCBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBvciBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKSAhPSAwbzYwMCBvciBpbmZvLnN0X25saW5rICE9IDE6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgc2luZ2xlLWxpbmsgc25hcHNob3QgY3VzdG9keSByZXF1aXJlZCcpCiAgICAgICAgcmV0dXJuIGluZm8KICAgIG1haW4gPSBtZXRhZGF0YShwYXRoKQogICAgaWYgbm90IDAgPCBtYWluLnN0X3NpemUgPD0gNTEyICogMTAyNCoqMjoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdib3VuZGVkIGZyb3plbiBzbmFwc2hvdCByZXF1aXJlZCcpCiAgICBkZWYgc2lkZWNhcnMoKToKICAgICAgICBpZGVudGl0aWVzID0ge30KICAgICAgICBmb3Igc3VmZml4IGluICgnLXdhbCcsICctc2htJyk6CiAgICAgICAgICAgIHRhcmdldCA9IFBhdGgoc3RyKHBhdGgpICsgc3VmZml4KQogICAgICAgICAgICBpZiBvcy5wYXRoLmxleGlzdHModGFyZ2V0KToKICAgICAgICAgICAgICAgIGluZm8gPSBtZXRhZGF0YSh0YXJnZXQpCiAgICAgICAgICAgICAgICBpZiBpbmZvLnN0X3VpZCAhPSBtYWluLnN0X3VpZCBvciBpbmZvLnN0X2dpZCAhPSBtYWluLnN0X2dpZDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBzaWRlY2FyIGN1c3RvZHkgY2hhbmdlZCcpCiAgICAgICAgICAgICAgICBpZiBzdWZmaXggPT0gJy13YWwnIGFuZCBpbmZvLnN0X3NpemUgIT0gMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBoYXMgV0FMIGZyYW1lczsgaW1tdXRhYmxlIHJlYWQgcmVmdXNlZCcpCiAgICAgICAgICAgICAgICBpZGVudGl0aWVzW3N1ZmZpeF0gPSAoaW5mby5zdF9kZXYsIGluZm8uc3RfaW5vLCBpbmZvLnN0X3NpemUsIGluZm8uc3RfbXRpbWVfbnMpCiAgICAgICAgcmV0dXJuIGlkZW50aXRpZXMKICAgIGJlZm9yZV9zaWRlY2FycyA9IHNpZGVjYXJzKCkKICAgIGRlZiBkaWdlc3QoKToKICAgICAgICB2YWx1ZSA9IGhhc2hsaWIuc2hhMjU2KCkKICAgICAgICB3aXRoIHBhdGgub3BlbigncmInKSBhcyBzdHJlYW06CiAgICAgICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6CiAgICAgICAgICAgICAgICB2YWx1ZS51cGRhdGUoYmxvY2spCiAgICAgICAgcmV0dXJuIHZhbHVlLmhleGRpZ2VzdCgpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTY6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIG1haW4tZmlsZSBkaWdlc3QgY2hhbmdlZCBiZWZvcmUgaW5zcGVjdGlvbicpCiAgICBwcm9vZiA9IGluc3BlY3RfcmVhZG9ubHkocGF0aCwgX2Nsb3NlZF9zbmFwc2hvdD1UcnVlKQogICAgYWZ0ZXIgPSBtZXRhZGF0YShwYXRoKQogICAgaWYgKGFmdGVyLnN0X2RldiwgYWZ0ZXIuc3RfaW5vLCBhZnRlci5zdF91aWQsIGFmdGVyLnN0X2dpZCwgYWZ0ZXIuc3Rfc2l6ZSkgIT0gKG1haW4uc3RfZGV2LCBtYWluLnN0X2lubywgbWFpbi5zdF91aWQsIG1haW4uc3RfZ2lkLCBtYWluLnN0X3NpemUpOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ2Zyb3plbiBtYWluLWZpbGUgaWRlbnRpdHkgY2hhbmdlZCcpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTYgb3Igc2lkZWNhcnMoKSAhPSBiZWZvcmVfc2lkZWNhcnM6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIHNuYXBzaG90IGNoYW5nZWQgZHVyaW5nIGluc3BlY3Rpb24nKQogICAgcmV0dXJuIHByb29mCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHBhcnNlciA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPV9fZG9jX18pCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWRiJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKICAgIHRyeToKICAgICAgICBwcmludChqc29uLmR1bXBzKGluc3BlY3RfcmVhZG9ubHkoYXJncy5kYiksIHNvcnRfa2V5cz1UcnVlKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmFpc2UgU3lzdGVtRXhpdCgncmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgcmVmdXNlZDsgbm8gU3RvcmUvYWRtaW4gb3BlbicpIGZyb20gTm9uZQo=" + }, + { + "digest": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "media_type": "application/json", + "content_base64": "ewogICJjb25maWdtYXAiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJ2MSIsCiAgICAiaW1tdXRhYmxlIjogdHJ1ZSwKICAgICJraW5kIjogIkNvbmZpZ01hcCIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOi9Db25maWdNYXA6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiLAogICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICB9LAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIsCiAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAidWlkIjogIjkwMTEzZDJkLTU0ZDktNGU4Mi1iMWQzLTkwYjQ5ZWJlZDJiNSIKICAgIH0sCiAgICAiY2Fub25pY2FsX2RhdGFfc2hhMjU2IjogIjhlYzQ2MmQxMjM0NzU0OGY1MDZlZWViZjFlM2M3Y2M0NzY0ODAxOWM4YTc4MzgwNGQwOWJjYzc5YjBmMjJhZjYiCiAgfSwKICAicHZjIjogewogICAgImFwaVZlcnNpb24iOiAidjEiLAogICAgImtpbmQiOiAiUGVyc2lzdGVudFZvbHVtZUNsYWltIiwKICAgICJtZXRhZGF0YSI6IHsKICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICJhcmdvY2QuYXJnb3Byb2ouaW8vdHJhY2tpbmctaWQiOiAiaW5mb3JtZWQtZGVjaXNpb246L1BlcnNpc3RlbnRWb2x1bWVDbGFpbTppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIsCiAgICAgICAgInB2Lmt1YmVybmV0ZXMuaW8vYmluZC1jb21wbGV0ZWQiOiAieWVzIiwKICAgICAgICAicHYua3ViZXJuZXRlcy5pby9ib3VuZC1ieS1jb250cm9sbGVyIjogInllcyIsCiAgICAgICAgInZvbHVtZS5iZXRhLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiLAogICAgICAgICJ2b2x1bWUua3ViZXJuZXRlcy5pby9zZWxlY3RlZC1ub2RlIjogIjIzOS42Mi4yMDUuOTIuaG9zdC5zZWN1cmVzZXJ2ZXIubmV0IiwKICAgICAgICAidm9sdW1lLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiCiAgICAgIH0sCiAgICAgICJmaW5hbGl6ZXJzIjogWwogICAgICAgICJrdWJlcm5ldGVzLmlvL3B2Yy1wcm90ZWN0aW9uIgogICAgICBdLAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICJ1aWQiOiAiZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfSwKICAgICJzcGVjIjogewogICAgICAiYWNjZXNzTW9kZXMiOiBbCiAgICAgICAgIlJlYWRXcml0ZU9uY2UiCiAgICAgIF0sCiAgICAgICJyZXNvdXJjZXMiOiB7CiAgICAgICAgInJlcXVlc3RzIjogewogICAgICAgICAgInN0b3JhZ2UiOiAiMUdpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInN0b3JhZ2VDbGFzc05hbWUiOiAibG9jYWwtcGF0aCIsCiAgICAgICJ2b2x1bWVNb2RlIjogIkZpbGVzeXN0ZW0iLAogICAgICAidm9sdW1lTmFtZSI6ICJwdmMtZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfQogIH0sCiAgInB2Y19waGFzZSI6ICJCb3VuZCIKfQo=" + }, + { + "digest": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5", + "media_type": "text/markdown", + "content_base64": "IyBWZXJzaW9uMiBwcm90ZWN0ZWQgZXhpc3Rpbmctc25hcHNob3QgcmVzY3VlIGFuZCBjb25kaXRpb25hbCBjb250aW51YXRpb24KClNhbWUgcHJvcG9zYWwgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEsIHRyaWFsIGluZmQtcHVycG9zZS0yMDI2MTAxMS1yMS4gT3JpZ2luYWwgdmVyc2lvbjEgZm91bmRlciBhY2NlcHRhbmNlIGFwcHJvdmVkIHNvdXJjZSBiYzY0OTRjZDFiMjkwNzgzZWYzYWVmMDc2M2JmMjhkMWRlYWJmNGIwLiBEcmlsbC1iYWNrdXAgY29tcGxldGVkOyBkcmlsbC1jb3B5IGZhaWxlZCBWYWx1ZUVycm9yIGJlZm9yZSBhbnkgbG9jYWxmaWxlLiBObyBpbWFnZSByb2xsb3V0IG9jY3VycmVkLiBUaGlzIGV4YWN0IGNoYW5nZWQgc291cmNlL3BsYW4vaGVscGVyIHJlcXVpcmVzIE5FVyBmb3VuZGVyIGFjY2VwdGFuY2Ugb2YgbWVtbyB2ZXJzaW9uMiBiZWZvcmUgcmVzY3VlL2NvbnRpbnVhdGlvbjsgcHJpb3IgYXBwcm92YWwgYW5kIHRlY2huaWNhbCByZXZpZXcgZG8gbm90IGFwcHJvdmUgaXQuCgojIyBGYWlsdXJlIGFuZCBuYXJyb3dseSBzZWxlY3RlZCByZXNjdWUKCk9yaWdpbmFsIHNuYXBzaG90IG1haW4xOTUzNzkyMGJ5dGVzIFNIQTg3NTZjZjgyNWRmOWU3YjViNzRiYjRhMDEwNmE1MDI3ZjVjZmYyYzU5ZmY0NWQ3YjQ4ZWVkODUyMmE3ZDMzZjMgaXMgdW5jaGFuZ2VkLiBSb290J3MgbWV0YWRhdGEtb25seSB2ZXJpZmljYXRpb24gc2hvd3MgV0FMMGJ5dGVzLCBTSE0zMjc2OGJ5dGVzLCBwcml2YXRlVUlEMTAwMDEvbW9kZTA2MDAvbmxpbmsxLCBhbmQgbm8gbG9jYWwgc25hcHNob3QuIFRoZSBvbGQgU1FMaXRlIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgZXhwbGljaXRseSBjbG9zZTsgaXRzIFdBTCByZWFkZXIgY2FuIGNyZWF0ZSBTSE0gaW5kZXhpbmcsIGFuZCB0aGUgbmV4dCBjb3B5IHJlamVjdGVkIHRoYXQgbm9uemVybyBpbmRleC4gUGxhdGZvcm0gaW5kZXBlbmRlbnRseSByZXByb2R1Y2VkIHRoaXMgb24gc3ludGhldGljIGRhdGEuIE5vIG5hdGl2ZSBEQiB3YXMgb3BlbmVkIHRvIGRpYWdub3NlIHRoZSBzaWRlY2FyIG1ldGFkYXRhLCBhbmQgbm8gbmF0aXZlIHNpZGVjYXIgaXMgZGVsZXRlZC9jaGVja3BvaW50ZWQuCgpSZXVzZSB0aGlzIGV4YWN0IGluZGVwZW5kZW50bHkgaGFzaC1ib3VuZCBmcm96ZW4gbWFpbiBzbmFwc2hvdCByYXRoZXIgdGhhbiBtYWtlIGFub3RoZXIgZHJpbGwgYmFja3VwLiBUaGUgYmFja3VwYWRtaW4gZXhpdGVkIGFmdGVyIGNyZWF0aW5nIHRoZSB1bmlxdWVseSBvd25lZCBwcml2YXRlIHNuYXBzaG90LiBPcmlnaW5hbCBzdWJzZXF1ZW50IHNuYXBzaG90IGFjY2VzcyB3YXMgcmVhZG9ubHk7IGFjdHVhbCBzZXJ2aWNlIERCIGlzIHRoZSBkaXN0aW5jdCAvZGF0YS9wcml2YXRlL3Jldmlldy5zcWxpdGUuIE9yaWdpbmFsIGpvdXJuYWwgaGFzIG9ubHkgQ09NUExFVEUgZHJpbGwtYmFja3VwIGQ2MzE4MmE3LWUxYTUtNGU4ZS1hNWYxLTJiZjMzMzNjZjE1MyBhbmQgVU5DRVJUQUlOIGRyaWxsLWNvcHkzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2MuIEl0cyBleGFjdCBTSEEgZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMSwgb3JpZ2luYWwgc291cmNlL21lbW8vcGxhbiBpZGVudGl0eSBhbmQgb3V0Y29tZXMgYXJlIHZlcmlmaWVkIGJlZm9yZS9hZnRlciBldmVyeSBuZXcgcGhhc2UuIE5vIG90aGVyIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0IGlzIGFsbG93ZWQuCgpUaGUgZXhwbGljaXRseSBuYW1lZCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBjcmVhdGVzIGEgc2VwYXJhdGUgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24vbG9jayBpbiBleGlzdGluZyBwcm90ZWN0ZWQgaWdub3JlZCBjdXN0b2R5OyBpdCBoYXNoLWxpbmtzIG9yaWdpbmFsIGF0dGVtcHRzIGFuZCBiYWNrdXByZXN1bHQgYW5kIG5ldmVyIHJld3JpdGVzL3N5bnRoZXNpemVzIHRoZSBvbGQgZmFpbGVkIHBoYXNlLiBBbnkgYXR0ZW1wdGVkIHJlc2N1ZSByZXN1bHQsIGNyYXNoIG9yIGFtYmlndW91cyBvdXRwdXQgaXMgZHVyYWJsZSBhbmQgc2FtZS1waGFzZSByZXRyeSBpcyByZWZ1c2VkLiBCZWZvcmUgcmVzY3VlOiBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgYW5kIGV4aXN0aW5nIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50OyBuYXRpdmUgb3JpZ2luYWxQb2RVSUQvY3VycmVudG9sZGltYWdlN2Y1L0FyZ283ZGIvc2VhbGVkRGVwbG95bWVudC9DTS9QVkMgbWF0Y2guIFRoZSBmaXhlZCBpbW11dGFibGUgc25hcHNob3QgcmVhZGVyIGNoZWNrcyByZWNvcmRlZCBkaWdlc3QvcHJpdmF0ZSBpZGVudGl0eS9ubyBXQUxmcmFtZXMgYmVmb3JlIGFuZCBhZnRlciBzY2hlbWE1L2ludGVncml0eS9jb3VudCB2YWxpZGF0aW9uLCByZXRhaW5pbmcgdW5jaGFuZ2VkIFNITS4gTm9uemVybyBXQUwgb3IgYW55IGlkZW50aXR5L2hhc2ggZHJpZnQgc3RvcHMgcmVzY3VlLiBTbmFwc2hvdCBiaW5hcnlzdGRvdXQgZmxvd3Mgb25seSB0byBhIG5ldzA2MDBwcml2YXRlIGZpbGUsIHdpdGggYm91bmRlZCBzaXplL2hhc2ggYW5kIHJlcGVhdCBzb3VyY2UgcHJvb2YuIEl0IG5ldmVyIHJlYWNoZXMgY2hhdC9sb2cvR2l0L1N0YXRlSHViLgoKIyMgTGl2ZS1XQUwgYW5kIGRhdGEgY29tcGF0aWJpbGl0eSBib3VuZGFyaWVzCgpMaXZlIHNvdXJjZSBhbmQgd3JpdGFibGUgb2ZmbGluZSBwcmUvcG9zdC1hZG1pbiByZWFkcyBNVVNUIHN0YXkgbW9kZT1yby9xdWVyeV9vbmx5IGFuZCBleHBsaWNpdGx5IGNsb3NlIFNRTGl0ZSBjb25uZWN0aW9ucy4gaW1tdXRhYmxlPTEgaWdub3JlcyBXQUwgYW5kIHdvdWxkIGxvc2UgY29tbWl0dGVkIGxpdmUgcm93czsgaXQgaXMgcmVzdHJpY3RlZCB0byB0aGUgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbmV2ZXIgdGhlIGxpdmVEQiBvciB3cml0YWJsZWNsb25lLiBCZWZvcmUgQU5ZIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5IFN0b3JlL2FkbWluIG9wZW4sIHJlcXVpcmUgc3RkbGliIHJlYWRvbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50czsgcmVmdXNlIG9sZHNjaGVtYXMgYmVmb3JlIGF1dG9tYXRpYyBtaWdyYXRpb24uIEZyb3plbiBzbmFwc2hvdC9jbG9uZSBjb3VudCBlcXVhbGl0eSBpcyBleGFjdDsgY3VycmVudGxpdmUgY291bnRlciBjaGFuZ2VzIG1heSByZWZsZWN0IGNvbmN1cnJlbnQgbGVnaXRpbWF0ZSBjb21taXRzIGFuZCBhcmUgcmV0YWluZWQuCgpPbmx5IGFmdGVyIENPTVBMRVRFIG5hbWVkIHJlc2N1ZSBkb2VzIG9mZmxpbmUtdmVyaWZ5IGNvbnN1bWUgaXRzIHJlc3VsdCB2aWEgZXhwbGljaXQgbWFwcGluZywgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGlzb2xhdGVkIGRpc3Bvc2FibGV2b2x1bWUgaW5mZC1wdXJwb3NlLXIxLXJlc3RvcmUtMjAyNjEwMTEgbXVzdCBiZSBhYnNlbnQvbmV3IG5vbmNlLWJvdW5kLiBPbmUgZXhhY3Q3NjNjIFVJRDAvQ0FQX0NIT1dOLW9ubHkgaW5pdGlhbGl6ZXIgcmVjZWl2ZXMgc25hcHNob3RzdGRpbiBpbnRvIHRoYXQgTkVXdm9sdW1lLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pLCBubyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50cy4gSXQgc2V0cyBmb2xkZXIwNzAwL2ZpbGUwNjAwVUlEMTAwMDEsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHByZS1vcGVuIHJlYWRvbmx5LCAtLWVudHJ5cG9pbnQgaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4gaW5zcGVjdCAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGUgYW5kIHBvc3QtYWRtaW4gcmVhZG9ubHkgZnVsbHByb29mOyBvcmlnaW5hbCBwcm90ZWN0ZWQgU0hBIG11c3QgcmVtYWluIHVuY2hhbmdlZC4gTm8gc2VydmljZWVudHJ5cG9pbnQgc3RhcnRzLiBDbGVhbnVwIG9ubHkgdGhpcyBkaXNwb3NhYmxlIHZvbHVtZSwgcmV0YWluaW5nIG9yaWdpbmFsIG5hdGl2ZS9vZmZjbHVzdGVyIHNuYXBzaG90cy9zaWRlY2Fycy4KCiMjIENvbmRpdGlvbmFsIHJlbWFpbmluZyBwaGFzZXMgYW5kIHJlbGVhc2UvcmVjb3ZlcnkKCk5ld2pvdXJuYWwgZml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnkuIGN1dG92ZXItYmFja3VwIHVzZXMgZGlzdGluY3QgbmV3Y3V0b3Zlci5zcWxpdGUgaW4gb3JpZ2luYWxwcml2YXRlY2FzZSBkaXJlY3RvcnksIGFmdGVyIHJlYWRvbmx5IGxpdmUgc2NoZW1hNS9jYXBhY2l0eSBnYXRlcywgU1FMaXRlYmFja3VwQVBJL2FkbWluIGNvbXBsZXRpb24sIGNsb3NlZC1tYWluIGltbXV0YWJsZSBwcm9vZjsgZG8gbm90IG92ZXJ3cml0ZSBvcmlnaW5hbHMgb3IgcmV0cnlmYWlsZWRwYXRocy4gVmVyc2lvbjIgYWNjZXB0YW5jZSBjb25kaXRpb25hbGx5IGFwcHJvdmVzIHRoZXNlIGV4YWN0IHVuY2hhbmdlZCByZW1haW5pbmcgb3BlcmF0aW9ucyBvbmx5IGFmdGVyIHJlc2N1ZStkcmlsbGdhdGVzLiBBbGwgZm91ciBjb21taXR0ZWQgS3VzdG9taXplIEdpdCBibG9icy9jdXJyZW50SEVBRCwgZXhhY3QgaGVscGVyL2Nhc2UgaGFzaGVzLCBDTS9QVkMvRGVwbG95bWVudCBzZWFscyBhbmQgbWFudWFsQXBwbGljYXRpb24obm8gYXV0b21hdGVke30gb3Igc291cmNlb3ZlcnJpZGUpIG11c3QgbWF0Y2guCgpSZWxlYXNlIHJldGFpbnMgZXhpc3RpbmcgcmVwbGljYTEvUmVjcmVhdGUvY29uZmlnNmMvc2NoZW1hNS9QVkMvY3JlZGVudGlhbHMvcG9saWNpZXM6IHNvdXJjZXBpbiBBcHBsaWNhdGlvbi5vcGVyYXRpb24gc2VydmVyZHJ5cnVuL1VJRCtyZXNvdXJjZVZlcnNpb24rc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5IGltYWdlNzYzYywgcHJ1bmU9ZmFsc2UuIE5vIHdob2xlLWFwcCBzeW5jL2Fkb3B0aW9uLiBWZXJpZnkgcmVxdWlyZXMgc3VjY2VlZGVkIGV4YWN0c2NvcGUvY29udHJvbGxlcmdlbmVyYXRpb24vUmVhZHkxLCBpbnN0YWxsZWRwb2xpY3loYXNoL21vZGVVSUQvMTBzeW50aGV0aWNwdXJwb3NldmFyaWFudHMrYm91bmRlZGhlYWx0aCwgc2FtZSBjdXJyZW50bGl2ZURCIHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50cy4gVGhvc2UgaW5zdGFsbGVkY2hlY2tzIHJlcG9ydCBuYXRpdmVfcHJvdmlkZXI9ZmFsc2U7IGFjdHVhbHByb3ZpZGVyL1BEUGF1dGhvcml0eSBldmlkZW5jZSByZW1haW5zIGEgc2VwYXJhdGUgVDA0Z2F0ZS4KClJvbGxiYWNrIGFmdGVyIHJlY29yZGVkIG5ld3JlbGVhc2UgYXR0ZW1wdCBwaW5zIHByaW9yN2RiLzdmNSBhbmQgcmV0YWlucyBsYXRlc3RzY2hlbWE1REIsIHdpdGhvdXQgcmVxdWlyaW5nIFJlYWR5IGZhaWxpbmdjYW5kaWRhdGUgb3IgY2FuZGlkYXRlREJleGVjLiBTZXBhcmF0ZSByb2xsYmFjay12ZXJpZnkgcHJvdmVzIG9sZGltYWdlUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9yZWFkb25seXNjaGVtYTUgY3VycmVudERCIGludGVncml0eS4gTmV2ZXIgcmVzdG9yZSBhbiBvbGRlciBzbmFwc2hvdCBvdmVyIHBvc3RjdXRvdmVycmVjb3Jkcy4gQW55IGRhdGEgcmVjb3ZlcnkgYmV5b25kIHRoaXMgc2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sgbmVlZHMgYW5vdGhlciBkZWNpc2lvbi4KCkFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZSwgdmVyaWZpY2F0aW9uIGFuZCByZWNvdmVyeSBtdXN0IGJlZ2luIGJlZm9yZTIwMjYtMTAtMTJUMjM6NTk6NTlaLiBTdGFydCBlYXJseSBlbm91Z2g7IGlmIGV4cGlyZWQgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbiwgd2hpY2ggbWF5IGRlbGF5IHJlY292ZXJ5LiBObyBhdXRvbWF0aWMgdGltZXIvY29udHJvbGxlci9leHRlbnNpb24uIFJvb3QgZnJlc2hseSBhdXRoZW50aWNhdGVzIGV4YWN0IGNvbmZpcm1lZCBwbGF0Zm9ybS1yb290IHBlcnNvbiBBQ0NFUFQgbWVtbyB2ZXJzaW9uMiBhdCBmaXhlZG5hdGl2ZW9yaWdpbiBiZWZvcmUgZXZlcnkgcGhhc2U7IHByb3RlY3RlZHJlY2VpcHRyZWxhdGlvbi9mcmVzaG5lc3MxMjBzZWMgaXMgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3QgYSBzaWduZWQvYXV0b25vbW91cyBncmFudC4KCkltYWdlNzYzYy9wb2xpY3k5ZDdjL2Jhc2U3ZjUgYW5kIGFjdHVhbHVuZmlsdGVyZWRzY2FuMEhJR0gvQ1JJVElDQUwvMWZpeGFibGVNRURJVU16bGliIHJlbWFpbiB1bmNoYW5nZWQsIG93bmVyIElORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxL1QwNSBkdWVPY3QxOC4gVGhlIGV4YWN0YnVuZGxlIGRpcmVjdGx5IGJpbmRzIGhlbHBlci9wbGFuL3Rlc3RzIHBsdXMgb3JpZ2luYWwgY291bnQtb25seWJhY2t1cC9mYWlsdXJlL2FuY2hvci4gRXhpc3RpbmdwdWJsaXNoZWRyZWNlaXB0IHN0aWxsIGJpbmRzIHVuY2hhbmdlZCByYXdzY2FuL1NCT00vYmFzZSBzY2FuOyBubyBzdXBwcmVzc2lvbi4gUHJlc2VydmUgb3JpZ2luYWxhcHByb3ZlZDIwZG9jcGFja2V0L2hlbHBlcnMvaGlzdG9yeSBpbiBpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkLiBObyB2ZXJzaW9uMiBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4uIEVVUjAgcmVjdXJyaW5naW5mcmFzdHJ1Y3R1cmU7IHByaXZhdGUgYm91bmRlZHN0b3JhZ2UvYXR0ZW5kZWR0aW1lIHVucHJpY2VkLCBubyBuZXdkcmlsbGJhY2t1cCBvciBhdXRvbm9teWdyYW50LgoKTmF0aXZlIHNvdXJjZSBwdWJsaWNhdGlvbiB1c2VzIGV4YWN0IHJldmlzaW9uLWNvbW1hbmQuanNvbiB2aWEgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMsIGV4cGVjdGVkX3ZlcnNpb24xLCBvbmx5IGFmdGVyIGZyZXNoIHVuYm91bmQtc291cmNlIHJlYWRiYWNrLiBObyB2ZXJzaW9uMiBpbnRha2UvcmVnaXN0ZXIuIFB1Ymxpc2gvcmV2aWV3IHNvdXJjZXZlcnNpb24yOyBuZXcgaHVtYW4gcmV2aWV3LUlEIGlzIG93bnZlcnNpb24xLCBzbyBpdHMgY29uZmlybWVkIG5lc3RlZCBkaXNwb3NpdGlvbiBtZW1vX3ZlcnNpb24xIGlzIGNvcnJlY3QuIFJvb3QgYWN0dWFsIG91dGNvbWVzIHF1ZXJ5IG11c3QgbmFtZSBTT1VSQ0UgdmVyc2lvbjIgYW5kIGV4YWN0IG5ld3Jldmlld0lEOyBvcmlnaW5hbCByZXZpZXcvYXBwcm92YWwgY2Fubm90IGJlIHJldXNlZC4K" + }, + { + "digest": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101", + "media_type": "application/json", + "content_base64": "ewogICJpZCI6ICJJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSIsCiAgImtpbmQiOiAib3duZXItdnVsbmVyYWJpbGl0eS1mb2xsb3ctdGhyb3VnaCIsCiAgIm93bmVyIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAidGFzayI6ICJJTkZELVdQLTAwMDktVDA1IiwKICAic3RhdHVzIjogIm9wZW4iLAogICJjcmVhdGVkIjogIjIwMjYtMTAtMTEiLAogICJyZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJmaW5kaW5nIjogIkNWRS0yMDI2LTg1MDkxIiwKICAic2Nhbm5lcl9zZXZlcml0eSI6ICJNRURJVU0iLAogICJlc3RhdGVfcmlza19ncmFkZSI6IG51bGwsCiAgImFmZmVjdGVkX3BhY2thZ2UiOiAiemxpYiIsCiAgImluc3RhbGxlZCI6ICIxLjMuMi1yMCIsCiAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAiYWN0dWFsX2N1cnJlbnRfYmFzZV9hbmRfY2FuZGlkYXRlX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgInNvdXJjZV9ldmlkZW5jZSI6ICJzZWN1cml0eS1zdW1tYXJ5Lmpzb24sIHRyaXZ5LWZ1bGwuanNvbiwgYmFzZS10cml2eS1mdWxsLmpzb24iLAogICJodW1hbl90ZW1wb3JhcnlfZGlzcG9zaXRpb24iOiAicGVuZGluZyIsCiAgImZvbGxvd190aHJvdWdoIjogIlByZXBhcmUgYSBzZXBhcmF0ZWx5IHNvdXJjZS1ib3VuZCBvZmZpY2lhbC1iYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCB0aHJvdWdoIG5vcm1hbCBvd25lciBDSSwgdmVyaWZ5IGZ1bGwgc2NhbiBhbmQgcnVudGltZSBjb21wYXRpYmlsaXR5LCBvYnRhaW4gZGlzdGluY3QgbmF0aXZlIHJlbGVhc2UgYXBwcm92YWwgYmVmb3JlIHVwZGF0aW5nIHRoaXMgd29ya2xvYWQiLAogICJtYW51YWxfcmV2aWV3X2V4cGlyeSI6ICJEdWUgZGF0ZSByZXF1aXJlcyBvd25lciByZXZpZXcvZXNjYWxhdGlvbiBpZiB1bnJlc29sdmVkOyBubyBhdXRvbWF0aWMgcm9sbGJhY2svY29udHJvbGxlciBpcyBpbnN0YWxsZWQiLAogICJjbG9zZV9jb25kaXRpb24iOiAiVmVyaWZpZWQgaW5zdGFsbGVkIG5hdGl2ZSBmaXhlZCBwYWNrYWdlIGFuZCBmdWxsIHVuZmlsdGVyZWQgcmVzY2FuOyBwcmVzZXJ2ZSBvcmlnaW5hbCBkZXRlY3Rpb24gYW5kIGFueSBodW1hbiBkaXNwb3NpdGlvbiIKfQo=" + }, + { + "digest": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "media_type": "application/json", + "content_base64": "ewogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjI1OjM4Ljc5MzU1NSswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibGl2ZV9yZWFkeV9yZXBsaWNhcyI6IDEsCiAgImFkbWl0dGVkX3VpZCI6ICJhNTg4ZTEwYS05MGQyLTQ4ODMtOTc1ZS02ZGQ4YjhmZWNhOTIiLAogICJzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWQiOiB0cnVlLAogICJhZG1pdHRlZF9zcGVjX2V4YWN0bHlfbGl2ZV9wbHVzX2ltYWdlIjogdHJ1ZSwKICAiY2xpZW50X2RpZmZfZXhpdCI6IDEsCiAgImNsaWVudF9kaWZmX3NoYTI1NiI6ICJhNGJjMDI0YThjZWM2NThmODM1Mjg1ZWQ1MTk2NGUyZTA4NGVkYmFmMTAzZDQ1YTQ4Yjg5YzA5NTBiY2QzZTdkIiwKICAibm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzIjogIihUb3RhbCBsaW1pdHMgbWF5IGJlIG92ZXIgMTAwIHBlcmNlbnQsIGkuZS4sIG92ZXJjb21taXR0ZWQuKVxuICBSZXNvdXJjZSAgICAgICAgICAgUmVxdWVzdHMgICAgICBMaW1pdHNcbiAgLS0tLS0tLS0gICAgICAgICAgIC0tLS0tLS0tICAgICAgLS0tLS0tXG4gIGNwdSAgICAgICAgICAgICAgICAzNDYwbSAoODYlKSAgIDM2MjAwbSAoOTA1JSlcbiAgbWVtb3J5ICAgICAgICAgICAgIDk0NzJNaSAoNTklKSAgMzI4OThNaSAoMjA1JSlcbiAgZXBoZW1lcmFsLXN0b3JhZ2UgIDAgKDAlKSAgICAgICAgMCAoMCUpXG4gIGh1Z2VwYWdlcy0xR2kgICAgICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMk1pICAgICAgMCAoMCUpICAgICAgICAwICgwJSkiLAogICJhbGxfY2hlY2tzX3Bhc3MiOiB0cnVlCn0K" + }, + { + "digest": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImFyZ29jZC5hcmdvcHJvai5pby90cmFja2luZy1pZCI6ICJpbmZvcm1lZC1kZWNpc2lvbjphcHBzL0RlcGxveW1lbnQ6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICJ1aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInJldmlzaW9uSGlzdG9yeUxpbWl0IjogMTAsCiAgICAic2VsZWN0b3IiOiB7CiAgICAgICJtYXRjaExhYmVscyI6IHsKICAgICAgICAiYXBwLmt1YmVybmV0ZXMuaW8vbmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIKICAgICAgfQogICAgfSwKICAgICJzdHJhdGVneSI6IHsKICAgICAgInR5cGUiOiAiUmVjcmVhdGUiCiAgICB9LAogICAgInRlbXBsYXRlIjogewogICAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiCiAgICAgICAgfSwKICAgICAgICAibGFiZWxzIjogewogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ICJyZXZpZXciLAogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgICAgfQogICAgICB9LAogICAgICAic3BlYyI6IHsKICAgICAgICAiYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbiI6IGZhbHNlLAogICAgICAgICJjb250YWluZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiZW52IjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIklORkRfS0VZQ0FQRV9JU1NVRVIiLAogICAgICAgICAgICAgICAgInZhbHVlIjogImh0dHBzOi8va2MuY291bG9tYi5zb2NpYWwiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0NPTlRBSU5FUl9DT05GSUciLAogICAgICAgICAgICAgICAgInZhbHVlIjogIi9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvbiIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICAgICAgICAgICAiaW1hZ2VQdWxsUG9saWN5IjogIklmTm90UHJlc2VudCIsCiAgICAgICAgICAgICJsaXZlbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICAgICAgICJwb3J0cyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODAsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJodHRwIiwKICAgICAgICAgICAgICAgICJwcm90b2NvbCI6ICJUQ1AiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIsCiAgICAgICAgICAgICAgICAicHJvdG9jb2wiOiAiVENQIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlYWRpbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVzb3VyY2VzIjogewogICAgICAgICAgICAgICJsaW1pdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjUwMG0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICIyNTZNaSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZXF1ZXN0cyI6IHsKICAgICAgICAgICAgICAgICJjcHUiOiAiNW0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICI2NE1pIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInNlY3VyaXR5Q29udGV4dCI6IHsKICAgICAgICAgICAgICAiYWxsb3dQcml2aWxlZ2VFc2NhbGF0aW9uIjogZmFsc2UsCiAgICAgICAgICAgICAgImNhcGFiaWxpdGllcyI6IHsKICAgICAgICAgICAgICAgICJkcm9wIjogWwogICAgICAgICAgICAgICAgICAiQUxMIgogICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInJlYWRPbmx5Um9vdEZpbGVzeXN0ZW0iOiB0cnVlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzdGFydHVwUHJvYmUiOiB7CiAgICAgICAgICAgICAgImZhaWx1cmVUaHJlc2hvbGQiOiAxMiwKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAidGVybWluYXRpb25NZXNzYWdlUGF0aCI6ICIvZGV2L3Rlcm1pbmF0aW9uLWxvZyIsCiAgICAgICAgICAgICJ0ZXJtaW5hdGlvbk1lc3NhZ2VQb2xpY3kiOiAiRmlsZSIsCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJkbnNQb2xpY3kiOiAiQ2x1c3RlckZpcnN0IiwKICAgICAgICAicmVzdGFydFBvbGljeSI6ICJBbHdheXMiLAogICAgICAgICJzY2hlZHVsZXJOYW1lIjogImRlZmF1bHQtc2NoZWR1bGVyIiwKICAgICAgICAic2VjdXJpdHlDb250ZXh0IjogewogICAgICAgICAgImZzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJmc0dyb3VwQ2hhbmdlUG9saWN5IjogIk9uUm9vdE1pc21hdGNoIiwKICAgICAgICAgICJydW5Bc0dyb3VwIjogMTAwMDEsCiAgICAgICAgICAicnVuQXNOb25Sb290IjogdHJ1ZSwKICAgICAgICAgICJydW5Bc1VzZXIiOiAxMDAwMSwKICAgICAgICAgICJzZWNjb21wUHJvZmlsZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiUnVudGltZURlZmF1bHQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic2VydmljZUFjY291bnQiOiAicmV2aWV3IiwKICAgICAgICAic2VydmljZUFjY291bnROYW1lIjogInJldmlldyIsCiAgICAgICAgInRlcm1pbmF0aW9uR3JhY2VQZXJpb2RTZWNvbmRzIjogNDUsCiAgICAgICAgInZvbHVtZXMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImRhdGEiLAogICAgICAgICAgICAicGVyc2lzdGVudFZvbHVtZUNsYWltIjogewogICAgICAgICAgICAgICJjbGFpbU5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tZGF0YSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImVtcHR5RGlyIjogewogICAgICAgICAgICAgICJtZWRpdW0iOiAiTWVtb3J5IiwKICAgICAgICAgICAgICAic2l6ZUxpbWl0IjogIjE2TWkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImNvbmZpZ3VyYXRpb24iCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJjYWxsZXIiLAogICAgICAgICAgICAicHJvamVjdGVkIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAic291cmNlcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgInNlcnZpY2VBY2NvdW50VG9rZW4iOiB7CiAgICAgICAgICAgICAgICAgICAgImF1ZGllbmNlIjogImZsZXgtYXV0aCIsCiAgICAgICAgICAgICAgICAgICAgImV4cGlyYXRpb25TZWNvbmRzIjogMzYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiYXVkaXQiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAidG9rZW4iLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJzZWNyZXROYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLWF1ZGl0IgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiA2MDAsCiAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAidG9rZW4iCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAia2V5IjogImNhLmNydCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXRoIjogImNhLmNydCIKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICJuYW1lIjogImt1YmUtcm9vdC1jYS5jcnQiCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjkyLAogICAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgInNlY3JldCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAia2V5IjogImNsaWVudC1zZWNyZXQiLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJjbGllbnQtc2VjcmV0IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm9wdGlvbmFsIjogZmFsc2UsCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy1yZXF1ZXN0ZXIiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0KICAgIH0KICB9Cn0K" + }, + { + "digest": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IGV4YWN0IERlcGxveW1lbnQgYW5kIGFkbWlzc2lvbiBib3VuZGFyaWVzOyBubyBtdXRhdGlvbiBhdXRob3JpdHkuIiIiCmltcG9ydCBjb3B5CmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCgpCQVNFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MycKQ0FORElEQVRFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYScKCgpkZWYgZGVwZW5kZW5jeV9wcm9qZWN0aW9uKGNvbmZpZ21hcCwgcHZjKToKICAgIGlmIChjb25maWdtYXAuZ2V0KCdraW5kJykgIT0gJ0NvbmZpZ01hcCcgb3IgY29uZmlnbWFwLmdldCgnaW1tdXRhYmxlJykgaXMgbm90IFRydWUKICAgICAgICAgICAgb3IgY29uZmlnbWFwWydtZXRhZGF0YSddWyduYW1lc3BhY2UnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24nCiAgICAgICAgICAgIG9yIGNvbmZpZ21hcFsnbWV0YWRhdGEnXVsnbmFtZSddICE9ICdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MScKICAgICAgICAgICAgb3Igc2V0KGNvbmZpZ21hcC5nZXQoJ2RhdGEnLCB7fSkpICE9IHsncnVudGltZS5qc29uJ30KICAgICAgICAgICAgb3IgY29uZmlnbWFwLmdldCgnYmluYXJ5RGF0YScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGltbXV0YWJsZSBydW50aW1lIGNvbmZpZyBpZGVudGl0eScpCiAgICBpZiAocHZjLmdldCgna2luZCcpICE9ICdQZXJzaXN0ZW50Vm9sdW1lQ2xhaW0nCiAgICAgICAgICAgIG9yIHB2Y1snbWV0YWRhdGEnXVsnbmFtZXNwYWNlJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJwogICAgICAgICAgICBvciBwdmNbJ21ldGFkYXRhJ11bJ25hbWUnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24tZGF0YScKICAgICAgICAgICAgb3IgcHZjLmdldCgnc3RhdHVzJywge30pLmdldCgncGhhc2UnKSAhPSAnQm91bmQnCiAgICAgICAgICAgIG9yIG5vdCBwdmMuZ2V0KCdzcGVjJywge30pLmdldCgndm9sdW1lTmFtZScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGJvdW5kIFBWQyBjdXN0b2R5JykKICAgIGNvbmZpZyA9IHByb2plY3Rpb24oY29uZmlnbWFwKQogICAgY29uZmlnLnBvcCgnZGF0YScpCiAgICBjb25maWdbJ2Nhbm9uaWNhbF9kYXRhX3NoYTI1NiddID0gaGFzaGxpYi5zaGEyNTYoanNvbi5kdW1wcygKICAgICAgICBjb25maWdtYXBbJ2RhdGEnXSwgc29ydF9rZXlzPVRydWUsIHNlcGFyYXRvcnM9KCcsJywgJzonKSkuZW5jb2RlKCkpLmhleGRpZ2VzdCgpCiAgICByZXR1cm4geydjb25maWdtYXAnOiBjb25maWcsICdwdmMnOiBwcm9qZWN0aW9uKHB2YyksICdwdmNfcGhhc2UnOiAnQm91bmQnfQoKCmRlZiBjaGVja19kZXBlbmRlbmNpZXMoY29uZmlnbWFwLCBwdmMsIHNlYWxlZCk6CiAgICBpZiBkZXBlbmRlbmN5X3Byb2plY3Rpb24oY29uZmlnbWFwLCBwdmMpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdydW50aW1lIGNvbmZpZyBvciBQVkMgaWRlbnRpdHkvY3VzdG9keSBjaGFuZ2VkJykKCgpkZWYgcHJvamVjdGlvbih2YWx1ZSk6CiAgICB2YWx1ZSA9IGNvcHkuZGVlcGNvcHkodmFsdWUpCiAgICB2YWx1ZS5wb3AoJ3N0YXR1cycsIE5vbmUpCiAgICBmb3Iga2V5IGluICgncmVzb3VyY2VWZXJzaW9uJywgJ2dlbmVyYXRpb24nLCAnY3JlYXRpb25UaW1lc3RhbXAnLCAnbWFuYWdlZEZpZWxkcycpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLnBvcChrZXksIE5vbmUpCiAgICBmb3Iga2V5IGluICgna3ViZWN0bC5rdWJlcm5ldGVzLmlvL2xhc3QtYXBwbGllZC1jb25maWd1cmF0aW9uJywgJ2RlcGxveW1lbnQua3ViZXJuZXRlcy5pby9yZXZpc2lvbicpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLmdldCgnYW5ub3RhdGlvbnMnLCB7fSkucG9wKGtleSwgTm9uZSkKICAgIHJldHVybiB2YWx1ZQoKCmRlZiBjaGVja19jdXJyZW50KGN1cnJlbnQsIHNlYWxlZCk6CiAgICBpZiBwcm9qZWN0aW9uKGN1cnJlbnQpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzZWFsZWQgbGl2ZSBVSUQgb3IgY29uZmlndXJhdGlvbiBjaGFuZ2VkJykKCgpkZWYgY2hlY2tfYWRtaXR0ZWQoYWRtaXR0ZWQsIHNlYWxlZCk6CiAgICBleHBlY3RlZCA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKQogICAgY29udGFpbmVycyA9IGV4cGVjdGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddCiAgICBpZiBsZW4oY29udGFpbmVycykgIT0gMSBvciBjb250YWluZXJzWzBdWyduYW1lJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJyBvciBjb250YWluZXJzWzBdWydpbWFnZSddICE9IEJBU0U6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigndW5leHBlY3RlZCBiYXNlbGluZSBjb250YWluZXIgaWRlbnRpdHknKQogICAgY29udGFpbmVyc1swXVsnaW1hZ2UnXSA9IENBTkRJREFURQogICAgaWYgcHJvamVjdGlvbihhZG1pdHRlZCkgIT0gZXhwZWN0ZWQ6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignYWRtaXNzaW9uIGNoYW5nZWQgY29uZmlndXJhdGlvbiBiZXlvbmQgdGhlIHNvbGUgaW1hZ2UgcGluJykKCgpkZWYgdHJhbnNwb3J0X3Jlc3VsdChleGl0X2NvZGUsIG91dHB1dCk6CiAgICBpbXBvcnQganNvbgogICAgdHJ5OgogICAgICAgIHZhbHVlID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6CiAgICAgICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdyZWFzb24nOiAnaW52YWxpZCB0cmFuc3BvcnQgcmVzdWx0J30KICAgIGlmIGV4aXRfY29kZSAhPSAwIG9yIG5vdCBpc2luc3RhbmNlKHZhbHVlLCBkaWN0KSBvciB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIG5vdCBUcnVlOgogICAgICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncmVhc29uJzogJ3JlYWQtb25seSBwcmVmbGlnaHQgcmVmdXNlZCd9CiAgICByZXR1cm4gdmFsdWUK" + }, + { + "digest": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IHJlZnJlc2g7IGV4YWN0IG9yaWdpbmFsIGNhcHR1cmUgcmVtYWlucyBpbW11dGFibGU7IG5ldmVyIGV4ZWN1dGUgY3V0b3Zlci4iIiIKaW1wb3J0IGFyZ3BhcnNlLGhhc2hsaWIsanNvbixzdWJwcm9jZXNzLHN5cwpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaWYgc3lzLmZsYWdzLm9wdGltaXplOgogcmFpc2UgU3lzdGVtRXhpdCgib3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQgYmVmb3JlIHNvdXJjZS90cmFuc3BvcnQgZXhlY3V0aW9uIikKUk9PVD1QYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50CnA9YXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKTtwLmFkZF9hcmd1bWVudCgnLS1yZWNlaXB0LW91dHB1dCcsdHlwZT1QYXRoLHJlcXVpcmVkPVRydWUpO3AuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yb290Jyx0eXBlPVBhdGgsZGVmYXVsdD1QYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24nKSk7YT1wLnBhcnNlX2FyZ3MoKQpvdXQ9YS5yZWNlaXB0X291dHB1dC5yZXNvbHZlKCkKaWYgbm90IGEucmVjZWlwdF9vdXRwdXQuaXNfYWJzb2x1dGUoKSBvciBvdXQ9PVJPT1Qgb3IgUk9PVCBpbiBvdXQucGFyZW50cyBvciBvdXQ9PWEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIG9yIGEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIGluIG91dC5wYXJlbnRzIG9yIG91dC5leGlzdHMoKToKIHJhaXNlIFN5c3RlbUV4aXQoJ3VuaXF1ZSBleGVjdXRpb24gcmVjZWlwdCBtdXN0IGJlIG91dHNpZGUgdGhlIHNlYWxlZCBwYWNrZXQnKQppbnB1dHM9anNvbi5sb2FkcygoUk9PVC8ncHJlZmxpZ2h0LWlucHV0cy5qc29uJykucmVhZF90ZXh0KCkpCmZvciByZWxhdGl2ZSxkaWdlc3QgaW4gaW5wdXRzWydwYWNrZXRfZmlsZXMnXS5pdGVtcygpOgogcGF0aD1ST09UL3JlbGF0aXZlCiBpZiBwYXRoLmlzX3N5bWxpbmsoKSBvciBoYXNobGliLnNoYTI1NihwYXRoLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCkhPWRpZ2VzdDpyYWlzZSBTeXN0ZW1FeGl0KCdzZWFsZWQgaGVscGVyL2lucHV0IGJ5dGVzIGNoYW5nZWQnKQpmb3IgcmVsYXRpdmUsZGlnZXN0IGluIGlucHV0c1snb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKToKIHBhdGg9YS5zb3VyY2Vfcm9vdC9yZWxhdGl2ZQogaWYgcGF0aC5pc19zeW1saW5rKCkgb3IgaGFzaGxpYi5zaGEyNTYocGF0aC5yZWFkX2J5dGVzKCkpLmhleGRpZ2VzdCgpIT1kaWdlc3Q6cmFpc2UgU3lzdGVtRXhpdCgnb3duZXIgc291cmNlIGJ5dGVzIGNoYW5nZWQnKQpmcm9tIGNoYW5nZV9ndWFyZCBpbXBvcnQgdHJhbnNwb3J0X3Jlc3VsdApwcm9ncmFtPSdpbXBvcnQgc3VicHJvY2Vzcyxqc29uLGhhc2hsaWIsZGF0ZXRpbWUsc3lzLGNvcHkscmVcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoIm9wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkIilcbmNhbmRpZGF0ZT1qc29uLmxvYWRzKENBTkRJREFURV9MSVRFUkFMKVxuc2VhbGVkX2RlcGVuZGVuY2llcz1qc29uLmxvYWRzKERFUEVOREVOQ0lFU19MSVRFUkFMKVxuc2VhbGVkX2Jhc2VsaW5lPWpzb24ubG9hZHMoU0VBTEVEX0xJVEVSQUwpXG5leGVjKEdVQVJEX0xJVEVSQUwpXG5kZWYgcnVuKGFyZ3MsZGF0YT1Ob25lKTpcbiBwPXN1YnByb2Nlc3MucnVuKGFyZ3MsaW5wdXQ9ZGF0YSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSlcbiBpZiBwLnJldHVybmNvZGU6IHJhaXNlIFZhbHVlRXJyb3IoXCdyZWFkLW9ubHkgY29tbWFuZCBmYWlsZWQ6IFwnK2FyZ3NbMV0rXCcgXCcrYXJnc1syXSlcbiByZXR1cm4gcC5zdGRvdXRcbmxpdmU9anNvbi5sb2FkcyhydW4oW1wna3ViZWN0bFwnLFwnZ2V0XCcsXCdkZXBsb3ltZW50XCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2luZm9ybWVkLWRlY2lzaW9uXCcsXCctb1wnLFwnanNvblwnXSkpXG5jbT1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2NvbmZpZ21hcFwnLFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcJyxcJy1uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW9cJyxcJ2pzb25cJ10pKVxucHZjPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwncHZjXCcsXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXCcsXCctblwnLFwnaW5mb3JtZWQtZGVjaXNpb25cJyxcJy1vXCcsXCdqc29uXCddKSlcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsc2VhbGVkX2RlcGVuZGVuY2llcylcbmNoZWNrX2N1cnJlbnQobGl2ZSxzZWFsZWRfYmFzZWxpbmUpXG5zcGVjPWxpdmVbXCdzcGVjXCddOyBjcz1zcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wnY29udGFpbmVyc1wnXTthc3NlcnQgbGVuKGNzKT09MSBhbmQgY3NbMF1bXCduYW1lXCddPT1cJ2luZm9ybWVkLWRlY2lzaW9uXCdcbmV4cGVjdGVkX2Vudj17XCdJTkZEX0tFWUNBUEVfSVNTVUVSXCc6XCdodHRwczovL2tjLmNvdWxvbWIuc29jaWFsXCcsXCdJTkZEX0NPTlRBSU5FUl9DT05GSUdcJzpcJy9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvblwnfVxuYXNzZXJ0IGNzWzBdLmdldChcJ2VudlwnKT09W3tcJ25hbWVcJzpcJ0lORkRfS0VZQ0FQRV9JU1NVRVJcJyxcJ3ZhbHVlXCc6ZXhwZWN0ZWRfZW52W1wnSU5GRF9LRVlDQVBFX0lTU1VFUlwnXX0se1wnbmFtZVwnOlwnSU5GRF9DT05UQUlORVJfQ09ORklHXCcsXCd2YWx1ZVwnOmV4cGVjdGVkX2VudltcJ0lORkRfQ09OVEFJTkVSX0NPTkZJR1wnXX1dXG5hc3NlcnQgY3NbMF1bXCdpbWFnZVwnXT09XCdmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcJ1xuYXNzZXJ0IHNwZWNbXCdyZXBsaWNhc1wnXT09MSBhbmQgc3BlY1tcJ3N0cmF0ZWd5XCddPT17XCd0eXBlXCc6XCdSZWNyZWF0ZVwnfVxuYXNzZXJ0IG5leHQodiBmb3IgdiBpbiBzcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wndm9sdW1lc1wnXSBpZiB2W1wnbmFtZVwnXT09XCdjb25maWd1cmF0aW9uXCcpW1wnY29uZmlnTWFwXCddW1wnbmFtZVwnXT09XCdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MVwnXG5hc3NlcnQgbGl2ZVtcJ3N0YXR1c1wnXS5nZXQoXCdyZWFkeVJlcGxpY2FzXCcpPT0xIGFuZCBsaXZlW1wnc3RhdHVzXCddLmdldChcJ3VwZGF0ZWRSZXBsaWNhc1wnKT09MVxuc2VhbGVkPXtcJ2FwaVZlcnNpb25cJzpsaXZlW1wnYXBpVmVyc2lvblwnXSxcJ2tpbmRcJzpsaXZlW1wna2luZFwnXSxcJ21ldGFkYXRhXCc6e2s6Y29weS5kZWVwY29weSh2KSBmb3Igayx2IGluIGxpdmVbXCdtZXRhZGF0YVwnXS5pdGVtcygpIGlmIGsgbm90IGluIChcJ3Jlc291cmNlVmVyc2lvblwnLFwnZ2VuZXJhdGlvblwnLFwnY3JlYXRpb25UaW1lc3RhbXBcJyxcJ21hbmFnZWRGaWVsZHNcJyl9LFwnc3BlY1wnOmNvcHkuZGVlcGNvcHkoc3BlYyl9XG5mb3Iga2V5IGluIChcJ2t1YmVjdGwua3ViZXJuZXRlcy5pby9sYXN0LWFwcGxpZWQtY29uZmlndXJhdGlvblwnLFwnZGVwbG95bWVudC5rdWJlcm5ldGVzLmlvL3JldmlzaW9uXCcpOnNlYWxlZFtcJ21ldGFkYXRhXCddLmdldChcJ2Fubm90YXRpb25zXCcse30pLnBvcChrZXksTm9uZSlcbmFkbWl0dGVkPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2FwcGx5XCcsXCctLWRyeS1ydW49c2VydmVyXCcsXCctZlwnLFwnLVwnLFwnLW9cJyxcJ2pzb25cJ10sanNvbi5kdW1wcyhjYW5kaWRhdGUpKSlcbmNoZWNrX2FkbWl0dGVkKGFkbWl0dGVkLHNlYWxlZF9iYXNlbGluZSlcbmFwcD1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2FwcGxpY2F0aW9uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2FyZ29jZFwnLFwnLW9cJyxcJ2pzb25cJ10pKVxuYXNzZXJ0IGFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCdwYXRoXCddPT1cJ2RlcGxveS9saWZlY3ljbGVcJyBhbmQgbm90IGFwcFtcJ3NwZWNcJ10uZ2V0KFwnc3luY1BvbGljeVwnLHt9KS5nZXQoXCdhdXRvbWF0ZWRcJylcbmFyZ289e1wndWlkXCc6YXBwW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdyZXBvVVJMXCc6YXBwW1wnc3BlY1wnXVtcJ3NvdXJjZVwnXVtcJ3JlcG9VUkxcJ10sXCd0YXJnZXRSZXZpc2lvblwnOmFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCd0YXJnZXRSZXZpc2lvblwnXSxcJ3BhdGhcJzphcHBbXCdzcGVjXCddW1wnc291cmNlXCddW1wncGF0aFwnXSxcJ2Rlc3RpbmF0aW9uXCc6YXBwW1wnc3BlY1wnXVtcJ2Rlc3RpbmF0aW9uXCddLFwnYXV0b21hdGVkXCc6RmFsc2UsXCdzeW5jXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdzeW5jXCcpLFwnaGVhbHRoXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdoZWFsdGhcJyl9XG5leHBlY3RlZF9hcmdvPWpzb24ubG9hZHMoQVJHT19MSVRFUkFMKVxuZm9yIGtleSBpbiAoXCd1aWRcJyxcJ3JlcG9VUkxcJyxcJ3RhcmdldFJldmlzaW9uXCcsXCdwYXRoXCcsXCdkZXN0aW5hdGlvblwnLFwnYXV0b21hdGVkXCcpOlxuIGFzc2VydCBhcmdvW2tleV09PWV4cGVjdGVkX2FyZ29ba2V5XVxuYXNzZXJ0IGFyZ29bXCdoZWFsdGhcJ11bXCdzdGF0dXNcJ109PVwnSGVhbHRoeVwnXG5kaWZmPXN1YnByb2Nlc3MucnVuKFtcJ2t1YmVjdGxcJyxcJ2RpZmZcJyxcJy1mXCcsXCctXCddLGlucHV0PWpzb24uZHVtcHMoY2FuZGlkYXRlKSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSk7YXNzZXJ0IGRpZmYucmV0dXJuY29kZSBpbiAoMCwxKVxuIyBEaWZmIGNhbiBjb250YWluIG9ubHkgbm9uc2VjcmV0IERlcGxveW1lbnQgcmVmZXJlbmNlczsgcHJlc2VydmUgZGlnZXN0IHJhdGhlciB0aGFuIHJhdyBzdGRvdXQuXG5ub2RlPXJ1bihbXCdrdWJlY3RsXCcsXCdkZXNjcmliZVwnLFwnbm9kZVwnXSk7YWxsb2NhdGVkPXJlLnNlYXJjaChyXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOi4qP0NQVSBSZXF1ZXN0c3xBbGxvY2F0ZWQgcmVzb3VyY2VzOlwnLG5vZGUscmUuUylcbnNlY3Rpb249bm9kZS5zcGxpdChcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcpWzFdLnNwbGl0KFwnRXZlbnRzOlwnKVswXSBpZiBcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcgaW4gbm9kZSBlbHNlIFwnXCdcbm5vZGVzPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwnbm9kZXNcJyxcJy1vXCcsXCdqc29uXCddKSlbXCdpdGVtc1wnXTthc3NlcnQgbGVuKG5vZGVzKT09MVxuYWxsb2M9bm9kZXNbMF1bXCdzdGF0dXNcJ11bXCdhbGxvY2F0YWJsZVwnXTtjcHU9YWxsb2NbXCdjcHVcJ107Y3B1X209aW50KGNwdVs6LTFdKSBpZiBjcHUuZW5kc3dpdGgoXCdtXCcpIGVsc2UgaW50KGNwdSkqMTAwMFxucmVxdWVzdGVkPWludChyZS5zZWFyY2goclwnY3B1XFxzKyhcXGQrKW1cJyxzZWN0aW9uKS5ncm91cCgxKSk7YXNzZXJ0IHJlcXVlc3RlZDw9Y3B1X21cbnJlY2VpcHQ9e1wnbm9kZV9hbGxvY2F0YWJsZV9jcHVfbVwnOmNwdV9tLFwnbm9kZV9yZXF1ZXN0ZWRfY3B1X21cJzpyZXF1ZXN0ZWQsXCdjYXB0dXJlZF9hdFwnOmRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpLmlzb2Zvcm1hdCgpLFwnbmF0aXZlX3dvcmtsb2FkX2NoYW5nZWRcJzpGYWxzZSxcJ25hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZFwnOkZhbHNlLFwnYXJnb1wnOmFyZ28sXCduYXRpdmVfZGVwZW5kZW5jaWVzX2NoZWNrZWRcJzpUcnVlLFwnY29uZmlnbWFwX3VpZFwnOmNtW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdwdmNfdWlkXCc6cHZjW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdsaXZlX3JlYWR5X3JlcGxpY2FzXCc6MSxcJ2FkbWl0dGVkX3VpZFwnOmFkbWl0dGVkW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWRcJzpUcnVlLFwnYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZVwnOlRydWUsXCdjbGllbnRfZGlmZl9leGl0XCc6ZGlmZi5yZXR1cm5jb2RlLFwnY2xpZW50X2RpZmZfc2hhMjU2XCc6aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpLFwnbm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzXCc6c2VjdGlvbi5zdHJpcCgpLFwnYWxsX2NoZWNrc19wYXNzXCc6VHJ1ZX1cbnByaW50KGpzb24uZHVtcHMocmVjZWlwdCkpXG4nCmZvciBtYXJrZXIsdmFsdWUgaW4gWygnREVQRU5ERU5DSUVTX0xJVEVSQUwnLChST09ULydzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLCgnQ0FORElEQVRFX0xJVEVSQUwnLChST09ULydjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLCgnU0VBTEVEX0xJVEVSQUwnLChST09ULydzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksKCdHVUFSRF9MSVRFUkFMJywoUk9PVC8nY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpLCgnQVJHT19MSVRFUkFMJyxqc29uLmR1bXBzKGpzb24ubG9hZHMoKFJPT1QvJ25hdGl2ZS1wcmVmbGlnaHQuanNvbicpLnJlYWRfdGV4dCgpKVsnYXJnbyddKSldOgogcHJvZ3JhbT1wcm9ncmFtLnJlcGxhY2UobWFya2VyLHJlcHIodmFsdWUpKQpwcm9ncmFtPSdpbXBvcnQgdHJhY2ViYWNrLGpzb25cbnRyeTpcbicrJycuam9pbignICAgICcrbGluZSsnXG4nIGZvciBsaW5lIGluIHByb2dyYW0uc3BsaXRsaW5lcygpKSsiZXhjZXB0IEV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICBwcmludChqc29uLmR1bXBzKHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZSwnZXhjZXB0aW9uX3R5cGUnOnR5cGUoZXJyb3IpLl9fbmFtZV9fLCdleGNlcHRpb25fbGluZSc6dHJhY2ViYWNrLmV4dHJhY3RfdGIoZXJyb3IuX190cmFjZWJhY2tfXylbLTFdLmxpbmVub30pKVxuIgpyPXN1YnByb2Nlc3MucnVuKFsnc3NoJywncmFpbGlhbmNlMDEnLCdweXRob24zIC0nXSxpbnB1dD1wcm9ncmFtLHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlKQpyZXN1bHQ9dHJhbnNwb3J0X3Jlc3VsdChyLnJldHVybmNvZGUsci5zdGRvdXQpO3Jlc3VsdFsnc2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2J109aGFzaGxpYi5zaGEyNTYoKFJPT1QvJ3ByZWZsaWdodC1pbnB1dHMuanNvbicpLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCk7cmVzdWx0WydmcmVzaF9leGVjdXRpb25fcmVjZWlwdCddPVRydWUKb3V0LndyaXRlX3RleHQoanNvbi5kdW1wcyhyZXN1bHQsaW5kZW50PTIpKydcbicpO3ByaW50KGpzb24uZHVtcHMocmVzdWx0LGluZGVudD0yKSk7c3lzLmV4aXQoMCBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgMSkK" + }, + { + "digest": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b", + "media_type": "application/json", + "content_base64": "ewogICJwYWNrZXRfZmlsZXMiOiB7CiAgICAiY2hhbmdlX2d1YXJkLnB5IjogImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmUiLAogICAgInByZWZsaWdodC5weSI6ICI2YjRjNjVmNzA4MjM4YzlhOWQxN2ZkMDY1ODc2YzdhMDBlMWYxNzQ1OTI2Zjk5MGExZGQ1ZTY2NzI5ODM0MGNkIiwKICAgICJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uIjogIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGUiLAogICAgInJvbGxiYWNrLWRlcGxveW1lbnQuanNvbiI6ICIzOWIzZjQzYmI4NGVmNDkyMWNjM2ExZmJjZGM0NDQ2MTA3NDFlZDg4MDkxNDlkOGY4ZjE3ZWQ4MDVmMjYyMTIxIiwKICAgICJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24iOiAiZDE4ZDI3MDYzZDA2ZjUzNWFlODg0ZWEwMWY5Njc0N2ZlMzAxNjg1NTE4YWI5NGIxY2JhMDcyYTFlMTUxOTM2MiIsCiAgICAibmF0aXZlLXByZWZsaWdodC5qc29uIjogImViNWY0MWFlZmI5NzY2NmJiMGMxMjc5NjE3ZTk1YTdjMDUwMTdhNjA5NDE1NjI0ZGFlZTcyNGM0OGI5MGQyNjIiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAic3FsaXRlX3JlYWRvbmx5LnB5IjogIjkwOTNjNjRmN2YwZTM5YjI0OWRhOWZlZmRmNWFhZjRlNDI1OGJjMzFlN2EyN2ZkODg4NDc5Y2UzMjlhMjA1MDkiCiAgfSwKICAib3duZXJfc291cmNlX2ZpbGVzIjogewogICAgImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uIjogIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTUiLAogICAgImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbiI6ICIzOGI3OGI5Y2JlZTVhZGU3NzUwYTU4ZDUxNTZjYTRjNTc3MzM1MmU5NDdhY2IzMDRlZTcxNGI1OWU3NDljZWI0IgogIH0KfQo=" + }, + { + "digest": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7", + "media_type": "application/json", + "content_base64": "ewogICJub2RlX2FsbG9jYXRhYmxlX2NwdV9tIjogNDAwMCwKICAibm9kZV9yZXF1ZXN0ZWRfY3B1X20iOiAzNDYwLAogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjM5OjE0LjIzNDI3NyswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibmF0aXZlX2RlcGVuZGVuY2llc19jaGVja2VkIjogdHJ1ZSwKICAiY29uZmlnbWFwX3VpZCI6ICI5MDExM2QyZC01NGQ5LTRlODItYjFkMy05MGI0OWViZWQyYjUiLAogICJwdmNfdWlkIjogImQ4MGIyNWIxLTE0MWEtNDQxYi1iMjA1LTk4ZmEyZmQ5OGI3YyIsCiAgImxpdmVfcmVhZHlfcmVwbGljYXMiOiAxLAogICJhZG1pdHRlZF91aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIiwKICAic2VydmVyX2RyeV9ydW5fcGFzc2VkIjogdHJ1ZSwKICAiYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZSI6IHRydWUsCiAgImNsaWVudF9kaWZmX2V4aXQiOiAxLAogICJjbGllbnRfZGlmZl9zaGEyNTYiOiAiODQwNzY5YzdkMmE5YzE2NTVjNDBhMzI1OWY4MzNkMWZjOGY2OTk1MGNlYjNiZWRiNzA3YTk1NWZlZDcxMTU2NiIsCiAgIm5vZGVfYWxsb2NhdGVkX3Jlc291cmNlcyI6ICIoVG90YWwgbGltaXRzIG1heSBiZSBvdmVyIDEwMCBwZXJjZW50LCBpLmUuLCBvdmVyY29tbWl0dGVkLilcbiAgUmVzb3VyY2UgICAgICAgICAgIFJlcXVlc3RzICAgICAgTGltaXRzXG4gIC0tLS0tLS0tICAgICAgICAgICAtLS0tLS0tLSAgICAgIC0tLS0tLVxuICBjcHUgICAgICAgICAgICAgICAgMzQ2MG0gKDg2JSkgICAzNjIwMG0gKDkwNSUpXG4gIG1lbW9yeSAgICAgICAgICAgICA5NDcyTWkgKDU5JSkgIDMyODk4TWkgKDIwNSUpXG4gIGVwaGVtZXJhbC1zdG9yYWdlICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMUdpICAgICAgMCAoMCUpICAgICAgICAwICgwJSlcbiAgaHVnZXBhZ2VzLTJNaSAgICAgIDAgKDAlKSAgICAgICAgMCAoMCUpIiwKICAiYWxsX2NoZWNrc19wYXNzIjogdHJ1ZSwKICAic2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2IjogIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDYiLAogICJmcmVzaF9leGVjdXRpb25fcmVjZWlwdCI6IHRydWUKfQo=" + } + ] + } + } +] diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json new file mode 100644 index 0000000..46e3881 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json @@ -0,0 +1,141 @@ +{ + "id": "infd-20261011-purpose-overlay-r1", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md new file mode 100644 index 0000000..d2b86de --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md @@ -0,0 +1,31 @@ +# Version2 protected existing-snapshot rescue and conditional continuation + +Same proposal INFD-WP-0009-T04/purpose-overlay-v1, trial infd-purpose-20261011-r1. Original version1 founder acceptance approved source bc6494cd1b290783ef3aef0763bf28d1deabf4b0. Drill-backup completed; drill-copy failed ValueError before any localfile. No image rollout occurred. This exact changed source/plan/helper requires NEW founder acceptance of memo version2 before rescue/continuation; prior approval and technical review do not approve it. + +## Failure and narrowly selected rescue + +Original snapshot main19537920bytes SHA8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3 is unchanged. Root's metadata-only verification shows WAL0bytes, SHM32768bytes, privateUID10001/mode0600/nlink1, and no local snapshot. The old SQLite connection context manager did not explicitly close; its WAL reader can create SHM indexing, and the next copy rejected that nonzero index. Platform independently reproduced this on synthetic data. No native DB was opened to diagnose the sidecar metadata, and no native sidecar is deleted/checkpointed. + +Reuse this exact independently hash-bound frozen main snapshot rather than make another drill backup. The backupadmin exited after creating the uniquely owned private snapshot. Original subsequent snapshot access was readonly; actual service DB is the distinct /data/private/review.sqlite. Original journal has only COMPLETE drill-backup d63182a7-e1a5-4e8e-a5f1-2bf3333cf153 and UNCERTAIN drill-copy329ef190-1692-4246-b953-e6a59664abcc. Its exact SHA d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1, original source/memo/plan identity and outcomes are verified before/after every new phase. No other original action or rollout is allowed. + +The explicitly named drill-copy-rescue-r1 creates a separate rescue-execution-journal-r1.json/lock in existing protected ignored custody; it hash-links original attempts and backupresult and never rewrites/synthesizes the old failed phase. Any attempted rescue result, crash or ambiguous output is durable and same-phase retry is refused. Before rescue: local drill.sqlite/cutover.sqlite and existing restore volume must be absent; native originalPodUID/currentoldimage7f5/Argo7db/sealedDeployment/CM/PVC match. The fixed immutable snapshot reader checks recorded digest/private identity/no WALframes before and after schema5/integrity/count validation, retaining unchanged SHM. Nonzero WAL or any identity/hash drift stops rescue. Snapshot binarystdout flows only to a new0600private file, with bounded size/hash and repeat source proof. It never reaches chat/log/Git/StateHub. + +## Live-WAL and data compatibility boundaries + +Live source and writable offline pre/post-admin reads MUST stay mode=ro/query_only and explicitly close SQLite connections. immutable=1 ignores WAL and would lose committed live rows; it is restricted to the proven frozen closed-main snapshot, never the liveDB or writableclone. Before ANY native source or restoredcopy Store/admin open, require stdlib readonly schema5/integrity/counts; refuse oldschemas before automatic migration. Frozen snapshot/clone count equality is exact; currentlive counter changes may reflect concurrent legitimate commits and are retained. + +Only after COMPLETE named rescue does offline-verify consume its result via explicit mapping, not the old UNCERTAIN drill-copy. Existing isolated disposablevolume infd-purpose-r1-restore-20261011 must be absent/new nonce-bound. One exact763c UID0/CAP_CHOWN-only initializer receives snapshotstdin into that NEWvolume, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/nativePVC/runtimeconfig/token mounts. It sets folder0700/file0600UID10001, followed by UID10001 pre-open readonly, --entrypoint informed-decision-admin inspect --db /restore/review.sqlite and post-admin readonly fullproof; original protected SHA must remain unchanged. No serviceentrypoint starts. Cleanup only this disposable volume, retaining original native/offcluster snapshots/sidecars. + +## Conditional remaining phases and release/recovery + +Newjournal fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. cutover-backup uses distinct newcutover.sqlite in originalprivatecase directory, after readonly live schema5/capacity gates, SQLitebackupAPI/admin completion, closed-main immutable proof; do not overwrite originals or retryfailedpaths. Version2 acceptance conditionally approves these exact unchanged remaining operations only after rescue+drillgates. All four committed Kustomize Git blobs/currentHEAD, exact helper/case hashes, CM/PVC/Deployment seals and manualApplication(no automated{} or sourceoverride) must match. + +Release retains existing replica1/Recreate/config6c/schema5/PVC/credentials/policies: sourcepin Application.operation serverdryrun/UID+resourceVersion+source CAS, Deployment-only image763c, prune=false. No whole-app sync/adoption. Verify requires succeeded exactscope/controllergeneration/Ready1, installedpolicyhash/modeUID/10syntheticpurposevariants+boundedhealth, same currentliveDB schema5/integrity/counts. Those installedchecks report native_provider=false; actualprovider/PDPauthority evidence remains a separate T04gate. + +Rollback after recorded newrelease attempt pins prior7db/7f5 and retains latestschema5DB, without requiring Ready failingcandidate or candidateDBexec. Separate rollback-verify proves oldimageReady1/scopedoperation/readonlyschema5 currentDB integrity. Never restore an older snapshot over postcutoverrecords. Any data recovery beyond this same-schema image rollback needs another decision. + +All phases including rescue, verification and recovery must begin before2026-10-12T23:59:59Z. Start early enough; if expired stop and obtain a fresh founder decision, which may delay recovery. No automatic timer/controller/extension. Root freshly authenticates exact confirmed platform-root person ACCEPT memo version2 at fixednativeorigin before every phase; protectedreceiptrelation/freshness120sec is supervisedbookkeeping, not a signed/autonomous grant. + +Image763c/policy9d7c/base7f5 and actualunfilteredscan0HIGH/CRITICAL/1fixableMEDIUMzlib remain unchanged, owner INFD-RISK-20261011-ZLIB-85091/T05 dueOct18. The exactbundle directly binds helper/plan/tests plus original count-onlybackup/failure/anchor. Existingpublishedreceipt still binds unchanged rawscan/SBOM/base scan; no suppression. Preserve originalapproved20docpacket/helpers/history in initial-approved-bc6494cd. No version2 native operation has run. EUR0 recurringinfrastructure; private boundedstorage/attendedtime unpriced, no newdrillbackup or autonomygrant. + +Native source publication uses exact revision-command.json via /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions, expected_version1, only after fresh unbound-source readback. No version2 intake/register. Publish/review sourceversion2; new human review-ID is ownversion1, so its confirmed nested disposition memo_version1 is correct. Root actual outcomes query must name SOURCE version2 and exact newreviewID; original review/approval cannot be reused. diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json new file mode 100644 index 0000000..a9b779f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json @@ -0,0 +1 @@ +{"phase": "drill-backup", "all_checks_pass": true, "raw_output_withheld": true, "native_approval_verified_by_root": {"approval_id": "ec92806a-9aa6-494f-a76b-0385f39ba609", "disposition_id": "disp-0968373d-294d-42bf-8979-36a7c5dd38cf", "accepted_at": "2026-10-11T02:34:20Z", "verified_at": "2026-10-11T02:38:41.777949+00:00"}, "native_authenticated_grant": false, "source_readonly_baseline": {"schema_version": 5, "lifecycle": {"records": 15, "events": 50, "pending": 0}, "outbox": {"delivered": 320}, "submissions": {"confirmed": 41}, "integrity": "ok", "read_only_pre_open": true, "store_constructed": false}, "snapshot_readonly": {"schema_version": 5, "lifecycle": {"records": 15, "events": 50, "pending": 0}, "outbox": {"delivered": 320}, "submissions": {"confirmed": 41}, "integrity": "ok", "read_only_pre_open": true, "store_constructed": false}, "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", "snapshot_bytes": 19537920, "snapshot_file": "drill.sqlite", "native_parent_private": true, "native_uid": 10001, "pod_name": "informed-decision-f557556df-mwpz7", "pod_uid": "e8561ae0-4b09-4455-924d-64c27b625fc7"} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json new file mode 100644 index 0000000..ca6f2c3 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json @@ -0,0 +1 @@ +{"all_checks_pass": false, "phase": "drill-copy", "failure_class": "ValueError", "failure": "fixed phase outcome uncertain; original evidence retained; no retry", "raw_output_withheld": true} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json new file mode 100644 index 0000000..b643e77 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json @@ -0,0 +1,20 @@ +{ + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json new file mode 100644 index 0000000..580ec6c --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json @@ -0,0 +1,16 @@ +{ + "packet_files": { + "change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "preflight.py": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "native-preflight.json": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "sqlite_readonly.py": "9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + "owner_source_files": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4" + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json new file mode 100644 index 0000000..70eaa03 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json @@ -0,0 +1,127 @@ +{ + "proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1", + "trial_id": "infd-purpose-20261011-r1", + "state": "prepared-unapproved", + "target": "realm:kubernetes/railiance01/informed-decision", + "authority": "ADMINISTER; activation APPROVED only upon exact founder disposition", + "candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "published_source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173", + "prior_argo_revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf", + "native_object": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "namespace": "informed-decision", + "name": "informed-decision", + "uid": "a588e10a-90d2-4883-975e-6dd8b8feca92" + }, + "argo_application_uid": "499868f2-eabc-4df4-ae31-b89ce58d750d", + "source_gate": "All four exact committed owner Kustomize input blobs in execution-plan.json and clean current owner HEAD must match; source preparation is not native approval", + "sync_scope": [ + "apps:Deployment:informed-decision" + ], + "prune": false, + "automated_sync": false, + "runtime_configmap": "informed-decision-runtime-6c221878d051", + "schema": 5, + "requested_operations": [ + "Read-only immutable validation of existing frozen19537920byte native drill snapshot, SHA8756..., privatecustody/no-writer/zeroWAL/staleSHM retained", + "Distinct drill-copy-rescue-r1 binarycopy into absent0600protected local destination, new hash-linked rescue journal preserving old UNCERTAIN copy", + "Existing isolated offline pre-open/admin/post-open compatibility drill and disposable-volume cleanup using rescued result", + "Distinct consistent cutover snapshot plus protectedcopy, followed only after allgates by Deployment-only image release/verify; same-schema rollback/recovery proof if needed" + ], + "execute_by": "2026-10-12T23:59:59Z", + "temporary_vulnerability_review_due": "2026-10-18", + "known_scan_findings": "0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical", + "vulnerability_record": "INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05", + "cost_estimate_EUR": 0, + "cost_limits": "No additional recurring infrastructure or second drill backup. Existing native snapshot19537920bytes retained; protected localcopy/offlineclone plus distinct cutover snapshots consume boundedexistingstorage. Attendedengineering/recovery time unpriced; no autopilot grant.", + "risk_estimates": [ + "Brief Recreate service interruption; no concurrent new writer/surge", + "Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence", + "Candidate purpose refusal may expose callers relying on advisory results as binding", + "Inherited known fixable MEDIUM remains until separately approved owner remediation", + "Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted", + "All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller." + ], + "rollback": "Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes", + "native_executed": "Original drill-backup executed; original drill-copy failed. No version2 action executed.", + "human_approval": "Version1 accepted originalsource; version2 requires fresh exact acceptance.", + "refinement_of_manifest": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300", + "mandatory_pre_open_gate": "stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration", + "optimized_interpreters": "local+remote explicitlyrefused beforeassert gates", + "native_dependency_gate": "sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads", + "live_counts": "Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained", + "source_basis": { + "original_approved_source": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "final_recovery_source": "exact final root-applied owner HEAD with approved four render blobs must be bound by new founder receipt" + }, + "approved_owner_render_blob_sha256": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "execution_bundle_sha256": "49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5", + "execution_helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", + "execution_plan_sha256": "9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258", + "execution_phases": [ + "drill-copy-rescue-r1", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.", + "offline_initializer": "One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.", + "rollback_dispatch": "Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.", + "purpose_proof_limit": "Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.", + "refinement_of_amended_manifest": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033", + "memo_version": 2, + "recovery": { + "original_anchor": { + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false + }, + "original_identity": { + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "memo_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937", + "plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + "new_journal": "rescue-execution-journal-r1.json", + "new_phase": "drill-copy-rescue-r1", + "old_uncertain_phase_overwrite_or_retry": false, + "new_snapshot_backup": false, + "snapshot_or_sidecar_mutation": false, + "mapping": "offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal" + }, + "original_native_outcome": { + "drill-backup": "COMPLETE", + "drill-copy": "UNCERTAIN before localfile creation", + "native_image": "unchanged7f5; no rollout", + "original_journal_and_sidecars": "retained unchanged" + }, + "rescue_limits": "No liveDBwrites during rescue inspection/copy, no sidecar deletion/checkpoint, no retry/overwrite original UNCERTAIN phase. Later existing admin offlineinspect/cutoverbackup and image actions need new exactversion2 acceptance andorderedguards.", + "submission_route": "POST /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions CAS expected_version1; source must remain unbound; publish/review sourceversion2, resulting human review ownversion1" +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json new file mode 100644 index 0000000..a608e79 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json @@ -0,0 +1,69 @@ +{ + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "observed_at": "2026-10-11T01:24:01.985128+00:00", + "native_owner_publication_job": { + "id": 11484, + "name": "publish-candidate", + "head_branch": "main", + "head_sha": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "run_number": 3, + "event": "push", + "display_title": "Prepare readable overlay context with the admitted legacy builder", + "status": "success", + "workflow_id": "purpose-overlay-image.yaml", + "url": "https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3", + "created_at": "2026-10-11T01:20:59Z", + "updated_at": "2026-10-11T01:21:08Z", + "run_started_at": "2026-10-11T01:20:59Z" + }, + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a", + "source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168", + "policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62", + "registry_proof_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "source_render_change_only": "Deployment/informed-decision spec.template.spec.containers[0].image", + "runtime_configmap_unchanged": "informed-decision-runtime-6c221878d051", + "installed_image_execution": { + "immutable_registry_artifact_pulled_anonymously": true, + "UID": 10001, + "GID": 10001, + "policy_file_UID": 0, + "policy_file_mode": "0644", + "purpose_variants": 10, + "binding_forms_allowed": 2, + "advisory_or_malformed_refused": 8, + "network": "none", + "read_only": true, + "synthetic_transport": true, + "native_PDP_test": false + }, + "scan_summary_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "historical_failed_runs_retained": [ + "f66de505/task11482/run1", + "acecad887/task11483/run2" + ], + "native_hosting_changed": false, + "native_backup_restore_executed": false, + "human_approval": false, + "evidence_file_sha256": { + "image-manifest.json": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb", + "image-config.json": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10", + "base-image-config.json": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00", + "registry-proof.json": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "trivy-full.json": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e", + "sbom.cdx.json": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d", + "base-trivy-full.json": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80", + "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", + "verify_registry.py": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4", + "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "review-refinement.json": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75", + "test_change_guard.py": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f", + "test_sqlite_readonly.py": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323", + "test_preflight_optimization.py": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d", + "initial-approved-bc6494cd/sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + "version2_source_pointer_refinement": { + "original_receipt_sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "original_receipt_archive": "initial-approved-bc6494cd/published-verification.json", + "reason": "Keep historical original pre-open checker hash bound to exact archived original bytes; current version2 checker is independently direct-packet/plan bound. Actual image/registry/scan/SBOM proof unchanged; no new artifact verification or native version2 action claimed." + } +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json new file mode 100644 index 0000000..c32d804 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json @@ -0,0 +1,261 @@ +{ + "kind": "informed-decision.memo-intake", + "version": 1, + "idempotency_key": "infd-20261011-purpose-overlay-r1-v2", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "drafted_by": "custodian-codex", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + }, + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "packet": [ + { + "item_id": "decision-packet-md", + "media_type": "text/markdown", + "content": "# Informed Decision version2 existing-snapshot rescue and image release\n\nApprove the exact source-refined recovery of the failed drill-copy and conditional remaining backup/drill/Deployment-only image rollout. This is memo version2 in the same proposal/trial, requiring NEW founder acceptance; original version1 acceptance is retained and cannot authorize changed helperbytes.\n\nOriginal source bc6494cd completed the protected native drill-backup, then copy failed before any localfile. Metadata-only verification proves unchanged main19537920bytes/SHA8756..., WAL0/privateSHM32768. The original reader could leave SHM indexing because its connection context manager did not close. The correction explicitlycloses all readers and uses immutable reads ONLY for a proven frozen closed-main snapshot, not live or writableclone. SHM stays unchanged; nonzeroWAL/hash/identity drift stops rescue.\n\nDistinct drill-copy-rescue-r1/newlinkedjournal preserves original UNCERTAINcopy and exact journalhash/attempts. No oldretry/overwrite, no newdrillbackup. Require originalCOMPLETEbackup/UNCERTAINcopy only, absentlocalfiles/restorevolume, originalnativePodUID/currentoldimage+sourcepin and allCM/PVC/Deployment seals. Copy snapshotbytes only into a newprivate0600file. Remainingorderedphases explicitly consume COMPLETErescueresult; one isolated UID0/CAP_CHOWN-only NEWvolume initializer then UID10001 pre-open/admin/post-admin checks proves real-data compatibility before cutover. No host/nativePVC/runtimeconfig/token mounts; no service startup. Any attempted failure/ambiguity is durable and cannotretry.\n\nImage763c from actualCI3e4bcb26 remains unchanged8base layers pluspolicy.py; legacyserialization differences disclosed. ActualinstalledUID10001/10purposevariants pass; native_provider=false/synthetictransport is not actualPDPauthority proof, which remains separateT04gate. Actualfull44packagescan0HIGH/CRITICAL, ONEfixableinheritedMEDIUMzlibCVE-2026-85091(1.3.2-r0→r1), identicalbasefinding. Explicittemporarypermission for this finding is requested again, with ownerT05/riskrecorddueOct18; no zero-CVE/RiskNexusgradeclaim. Rawscan/SBOM/base scan stay unchangedhashbound via publishedreceipt; exacthelperandoriginalcount-onlyreceipts directlybundle-bound within20docs.\n\nAfter rescue+offlinegates, distinctcutoverbackup/copy and manualArgoDeployment-only image763c/prune=false remain conditional. FourcommittedKustomizeblobs/currentfinalsourceHEAD/helpers/casehashes match; automated{} or overrides refuse. Config6c/schema5/PVC/identity/policies/replica1Recreate stayfixed. Rollbackdoesnotneed Readycandidate or itsDBexec; oldimageReady/scopedoperation/schema5currentDB is a separateproof. Preserve latestliveDB/allnewcommits and alluncertainoutcomes; neverrestoreolderbackup overlaterrecords.\n\nAllphases including rescue/recovery/verify mustbegin beforeOct12 23:59:59Z; expiryrequiresnewdecision and maydelayrecovery. No automaticexpirycontroller. Freshroot-authenticated nativefounderacceptance version2 beforeeachphase; receipts are supervisedbookkeeping, notsignedgrant/autonomy. EUR0 recurringinfra, existingprivatecopy/storage/attendedtime unpriced; no secondnative drillbackup. Exactoriginalapprovedpacket/failure/technicalrefinements preserved sameproposal/trial. No version2nativeoperation yet.\n" + }, + { + "item_id": "proposal-json", + "media_type": "application/json", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"authority\": \"ADMINISTER; activation APPROVED only upon exact founder disposition\",\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"published_source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"prior_argo_revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"native_object\": {\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"namespace\": \"informed-decision\",\n \"name\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"argo_application_uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"source_gate\": \"All four exact committed owner Kustomize input blobs in execution-plan.json and clean current owner HEAD must match; source preparation is not native approval\",\n \"sync_scope\": [\n \"apps:Deployment:informed-decision\"\n ],\n \"prune\": false,\n \"automated_sync\": false,\n \"runtime_configmap\": \"informed-decision-runtime-6c221878d051\",\n \"schema\": 5,\n \"requested_operations\": [\n \"Read-only immutable validation of existing frozen19537920byte native drill snapshot, SHA8756..., privatecustody/no-writer/zeroWAL/staleSHM retained\",\n \"Distinct drill-copy-rescue-r1 binarycopy into absent0600protected local destination, new hash-linked rescue journal preserving old UNCERTAIN copy\",\n \"Existing isolated offline pre-open/admin/post-open compatibility drill and disposable-volume cleanup using rescued result\",\n \"Distinct consistent cutover snapshot plus protectedcopy, followed only after allgates by Deployment-only image release/verify; same-schema rollback/recovery proof if needed\"\n ],\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"temporary_vulnerability_review_due\": \"2026-10-18\",\n \"known_scan_findings\": \"0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical\",\n \"vulnerability_record\": \"INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05\",\n \"cost_estimate_EUR\": 0,\n \"cost_limits\": \"No additional recurring infrastructure or second drill backup. Existing native snapshot19537920bytes retained; protected localcopy/offlineclone plus distinct cutover snapshots consume boundedexistingstorage. Attendedengineering/recovery time unpriced; no autopilot grant.\",\n \"risk_estimates\": [\n \"Brief Recreate service interruption; no concurrent new writer/surge\",\n \"Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence\",\n \"Candidate purpose refusal may expose callers relying on advisory results as binding\",\n \"Inherited known fixable MEDIUM remains until separately approved owner remediation\",\n \"Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted\",\n \"All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller.\"\n ],\n \"rollback\": \"Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes\",\n \"native_executed\": \"Original drill-backup executed; original drill-copy failed. No version2 action executed.\",\n \"human_approval\": \"Version1 accepted originalsource; version2 requires fresh exact acceptance.\",\n \"refinement_of_manifest\": \"7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300\",\n \"mandatory_pre_open_gate\": \"stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration\",\n \"optimized_interpreters\": \"local+remote explicitlyrefused beforeassert gates\",\n \"native_dependency_gate\": \"sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads\",\n \"live_counts\": \"Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained\",\n \"source_basis\": {\n \"original_approved_source\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\",\n \"final_recovery_source\": \"exact final root-applied owner HEAD with approved four render blobs must be bound by new founder receipt\"\n },\n \"approved_owner_render_blob_sha256\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"execution_bundle_sha256\": \"49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5\",\n \"execution_helper_manifest_sha256\": \"f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c\",\n \"execution_plan_sha256\": \"9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258\",\n \"execution_phases\": [\n \"drill-copy-rescue-r1\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\",\n \"offline_initializer\": \"One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.\",\n \"rollback_dispatch\": \"Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.\",\n \"purpose_proof_limit\": \"Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.\",\n \"refinement_of_amended_manifest\": \"b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033\",\n \"memo_version\": 2,\n \"recovery\": {\n \"original_anchor\": {\n \"original_journal_sha256\": \"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\",\n \"phase_metadata\": {\n \"drill-backup\": {\n \"state\": \"COMPLETE\",\n \"attempt_id\": \"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\",\n \"started_at\": \"2026-10-11T02:38:45.310653+00:00\"\n },\n \"drill-copy\": {\n \"state\": \"UNCERTAIN\",\n \"attempt_id\": \"329ef190-1692-4246-b953-e6a59664abcc\",\n \"started_at\": \"2026-10-11T02:39:50.198740+00:00\"\n }\n },\n \"frozen_backup_receipt_sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\",\n \"snapshot_bytes\": 19537920,\n \"off_cluster_file_exists\": false,\n \"old_uncertain_retry_authorized\": false\n },\n \"original_identity\": {\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"source_revision\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\",\n \"memo_sha256\": \"506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937\",\n \"plan_sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\"\n },\n \"new_journal\": \"rescue-execution-journal-r1.json\",\n \"new_phase\": \"drill-copy-rescue-r1\",\n \"old_uncertain_phase_overwrite_or_retry\": false,\n \"new_snapshot_backup\": false,\n \"snapshot_or_sidecar_mutation\": false,\n \"mapping\": \"offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal\"\n },\n \"original_native_outcome\": {\n \"drill-backup\": \"COMPLETE\",\n \"drill-copy\": \"UNCERTAIN before localfile creation\",\n \"native_image\": \"unchanged7f5; no rollout\",\n \"original_journal_and_sidecars\": \"retained unchanged\"\n },\n \"rescue_limits\": \"No liveDBwrites during rescue inspection/copy, no sidecar deletion/checkpoint, no retry/overwrite original UNCERTAIN phase. Later existing admin offlineinspect/cutoverbackup and image actions need new exactversion2 acceptance andorderedguards.\",\n \"submission_route\": \"POST /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions CAS expected_version1; source must remain unbound; publish/review sourceversion2, resulting human review ownversion1\"\n}\n" + }, + { + "item_id": "candidate-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "rollback-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "candidate-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "rollback-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "published-verification-json", + "media_type": "application/json", + "content": "{\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"observed_at\": \"2026-10-11T01:24:01.985128+00:00\",\n \"native_owner_publication_job\": {\n \"id\": 11484,\n \"name\": \"publish-candidate\",\n \"head_branch\": \"main\",\n \"head_sha\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"run_number\": 3,\n \"event\": \"push\",\n \"display_title\": \"Prepare readable overlay context with the admitted legacy builder\",\n \"status\": \"success\",\n \"workflow_id\": \"purpose-overlay-image.yaml\",\n \"url\": \"https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3\",\n \"created_at\": \"2026-10-11T01:20:59Z\",\n \"updated_at\": \"2026-10-11T01:21:08Z\",\n \"run_started_at\": \"2026-10-11T01:20:59Z\"\n },\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"registry_proof_sha256\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"source_render_change_only\": \"Deployment/informed-decision spec.template.spec.containers[0].image\",\n \"runtime_configmap_unchanged\": \"informed-decision-runtime-6c221878d051\",\n \"installed_image_execution\": {\n \"immutable_registry_artifact_pulled_anonymously\": true,\n \"UID\": 10001,\n \"GID\": 10001,\n \"policy_file_UID\": 0,\n \"policy_file_mode\": \"0644\",\n \"purpose_variants\": 10,\n \"binding_forms_allowed\": 2,\n \"advisory_or_malformed_refused\": 8,\n \"network\": \"none\",\n \"read_only\": true,\n \"synthetic_transport\": true,\n \"native_PDP_test\": false\n },\n \"scan_summary_sha256\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\",\n \"historical_failed_runs_retained\": [\n \"f66de505/task11482/run1\",\n \"acecad887/task11483/run2\"\n ],\n \"native_hosting_changed\": false,\n \"native_backup_restore_executed\": false,\n \"human_approval\": false,\n \"evidence_file_sha256\": {\n \"image-manifest.json\": \"978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb\",\n \"image-config.json\": \"4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10\",\n \"base-image-config.json\": \"b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00\",\n \"registry-proof.json\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"trivy-full.json\": \"f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e\",\n \"sbom.cdx.json\": \"a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d\",\n \"base-trivy-full.json\": \"d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"verify_registry.py\": \"413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"review-refinement.json\": \"ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75\",\n \"test_change_guard.py\": \"da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f\",\n \"test_sqlite_readonly.py\": \"c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323\",\n \"test_preflight_optimization.py\": \"a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d\",\n \"initial-approved-bc6494cd/sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\"\n },\n \"version2_source_pointer_refinement\": {\n \"original_receipt_sha256\": \"8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2\",\n \"original_receipt_archive\": \"initial-approved-bc6494cd/published-verification.json\",\n \"reason\": \"Keep historical original pre-open checker hash bound to exact archived original bytes; current version2 checker is independently direct-packet/plan bound. Actual image/registry/scan/SBOM proof unchanged; no new artifact verification or native version2 action claimed.\"\n }\n}\n" + }, + { + "item_id": "registry-proof-json", + "media_type": "application/json", + "content": "{\n \"image_digest\": \"sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"base_image_digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"base_layer_bytes_identical\": true,\n \"layer_media_type_conversion\": \"OCI gzip to Docker gzip, same digest and size\",\n \"base_runtime_config_semantics_identical\": true,\n \"legacy_builder_config_additions\": {\n \"Hostname\": \"\",\n \"Domainname\": \"\",\n \"AttachStdin\": false,\n \"AttachStdout\": false,\n \"AttachStderr\": false,\n \"Tty\": false,\n \"OpenStdin\": false,\n \"StdinOnce\": false,\n \"Cmd\": null,\n \"Volumes\": null,\n \"OnBuild\": null,\n \"Image\": \"sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883\"\n },\n \"base_rootfs_prefix_identical\": true,\n \"overlay_regular_files\": [\n \"opt/venv/lib/python3.12/site-packages/informed_decision/policy.py\"\n ],\n \"overlay_directories\": [\n \"opt\",\n \"opt/venv\",\n \"opt/venv/lib\",\n \"opt/venv/lib/python3.12\",\n \"opt/venv/lib/python3.12/site-packages\",\n \"opt/venv/lib/python3.12/site-packages/informed_decision\"\n ],\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"policy_mode\": \"0644\",\n \"base_user\": \"10001:10001\",\n \"source_scope_labels\": {\n \"org.opencontainers.image.revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"org.opencontainers.image.base.digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"social.coulomb.source.policy.sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"social.coulomb.release.scope\": \"INFD-WP-0009-T04/purpose-overlay-v1\"\n },\n \"registry_read_route\": \"anonymous public scoped bearer challenge, no token retention\",\n \"image_executed\": false,\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false\n}\n" + }, + { + "item_id": "security-summary-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"scanner\": \"aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969\",\n \"version\": \"0.74.0\",\n \"db_metadata\": {\n \"Version\": 2,\n \"NextUpdate\": \"2026-10-11T18:59:50.889010572Z\",\n \"UpdatedAt\": \"2026-10-10T18:59:50.889010923Z\",\n \"DownloadedAt\": \"2026-10-10T23:32:32.380033131Z\"\n },\n \"suppression\": false,\n \"ignore_unfixed\": false,\n \"severity_filter\": null,\n \"package_count\": 44,\n \"findings_by_severity\": {\n \"MEDIUM\": 1\n },\n \"findings\": [\n {\n \"id\": \"CVE-2026-85091\",\n \"package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"severity\": \"MEDIUM\"\n }\n ],\n \"coverage_limits\": [\n \"Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages\",\n \"Known findings asof pinnedDB, not claim absence of unknown vulnerabilities\"\n ],\n \"high_critical\": 0,\n \"same_scanner_actual_base_scan_findings_identical\": true,\n \"base_scan_file\": \"base-trivy-full.json\"\n}\n" + }, + { + "item_id": "execution-bundle-json", + "media_type": "application/json", + "content": "{\n \"kind\": \"informed-decision.supervised-execution-source-bundle\",\n \"version\": 2,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"files\": {\n \"README.md\": {\n \"sha256\": \"51b56c8ec2f30ad62f6cd09732c0f73dd7b5ebf2081320223c85bbcbf00d15a9\",\n \"content\": \"# Version2 protected existing-snapshot rescue — prepared, unapproved\\n\\nOriginal approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed.\\n\\nFresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation.\\n\\nFixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase.\\n\\nBefore rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome.\\n\\nOffline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup.\\n\\nFour committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension.\\n\\nImage763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation.\\n\\nNative publication route: POST existing source /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions with expected_version1 and exact memo2/documents/summary, then publications/review-requests version2. Fresh source readback must prove currentversion1 is unbound before revision; bound/different source stops. Intake/register refuse version2 as designed and are not used. Review integration creates a NEW review-ID at its own version1; founder disposition memo_version1 belongs to that new review. Root fresh outcomes must be queried for SOURCE version2, exact newreviewID/memoSHA and confirmed nested personapproval. Receipt outcome_query pins that sourceversion2 route; it does not authenticate by itself.\\n\"\n },\n \"actuator.py\": {\n \"sha256\": \"86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2\",\n \"content\": \"\\\"\\\"\\\"One fixed supervised phase; never run this during source preparation.\\\"\\\"\\\"\\nimport argparse\\nimport hashlib\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport re\\nimport selectors\\nimport stat\\nimport subprocess\\nimport sys\\nimport time\\n\\nif sys.flags.optimize:\\n raise SystemExit('optimized interpreter refused')\\n\\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\nROOT = Path(__file__).resolve().parent\\nCASE = ROOT.parent\\nOWNER = Path('/home/worsch/informed-decision')\\nCUSTODIAN = Path('/home/worsch/the-custodian')\\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\\nSOCKET = 'unix:///var/run/docker.sock'\\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\\nVOLUME = 'infd-purpose-r1-restore-20261011'\\nMAX_BYTES = 512 * 1024**2\\n\\n\\ndef run(argv, body=None, timeout=90):\\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\\n\\n\\ndef json_result(result):\\n try:\\n value = json.loads(result.stdout)\\n except (ValueError, TypeError):\\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\\n 'phase did not verify complete; raw output withheld; no retry')\\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\\n require(set(value) <= permitted, 'unexpected output fields withheld')\\n from receipt_safety import counts\\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\\n if name in value:\\n counts(value[name])\\n for name in ('snapshot_sha256', 'client_diff_sha256'):\\n if name in value:\\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\\n if 'snapshot_bytes' in value:\\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\\n 'invalid output size withheld')\\n if 'snapshot_file' in value:\\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\\n return value\\n\\n\\ndef docker(argv, body=None, timeout=120):\\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\\n body=body, timeout=timeout)\\n\\n\\ndef remote(phase, revision, approved, snapshot_identity=None):\\n # Fixed module imported only after main verifies every executor source hash.\\n from native_program import PROGRAM\\n payload = {'snapshot_identity': snapshot_identity, 'phase': phase, 'source_revision': revision, 'approval': approved,\\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\\n\\n\\ndef copy_snapshot(phase, revision, approved, journal):\\n prior = (journal.data['identity']['recovery_anchor']['backup_result']\\n if phase == 'drill-copy-rescue-r1' else journal.data['phases']['cutover-backup']['result'])\\n metadata = remote(phase, revision, approved, snapshot_identity=prior)\\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\\n name = metadata['snapshot_file']\\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\\n 'fixed bounded snapshot required')\\n pod = metadata['pod_name']\\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\\n local = CUSTODY / name\\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\\n # Snapshot schema/count metadata was validated before opening this destination.\\n with os.fdopen(fd, 'wb') as destination:\\n command = ('kubectl exec -n informed-decision ' + pod +\\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\\n stderr=subprocess.DEVNULL)\\n selector = selectors.DefaultSelector()\\n selector.register(transfer.stdout, selectors.EVENT_READ)\\n deadline = time.monotonic() + 150\\n received = 0\\n try:\\n while True:\\n remaining = deadline - time.monotonic()\\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\\n block = os.read(transfer.stdout.fileno(), 1024**2)\\n if not block:\\n break\\n received += len(block)\\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\\n 'private copy exceeds frozen snapshot size')\\n destination.write(block)\\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\\n finally:\\n selector.close()\\n transfer.stdout.close()\\n if transfer.poll() is None:\\n transfer.kill()\\n transfer.wait()\\n destination.flush()\\n os.fsync(destination.fileno())\\n private(local)\\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\\n # Re-read identity/hash after transfer. This is verification, not a write retry.\\n after = remote(phase, revision, approved, snapshot_identity=prior)\\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\\n 'source identity/snapshot changed during transfer')\\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\\n\\n\\ndef offline_verify(journal):\\n from receipt_safety import counts\\n snapshot = CUSTODY / 'drill.sqlite'\\n private(snapshot)\\n previous = journal.data['phases']['drill-copy-rescue-r1']['result']\\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\\n identity = docker(['info', '--format', '{{json .Name}}'])\\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\\n 'local offline Docker engine identity changed')\\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\\n 'disposable volume absence not verified')\\n nonce = journal.data['phases']['offline-verify']['attempt_id']\\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\\n '--label', 'informed-decision.attempt=' + nonce,\\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'new volume identity unavailable')\\n volume = json.loads(inspected.stdout)\\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\\n journal.note('offline-verify', 'created_volume_identity', identity)\\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\\n # No host/live PVC/config/token mount exists; this detail needs packet review.\\n initializer = \\\"\\\"\\\"import hashlib,os,stat,sys\\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\\nfolder='/restore';expected=EXPECTED\\nif os.listdir(folder):raise ValueError('new empty private volume required')\\nos.chmod(folder,0o700)\\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\\ndigest=hashlib.sha256();size=0\\nwith os.fdopen(fd,'wb') as target:\\n while True:\\n block=sys.stdin.buffer.read(1024**2)\\n if not block:break\\n size+=len(block)\\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\\n target.write(block);digest.update(block)\\n target.flush();os.fsync(target.fileno())\\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\\nprint('{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}')\\n\\\"\\\"\\\".replace('EXPECTED', repr(previous['snapshot_sha256']))\\n with snapshot.open('rb') as source:\\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\\n '--entrypoint', 'python', IMAGE, '-c', initializer]\\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\\n json_result(copied)\\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\\n checked = counts(json.loads(readonly.stdout))\\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\\n 'inspect', '--db', '/restore/review.sqlite'])\\n require(admin.returncode == 0, 'offline admin result uncertain')\\n admin_counts = json.loads(admin.stdout)\\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\\n 'offline admin changed frozen snapshot counters')\\n # Admin Store construction must not silently alter schema/integrity/counters.\\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\\n post_checked = counts(json.loads(post.stdout))\\n require(post_checked == checked == previous['snapshot_readonly'],\\n 'offline admin altered frozen snapshot proof')\\n private(snapshot)\\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\\n 'created_volume_identity': identity,\\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\\n\\n\\ndef cleanup_offline(journal):\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\\n value = json.loads(inspected.stdout)\\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\\n and not value[0].get('Options'), 'volume ownership/recreation changed')\\n removed = docker(['volume', 'rm', VOLUME])\\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\\n 'cleanup outcome ambiguous; do not retry')\\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\\n 'native_and_offcluster_original_snapshots_retained': True}\\n\\n\\ndef main():\\n parser = argparse.ArgumentParser(description=__doc__)\\n parser.add_argument('--phase', choices=PHASES, required=True)\\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\\n parser.add_argument('--root-native-outcome', type=Path, required=True)\\n parser.add_argument('--source-revision', required=True)\\n args = parser.parse_args()\\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\\n 'fixed supervised receipt paths required')\\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\\n # Verify all prepared executor/input bytes before reading authority or dispatching.\\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\\n 'fixed executor sources required')\\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\\n 'deploy/lifecycle/service.candidate.json',\\n 'deploy/lifecycle/kustomization.yaml',\\n 'deploy/lifecycle/registries.candidate.json'},\\n 'fixed owner image sources required')\\n for relative, digest in plan['executor_files'].items():\\n target = ROOT / relative\\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\\n for relative, digest in plan['case_files'].items():\\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\\n 'case source path escaped')\\n target = CASE / relative\\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\\n for relative, digest in plan['owner_source_files'].items():\\n target = OWNER / relative\\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\\n capture_output=True)\\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\\n 'committed owner render source differs from approved inputs')\\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\\n from authority_journal import Journal, authority, original_anchor\\n private(args.root_authority_receipt)\\n private(args.root_native_outcome)\\n receipt = json.loads(args.root_authority_receipt.read_text())\\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\\n 'root verified executor plan differs')\\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\\n args.source_revision, args.phase)\\n parent = CUSTODY.parent\\n private(parent, directory=True)\\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\\n require(CUSTODY.exists(), 'original protected custody must already exist')\\n private(CUSTODY, directory=True)\\n capacity = os.statvfs(CUSTODY)\\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\\n 'independent protected custody headroom insufficient')\\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\\n private(CUSTODY / 'empty-docker-config', directory=True)\\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\\n anchor = original_anchor(CUSTODY, plan['recovery']['original_anchor'],\\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\\n plan['recovery']['original_identity'])\\n if args.phase == 'drill-copy-rescue-r1':\\n require(not os.path.lexists(CUSTODY / 'drill.sqlite')\\n and not os.path.lexists(CUSTODY / 'cutover.sqlite'), 'rescue destination must be absent')\\n identity = docker(['info', '--format', '{{json .Name}}'])\\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\\n 'local engine identity changed')\\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\\n 'existing restore volume forbids rescue')\\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json'),\\n 'recovery_anchor': anchor})\\n try:\\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\\n if args.phase in ('drill-copy-rescue-r1', 'cutover-copy'):\\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\\n elif args.phase == 'offline-verify':\\n result = offline_verify(journal)\\n elif args.phase == 'cleanup-offline':\\n result = cleanup_offline(journal)\\n else:\\n result = remote(args.phase, args.source_revision, approved)\\n require(original_anchor(CUSTODY, plan['recovery']['original_anchor'],\\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\\n plan['recovery']['original_identity']) == anchor,\\n 'original failed journal changed during new phase')\\n journal.finish(args.phase, result)\\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\\n except BaseException as error:\\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\\n 'raw_output_withheld': True}\\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\\n journal.finish(args.phase, safe)\\n print(json.dumps(safe))\\n raise SystemExit(1) from None\\n finally:\\n journal.close()\\n\\n\\nif __name__ == '__main__':\\n try:\\n main()\\n except Exception:\\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\\n\"\n },\n \"authority_journal.py\": {\n \"sha256\": \"0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68\",\n \"content\": \"\\\"\\\"\\\"Supervised receipt bookkeeping, not an authenticated approval provider.\\\"\\\"\\\"\\nimport datetime\\nimport fcntl\\nimport hashlib\\nimport json\\nimport os\\nimport re\\nfrom pathlib import Path\\nimport stat\\nimport uuid\\n\\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\n\\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\\n \\\"\\\"\\\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\\n\\n Receipt files/flags are not signed grants. This function checks the exact\\n supervised receipt relation; existing harness/founder authority remains the\\n actual permission boundary. It never authenticates a caller as human.\\n \\\"\\\"\\\"\\n now = now or datetime.datetime.now(datetime.timezone.utc)\\n require(phase in PHASES, 'fixed phase required')\\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\\n and receipt.get('memo_version') == 2 and receipt.get('memo_sha256') == memo_sha\\n and receipt.get('source_revision') == source_revision\\n and receipt.get('activation') == 'APPROVED'\\n and receipt.get('authority_mode') == 'ADMINISTER'\\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\\n and receipt.get('runtime_authenticated_grant') is False\\n and receipt.get('outcome_query') == '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\\n 'exact externally verified supervised receipt required')\\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\\n 'fresh root native readback required before every phase')\\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\\n require(now < deadline, 'approved execution window expired')\\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\\n review_id = outcome['review']['memo_id']\\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\\n accepted = [x for x in outcome.get('dispositions', [])\\n if x.get('submission_state') == 'confirmed'\\n and x.get('disposition', {}).get('verb') == 'accept'\\n and x['disposition'].get('memo_version') == 1]\\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\\n accepted = accepted[0]['disposition']\\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\\n and accepted.get('approval_id') == receipt.get('approval_id')\\n and accepted.get('id') == receipt.get('disposition_id')\\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\\n 'native disposition identifiers are malformed')\\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\\n\\n\\ndef original_anchor(parent, expected, backup_result, original_identity):\\n \\\"\\\"\\\"Read only sanitized original journal; never rewrite/synthesize its phases.\\\"\\\"\\\"\\n path = Path(parent) / 'execution-journal.json'\\n private(path)\\n require(sha(path) == expected['original_journal_sha256'], 'original journal bytes changed')\\n original = json.loads(path.read_text())\\n require(original.get('identity') == original_identity, 'original approved identity changed')\\n phases = original.get('phases', {})\\n require(set(phases) == {'drill-backup', 'drill-copy'}, 'unexpected original action or rollout')\\n for name, fields in expected['phase_metadata'].items():\\n require(all(phases[name].get(key) == value for key,value in fields.items()),\\n 'original failed/completed attempt identity changed')\\n require(phases['drill-backup'].get('result') == backup_result\\n and backup_result.get('all_checks_pass') is True\\n and phases['drill-copy'].get('result', {}).get('all_checks_pass') is False,\\n 'original backup/copy outcome changed')\\n require(backup_result.get('snapshot_sha256') == expected['snapshot_sha256']\\n and backup_result.get('snapshot_bytes') == expected['snapshot_bytes']\\n and backup_result.get('pod_uid') == 'e8561ae0-4b09-4455-924d-64c27b625fc7',\\n 'original frozen snapshot identity changed')\\n require(sha(path) == expected['original_journal_sha256'], 'original journal changed during read')\\n return {'original_journal_sha256': expected['original_journal_sha256'],\\n 'original_copy_attempt_id': phases['drill-copy']['attempt_id'],\\n 'original_backup_attempt_id': phases['drill-backup']['attempt_id'],\\n 'backup_result': backup_result, 'old_uncertain_phase_retained': True}\\n\\n\\nclass Journal:\\n def __init__(self, parent, identity):\\n self.parent = Path(parent)\\n private(self.parent, directory=True)\\n self.path = self.parent / 'rescue-execution-journal-r1.json'\\n self.lock = os.open(self.parent / 'rescue-execution-r1.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\\n private(self.parent / 'rescue-execution-r1.lock')\\n if self.path.exists():\\n private(self.path)\\n self.data = json.loads(self.path.read_text())\\n require(self.data['identity'] == identity, 'journal case/source identity changed')\\n else:\\n self.data = {'identity': identity, 'phases': {}}\\n self.save()\\n\\n def save(self):\\n temporary = self.parent / 'execution-journal.new'\\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\\n try:\\n with os.fdopen(fd, 'w') as stream:\\n json.dump(self.data, stream, indent=2)\\n stream.write('\\\\n')\\n stream.flush()\\n os.fsync(stream.fileno())\\n os.replace(temporary, self.path)\\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\\n try:\\n os.fsync(directory)\\n finally:\\n os.close(directory)\\n except BaseException:\\n # Retain evidence rather than overwriting an uncertain durable intent.\\n raise\\n\\n def start(self, phase, approval):\\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\\n require(phase in PHASES, 'fixed rescue or remaining phase required')\\n predecessors = dict(zip(PHASES[1:7], PHASES[:6]))\\n predecessors['rollback-verify'] = 'rollback'\\n if phase in predecessors:\\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\\n 'preceding phase is not verified complete')\\n if phase == 'rollback':\\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\\n 'attempt_id': str(uuid.uuid4()),\\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\\n self.save()\\n\\n def note(self, phase, key, value):\\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\\n self.data['phases'][phase][key] = value\\n self.save()\\n\\n def finish(self, phase, result):\\n entry = self.data['phases'][phase]\\n require(entry['state'] == 'RUNNING', 'phase intent missing')\\n entry['result'] = result\\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\\n self.save()\\n\\n def close(self):\\n os.close(self.lock)\\n\"\n },\n \"execution-plan.json\": {\n \"sha256\": \"9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258\",\n \"content\": \"{\\n \\\"kind\\\": \\\"informed-decision.supervised-mechanical-release-plan\\\",\\n \\\"version\\\": 2,\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"trial_id\\\": \\\"infd-purpose-20261011-r1\\\",\\n \\\"state\\\": \\\"prepared-unapproved\\\",\\n \\\"executor_files\\\": {\\n \\\"actuator.py\\\": \\\"86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2\\\",\\n \\\"authority_journal.py\\\": \\\"0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68\\\",\\n \\\"native_program.py\\\": \\\"788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91\\\",\\n \\\"receipt_safety.py\\\": \\\"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\\\"\\n },\\n \\\"case_files\\\": {\\n \\\"change_guard.py\\\": \\\"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\\\",\\n \\\"sqlite_readonly.py\\\": \\\"9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509\\\",\\n \\\"preflight-inputs.json\\\": \\\"03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b\\\",\\n \\\"sealed-live-deployment.json\\\": \\\"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\\\",\\n \\\"sealed-native-dependencies.json\\\": \\\"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\\\",\\n \\\"candidate-deployment.json\\\": \\\"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\\\",\\n \\\"rollback-deployment.json\\\": \\\"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\\\",\\n \\\"check_installed.py\\\": \\\"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\\\",\\n \\\"published-verification.json\\\": \\\"e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd\\\",\\n \\\"security-summary.json\\\": \\\"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\\\",\\n \\\"original-approved-drill-backup.json\\\": \\\"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\\\",\\n \\\"original-approved-drill-copy-failure.json\\\": \\\"fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56\\\",\\n \\\"original-journal-sanitized-anchor.json\\\": \\\"988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454\\\"\\n },\\n \\\"owner_source_files\\\": {\\n \\\"deploy/lifecycle/admission.candidate.json\\\": \\\"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\\\",\\n \\\"deploy/lifecycle/service.candidate.json\\\": \\\"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\\\",\\n \\\"deploy/lifecycle/kustomization.yaml\\\": \\\"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\\\",\\n \\\"deploy/lifecycle/registries.candidate.json\\\": \\\"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\\\"\\n },\\n \\\"candidate_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\\\",\\n \\\"prior_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\\",\\n \\\"source_revision\\\": \\\"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\\\",\\n \\\"phases\\\": [\\n \\\"drill-copy-rescue-r1\\\",\\n \\\"offline-verify\\\",\\n \\\"cleanup-offline\\\",\\n \\\"cutover-backup\\\",\\n \\\"cutover-copy\\\",\\n \\\"release\\\",\\n \\\"verify\\\",\\n \\\"rollback\\\",\\n \\\"rollback-verify\\\"\\n ],\\n \\\"authorization\\\": \\\"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\\\",\\n \\\"execute_by\\\": \\\"2026-10-12T23:59:59Z\\\",\\n \\\"raw_output_withheld\\\": true,\\n \\\"native_data_or_workload_action_executed\\\": false,\\n \\\"deadline_semantics\\\": \\\"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\\\",\\n \\\"recovery\\\": {\\n \\\"original_anchor\\\": {\\n \\\"original_journal_sha256\\\": \\\"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\\\",\\n \\\"phase_metadata\\\": {\\n \\\"drill-backup\\\": {\\n \\\"state\\\": \\\"COMPLETE\\\",\\n \\\"attempt_id\\\": \\\"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:38:45.310653+00:00\\\"\\n },\\n \\\"drill-copy\\\": {\\n \\\"state\\\": \\\"UNCERTAIN\\\",\\n \\\"attempt_id\\\": \\\"329ef190-1692-4246-b953-e6a59664abcc\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:39:50.198740+00:00\\\"\\n }\\n },\\n \\\"frozen_backup_receipt_sha256\\\": \\\"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\\\",\\n \\\"snapshot_sha256\\\": \\\"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\\\",\\n \\\"snapshot_bytes\\\": 19537920,\\n \\\"off_cluster_file_exists\\\": false,\\n \\\"old_uncertain_retry_authorized\\\": false\\n },\\n \\\"original_identity\\\": {\\n \\\"proposal\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"source_revision\\\": \\\"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\\\",\\n \\\"memo_sha256\\\": \\\"506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937\\\",\\n \\\"plan_sha256\\\": \\\"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\\\"\\n },\\n \\\"new_journal\\\": \\\"rescue-execution-journal-r1.json\\\",\\n \\\"new_phase\\\": \\\"drill-copy-rescue-r1\\\",\\n \\\"old_uncertain_phase_overwrite_or_retry\\\": false,\\n \\\"new_snapshot_backup\\\": false,\\n \\\"snapshot_or_sidecar_mutation\\\": false,\\n \\\"mapping\\\": \\\"offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal\\\"\\n },\\n \\\"source_memo_version\\\": 2,\\n \\\"native_review_memo_version\\\": 1\\n}\\n\"\n },\n \"native_program.py\": {\n \"sha256\": \"788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91\",\n \"content\": \"\\\"\\\"\\\"Fixed version2 recovery remote source; requires fresh exact acceptance.\\\"\\\"\\\"\\nPROGRAM = '\\\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\\\nif sys.flags.optimize:raise RuntimeError(\\\\'optimized interpreter refused\\\\')\\\\npayload=json.loads(__PAYLOAD__)\\\\nexec(__GUARD__)\\\\nphase=payload[\\\\'phase\\\\']\\\\nif phase not in (\\\\'cutover-backup\\\\',\\\\'drill-copy-rescue-r1\\\\',\\\\'cutover-copy\\\\',\\\\'release\\\\',\\\\'verify\\\\',\\\\'rollback\\\\',\\\\'rollback-verify\\\\'):raise ValueError(\\\\'fixed native phase required\\\\')\\\\ndeadline=datetime.datetime.fromisoformat(\\\\'2026-10-12T23:59:59+00:00\\\\')\\\\ndef require(value,reason):\\\\n if not value:raise ValueError(reason)\\\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\\\'drill-backup\\\\' else 1)+16*1024**2,\\\\'bounded native snapshot capacity required\\\\')\\\\n if action==\\\\'drill-backup\\\\':\\\\n require(not os.path.lexists(folder),\\\\'native case directory must be unique\\\\')\\\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\\\n private(folder,True)\\\\n filename=\\\\'drill.sqlite\\\\' if action==\\\\'drill-backup\\\\' else \\\\'cutover.sqlite\\\\';output=folder+\\\\'/\\\\'+filename\\\\n require(not os.path.lexists(output),\\\\'snapshot output must be unique\\\\')\\\\n admin=subprocess.run([\\\\'informed-decision-admin\\\\',\\\\'backup\\\\',\\\\'--db\\\\',db,\\\\'--output\\\\',output],capture_output=True,text=True,timeout=120)\\\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\\\'status\\\\':\\\\'backed_up\\\\',\\\\'consistent_snapshot\\\\':True},\\\\'backup completion not verified; do not retry\\\\')\\\\n private(output)\\\\n for suffix in (\\\\'-wal\\\\',):\\\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\\\'snapshot has WAL frames; immutable read refused\\\\')\\\\n digest=hashlib.sha256()\\\\n with open(output,\\\\'rb\\\\') as stream:\\\\n for block in iter(lambda:stream.read(1024**2),b\\\\'\\\\'):digest.update(block)\\\\n frozen_digest=digest.hexdigest()\\\\n snapshot=counts(inspect_closed_snapshot(output,frozen_digest))\\\\n size=os.stat(output).st_size;require(0 10**12\\n for number in value[group].values()):\\n raise ValueError('count-only receipt values refused')\\n return value\\n\"\n },\n \"root-authority-receipt-template.json\": {\n \"sha256\": \"db28d03e3c46b4de52dc404c912054483f4a2aaa6c4f476b7892cab2a5f408d4\",\n \"content\": \"{\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"memo_id\\\": \\\"infd-20261011-purpose-overlay-r1\\\",\\n \\\"memo_version\\\": 2,\\n \\\"memo_sha256\\\": null,\\n \\\"source_revision\\\": null,\\n \\\"activation\\\": \\\"PENDING\\\",\\n \\\"authority_mode\\\": \\\"ADMINISTER\\\",\\n \\\"target\\\": \\\"realm:kubernetes/railiance01/informed-decision\\\",\\n \\\"verification_method\\\": \\\"root-fixed-origin-native-readback\\\",\\n \\\"runtime_authenticated_grant\\\": false,\\n \\\"verified_at\\\": null,\\n \\\"accepted_at\\\": null,\\n \\\"review_memo_id\\\": null,\\n \\\"approval_id\\\": null,\\n \\\"disposition_id\\\": null,\\n \\\"native_outcome_sha256\\\": null,\\n \\\"executor_plan_sha256\\\": \\\"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\\\",\\n \\\"outcome_query\\\": \\\"/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2\\\",\\n \\\"review_memo_version\\\": 1\\n}\\n\"\n },\n \"test_execution.py\": {\n \"sha256\": \"b250441282513862eeb990b18d01bb1eafe787b934d670a75a2bfaa9f5cfb89c\",\n \"content\": \"\\\"\\\"\\\"Synthetic custody/transport tests. No native data, Docker or cluster action.\\\"\\\"\\\"\\nimport copy\\nimport datetime\\nimport io\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport subprocess\\nimport sys\\nimport tempfile\\nimport unittest\\nfrom unittest.mock import patch\\nfrom contextlib import redirect_stdout\\n\\nimport actuator\\nfrom authority_journal import Journal, authority\\nfrom native_program import PROGRAM\\nfrom receipt_safety import counts\\n\\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\\nREVISION = 'e' * 40\\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\\n\\n\\ndef accepted():\\n approval = '11111111-1111-4111-8111-111111111111'\\n review = 'review-22222222-2222-4222-8222-222222222222'\\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 2,\\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False, 'outcome_query': '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\\n 'approval_id': approval, 'id': disposition,\\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\\n 'at': receipt['accepted_at']}}]}\\n return receipt, outcome\\n\\n\\nclass AuthorityAndCustody(unittest.TestCase):\\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\\n receipt, outcome = accepted()\\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-copy-rescue-r1', NOW)\\n self.assertEqual(result['approval_id'], receipt['approval_id'])\\n\\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\\n mutations = [lambda r, o: r.update(activation='PENDING'),\\n lambda r, o: r.update(memo_sha256='changed'),\\n lambda r, o: r.update(source_revision='changed'),\\n lambda r, o: r.update(target='other'),\\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\\n lambda r, o: r.update(verification_method='caller-asserted'),\\n lambda r, o: r.update(runtime_authenticated_grant=True),\\n lambda r, o: o['review'].update(stale=True),\\n lambda r, o: o['review'].update(intake_state='pending'),\\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=3),\\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n r, o = accepted()\\n mutate(r, o)\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\\n\\n def test_expired_window_and_unknown_phase_refuse(self):\\n r, o = accepted()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\\n r['verified_at'] = late.isoformat()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\\n\\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\\n with tempfile.TemporaryDirectory() as directory:\\n parent = Path(directory)\\n os.chmod(parent, 0o700)\\n journal = Journal(parent, {'case': 'fixture'})\\n journal.start('drill-copy-rescue-r1', {'approval_id': 'fixture'})\\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-copy-rescue-r1']['state'], 'RUNNING')\\n journal.close() # simulated crash before result\\n recovered = Journal(parent, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-copy-rescue-r1', {})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-copy-rescue-r1', {})\\n recovered.close()\\n\\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\\n with tempfile.TemporaryDirectory() as directory:\\n os.chmod(directory, 0o700)\\n j = Journal(directory, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n for phase in actuator.PHASES[:5]:\\n j.start(phase, {})\\n j.finish(phase, {'all_checks_pass': True})\\n j.start('release', {})\\n j.finish('release', {'all_checks_pass': False})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n with self.assertRaises(ValueError):\\n j.start('verify', {})\\n j.start('rollback', {})\\n j.finish('rollback', {'all_checks_pass': True})\\n j.close()\\n\\n def test_secret_or_unknown_child_output_is_withheld(self):\\n for body in ('not-json', '{\\\"all_checks_pass\\\":true,\\\"token\\\":\\\"private-value\\\"}',\\n '{\\\"all_checks_pass\\\":true,\\\"snapshot_readonly\\\":{\\\"schema_version\\\":5}}'):\\n with self.assertRaises(ValueError):\\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\\n wrong = copy.deepcopy(COUNT)\\n wrong['outbox'] = {'private-row-value': 1}\\n with self.assertRaises(ValueError):\\n counts(wrong)\\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\\n\\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\\n blob = b'synthetic private fixture bytes'\\n digest = __import__('hashlib').sha256(blob).hexdigest()\\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\\n journal = type('FixtureJournal', (), {'data': {'identity': {'recovery_anchor': {'backup_result': metadata}}}})()\\n real_popen = subprocess.Popen\\n for extra in (b'', b'oversized'):\\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\\n os.chmod(folder, 0o700)\\n output = io.StringIO()\\n\\n def child(*args, **kwargs):\\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\\n\\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\\\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\\n if extra:\\n with self.assertRaises(ValueError):\\n actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\\n else:\\n result = actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\\n self.assertTrue(result['off_cluster_private_copy_verified'])\\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\\n self.assertEqual(output.getvalue(), '')\\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\\n\\n def test_recreated_offline_volume_cannot_be_deleted(self):\\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\\n journal = type('FixtureJournal', (), {'data': {'phases': {\\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\\n with self.assertRaises(ValueError):\\n actuator.cleanup_offline(journal)\\n self.assertEqual(mocked.call_count, 1)\\n\\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\\n for defect in ('none', 'post-integrity', 'original-hash'):\\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\\n folder=Path(directory);os.chmod(folder,0o700)\\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\\n digest=actuator.sha(snapshot)\\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy-rescue-r1':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\\n reads=[]\\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\\n def docker(argv, body=None, **kwargs):\\n if argv[0]=='info':body=json.dumps('bnt-lap001')\\n elif argv[:2]==['volume','ls']:body=''\\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\\n elif 'informed-decision-admin' in argv:\\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\\n elif '--entrypoint' in argv and 'python' in argv:\\n reads.append(argv);proof=copy.deepcopy(COUNT)\\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\\n body=json.dumps(proof)\\n else:raise AssertionError('unexpected offline command')\\n return subprocess.CompletedProcess(argv,0,body,'')\\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}','')):\\n if defect=='none':\\n result=actuator.offline_verify(journal)\\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\\n self.assertTrue(result['original_snapshot_hash_unchanged'])\\n else:\\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\\n self.assertEqual(len(reads),2)\\n\\n\\nclass FixedNativeProgram(unittest.TestCase):\\n def fixture(self):\\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\\n live = copy.deepcopy(sealed)\\n live['metadata'].update(generation=42)\\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\\n cm = copy.deepcopy(dependencies['configmap'])\\n cm.pop('canonical_data_sha256')\\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\\n pvc = copy.deepcopy(dependencies['pvc'])\\n pvc['status'] = {'phase': 'Bound'}\\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\\n 'dependencies': dependencies, 'candidate': service,\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\\n return objects, payload\\n\\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\\n writes = []\\n calls = []\\n\\n def fake(argv, input=None, **kwargs):\\n calls.append(argv)\\n if argv[:2] == ['kubectl', 'get']:\\n kind = argv[2]\\n if kind in objects:\\n body = objects[kind]\\n elif kind == 'pods':\\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\\n 'spec': objects['deployment']['spec']['template']['spec'],\\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\\n elif kind == 'replicaset':\\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\\n elif kind == 'nodes':\\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\\n else:\\n raise AssertionError('unexpected fixed metadata route')\\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\\n if argv[:2] == ['kubectl', 'exec']:\\n if schema_refused:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, json.dumps({\\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\\n if argv[:2] == ['kubectl', 'apply']:\\n admitted = copy.deepcopy(payload['sealed'])\\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\\n if argv[:2] == ['kubectl', 'describe']:\\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\\\n cpu 3460m (86%)\\\\n', '')\\n if argv[:2] == ['kubectl', 'diff']:\\n return subprocess.CompletedProcess(argv, 1, '-image: base\\\\n+image: candidate\\\\n', '')\\n if argv[:2] == ['kubectl', 'patch']:\\n if '--dry-run=server' not in argv:\\n writes.append(json.loads(input))\\n if ambiguous:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\\\n', '')\\n raise AssertionError('unexpected command')\\n\\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n output = io.StringIO()\\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\\n try:\\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\\n except (ValueError, SystemExit):\\n pass\\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\\n return receipt, writes, calls\\n\\n def test_only_existing_application_operation_and_deployment_are_requested(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n operation = writes[0][-1]['value']\\n self.assertFalse(operation['sync']['prune'])\\n self.assertEqual(operation['sync']['resources'], [\\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\\n\\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\\n lambda o: o['application']['spec'].update(sources=[{}]),\\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n objects, payload = self.fixture()\\n mutate(objects)\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n def test_preopen_schema_refusal_prevents_image_operation(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n\\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\\n objects, payload = self.fixture()\\n payload['phase'] = 'rollback'\\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\\n objects['application']['spec']['source']['targetRevision'] = REVISION\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\\n\\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\\n for defect in ('cm', 'pvc', 'image'):\\n with self.subTest(defect=defect):\\n objects, payload = self.fixture();payload['phase'] = 'rollback'\\n objects['deployment']['status']['readyReplicas'] = 0\\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\\n\\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\\n self.assertEqual(writes, [])\\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\\n objects['deployment']['status']['readyReplicas'] = 0\\n receipt, writes, calls = self.execute_fake(objects,payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n\\n def test_ambiguous_patch_is_never_retried(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(len(writes), 1)\\n\\n\\nif __name__ == '__main__':\\n unittest.main()\\n\"\n },\n \"test_rescue_execution.py\": {\n \"sha256\": \"8ecbb0260a87a7a12bd5c4c9678fb2a9d43a4ea7322129734bc21f8ee383cd70\",\n \"content\": \"\\\"\\\"\\\"Synthetic recovery guards; no actual private journal/DB/native command.\\\"\\\"\\\"\\nimport copy\\nimport datetime\\nimport hashlib\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport tempfile\\nimport unittest\\nfrom authority_journal import Journal, authority, original_anchor\\nfrom test_execution import accepted, NOW, REVISION\\n\\nROOT=Path(__file__).parent\\nPLAN=json.loads((ROOT/'execution-plan.json').read_text())\\nCASE=ROOT.parent\\nBACKUP=json.loads((CASE/'original-approved-drill-backup.json').read_text())\\n\\nclass RescueGuards(unittest.TestCase):\\n def original(self,parent):\\n original={'identity':PLAN['recovery']['original_identity'],'phases':{}}\\n for name,metadata in PLAN['recovery']['original_anchor']['phase_metadata'].items():\\n original['phases'][name]={**metadata,'result':BACKUP if name=='drill-backup' else {'all_checks_pass':False}}\\n p=parent/'execution-journal.json';p.write_text(json.dumps(original));os.chmod(p,0o600)\\n anchor=copy.deepcopy(PLAN['recovery']['original_anchor']);anchor['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\\n return p,original,anchor\\n\\n def test_exact_original_failed_journal_is_linked_without_mutation(self):\\n with tempfile.TemporaryDirectory() as directory:\\n parent=Path(directory);os.chmod(parent,0o700);p,original,expected=self.original(parent);before=p.read_bytes()\\n anchor=original_anchor(parent,expected,BACKUP,original['identity'])\\n j=Journal(parent,{'fixture':True,'recovery_anchor':anchor});j.start('drill-copy-rescue-r1',{})\\n self.assertEqual(p.read_bytes(),before);self.assertEqual(j.path.name,'rescue-execution-journal-r1.json')\\n j.finish('drill-copy-rescue-r1',{'all_checks_pass':True});j.start('offline-verify',{})\\n self.assertEqual(p.read_bytes(),before);j.close()\\n\\n def test_original_missing_uncertain_recreated_attempt_or_rollout_refuse(self):\\n for defect in ('missing','complete','attempt','rollout','hash'):\\n with self.subTest(defect=defect),tempfile.TemporaryDirectory() as directory:\\n parent=Path(directory);os.chmod(parent,0o700);p,o,e=self.original(parent)\\n if defect=='missing':o['phases'].pop('drill-copy')\\n elif defect=='complete':o['phases']['drill-copy']['state']='COMPLETE'\\n elif defect=='attempt':o['phases']['drill-copy']['attempt_id']='different'\\n elif defect=='rollout':o['phases']['release']={'state':'RUNNING'}\\n if defect!='hash':\\n p.write_text(json.dumps(o));e['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\\n else:e['original_journal_sha256']='0'*64\\n with self.assertRaises((ValueError,KeyError)):original_anchor(parent,e,BACKUP,PLAN['recovery']['original_identity'])\\n\\n def test_rescue_replay_refused_and_old_phase_never_admitted(self):\\n with tempfile.TemporaryDirectory() as directory:\\n os.chmod(directory,0o700);j=Journal(directory,{'fixture':True})\\n with self.assertRaises(ValueError):j.start('drill-copy',{})\\n with self.assertRaises(ValueError):j.start('drill-backup',{})\\n with self.assertRaises(ValueError):j.start('offline-verify',{})\\n j.start('drill-copy-rescue-r1',{});j.finish('drill-copy-rescue-r1',{'all_checks_pass':False})\\n with self.assertRaises(ValueError):j.start('drill-copy-rescue-r1',{})\\n with self.assertRaises(ValueError):j.start('offline-verify',{})\\n j.close()\\n\\n def test_new_authority_requires_version2_old_approval_refuses(self):\\n receipt,outcome=accepted();receipt['memo_version']=2;outcome['dispositions'][0]['disposition']['memo_version']=1\\n authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\\n receipt['memo_version']=1\\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy',NOW)\\n receipt['memo_version']=2;receipt['outcome_query']='/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=1'\\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\\n\\n def test_explicit_offline_input_mapping_and_absence_guards(self):\\n source=(ROOT/'actuator.py').read_text()\\n self.assertIn(\\\"previous = journal.data['phases']['drill-copy-rescue-r1']['result']\\\",source)\\n self.assertIn(\\\"not os.path.lexists(CUSTODY / 'drill.sqlite')\\\",source)\\n self.assertIn(\\\"VOLUME not in listed.stdout.splitlines()\\\",source)\\n self.assertNotIn(\\\"os.mkdir(CUSTODY\\\",source)\\n import ast\\n program=ast.literal_eval(next(n.value for n in ast.parse((ROOT/'native_program.py').read_text()).body if isinstance(n,ast.Assign)))\\n compile(program,'native-rescue-fixture','exec')\\n self.assertIn(\\\"phase=='drill-copy-rescue-r1':require(pod['metadata']['uid']=='e8561ae0-4b09-4455-924d-64c27b625fc7'\\\",program)\\n\\nif __name__=='__main__':unittest.main()\\n\"\n },\n \"validation.json\": {\n \"sha256\": \"6f3379f63968e9a0294aba7b5b57ea4662adda6b1fa1b37eff11c2f72a58931f\",\n \"content\": \"{\\n \\\"state\\\": \\\"prepared-unapproved-version2\\\",\\n \\\"executor_tests\\\": 21,\\n \\\"snapshot_mock_tests\\\": 5,\\n \\\"native_actions\\\": false,\\n \\\"database_admin_commands_in_preparation\\\": false,\\n \\\"old_journal_modified\\\": false,\\n \\\"old_failed_phase_retried\\\": false,\\n \\\"owner_head_unchanged\\\": \\\"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\\\"\\n}\\n\"\n }\n },\n \"native_execution\": false,\n \"case_evidence\": {\n \"original-approved-drill-backup.json\": {\n \"sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"content\": \"{\\\"phase\\\": \\\"drill-backup\\\", \\\"all_checks_pass\\\": true, \\\"raw_output_withheld\\\": true, \\\"native_approval_verified_by_root\\\": {\\\"approval_id\\\": \\\"ec92806a-9aa6-494f-a76b-0385f39ba609\\\", \\\"disposition_id\\\": \\\"disp-0968373d-294d-42bf-8979-36a7c5dd38cf\\\", \\\"accepted_at\\\": \\\"2026-10-11T02:34:20Z\\\", \\\"verified_at\\\": \\\"2026-10-11T02:38:41.777949+00:00\\\"}, \\\"native_authenticated_grant\\\": false, \\\"source_readonly_baseline\\\": {\\\"schema_version\\\": 5, \\\"lifecycle\\\": {\\\"records\\\": 15, \\\"events\\\": 50, \\\"pending\\\": 0}, \\\"outbox\\\": {\\\"delivered\\\": 320}, \\\"submissions\\\": {\\\"confirmed\\\": 41}, \\\"integrity\\\": \\\"ok\\\", \\\"read_only_pre_open\\\": true, \\\"store_constructed\\\": false}, \\\"snapshot_readonly\\\": {\\\"schema_version\\\": 5, \\\"lifecycle\\\": {\\\"records\\\": 15, \\\"events\\\": 50, \\\"pending\\\": 0}, \\\"outbox\\\": {\\\"delivered\\\": 320}, \\\"submissions\\\": {\\\"confirmed\\\": 41}, \\\"integrity\\\": \\\"ok\\\", \\\"read_only_pre_open\\\": true, \\\"store_constructed\\\": false}, \\\"snapshot_sha256\\\": \\\"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\\\", \\\"snapshot_bytes\\\": 19537920, \\\"snapshot_file\\\": \\\"drill.sqlite\\\", \\\"native_parent_private\\\": true, \\\"native_uid\\\": 10001, \\\"pod_name\\\": \\\"informed-decision-f557556df-mwpz7\\\", \\\"pod_uid\\\": \\\"e8561ae0-4b09-4455-924d-64c27b625fc7\\\"}\\n\"\n },\n \"original-approved-drill-copy-failure.json\": {\n \"sha256\": \"fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56\",\n \"content\": \"{\\\"all_checks_pass\\\": false, \\\"phase\\\": \\\"drill-copy\\\", \\\"failure_class\\\": \\\"ValueError\\\", \\\"failure\\\": \\\"fixed phase outcome uncertain; original evidence retained; no retry\\\", \\\"raw_output_withheld\\\": true}\\n\"\n },\n \"original-journal-sanitized-anchor.json\": {\n \"sha256\": \"988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454\",\n \"content\": \"{\\n \\\"original_journal_sha256\\\": \\\"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\\\",\\n \\\"phase_metadata\\\": {\\n \\\"drill-backup\\\": {\\n \\\"state\\\": \\\"COMPLETE\\\",\\n \\\"attempt_id\\\": \\\"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:38:45.310653+00:00\\\"\\n },\\n \\\"drill-copy\\\": {\\n \\\"state\\\": \\\"UNCERTAIN\\\",\\n \\\"attempt_id\\\": \\\"329ef190-1692-4246-b953-e6a59664abcc\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:39:50.198740+00:00\\\"\\n }\\n },\\n \\\"frozen_backup_receipt_sha256\\\": \\\"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\\\",\\n \\\"snapshot_sha256\\\": \\\"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\\\",\\n \\\"snapshot_bytes\\\": 19537920,\\n \\\"off_cluster_file_exists\\\": false,\\n \\\"old_uncertain_retry_authorized\\\": false\\n}\\n\"\n }\n }\n}\n" + }, + { + "item_id": "sqlite-readonly-py", + "media_type": "text/plain", + "content": "\"\"\"Pre-open schema/integrity/count proof; stdlib only, never constructs Store.\"\"\"\nimport argparse\nfrom contextlib import closing\nimport hashlib\nimport os\nimport re\nimport stat\nimport json\nfrom pathlib import Path\nimport sqlite3\n\n\ndef inspect_readonly(path, *, _closed_snapshot=False):\n path = Path(path)\n if not path.is_file() or path.is_symlink():\n raise ValueError('existing nonsymlink private database required')\n uri = path.resolve().as_uri() + '?mode=ro' + ('&immutable=1' if _closed_snapshot else '')\n # sqlite3.Connection context management ends transactions; it does not close.\n with closing(sqlite3.connect(uri, uri=True, timeout=5)) as db:\n db.execute('PRAGMA query_only=ON')\n db.execute('BEGIN')\n version = db.execute('PRAGMA user_version').fetchone()[0]\n if version != 5:\n raise ValueError('pre-open database is not schema5; refuse migration')\n if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]:\n raise ValueError('read-only integrity check refused')\n lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0]\n for name, table in (('records', 'lifecycle_records'),\n ('events', 'lifecycle_events'),\n ('pending', 'lifecycle_pending'))}\n result = {'schema_version': version, 'lifecycle': lifecycle,\n 'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')),\n 'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')),\n 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False}\n db.rollback()\n return result\n\n\ndef inspect_closed_snapshot(path, expected_sha256):\n \"\"\"Only a privately retained, frozen main-file snapshot with no WAL frames.\n\n Caller must establish exclusive snapshot creation/admin exit/no writer, and\n supply the recorded frozen main digest. Never use for the live database.\n Immutable SQLite reads ignore stale SHM and never create/change sidecars.\n Existing sidecars remain custody evidence; nothing is deleted/checkpointed.\n \"\"\"\n path = Path(path)\n if re.fullmatch(r'[0-9a-f]{64}', expected_sha256) is None:\n raise ValueError('exact frozen snapshot digest required')\n def metadata(target):\n info = target.lstat()\n if not stat.S_ISREG(info.st_mode) or stat.S_IMODE(info.st_mode) != 0o600 or info.st_nlink != 1:\n raise ValueError('private single-link snapshot custody required')\n return info\n main = metadata(path)\n if not 0 < main.st_size <= 512 * 1024**2:\n raise ValueError('bounded frozen snapshot required')\n def sidecars():\n identities = {}\n for suffix in ('-wal', '-shm'):\n target = Path(str(path) + suffix)\n if os.path.lexists(target):\n info = metadata(target)\n if info.st_uid != main.st_uid or info.st_gid != main.st_gid:\n raise ValueError('snapshot sidecar custody changed')\n if suffix == '-wal' and info.st_size != 0:\n raise ValueError('snapshot has WAL frames; immutable read refused')\n identities[suffix] = (info.st_dev, info.st_ino, info.st_size, info.st_mtime_ns)\n return identities\n before_sidecars = sidecars()\n def digest():\n value = hashlib.sha256()\n with path.open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n value.update(block)\n return value.hexdigest()\n if digest() != expected_sha256:\n raise ValueError('frozen main-file digest changed before inspection')\n proof = inspect_readonly(path, _closed_snapshot=True)\n after = metadata(path)\n if (after.st_dev, after.st_ino, after.st_uid, after.st_gid, after.st_size) != (main.st_dev, main.st_ino, main.st_uid, main.st_gid, main.st_size):\n raise ValueError('frozen main-file identity changed')\n if digest() != expected_sha256 or sidecars() != before_sidecars:\n raise ValueError('frozen snapshot changed during inspection')\n return proof\n\n\nif __name__ == '__main__':\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--db', type=Path, required=True)\n args = parser.parse_args()\n try:\n print(json.dumps(inspect_readonly(args.db), sort_keys=True))\n except Exception:\n raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None\n" + }, + { + "item_id": "sealed-native-dependencies-json", + "media_type": "application/json", + "content": "{\n \"configmap\": {\n \"apiVersion\": \"v1\",\n \"immutable\": true,\n \"kind\": \"ConfigMap\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/ConfigMap:informed-decision/informed-decision-runtime-6c221878d051\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision-runtime-6c221878d051\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\"\n },\n \"canonical_data_sha256\": \"8ec462d12347548f506eeebf1e3c7cc47648019c8a783804d09bcc79b0f22af6\"\n },\n \"pvc\": {\n \"apiVersion\": \"v1\",\n \"kind\": \"PersistentVolumeClaim\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/PersistentVolumeClaim:informed-decision/informed-decision-data\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"pv.kubernetes.io/bind-completed\": \"yes\",\n \"pv.kubernetes.io/bound-by-controller\": \"yes\",\n \"volume.beta.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\",\n \"volume.kubernetes.io/selected-node\": \"239.62.205.92.host.secureserver.net\",\n \"volume.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\"\n },\n \"finalizers\": [\n \"kubernetes.io/pvc-protection\"\n ],\n \"name\": \"informed-decision-data\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n },\n \"spec\": {\n \"accessModes\": [\n \"ReadWriteOnce\"\n ],\n \"resources\": {\n \"requests\": {\n \"storage\": \"1Gi\"\n }\n },\n \"storageClassName\": \"local-path\",\n \"volumeMode\": \"Filesystem\",\n \"volumeName\": \"pvc-d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n }\n },\n \"pvc_phase\": \"Bound\"\n}\n" + }, + { + "item_id": "native-backup-restore-protocol-md", + "media_type": "text/markdown", + "content": "# Version2 protected existing-snapshot rescue and conditional continuation\n\nSame proposal INFD-WP-0009-T04/purpose-overlay-v1, trial infd-purpose-20261011-r1. Original version1 founder acceptance approved source bc6494cd1b290783ef3aef0763bf28d1deabf4b0. Drill-backup completed; drill-copy failed ValueError before any localfile. No image rollout occurred. This exact changed source/plan/helper requires NEW founder acceptance of memo version2 before rescue/continuation; prior approval and technical review do not approve it.\n\n## Failure and narrowly selected rescue\n\nOriginal snapshot main19537920bytes SHA8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3 is unchanged. Root's metadata-only verification shows WAL0bytes, SHM32768bytes, privateUID10001/mode0600/nlink1, and no local snapshot. The old SQLite connection context manager did not explicitly close; its WAL reader can create SHM indexing, and the next copy rejected that nonzero index. Platform independently reproduced this on synthetic data. No native DB was opened to diagnose the sidecar metadata, and no native sidecar is deleted/checkpointed.\n\nReuse this exact independently hash-bound frozen main snapshot rather than make another drill backup. The backupadmin exited after creating the uniquely owned private snapshot. Original subsequent snapshot access was readonly; actual service DB is the distinct /data/private/review.sqlite. Original journal has only COMPLETE drill-backup d63182a7-e1a5-4e8e-a5f1-2bf3333cf153 and UNCERTAIN drill-copy329ef190-1692-4246-b953-e6a59664abcc. Its exact SHA d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1, original source/memo/plan identity and outcomes are verified before/after every new phase. No other original action or rollout is allowed.\n\nThe explicitly named drill-copy-rescue-r1 creates a separate rescue-execution-journal-r1.json/lock in existing protected ignored custody; it hash-links original attempts and backupresult and never rewrites/synthesizes the old failed phase. Any attempted rescue result, crash or ambiguous output is durable and same-phase retry is refused. Before rescue: local drill.sqlite/cutover.sqlite and existing restore volume must be absent; native originalPodUID/currentoldimage7f5/Argo7db/sealedDeployment/CM/PVC match. The fixed immutable snapshot reader checks recorded digest/private identity/no WALframes before and after schema5/integrity/count validation, retaining unchanged SHM. Nonzero WAL or any identity/hash drift stops rescue. Snapshot binarystdout flows only to a new0600private file, with bounded size/hash and repeat source proof. It never reaches chat/log/Git/StateHub.\n\n## Live-WAL and data compatibility boundaries\n\nLive source and writable offline pre/post-admin reads MUST stay mode=ro/query_only and explicitly close SQLite connections. immutable=1 ignores WAL and would lose committed live rows; it is restricted to the proven frozen closed-main snapshot, never the liveDB or writableclone. Before ANY native source or restoredcopy Store/admin open, require stdlib readonly schema5/integrity/counts; refuse oldschemas before automatic migration. Frozen snapshot/clone count equality is exact; currentlive counter changes may reflect concurrent legitimate commits and are retained.\n\nOnly after COMPLETE named rescue does offline-verify consume its result via explicit mapping, not the old UNCERTAIN drill-copy. Existing isolated disposablevolume infd-purpose-r1-restore-20261011 must be absent/new nonce-bound. One exact763c UID0/CAP_CHOWN-only initializer receives snapshotstdin into that NEWvolume, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/nativePVC/runtimeconfig/token mounts. It sets folder0700/file0600UID10001, followed by UID10001 pre-open readonly, --entrypoint informed-decision-admin inspect --db /restore/review.sqlite and post-admin readonly fullproof; original protected SHA must remain unchanged. No serviceentrypoint starts. Cleanup only this disposable volume, retaining original native/offcluster snapshots/sidecars.\n\n## Conditional remaining phases and release/recovery\n\nNewjournal fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. cutover-backup uses distinct newcutover.sqlite in originalprivatecase directory, after readonly live schema5/capacity gates, SQLitebackupAPI/admin completion, closed-main immutable proof; do not overwrite originals or retryfailedpaths. Version2 acceptance conditionally approves these exact unchanged remaining operations only after rescue+drillgates. All four committed Kustomize Git blobs/currentHEAD, exact helper/case hashes, CM/PVC/Deployment seals and manualApplication(no automated{} or sourceoverride) must match.\n\nRelease retains existing replica1/Recreate/config6c/schema5/PVC/credentials/policies: sourcepin Application.operation serverdryrun/UID+resourceVersion+source CAS, Deployment-only image763c, prune=false. No whole-app sync/adoption. Verify requires succeeded exactscope/controllergeneration/Ready1, installedpolicyhash/modeUID/10syntheticpurposevariants+boundedhealth, same currentliveDB schema5/integrity/counts. Those installedchecks report native_provider=false; actualprovider/PDPauthority evidence remains a separate T04gate.\n\nRollback after recorded newrelease attempt pins prior7db/7f5 and retains latestschema5DB, without requiring Ready failingcandidate or candidateDBexec. Separate rollback-verify proves oldimageReady1/scopedoperation/readonlyschema5 currentDB integrity. Never restore an older snapshot over postcutoverrecords. Any data recovery beyond this same-schema image rollback needs another decision.\n\nAll phases including rescue, verification and recovery must begin before2026-10-12T23:59:59Z. Start early enough; if expired stop and obtain a fresh founder decision, which may delay recovery. No automatic timer/controller/extension. Root freshly authenticates exact confirmed platform-root person ACCEPT memo version2 at fixednativeorigin before every phase; protectedreceiptrelation/freshness120sec is supervisedbookkeeping, not a signed/autonomous grant.\n\nImage763c/policy9d7c/base7f5 and actualunfilteredscan0HIGH/CRITICAL/1fixableMEDIUMzlib remain unchanged, owner INFD-RISK-20261011-ZLIB-85091/T05 dueOct18. The exactbundle directly binds helper/plan/tests plus original count-onlybackup/failure/anchor. Existingpublishedreceipt still binds unchanged rawscan/SBOM/base scan; no suppression. Preserve originalapproved20docpacket/helpers/history in initial-approved-bc6494cd. No version2 native operation has run. EUR0 recurringinfrastructure; private boundedstorage/attendedtime unpriced, no newdrillbackup or autonomygrant.\n\nNative source publication uses exact revision-command.json via /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions, expected_version1, only after fresh unbound-source readback. No version2 intake/register. Publish/review sourceversion2; new human review-ID is ownversion1, so its confirmed nested disposition memo_version1 is correct. Root actual outcomes query must name SOURCE version2 and exact newreviewID; original review/approval cannot be reused.\n" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "media_type": "application/json", + "content": "{\n \"id\": \"INFD-RISK-20261011-ZLIB-85091\",\n \"kind\": \"owner-vulnerability-follow-through\",\n \"owner\": \"informed-decision\",\n \"task\": \"INFD-WP-0009-T05\",\n \"status\": \"open\",\n \"created\": \"2026-10-11\",\n \"review_due\": \"2026-10-18\",\n \"finding\": \"CVE-2026-85091\",\n \"scanner_severity\": \"MEDIUM\",\n \"estate_risk_grade\": null,\n \"affected_package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"actual_current_base_and_candidate_findings_identical\": true,\n \"source_evidence\": \"security-summary.json, trivy-full.json, base-trivy-full.json\",\n \"human_temporary_disposition\": \"pending\",\n \"follow_through\": \"Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload\",\n \"manual_review_expiry\": \"Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed\",\n \"close_condition\": \"Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition\"\n}\n" + }, + { + "item_id": "native-preflight-json", + "media_type": "application/json", + "content": "{\n \"captured_at\": \"2026-10-11T01:25:38.793555+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true\n}\n" + }, + { + "item_id": "sealed-live-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"revisionHistoryLimit\": 10,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"imagePullPolicy\": \"IfNotPresent\",\n \"livenessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\",\n \"protocol\": \"TCP\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\",\n \"protocol\": \"TCP\"\n }\n ],\n \"readinessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"terminationMessagePath\": \"/dev/termination-log\",\n \"terminationMessagePolicy\": \"File\",\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"dnsPolicy\": \"ClusterFirst\",\n \"restartPolicy\": \"Always\",\n \"schedulerName\": \"default-scheduler\",\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccount\": \"review\",\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "change-guard-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only exact Deployment and admission boundaries; no mutation authority.\"\"\"\nimport copy\nimport hashlib\nimport json\n\nBASE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'\nCANDIDATE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\n\n\ndef dependency_projection(configmap, pvc):\n if (configmap.get('kind') != 'ConfigMap' or configmap.get('immutable') is not True\n or configmap['metadata']['namespace'] != 'informed-decision'\n or configmap['metadata']['name'] != 'informed-decision-runtime-6c221878d051'\n or set(configmap.get('data', {})) != {'runtime.json'}\n or configmap.get('binaryData')):\n raise ValueError('unexpected immutable runtime config identity')\n if (pvc.get('kind') != 'PersistentVolumeClaim'\n or pvc['metadata']['namespace'] != 'informed-decision'\n or pvc['metadata']['name'] != 'informed-decision-data'\n or pvc.get('status', {}).get('phase') != 'Bound'\n or not pvc.get('spec', {}).get('volumeName')):\n raise ValueError('unexpected bound PVC custody')\n config = projection(configmap)\n config.pop('data')\n config['canonical_data_sha256'] = hashlib.sha256(json.dumps(\n configmap['data'], sort_keys=True, separators=(',', ':')).encode()).hexdigest()\n return {'configmap': config, 'pvc': projection(pvc), 'pvc_phase': 'Bound'}\n\n\ndef check_dependencies(configmap, pvc, sealed):\n if dependency_projection(configmap, pvc) != sealed:\n raise ValueError('runtime config or PVC identity/custody changed')\n\n\ndef projection(value):\n value = copy.deepcopy(value)\n value.pop('status', None)\n for key in ('resourceVersion', 'generation', 'creationTimestamp', 'managedFields'):\n value['metadata'].pop(key, None)\n for key in ('kubectl.kubernetes.io/last-applied-configuration', 'deployment.kubernetes.io/revision'):\n value['metadata'].get('annotations', {}).pop(key, None)\n return value\n\n\ndef check_current(current, sealed):\n if projection(current) != sealed:\n raise ValueError('sealed live UID or configuration changed')\n\n\ndef check_admitted(admitted, sealed):\n expected = copy.deepcopy(sealed)\n containers = expected['spec']['template']['spec']['containers']\n if len(containers) != 1 or containers[0]['name'] != 'informed-decision' or containers[0]['image'] != BASE:\n raise ValueError('unexpected baseline container identity')\n containers[0]['image'] = CANDIDATE\n if projection(admitted) != expected:\n raise ValueError('admission changed configuration beyond the sole image pin')\n\n\ndef transport_result(exit_code, output):\n import json\n try:\n value = json.loads(output)\n except (ValueError, TypeError):\n return {'all_checks_pass': False, 'reason': 'invalid transport result'}\n if exit_code != 0 or not isinstance(value, dict) or value.get('all_checks_pass') is not True:\n return {'all_checks_pass': False, 'reason': 'read-only preflight refused'}\n return value\n" + }, + { + "item_id": "preflight-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only refresh; exact original capture remains immutable; never execute cutover.\"\"\"\nimport argparse,hashlib,json,subprocess,sys\nfrom pathlib import Path\nif sys.flags.optimize:\n raise SystemExit(\"optimized interpreter refused before source/transport execution\")\nROOT=Path(__file__).resolve().parent\np=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args()\nout=a.receipt_output.resolve()\nif not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists():\n raise SystemExit('unique execution receipt must be outside the sealed packet')\ninputs=json.loads((ROOT/'preflight-inputs.json').read_text())\nfor relative,digest in inputs['packet_files'].items():\n path=ROOT/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed')\nfor relative,digest in inputs['owner_source_files'].items():\n path=a.source_root/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed')\nfrom change_guard import transport_result\nprogram='import subprocess,json,hashlib,datetime,sys,copy,re\\nif sys.flags.optimize:raise RuntimeError(\"optimized interpreter refused\")\\ncandidate=json.loads(CANDIDATE_LITERAL)\\nsealed_dependencies=json.loads(DEPENDENCIES_LITERAL)\\nsealed_baseline=json.loads(SEALED_LITERAL)\\nexec(GUARD_LITERAL)\\ndef run(args,data=None):\\n p=subprocess.run(args,input=data,text=True,capture_output=True)\\n if p.returncode: raise ValueError(\\'read-only command failed: \\'+args[1]+\\' \\'+args[2])\\n return p.stdout\\nlive=json.loads(run([\\'kubectl\\',\\'get\\',\\'deployment\\',\\'informed-decision\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncm=json.loads(run([\\'kubectl\\',\\'get\\',\\'configmap\\',\\'informed-decision-runtime-6c221878d051\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\npvc=json.loads(run([\\'kubectl\\',\\'get\\',\\'pvc\\',\\'informed-decision-data\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncheck_dependencies(cm,pvc,sealed_dependencies)\\ncheck_current(live,sealed_baseline)\\nspec=live[\\'spec\\']; cs=spec[\\'template\\'][\\'spec\\'][\\'containers\\'];assert len(cs)==1 and cs[0][\\'name\\']==\\'informed-decision\\'\\nexpected_env={\\'INFD_KEYCAPE_ISSUER\\':\\'https://kc.coulomb.social\\',\\'INFD_CONTAINER_CONFIG\\':\\'/configuration/runtime.json\\'}\\nassert cs[0].get(\\'env\\')==[{\\'name\\':\\'INFD_KEYCAPE_ISSUER\\',\\'value\\':expected_env[\\'INFD_KEYCAPE_ISSUER\\']},{\\'name\\':\\'INFD_CONTAINER_CONFIG\\',\\'value\\':expected_env[\\'INFD_CONTAINER_CONFIG\\']}]\\nassert cs[0][\\'image\\']==\\'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\'\\nassert spec[\\'replicas\\']==1 and spec[\\'strategy\\']=={\\'type\\':\\'Recreate\\'}\\nassert next(v for v in spec[\\'template\\'][\\'spec\\'][\\'volumes\\'] if v[\\'name\\']==\\'configuration\\')[\\'configMap\\'][\\'name\\']==\\'informed-decision-runtime-6c221878d051\\'\\nassert live[\\'status\\'].get(\\'readyReplicas\\')==1 and live[\\'status\\'].get(\\'updatedReplicas\\')==1\\nsealed={\\'apiVersion\\':live[\\'apiVersion\\'],\\'kind\\':live[\\'kind\\'],\\'metadata\\':{k:copy.deepcopy(v) for k,v in live[\\'metadata\\'].items() if k not in (\\'resourceVersion\\',\\'generation\\',\\'creationTimestamp\\',\\'managedFields\\')},\\'spec\\':copy.deepcopy(spec)}\\nfor key in (\\'kubectl.kubernetes.io/last-applied-configuration\\',\\'deployment.kubernetes.io/revision\\'):sealed[\\'metadata\\'].get(\\'annotations\\',{}).pop(key,None)\\nadmitted=json.loads(run([\\'kubectl\\',\\'apply\\',\\'--dry-run=server\\',\\'-f\\',\\'-\\',\\'-o\\',\\'json\\'],json.dumps(candidate)))\\ncheck_admitted(admitted,sealed_baseline)\\napp=json.loads(run([\\'kubectl\\',\\'get\\',\\'application\\',\\'informed-decision\\',\\'-n\\',\\'argocd\\',\\'-o\\',\\'json\\']))\\nassert app[\\'spec\\'][\\'source\\'][\\'path\\']==\\'deploy/lifecycle\\' and not app[\\'spec\\'].get(\\'syncPolicy\\',{}).get(\\'automated\\')\\nargo={\\'uid\\':app[\\'metadata\\'][\\'uid\\'],\\'repoURL\\':app[\\'spec\\'][\\'source\\'][\\'repoURL\\'],\\'targetRevision\\':app[\\'spec\\'][\\'source\\'][\\'targetRevision\\'],\\'path\\':app[\\'spec\\'][\\'source\\'][\\'path\\'],\\'destination\\':app[\\'spec\\'][\\'destination\\'],\\'automated\\':False,\\'sync\\':app.get(\\'status\\',{}).get(\\'sync\\'),\\'health\\':app.get(\\'status\\',{}).get(\\'health\\')}\\nexpected_argo=json.loads(ARGO_LITERAL)\\nfor key in (\\'uid\\',\\'repoURL\\',\\'targetRevision\\',\\'path\\',\\'destination\\',\\'automated\\'):\\n assert argo[key]==expected_argo[key]\\nassert argo[\\'health\\'][\\'status\\']==\\'Healthy\\'\\ndiff=subprocess.run([\\'kubectl\\',\\'diff\\',\\'-f\\',\\'-\\'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\\nnode=run([\\'kubectl\\',\\'describe\\',\\'node\\']);allocated=re.search(r\\'Allocated resources:.*?CPU Requests|Allocated resources:\\',node,re.S)\\nsection=node.split(\\'Allocated resources:\\')[1].split(\\'Events:\\')[0] if \\'Allocated resources:\\' in node else \\'\\'\\nnodes=json.loads(run([\\'kubectl\\',\\'get\\',\\'nodes\\',\\'-o\\',\\'json\\']))[\\'items\\'];assert len(nodes)==1\\nalloc=nodes[0][\\'status\\'][\\'allocatable\\'];cpu=alloc[\\'cpu\\'];cpu_m=int(cpu[:-1]) if cpu.endswith(\\'m\\') else int(cpu)*1000\\nrequested=int(re.search(r\\'cpu\\\\s+(\\\\d+)m\\',section).group(1));assert requested<=cpu_m\\nreceipt={\\'node_allocatable_cpu_m\\':cpu_m,\\'node_requested_cpu_m\\':requested,\\'captured_at\\':datetime.datetime.now(datetime.timezone.utc).isoformat(),\\'native_workload_changed\\':False,\\'native_backup_restore_executed\\':False,\\'argo\\':argo,\\'native_dependencies_checked\\':True,\\'configmap_uid\\':cm[\\'metadata\\'][\\'uid\\'],\\'pvc_uid\\':pvc[\\'metadata\\'][\\'uid\\'],\\'live_ready_replicas\\':1,\\'admitted_uid\\':admitted[\\'metadata\\'][\\'uid\\'],\\'server_dry_run_passed\\':True,\\'admitted_spec_exactly_live_plus_image\\':True,\\'client_diff_exit\\':diff.returncode,\\'client_diff_sha256\\':hashlib.sha256(diff.stdout.encode()).hexdigest(),\\'node_allocated_resources\\':section.strip(),\\'all_checks_pass\\':True}\\nprint(json.dumps(receipt))\\n'\nfor marker,value in [('DEPENDENCIES_LITERAL',(ROOT/'sealed-native-dependencies.json').read_text()),('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]:\n program=program.replace(marker,repr(value))\nprogram='import traceback,json\\ntry:\\n'+''.join(' '+line+'\\n' for line in program.splitlines())+\"except Exception as error:\\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\\n\"\nr=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True)\nresult=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True\nout.write_text(json.dumps(result,indent=2)+'\\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1)\n" + }, + { + "item_id": "preflight-inputs-json", + "media_type": "application/json", + "content": "{\n \"packet_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"preflight.py\": \"6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"native-preflight.json\": \"eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"sqlite_readonly.py\": \"9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\"\n }\n}\n" + }, + { + "item_id": "fresh-preflight-validation-json", + "media_type": "application/json", + "content": "{\n \"node_allocatable_cpu_m\": 4000,\n \"node_requested_cpu_m\": 3460,\n \"captured_at\": \"2026-10-11T01:39:14.234277+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"native_dependencies_checked\": true,\n \"configmap_uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\",\n \"pvc_uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\",\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"840769c7d2a9c1655c40a3259f833d1fc8f69950ceb3bedb707a955fed711566\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true,\n \"sealed_preflight_inputs_sha256\": \"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\",\n \"fresh_execution_receipt\": true\n}\n" + } + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/revision-command.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/revision-command.json new file mode 100644 index 0000000..f0a9665 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/revision-command.json @@ -0,0 +1,247 @@ +{ + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "expected_version": 1, + "summary": "Same supervised trial: retain original approvedbackup and UNCERTAINcopy; correct explicitSQLiteclose/frozenimmutable reads and introduce exact named existing-snapshot rescue with separate hash-linked journal, fresh human review, unchanged image/scope.", + "documents": [ + { + "digest": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024", + "media_type": "text/markdown", + "content_base64": "IyBJbmZvcm1lZCBEZWNpc2lvbiB2ZXJzaW9uMiBleGlzdGluZy1zbmFwc2hvdCByZXNjdWUgYW5kIGltYWdlIHJlbGVhc2UKCkFwcHJvdmUgdGhlIGV4YWN0IHNvdXJjZS1yZWZpbmVkIHJlY292ZXJ5IG9mIHRoZSBmYWlsZWQgZHJpbGwtY29weSBhbmQgY29uZGl0aW9uYWwgcmVtYWluaW5nIGJhY2t1cC9kcmlsbC9EZXBsb3ltZW50LW9ubHkgaW1hZ2Ugcm9sbG91dC4gVGhpcyBpcyBtZW1vIHZlcnNpb24yIGluIHRoZSBzYW1lIHByb3Bvc2FsL3RyaWFsLCByZXF1aXJpbmcgTkVXIGZvdW5kZXIgYWNjZXB0YW5jZTsgb3JpZ2luYWwgdmVyc2lvbjEgYWNjZXB0YW5jZSBpcyByZXRhaW5lZCBhbmQgY2Fubm90IGF1dGhvcml6ZSBjaGFuZ2VkIGhlbHBlcmJ5dGVzLgoKT3JpZ2luYWwgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCB0aGUgcHJvdGVjdGVkIG5hdGl2ZSBkcmlsbC1iYWNrdXAsIHRoZW4gY29weSBmYWlsZWQgYmVmb3JlIGFueSBsb2NhbGZpbGUuIE1ldGFkYXRhLW9ubHkgdmVyaWZpY2F0aW9uIHByb3ZlcyB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMC9wcml2YXRlU0hNMzI3NjguIFRoZSBvcmlnaW5hbCByZWFkZXIgY291bGQgbGVhdmUgU0hNIGluZGV4aW5nIGJlY2F1c2UgaXRzIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgY2xvc2UuIFRoZSBjb3JyZWN0aW9uIGV4cGxpY2l0bHljbG9zZXMgYWxsIHJlYWRlcnMgYW5kIHVzZXMgaW1tdXRhYmxlIHJlYWRzIE9OTFkgZm9yIGEgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbm90IGxpdmUgb3Igd3JpdGFibGVjbG9uZS4gU0hNIHN0YXlzIHVuY2hhbmdlZDsgbm9uemVyb1dBTC9oYXNoL2lkZW50aXR5IGRyaWZ0IHN0b3BzIHJlc2N1ZS4KCkRpc3RpbmN0IGRyaWxsLWNvcHktcmVzY3VlLXIxL25ld2xpbmtlZGpvdXJuYWwgcHJlc2VydmVzIG9yaWdpbmFsIFVOQ0VSVEFJTmNvcHkgYW5kIGV4YWN0IGpvdXJuYWxoYXNoL2F0dGVtcHRzLiBObyBvbGRyZXRyeS9vdmVyd3JpdGUsIG5vIG5ld2RyaWxsYmFja3VwLiBSZXF1aXJlIG9yaWdpbmFsQ09NUExFVEViYWNrdXAvVU5DRVJUQUlOY29weSBvbmx5LCBhYnNlbnRsb2NhbGZpbGVzL3Jlc3RvcmV2b2x1bWUsIG9yaWdpbmFsbmF0aXZlUG9kVUlEL2N1cnJlbnRvbGRpbWFnZStzb3VyY2VwaW4gYW5kIGFsbENNL1BWQy9EZXBsb3ltZW50IHNlYWxzLiBDb3B5IHNuYXBzaG90Ynl0ZXMgb25seSBpbnRvIGEgbmV3cHJpdmF0ZTA2MDBmaWxlLiBSZW1haW5pbmdvcmRlcmVkcGhhc2VzIGV4cGxpY2l0bHkgY29uc3VtZSBDT01QTEVURXJlc2N1ZXJlc3VsdDsgb25lIGlzb2xhdGVkIFVJRDAvQ0FQX0NIT1dOLW9ubHkgTkVXdm9sdW1lIGluaXRpYWxpemVyIHRoZW4gVUlEMTAwMDEgcHJlLW9wZW4vYWRtaW4vcG9zdC1hZG1pbiBjaGVja3MgcHJvdmVzIHJlYWwtZGF0YSBjb21wYXRpYmlsaXR5IGJlZm9yZSBjdXRvdmVyLiBObyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50czsgbm8gc2VydmljZSBzdGFydHVwLiBBbnkgYXR0ZW1wdGVkIGZhaWx1cmUvYW1iaWd1aXR5IGlzIGR1cmFibGUgYW5kIGNhbm5vdHJldHJ5LgoKSW1hZ2U3NjNjIGZyb20gYWN0dWFsQ0kzZTRiY2IyNiByZW1haW5zIHVuY2hhbmdlZDhiYXNlIGxheWVycyBwbHVzcG9saWN5LnB5OyBsZWdhY3lzZXJpYWxpemF0aW9uIGRpZmZlcmVuY2VzIGRpc2Nsb3NlZC4gQWN0dWFsaW5zdGFsbGVkVUlEMTAwMDEvMTBwdXJwb3NldmFyaWFudHMgcGFzczsgbmF0aXZlX3Byb3ZpZGVyPWZhbHNlL3N5bnRoZXRpY3RyYW5zcG9ydCBpcyBub3QgYWN0dWFsUERQYXV0aG9yaXR5IHByb29mLCB3aGljaCByZW1haW5zIHNlcGFyYXRlVDA0Z2F0ZS4gQWN0dWFsZnVsbDQ0cGFja2FnZXNjYW4wSElHSC9DUklUSUNBTCwgT05FZml4YWJsZWluaGVyaXRlZE1FRElVTXpsaWJDVkUtMjAyNi04NTA5MSgxLjMuMi1yMOKGknIxKSwgaWRlbnRpY2FsYmFzZWZpbmRpbmcuIEV4cGxpY2l0dGVtcG9yYXJ5cGVybWlzc2lvbiBmb3IgdGhpcyBmaW5kaW5nIGlzIHJlcXVlc3RlZCBhZ2Fpbiwgd2l0aCBvd25lclQwNS9yaXNrcmVjb3JkZHVlT2N0MTg7IG5vIHplcm8tQ1ZFL1Jpc2tOZXh1c2dyYWRlY2xhaW0uIFJhd3NjYW4vU0JPTS9iYXNlIHNjYW4gc3RheSB1bmNoYW5nZWRoYXNoYm91bmQgdmlhIHB1Ymxpc2hlZHJlY2VpcHQ7IGV4YWN0aGVscGVyYW5kb3JpZ2luYWxjb3VudC1vbmx5cmVjZWlwdHMgZGlyZWN0bHlidW5kbGUtYm91bmQgd2l0aGluMjBkb2NzLgoKQWZ0ZXIgcmVzY3VlK29mZmxpbmVnYXRlcywgZGlzdGluY3RjdXRvdmVyYmFja3VwL2NvcHkgYW5kIG1hbnVhbEFyZ29EZXBsb3ltZW50LW9ubHkgaW1hZ2U3NjNjL3BydW5lPWZhbHNlIHJlbWFpbiBjb25kaXRpb25hbC4gRm91cmNvbW1pdHRlZEt1c3RvbWl6ZWJsb2JzL2N1cnJlbnRmaW5hbHNvdXJjZUhFQUQvaGVscGVycy9jYXNlaGFzaGVzIG1hdGNoOyBhdXRvbWF0ZWR7fSBvciBvdmVycmlkZXMgcmVmdXNlLiBDb25maWc2Yy9zY2hlbWE1L1BWQy9pZGVudGl0eS9wb2xpY2llcy9yZXBsaWNhMVJlY3JlYXRlIHN0YXlmaXhlZC4gUm9sbGJhY2tkb2Vzbm90bmVlZCBSZWFkeWNhbmRpZGF0ZSBvciBpdHNEQmV4ZWM7IG9sZGltYWdlUmVhZHkvc2NvcGVkb3BlcmF0aW9uL3NjaGVtYTVjdXJyZW50REIgaXMgYSBzZXBhcmF0ZXByb29mLiBQcmVzZXJ2ZSBsYXRlc3RsaXZlREIvYWxsbmV3Y29tbWl0cyBhbmQgYWxsdW5jZXJ0YWlub3V0Y29tZXM7IG5ldmVycmVzdG9yZW9sZGVyYmFja3VwIG92ZXJsYXRlcnJlY29yZHMuCgpBbGxwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZS9yZWNvdmVyeS92ZXJpZnkgbXVzdGJlZ2luIGJlZm9yZU9jdDEyIDIzOjU5OjU5WjsgZXhwaXJ5cmVxdWlyZXNuZXdkZWNpc2lvbiBhbmQgbWF5ZGVsYXlyZWNvdmVyeS4gTm8gYXV0b21hdGljZXhwaXJ5Y29udHJvbGxlci4gRnJlc2hyb290LWF1dGhlbnRpY2F0ZWQgbmF0aXZlZm91bmRlcmFjY2VwdGFuY2UgdmVyc2lvbjIgYmVmb3JlZWFjaHBoYXNlOyByZWNlaXB0cyBhcmUgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3RzaWduZWRncmFudC9hdXRvbm9teS4gRVVSMCByZWN1cnJpbmdpbmZyYSwgZXhpc3Rpbmdwcml2YXRlY29weS9zdG9yYWdlL2F0dGVuZGVkdGltZSB1bnByaWNlZDsgbm8gc2Vjb25kbmF0aXZlIGRyaWxsYmFja3VwLiBFeGFjdG9yaWdpbmFsYXBwcm92ZWRwYWNrZXQvZmFpbHVyZS90ZWNobmljYWxyZWZpbmVtZW50cyBwcmVzZXJ2ZWQgc2FtZXByb3Bvc2FsL3RyaWFsLiBObyB2ZXJzaW9uMm5hdGl2ZW9wZXJhdGlvbiB5ZXQuCg==" + }, + { + "digest": "sha256:34a5a805941d4b498fe407b7c7ac061e3fd627d076b328ce7012a30f5b85c62e", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbF9pZCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgInRyaWFsX2lkIjogImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMSIsCiAgInN0YXRlIjogInByZXBhcmVkLXVuYXBwcm92ZWQiLAogICJ0YXJnZXQiOiAicmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbiIsCiAgImF1dGhvcml0eSI6ICJBRE1JTklTVEVSOyBhY3RpdmF0aW9uIEFQUFJPVkVEIG9ubHkgdXBvbiBleGFjdCBmb3VuZGVyIGRpc3Bvc2l0aW9uIiwKICAiY2FuZGlkYXRlX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYSIsCiAgInB1Ymxpc2hlZF9zb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInByaW9yX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgInByaW9yX2FyZ29fcmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgIm5hdGl2ZV9vYmplY3QiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJhcHBzL3YxIiwKICAgICJraW5kIjogIkRlcGxveW1lbnQiLAogICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAidWlkIjogImE1ODhlMTBhLTkwZDItNDg4My05NzVlLTZkZDhiOGZlY2E5MiIKICB9LAogICJhcmdvX2FwcGxpY2F0aW9uX3VpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICJzb3VyY2VfZ2F0ZSI6ICJBbGwgZm91ciBleGFjdCBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGluIGV4ZWN1dGlvbi1wbGFuLmpzb24gYW5kIGNsZWFuIGN1cnJlbnQgb3duZXIgSEVBRCBtdXN0IG1hdGNoOyBzb3VyY2UgcHJlcGFyYXRpb24gaXMgbm90IG5hdGl2ZSBhcHByb3ZhbCIsCiAgInN5bmNfc2NvcGUiOiBbCiAgICAiYXBwczpEZXBsb3ltZW50OmluZm9ybWVkLWRlY2lzaW9uIgogIF0sCiAgInBydW5lIjogZmFsc2UsCiAgImF1dG9tYXRlZF9zeW5jIjogZmFsc2UsCiAgInJ1bnRpbWVfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAic2NoZW1hIjogNSwKICAicmVxdWVzdGVkX29wZXJhdGlvbnMiOiBbCiAgICAiUmVhZC1vbmx5IGltbXV0YWJsZSB2YWxpZGF0aW9uIG9mIGV4aXN0aW5nIGZyb3plbjE5NTM3OTIwYnl0ZSBuYXRpdmUgZHJpbGwgc25hcHNob3QsIFNIQTg3NTYuLi4sIHByaXZhdGVjdXN0b2R5L25vLXdyaXRlci96ZXJvV0FML3N0YWxlU0hNIHJldGFpbmVkIiwKICAgICJEaXN0aW5jdCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBiaW5hcnljb3B5IGludG8gYWJzZW50MDYwMHByb3RlY3RlZCBsb2NhbCBkZXN0aW5hdGlvbiwgbmV3IGhhc2gtbGlua2VkIHJlc2N1ZSBqb3VybmFsIHByZXNlcnZpbmcgb2xkIFVOQ0VSVEFJTiBjb3B5IiwKICAgICJFeGlzdGluZyBpc29sYXRlZCBvZmZsaW5lIHByZS1vcGVuL2FkbWluL3Bvc3Qtb3BlbiBjb21wYXRpYmlsaXR5IGRyaWxsIGFuZCBkaXNwb3NhYmxlLXZvbHVtZSBjbGVhbnVwIHVzaW5nIHJlc2N1ZWQgcmVzdWx0IiwKICAgICJEaXN0aW5jdCBjb25zaXN0ZW50IGN1dG92ZXIgc25hcHNob3QgcGx1cyBwcm90ZWN0ZWRjb3B5LCBmb2xsb3dlZCBvbmx5IGFmdGVyIGFsbGdhdGVzIGJ5IERlcGxveW1lbnQtb25seSBpbWFnZSByZWxlYXNlL3ZlcmlmeTsgc2FtZS1zY2hlbWEgcm9sbGJhY2svcmVjb3ZlcnkgcHJvb2YgaWYgbmVlZGVkIgogIF0sCiAgImV4ZWN1dGVfYnkiOiAiMjAyNi0xMC0xMlQyMzo1OTo1OVoiLAogICJ0ZW1wb3JhcnlfdnVsbmVyYWJpbGl0eV9yZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJrbm93bl9zY2FuX2ZpbmRpbmdzIjogIjBISUdIL0NSSVRJQ0FMLDFmaXhhYmxlIGluaGVyaXRlZE1FRElVTSB6bGliLCBhY3R1YWwgY3VycmVudGJhc2UrY2FuZGlkYXRlIGZpbmRpbmdzIGlkZW50aWNhbCIsCiAgInZ1bG5lcmFiaWxpdHlfcmVjb3JkIjogIklORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxIC8gSU5GRC1XUC0wMDA5LVQwNSIsCiAgImNvc3RfZXN0aW1hdGVfRVVSIjogMCwKICAiY29zdF9saW1pdHMiOiAiTm8gYWRkaXRpb25hbCByZWN1cnJpbmcgaW5mcmFzdHJ1Y3R1cmUgb3Igc2Vjb25kIGRyaWxsIGJhY2t1cC4gRXhpc3RpbmcgbmF0aXZlIHNuYXBzaG90MTk1Mzc5MjBieXRlcyByZXRhaW5lZDsgcHJvdGVjdGVkIGxvY2FsY29weS9vZmZsaW5lY2xvbmUgcGx1cyBkaXN0aW5jdCBjdXRvdmVyIHNuYXBzaG90cyBjb25zdW1lIGJvdW5kZWRleGlzdGluZ3N0b3JhZ2UuIEF0dGVuZGVkZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZDsgbm8gYXV0b3BpbG90IGdyYW50LiIsCiAgInJpc2tfZXN0aW1hdGVzIjogWwogICAgIkJyaWVmIFJlY3JlYXRlIHNlcnZpY2UgaW50ZXJydXB0aW9uOyBubyBjb25jdXJyZW50IG5ldyB3cml0ZXIvc3VyZ2UiLAogICAgIlByaXZhdGUgZXZpZGVuY2Ugc25hcHNob3QgY3VzdG9keSBhbmQgZGlzcG9zYWwgZXJyb3JzOyBubyBzbmFwc2hvdHMvdG9rZW5zIGluIHB1YmxpYyBldmlkZW5jZSIsCiAgICAiQ2FuZGlkYXRlIHB1cnBvc2UgcmVmdXNhbCBtYXkgZXhwb3NlIGNhbGxlcnMgcmVseWluZyBvbiBhZHZpc29yeSByZXN1bHRzIGFzIGJpbmRpbmciLAogICAgIkluaGVyaXRlZCBrbm93biBmaXhhYmxlIE1FRElVTSByZW1haW5zIHVudGlsIHNlcGFyYXRlbHkgYXBwcm92ZWQgb3duZXIgcmVtZWRpYXRpb24iLAogICAgIkV4aXN0aW5nIEFyZ28gT3V0T2ZTeW5jIGJhc2VsaW5lIGlzIHJldGFpbmVkOyBubyB3aG9sZS1hcHAgc3luYyBvciB1bnJlbGF0ZWQgcmVwYWlycyBwZXJtaXR0ZWQiLAogICAgIkFsbCBwaGFzZXMsIGluY2x1ZGluZyByZWNvdmVyeS92ZXJpZmljYXRpb24sIG11c3QgYmVnaW4gYmVmb3JlIE9jdDEyIGRlYWRsaW5lOyBpZiByZWNvdmVyeSB3aW5kb3cgaXMgZXhoYXVzdGVkIHN0b3AgYW5kIG9idGFpbiBhIGZyZXNoIGZvdW5kZXIgZGVjaXNpb24uIE5vIGF1dG9tYXRpYyBleHBpcnkgY29udHJvbGxlci4iCiAgXSwKICAicm9sbGJhY2siOiAiTWFudWFsIEFyZ28gc291cmNlIHBpbiBiYWNrIHRvN2RiODQ4NSBhbmQgc2NvcGVkIERlcGxveW1lbnQtb25seSBzeW5jIHRvN2Y1YyBpbWFnZTsgcmV0YWluIGN1cnJlbnQgc2NoZW1hNSBkYXRhYmFzZSBhbmQgYWxsIHBvc3QtY3V0b3ZlciBldmlkZW5jZSwgbmV2ZXIgcmVzdG9yZSBvbGRlciBzbmFwc2hvdCBvdmVyIGxpdmUgd3JpdGVzIiwKICAibmF0aXZlX2V4ZWN1dGVkIjogIk9yaWdpbmFsIGRyaWxsLWJhY2t1cCBleGVjdXRlZDsgb3JpZ2luYWwgZHJpbGwtY29weSBmYWlsZWQuIE5vIHZlcnNpb24yIGFjdGlvbiBleGVjdXRlZC4iLAogICJodW1hbl9hcHByb3ZhbCI6ICJWZXJzaW9uMSBhY2NlcHRlZCBvcmlnaW5hbHNvdXJjZTsgdmVyc2lvbjIgcmVxdWlyZXMgZnJlc2ggZXhhY3QgYWNjZXB0YW5jZS4iLAogICJyZWZpbmVtZW50X29mX21hbmlmZXN0IjogIjdjNjczOGIzOWVhOGU1NGU2MWM4ZWQ2MjVlOTRhZDBiMjc1NWU2NzJlMTU3NmVmY2RmODRhMWQ2NjVhYzMzMDAiLAogICJtYW5kYXRvcnlfcHJlX29wZW5fZ2F0ZSI6ICJzdGRsaWJTUUxpdGUgbW9kZT1yby9xdWVyeV9vbmx5OiBzY2hlbWE1K2ludGVncml0eStjb3VudCBiYXNlbGluZSBiZWZvcmUgQU5ZIFN0b3JlL2FkbWluIG9uIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5OyByZWZ1c2VvbGRzY2hlbWFzIHdpdGhvdXQgbWlncmF0aW9uIiwKICAib3B0aW1pemVkX2ludGVycHJldGVycyI6ICJsb2NhbCtyZW1vdGUgZXhwbGljaXRseXJlZnVzZWQgYmVmb3JlYXNzZXJ0IGdhdGVzIiwKICAibmF0aXZlX2RlcGVuZGVuY3lfZ2F0ZSI6ICJzZWFsZWQgYWN0dWFsQ00gVUlEL2ltbXV0YWJsZS9jYW5vbmljYWxkYXRhaGFzaCtQVkMgVUlEL2Z1bGxzcGVjL0JvdW5kL3ZvbHVtZU5hbWUsIG5vIHJhd0NNZGF0YSBvclNlY3JldCByZWFkcyIsCiAgImxpdmVfY291bnRzIjogIkZyb3plbiBzbmFwc2hvdC9jbG9uZSBleGFjdGNvdW50ZXIgZXF1YWxpdHk7IHBvc3RjdXRvdmVyL3JvbGxiYWNrIGxpdmVjb3VudGVyY2hhbmdlcyBtYXkgcmVmbGVjdCBsZWdpdGltYXRlIGNvbmN1cnJlbnRjb21taXRzL3N0YXRlIHRyYW5zaXRpb25zLCBsYXRlc3REQiBhbHdheXNyZXRhaW5lZCIsCiAgInNvdXJjZV9iYXNpcyI6IHsKICAgICJvcmlnaW5hbF9hcHByb3ZlZF9zb3VyY2UiOiAiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMCIsCiAgICAiZmluYWxfcmVjb3Zlcnlfc291cmNlIjogImV4YWN0IGZpbmFsIHJvb3QtYXBwbGllZCBvd25lciBIRUFEIHdpdGggYXBwcm92ZWQgZm91ciByZW5kZXIgYmxvYnMgbXVzdCBiZSBib3VuZCBieSBuZXcgZm91bmRlciByZWNlaXB0IgogIH0sCiAgImFwcHJvdmVkX293bmVyX3JlbmRlcl9ibG9iX3NoYTI1NiI6IHsKICAgICJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvbiI6ICI5MjM4MmE1NmIzNDljM2I4OTVlNTgwNmU5NzUwODI1MjdiYjk5ZDFhMDAxMTQwZTY5ZDg1N2U1YjAzOTFmYTU1IiwKICAgICJkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24iOiAiMzhiNzhiOWNiZWU1YWRlNzc1MGE1OGQ1MTU2Y2E0YzU3NzMzNTJlOTQ3YWNiMzA0ZWU3MTRiNTllNzQ5Y2ViNCIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwiOiAiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0NyIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uIjogIjliYWQ2ZGI1ZmJjMjE3OGQzMWIwNDEyMDAxNmE0MTgzMGMzNTUyZmJiOWUyNTE3YjcxOGY5YmJlODdjZjY0OWUiCiAgfSwKICAiZXhlY3V0aW9uX2J1bmRsZV9zaGEyNTYiOiAiNDljOWNiNzBmMzZmNmNlYjdiMGQyMjQwMGIyZWM5MjMyYTVlMWE4YTAwZDE3ZTkyYjkyZmUzNjdjOThlZmZiNSIsCiAgImV4ZWN1dGlvbl9oZWxwZXJfbWFuaWZlc3Rfc2hhMjU2IjogImYyZmFkNmMyNTFmYmI0NDIwZTA3YzEzMjk4MDJmNTIxYjUxM2JiZjY2ZTUxZjY0YzVkNjczZWYwNGYxNjI4NGMiLAogICJleGVjdXRpb25fcGxhbl9zaGEyNTYiOiAiOWNlNTcyOGE1NjFlNmQzOGY4NDk3MjAxYmFhMmI4NDBkMTE0NDRhMGFmOGFkNjIzNGRmYzM3NDI4MTEzZjI1OCIsCiAgImV4ZWN1dGlvbl9waGFzZXMiOiBbCiAgICAiZHJpbGwtY29weS1yZXNjdWUtcjEiLAogICAgIm9mZmxpbmUtdmVyaWZ5IiwKICAgICJjbGVhbnVwLW9mZmxpbmUiLAogICAgImN1dG92ZXItYmFja3VwIiwKICAgICJjdXRvdmVyLWNvcHkiLAogICAgInJlbGVhc2UiLAogICAgInZlcmlmeSIsCiAgICAicm9sbGJhY2siLAogICAgInJvbGxiYWNrLXZlcmlmeSIKICBdLAogICJkZWFkbGluZV9zZW1hbnRpY3MiOiAiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LiIsCiAgIm9mZmxpbmVfaW5pdGlhbGl6ZXIiOiAiT25lIGlzb2xhdGVkIGxvY2FsIFVJRDA6MC9DQVBfQ0hPV04tb25seSBpbml0aWFsaXplciBvZiB0aGUgbmV3bHkgY3JlYXRlZCBub25jZS1ib3VuZCBkaXNwb3NhYmxlIHZvbHVtZSwgZXhhY3QgY2FuZGlkYXRlIGltYWdlLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pOyBubyBob3N0L2xpdmVQVkMvdG9rZW4vY29uZmlnIG1vdW50LiBTdWJzZXF1ZW50IHByZS1vcGVuL2FkbWluL3Bvc3Qtb3BlbiBjaGVja3MgVUlEMTAwMDE6MTAwMDEuIiwKICAicm9sbGJhY2tfZGlzcGF0Y2giOiAiU2VhbGVkIERlcGxveW1lbnQvQ00vUFZDIGFuZCBzYW1lLXNjaGVtYSBzb3VyY2UvaW1hZ2UgcGFpciBwbHVzIGFkbWlzc2lvbiBDQVM7IG5vIFJlYWR5IGNhbmRpZGF0ZSBvciBQb2QvZGF0YWJhc2UgZXhlYyBwcmVyZXF1aXNpdGUuIHJvbGxiYWNrLXZlcmlmeSBzZXBhcmF0ZWx5IHByb3ZlcyByZWNvdmVyZWQgb2xkIGltYWdlL1JlYWR5MS9zY29wZWQgb3BlcmF0aW9uIGFuZCByZWFkb25seSBjdXJyZW50IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50cy4iLAogICJwdXJwb3NlX3Byb29mX2xpbWl0IjogIlRlbiBpbnN0YWxsZWQgc3ludGhldGljLXRyYW5zcG9ydCBjaGVja3Mgb24gYWN0dWFsIHBsYWNlbWVudDsgbmF0aXZlX3Byb3ZpZGVyPWZhbHNlLiBOb3QgYWN0dWFsIHByb3ZpZGVyL1BEUCBhdXRob3JpdHkgcHJvb2YsIHdoaWNoIHJlbWFpbnMgYSBkaXN0aW5jdCBUMDQgY29tcGxldGlvbiBnYXRlLiIsCiAgInJlZmluZW1lbnRfb2ZfYW1lbmRlZF9tYW5pZmVzdCI6ICJiMWUzZTY2YmM0MDIzZGM4MGM2ZWE1OTU2NGMzNTU3Yzc2NTNmYjNjMzA3ZjQ2YTA0OTk5N2I3NjE5OGE5MDMzIiwKICAibWVtb192ZXJzaW9uIjogMiwKICAicmVjb3ZlcnkiOiB7CiAgICAib3JpZ2luYWxfYW5jaG9yIjogewogICAgICAib3JpZ2luYWxfam91cm5hbF9zaGEyNTYiOiAiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMSIsCiAgICAgICJwaGFzZV9tZXRhZGF0YSI6IHsKICAgICAgICAiZHJpbGwtYmFja3VwIjogewogICAgICAgICAgInN0YXRlIjogIkNPTVBMRVRFIiwKICAgICAgICAgICJhdHRlbXB0X2lkIjogImQ2MzE4MmE3LWUxYTUtNGU4ZS1hNWYxLTJiZjMzMzNjZjE1MyIsCiAgICAgICAgICAic3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAyOjM4OjQ1LjMxMDY1MyswMDowMCIKICAgICAgICB9LAogICAgICAgICJkcmlsbC1jb3B5IjogewogICAgICAgICAgInN0YXRlIjogIlVOQ0VSVEFJTiIsCiAgICAgICAgICAiYXR0ZW1wdF9pZCI6ICIzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2MiLAogICAgICAgICAgInN0YXJ0ZWRfYXQiOiAiMjAyNi0xMC0xMVQwMjozOTo1MC4xOTg3NDArMDA6MDAiCiAgICAgICAgfQogICAgICB9LAogICAgICAiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NiI6ICIwMjVkZGRmMWU5MzkzNmYzMWU5OGI5ZmJmYTg0YWEyYmRhYWEzMzU3M2Y5ZDNiMGUzMmQ5NDdmZDI4NmIxNzBlIiwKICAgICAgInNuYXBzaG90X3NoYTI1NiI6ICI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzIiwKICAgICAgInNuYXBzaG90X2J5dGVzIjogMTk1Mzc5MjAsCiAgICAgICJvZmZfY2x1c3Rlcl9maWxlX2V4aXN0cyI6IGZhbHNlLAogICAgICAib2xkX3VuY2VydGFpbl9yZXRyeV9hdXRob3JpemVkIjogZmFsc2UKICAgIH0sCiAgICAib3JpZ2luYWxfaWRlbnRpdHkiOiB7CiAgICAgICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgICAgICJzb3VyY2VfcmV2aXNpb24iOiAiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMCIsCiAgICAgICJtZW1vX3NoYTI1NiI6ICI1MDZkMzk1NmJlYjdjNjJhYjJiYmRmZGE3ODNjMDU5MDVkMTgzNDUyYTFmNjdhMTgxN2YzZmI4YzJlNTIyOTM3IiwKICAgICAgInBsYW5fc2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiCiAgICB9LAogICAgIm5ld19qb3VybmFsIjogInJlc2N1ZS1leGVjdXRpb24tam91cm5hbC1yMS5qc29uIiwKICAgICJuZXdfcGhhc2UiOiAiZHJpbGwtY29weS1yZXNjdWUtcjEiLAogICAgIm9sZF91bmNlcnRhaW5fcGhhc2Vfb3ZlcndyaXRlX29yX3JldHJ5IjogZmFsc2UsCiAgICAibmV3X3NuYXBzaG90X2JhY2t1cCI6IGZhbHNlLAogICAgInNuYXBzaG90X29yX3NpZGVjYXJfbXV0YXRpb24iOiBmYWxzZSwKICAgICJtYXBwaW5nIjogIm9mZmxpbmUtdmVyaWZ5IGNvbnN1bWVzIENPTVBMRVRFIGRyaWxsLWNvcHktcmVzY3VlLXIxIHJlc3VsdDsgYWxsIGxhdGVyIHBoYXNlcyBvcmRlcmVkIG9ubHkgaW4gbmV3IGhhc2gtbGlua2VkIHJlY292ZXJ5IGpvdXJuYWwiCiAgfSwKICAib3JpZ2luYWxfbmF0aXZlX291dGNvbWUiOiB7CiAgICAiZHJpbGwtYmFja3VwIjogIkNPTVBMRVRFIiwKICAgICJkcmlsbC1jb3B5IjogIlVOQ0VSVEFJTiBiZWZvcmUgbG9jYWxmaWxlIGNyZWF0aW9uIiwKICAgICJuYXRpdmVfaW1hZ2UiOiAidW5jaGFuZ2VkN2Y1OyBubyByb2xsb3V0IiwKICAgICJvcmlnaW5hbF9qb3VybmFsX2FuZF9zaWRlY2FycyI6ICJyZXRhaW5lZCB1bmNoYW5nZWQiCiAgfSwKICAicmVzY3VlX2xpbWl0cyI6ICJObyBsaXZlREJ3cml0ZXMgZHVyaW5nIHJlc2N1ZSBpbnNwZWN0aW9uL2NvcHksIG5vIHNpZGVjYXIgZGVsZXRpb24vY2hlY2twb2ludCwgbm8gcmV0cnkvb3ZlcndyaXRlIG9yaWdpbmFsIFVOQ0VSVEFJTiBwaGFzZS4gTGF0ZXIgZXhpc3RpbmcgYWRtaW4gb2ZmbGluZWluc3BlY3QvY3V0b3ZlcmJhY2t1cCBhbmQgaW1hZ2UgYWN0aW9ucyBuZWVkIG5ldyBleGFjdHZlcnNpb24yIGFjY2VwdGFuY2UgYW5kb3JkZXJlZGd1YXJkcy4iLAogICJzdWJtaXNzaW9uX3JvdXRlIjogIlBPU1QgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMgQ0FTIGV4cGVjdGVkX3ZlcnNpb24xOyBzb3VyY2UgbXVzdCByZW1haW4gdW5ib3VuZDsgcHVibGlzaC9yZXZpZXcgc291cmNldmVyc2lvbjIsIHJlc3VsdGluZyBodW1hbiByZXZpZXcgb3dudmVyc2lvbjEiCn0K" + }, + { + "digest": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgIm9ic2VydmVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjQ6MDEuOTg1MTI4KzAwOjAwIiwKICAibmF0aXZlX293bmVyX3B1YmxpY2F0aW9uX2pvYiI6IHsKICAgICJpZCI6IDExNDg0LAogICAgIm5hbWUiOiAicHVibGlzaC1jYW5kaWRhdGUiLAogICAgImhlYWRfYnJhbmNoIjogIm1haW4iLAogICAgImhlYWRfc2hhIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgInJ1bl9udW1iZXIiOiAzLAogICAgImV2ZW50IjogInB1c2giLAogICAgImRpc3BsYXlfdGl0bGUiOiAiUHJlcGFyZSByZWFkYWJsZSBvdmVybGF5IGNvbnRleHQgd2l0aCB0aGUgYWRtaXR0ZWQgbGVnYWN5IGJ1aWxkZXIiLAogICAgInN0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJ3b3JrZmxvd19pZCI6ICJwdXJwb3NlLW92ZXJsYXktaW1hZ2UueWFtbCIsCiAgICAidXJsIjogImh0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uL2FjdGlvbnMvcnVucy8zIiwKICAgICJjcmVhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjA6NTlaIiwKICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjE6MDhaIiwKICAgICJydW5fc3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjIwOjU5WiIKICB9LAogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInBvbGljeV9zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgInJlZ2lzdHJ5X3Byb29mX3NoYTI1NiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAic291cmNlX3JlbmRlcl9jaGFuZ2Vfb25seSI6ICJEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHNwZWMudGVtcGxhdGUuc3BlYy5jb250YWluZXJzWzBdLmltYWdlIiwKICAicnVudGltZV9jb25maWdtYXBfdW5jaGFuZ2VkIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAiaW5zdGFsbGVkX2ltYWdlX2V4ZWN1dGlvbiI6IHsKICAgICJpbW11dGFibGVfcmVnaXN0cnlfYXJ0aWZhY3RfcHVsbGVkX2Fub255bW91c2x5IjogdHJ1ZSwKICAgICJVSUQiOiAxMDAwMSwKICAgICJHSUQiOiAxMDAwMSwKICAgICJwb2xpY3lfZmlsZV9VSUQiOiAwLAogICAgInBvbGljeV9maWxlX21vZGUiOiAiMDY0NCIsCiAgICAicHVycG9zZV92YXJpYW50cyI6IDEwLAogICAgImJpbmRpbmdfZm9ybXNfYWxsb3dlZCI6IDIsCiAgICAiYWR2aXNvcnlfb3JfbWFsZm9ybWVkX3JlZnVzZWQiOiA4LAogICAgIm5ldHdvcmsiOiAibm9uZSIsCiAgICAicmVhZF9vbmx5IjogdHJ1ZSwKICAgICJzeW50aGV0aWNfdHJhbnNwb3J0IjogdHJ1ZSwKICAgICJuYXRpdmVfUERQX3Rlc3QiOiBmYWxzZQogIH0sCiAgInNjYW5fc3VtbWFyeV9zaGEyNTYiOiAiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NCIsCiAgImhpc3RvcmljYWxfZmFpbGVkX3J1bnNfcmV0YWluZWQiOiBbCiAgICAiZjY2ZGU1MDUvdGFzazExNDgyL3J1bjEiLAogICAgImFjZWNhZDg4Ny90YXNrMTE0ODMvcnVuMiIKICBdLAogICJuYXRpdmVfaG9zdGluZ19jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJodW1hbl9hcHByb3ZhbCI6IGZhbHNlLAogICJldmlkZW5jZV9maWxlX3NoYTI1NiI6IHsKICAgICJpbWFnZS1tYW5pZmVzdC5qc29uIjogIjk3OGM1NzVkM2M3YmYwZGUzOWRiZTRlOTU2N2MzOWNkMzZmNzBiN2U1NWJjMTczNTdiZGIwM2ZiM2I5NmIwZmIiLAogICAgImltYWdlLWNvbmZpZy5qc29uIjogIjRhZDcyNDljNzVmZDlmYzAzOWNlYjE4Njc3MjQxOWUxY2JhNWZkOTc1OWM0MDQ1NTY0NTljODBhMmQyODVkMTAiLAogICAgImJhc2UtaW1hZ2UtY29uZmlnLmpzb24iOiAiYjcwNmM5MjA5ZTMyNGYzOWE4NmZmY2RhMmEzZTlkOTRjOTI2NDk3MzlhZDViMjFmZTQ2MTEwMDZlMzZmNmYwMCIsCiAgICAicmVnaXN0cnktcHJvb2YuanNvbiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAgICJ0cml2eS1mdWxsLmpzb24iOiAiZjM4YThmN2U2YzQxOWVlZDkxNTRkNzc2MmY5MzJiOWRlYjY2ODBhNjIyMjQ3YjA4MTk2Yjc0NThiODkzNDM0ZSIsCiAgICAic2JvbS5jZHguanNvbiI6ICJhNDI1Mjk1MWUyMDI3NDcyYzI2ZDg2NzljYjU0M2UzMDk4MzE4MDgwOWQ2ZGQzYzdjOTRiODgzZDYyODAzZTVkIiwKICAgICJiYXNlLXRyaXZ5LWZ1bGwuanNvbiI6ICJkNDRjNTU1YWVjYmIxYTQ1MThmNDEyN2Q0ODAxNWVhNDU5MzI1YzkzZThiMDM3MTkxMGE1NWRlNDcyOTNjYTgwIiwKICAgICJjaGVja19pbnN0YWxsZWQucHkiOiAiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZCIsCiAgICAidmVyaWZ5X3JlZ2lzdHJ5LnB5IjogIjQxM2Y1NzVjMjFhMmJkMThhMzY5NmY4ZjJkOTM5ZWVhZGM1MmQ3NmYyODJjNDI4MTNmNzZiYjBlM2VlOGEyYTQiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAicmV2aWV3LXJlZmluZW1lbnQuanNvbiI6ICJlYTYyODQ1Y2VlNWVlNmY0ZjZjYjdmNWRjZDBhZjYwMWJhMjlhMjFjOGZmODBlZmJiYzAyYWQxNmUzNWJlYTc1IiwKICAgICJ0ZXN0X2NoYW5nZV9ndWFyZC5weSI6ICJkYTUzNTA0MzczNTdiYTMyOTIzNmNjMTM3NjEwYzAzODU2ZjM4ZjgzNmRkZjI4NTYwMjViYzEyMDExZmFkMDdmIiwKICAgICJ0ZXN0X3NxbGl0ZV9yZWFkb25seS5weSI6ICJjN2E5MWQwYzZhMzczZDczOGM4OGJiODE3ZDliZmIyZmY4YTE3OWJjNjFiOTMwNjNiODk2NzdiNTY2NTIwMzIzIiwKICAgICJ0ZXN0X3ByZWZsaWdodF9vcHRpbWl6YXRpb24ucHkiOiAiYTBjNGZhMThjNWQ2YzIxNDc2YTA2YzZkMDVmZTc2NTYyNTlkMjA0Mjk5MTM4ODUxNTk5ZTkyMTRkOTExMjA2ZCIsCiAgICAiaW5pdGlhbC1hcHByb3ZlZC1iYzY0OTRjZC9zcWxpdGVfcmVhZG9ubHkucHkiOiAiZWVmNTNkZDIzM2VlZTc0YzE3ZjIwODIzYmQ3ZjU3ODdjNjBjYWQ3OWFjNjQ4MDIxYzk0Nzk2NDNjNmNlOWUzOCIKICB9LAogICJ2ZXJzaW9uMl9zb3VyY2VfcG9pbnRlcl9yZWZpbmVtZW50IjogewogICAgIm9yaWdpbmFsX3JlY2VpcHRfc2hhMjU2IjogIjhhNjc2YzM4Zjg5ZjljYTc2MmI4ZWJlOTQ1YjVhY2I5MGQ0N2E0Y2IzNTA2OTI2ODdhYmI5ODViYmIyZDhhZTIiLAogICAgIm9yaWdpbmFsX3JlY2VpcHRfYXJjaGl2ZSI6ICJpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkL3B1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvbiIsCiAgICAicmVhc29uIjogIktlZXAgaGlzdG9yaWNhbCBvcmlnaW5hbCBwcmUtb3BlbiBjaGVja2VyIGhhc2ggYm91bmQgdG8gZXhhY3QgYXJjaGl2ZWQgb3JpZ2luYWwgYnl0ZXM7IGN1cnJlbnQgdmVyc2lvbjIgY2hlY2tlciBpcyBpbmRlcGVuZGVudGx5IGRpcmVjdC1wYWNrZXQvcGxhbiBib3VuZC4gQWN0dWFsIGltYWdlL3JlZ2lzdHJ5L3NjYW4vU0JPTSBwcm9vZiB1bmNoYW5nZWQ7IG5vIG5ldyBhcnRpZmFjdCB2ZXJpZmljYXRpb24gb3IgbmF0aXZlIHZlcnNpb24yIGFjdGlvbiBjbGFpbWVkLiIKICB9Cn0K" + }, + { + "digest": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZV9kaWdlc3QiOiAic2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgImJhc2VfaW1hZ2VfZGlnZXN0IjogInNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAiYmFzZV9sYXllcl9ieXRlc19pZGVudGljYWwiOiB0cnVlLAogICJsYXllcl9tZWRpYV90eXBlX2NvbnZlcnNpb24iOiAiT0NJIGd6aXAgdG8gRG9ja2VyIGd6aXAsIHNhbWUgZGlnZXN0IGFuZCBzaXplIiwKICAiYmFzZV9ydW50aW1lX2NvbmZpZ19zZW1hbnRpY3NfaWRlbnRpY2FsIjogdHJ1ZSwKICAibGVnYWN5X2J1aWxkZXJfY29uZmlnX2FkZGl0aW9ucyI6IHsKICAgICJIb3N0bmFtZSI6ICIiLAogICAgIkRvbWFpbm5hbWUiOiAiIiwKICAgICJBdHRhY2hTdGRpbiI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZG91dCI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZGVyciI6IGZhbHNlLAogICAgIlR0eSI6IGZhbHNlLAogICAgIk9wZW5TdGRpbiI6IGZhbHNlLAogICAgIlN0ZGluT25jZSI6IGZhbHNlLAogICAgIkNtZCI6IG51bGwsCiAgICAiVm9sdW1lcyI6IG51bGwsCiAgICAiT25CdWlsZCI6IG51bGwsCiAgICAiSW1hZ2UiOiAic2hhMjU2OjkwZjE1NzRmOWVkYTM1ZmE2Y2I5NzI5NjFiZWIyN2E3Y2I5MDRjMzY1NjBlMzgxOTMwYjBlMTQwNjVjMjM4ODMiCiAgfSwKICAiYmFzZV9yb290ZnNfcHJlZml4X2lkZW50aWNhbCI6IHRydWUsCiAgIm92ZXJsYXlfcmVndWxhcl9maWxlcyI6IFsKICAgICJvcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weSIKICBdLAogICJvdmVybGF5X2RpcmVjdG9yaWVzIjogWwogICAgIm9wdCIsCiAgICAib3B0L3ZlbnYiLAogICAgIm9wdC92ZW52L2xpYiIsCiAgICAib3B0L3ZlbnYvbGliL3B5dGhvbjMuMTIiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24iCiAgXSwKICAicG9saWN5X3NoYTI1NiI6ICI5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyIiwKICAicG9saWN5X21vZGUiOiAiMDY0NCIsCiAgImJhc2VfdXNlciI6ICIxMDAwMToxMDAwMSIsCiAgInNvdXJjZV9zY29wZV9sYWJlbHMiOiB7CiAgICAib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnJldmlzaW9uIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgIm9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5iYXNlLmRpZ2VzdCI6ICJzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgICAic29jaWFsLmNvdWxvbWIuc291cmNlLnBvbGljeS5zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgICAic29jaWFsLmNvdWxvbWIucmVsZWFzZS5zY29wZSI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIKICB9LAogICJyZWdpc3RyeV9yZWFkX3JvdXRlIjogImFub255bW91cyBwdWJsaWMgc2NvcGVkIGJlYXJlciBjaGFsbGVuZ2UsIG5vIHRva2VuIHJldGVudGlvbiIsCiAgImltYWdlX2V4ZWN1dGVkIjogZmFsc2UsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlCn0K" + }, + { + "digest": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInNjYW5uZXIiOiAiYXF1YXNlYy90cml2eUBzaGEyNTY6NjJiMWU2NWU4ODY5YmM0YjRjNmFhNGZhMmIyMTU5NTI1NmM3YzJmNjAxOGE5ZDlhZDYxY2FmODcxODdjMTk2OSIsCiAgInZlcnNpb24iOiAiMC43NC4wIiwKICAiZGJfbWV0YWRhdGEiOiB7CiAgICAiVmVyc2lvbiI6IDIsCiAgICAiTmV4dFVwZGF0ZSI6ICIyMDI2LTEwLTExVDE4OjU5OjUwLjg4OTAxMDU3MloiLAogICAgIlVwZGF0ZWRBdCI6ICIyMDI2LTEwLTEwVDE4OjU5OjUwLjg4OTAxMDkyM1oiLAogICAgIkRvd25sb2FkZWRBdCI6ICIyMDI2LTEwLTEwVDIzOjMyOjMyLjM4MDAzMzEzMVoiCiAgfSwKICAic3VwcHJlc3Npb24iOiBmYWxzZSwKICAiaWdub3JlX3VuZml4ZWQiOiBmYWxzZSwKICAic2V2ZXJpdHlfZmlsdGVyIjogbnVsbCwKICAicGFja2FnZV9jb3VudCI6IDQ0LAogICJmaW5kaW5nc19ieV9zZXZlcml0eSI6IHsKICAgICJNRURJVU0iOiAxCiAgfSwKICAiZmluZGluZ3MiOiBbCiAgICB7CiAgICAgICJpZCI6ICJDVkUtMjAyNi04NTA5MSIsCiAgICAgICJwYWNrYWdlIjogInpsaWIiLAogICAgICAiaW5zdGFsbGVkIjogIjEuMy4yLXIwIiwKICAgICAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAgICAgInNldmVyaXR5IjogIk1FRElVTSIKICAgIH0KICBdLAogICJjb3ZlcmFnZV9saW1pdHMiOiBbCiAgICAiQWxwaW5lMy4yNCBhYnNlbnQgc2Nhbm5lciBFT0wgbGlzdDsgT1MgZGV0ZWN0b3IgcmFuIGFnYWluc3QgQWxwaW5lMy4yNCByZXBvc2l0b3J5IG9uMzhPUyBwYWNrYWdlcyIsCiAgICAiS25vd24gZmluZGluZ3MgYXNvZiBwaW5uZWREQiwgbm90IGNsYWltIGFic2VuY2Ugb2YgdW5rbm93biB2dWxuZXJhYmlsaXRpZXMiCiAgXSwKICAiaGlnaF9jcml0aWNhbCI6IDAsCiAgInNhbWVfc2Nhbm5lcl9hY3R1YWxfYmFzZV9zY2FuX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgImJhc2Vfc2Nhbl9maWxlIjogImJhc2UtdHJpdnktZnVsbC5qc29uIgp9Cg==" + }, + { + "digest": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5", + "media_type": "application/json", + "content_base64": "ewogICJraW5kIjogImluZm9ybWVkLWRlY2lzaW9uLnN1cGVydmlzZWQtZXhlY3V0aW9uLXNvdXJjZS1idW5kbGUiLAogICJ2ZXJzaW9uIjogMiwKICAicHJvcG9zYWxfaWQiOiAiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEiLAogICJmaWxlcyI6IHsKICAgICJSRUFETUUubWQiOiB7CiAgICAgICJzaGEyNTYiOiAiNTFiNTZjOGVjMmYzMGFkNjJmNmNkMDk3MzJjMGY3M2RkN2I1ZWJmMjA4MTMyMDIyM2M4NWJiY2JmMDBkMTVhOSIsCiAgICAgICJjb250ZW50IjogIiMgVmVyc2lvbjIgcHJvdGVjdGVkIGV4aXN0aW5nLXNuYXBzaG90IHJlc2N1ZSDigJQgcHJlcGFyZWQsIHVuYXBwcm92ZWRcblxuT3JpZ2luYWwgYXBwcm92ZWQgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCBkcmlsbC1iYWNrdXAsIHRoZW4gZHJpbGwtY29weSBmYWlsZWQgYmVmb3JlIGNyZWF0aW5nIGEgbG9jYWwgc25hcHNob3QuIE9yaWdpbmFsIGpvdXJuYWwgZHJpbGwtY29weSByZW1haW5zIFVOQ0VSVEFJTi4gTWV0YWRhdGEtb25seSBjYXB0dXJlIHByb3ZlcyBleGFjdCB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMCBhbmQgcHJpdmF0ZVNITTMyNzY4LiBTb3VyY2UgY2xvc2VzIFNRTGl0ZSBjb25uZWN0aW9ucyBleHBsaWNpdGx5OyBpbW11dGFibGUgcmVhZHMgYXJlIG9ubHkgZm9yIHRoZSBmcm96ZW4gbWFpbiBzbmFwc2hvdCB3aXRoIGV4YWN0IHByaW9yIGRpZ2VzdC9zaXplL3ByaXZhdGUgaWRlbnRpdHkgYW5kIG5vIFdBTCBmcmFtZXMuIExpdmUgc291cmNlIGFuZCBvZmZsaW5lIHByZS9wb3N0LWFkbWluIHJlYWRzIHJlbWFpbiBtb2RlPXJvL3F1ZXJ5X29ubHkgV0FMLWF3YXJlOyBpbW11dGFibGUgaXMgbmV2ZXIgYSBsaXZlIERCIG9yIHNjaGVtYS1taWdyYXRpb24gc2hvcnRjdXQuIFNpZGVjYXJzIHJlbWFpbiByZXRhaW5lZCwgbmV2ZXIgZGVsZXRlZC9jaGVja3BvaW50ZWQuXG5cbkZyZXNoIGZvdW5kZXIgYWNjZXB0YW5jZSBvZiB0aGUgZXhhY3QgbWVtbyB2ZXJzaW9uMiBpcyByZXF1aXJlZCBiZWZvcmUgYW55IHJlc2N1ZSBvciBjb250aW51YXRpb24uIE9sZCB2ZXJzaW9uMSBhY2NlcHRhbmNlIGNhbm5vdCBwYXNzIGF1dGhvcml0eSBjaGVja3MuIFJvb3QgbXVzdCBmcmVzaGx5IGF1dGhlbnRpY2F0ZSBhY3R1YWwgY29uZmlybWVkIHBlcnNvbi9wbGF0Zm9ybS1yb290IEFDQ0VQVCBhdCB0aGUgZml4ZWQgbmF0aXZlIG9yaWdpbiBiZWZvcmUgZWFjaCBwaGFzZTsgcHJvdGVjdGVkIHJlY2VpcHQgY2hlY2tpbmcgaXMgc3VwZXJ2aXNlZCBib29ra2VlcGluZywgbm90IGFuIGF1dGhlbnRpY2F0ZWQgc2lnbmVkL2F1dG9ub21vdXMgZ3JhbnQuIE5vIG5ldyBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4gaW4gdGhpcyBwcmVwYXJhdGlvbi5cblxuRml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnk7IHJvbGxiYWNrIOKGkiByb2xsYmFjay12ZXJpZnkgb25seSBhZnRlciByZWNvcmRlZCBuZXcgcmVsZWFzZSBhdHRlbXB0LiBOZXcgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24gYW5kIHJlc2N1ZS1leGVjdXRpb24tcjEubG9jayBjb2V4aXN0IHdpdGggdGhlIHVuY2hhbmdlZCBvcmlnaW5hbCBleGVjdXRpb24tam91cm5hbC5qc29uLiBUaGV5IGhhc2gtbGluayBpdHMgZXhhY3Qgb3JpZ2luYWwgYXBwcm92ZWQgaWRlbnRpdHksIENPTVBMRVRFIGJhY2t1cCBhbmQgVU5DRVJUQUlOIGNvcHkgYXR0ZW1wdCBJRHMvcmVzdWx0cy4gTm8gZXh0cmEgb3JpZ2luYWwgcGhhc2Ugb3IgcmVsZWFzZSBpcyBhbGxvd2VkOyBvcmlnaW5hbCBqb3VybmFsIGhhc2ggaXMgY2hlY2tlZCBiZWZvcmUgYW5kIGFmdGVyIGVhY2ggbmV3IHBoYXNlLiBObyBvbGQgZHJpbGwtY29weSByZXRyeS9vdmVyd3JpdGUgb3Igc3ludGhlc2l6ZWQgY29tcGxldGVkIHBoYXNlLlxuXG5CZWZvcmUgcmVzY3VlLCBvcmlnaW5hbCBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgbXVzdCBiZSBhYnNlbnQsIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50LCBhbmQgbG9jYWwgZW5naW5lIGJudC1sYXAwMDEvY3VycmVudCBuYXRpdmUgb2xkaW1hZ2U3ZjUvc291cmNlN2RiL3NlYWxlZERlcGxveW1lbnQrQ00vUFZDL29yaWdpbmFsUG9kVUlEIG11c3QgbWF0Y2guIFRoZSBvbGQgYmFja3VwIGFkbWluIGFscmVhZHkgZXhpdGVkIGFmdGVyIHVuaXF1ZWx5IGNyZWF0aW5nIHRoZSBwcml2YXRlIGZpeGVkIHNuYXBzaG90IHBhdGg7IHRoZSBvbmx5IGxhdGVyIG9yaWdpbmFsIGFjY2VzcyB3YXMgV0FMLWF3YXJlIHJlYWRvbmx5IGluc3BlY3Rpb24sIHdpdGggbm8gc25hcHNob3Qgd3JpdGVyLiBNYWluIGhhc2gsIHByaXZhdGUgaWRlbnRpdGllcyBhbmQgYWJzZW50L3plcm8gV0FMIGFyZSBjaGVja2VkIGJlZm9yZS9hZnRlciBpbW11dGFibGUgaW5zcGVjdGlvbiBhbmQgY29weS4gT3JpZ2luYWwgcHJpdmF0ZSBTSE0gaXMgaW5kZXhpbmcgYW5kIGlzIHJldGFpbmVkIHVuY2hhbmdlZC4gTm9uZW1wdHkgV0FMLCBjaGFuZ2VkIGhhc2gvbWV0YWRhdGEsIG1pc3NpbmcgZmFpbGVkIGpvdXJuYWwsIG1pc3Npbmcgb3JpZ2luIG9yIGFueSB1bnZlcmlmaWVkIG91dGNvbWUgc3RvcHMgcmVzY3VlLiBObyBuZXcgbmF0aXZlIGJhY2t1cCBpcyBtYWRlIGZvciB0aGUgZHJpbGwuIEJpbmFyeSBzbmFwc2hvdCBieXRlcyBmbG93IG9ubHkgaW50byBhIG5ldzA2MDAgbG9jYWxmaWxlLCBuZXZlciBjaGF0L2xvZy9wYWNrZXQuIFNhbWUgcmVzY3VlLXBoYXNlIHJldHJ5IGlzIHJlZnVzZWQgYWZ0ZXIgYW55IGF0dGVtcHRlZCBvdXRjb21lLlxuXG5PZmZsaW5lIHZlcmlmaWNhdGlvbiBleHBsaWNpdGx5IGNvbnN1bWVzIENPTVBMRVRFIGRyaWxsLWNvcHktcmVzY3VlLXIxIHJlc3VsdCwgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGV4YWN0IGlzb2xhdGVkIG5ldy12b2x1bWUgVUlEMC9DQVBfQ0hPV04gaW5pdGlhbGl6ZXIsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHJlYWRvbmx5L2FkbWluL3Bvc3QtYWRtaW4gY2hlY2tzIGFuZCByZXRhaW5lZCBvcmlnaW5hbCBTSEEsIHJlbWFpbnMgYm91bmRlZCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3QvQ1BVMS8xMjhNaSB3aXRoIG5vIGhvc3QvbmF0aXZlUFZDL3J1bnRpbWVjb25maWcvdG9rZW4gbW91bnRzLiBPbmx5IHRoZSBkaXNwb3NhYmxlIGNvcHkgdm9sdW1lIGNhbiBiZSByZW1vdmVkLiBDdXRvdmVyIHNuYXBzaG90IGlzIHRoZSBkaXN0aW5jdCBhbHJlYWR5LXNjb3BlZCBuZXcgY3V0b3Zlci5zcWxpdGU7IHJlc2N1ZSBuZXZlciBvdmVyd3JpdGVzIGRyaWxsLnNxbGl0ZSBvciBjcmVhdGVzIGFub3RoZXIgZHJpbGwgYmFja3VwLlxuXG5Gb3VyIGNvbW1pdHRlZCBvd25lciByZW5kZXIgR2l0IGJsb2JzIGFuZCBoZWxwZXIvY2FzZSBoYXNoZXMgbXVzdCBtYXRjaCBleGFjdCBmaW5hbCBzb3VyY2UgSEVBRC4gTWFudWFsQXBwbGljYXRpb24gcmVqZWN0cyBhbnkgYXV0b21hdGVkIGNvbmZpZ3VyYXRpb24gaW5jbHVkaW5nIHt9IG9yIHNvdXJjZSBvdmVycmlkZXMuIFNvdXJjZS1waW4gQXBwbGljYXRpb24ub3BlcmF0aW9uIHVzZXMgc2VydmVyIGRyeS1ydW4gYW5kIFVJRC9yZXNvdXJjZVZlcnNpb24vc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5L3BydW5lPWZhbHNlOyBubyB3aG9sZS1hcHAgc3luYy4gUm9sbGJhY2sgZGlzcGF0Y2ggaGFzIG5vIGZhaWxpbmctY2FuZGlkYXRlIFBvZC9EQiBkZXBlbmRlbmN5OyBzZXBhcmF0ZSByZWNvdmVyeSBwcm9vZiBjaGVja3Mgb2xkaW1hZ2UgUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9zY2hlbWE1IHJldGFpbmVkbGF0ZXN0REIuIEFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlY292ZXJ5L3ZlcmlmaWNhdGlvbiBtdXN0IGJlZ2luIGJ5MjAyNi0xMC0xMlQyMzo1OTo1OVo7IGFmdGVyIGV4cGlyeSBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBObyBleHBpcnkgY29udHJvbGxlciBvciBpbXBsaWNpdCBleHRlbnNpb24uXG5cbkltYWdlNzYzYy9wb2xpY3k5ZDdjIGFuZCBrbm93biBpbmhlcml0ZWQgZml4YWJsZSBNRURJVU0gcmVtYWluIHVuY2hhbmdlZDsgb3duZXIgVDA1IGR1ZU9jdDE4LiBUZW4gaW5zdGFsbGVkIGNoZWNrcyB1c2Ugc3ludGhldGljIHRyYW5zcG9ydC9uYXRpdmVfcHJvdmlkZXI9ZmFsc2UgYW5kIGRvIG5vdCBmdWxmaWxsIHNlcGFyYXRlIGFjdHVhbC1wcm92aWRlciBUMDQgZ2F0ZS4gUHJlc2VydmUgb3JpZ2luYWwgYWNjZXB0YW5jZS9iYWNrdXAvZmFpbHVyZS9oaXN0b3J5IGluIHRoaXMgc2FtZSB0cmlhbC4gVHdlbnR5LXNpeCBtb2NrZWQvc291cmNlIGV4ZWN1dG9yIHJlZ3Jlc3Npb25zIHBhc3M7IG5vIGFjdHVhbCBEQi9hZG1pbi9uYXRpdmUgY29tbWFuZCBkdXJpbmcgdGVzdHMvcHJlcGFyYXRpb24uXG5cbk5hdGl2ZSBwdWJsaWNhdGlvbiByb3V0ZTogUE9TVCBleGlzdGluZyBzb3VyY2UgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMgd2l0aCBleHBlY3RlZF92ZXJzaW9uMSBhbmQgZXhhY3QgbWVtbzIvZG9jdW1lbnRzL3N1bW1hcnksIHRoZW4gcHVibGljYXRpb25zL3Jldmlldy1yZXF1ZXN0cyB2ZXJzaW9uMi4gRnJlc2ggc291cmNlIHJlYWRiYWNrIG11c3QgcHJvdmUgY3VycmVudHZlcnNpb24xIGlzIHVuYm91bmQgYmVmb3JlIHJldmlzaW9uOyBib3VuZC9kaWZmZXJlbnQgc291cmNlIHN0b3BzLiBJbnRha2UvcmVnaXN0ZXIgcmVmdXNlIHZlcnNpb24yIGFzIGRlc2lnbmVkIGFuZCBhcmUgbm90IHVzZWQuIFJldmlldyBpbnRlZ3JhdGlvbiBjcmVhdGVzIGEgTkVXIHJldmlldy1JRCBhdCBpdHMgb3duIHZlcnNpb24xOyBmb3VuZGVyIGRpc3Bvc2l0aW9uIG1lbW9fdmVyc2lvbjEgYmVsb25ncyB0byB0aGF0IG5ldyByZXZpZXcuIFJvb3QgZnJlc2ggb3V0Y29tZXMgbXVzdCBiZSBxdWVyaWVkIGZvciBTT1VSQ0UgdmVyc2lvbjIsIGV4YWN0IG5ld3Jldmlld0lEL21lbW9TSEEgYW5kIGNvbmZpcm1lZCBuZXN0ZWQgcGVyc29uYXBwcm92YWwuIFJlY2VpcHQgb3V0Y29tZV9xdWVyeSBwaW5zIHRoYXQgc291cmNldmVyc2lvbjIgcm91dGU7IGl0IGRvZXMgbm90IGF1dGhlbnRpY2F0ZSBieSBpdHNlbGYuXG4iCiAgICB9LAogICAgImFjdHVhdG9yLnB5IjogewogICAgICAic2hhMjU2IjogIjg2YjY3ZDFhYmFkNmFmMmE4YzQ5NTI4ZmUxMjVhNWJhYjk0NDk3NWQzZTgwMTgyNmM1MTFlZTg4ODQ2NTcxYjIiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmUgZml4ZWQgc3VwZXJ2aXNlZCBwaGFzZTsgbmV2ZXIgcnVuIHRoaXMgZHVyaW5nIHNvdXJjZSBwcmVwYXJhdGlvbi5cIlwiXCJcbmltcG9ydCBhcmdwYXJzZVxuaW1wb3J0IGhhc2hsaWJcbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHJlXG5pbXBvcnQgc2VsZWN0b3JzXG5pbXBvcnQgc3RhdFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0aW1lXG5cbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KCdvcHRpbWl6ZWQgaW50ZXJwcmV0ZXIgcmVmdXNlZCcpXG5cblBIQVNFUyA9ICgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCAnb2ZmbGluZS12ZXJpZnknLCAnY2xlYW51cC1vZmZsaW5lJyxcbiAgICAgICAgICAnY3V0b3Zlci1iYWNrdXAnLCAnY3V0b3Zlci1jb3B5JywgJ3JlbGVhc2UnLCAndmVyaWZ5JywgJ3JvbGxiYWNrJywgJ3JvbGxiYWNrLXZlcmlmeScpXG5cblxuZGVmIHJlcXVpcmUodmFsdWUsIHJlYXNvbik6XG4gICAgaWYgbm90IHZhbHVlOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcblxuXG5kZWYgc2hhKHBhdGgpOlxuICAgIGRpZ2VzdCA9IGhhc2hsaWIuc2hhMjU2KClcbiAgICB3aXRoIFBhdGgocGF0aCkub3BlbigncmInKSBhcyBzdHJlYW06XG4gICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6XG4gICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJsb2NrKVxuICAgIHJldHVybiBkaWdlc3QuaGV4ZGlnZXN0KClcblxuXG5kZWYgcHJpdmF0ZShwYXRoLCBkaXJlY3Rvcnk9RmFsc2UpOlxuICAgIGluZm8gPSBQYXRoKHBhdGgpLmxzdGF0KClcbiAgICByZXF1aXJlKChzdGF0LlNfSVNESVIoaW5mby5zdF9tb2RlKSBpZiBkaXJlY3RvcnkgZWxzZSBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSlcbiAgICAgICAgICAgIGFuZCBpbmZvLnN0X3VpZCA9PSBvcy5nZXR1aWQoKSBhbmQgc3RhdC5TX0lNT0RFKGluZm8uc3RfbW9kZSkgPT0gKDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxuICAgICAgICAgICAgYW5kIChkaXJlY3Rvcnkgb3IgaW5mby5zdF9ubGluayA9PSAxKSwgJ3ByaXZhdGUgb3duZWQgY3VzdG9keSByZXF1aXJlZCcpXG5cblJPT1QgPSBQYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50XG5DQVNFID0gUk9PVC5wYXJlbnRcbk9XTkVSID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uJylcbkNVU1RPRElBTiA9IFBhdGgoJy9ob21lL3dvcnNjaC90aGUtY3VzdG9kaWFuJylcbkNVU1RPRFkgPSBDVVNUT0RJQU4gLyAnLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjEnXG5TT0NLRVQgPSAndW5peDovLy92YXIvcnVuL2RvY2tlci5zb2NrJ1xuSU1BR0UgPSAnZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhJ1xuVk9MVU1FID0gJ2luZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExJ1xuTUFYX0JZVEVTID0gNTEyICogMTAyNCoqMlxuXG5cbmRlZiBydW4oYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTkwKTpcbiAgICByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndiwgaW5wdXQ9Ym9keSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIGpzb25fcmVzdWx0KHJlc3VsdCk6XG4gICAgdHJ5OlxuICAgICAgICB2YWx1ZSA9IGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcbiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhZmUgcGhhc2UgcmVjZWlwdCB1bmF2YWlsYWJsZTsgb3V0Y29tZSB1bmNlcnRhaW4nKSBmcm9tIE5vbmVcbiAgICByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlID09IDAgYW5kIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIFRydWUsXG4gICAgICAgICAgICAncGhhc2UgZGlkIG5vdCB2ZXJpZnkgY29tcGxldGU7IHJhdyBvdXRwdXQgd2l0aGhlbGQ7IG5vIHJldHJ5JylcbiAgICBwZXJtaXR0ZWQgPSB7J3BoYXNlJywgJ2FsbF9jaGVja3NfcGFzcycsICdyYXdfb3V0cHV0X3dpdGhoZWxkJywgJ25hdGl2ZV9hcHByb3ZhbF92ZXJpZmllZF9ieV9yb290JyxcbiAgICAgICAgICAgICAgICAgJ25hdGl2ZV9hdXRoZW50aWNhdGVkX2dyYW50JywgJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZScsICdzbmFwc2hvdF9yZWFkb25seScsXG4gICAgICAgICAgICAgICAgICdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICduYXRpdmVfcGFyZW50X3ByaXZhdGUnLFxuICAgICAgICAgICAgICAgICAnbmF0aXZlX3VpZCcsICdwb2RfbmFtZScsICdwb2RfdWlkJywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnLFxuICAgICAgICAgICAgICAgICAnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzJywgJ29wZXJhdGlvbl9yZXF1ZXN0ZWQnLCAnc291cmNlX3JldmlzaW9uJyxcbiAgICAgICAgICAgICAgICAgJ3Jlc291cmNlcycsICdwcnVuZScsICdyb2xsb3V0X3ZlcmlmaWVkJywgJ2xhdGVzdF9saXZlX2RhdGFiYXNlX3JldGFpbmVkJyxcbiAgICAgICAgICAgICAgICAgJ2NsaWVudF9kaWZmX3NoYTI1NicsICduYXRpdmVfcm9sbG91dF92ZXJpZmllZCcsICdjdXJyZW50X3NjaGVtYTVfZGF0YWJhc2VfcmV0YWluZWQnLFxuICAgICAgICAgICAgICAgICAncHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJywgJ2luc3RhbGxlZF9wdXJwb3NlX2NoZWNrcycsICdwb2xpY3lfc2hhMjU2JyxcbiAgICAgICAgICAgICAgICAgJ3BvbGljeV9tb2RlJywgJ3BvbGljeV91aWQnLCAnaGVhbHRoX3N0YXR1c2VzJywgJ25hdGl2ZV9wcm92aWRlcl9wcm9iZScsICdyZWNvdmVyeV92ZXJpZmljYXRpb24nfVxuICAgIHJlcXVpcmUoc2V0KHZhbHVlKSA8PSBwZXJtaXR0ZWQsICd1bmV4cGVjdGVkIG91dHB1dCBmaWVsZHMgd2l0aGhlbGQnKVxuICAgIGZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuICAgIGZvciBuYW1lIGluICgnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lJywgJ3NuYXBzaG90X3JlYWRvbmx5JywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIGNvdW50cyh2YWx1ZVtuYW1lXSlcbiAgICBmb3IgbmFtZSBpbiAoJ3NuYXBzaG90X3NoYTI1NicsICdjbGllbnRfZGlmZl9zaGEyNTYnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOV17NjR9JywgdmFsdWVbbmFtZV0pIGlzIG5vdCBOb25lLCAnaW52YWxpZCBvdXRwdXQgZGlnZXN0IHdpdGhoZWxkJylcbiAgICBpZiAnc25hcHNob3RfYnl0ZXMnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHR5cGUodmFsdWVbJ3NuYXBzaG90X2J5dGVzJ10pIGlzIGludCBhbmQgMCA8IHZhbHVlWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAnaW52YWxpZCBvdXRwdXQgc2l6ZSB3aXRoaGVsZCcpXG4gICAgaWYgJ3NuYXBzaG90X2ZpbGUnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHZhbHVlWydzbmFwc2hvdF9maWxlJ10gaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSwgJ2ludmFsaWQgb3V0cHV0IGZpbGUgd2l0aGhlbGQnKVxuICAgIHJldHVybiB2YWx1ZVxuXG5cbmRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTEyMCk6XG4gICAgcmV0dXJuIHJ1bihbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVF0gKyBhcmd2LFxuICAgICAgICAgICAgICAgYm9keT1ib2R5LCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkLCBzbmFwc2hvdF9pZGVudGl0eT1Ob25lKTpcbiAgICAjIEZpeGVkIG1vZHVsZSBpbXBvcnRlZCBvbmx5IGFmdGVyIG1haW4gdmVyaWZpZXMgZXZlcnkgZXhlY3V0b3Igc291cmNlIGhhc2guXG4gICAgZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuICAgIHBheWxvYWQgPSB7J3NuYXBzaG90X2lkZW50aXR5Jzogc25hcHNob3RfaWRlbnRpdHksICdwaGFzZSc6IHBoYXNlLCAnc291cmNlX3JldmlzaW9uJzogcmV2aXNpb24sICdhcHByb3ZhbCc6IGFwcHJvdmVkLFxuICAgICAgICAgICAgICAgJ3NlYWxlZCc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ2RlcGVuZGVuY2llcyc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLW5hdGl2ZS1kZXBlbmRlbmNpZXMuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdjYW5kaWRhdGUnOiBqc29uLmxvYWRzKChDQVNFIC8gJ2NhbmRpZGF0ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdyZWNlaXB0X3NhZmV0eSc6IChST09UIC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCksXG4gICAgICAgICAgICAgICAncHVycG9zZV9jaGVja3MnOiAoQ0FTRSAvICdjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICdyZWFkb25seSc6IChDQVNFIC8gJ3NxbGl0ZV9yZWFkb25seS5weScpLnJlYWRfdGV4dCgpfVxuICAgIHNjcmlwdCA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAnX19HVUFSRF9fJywgcmVwcigoQ0FTRSAvICdjaGFuZ2VfZ3VhcmQucHknKS5yZWFkX3RleHQoKSkpXG4gICAgcmV0dXJuIGpzb25fcmVzdWx0KHJ1bihbJ3NzaCcsICdyYWlsaWFuY2UwMScsICdweXRob24zIC0nXSwgc2NyaXB0LCB0aW1lb3V0PTIwMCkpXG5cblxuZGVmIGNvcHlfc25hcHNob3QocGhhc2UsIHJldmlzaW9uLCBhcHByb3ZlZCwgam91cm5hbCk6XG4gICAgcHJpb3IgPSAoam91cm5hbC5kYXRhWydpZGVudGl0eSddWydyZWNvdmVyeV9hbmNob3InXVsnYmFja3VwX3Jlc3VsdCddXG4gICAgICAgICAgICAgaWYgcGhhc2UgPT0gJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyBlbHNlIGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2N1dG92ZXItYmFja3VwJ11bJ3Jlc3VsdCddKVxuICAgIG1ldGFkYXRhID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIGZvciBrZXkgaW4gKCdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICdzbmFwc2hvdF9yZWFkb25seScpOlxuICAgICAgICByZXF1aXJlKG1ldGFkYXRhW2tleV0gPT0gcHJpb3Jba2V5XSwgJ2Nsb3NlZCBmcm96ZW4gc25hcHNob3QgY2hhbmdlZCcpXG4gICAgbmFtZSA9IG1ldGFkYXRhWydzbmFwc2hvdF9maWxlJ11cbiAgICByZXF1aXJlKG5hbWUgaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSBhbmQgMCA8IG1ldGFkYXRhWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICdmaXhlZCBib3VuZGVkIHNuYXBzaG90IHJlcXVpcmVkJylcbiAgICBwb2QgPSBtZXRhZGF0YVsncG9kX25hbWUnXVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtejAtOV0oWy1hLXowLTldKlthLXowLTldKT8nLCBwb2QpIGlzIG5vdCBOb25lLCAnZml4ZWQgb3duZXIgcG9kIG5hbWUgcmVxdWlyZWQnKVxuICAgIGxvY2FsID0gQ1VTVE9EWSAvIG5hbWVcbiAgICBmZCA9IG9zLm9wZW4obG9jYWwsIG9zLk9fV1JPTkxZIHwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1csIDBvNjAwKVxuICAgICMgQmluYXJ5IHNuYXBzaG90IHN0ZG91dCBnb2VzIG9ubHkgdG8gYSBwcml2YXRlIGZpbGUsIG5ldmVyIHRvb2wvY2hhdC9sb2cgb3V0cHV0LlxuICAgICMgU25hcHNob3Qgc2NoZW1hL2NvdW50IG1ldGFkYXRhIHdhcyB2YWxpZGF0ZWQgYmVmb3JlIG9wZW5pbmcgdGhpcyBkZXN0aW5hdGlvbi5cbiAgICB3aXRoIG9zLmZkb3BlbihmZCwgJ3diJykgYXMgZGVzdGluYXRpb246XG4gICAgICAgIGNvbW1hbmQgPSAoJ2t1YmVjdGwgZXhlYyAtbiBpbmZvcm1lZC1kZWNpc2lvbiAnICsgcG9kICtcbiAgICAgICAgICAgICAgICAgICAnIC1jIGluZm9ybWVkLWRlY2lzaW9uIC0tIGNhdCAvZGF0YS9wcml2YXRlL3B1cnBvc2Utb3ZlcmxheS1yMS8nICsgbmFtZSlcbiAgICAgICAgdHJhbnNmZXIgPSBzdWJwcm9jZXNzLlBvcGVuKFsnc3NoJywgJ3JhaWxpYW5jZTAxJywgY29tbWFuZF0sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRlcnI9c3VicHJvY2Vzcy5ERVZOVUxMKVxuICAgICAgICBzZWxlY3RvciA9IHNlbGVjdG9ycy5EZWZhdWx0U2VsZWN0b3IoKVxuICAgICAgICBzZWxlY3Rvci5yZWdpc3Rlcih0cmFuc2Zlci5zdGRvdXQsIHNlbGVjdG9ycy5FVkVOVF9SRUFEKVxuICAgICAgICBkZWFkbGluZSA9IHRpbWUubW9ub3RvbmljKCkgKyAxNTBcbiAgICAgICAgcmVjZWl2ZWQgPSAwXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdoaWxlIFRydWU6XG4gICAgICAgICAgICAgICAgcmVtYWluaW5nID0gZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZW1haW5pbmcgPiAwIGFuZCBzZWxlY3Rvci5zZWxlY3QocmVtYWluaW5nKSwgJ3ByaXZhdGUgdHJhbnNmZXIgdGltZWQgb3V0JylcbiAgICAgICAgICAgICAgICBibG9jayA9IG9zLnJlYWQodHJhbnNmZXIuc3Rkb3V0LmZpbGVubygpLCAxMDI0KioyKVxuICAgICAgICAgICAgICAgIGlmIG5vdCBibG9jazpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICByZWNlaXZlZCArPSBsZW4oYmxvY2spXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZWNlaXZlZCA8PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXSBhbmQgcmVjZWl2ZWQgPD0gTUFYX0JZVEVTLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3ByaXZhdGUgY29weSBleGNlZWRzIGZyb3plbiBzbmFwc2hvdCBzaXplJylcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbi53cml0ZShibG9jaylcbiAgICAgICAgICAgIHRyYW5zZmVyLndhaXQodGltZW91dD1tYXgoMSwgZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpKSlcbiAgICAgICAgZmluYWxseTpcbiAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKClcbiAgICAgICAgICAgIHRyYW5zZmVyLnN0ZG91dC5jbG9zZSgpXG4gICAgICAgICAgICBpZiB0cmFuc2Zlci5wb2xsKCkgaXMgTm9uZTpcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci5raWxsKClcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci53YWl0KClcbiAgICAgICAgZGVzdGluYXRpb24uZmx1c2goKVxuICAgICAgICBvcy5mc3luYyhkZXN0aW5hdGlvbi5maWxlbm8oKSlcbiAgICBwcml2YXRlKGxvY2FsKVxuICAgIHJlcXVpcmUodHJhbnNmZXIucmV0dXJuY29kZSA9PSAwIGFuZCBsb2NhbC5zdGF0KCkuc3Rfc2l6ZSA9PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIHNoYShsb2NhbCkgPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLCAncHJpdmF0ZSBjb3B5IGluY29tcGxldGUvdW5jZXJ0YWluOyByZXRhaW4sIG5vIHJldHJ5JylcbiAgICAjIFJlLXJlYWQgaWRlbnRpdHkvaGFzaCBhZnRlciB0cmFuc2Zlci4gVGhpcyBpcyB2ZXJpZmljYXRpb24sIG5vdCBhIHdyaXRlIHJldHJ5LlxuICAgIGFmdGVyID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIHJlcXVpcmUoYWZ0ZXJbJ3BvZF91aWQnXSA9PSBtZXRhZGF0YVsncG9kX3VpZCddIGFuZCBhZnRlclsnc25hcHNob3Rfc2hhMjU2J10gPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLFxuICAgICAgICAgICAgJ3NvdXJjZSBpZGVudGl0eS9zbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyB0cmFuc2ZlcicpXG4gICAgcmV0dXJuIHsqKm1ldGFkYXRhLCAnb2ZmX2NsdXN0ZXJfcHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJzogVHJ1ZSwgJ3NuYXBzaG90X2NvbnRlbnRzX291dHB1dCc6IEZhbHNlfVxuXG5cbmRlZiBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKTpcbiAgICBmcm9tIHJlY2VpcHRfc2FmZXR5IGltcG9ydCBjb3VudHNcbiAgICBzbmFwc2hvdCA9IENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJ1xuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcHJldmlvdXMgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydyZXN1bHQnXVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdwcm90ZWN0ZWQgc25hcHNob3QgYnl0ZXMgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgcmVxdWlyZShpZGVudGl0eS5yZXR1cm5jb2RlID09IDAgYW5kIGpzb24ubG9hZHMoaWRlbnRpdHkuc3Rkb3V0KSA9PSAnYm50LWxhcDAwMScsXG4gICAgICAgICAgICAnbG9jYWwgb2ZmbGluZSBEb2NrZXIgZW5naW5lIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICByZXF1aXJlKGxpc3RlZC5yZXR1cm5jb2RlID09IDAgYW5kIFZPTFVNRSBub3QgaW4gbGlzdGVkLnN0ZG91dC5zcGxpdGxpbmVzKCksXG4gICAgICAgICAgICAnZGlzcG9zYWJsZSB2b2x1bWUgYWJzZW5jZSBub3QgdmVyaWZpZWQnKVxuICAgIG5vbmNlID0gam91cm5hbC5kYXRhWydwaGFzZXMnXVsnb2ZmbGluZS12ZXJpZnknXVsnYXR0ZW1wdF9pZCddXG4gICAgbGFiZWxzID0geydpbmZvcm1lZC1kZWNpc2lvbi5jYXNlJzogJ2luZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsXG4gICAgICAgICAgICAgICdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOiAnb2ZmbGluZS1yZXN0b3JlLW9ubHknLCAnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdCc6IG5vbmNlfVxuICAgIGNyZWF0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnY3JlYXRlJywgJy0tZHJpdmVyJywgJ2xvY2FsJywgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24uY2FzZT1pbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQ9JyArIG5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLnVzZT1vZmZsaW5lLXJlc3RvcmUtb25seScsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShjcmVhdGVkLnJldHVybmNvZGUgPT0gMCBhbmQgY3JlYXRlZC5zdGRvdXQuc3RyaXAoKSA9PSBWT0xVTUUsICd2b2x1bWUgY3JlYXRpb24gdW5jZXJ0YWluOyBubyByZXRyeScpXG4gICAgaW5zcGVjdGVkID0gZG9ja2VyKFsndm9sdW1lJywgJ2luc3BlY3QnLCBWT0xVTUVdKVxuICAgIHJlcXVpcmUoaW5zcGVjdGVkLnJldHVybmNvZGUgPT0gMCwgJ25ldyB2b2x1bWUgaWRlbnRpdHkgdW5hdmFpbGFibGUnKVxuICAgIHZvbHVtZSA9IGpzb24ubG9hZHMoaW5zcGVjdGVkLnN0ZG91dClcbiAgICByZXF1aXJlKGxlbih2b2x1bWUpID09IDEgYW5kIHZvbHVtZVswXVsnTmFtZSddID09IFZPTFVNRSBhbmQgdm9sdW1lWzBdLmdldCgnTGFiZWxzJykgPT0gbGFiZWxzXG4gICAgICAgICAgICBhbmQgdm9sdW1lWzBdLmdldCgnRHJpdmVyJykgPT0gJ2xvY2FsJyBhbmQgbm90IHZvbHVtZVswXS5nZXQoJ09wdGlvbnMnKVxuICAgICAgICAgICAgYW5kIHZvbHVtZVswXS5nZXQoJ1Njb3BlJykgPT0gJ2xvY2FsJywgJ25ldyBpc29sYXRlZCB2b2x1bWUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSB7a2V5OiB2b2x1bWVbMF1ba2V5XSBmb3Iga2V5IGluICgnTmFtZScsICdMYWJlbHMnLCAnRHJpdmVyJywgJ1Njb3BlJywgJ0NyZWF0ZWRBdCcpfVxuICAgIGpvdXJuYWwubm90ZSgnb2ZmbGluZS12ZXJpZnknLCAnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknLCBpZGVudGl0eSlcbiAgICAjIE9uZS10aW1lIFVJRDAvQ0FQX0NIT1dOIGluaXRpYWxpemF0aW9uIGlzIGlzb2xhdGVkIHRvIHRoZSBORVcgbmFtZWQgdm9sdW1lLlxuICAgICMgTm8gaG9zdC9saXZlIFBWQy9jb25maWcvdG9rZW4gbW91bnQgZXhpc3RzOyB0aGlzIGRldGFpbCBuZWVkcyBwYWNrZXQgcmV2aWV3LlxuICAgIGluaXRpYWxpemVyID0gXCJcIlwiaW1wb3J0IGhhc2hsaWIsb3Msc3RhdCxzeXNcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkJylcbmZvbGRlcj0nL3Jlc3RvcmUnO2V4cGVjdGVkPUVYUEVDVEVEXG5pZiBvcy5saXN0ZGlyKGZvbGRlcik6cmFpc2UgVmFsdWVFcnJvcignbmV3IGVtcHR5IHByaXZhdGUgdm9sdW1lIHJlcXVpcmVkJylcbm9zLmNobW9kKGZvbGRlciwwbzcwMClcbmZkPW9zLm9wZW4oZm9sZGVyKycvcmV2aWV3LnNxbGl0ZScsb3MuT19DUkVBVHxvcy5PX0VYQ0x8b3MuT19OT0ZPTExPV3xvcy5PX1dST05MWSwwbzYwMClcbmRpZ2VzdD1oYXNobGliLnNoYTI1NigpO3NpemU9MFxud2l0aCBvcy5mZG9wZW4oZmQsJ3diJykgYXMgdGFyZ2V0OlxuIHdoaWxlIFRydWU6XG4gIGJsb2NrPXN5cy5zdGRpbi5idWZmZXIucmVhZCgxMDI0KioyKVxuICBpZiBub3QgYmxvY2s6YnJlYWtcbiAgc2l6ZSs9bGVuKGJsb2NrKVxuICBpZiBzaXplPjUxMioxMDI0KioyOnJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgcmVzdG9yZSBzaXplIGV4Y2VlZHMgYm91bmQnKVxuICB0YXJnZXQud3JpdGUoYmxvY2spO2RpZ2VzdC51cGRhdGUoYmxvY2spXG4gdGFyZ2V0LmZsdXNoKCk7b3MuZnN5bmModGFyZ2V0LmZpbGVubygpKVxuaWYgZGlnZXN0LmhleGRpZ2VzdCgpIT1leHBlY3RlZDpyYWlzZSBWYWx1ZUVycm9yKCdwcml2YXRlIGNvcGllZCBzbmFwc2hvdCBkaWZmZXJzJylcbm9zLmNob3duKGZvbGRlcisnL3Jldmlldy5zcWxpdGUnLDEwMDAxLDEwMDAxKTtvcy5jaG93bihmb2xkZXIsMTAwMDEsMTAwMDEpXG5wcmludCgne1wiYWxsX2NoZWNrc19wYXNzXCI6dHJ1ZSxcInByaXZhdGVfY29weV92ZXJpZmllZFwiOnRydWV9JylcblwiXCJcIi5yZXBsYWNlKCdFWFBFQ1RFRCcsIHJlcHIocHJldmlvdXNbJ3NuYXBzaG90X3NoYTI1NiddKSlcbiAgICB3aXRoIHNuYXBzaG90Lm9wZW4oJ3JiJykgYXMgc291cmNlOlxuICAgICAgICBhcmd2ID0gWydkb2NrZXInLCAnLS1jb25maWcnLCBzdHIoQ1VTVE9EWSAvICdlbXB0eS1kb2NrZXItY29uZmlnJyksICctLWhvc3QnLCBTT0NLRVQsXG4gICAgICAgICAgICAgICAgJ3J1bicsICctLXJtJywgJy1pJywgJy0tbmV0d29yaycsICdub25lJywgJy0tcmVhZC1vbmx5JywgJy0tY3B1cycsICcxJywgJy0tbWVtb3J5JywgJzEyOG0nLFxuICAgICAgICAgICAgICAgICctLXVzZXInLCAnMDowJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tY2FwLWFkZCcsICdDSE9XTicsXG4gICAgICAgICAgICAgICAgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJywgJy0tbW91bnQnLCAndHlwZT12b2x1bWUsc3JjPScgKyBWT0xVTUUgKyAnLGRzdD0vcmVzdG9yZScsXG4gICAgICAgICAgICAgICAgJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy1jJywgaW5pdGlhbGl6ZXJdXG4gICAgICAgIGNvcGllZCA9IHN1YnByb2Nlc3MucnVuKGFyZ3YsIHN0ZGluPXNvdXJjZSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PTE1MClcbiAgICBqc29uX3Jlc3VsdChjb3BpZWQpXG4gICAgb3B0aW9ucyA9IFsncnVuJywgJy0tcm0nLCAnLWknLCAnLS1uZXR3b3JrJywgJ25vbmUnLCAnLS1yZWFkLW9ubHknLCAnLS1jcHVzJywgJzEnLCAnLS1tZW1vcnknLCAnMTI4bScsXG4gICAgICAgICAgICAgICAnLS11c2VyJywgJzEwMDAxOjEwMDAxJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJyxcbiAgICAgICAgICAgICAgICctLW1vdW50JywgJ3R5cGU9dm9sdW1lLHNyYz0nICsgVk9MVU1FICsgJyxkc3Q9L3Jlc3RvcmUnXVxuICAgIHJlYWRvbmx5ID0gZG9ja2VyKG9wdGlvbnMgKyBbJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy0nLCAnLS1kYicsICcvcmVzdG9yZS9yZXZpZXcuc3FsaXRlJ10sXG4gICAgICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShyZWFkb25seS5yZXR1cm5jb2RlID09IDAsICdvZmZsaW5lIHByZS1vcGVuIHNjaGVtYS9pbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkOyBuZXZlciBvcGVuIFN0b3JlJylcbiAgICBjaGVja2VkID0gY291bnRzKGpzb24ubG9hZHMocmVhZG9ubHkuc3Rkb3V0KSlcbiAgICByZXF1aXJlKGNoZWNrZWQgPT0gcHJldmlvdXNbJ3NuYXBzaG90X3JlYWRvbmx5J10sICdmcm96ZW4gc25hcHNob3QvY2xvbmUgcmVhZG9ubHkgY291bnRzIGRpZmZlcicpXG4gICAgYWRtaW4gPSBkb2NrZXIob3B0aW9ucyArIFsnLS1lbnRyeXBvaW50JywgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJywgSU1BR0UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaW5zcGVjdCcsICctLWRiJywgJy9yZXN0b3JlL3Jldmlldy5zcWxpdGUnXSlcbiAgICByZXF1aXJlKGFkbWluLnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgYWRtaW4gcmVzdWx0IHVuY2VydGFpbicpXG4gICAgYWRtaW5fY291bnRzID0ganNvbi5sb2FkcyhhZG1pbi5zdGRvdXQpXG4gICAgcmVxdWlyZShhZG1pbl9jb3VudHMgPT0ge2tleTogY2hlY2tlZFtrZXldIGZvciBrZXkgaW4gKCdzY2hlbWFfdmVyc2lvbicsICdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyl9LFxuICAgICAgICAgICAgJ29mZmxpbmUgYWRtaW4gY2hhbmdlZCBmcm96ZW4gc25hcHNob3QgY291bnRlcnMnKVxuICAgICMgQWRtaW4gU3RvcmUgY29uc3RydWN0aW9uIG11c3Qgbm90IHNpbGVudGx5IGFsdGVyIHNjaGVtYS9pbnRlZ3JpdHkvY291bnRlcnMuXG4gICAgcG9zdCA9IGRvY2tlcihvcHRpb25zICsgWyctLWVudHJ5cG9pbnQnLCAncHl0aG9uJywgSU1BR0UsICctJywgJy0tZGInLCAnL3Jlc3RvcmUvcmV2aWV3LnNxbGl0ZSddLFxuICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShwb3N0LnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgcG9zdC1hZG1pbiByZWFkb25seSBpbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkJylcbiAgICBwb3N0X2NoZWNrZWQgPSBjb3VudHMoanNvbi5sb2Fkcyhwb3N0LnN0ZG91dCkpXG4gICAgcmVxdWlyZShwb3N0X2NoZWNrZWQgPT0gY2hlY2tlZCA9PSBwcmV2aW91c1snc25hcHNob3RfcmVhZG9ubHknXSxcbiAgICAgICAgICAgICdvZmZsaW5lIGFkbWluIGFsdGVyZWQgZnJvemVuIHNuYXBzaG90IHByb29mJylcbiAgICBwcml2YXRlKHNuYXBzaG90KVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdvcmlnaW5hbCBwcm90ZWN0ZWQgc25hcHNob3QgY2hhbmdlZCBkdXJpbmcgZHJpbGwnKVxuICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdvZmZsaW5lX3ZvbHVtZSc6IFZPTFVNRSwgJ29mZmxpbmVfcmVhZG9ubHknOiBjaGVja2VkLFxuICAgICAgICAgICAgJ29mZmxpbmVfcG9zdF9hZG1pbl9yZWFkb25seSc6IHBvc3RfY2hlY2tlZCwgJ29yaWdpbmFsX3NuYXBzaG90X2hhc2hfdW5jaGFuZ2VkJzogVHJ1ZSxcbiAgICAgICAgICAgICdjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eSc6IGlkZW50aXR5LFxuICAgICAgICAgICAgJ2FkbWluX2NvdW50cyc6IGFkbWluX2NvdW50cywgJ25ldHdvcmsnOiAnbm9uZScsICdydW50aW1lX3Rva2Vuc19vcl9jb25maWdfbW91bnRlZCc6IEZhbHNlLFxuICAgICAgICAgICAgJ3NlcnZpY2VfZW50cnlwb2ludF9zdGFydGVkJzogRmFsc2UsICdvcmlnaW5hbF9zbmFwc2hvdF9yZXRhaW5lZCc6IFRydWV9XG5cblxuZGVmIGNsZWFudXBfb2ZmbGluZShqb3VybmFsKTpcbiAgICBpbnNwZWN0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnaW5zcGVjdCcsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShpbnNwZWN0ZWQucmV0dXJuY29kZSA9PSAwLCAnb3duZWQgZGlzcG9zYWJsZSB2b2x1bWUgaWRlbnRpdHkgdW52ZXJpZmllZCcpXG4gICAgdmFsdWUgPSBqc29uLmxvYWRzKGluc3BlY3RlZC5zdGRvdXQpXG4gICAgZXhwZWN0ZWQgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydvZmZsaW5lLXZlcmlmeSddWydyZXN1bHQnXVsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknXVxuICAgIHJlcXVpcmUobGVuKHZhbHVlKSA9PSAxIGFuZCB7a2V5OiB2YWx1ZVswXS5nZXQoa2V5KSBmb3Iga2V5IGluIGV4cGVjdGVkfSA9PSBleHBlY3RlZFxuICAgICAgICAgICAgYW5kIG5vdCB2YWx1ZVswXS5nZXQoJ09wdGlvbnMnKSwgJ3ZvbHVtZSBvd25lcnNoaXAvcmVjcmVhdGlvbiBjaGFuZ2VkJylcbiAgICByZW1vdmVkID0gZG9ja2VyKFsndm9sdW1lJywgJ3JtJywgVk9MVU1FXSlcbiAgICByZXF1aXJlKHJlbW92ZWQucmV0dXJuY29kZSA9PSAwIGFuZCByZW1vdmVkLnN0ZG91dC5zdHJpcCgpID09IFZPTFVNRVxuICAgICAgICAgICAgYW5kIGRvY2tlcihbJ3ZvbHVtZScsICdpbnNwZWN0JywgVk9MVU1FXSkucmV0dXJuY29kZSAhPSAwLFxuICAgICAgICAgICAgJ2NsZWFudXAgb3V0Y29tZSBhbWJpZ3VvdXM7IGRvIG5vdCByZXRyeScpXG4gICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ29ubHlfZGlzcG9zYWJsZV9vZmZsaW5lX3ZvbHVtZV9yZW1vdmVkJzogVk9MVU1FLFxuICAgICAgICAgICAgJ25hdGl2ZV9hbmRfb2ZmY2x1c3Rlcl9vcmlnaW5hbF9zbmFwc2hvdHNfcmV0YWluZWQnOiBUcnVlfVxuXG5cbmRlZiBtYWluKCk6XG4gICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249X19kb2NfXylcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXBoYXNlJywgY2hvaWNlcz1QSEFTRVMsIHJlcXVpcmVkPVRydWUpXG4gICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1yb290LWF1dGhvcml0eS1yZWNlaXB0JywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tcm9vdC1uYXRpdmUtb3V0Y29tZScsIHR5cGU9UGF0aCwgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yZXZpc2lvbicsIHJlcXVpcmVkPVRydWUpXG4gICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKClcbiAgICByZXF1aXJlKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdCA9PSBQYXRoKCcvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1yb290LWF1dGhvcml0eS5qc29uJylcbiAgICAgICAgICAgIGFuZCBhcmdzLnJvb3RfbmF0aXZlX291dGNvbWUgPT0gUGF0aCgnL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2UtbmF0aXZlLW91dGNvbWUtbGF0ZXN0Lmpzb24nKSxcbiAgICAgICAgICAgICdmaXhlZCBzdXBlcnZpc2VkIHJlY2VpcHQgcGF0aHMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInWzAtOWEtZl17NDB9JywgYXJncy5zb3VyY2VfcmV2aXNpb24pIGlzIG5vdCBOb25lLCAnZXhhY3Qgc291cmNlIGNvbW1pdCByZXF1aXJlZCcpXG4gICAgIyBWZXJpZnkgYWxsIHByZXBhcmVkIGV4ZWN1dG9yL2lucHV0IGJ5dGVzIGJlZm9yZSByZWFkaW5nIGF1dGhvcml0eSBvciBkaXNwYXRjaGluZy5cbiAgICBwbGFuID0ganNvbi5sb2FkcygoUk9PVCAvICdleGVjdXRpb24tcGxhbi5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShzZXQocGxhblsnZXhlY3V0b3JfZmlsZXMnXSkgPT0geydhY3R1YXRvci5weScsICdhdXRob3JpdHlfam91cm5hbC5weScsICduYXRpdmVfcHJvZ3JhbS5weScsICdyZWNlaXB0X3NhZmV0eS5weSd9LFxuICAgICAgICAgICAgJ2ZpeGVkIGV4ZWN1dG9yIHNvdXJjZXMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUoc2V0KHBsYW5bJ293bmVyX3NvdXJjZV9maWxlcyddKSA9PSB7J2RlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL3JlZ2lzdHJpZXMuY2FuZGlkYXRlLmpzb24nfSxcbiAgICAgICAgICAgICdmaXhlZCBvd25lciBpbWFnZSBzb3VyY2VzIHJlcXVpcmVkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydleGVjdXRvcl9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHRhcmdldCA9IFJPT1QgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdleGVjdXRvciBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnY2FzZV9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUobm90IFBhdGgocmVsYXRpdmUpLmlzX2Fic29sdXRlKCkgYW5kICcuLicgbm90IGluIFBhdGgocmVsYXRpdmUpLnBhcnRzLFxuICAgICAgICAgICAgICAgICdjYXNlIHNvdXJjZSBwYXRoIGVzY2FwZWQnKVxuICAgICAgICB0YXJnZXQgPSBDQVNFIC8gcmVsYXRpdmVcbiAgICAgICAgcmVxdWlyZShub3QgdGFyZ2V0LmlzX3N5bWxpbmsoKSBhbmQgc2hhKHRhcmdldCkgPT0gZGlnZXN0LCAnY2FzZSBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgdGFyZ2V0ID0gT1dORVIgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdvd25lciBpbWFnZS1vbmx5IHNvdXJjZSBjaGFuZ2VkJylcbiAgICAgICAgY29tbWl0dGVkID0gc3VicHJvY2Vzcy5ydW4oWydnaXQnLCAnLUMnLCBzdHIoT1dORVIpLCAnc2hvdycsIGFyZ3Muc291cmNlX3JldmlzaW9uICsgJzonICsgcmVsYXRpdmVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlKVxuICAgICAgICByZXF1aXJlKGNvbW1pdHRlZC5yZXR1cm5jb2RlID09IDAgYW5kIGhhc2hsaWIuc2hhMjU2KGNvbW1pdHRlZC5zdGRvdXQpLmhleGRpZ2VzdCgpID09IGRpZ2VzdCxcbiAgICAgICAgICAgICAgICAnY29tbWl0dGVkIG93bmVyIHJlbmRlciBzb3VyY2UgZGlmZmVycyBmcm9tIGFwcHJvdmVkIGlucHV0cycpXG4gICAgaGVhZCA9IHJ1bihbJ2dpdCcsICctQycsIHN0cihPV05FUiksICdyZXYtcGFyc2UnLCAnSEVBRCddKVxuICAgIHJlcXVpcmUoaGVhZC5yZXR1cm5jb2RlID09IDAgYW5kIGhlYWQuc3Rkb3V0LnN0cmlwKCkgPT0gYXJncy5zb3VyY2VfcmV2aXNpb24sICdvd25lciBzb3VyY2UgSEVBRCBkaWZmZXJzJylcbiAgICBmcm9tIGF1dGhvcml0eV9qb3VybmFsIGltcG9ydCBKb3VybmFsLCBhdXRob3JpdHksIG9yaWdpbmFsX2FuY2hvclxuICAgIHByaXZhdGUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0KVxuICAgIHByaXZhdGUoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKVxuICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlY2VpcHQuZ2V0KCduYXRpdmVfb3V0Y29tZV9zaGEyNTYnKSA9PSBzaGEoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKSwgJ25hdGl2ZSBvdXRjb21lIGJ5dGVzIGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ2V4ZWN1dG9yX3BsYW5fc2hhMjU2JykgPT0gc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgJ3Jvb3QgdmVyaWZpZWQgZXhlY3V0b3IgcGxhbiBkaWZmZXJzJylcbiAgICBhcHByb3ZlZCA9IGF1dGhvcml0eShyZWNlaXB0LCBqc29uLmxvYWRzKGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZS5yZWFkX3RleHQoKSksIHNoYShDQVNFIC8gJ21lbW8uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcmdzLnBoYXNlKVxuICAgIHBhcmVudCA9IENVU1RPRFkucGFyZW50XG4gICAgcHJpdmF0ZShwYXJlbnQsIGRpcmVjdG9yeT1UcnVlKVxuICAgIGlnbm9yZWQgPSBydW4oWydnaXQnLCAnLUMnLCBzdHIoQ1VTVE9ESUFOKSwgJ2NoZWNrLWlnbm9yZScsICctLW5vLWluZGV4Jywgc3RyKENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJyldKVxuICAgIHJlcXVpcmUoaWdub3JlZC5yZXR1cm5jb2RlID09IDAsICdvZmZjbHVzdGVyIGN1c3RvZHkgaXMgbm90IGlnbm9yZWQnKVxuICAgIHJlcXVpcmUoQ1VTVE9EWS5leGlzdHMoKSwgJ29yaWdpbmFsIHByb3RlY3RlZCBjdXN0b2R5IG11c3QgYWxyZWFkeSBleGlzdCcpXG4gICAgcHJpdmF0ZShDVVNUT0RZLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICBjYXBhY2l0eSA9IG9zLnN0YXR2ZnMoQ1VTVE9EWSlcbiAgICByZXF1aXJlKGNhcGFjaXR5LmZfYmF2YWlsICogY2FwYWNpdHkuZl9mcnNpemUgPj0gMiAqIE1BWF9CWVRFUyArIDE2ICogMTAyNCoqMixcbiAgICAgICAgICAgICdpbmRlcGVuZGVudCBwcm90ZWN0ZWQgY3VzdG9keSBoZWFkcm9vbSBpbnN1ZmZpY2llbnQnKVxuICAgIG9zLm1ha2VkaXJzKENVU1RPRFkgLyAnZW1wdHktZG9ja2VyLWNvbmZpZycsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpXG4gICAgcHJpdmF0ZShDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICByZXF1aXJlKG5vdCBsaXN0KChDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKS5pdGVyZGlyKCkpLCAncHVibGljIERvY2tlciByZWFkIGNvbmZpZyBtdXN0IHN0YXkgZW1wdHknKVxuICAgIGFuY2hvciA9IG9yaWdpbmFsX2FuY2hvcihDVVNUT0RZLCBwbGFuWydyZWNvdmVyeSddWydvcmlnaW5hbF9hbmNob3InXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5sb2FkcygoQ0FTRSAvICdvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcbiAgICBpZiBhcmdzLnBoYXNlID09ICdkcmlsbC1jb3B5LXJlc2N1ZS1yMSc6XG4gICAgICAgIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXG4gICAgICAgICAgICAgICAgYW5kIG5vdCBvcy5wYXRoLmxleGlzdHMoQ1VTVE9EWSAvICdjdXRvdmVyLnNxbGl0ZScpLCAncmVzY3VlIGRlc3RpbmF0aW9uIG11c3QgYmUgYWJzZW50JylcbiAgICAgICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgICAgIHJlcXVpcmUoaWRlbnRpdHkucmV0dXJuY29kZSA9PSAwIGFuZCBqc29uLmxvYWRzKGlkZW50aXR5LnN0ZG91dCkgPT0gJ2JudC1sYXAwMDEnLFxuICAgICAgICAgICAgICAgICdsb2NhbCBlbmdpbmUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICAgICAgcmVxdWlyZShsaXN0ZWQucmV0dXJuY29kZSA9PSAwIGFuZCBWT0xVTUUgbm90IGluIGxpc3RlZC5zdGRvdXQuc3BsaXRsaW5lcygpLFxuICAgICAgICAgICAgICAgICdleGlzdGluZyByZXN0b3JlIHZvbHVtZSBmb3JiaWRzIHJlc2N1ZScpXG4gICAgam91cm5hbCA9IEpvdXJuYWwoQ1VTVE9EWSwgeydwcm9wb3NhbCc6IHBsYW5bJ3Byb3Bvc2FsX2lkJ10sICdzb3VyY2VfcmV2aXNpb24nOiBhcmdzLnNvdXJjZV9yZXZpc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWVtb19zaGEyNTYnOiBzaGEoQ0FTRSAvICdtZW1vLmpzb24nKSwgJ3BsYW5fc2hhMjU2Jzogc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZWNvdmVyeV9hbmNob3InOiBhbmNob3J9KVxuICAgIHRyeTpcbiAgICAgICAgam91cm5hbC5zdGFydChhcmdzLnBoYXNlLCBhcHByb3ZlZCkgIyBmc3luY2VkIFJVTk5JTkcgYmVmb3JlIGFueSBwaGFzZSBlZmZlY3QuXG4gICAgICAgIGlmIGFyZ3MucGhhc2UgaW4gKCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsICdjdXRvdmVyLWNvcHknKTpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNvcHlfc25hcHNob3QoYXJncy5waGFzZSwgYXJncy5zb3VyY2VfcmV2aXNpb24sIGFwcHJvdmVkLCBqb3VybmFsKVxuICAgICAgICBlbGlmIGFyZ3MucGhhc2UgPT0gJ29mZmxpbmUtdmVyaWZ5JzpcbiAgICAgICAgICAgIHJlc3VsdCA9IG9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgIGVsaWYgYXJncy5waGFzZSA9PSAnY2xlYW51cC1vZmZsaW5lJzpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNsZWFudXBfb2ZmbGluZShqb3VybmFsKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgcmVzdWx0ID0gcmVtb3RlKGFyZ3MucGhhc2UsIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcHByb3ZlZClcbiAgICAgICAgcmVxdWlyZShvcmlnaW5hbF9hbmNob3IoQ1VTVE9EWSwgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubG9hZHMoKENBU0UgLyAnb3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtYmFja3VwLmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYW5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10pID09IGFuY2hvcixcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkIGpvdXJuYWwgY2hhbmdlZCBkdXJpbmcgbmV3IHBoYXNlJylcbiAgICAgICAgam91cm5hbC5maW5pc2goYXJncy5waGFzZSwgcmVzdWx0KVxuICAgICAgICBwcmludChqc29uLmR1bXBzKHJlc3VsdCkpICMgT25seSBjb3VudC9oYXNoL2lkZW50aXR5IHJlY2VpcHRzLCBuZXZlciBzbmFwc2hvdCBieXRlcy5cbiAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICAgICAgc2FmZSA9IHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdwaGFzZSc6IGFyZ3MucGhhc2UsICdmYWlsdXJlX2NsYXNzJzogdHlwZShlcnJvcikuX19uYW1lX18sXG4gICAgICAgICAgICAgICAgJ2ZhaWx1cmUnOiAnZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeScsXG4gICAgICAgICAgICAgICAgJ3Jhd19vdXRwdXRfd2l0aGhlbGQnOiBUcnVlfVxuICAgICAgICBpZiBqb3VybmFsLmRhdGFbJ3BoYXNlcyddLmdldChhcmdzLnBoYXNlLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdSVU5OSU5HJzpcbiAgICAgICAgICAgIGpvdXJuYWwuZmluaXNoKGFyZ3MucGhhc2UsIHNhZmUpXG4gICAgICAgIHByaW50KGpzb24uZHVtcHMoc2FmZSkpXG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoMSkgZnJvbSBOb25lXG4gICAgZmluYWxseTpcbiAgICAgICAgam91cm5hbC5jbG9zZSgpXG5cblxuaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzpcbiAgICB0cnk6XG4gICAgICAgIG1haW4oKVxuICAgIGV4Y2VwdCBFeGNlcHRpb246XG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoJ3N1cGVydmlzZWQgZXhlY3V0aW9uIHJlZnVzZWQgYmVmb3JlIHBoYXNlOyByYXcgb3V0cHV0IHdpdGhoZWxkJykgZnJvbSBOb25lXG4iCiAgICB9LAogICAgImF1dGhvcml0eV9qb3VybmFsLnB5IjogewogICAgICAic2hhMjU2IjogIjA1MzU5NzVhZTYzMTIxOWY5MGZjZTdlNTJmOGI1NGU2MWU4YWZkNGVmNjhiYjc0NzM4NjM0NzhmMGY1MTlmNjgiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTdXBlcnZpc2VkIHJlY2VpcHQgYm9va2tlZXBpbmcsIG5vdCBhbiBhdXRoZW50aWNhdGVkIGFwcHJvdmFsIHByb3ZpZGVyLlwiXCJcIlxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgZmNudGxcbmltcG9ydCBoYXNobGliXG5pbXBvcnQganNvblxuaW1wb3J0IG9zXG5pbXBvcnQgcmVcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN0YXRcbmltcG9ydCB1dWlkXG5cbkZPVU5ERVIgPSB7J2tpbmQnOiAncGVyc29uJywgJ3N1Yic6ICd1aWQ9cGxhdGZvcm0tcm9vdCxvdT1wZW9wbGUsZGM9bmV0a2luZ2RvbSxkYz1sb2NhbCd9XG5NRU1PX0lEID0gJ2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxJ1xuUFJPUE9TQUwgPSAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnXG5QSEFTRVMgPSAoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywgJ29mZmxpbmUtdmVyaWZ5JywgJ2NsZWFudXAtb2ZmbGluZScsXG4gICAgICAgICAgJ2N1dG92ZXItYmFja3VwJywgJ2N1dG92ZXItY29weScsICdyZWxlYXNlJywgJ3ZlcmlmeScsICdyb2xsYmFjaycsICdyb2xsYmFjay12ZXJpZnknKVxuXG5cbmRlZiByZXF1aXJlKHZhbHVlLCByZWFzb24pOlxuICAgIGlmIG5vdCB2YWx1ZTpcbiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcihyZWFzb24pXG5cblxuZGVmIHNoYShwYXRoKTpcbiAgICBkaWdlc3QgPSBoYXNobGliLnNoYTI1NigpXG4gICAgd2l0aCBQYXRoKHBhdGgpLm9wZW4oJ3JiJykgYXMgc3RyZWFtOlxuICAgICAgICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6IHN0cmVhbS5yZWFkKDEwMjQqKjIpLCBiJycpOlxuICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZShibG9jaylcbiAgICByZXR1cm4gZGlnZXN0LmhleGRpZ2VzdCgpXG5cblxuZGVmIHByaXZhdGUocGF0aCwgZGlyZWN0b3J5PUZhbHNlKTpcbiAgICBpbmZvID0gUGF0aChwYXRoKS5sc3RhdCgpXG4gICAgcmVxdWlyZSgoc3RhdC5TX0lTRElSKGluZm8uc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKGluZm8uc3RfbW9kZSkpXG4gICAgICAgICAgICBhbmQgaW5mby5zdF91aWQgPT0gb3MuZ2V0dWlkKCkgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpID09ICgwbzcwMCBpZiBkaXJlY3RvcnkgZWxzZSAwbzYwMClcbiAgICAgICAgICAgIGFuZCAoZGlyZWN0b3J5IG9yIGluZm8uc3RfbmxpbmsgPT0gMSksICdwcml2YXRlIG93bmVkIGN1c3RvZHkgcmVxdWlyZWQnKVxuXG5cbmRlZiBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgbWVtb19zaGEsIHNvdXJjZV9yZXZpc2lvbiwgcGhhc2UsIG5vdz1Ob25lKTpcbiAgICBcIlwiXCJSb290IG11c3QgZnJlc2hseSB2ZXJpZnkgbmF0aXZlIG91dGNvbWUgYXQgZml4ZWQgT1JJR0lOIG91dHNpZGUgdGhpcyBoZWxwZXIuXG5cbiAgICBSZWNlaXB0IGZpbGVzL2ZsYWdzIGFyZSBub3Qgc2lnbmVkIGdyYW50cy4gVGhpcyBmdW5jdGlvbiBjaGVja3MgdGhlIGV4YWN0XG4gICAgc3VwZXJ2aXNlZCByZWNlaXB0IHJlbGF0aW9uOyBleGlzdGluZyBoYXJuZXNzL2ZvdW5kZXIgYXV0aG9yaXR5IHJlbWFpbnMgdGhlXG4gICAgYWN0dWFsIHBlcm1pc3Npb24gYm91bmRhcnkuIEl0IG5ldmVyIGF1dGhlbnRpY2F0ZXMgYSBjYWxsZXIgYXMgaHVtYW4uXG4gICAgXCJcIlwiXG4gICAgbm93ID0gbm93IG9yIGRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpXG4gICAgcmVxdWlyZShwaGFzZSBpbiBQSEFTRVMsICdmaXhlZCBwaGFzZSByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShyZWNlaXB0LmdldCgncHJvcG9zYWxfaWQnKSA9PSBQUk9QT1NBTCBhbmQgcmVjZWlwdC5nZXQoJ21lbW9faWQnKSA9PSBNRU1PX0lEXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ21lbW9fdmVyc2lvbicpID09IDIgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX3NoYTI1NicpID09IG1lbW9fc2hhXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3NvdXJjZV9yZXZpc2lvbicpID09IHNvdXJjZV9yZXZpc2lvblxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhY3RpdmF0aW9uJykgPT0gJ0FQUFJPVkVEJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhdXRob3JpdHlfbW9kZScpID09ICdBRE1JTklTVEVSJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCd0YXJnZXQnKSA9PSAncmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbidcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgndmVyaWZpY2F0aW9uX21ldGhvZCcpID09ICdyb290LWZpeGVkLW9yaWdpbi1uYXRpdmUtcmVhZGJhY2snXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3J1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudCcpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ291dGNvbWVfcXVlcnknKSA9PSAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgJ2V4YWN0IGV4dGVybmFsbHkgdmVyaWZpZWQgc3VwZXJ2aXNlZCByZWNlaXB0IHJlcXVpcmVkJylcbiAgICB2ZXJpZmllZCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQocmVjZWlwdFsndmVyaWZpZWRfYXQnXS5yZXBsYWNlKCdaJywgJyswMDowMCcpKVxuICAgIHJlcXVpcmUodmVyaWZpZWQudHppbmZvIGlzIG5vdCBOb25lIGFuZCAwIDw9IChub3cgLSB2ZXJpZmllZCkudG90YWxfc2Vjb25kcygpIDw9IDEyMCxcbiAgICAgICAgICAgICdmcmVzaCByb290IG5hdGl2ZSByZWFkYmFjayByZXF1aXJlZCBiZWZvcmUgZXZlcnkgcGhhc2UnKVxuICAgIGRlYWRsaW5lID0gZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdCgnMjAyNi0xMC0xMlQyMzo1OTo1OSswMDowMCcpXG4gICAgcmVxdWlyZShub3cgPCBkZWFkbGluZSwgJ2FwcHJvdmVkIGV4ZWN1dGlvbiB3aW5kb3cgZXhwaXJlZCcpXG4gICAgcmVxdWlyZShvdXRjb21lLmdldCgnbWVtb19pZCcpID09IE1FTU9fSUQgYW5kIG91dGNvbWUuZ2V0KCdyZXZpZXcnLCB7fSkuZ2V0KCdzdGFsZScpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgb3V0Y29tZVsncmV2aWV3J10uZ2V0KCdpbnRha2Vfc3RhdGUnKSA9PSAncmVhZHknLCAnbmF0aXZlIHJldmlldyBpcyBub3QgcmVhZHkvY3VycmVudCcpXG4gICAgcmV2aWV3X2lkID0gb3V0Y29tZVsncmV2aWV3J11bJ21lbW9faWQnXVxuICAgIHJlcXVpcmUocmV2aWV3X2lkID09IHJlY2VpcHQuZ2V0KCdyZXZpZXdfbWVtb19pZCcpLCAnbmF0aXZlIHJldmlldyBpZGVudGl0eSBjaGFuZ2VkJylcbiAgICBhY2NlcHRlZCA9IFt4IGZvciB4IGluIG91dGNvbWUuZ2V0KCdkaXNwb3NpdGlvbnMnLCBbXSlcbiAgICAgICAgICAgICAgICBpZiB4LmdldCgnc3VibWlzc2lvbl9zdGF0ZScpID09ICdjb25maXJtZWQnXG4gICAgICAgICAgICAgICAgYW5kIHguZ2V0KCdkaXNwb3NpdGlvbicsIHt9KS5nZXQoJ3ZlcmInKSA9PSAnYWNjZXB0J1xuICAgICAgICAgICAgICAgIGFuZCB4WydkaXNwb3NpdGlvbiddLmdldCgnbWVtb192ZXJzaW9uJykgPT0gMV1cbiAgICByZXF1aXJlKGxlbihhY2NlcHRlZCkgPT0gMSwgJ29uZSBjb25maXJtZWQgZm91bmRlciBhY2NlcHRhbmNlIHJlcXVpcmVkJylcbiAgICBhY2NlcHRlZCA9IGFjY2VwdGVkWzBdWydkaXNwb3NpdGlvbiddXG4gICAgcmVxdWlyZShhY2NlcHRlZC5nZXQoJ2FjdG9yJykgPT0gRk9VTkRFUiBhbmQgYWNjZXB0ZWQuZ2V0KCdtZW1vX2lkJykgPT0gcmV2aWV3X2lkXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhcHByb3ZhbF9pZCcpID09IHJlY2VpcHQuZ2V0KCdhcHByb3ZhbF9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdpZCcpID09IHJlY2VpcHQuZ2V0KCdkaXNwb3NpdGlvbl9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhdCcpID09IHJlY2VpcHQuZ2V0KCdhY2NlcHRlZF9hdCcpLCAnZXhhY3QgZm91bmRlciBkaXNwb3NpdGlvbiBtaXNtYXRjaCcpXG4gICAgcmVxdWlyZShyZS5mdWxsbWF0Y2gocidbYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2FwcHJvdmFsX2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHInZGlzcC1bYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHIncmV2aWV3LVthLWYwLTktXXszNn0nLCByZXZpZXdfaWQpIGlzIG5vdCBOb25lLFxuICAgICAgICAgICAgJ25hdGl2ZSBkaXNwb3NpdGlvbiBpZGVudGlmaWVycyBhcmUgbWFsZm9ybWVkJylcbiAgICBhY2NlcHRlZF9hdCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQoYWNjZXB0ZWRbJ2F0J10ucmVwbGFjZSgnWicsICcrMDA6MDAnKSlcbiAgICByZXF1aXJlKGFjY2VwdGVkX2F0LnR6aW5mbyBpcyBub3QgTm9uZSBhbmQgYWNjZXB0ZWRfYXQgPD0gdmVyaWZpZWQsICdhY2NlcHRhbmNlIHRpbWUgbm90IGJvdW5kZWQnKVxuICAgIHJldHVybiB7a2V5OiByZWNlaXB0W2tleV0gZm9yIGtleSBpbiAoJ2FwcHJvdmFsX2lkJywgJ2Rpc3Bvc2l0aW9uX2lkJywgJ2FjY2VwdGVkX2F0JywgJ3ZlcmlmaWVkX2F0Jyl9XG5cblxuZGVmIG9yaWdpbmFsX2FuY2hvcihwYXJlbnQsIGV4cGVjdGVkLCBiYWNrdXBfcmVzdWx0LCBvcmlnaW5hbF9pZGVudGl0eSk6XG4gICAgXCJcIlwiUmVhZCBvbmx5IHNhbml0aXplZCBvcmlnaW5hbCBqb3VybmFsOyBuZXZlciByZXdyaXRlL3N5bnRoZXNpemUgaXRzIHBoYXNlcy5cIlwiXCJcbiAgICBwYXRoID0gUGF0aChwYXJlbnQpIC8gJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nXG4gICAgcHJpdmF0ZShwYXRoKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBieXRlcyBjaGFuZ2VkJylcbiAgICBvcmlnaW5hbCA9IGpzb24ubG9hZHMocGF0aC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKG9yaWdpbmFsLmdldCgnaWRlbnRpdHknKSA9PSBvcmlnaW5hbF9pZGVudGl0eSwgJ29yaWdpbmFsIGFwcHJvdmVkIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHBoYXNlcyA9IG9yaWdpbmFsLmdldCgncGhhc2VzJywge30pXG4gICAgcmVxdWlyZShzZXQocGhhc2VzKSA9PSB7J2RyaWxsLWJhY2t1cCcsICdkcmlsbC1jb3B5J30sICd1bmV4cGVjdGVkIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0JylcbiAgICBmb3IgbmFtZSwgZmllbGRzIGluIGV4cGVjdGVkWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUoYWxsKHBoYXNlc1tuYW1lXS5nZXQoa2V5KSA9PSB2YWx1ZSBmb3Iga2V5LHZhbHVlIGluIGZpZWxkcy5pdGVtcygpKSxcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkL2NvbXBsZXRlZCBhdHRlbXB0IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocGhhc2VzWydkcmlsbC1iYWNrdXAnXS5nZXQoJ3Jlc3VsdCcpID09IGJhY2t1cF9yZXN1bHRcbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZVxuICAgICAgICAgICAgYW5kIHBoYXNlc1snZHJpbGwtY29weSddLmdldCgncmVzdWx0Jywge30pLmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgRmFsc2UsXG4gICAgICAgICAgICAnb3JpZ2luYWwgYmFja3VwL2NvcHkgb3V0Y29tZSBjaGFuZ2VkJylcbiAgICByZXF1aXJlKGJhY2t1cF9yZXN1bHQuZ2V0KCdzbmFwc2hvdF9zaGEyNTYnKSA9PSBleHBlY3RlZFsnc25hcHNob3Rfc2hhMjU2J11cbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnc25hcHNob3RfYnl0ZXMnKSA9PSBleHBlY3RlZFsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIGJhY2t1cF9yZXN1bHQuZ2V0KCdwb2RfdWlkJykgPT0gJ2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNycsXG4gICAgICAgICAgICAnb3JpZ2luYWwgZnJvemVuIHNuYXBzaG90IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBjaGFuZ2VkIGR1cmluZyByZWFkJylcbiAgICByZXR1cm4geydvcmlnaW5hbF9qb3VybmFsX3NoYTI1Nic6IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLFxuICAgICAgICAgICAgJ29yaWdpbmFsX2NvcHlfYXR0ZW1wdF9pZCc6IHBoYXNlc1snZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnb3JpZ2luYWxfYmFja3VwX2F0dGVtcHRfaWQnOiBwaGFzZXNbJ2RyaWxsLWJhY2t1cCddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnYmFja3VwX3Jlc3VsdCc6IGJhY2t1cF9yZXN1bHQsICdvbGRfdW5jZXJ0YWluX3BoYXNlX3JldGFpbmVkJzogVHJ1ZX1cblxuXG5jbGFzcyBKb3VybmFsOlxuICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXJlbnQsIGlkZW50aXR5KTpcbiAgICAgICAgc2VsZi5wYXJlbnQgPSBQYXRoKHBhcmVudClcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCwgZGlyZWN0b3J5PVRydWUpXG4gICAgICAgIHNlbGYucGF0aCA9IHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tam91cm5hbC1yMS5qc29uJ1xuICAgICAgICBzZWxmLmxvY2sgPSBvcy5vcGVuKHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tcjEubG9jaycsIG9zLk9fQ1JFQVQgfCBvcy5PX05PRk9MTE9XIHwgb3MuT19SRFdSLCAwbzYwMClcbiAgICAgICAgZmNudGwuZmxvY2soc2VsZi5sb2NrLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQilcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCAvICdyZXNjdWUtZXhlY3V0aW9uLXIxLmxvY2snKVxuICAgICAgICBpZiBzZWxmLnBhdGguZXhpc3RzKCk6XG4gICAgICAgICAgICBwcml2YXRlKHNlbGYucGF0aClcbiAgICAgICAgICAgIHNlbGYuZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5wYXRoLnJlYWRfdGV4dCgpKVxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ2lkZW50aXR5J10gPT0gaWRlbnRpdHksICdqb3VybmFsIGNhc2Uvc291cmNlIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgc2VsZi5kYXRhID0geydpZGVudGl0eSc6IGlkZW50aXR5LCAncGhhc2VzJzoge319XG4gICAgICAgICAgICBzZWxmLnNhdmUoKVxuXG4gICAgZGVmIHNhdmUoc2VsZik6XG4gICAgICAgIHRlbXBvcmFyeSA9IHNlbGYucGFyZW50IC8gJ2V4ZWN1dGlvbi1qb3VybmFsLm5ldydcbiAgICAgICAgZmQgPSBvcy5vcGVuKHRlbXBvcmFyeSwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1cgfCBvcy5PX1dST05MWSwgMG82MDApXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAndycpIGFzIHN0cmVhbTpcbiAgICAgICAgICAgICAgICBqc29uLmR1bXAoc2VsZi5kYXRhLCBzdHJlYW0sIGluZGVudD0yKVxuICAgICAgICAgICAgICAgIHN0cmVhbS53cml0ZSgnXFxuJylcbiAgICAgICAgICAgICAgICBzdHJlYW0uZmx1c2goKVxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKHN0cmVhbS5maWxlbm8oKSlcbiAgICAgICAgICAgIG9zLnJlcGxhY2UodGVtcG9yYXJ5LCBzZWxmLnBhdGgpXG4gICAgICAgICAgICBkaXJlY3RvcnkgPSBvcy5vcGVuKHNlbGYucGFyZW50LCBvcy5PX0RJUkVDVE9SWSB8IG9zLk9fUkRPTkxZKVxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIGZpbmFsbHk6XG4gICAgICAgICAgICAgICAgb3MuY2xvc2UoZGlyZWN0b3J5KVxuICAgICAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbjpcbiAgICAgICAgICAgICMgUmV0YWluIGV2aWRlbmNlIHJhdGhlciB0aGFuIG92ZXJ3cml0aW5nIGFuIHVuY2VydGFpbiBkdXJhYmxlIGludGVudC5cbiAgICAgICAgICAgIHJhaXNlXG5cbiAgICBkZWYgc3RhcnQoc2VsZiwgcGhhc2UsIGFwcHJvdmFsKTpcbiAgICAgICAgcmVxdWlyZShwaGFzZSBub3QgaW4gc2VsZi5kYXRhWydwaGFzZXMnXSwgJ2FscmVhZHkgYXR0ZW1wdGVkIHBoYXNlOyBubyByZXRyeScpXG4gICAgICAgIHJlcXVpcmUocGhhc2UgaW4gUEhBU0VTLCAnZml4ZWQgcmVzY3VlIG9yIHJlbWFpbmluZyBwaGFzZSByZXF1aXJlZCcpXG4gICAgICAgIHByZWRlY2Vzc29ycyA9IGRpY3QoemlwKFBIQVNFU1sxOjddLCBQSEFTRVNbOjZdKSlcbiAgICAgICAgcHJlZGVjZXNzb3JzWydyb2xsYmFjay12ZXJpZnknXSA9ICdyb2xsYmFjaydcbiAgICAgICAgaWYgcGhhc2UgaW4gcHJlZGVjZXNzb3JzOlxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ3BoYXNlcyddLmdldChwcmVkZWNlc3NvcnNbcGhhc2VdLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdDT01QTEVURScsXG4gICAgICAgICAgICAgICAgICAgICdwcmVjZWRpbmcgcGhhc2UgaXMgbm90IHZlcmlmaWVkIGNvbXBsZXRlJylcbiAgICAgICAgaWYgcGhhc2UgPT0gJ3JvbGxiYWNrJzpcbiAgICAgICAgICAgIHJlcXVpcmUoJ3JlbGVhc2UnIGluIHNlbGYuZGF0YVsncGhhc2VzJ10sICdyb2xsYmFjayByZXF1aXJlcyBhIHJlY29yZGVkIHJlbGVhc2UgYXR0ZW1wdCcpXG4gICAgICAgIHNlbGYuZGF0YVsncGhhc2VzJ11bcGhhc2VdID0geydzdGF0ZSc6ICdSVU5OSU5HJywgJ2FwcHJvdmFsJzogYXBwcm92YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhdHRlbXB0X2lkJzogc3RyKHV1aWQudXVpZDQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdGFydGVkX2F0JzogZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0YykuaXNvZm9ybWF0KCl9XG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgbm90ZShzZWxmLCBwaGFzZSwga2V5LCB2YWx1ZSk6XG4gICAgICAgIHJlcXVpcmUoc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1bJ3N0YXRlJ10gPT0gJ1JVTk5JTkcnLCAncGhhc2UgaW50ZW50IG1pc3NpbmcnKVxuICAgICAgICBzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVtrZXldID0gdmFsdWVcbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBmaW5pc2goc2VsZiwgcGhhc2UsIHJlc3VsdCk6XG4gICAgICAgIGVudHJ5ID0gc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1cbiAgICAgICAgcmVxdWlyZShlbnRyeVsnc3RhdGUnXSA9PSAnUlVOTklORycsICdwaGFzZSBpbnRlbnQgbWlzc2luZycpXG4gICAgICAgIGVudHJ5WydyZXN1bHQnXSA9IHJlc3VsdFxuICAgICAgICBlbnRyeVsnc3RhdGUnXSA9ICdDT01QTEVURScgaWYgcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZSBlbHNlICdVTkNFUlRBSU4nXG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgY2xvc2Uoc2VsZik6XG4gICAgICAgIG9zLmNsb3NlKHNlbGYubG9jaylcbiIKICAgIH0sCiAgICAiZXhlY3V0aW9uLXBsYW4uanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICI5Y2U1NzI4YTU2MWU2ZDM4Zjg0OTcyMDFiYWEyYjg0MGQxMTQ0NGEwYWY4YWQ2MjM0ZGZjMzc0MjgxMTNmMjU4IiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcImtpbmRcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi5zdXBlcnZpc2VkLW1lY2hhbmljYWwtcmVsZWFzZS1wbGFuXCIsXG4gIFwidmVyc2lvblwiOiAyLFxuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcInN0YXRlXCI6IFwicHJlcGFyZWQtdW5hcHByb3ZlZFwiLFxuICBcImV4ZWN1dG9yX2ZpbGVzXCI6IHtcbiAgICBcImFjdHVhdG9yLnB5XCI6IFwiODZiNjdkMWFiYWQ2YWYyYThjNDk1MjhmZTEyNWE1YmFiOTQ0OTc1ZDNlODAxODI2YzUxMWVlODg4NDY1NzFiMlwiLFxuICAgIFwiYXV0aG9yaXR5X2pvdXJuYWwucHlcIjogXCIwNTM1OTc1YWU2MzEyMTlmOTBmY2U3ZTUyZjhiNTRlNjFlOGFmZDRlZjY4YmI3NDczODYzNDc4ZjBmNTE5ZjY4XCIsXG4gICAgXCJuYXRpdmVfcHJvZ3JhbS5weVwiOiBcIjc4OGRjOTlmN2VkZmJmZDU0MmEzYmIwOGZjMzFmNjBjYWY0ZjhmZDVkNjU0YTZhOTFiNDVlMTk3ZWNmZjlmOTFcIixcbiAgICBcInJlY2VpcHRfc2FmZXR5LnB5XCI6IFwiNWM1NDM3M2YyZGM0YjA2NDAwODIyNWMxODZlZmIxZDVhZmRlZWMzNmQxNTM1MGJkYTBhMTJkZWQ5NzYwMmQxYlwiXG4gIH0sXG4gIFwiY2FzZV9maWxlc1wiOiB7XG4gICAgXCJjaGFuZ2VfZ3VhcmQucHlcIjogXCJmMzQ4ZTQ0OWM0OWY0ZDllNDlhZjllODJlMDE3NjRlNzE5NzgzN2ZkM2RmOWQ3NTZmNTg5MWQ5YjhkOWIzOGJlXCIsXG4gICAgXCJzcWxpdGVfcmVhZG9ubHkucHlcIjogXCI5MDkzYzY0ZjdmMGUzOWIyNDlkYTlmZWZkZjVhYWY0ZTQyNThiYzMxZTdhMjdmZDg4ODQ3OWNlMzI5YTIwNTA5XCIsXG4gICAgXCJwcmVmbGlnaHQtaW5wdXRzLmpzb25cIjogXCIwM2JiNGI0MmZlMWFhNTFiODQ2ZTk1N2E5ZTIzOTI2ZmFlNzJmMDJhMmNiNWUyOTczNjgwNDdmYjI1YzE3ZTliXCIsXG4gICAgXCJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb25cIjogXCJkMThkMjcwNjNkMDZmNTM1YWU4ODRlYTAxZjk2NzQ3ZmUzMDE2ODU1MThhYjk0YjFjYmEwNzJhMWUxNTE5MzYyXCIsXG4gICAgXCJzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uXCI6IFwiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OVwiLFxuICAgIFwiY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvblwiOiBcIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGVcIixcbiAgICBcInJvbGxiYWNrLWRlcGxveW1lbnQuanNvblwiOiBcIjM5YjNmNDNiYjg0ZWY0OTIxY2MzYTFmYmNkYzQ0NDYxMDc0MWVkODgwOTE0OWQ4ZjhmMTdlZDgwNWYyNjIxMjFcIixcbiAgICBcImNoZWNrX2luc3RhbGxlZC5weVwiOiBcImEzNGE1MWJlOWM5ZjJiMTZhMDZhODgxNzNiNWM2YzQ5MmM5OTU3ZmUwMjFjZjQxMmE4NmExNzM3NzMwNjQwYWRcIixcbiAgICBcInB1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvblwiOiBcImU1OWFiNDRiMWFhZjI4MTQwNTA5NTkzYWFlNGFiOWI5N2FiNjJjYzhiNTg5ZTNmMTU1MmJhYzc4NjE4ODk2ZGRcIixcbiAgICBcInNlY3VyaXR5LXN1bW1hcnkuanNvblwiOiBcIjBlZTU2NDAwZGM3MDNmN2M5OTY4YzJhMGEzZWEwMzkwZDgzNjJmOGQwYmJmODAwMmEyYmQ3ZmE1OGYxOWNiNDRcIixcbiAgICBcIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWJhY2t1cC5qc29uXCI6IFwiMDI1ZGRkZjFlOTM5MzZmMzFlOThiOWZiZmE4NGFhMmJkYWFhMzM1NzNmOWQzYjBlMzJkOTQ3ZmQyODZiMTcwZVwiLFxuICAgIFwib3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtY29weS1mYWlsdXJlLmpzb25cIjogXCJmYjc4ZmIyZThjM2Q0MTY0OTBjZjBmNTU5YjJmNWJkMDE5NDA2YTQ5MGY4ZjVmYTZmNTkzMjQyMWYwYjFhYzU2XCIsXG4gICAgXCJvcmlnaW5hbC1qb3VybmFsLXNhbml0aXplZC1hbmNob3IuanNvblwiOiBcIjk4OGZjYTYxYWQ4ZWI5ZDQzZDkzMzkwYTgzNTMyM2Y5NTIxOTZiYmNlOGNjMGJkZTUxYzQyYTE3ZDQxMWY0NTRcIlxuICB9LFxuICBcIm93bmVyX3NvdXJjZV9maWxlc1wiOiB7XG4gICAgXCJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvblwiOiBcIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTVcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvblwiOiBcIjM4Yjc4YjljYmVlNWFkZTc3NTBhNThkNTE1NmNhNGM1NzczMzUyZTk0N2FjYjMwNGVlNzE0YjU5ZTc0OWNlYjRcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUva3VzdG9taXphdGlvbi55YW1sXCI6IFwiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0N1wiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uXCI6IFwiOWJhZDZkYjVmYmMyMTc4ZDMxYjA0MTIwMDE2YTQxODMwYzM1NTJmYmI5ZTI1MTdiNzE4ZjliYmU4N2NmNjQ5ZVwiXG4gIH0sXG4gIFwiY2FuZGlkYXRlX2ltYWdlXCI6IFwiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhXCIsXG4gIFwicHJpb3JfaW1hZ2VcIjogXCJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcIixcbiAgXCJzb3VyY2VfcmV2aXNpb25cIjogXCJtdXN0LWJlLWV4YWN0LWZpbmFsLW93bmVyLUhFQUQtd2l0aC1hcHByb3ZlZC1mb3VyLUdpdC1ibG9ic1wiLFxuICBcInBoYXNlc1wiOiBbXG4gICAgXCJkcmlsbC1jb3B5LXJlc2N1ZS1yMVwiLFxuICAgIFwib2ZmbGluZS12ZXJpZnlcIixcbiAgICBcImNsZWFudXAtb2ZmbGluZVwiLFxuICAgIFwiY3V0b3Zlci1iYWNrdXBcIixcbiAgICBcImN1dG92ZXItY29weVwiLFxuICAgIFwicmVsZWFzZVwiLFxuICAgIFwidmVyaWZ5XCIsXG4gICAgXCJyb2xsYmFja1wiLFxuICAgIFwicm9sbGJhY2stdmVyaWZ5XCJcbiAgXSxcbiAgXCJhdXRob3JpemF0aW9uXCI6IFwiZnJlc2ggZXh0ZXJuYWxseSBhdXRoZW50aWNhdGVkIHJvb3QgZml4ZWQtb3JpZ2luIG5hdGl2ZSByZWFkYmFjayBiZWZvcmUgZWFjaCBwaGFzZTsgZXhhY3QgY29uZmlybWVkIHBsYXRmb3JtLXJvb3QgZGlzcG9zaXRpb24gYW5kIGN1cnJlbnQgcGFja2V0IFNIQS9zb3VyY2UgY29tbWl0OyByZWNlaXB0IGJvb2trZWVwaW5nIGlzIG5vdCBhbiBhdXRvbm9tb3VzIHNpZ25lZCBncmFudFwiLFxuICBcImV4ZWN1dGVfYnlcIjogXCIyMDI2LTEwLTEyVDIzOjU5OjU5WlwiLFxuICBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZSxcbiAgXCJuYXRpdmVfZGF0YV9vcl93b3JrbG9hZF9hY3Rpb25fZXhlY3V0ZWRcIjogZmFsc2UsXG4gIFwiZGVhZGxpbmVfc2VtYW50aWNzXCI6IFwiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LlwiLFxuICBcInJlY292ZXJ5XCI6IHtcbiAgICBcIm9yaWdpbmFsX2FuY2hvclwiOiB7XG4gICAgICBcIm9yaWdpbmFsX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICAgICAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgICAgIFwiZHJpbGwtYmFja3VwXCI6IHtcbiAgICAgICAgICBcInN0YXRlXCI6IFwiQ09NUExFVEVcIixcbiAgICAgICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgICAgICBcInN0YXJ0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM4OjQ1LjMxMDY1MyswMDowMFwiXG4gICAgICAgIH0sXG4gICAgICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICAgICAgXCJzdGF0ZVwiOiBcIlVOQ0VSVEFJTlwiLFxuICAgICAgICAgIFwiYXR0ZW1wdF9pZFwiOiBcIjMyOWVmMTkwLTE2OTItNDI0Ni1iOTUzLWU2YTU5NjY0YWJjY1wiLFxuICAgICAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgICAgIFwic25hcHNob3Rfc2hhMjU2XCI6IFwiODc1NmNmODI1ZGY5ZTdiNWI3NGJiNGEwMTA2YTUwMjdmNWNmZjJjNTlmZjQ1ZDdiNDhlZWQ4NTIyYTdkMzNmM1wiLFxuICAgICAgXCJzbmFwc2hvdF9ieXRlc1wiOiAxOTUzNzkyMCxcbiAgICAgIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gICAgICBcIm9sZF91bmNlcnRhaW5fcmV0cnlfYXV0aG9yaXplZFwiOiBmYWxzZVxuICAgIH0sXG4gICAgXCJvcmlnaW5hbF9pZGVudGl0eVwiOiB7XG4gICAgICBcInByb3Bvc2FsXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgICAgIFwic291cmNlX3JldmlzaW9uXCI6IFwiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMFwiLFxuICAgICAgXCJtZW1vX3NoYTI1NlwiOiBcIjUwNmQzOTU2YmViN2M2MmFiMmJiZGZkYTc4M2MwNTkwNWQxODM0NTJhMWY2N2ExODE3ZjNmYjhjMmU1MjI5MzdcIixcbiAgICAgIFwicGxhbl9zaGEyNTZcIjogXCJmNWU1ZmE5MDZmZjE5ZDNhNDVkMTBkY2RiMjgxMDM3M2FlMjFmOWNmNDRjMDQ3MmZmMmJkNDdkM2JjMzMyOGQ2XCJcbiAgICB9LFxuICAgIFwibmV3X2pvdXJuYWxcIjogXCJyZXNjdWUtZXhlY3V0aW9uLWpvdXJuYWwtcjEuanNvblwiLFxuICAgIFwibmV3X3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgICBcIm9sZF91bmNlcnRhaW5fcGhhc2Vfb3ZlcndyaXRlX29yX3JldHJ5XCI6IGZhbHNlLFxuICAgIFwibmV3X3NuYXBzaG90X2JhY2t1cFwiOiBmYWxzZSxcbiAgICBcInNuYXBzaG90X29yX3NpZGVjYXJfbXV0YXRpb25cIjogZmFsc2UsXG4gICAgXCJtYXBwaW5nXCI6IFwib2ZmbGluZS12ZXJpZnkgY29uc3VtZXMgQ09NUExFVEUgZHJpbGwtY29weS1yZXNjdWUtcjEgcmVzdWx0OyBhbGwgbGF0ZXIgcGhhc2VzIG9yZGVyZWQgb25seSBpbiBuZXcgaGFzaC1saW5rZWQgcmVjb3Zlcnkgam91cm5hbFwiXG4gIH0sXG4gIFwic291cmNlX21lbW9fdmVyc2lvblwiOiAyLFxuICBcIm5hdGl2ZV9yZXZpZXdfbWVtb192ZXJzaW9uXCI6IDFcbn1cbiIKICAgIH0sCiAgICAibmF0aXZlX3Byb2dyYW0ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiNzg4ZGM5OWY3ZWRmYmZkNTQyYTNiYjA4ZmMzMWY2MGNhZjRmOGZkNWQ2NTRhNmE5MWI0NWUxOTdlY2ZmOWY5MSIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIkZpeGVkIHZlcnNpb24yIHJlY292ZXJ5IHJlbW90ZSBzb3VyY2U7IHJlcXVpcmVzIGZyZXNoIGV4YWN0IGFjY2VwdGFuY2UuXCJcIlwiXG5QUk9HUkFNID0gJ1xcbmltcG9ydCBjb3B5LGRhdGV0aW1lLGhhc2hsaWIsanNvbixvcyxyZSxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxucGF5bG9hZD1qc29uLmxvYWRzKF9fUEFZTE9BRF9fKVxcbmV4ZWMoX19HVUFSRF9fKVxcbnBoYXNlPXBheWxvYWRbXFwncGhhc2VcXCddXFxuaWYgcGhhc2Ugbm90IGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2tcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2ZpeGVkIG5hdGl2ZSBwaGFzZSByZXF1aXJlZFxcJylcXG5kZWFkbGluZT1kYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KFxcJzIwMjYtMTAtMTJUMjM6NTk6NTkrMDA6MDBcXCcpXFxuZGVmIHJlcXVpcmUodmFsdWUscmVhc29uKTpcXG4gaWYgbm90IHZhbHVlOnJhaXNlIFZhbHVlRXJyb3IocmVhc29uKVxcbnJlcXVpcmUoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0Yyk8ZGVhZGxpbmUsXFwnZXhlY3V0aW9uIHdpbmRvdyBleHBpcmVkXFwnKVxcbmVudj17Kipvcy5lbnZpcm9uLFxcJ0tVQkVDT05GSUdcXCc6XFwnL2V0Yy9yYW5jaGVyL2szcy9rM3MueWFtbFxcJ31cXG5kZWYgcnVuKGFyZ3YsYm9keT1Ob25lLHRpbWVvdXQ9OTApOlxcbiByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndixpbnB1dD1ib2R5LHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlLHRpbWVvdXQ9dGltZW91dCxlbnY9ZW52KVxcbmRlZiByZWFkKGtpbmQsbmFtZSxuYW1lc3BhY2UpOlxcbiByZXN1bHQ9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxraW5kLG5hbWUsXFwnLW5cXCcsbmFtZXNwYWNlLFxcJy1vXFwnLFxcJ2pzb25cXCddKVxcbiByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlPT0wLFxcJ2ZpeGVkIG1ldGFkYXRhIHJlYWQgcmVmdXNlZFxcJylcXG4gcmV0dXJuIGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcXG5zZWFsZWQ9cGF5bG9hZFtcXCdzZWFsZWRcXCddOyBkZXBlbmRlbmNpZXM9cGF5bG9hZFtcXCdkZXBlbmRlbmNpZXNcXCddXFxubGl2ZT1yZWFkKFxcJ2RlcGxveW1lbnRcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY209cmVhZChcXCdjb25maWdtYXBcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxucHZjPXJlYWQoXFwncHZjXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uLWRhdGFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY2hlY2tfZGVwZW5kZW5jaWVzKGNtLHB2YyxkZXBlbmRlbmNpZXMpXFxuYXBwPXJlYWQoXFwnYXBwbGljYXRpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnYXJnb2NkXFwnKVxcbnJlcXVpcmUoYXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddPT1cXCc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGRcXCcsXFwnQXBwbGljYXRpb24gVUlEIGNoYW5nZWRcXCcpXFxucmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdyZXBvVVJMXFwnXT09XFwnaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0XFwnXFxuIGFuZCBhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdwYXRoXFwnXT09XFwnZGVwbG95L2xpZmVjeWNsZVxcJ1xcbiBhbmQgYXBwW1xcJ3NwZWNcXCddW1xcJ2Rlc3RpbmF0aW9uXFwnXT09e1xcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCdzZXJ2ZXJcXCc6XFwnaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjXFwnfVxcbiBhbmQgYXBwW1xcJ3NwZWNcXCddLmdldChcXCdzeW5jUG9saWN5XFwnLHt9KS5nZXQoXFwnYXV0b21hdGVkXFwnKSBpcyBOb25lXFxuIGFuZCBzZXQoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ10pPT17XFwncmVwb1VSTFxcJyxcXCdwYXRoXFwnLFxcJ3RhcmdldFJldmlzaW9uXFwnfSBhbmQgbm90IGFwcFtcXCdzcGVjXFwnXS5nZXQoXFwnc291cmNlc1xcJyksXFwnQXBwbGljYXRpb24gb3duZXIvc2NvcGUgY2hhbmdlZFxcJylcXG5leHBlY3RlZD1jb3B5LmRlZXBjb3B5KHNlYWxlZClcXG5pZiBwaGFzZT09XFwndmVyaWZ5XFwnOmV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOlxcbiBpbWFnZT1saXZlW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ11cXG4gcmVxdWlyZShpbWFnZSBpbiAoQkFTRSxDQU5ESURBVEUpLFxcJ3JvbGxiYWNrIGltYWdlIGlzIG91dHNpZGUgc2FtZS1zY2hlbWEgcGFpclxcJylcXG4gZXhwZWN0ZWRbXFwnc3BlY1xcJ11bXFwndGVtcGxhdGVcXCddW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXT1pbWFnZVxcbmNoZWNrX2N1cnJlbnQobGl2ZSxleHBlY3RlZClcXG5pZiBwaGFzZSE9XFwncm9sbGJhY2tcXCc6XFxuIHJlcXVpcmUobGl2ZS5nZXQoXFwnc3RhdHVzXFwnLHt9KS5nZXQoXFwncmVhZHlSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ3VwZGF0ZWRSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ29ic2VydmVkR2VuZXJhdGlvblxcJyk9PWxpdmVbXFwnbWV0YWRhdGFcXCddW1xcJ2dlbmVyYXRpb25cXCddLFxcJ3NlcnZpY2Ugbm90IFJlYWR5MVxcJylcXG50YXJnZXQ9cGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddIGlmIHBoYXNlPT1cXCd2ZXJpZnlcXCcgZWxzZSBcXCc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmXFwnXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwndGFyZ2V0UmV2aXNpb25cXCddIGluICh0YXJnZXQscGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddKSxcXCdyb2xsYmFjayBzb3VyY2UgaXMgb3V0c2lkZSBwYWlyXFwnKVxcbmVsc2U6cmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ109PXRhcmdldCxcXCd1bmV4cGVjdGVkIHNvdXJjZSBwaW5cXCcpXFxucmVzdWx0PXtcXCdwaGFzZVxcJzpwaGFzZSxcXCdhbGxfY2hlY2tzX3Bhc3NcXCc6RmFsc2UsXFwncmF3X291dHB1dF93aXRoaGVsZFxcJzpUcnVlLFxcbiBcXCduYXRpdmVfYXBwcm92YWxfdmVyaWZpZWRfYnlfcm9vdFxcJzpwYXlsb2FkW1xcJ2FwcHJvdmFsXFwnXSxcXCduYXRpdmVfYXV0aGVudGljYXRlZF9ncmFudFxcJzpGYWxzZX1cXG50cnk6XFxuIGlmIHBoYXNlIGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gIHBvZGxpc3Q9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxcXCdwb2RzXFwnLFxcJy1uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy1sXFwnLFxcJ2FwcC5rdWJlcm5ldGVzLmlvL25hbWU9aW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pXFxuICByZXF1aXJlKHBvZGxpc3QucmV0dXJuY29kZT09MCxcXCdwb2QgbWV0YWRhdGEgcXVlcnkgcmVmdXNlZFxcJylcXG4gIHBvZHM9W3AgZm9yIHAgaW4ganNvbi5sb2Fkcyhwb2RsaXN0LnN0ZG91dClbXFwnaXRlbXNcXCddIGlmIG5vdCBwW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnZGVsZXRpb25UaW1lc3RhbXBcXCcpXVxcbiAgcmVxdWlyZShsZW4ocG9kcyk9PTEsXFwnZXhhY3Qgc2luZ2xlIGxpdmUgb3duZXIgcG9kIHJlcXVpcmVkXFwnKTtwb2Q9cG9kc1swXVxcbiAgcmVxdWlyZShwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwncGhhc2VcXCcpPT1cXCdSdW5uaW5nXFwnIGFuZCBsZW4ocG9kW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddKT09MVxcbiAgIGFuZCBwb2RbXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddPT1leHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddXFxuICAgYW5kIGxlbihwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwnY29udGFpbmVyU3RhdHVzZXNcXCcsW10pKT09MVxcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ25hbWVcXCcpPT1cXCdpbmZvcm1lZC1kZWNpc2lvblxcJ1xcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ3JlYWR5XFwnKSBpcyBUcnVlLFxcJ293bmVyIHBvZCByZWFkaW5lc3MvaW1hZ2UgY2hhbmdlZFxcJylcXG4gIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJzpyZXF1aXJlKHBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09XFwnZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XFwnLFxcJ29yaWdpbmFsIGJhY2t1cCBQb2QgaWRlbnRpdHkgY2hhbmdlZFxcJylcXG4gIHRlbXBsYXRlPWV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVxcbiAgY29udHJvbGxlZD1zZXQodGVtcGxhdGUpfHtcXCdpbml0Q29udGFpbmVyc1xcJyxcXCdob3N0TmV0d29ya1xcJyxcXCdob3N0UElEXFwnLFxcJ2hvc3RJUENcXCcsXFwncnVudGltZUNsYXNzTmFtZVxcJyxcXCdzaGFyZVByb2Nlc3NOYW1lc3BhY2VcXCd9XFxuICByZXF1aXJlKGFsbChwb2RbXFwnc3BlY1xcJ10uZ2V0KGtleSk9PXRlbXBsYXRlLmdldChrZXkpIGZvciBrZXkgaW4gY29udHJvbGxlZCksXFwnYWN0dWFsIG93bmVyIFBvZCBjb25maWd1cmF0aW9uIGRyaWZ0ZWRcXCcpXFxuICBvd25lcnM9cG9kW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnb3duZXJSZWZlcmVuY2VzXFwnLFtdKTtyZXF1aXJlKGxlbihvd25lcnMpPT0xIGFuZCBvd25lcnNbMF1bXFwna2luZFxcJ109PVxcJ1JlcGxpY2FTZXRcXCcsXFwncG9kIG93bmVyIGNoYWluIGNoYW5nZWRcXCcpXFxuICBycz1yZWFkKFxcJ3JlcGxpY2FzZXRcXCcsb3duZXJzWzBdW1xcJ25hbWVcXCddLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbiAgcmVxdWlyZShyc1tcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09b3duZXJzWzBdW1xcJ3VpZFxcJ10gYW5kIGFueShvLmdldChcXCd1aWRcXCcpPT1zZWFsZWRbXFwnbWV0YWRhdGFcXCddW1xcJ3VpZFxcJ11cXG4gICBhbmQgby5nZXQoXFwna2luZFxcJyk9PVxcJ0RlcGxveW1lbnRcXCcgZm9yIG8gaW4gcnNbXFwnbWV0YWRhdGFcXCddLmdldChcXCdvd25lclJlZmVyZW5jZXNcXCcsW10pKSxcXCdSZXBsaWNhU2V0IG93bmVyc2hpcCBjaGFuZ2VkXFwnKVxcbiAgaW5uZXI9clwiXCJcIlxcbmltcG9ydCBoYXNobGliLGpzb24sb3Msc3RhdCxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxuZXhlYyhfX1JFQURPTkxZX18pXFxuZXhlYyhfX1NBRkVUWV9fKVxcbmFjdGlvbj1fX0FDVElPTl9fO2RiPVxcJy9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZVxcJztmb2xkZXI9XFwnL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjFcXCdcXG5kZWYgcmVxdWlyZSh2LHIpOlxcbiBpZiBub3QgdjpyYWlzZSBWYWx1ZUVycm9yKHIpXFxucmVxdWlyZShvcy5nZXR1aWQoKT09MTAwMDEgYW5kIG9zLmdldGdpZCgpPT0xMDAwMSxcXCduYXRpdmUgb3duZXIgVUlEL0dJRCByZXF1aXJlZFxcJylcXG5kZWYgcHJpdmF0ZShwLGRpcmVjdG9yeT1GYWxzZSk6XFxuIHM9b3MubHN0YXQocCk7cmVxdWlyZSgoc3RhdC5TX0lTRElSKHMuc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKHMuc3RfbW9kZSkpXFxuICBhbmQgcy5zdF91aWQ9PTEwMDAxIGFuZCBzdGF0LlNfSU1PREUocy5zdF9tb2RlKT09KDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxcbiAgYW5kIChkaXJlY3Rvcnkgb3Igcy5zdF9ubGluaz09MSksXFwncHJpdmF0ZSBuYXRpdmUgY3VzdG9keSByZXF1aXJlZFxcJylcXG5wcml2YXRlKFxcJy9kYXRhL3ByaXZhdGVcXCcsVHJ1ZSk7cHJpdmF0ZShkYilcXG5iYXNlbGluZT1jb3VudHMoaW5zcGVjdF9yZWFkb25seShkYikpICMgTVVTVCBwcmVjZWRlIGFueSBTdG9yZS9hZG1pbiBvcGVuLlxcbmlmIGFjdGlvbiBpbiAoXFwnY3V0b3Zlci1iYWNrdXBcXCcpOlxcbiBzaXplPW9zLnN0YXQoZGIpLnN0X3NpemVcXG4gaWYgb3MucGF0aC5leGlzdHMoZGIrXFwnLXdhbFxcJyk6c2l6ZSs9b3Muc3RhdChkYitcXCctd2FsXFwnKS5zdF9zaXplXFxuIHY9b3Muc3RhdHZmcyhcXCcvZGF0YS9wcml2YXRlXFwnKTtmcmVlPXYuZl9iYXZhaWwqdi5mX2Zyc2l6ZVxcbiByZXF1aXJlKHNpemU+MCBhbmQgc2l6ZTw9NTEyKjEwMjQqKjIgYW5kIGZyZWU+PXNpemUqKDIgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSAxKSsxNioxMDI0KioyLFxcJ2JvdW5kZWQgbmF0aXZlIHNuYXBzaG90IGNhcGFjaXR5IHJlcXVpcmVkXFwnKVxcbiBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJzpcXG4gIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhmb2xkZXIpLFxcJ25hdGl2ZSBjYXNlIGRpcmVjdG9yeSBtdXN0IGJlIHVuaXF1ZVxcJylcXG4gIG9zLm1rZGlyKGZvbGRlciwwbzcwMCk7b3MuY2htb2QoZm9sZGVyLDBvNzAwKVxcbiBwcml2YXRlKGZvbGRlcixUcnVlKVxcbiBmaWxlbmFtZT1cXCdkcmlsbC5zcWxpdGVcXCcgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSBcXCdjdXRvdmVyLnNxbGl0ZVxcJztvdXRwdXQ9Zm9sZGVyK1xcJy9cXCcrZmlsZW5hbWVcXG4gcmVxdWlyZShub3Qgb3MucGF0aC5sZXhpc3RzKG91dHB1dCksXFwnc25hcHNob3Qgb3V0cHV0IG11c3QgYmUgdW5pcXVlXFwnKVxcbiBhZG1pbj1zdWJwcm9jZXNzLnJ1bihbXFwnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW5cXCcsXFwnYmFja3VwXFwnLFxcJy0tZGJcXCcsZGIsXFwnLS1vdXRwdXRcXCcsb3V0cHV0XSxjYXB0dXJlX291dHB1dD1UcnVlLHRleHQ9VHJ1ZSx0aW1lb3V0PTEyMClcXG4gcmVxdWlyZShhZG1pbi5yZXR1cm5jb2RlPT0wIGFuZCBqc29uLmxvYWRzKGFkbWluLnN0ZG91dCk9PXtcXCdzdGF0dXNcXCc6XFwnYmFja2VkX3VwXFwnLFxcJ2NvbnNpc3RlbnRfc25hcHNob3RcXCc6VHJ1ZX0sXFwnYmFja3VwIGNvbXBsZXRpb24gbm90IHZlcmlmaWVkOyBkbyBub3QgcmV0cnlcXCcpXFxuIHByaXZhdGUob3V0cHV0KVxcbiBmb3Igc3VmZml4IGluIChcXCctd2FsXFwnLCk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnc25hcHNob3QgaGFzIFdBTCBmcmFtZXM7IGltbXV0YWJsZSByZWFkIHJlZnVzZWRcXCcpXFxuIGRpZ2VzdD1oYXNobGliLnNoYTI1NigpXFxuIHdpdGggb3BlbihvdXRwdXQsXFwncmJcXCcpIGFzIHN0cmVhbTpcXG4gIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTpzdHJlYW0ucmVhZCgxMDI0KioyKSxiXFwnXFwnKTpkaWdlc3QudXBkYXRlKGJsb2NrKVxcbiBmcm96ZW5fZGlnZXN0PWRpZ2VzdC5oZXhkaWdlc3QoKVxcbiBzbmFwc2hvdD1jb3VudHMoaW5zcGVjdF9jbG9zZWRfc25hcHNob3Qob3V0cHV0LGZyb3plbl9kaWdlc3QpKVxcbiBzaXplPW9zLnN0YXQob3V0cHV0KS5zdF9zaXplO3JlcXVpcmUoMDxzaXplPD01MTIqMTAyNCoqMixcXCdzbmFwc2hvdCBvdXRzaWRlIGJvdW5kZWQgY29weSBzaXplXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXFwnOmJhc2VsaW5lLFxcJ3NuYXBzaG90X3JlYWRvbmx5XFwnOnNuYXBzaG90LFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfYnl0ZXNcXCc6c2l6ZSxcXCdzbmFwc2hvdF9maWxlXFwnOmZpbGVuYW1lLFxcJ25hdGl2ZV9wYXJlbnRfcHJpdmF0ZVxcJzpUcnVlLFxcJ25hdGl2ZV91aWRcXCc6b3MuZ2V0dWlkKCl9KSlcXG5lbGlmIGFjdGlvbiBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gcHJvb2Y9e1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHNcXCc6YmFzZWxpbmUsXFwnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzXFwnOlRydWV9XFxuIGlmIGFjdGlvbj09XFwndmVyaWZ5XFwnOlxcbiAgaW1wb3J0IHVybGxpYi5yZXF1ZXN0XFxuICBtb2R1bGU9XFwnL29wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24vcG9saWN5LnB5XFwnO2luZm89b3MubHN0YXQobW9kdWxlKVxcbiAgcmVxdWlyZShzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBhbmQgaW5mby5zdF91aWQ9PTAgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpPT0wbzY0NCxcXCdpbnN0YWxsZWQgcG9saWN5IG1ldGFkYXRhIGRpZmZlcnNcXCcpXFxuICB3aXRoIG9wZW4obW9kdWxlLFxcJ3JiXFwnKSBhcyBzb3VyY2U6bW9kdWxlX2RpZ2VzdD1oYXNobGliLnNoYTI1Nihzb3VyY2UucmVhZCgpKS5oZXhkaWdlc3QoKVxcbiAgcmVxdWlyZShtb2R1bGVfZGlnZXN0PT1cXCc5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyXFwnLFxcJ2luc3RhbGxlZCBzb3VyY2UgbW9kdWxlIGRpZmZlcnNcXCcpXFxuICBwdXJwb3NlPXN1YnByb2Nlc3MucnVuKFtzeXMuZXhlY3V0YWJsZSxcXCctXFwnXSxpbnB1dD1fX1BVUlBPU0VfXyx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0aW1lb3V0PTMwKVxcbiAgcmVxdWlyZShwdXJwb3NlLnJldHVybmNvZGU9PTAsXFwnaW5zdGFsbGVkIG5hdGl2ZS1wbGFjZW1lbnQgcHVycG9zZSBjaGVja3MgZmFpbGVkXFwnKVxcbiAgdGVzdGVkPWpzb24ubG9hZHMocHVycG9zZS5zdGRvdXQpXFxuICByZXF1aXJlKHRlc3RlZD09e1xcJ2luc3RhbGxlZF9pbWFnZV9wdXJwb3NlX3ZhcmlhbnRzXFwnOjEwLFxcJ2JpbmRpbmdfZm9ybXNfYWxsb3dlZFxcJzoyLFxcJ2Fkdmlzb3J5X29yX21hbGZvcm1lZF9yZWZ1c2VkXFwnOjgsXFwnc3ludGhldGljX29ubHlcXCc6VHJ1ZSxcXCduYXRpdmVfcHJvdmlkZXJcXCc6RmFsc2V9LFxcJ3B1cnBvc2UgcmVzdWx0IGRpZmZlcnNcXCcpXFxuICBjbGFzcyBOb1JlZGlyZWN0KHVybGxpYi5yZXF1ZXN0LkhUVFBSZWRpcmVjdEhhbmRsZXIpOlxcbiAgIGRlZiByZWRpcmVjdF9yZXF1ZXN0KHNlbGYsKmFyZ3MsKiprd2FyZ3MpOnJhaXNlIFZhbHVlRXJyb3IoXFwnaGVhbHRoIHJlZGlyZWN0IHJlZnVzZWRcXCcpXFxuICBvcGVuZXI9dXJsbGliLnJlcXVlc3QuYnVpbGRfb3BlbmVyKE5vUmVkaXJlY3QoKSk7c3RhdHVzZXM9e31cXG4gIGZvciByb3V0ZSBpbiAoXFwnL2hlYWx0aHpcXCcsXFwnL3JlYWR5elxcJyk6XFxuICAgd2l0aCBvcGVuZXIub3BlbihcXCdodHRwOi8vMTI3LjAuMC4xOjgwODBcXCcrcm91dGUsdGltZW91dD0xMCkgYXMgcmVzcG9uc2U6XFxuICAgIHJlcXVpcmUocmVzcG9uc2Uuc3RhdHVzPT0yMDAgYW5kIGxlbihyZXNwb25zZS5yZWFkKDgxOTMpKTw9ODE5MixcXCdib3VuZGVkIGhlYWx0aCBjaGVjayByZWZ1c2VkXFwnKTtzdGF0dXNlc1tyb3V0ZV09MjAwXFxuICBwcm9vZi51cGRhdGUoaW5zdGFsbGVkX3B1cnBvc2VfY2hlY2tzPXRlc3RlZCxwb2xpY3lfc2hhMjU2PW1vZHVsZV9kaWdlc3QscG9saWN5X21vZGU9XFwnMDY0NFxcJyxwb2xpY3lfdWlkPTAsaGVhbHRoX3N0YXR1c2VzPXN0YXR1c2VzLG5hdGl2ZV9wcm92aWRlcl9wcm9iZT1GYWxzZSlcXG4gcHJpbnQoanNvbi5kdW1wcyhwcm9vZikpXFxuZWxpZiBhY3Rpb24gaW4gKFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnKTpcXG4gcHJpdmF0ZShmb2xkZXIsVHJ1ZSk7ZmlsZW5hbWU9XFwnZHJpbGwuc3FsaXRlXFwnIGlmIGFjdGlvbj09XFwnZHJpbGwtY29weVxcJyBlbHNlIFxcJ2N1dG92ZXIuc3FsaXRlXFwnO291dHB1dD1mb2xkZXIrXFwnL1xcJytmaWxlbmFtZTtwcml2YXRlKG91dHB1dClcXG4gaWRlbnRpdHk9X19TTkFQU0hPVF9fO3JlcXVpcmUoaXNpbnN0YW5jZShpZGVudGl0eSxkaWN0KSBhbmQgaWRlbnRpdHkuZ2V0KFxcJ3NuYXBzaG90X2ZpbGVcXCcpPT1maWxlbmFtZSxcXCdyZWNvcmRlZCBvcmlnaW5hbCBmcm96ZW4gc25hcHNob3QgaWRlbnRpdHkgcmVxdWlyZWRcXCcpXFxuIHNuYXBzaG90PWNvdW50cyhpbnNwZWN0X2Nsb3NlZF9zbmFwc2hvdChvdXRwdXQsaWRlbnRpdHlbXFwnc25hcHNob3Rfc2hhMjU2XFwnXSkpO3NpemU9b3Muc3RhdChvdXRwdXQpLnN0X3NpemU7cmVxdWlyZShzaXplPT1pZGVudGl0eVtcXCdzbmFwc2hvdF9ieXRlc1xcJ10gYW5kIDA8c2l6ZTw9NTEyKjEwMjQqKjIsXFwnc25hcHNob3Qgc2l6ZSBvdXRzaWRlIGZyb3plbiBib3VuZFxcJylcXG4gcmVxdWlyZShzbmFwc2hvdD09aWRlbnRpdHlbXFwnc25hcHNob3RfcmVhZG9ubHlcXCddLFxcJ2Zyb3plbiBzbmFwc2hvdCBwcm9vZiBkaWZmZXJzXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc25hcHNob3RfZmlsZVxcJzpmaWxlbmFtZSxcXCdzbmFwc2hvdF9ieXRlc1xcJzpzaXplLFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfcmVhZG9ubHlcXCc6c25hcHNob3R9KSlcXG5lbHNlOnJhaXNlIFZhbHVlRXJyb3IoXFwnZml4ZWQgbmF0aXZlIGJhY2t1cC92ZXJpZnkgcGhhc2UgcmVxdWlyZWRcXCcpXFxuXCJcIlwiXFxuICAjIFN0cmlwIHRoZSBDTEkgYnJhbmNoOiBleGVjIG9ubHkgdGhlIHZlcmlmaWVkIHN0ZGxpYiBmdW5jdGlvbiwgbmV2ZXIgU3RvcmUuXFxuICByZWFkb25seT1wYXlsb2FkW1xcJ3JlYWRvbmx5XFwnXS5zcGxpdChcImlmIF9fbmFtZV9fID09IFxcJ19fbWFpbl9fXFwnOlwiLDEpWzBdXFxuICBpbm5lcj1pbm5lci5yZXBsYWNlKFxcJ19fUkVBRE9OTFlfX1xcJyxyZXByKHJlYWRvbmx5KSkucmVwbGFjZShcXCdfX1NBRkVUWV9fXFwnLHJlcHIocGF5bG9hZFtcXCdyZWNlaXB0X3NhZmV0eVxcJ10pKS5yZXBsYWNlKFxcJ19fQUNUSU9OX19cXCcscmVwcihcXCdkcmlsbC1jb3B5XFwnIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyBlbHNlIHBoYXNlKSkucmVwbGFjZShcXCdfX1BVUlBPU0VfX1xcJyxyZXByKHBheWxvYWRbXFwncHVycG9zZV9jaGVja3NcXCddKSkucmVwbGFjZShcXCdfX1NOQVBTSE9UX19cXCcscmVwcihwYXlsb2FkLmdldChcXCdzbmFwc2hvdF9pZGVudGl0eVxcJykpKVxcbiAgcD1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnZXhlY1xcJyxcXCctaVxcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxwb2RbXFwnbWV0YWRhdGFcXCddW1xcJ25hbWVcXCddLFxcJy1jXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy0tXFwnLFxcJ3B5dGhvblxcJyxcXCctXFwnXSxpbm5lciwxNTApXFxuICByZXF1aXJlKHAucmV0dXJuY29kZT09MCxcXCduYXRpdmUgcGhhc2Ugb3V0Y29tZSB1bnZlcmlmaWVkOyByYXcgb3V0cHV0IHdpdGhoZWxkLCBkbyBub3QgcmV0cnlcXCcpXFxuICBvdXRjb21lPWpzb24ubG9hZHMocC5zdGRvdXQpO3JlcXVpcmUob3V0Y29tZS5nZXQoXFwnYWxsX2NoZWNrc19wYXNzXFwnKSBpcyBUcnVlLFxcJ25hdGl2ZSBwaGFzZSBnYXRlIHJlZnVzZWRcXCcpXFxuICByZXN1bHQudXBkYXRlKG91dGNvbWUscG9kX25hbWU9cG9kW1xcJ21ldGFkYXRhXFwnXVtcXCduYW1lXFwnXSxwb2RfdWlkPXBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXSlcXG4gaWYgcGhhc2UgaW4gKFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2tcXCcpOlxcbiAgbm9kZV9yZWFkPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwnbm9kZXNcXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pO3JlcXVpcmUobm9kZV9yZWFkLnJldHVybmNvZGU9PTAsXFwnbm9kZSBtZXRhZGF0YSB1bmF2YWlsYWJsZVxcJylcXG4gIG5vZGVzPWpzb24ubG9hZHMobm9kZV9yZWFkLnN0ZG91dClbXFwnaXRlbXNcXCddO3JlcXVpcmUobGVuKG5vZGVzKT09MSxcXCdvbmUgdGFyZ2V0IG5vZGUgcmVxdWlyZWRcXCcpO25vZGU9bm9kZXNbMF1cXG4gIHJlcXVpcmUoYW55KGEuZ2V0KFxcJ2FkZHJlc3NcXCcpPT1cXCc5Mi4yMDUuNjIuMjM5XFwnIGZvciBhIGluIG5vZGVbXFwnc3RhdHVzXFwnXVtcXCdhZGRyZXNzZXNcXCddKSxcXCd0YXJnZXQgbm9kZSBhZGRyZXNzIGNoYW5nZWRcXCcpXFxuICBjb25kaXRpb25zPXtjW1xcJ3R5cGVcXCddOmNbXFwnc3RhdHVzXFwnXSBmb3IgYyBpbiBub2RlW1xcJ3N0YXR1c1xcJ11bXFwnY29uZGl0aW9uc1xcJ119XFxuICByZXF1aXJlKGNvbmRpdGlvbnMuZ2V0KFxcJ1JlYWR5XFwnKT09XFwnVHJ1ZVxcJyBhbmQgYWxsKGNvbmRpdGlvbnMuZ2V0KGspPT1cXCdGYWxzZVxcJyBmb3IgayBpbiAoXFwnTWVtb3J5UHJlc3N1cmVcXCcsXFwnRGlza1ByZXNzdXJlXFwnLFxcJ1BJRFByZXNzdXJlXFwnKSksXFwnbm9kZSB1bmhlYWx0aHkgb3IgcHJlc3N1cmVkXFwnKVxcbiAgZGVzY3JpcHRpb249cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2Rlc2NyaWJlXFwnLFxcJ25vZGVcXCcsbm9kZVtcXCdtZXRhZGF0YVxcJ11bXFwnbmFtZVxcJ11dKTtyZXF1aXJlKGRlc2NyaXB0aW9uLnJldHVybmNvZGU9PTAsXFwnaGVhZHJvb20gY2FwdHVyZSB1bmF2YWlsYWJsZVxcJylcXG4gIHRhYmxlPWRlc2NyaXB0aW9uLnN0ZG91dC5zcGxpdChcXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcJywxKVsxXTtyZXF1ZXN0ZWQ9aW50KHJlLnNlYXJjaChyXFwnY3B1XFxcXHMrKFxcXFxkKyltXFwnLHRhYmxlKS5ncm91cCgxKSk7YWxsb2M9bm9kZVtcXCdzdGF0dXNcXCddW1xcJ2FsbG9jYXRhYmxlXFwnXVtcXCdjcHVcXCddO2NhcGFjaXR5PWludChhbGxvY1s6LTFdKSBpZiBhbGxvYy5lbmRzd2l0aChcXCdtXFwnKSBlbHNlIGludChhbGxvYykqMTAwMFxcbiAgcmVxdWlyZShyZXF1ZXN0ZWQ8PWNhcGFjaXR5LFxcJ1JlY3JlYXRlIHJlcXVlc3RlZCBDUFUgZXhjZWVkcyBjYXBhY2l0eVxcJylcXG4gIHJlcXVpcmUobm90IGFwcC5nZXQoXFwnb3BlcmF0aW9uXFwnKSBhbmQgYXBwLmdldChcXCdzdGF0dXNcXCcse30pLmdldChcXCdvcGVyYXRpb25TdGF0ZVxcJyx7fSkuZ2V0KFxcJ3BoYXNlXFwnKSBub3QgaW4gKFxcJ1J1bm5pbmdcXCcsXFwnVGVybWluYXRpbmdcXCcpLFxcJ2V4aXN0aW5nIEFyZ28gb3BlcmF0aW9uIG11c3QgYmUgc2V0dGxlZFxcJylcXG4gIGRlc3RpbmF0aW9uPXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwncmVsZWFzZVxcJyBlbHNlIFxcJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmZcXCdcXG4gIGJvZHk9Y29weS5kZWVwY29weShwYXlsb2FkW1xcJ2NhbmRpZGF0ZVxcJ10gaWYgcGhhc2U9PVxcJ3JlbGVhc2VcXCcgZWxzZSBwYXlsb2FkW1xcJ3JvbGxiYWNrXFwnXSlcXG4gIGRyeT1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnYXBwbHlcXCcsXFwnLS1kcnktcnVuPXNlcnZlclxcJyxcXCctZlxcJyxcXCctXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddLGpzb24uZHVtcHMoYm9keSkpXFxuICByZXF1aXJlKGRyeS5yZXR1cm5jb2RlPT0wLFxcJ2ZyZXNoIG93bmVyIHNlcnZlciBhZG1pc3Npb24gcmVmdXNlZFxcJylcXG4gIGFkbWl0dGVkPWpzb24ubG9hZHMoZHJ5LnN0ZG91dCk7d2FudGVkPWNvcHkuZGVlcGNvcHkoc2VhbGVkKVxcbiAgd2FudGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFIGlmIHBoYXNlPT1cXCdyZWxlYXNlXFwnIGVsc2UgQkFTRVxcbiAgcmVxdWlyZShwcm9qZWN0aW9uKGFkbWl0dGVkKT09d2FudGVkLFxcJ2RyeS1ydW4gY2hhbmdlZCBhbnl0aGluZyBiZXlvbmQgZXhhY3QgaW1hZ2VcXCcpXFxuICBkaWZmPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdkaWZmXFwnLFxcJy1mXFwnLFxcJy1cXCddLGpzb24uZHVtcHMoYm9keSkpO3JlcXVpcmUoZGlmZi5yZXR1cm5jb2RlIGluICgwLDEpLFxcJ2NsaWVudCBkaWZmIHVuYXZhaWxhYmxlXFwnKVxcbiAgb3BlcmF0aW9uPXtcXCdpbml0aWF0ZWRCeVxcJzp7XFwndXNlcm5hbWVcXCc6XFwnY3VzdG9kaWFuLWNvZGV4XFwnfSxcXCdzeW5jXFwnOntcXCdyZXZpc2lvblxcJzpkZXN0aW5hdGlvbixcXCdwcnVuZVxcJzpGYWxzZSxcXG4gICBcXCdyZXNvdXJjZXNcXCc6W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dfX1cXG4gIHBhdGNoPVt7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS91aWRcXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS9yZXNvdXJjZVZlcnNpb25cXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCdyZXNvdXJjZVZlcnNpb25cXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9zcGVjL3NvdXJjZS90YXJnZXRSZXZpc2lvblxcJyxcXCd2YWx1ZVxcJzphcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ119LFxcbiAgIHtcXCdvcFxcJzpcXCdyZXBsYWNlXFwnLFxcJ3BhdGhcXCc6XFwnL3NwZWMvc291cmNlL3RhcmdldFJldmlzaW9uXFwnLFxcJ3ZhbHVlXFwnOmRlc3RpbmF0aW9ufSxcXG4gICB7XFwnb3BcXCc6XFwnYWRkXFwnLFxcJ3BhdGhcXCc6XFwnL29wZXJhdGlvblxcJyxcXCd2YWx1ZVxcJzpvcGVyYXRpb259XVxcbiAgYXJndj1bXFwna3ViZWN0bFxcJyxcXCdwYXRjaFxcJyxcXCdhcHBsaWNhdGlvblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctblxcJyxcXCdhcmdvY2RcXCcsXFwnLS10eXBlPWpzb25cXCcsXFwnLS1wYXRjaC1maWxlPS9kZXYvc3RkaW5cXCcsXFwnLW9cXCcsXFwnbmFtZVxcJ11cXG4gIHBhdGNoZHJ5PXJ1bihhcmd2K1tcXCctLWRyeS1ydW49c2VydmVyXFwnXSxqc29uLmR1bXBzKHBhdGNoKSk7cmVxdWlyZShwYXRjaGRyeS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIG9wZXJhdGlvbiBkcnktcnVuIHJlZnVzZWRcXCcpXFxuICBjaGFuZ2U9cnVuKGFyZ3YsanNvbi5kdW1wcyhwYXRjaCkpXFxuICByZXF1aXJlKGNoYW5nZS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIHBhdGNoIG91dGNvbWUgYW1iaWd1b3VzOyBkbyBub3QgcmV0cnlcXCcpXFxuICByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1UcnVlLG9wZXJhdGlvbl9yZXF1ZXN0ZWQ9VHJ1ZSxzb3VyY2VfcmV2aXNpb249ZGVzdGluYXRpb24sXFxuICAgcmVzb3VyY2VzPW9wZXJhdGlvbltcXCdzeW5jXFwnXVtcXCdyZXNvdXJjZXNcXCddLHBydW5lPUZhbHNlLHJvbGxvdXRfdmVyaWZpZWQ9RmFsc2UsXFxuICAgbGF0ZXN0X2xpdmVfZGF0YWJhc2VfcmV0YWluZWQ9VHJ1ZSxjbGllbnRfZGlmZl9zaGEyNTY9aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpKVxcbiBpZiBwaGFzZSBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBvcD1hcHAuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ29wZXJhdGlvblN0YXRlXFwnLHt9KTtzeW5jPW9wLmdldChcXCdvcGVyYXRpb25cXCcse30pLmdldChcXCdzeW5jXFwnLHt9KVxcbiAgcmVxdWlyZShvcC5nZXQoXFwncGhhc2VcXCcpPT1cXCdTdWNjZWVkZWRcXCcgYW5kIHN5bmMuZ2V0KFxcJ3JldmlzaW9uXFwnKT09dGFyZ2V0IGFuZCBzeW5jLmdldChcXCdwcnVuZVxcJykgaXMgRmFsc2VcXG4gICBhbmQgc3luYy5nZXQoXFwncmVzb3VyY2VzXFwnKT09W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dLFxcJ2V4YWN0IG5hdGl2ZSBBcmdvIG9wZXJhdGlvbiBjb21wbGV0aW9uIHVudmVyaWZpZWRcXCcpXFxuICByZXF1aXJlKGxpdmVbXFwnc3RhdHVzXFwnXS5nZXQoXFwnb2JzZXJ2ZWRHZW5lcmF0aW9uXFwnKT09bGl2ZVtcXCdtZXRhZGF0YVxcJ11bXFwnZ2VuZXJhdGlvblxcJ10sXFwnY29udHJvbGxlciBnZW5lcmF0aW9uIG5vdCBzZXR0bGVkXFwnKVxcbiAgcmVzdWx0LnVwZGF0ZShuYXRpdmVfcm9sbG91dF92ZXJpZmllZD1UcnVlLGN1cnJlbnRfc2NoZW1hNV9kYXRhYmFzZV9yZXRhaW5lZD1UcnVlLHJlY292ZXJ5X3ZlcmlmaWNhdGlvbj1waGFzZT09XFwncm9sbGJhY2stdmVyaWZ5XFwnKVxcbmV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGVycm9yOlxcbiByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1GYWxzZSxmYWlsdXJlX2NsYXNzPXR5cGUoZXJyb3IpLl9fbmFtZV9fLFxcbiAgZmFpbHVyZT1cXCdmaXhlZCBwaGFzZSBvdXRjb21lIHJlZnVzZWQgb3IgYW1iaWd1b3VzOyByYXcgb3V0cHV0IHdpdGhoZWxkOyBubyByZXRyeVxcJylcXG5wcmludChqc29uLmR1bXBzKHJlc3VsdCkpO3N5cy5leGl0KDAgaWYgcmVzdWx0LmdldChcXCdhbGxfY2hlY2tzX3Bhc3NcXCcpIGlzIFRydWUgZWxzZSAxKVxcbidcbiIKICAgIH0sCiAgICAicGFja2V0LXJlZmluZW1lbnQuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIzMWI3MThhNDllZDQ3NTg2NWVkZWExYjJmNmQ3NDlhNTBhM2U2NmY1NmRiYzRmYTliNWZmMTE1OGFjYWVmNTYzIiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm9yaWdpbmFsX2FwcHJvdmVkX3NvdXJjZVwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIixcbiAgXCJvcmlnaW5hbF9wYWNrZXRfYXJjaGl2ZVwiOiBcImluaXRpYWwtYXBwcm92ZWQtYmM2NDk0Y2RcIixcbiAgXCJvcmlnaW5hbF9hcHByb3ZlZF9zdWJtaXNzaW9uX2RpZ2VzdFwiOiBcInNoYTI1NjpmZDc4ZDQ4NjE3NDY3MGUxMmVmYjJmODEyYmFjMDJlNjhmMjk0ZTc3OTFiOTMwMmQwZDQ1OGMwNTMyNDBmNWE5XCIsXG4gIFwib3JpZ2luYWxfZmFpbGVkX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICBcIm9yaWdpbmFsX29sZF91bmNlcnRhaW5fcmV0cnlcIjogZmFsc2UsXG4gIFwicmVzY3VlX3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgXCJyZWZpbmVtZW50c1wiOiBbXG4gICAgXCJleHBsaWNpdGNsb3NlIGxpdmUgV0FMLWF3YXJlIGluc3BlY3RvclwiLFxuICAgIFwiaW1tdXRhYmxlIGZpeGVkIGhhc2gtYm91bmQgZnJvemVuIHNuYXBzaG90IGFsbG93aW5nIHJldGFpbmVkIHN0YWxlU0hNIG9ubHkgd2l0aCB6ZXJvV0FMXCIsXG4gICAgXCJuZXcgc2VwYXJhdGVseSBsaW5rZWQgam91cm5hbCBhbmQgZGlzdGluY3QgbmFtZWQgcmVzY3VlLWNvcHkgYXR0ZW1wdFwiLFxuICAgIFwicmVtYWluaW5nIHBoYXNlIGlucHV0IGV4cGxpY2l0bHkgcmVzY3VlZCByZXN1bHRcIlxuICBdLFxuICBcIm5ld19uYXRpdmVfYWN0aW9uc1wiOiBmYWxzZSxcbiAgXCJuZXdfZm91bmRlcl9hcHByb3ZhbFwiOiBmYWxzZVxufVxuIgogICAgfSwKICAgICJyZWNlaXB0X3NhZmV0eS5weSI6IHsKICAgICAgInNoYTI1NiI6ICI1YzU0MzczZjJkYzRiMDY0MDA4MjI1YzE4NmVmYjFkNWFmZGVlYzM2ZDE1MzUwYmRhMGExMmRlZDk3NjAyZDFiIiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiT25seSBzdHJ1Y3R1cmFsIGNvdW50L2hhc2ggcmVjZWlwdHMgY2FuIGxlYXZlIHRoZSBwcml2YXRlIGV4ZWN1dGlvbiBwaGFzZS5cIlwiXCJcbmRlZiBjb3VudHModmFsdWUpOlxuICAgIGlmIChzZXQodmFsdWUpICE9IHsnc2NoZW1hX3ZlcnNpb24nLCAnbGlmZWN5Y2xlJywgJ291dGJveCcsICdzdWJtaXNzaW9ucycsICdpbnRlZ3JpdHknLFxuICAgICAgICAgICAgICAgICAgICAgICAncmVhZF9vbmx5X3ByZV9vcGVuJywgJ3N0b3JlX2NvbnN0cnVjdGVkJ31cbiAgICAgICAgICAgIG9yIHZhbHVlWydzY2hlbWFfdmVyc2lvbiddICE9IDUgb3IgdmFsdWVbJ2ludGVncml0eSddICE9ICdvaydcbiAgICAgICAgICAgIG9yIHZhbHVlWydyZWFkX29ubHlfcHJlX29wZW4nXSBpcyBub3QgVHJ1ZSBvciB2YWx1ZVsnc3RvcmVfY29uc3RydWN0ZWQnXSBpcyBub3QgRmFsc2VcbiAgICAgICAgICAgIG9yIHNldCh2YWx1ZVsnbGlmZWN5Y2xlJ10pICE9IHsncmVjb3JkcycsICdldmVudHMnLCAncGVuZGluZyd9XG4gICAgICAgICAgICBvciBub3Qgc2V0KHZhbHVlWydvdXRib3gnXSkgPD0geydwZW5kaW5nJywgJ2RlbGl2ZXJlZCcsICdibG9ja2VkJ31cbiAgICAgICAgICAgIG9yIG5vdCBzZXQodmFsdWVbJ3N1Ym1pc3Npb25zJ10pIDw9IHsncHJlcGFyZWQnLCAnaW5fZmxpZ2h0JywgJ2NvbmZpcm1lZCcsICd1bnJlc29sdmVkJ30pOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdjb3VudC1vbmx5IHJlY2VpcHQgc2hhcGUvc3RhdGUgcmVmdXNlZDsgdmFsdWVzIHdpdGhoZWxkJylcbiAgICBmb3IgZ3JvdXAgaW4gKCdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyk6XG4gICAgICAgIGlmIGFueSh0eXBlKG51bWJlcikgaXMgbm90IGludCBvciBudW1iZXIgPCAwIG9yIG51bWJlciA+IDEwKioxMlxuICAgICAgICAgICAgICAgZm9yIG51bWJlciBpbiB2YWx1ZVtncm91cF0udmFsdWVzKCkpOlxuICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignY291bnQtb25seSByZWNlaXB0IHZhbHVlcyByZWZ1c2VkJylcbiAgICByZXR1cm4gdmFsdWVcbiIKICAgIH0sCiAgICAicm9vdC1hdXRob3JpdHktcmVjZWlwdC10ZW1wbGF0ZS5qc29uIjogewogICAgICAic2hhMjU2IjogImRiMjhkMDNlM2M0NmI0ZGU1MmRjNDA0YzkxMjA1NDQ4M2Y0YTJhYWE2YzRmNDc2Yjc4OTJjYWIyYTVmNDA4ZDQiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwicHJvcG9zYWxfaWRcIjogXCJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MVwiLFxuICBcIm1lbW9faWRcIjogXCJpbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm1lbW9fc2hhMjU2XCI6IG51bGwsXG4gIFwic291cmNlX3JldmlzaW9uXCI6IG51bGwsXG4gIFwiYWN0aXZhdGlvblwiOiBcIlBFTkRJTkdcIixcbiAgXCJhdXRob3JpdHlfbW9kZVwiOiBcIkFETUlOSVNURVJcIixcbiAgXCJ0YXJnZXRcIjogXCJyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uXCIsXG4gIFwidmVyaWZpY2F0aW9uX21ldGhvZFwiOiBcInJvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFja1wiLFxuICBcInJ1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudFwiOiBmYWxzZSxcbiAgXCJ2ZXJpZmllZF9hdFwiOiBudWxsLFxuICBcImFjY2VwdGVkX2F0XCI6IG51bGwsXG4gIFwicmV2aWV3X21lbW9faWRcIjogbnVsbCxcbiAgXCJhcHByb3ZhbF9pZFwiOiBudWxsLFxuICBcImRpc3Bvc2l0aW9uX2lkXCI6IG51bGwsXG4gIFwibmF0aXZlX291dGNvbWVfc2hhMjU2XCI6IG51bGwsXG4gIFwiZXhlY3V0b3JfcGxhbl9zaGEyNTZcIjogXCI0ZDU1MzBlNzQxOGY2MzhiMTBjY2ZmMGUwZDlhMDcyN2FkYzY0YTdmM2E0NTkwN2Y2ZGViNTczOWFkMmFkYzg1XCIsXG4gIFwib3V0Y29tZV9xdWVyeVwiOiBcIi9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0yXCIsXG4gIFwicmV2aWV3X21lbW9fdmVyc2lvblwiOiAxXG59XG4iCiAgICB9LAogICAgInRlc3RfZXhlY3V0aW9uLnB5IjogewogICAgICAic2hhMjU2IjogImIyNTA0NDEyODI1MTM4NjJlZWI5OTBiMThkMDFiYjFlYWZlNzg3YjkzNGQ2NzBhNzVhMmJmYWE5ZjVjZmI4OWMiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTeW50aGV0aWMgY3VzdG9keS90cmFuc3BvcnQgdGVzdHMuIE5vIG5hdGl2ZSBkYXRhLCBEb2NrZXIgb3IgY2x1c3RlciBhY3Rpb24uXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaW9cbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0ZW1wZmlsZVxuaW1wb3J0IHVuaXR0ZXN0XG5mcm9tIHVuaXR0ZXN0Lm1vY2sgaW1wb3J0IHBhdGNoXG5mcm9tIGNvbnRleHRsaWIgaW1wb3J0IHJlZGlyZWN0X3N0ZG91dFxuXG5pbXBvcnQgYWN0dWF0b3JcbmZyb20gYXV0aG9yaXR5X2pvdXJuYWwgaW1wb3J0IEpvdXJuYWwsIGF1dGhvcml0eVxuZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuZnJvbSByZWNlaXB0X3NhZmV0eSBpbXBvcnQgY291bnRzXG5cbkNBU0UgPSBQYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24vZG9jcy9ldmlkZW5jZS8yMDI2LTEwLTExLXB1cnBvc2UtaW1hZ2UtcmVsZWFzZScpXG5OT1cgPSBkYXRldGltZS5kYXRldGltZSgyMDI2LCAxMCwgMTEsIDIsIDAsIHR6aW5mbz1kYXRldGltZS50aW1lem9uZS51dGMpXG5SRVZJU0lPTiA9ICdlJyAqIDQwXG5DT1VOVCA9IHsnc2NoZW1hX3ZlcnNpb24nOiA1LCAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlLFxuICAgICAgICAgJ2xpZmVjeWNsZSc6IHsncmVjb3Jkcyc6IDMsICdldmVudHMnOiA4LCAncGVuZGluZyc6IDF9LFxuICAgICAgICAgJ291dGJveCc6IHsncGVuZGluZyc6IDIsICdkZWxpdmVyZWQnOiAxMH0sICdzdWJtaXNzaW9ucyc6IHsnY29uZmlybWVkJzogMSwgJ3VucmVzb2x2ZWQnOiAxfX1cblxuXG5kZWYgYWNjZXB0ZWQoKTpcbiAgICBhcHByb3ZhbCA9ICcxMTExMTExMS0xMTExLTQxMTEtODExMS0xMTExMTExMTExMTEnXG4gICAgcmV2aWV3ID0gJ3Jldmlldy0yMjIyMjIyMi0yMjIyLTQyMjItODIyMi0yMjIyMjIyMjIyMjInXG4gICAgZGlzcG9zaXRpb24gPSAnZGlzcC0zMzMzMzMzMy0zMzMzLTQzMzMtODMzMy0zMzMzMzMzMzMzMzMnXG4gICAgcmVjZWlwdCA9IHsncHJvcG9zYWxfaWQnOiAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnLFxuICAgICAgICAgICAgICAgJ21lbW9faWQnOiAnaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEnLCAnbWVtb192ZXJzaW9uJzogMixcbiAgICAgICAgICAgICAgICdtZW1vX3NoYTI1Nic6ICdhJyAqIDY0LCAnc291cmNlX3JldmlzaW9uJzogUkVWSVNJT04sICdhY3RpdmF0aW9uJzogJ0FQUFJPVkVEJyxcbiAgICAgICAgICAgICAgICdhdXRob3JpdHlfbW9kZSc6ICdBRE1JTklTVEVSJywgJ3RhcmdldCc6ICdyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uJyxcbiAgICAgICAgICAgICAgICd2ZXJpZmljYXRpb25fbWV0aG9kJzogJ3Jvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFjaycsICdydW50aW1lX2F1dGhlbnRpY2F0ZWRfZ3JhbnQnOiBGYWxzZSwgJ291dGNvbWVfcXVlcnknOiAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgICAgJ3ZlcmlmaWVkX2F0JzogJzIwMjYtMTAtMTFUMDI6MDA6MDBaJywgJ2FjY2VwdGVkX2F0JzogJzIwMjYtMTAtMTFUMDE6NTk6MDBaJyxcbiAgICAgICAgICAgICAgICdyZXZpZXdfbWVtb19pZCc6IHJldmlldywgJ2FwcHJvdmFsX2lkJzogYXBwcm92YWwsICdkaXNwb3NpdGlvbl9pZCc6IGRpc3Bvc2l0aW9ufVxuICAgIG91dGNvbWUgPSB7J21lbW9faWQnOiByZWNlaXB0WydtZW1vX2lkJ10sICdyZXZpZXcnOiB7J21lbW9faWQnOiByZXZpZXcsICdzdGFsZSc6IEZhbHNlLCAnaW50YWtlX3N0YXRlJzogJ3JlYWR5J30sXG4gICAgICAgICAgICAgICAnZGlzcG9zaXRpb25zJzogW3snYXBwcm92YWxfaWQnOiBOb25lLCAnc3VibWlzc2lvbl9zdGF0ZSc6ICdjb25maXJtZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Rpc3Bvc2l0aW9uJzogeyd2ZXJiJzogJ2FjY2VwdCcsICdtZW1vX3ZlcnNpb24nOiAxLCAnbWVtb19pZCc6IHJldmlldyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXBwcm92YWxfaWQnOiBhcHByb3ZhbCwgJ2lkJzogZGlzcG9zaXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FjdG9yJzogeydraW5kJzogJ3BlcnNvbicsICdzdWInOiAndWlkPXBsYXRmb3JtLXJvb3Qsb3U9cGVvcGxlLGRjPW5ldGtpbmdkb20sZGM9bG9jYWwnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXQnOiByZWNlaXB0WydhY2NlcHRlZF9hdCddfX1dfVxuICAgIHJldHVybiByZWNlaXB0LCBvdXRjb21lXG5cblxuY2xhc3MgQXV0aG9yaXR5QW5kQ3VzdG9keSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIHRlc3RfZXhhY3RfbmVzdGVkX2ZvdW5kZXJfcmVjZWlwdF9ub3RfdG9wX2xldmVsX2FwcHJvdmFsKHNlbGYpOlxuICAgICAgICByZWNlaXB0LCBvdXRjb21lID0gYWNjZXB0ZWQoKVxuICAgICAgICByZXN1bHQgPSBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgJ2EnICogNjQsIFJFVklTSU9OLCAnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBOT1cpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydhcHByb3ZhbF9pZCddLCByZWNlaXB0WydhcHByb3ZhbF9pZCddKVxuXG4gICAgZGVmIHRlc3RfcGVuZGluZ19zdGFsZV93cm9uZ19hY3Rvcl92ZXJzaW9uX2FuZF9iaW5kaW5nX3JlZnVzZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSByLCBvOiByLnVwZGF0ZShhY3RpdmF0aW9uPSdQRU5ESU5HJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUobWVtb19zaGEyNTY9J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZShzb3VyY2VfcmV2aXNpb249J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZSh0YXJnZXQ9J290aGVyJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpZWRfYXQ9JzIwMjYtMTAtMTFUMDE6MDA6MDBaJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpY2F0aW9uX21ldGhvZD0nY2FsbGVyLWFzc2VydGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUocnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50PVRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ3JldmlldyddLnVwZGF0ZShzdGFsZT1UcnVlKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydyZXZpZXcnXS51cGRhdGUoaW50YWtlX3N0YXRlPSdwZW5kaW5nJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ11bMF0udXBkYXRlKHN1Ym1pc3Npb25fc3RhdGU9J3VucmVzb2x2ZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydkaXNwb3NpdGlvbnMnXVswXVsnZGlzcG9zaXRpb24nXS51cGRhdGUobWVtb192ZXJzaW9uPTMpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddLnVwZGF0ZShhY3Rvcj17J2tpbmQnOiAnYWdlbnQnLCAnc3ViJzogJ3BsYXRmb3JtLXJvb3QnfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ10uYXBwZW5kKGNvcHkuZGVlcGNvcHkob1snZGlzcG9zaXRpb25zJ11bMF0pKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShyLCBvKVxuICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyZWxlYXNlJywgTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwaXJlZF93aW5kb3dfYW5kX3Vua25vd25fcGhhc2VfcmVmdXNlKHNlbGYpOlxuICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgYXV0aG9yaXR5KHIsIG8sICdhJyAqIDY0LCBSRVZJU0lPTiwgJ2FyYml0cmFyeScsIE5PVylcbiAgICAgICAgbGF0ZSA9IGRhdGV0aW1lLmRhdGV0aW1lKDIwMjYsIDEwLCAxMywgdHppbmZvPWRhdGV0aW1lLnRpbWV6b25lLnV0YylcbiAgICAgICAgclsndmVyaWZpZWRfYXQnXSA9IGxhdGUuaXNvZm9ybWF0KClcbiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyb2xsYmFjaycsIGxhdGUpXG5cbiAgICBkZWYgdGVzdF9kdXJhYmxlX2ludGVudF9wcmVjZWRlc19kaXNwYXRjaF9hbmRfbmV2ZXJfcmV0cmllcyhzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQgPSBQYXRoKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIG9zLmNobW9kKHBhcmVudCwgMG83MDApXG4gICAgICAgICAgICBqb3VybmFsID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICBqb3VybmFsLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIHsnYXBwcm92YWxfaWQnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChqc29uLmxvYWRzKGpvdXJuYWwucGF0aC5yZWFkX3RleHQoKSlbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydzdGF0ZSddLCAnUlVOTklORycpXG4gICAgICAgICAgICBqb3VybmFsLmNsb3NlKCkgICMgc2ltdWxhdGVkIGNyYXNoIGJlZm9yZSByZXN1bHRcbiAgICAgICAgICAgIHJlY292ZXJlZCA9IEpvdXJuYWwocGFyZW50LCB7J2Nhc2UnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICByZWNvdmVyZWQuc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCB7fSlcbiAgICAgICAgICAgIHJlY292ZXJlZC5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9waGFzZV9vcmRlcl9hbmRfdW5jZXJ0YWluX3JlbGVhc2VfYWxsb3dzX29ubHlfZGlzdGluY3RfcmVjb3Zlcnkoc2VsZik6XG4gICAgICAgIHdpdGggdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZGlyZWN0b3J5OlxuICAgICAgICAgICAgb3MuY2htb2QoZGlyZWN0b3J5LCAwbzcwMClcbiAgICAgICAgICAgIGogPSBKb3VybmFsKGRpcmVjdG9yeSwgeydjYXNlJzogJ2ZpeHR1cmUnfSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgai5zdGFydCgncmVsZWFzZScsIHt9KVxuICAgICAgICAgICAgZm9yIHBoYXNlIGluIGFjdHVhdG9yLlBIQVNFU1s6NV06XG4gICAgICAgICAgICAgICAgai5zdGFydChwaGFzZSwge30pXG4gICAgICAgICAgICAgICAgai5maW5pc2gocGhhc2UsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICBqLmZpbmlzaCgncmVsZWFzZScsIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2V9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGouc3RhcnQoJ3ZlcmlmeScsIHt9KVxuICAgICAgICAgICAgai5zdGFydCgncm9sbGJhY2snLCB7fSlcbiAgICAgICAgICAgIGouZmluaXNoKCdyb2xsYmFjaycsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X3NlY3JldF9vcl91bmtub3duX2NoaWxkX291dHB1dF9pc193aXRoaGVsZChzZWxmKTpcbiAgICAgICAgZm9yIGJvZHkgaW4gKCdub3QtanNvbicsICd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwidG9rZW5cIjpcInByaXZhdGUtdmFsdWVcIn0nLFxuICAgICAgICAgICAgICAgICAgICAgJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJzbmFwc2hvdF9yZWFkb25seVwiOntcInNjaGVtYV92ZXJzaW9uXCI6NX19Jyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGFjdHVhdG9yLmpzb25fcmVzdWx0KHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwgMCwgYm9keSwgJycpKVxuICAgICAgICB3cm9uZyA9IGNvcHkuZGVlcGNvcHkoQ09VTlQpXG4gICAgICAgIHdyb25nWydvdXRib3gnXSA9IHsncHJpdmF0ZS1yb3ctdmFsdWUnOiAxfVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgY291bnRzKHdyb25nKVxuICAgICAgICBjb3VudHMoQ09VTlQpICAjIGJsb2NrZWQvdW5yZXNvbHZlZCBjb3VudHMgYXJlIG5vdCByZXF1aXJlZCB0byBiZSB6ZXJvLlxuXG4gICAgZGVmIHRlc3RfYmluYXJ5X2NvcHlfaXNfYm91bmRlZF9wcml2YXRlX2FuZF9uZXZlcl9lY2hvZWQoc2VsZik6XG4gICAgICAgIGJsb2IgPSBiJ3N5bnRoZXRpYyBwcml2YXRlIGZpeHR1cmUgYnl0ZXMnXG4gICAgICAgIGRpZ2VzdCA9IF9faW1wb3J0X18oJ2hhc2hsaWInKS5zaGEyNTYoYmxvYikuaGV4ZGlnZXN0KClcbiAgICAgICAgbWV0YWRhdGEgPSB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdzbmFwc2hvdF9maWxlJzogJ2RyaWxsLnNxbGl0ZScsICdzbmFwc2hvdF9ieXRlcyc6IGxlbihibG9iKSxcbiAgICAgICAgICAgICAgICAgICAgJ3NuYXBzaG90X3NoYTI1Nic6IGRpZ2VzdCwgJ3NuYXBzaG90X3JlYWRvbmx5JzogQ09VTlQsXG4gICAgICAgICAgICAgICAgICAgICdwb2RfbmFtZSc6ICdmaXh0dXJlLXBvZCcsICdwb2RfdWlkJzogJ2ZpeHR1cmUtdWlkJ31cbiAgICAgICAgam91cm5hbCA9IHR5cGUoJ0ZpeHR1cmVKb3VybmFsJywgKCksIHsnZGF0YSc6IHsnaWRlbnRpdHknOiB7J3JlY292ZXJ5X2FuY2hvcic6IHsnYmFja3VwX3Jlc3VsdCc6IG1ldGFkYXRhfX19fSkoKVxuICAgICAgICByZWFsX3BvcGVuID0gc3VicHJvY2Vzcy5Qb3BlblxuICAgICAgICBmb3IgZXh0cmEgaW4gKGInJywgYidvdmVyc2l6ZWQnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGV4dHJhPWV4dHJhKSwgdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZm9sZGVyOlxuICAgICAgICAgICAgICAgIG9zLmNobW9kKGZvbGRlciwgMG83MDApXG4gICAgICAgICAgICAgICAgb3V0cHV0ID0gaW8uU3RyaW5nSU8oKVxuXG4gICAgICAgICAgICAgICAgZGVmIGNoaWxkKCphcmdzLCAqKmt3YXJncyk6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFsX3BvcGVuKFtzeXMuZXhlY3V0YWJsZSwgJy1jJywgJ2ltcG9ydCBzeXM7c3lzLnN0ZG91dC5idWZmZXIud3JpdGUoJyArIHJlcHIoYmxvYiArIGV4dHJhKSArICcpJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwpXG5cbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwgJ0NVU1RPRFknLCBQYXRoKGZvbGRlcikpLCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdyZW1vdGUnLCByZXR1cm5fdmFsdWU9bWV0YWRhdGEpLCBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2goJ3N1YnByb2Nlc3MuUG9wZW4nLCBzaWRlX2VmZmVjdD1jaGlsZCksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgICAgICAgICBpZiBleHRyYTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWF0b3IuY29weV9zbmFwc2hvdCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBSRVZJU0lPTiwge30sIGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBhY3R1YXRvci5jb3B5X3NuYXBzaG90KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIFJFVklTSU9OLCB7fSwgam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29mZl9jbHVzdGVyX3ByaXZhdGVfY29weV92ZXJpZmllZCddKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoUGF0aChmb2xkZXIpIC8gJ2RyaWxsLnNxbGl0ZScpLnJlYWRfYnl0ZXMoKSwgYmxvYilcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG91dHB1dC5nZXR2YWx1ZSgpLCAnJylcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKChQYXRoKGZvbGRlcikgLyAnZHJpbGwuc3FsaXRlJykuc3RhdCgpLnN0X21vZGUgJiAwbzc3NywgMG82MDApXG5cbiAgICBkZWYgdGVzdF9yZWNyZWF0ZWRfb2ZmbGluZV92b2x1bWVfY2Fubm90X2JlX2RlbGV0ZWQoc2VsZik6XG4gICAgICAgIGlkZW50aXR5ID0geydOYW1lJzogYWN0dWF0b3IuVk9MVU1FLCAnTGFiZWxzJzogeydub25jZSc6ICdvbGQnfSwgJ0NyZWF0ZWRBdCc6ICdvbGQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7XG4gICAgICAgICAgICAnb2ZmbGluZS12ZXJpZnknOiB7J3Jlc3VsdCc6IHsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknOiBpZGVudGl0eX19fX19KSgpXG4gICAgICAgIGluc3BlY3RlZCA9IFt7KippZGVudGl0eSwgJ0NyZWF0ZWRBdCc6ICdyZWNyZWF0ZWQnfV1cbiAgICAgICAgd2l0aCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdkb2NrZXInLCByZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBqc29uLmR1bXBzKGluc3BlY3RlZCksICcnKSkgYXMgbW9ja2VkOlxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBhY3R1YXRvci5jbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobW9ja2VkLmNhbGxfY291bnQsIDEpXG5cbiAgICBkZWYgdGVzdF9vZmZsaW5lX3Bvc3RfYWRtaW5faW50ZWdyaXR5X2FuZF9vcmlnaW5hbF9oYXNoX2FyZV9yZWNoZWNrZWQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdub25lJywgJ3Bvc3QtaW50ZWdyaXR5JywgJ29yaWdpbmFsLWhhc2gnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgZm9sZGVyPVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChmb2xkZXIsMG83MDApXG4gICAgICAgICAgICAgICAgc25hcHNob3Q9Zm9sZGVyLydkcmlsbC5zcWxpdGUnO3NuYXBzaG90LndyaXRlX2J5dGVzKGIncHJpdmF0ZSBzeW50aGV0aWMgc25hcHNob3QnKTtvcy5jaG1vZChzbmFwc2hvdCwwbzYwMClcbiAgICAgICAgICAgICAgICBkaWdlc3Q9YWN0dWF0b3Iuc2hhKHNuYXBzaG90KVxuICAgICAgICAgICAgICAgIHByaW9yPXsnc25hcHNob3Rfc2hhMjU2JzpkaWdlc3QsJ3NuYXBzaG90X3JlYWRvbmx5JzpDT1VOVH1cbiAgICAgICAgICAgICAgICBqb3VybmFsPXR5cGUoJ0ZpeHR1cmVKb3VybmFsJywoKSx7J2RhdGEnOnsncGhhc2VzJzp7J2RyaWxsLWNvcHktcmVzY3VlLXIxJzp7J3Jlc3VsdCc6cHJpb3J9LCdvZmZsaW5lLXZlcmlmeSc6eydhdHRlbXB0X2lkJzonbm9uY2UnfX19LCdub3RlJzpsYW1iZGEgKmFyZ3M6Tm9uZX0pKClcbiAgICAgICAgICAgICAgICByZWFkcz1bXVxuICAgICAgICAgICAgICAgIHZvbHVtZT17J05hbWUnOmFjdHVhdG9yLlZPTFVNRSwnTGFiZWxzJzp7J2luZm9ybWVkLWRlY2lzaW9uLmNhc2UnOidpbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLCdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOidvZmZsaW5lLXJlc3RvcmUtb25seScsJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQnOidub25jZSd9LCdEcml2ZXInOidsb2NhbCcsJ1Njb3BlJzonbG9jYWwnLCdDcmVhdGVkQXQnOidmaXh0dXJlJywnT3B0aW9ucyc6Tm9uZX1cbiAgICAgICAgICAgICAgICBkZWYgZG9ja2VyKGFyZ3YsIGJvZHk9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgICAgICAgICBpZiBhcmd2WzBdPT0naW5mbyc6Ym9keT1qc29uLmR1bXBzKCdibnQtbGFwMDAxJylcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdscyddOmJvZHk9JydcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdjcmVhdGUnXTpib2R5PWFjdHVhdG9yLlZPTFVNRVxuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2luc3BlY3QnXTpib2R5PWpzb24uZHVtcHMoW3ZvbHVtZV0pXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJyBpbiBhcmd2OlxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keT1qc29uLmR1bXBzKHtrZXk6Q09VTlRba2V5XSBmb3Iga2V5IGluICgnc2NoZW1hX3ZlcnNpb24nLCdsaWZlY3ljbGUnLCdvdXRib3gnLCdzdWJtaXNzaW9ucycpfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J29yaWdpbmFsLWhhc2gnOnNuYXBzaG90LndyaXRlX2J5dGVzKGInY2hhbmdlZCBzeW50aGV0aWMgb3JpZ2luYWwnKVxuICAgICAgICAgICAgICAgICAgICBlbGlmICctLWVudHJ5cG9pbnQnIGluIGFyZ3YgYW5kICdweXRob24nIGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkcy5hcHBlbmQoYXJndik7cHJvb2Y9Y29weS5kZWVwY29weShDT1VOVClcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihyZWFkcyk9PTIgYW5kIGRlZmVjdD09J3Bvc3QtaW50ZWdyaXR5Jzpwcm9vZlsnaW50ZWdyaXR5J109J2NvcnJ1cHQnXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5PWpzb24uZHVtcHMocHJvb2YpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6cmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgb2ZmbGluZSBjb21tYW5kJylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LDAsYm9keSwnJylcbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwnQ1VTVE9EWScsZm9sZGVyKSxwYXRjaC5vYmplY3QoYWN0dWF0b3IsJ0NBU0UnLENBU0UpLHBhdGNoLm9iamVjdChhY3R1YXRvciwnZG9ja2VyJyxzaWRlX2VmZmVjdD1kb2NrZXIpLHBhdGNoKCdzdWJwcm9jZXNzLnJ1bicscmV0dXJuX3ZhbHVlPXN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwwLCd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwicHJpdmF0ZV9jb3B5X3ZlcmlmaWVkXCI6dHJ1ZX0nLCcnKSk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J25vbmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0PWFjdHVhdG9yLm9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlc3VsdFsnb2ZmbGluZV9wb3N0X2FkbWluX3JlYWRvbmx5J10sQ09VTlQpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydFRydWUocmVzdWx0WydvcmlnaW5hbF9zbmFwc2hvdF9oYXNoX3VuY2hhbmdlZCddKVxuICAgICAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTphY3R1YXRvci5vZmZsaW5lX3ZlcmlmeShqb3VybmFsKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlYWRzKSwyKVxuXG5cbmNsYXNzIEZpeGVkTmF0aXZlUHJvZ3JhbSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIGZpeHR1cmUoc2VsZik6XG4gICAgICAgIHNlYWxlZCA9IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgICAgIGxpdmUgPSBjb3B5LmRlZXBjb3B5KHNlYWxlZClcbiAgICAgICAgbGl2ZVsnbWV0YWRhdGEnXS51cGRhdGUoZ2VuZXJhdGlvbj00MilcbiAgICAgICAgbGl2ZVsnc3RhdHVzJ10gPSB7J3JlYWR5UmVwbGljYXMnOiAxLCAndXBkYXRlZFJlcGxpY2FzJzogMSwgJ29ic2VydmVkR2VuZXJhdGlvbic6IDQyfVxuICAgICAgICBkZXBlbmRlbmNpZXMgPSBqc29uLmxvYWRzKChDQVNFIC8gJ3NlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY20gPSBjb3B5LmRlZXBjb3B5KGRlcGVuZGVuY2llc1snY29uZmlnbWFwJ10pXG4gICAgICAgIGNtLnBvcCgnY2Fub25pY2FsX2RhdGFfc2hhMjU2JylcbiAgICAgICAgc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UgLyAnY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBzb3VyY2Vfc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UucGFyZW50c1syXSAvICdkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY21bJ2RhdGEnXSA9IG5leHQoeCBmb3IgeCBpbiBzb3VyY2Vfc2VydmljZVsnaXRlbXMnXSBpZiB4WydraW5kJ10gPT0gJ0NvbmZpZ01hcCcpWydkYXRhJ11cbiAgICAgICAgcHZjID0gY29weS5kZWVwY29weShkZXBlbmRlbmNpZXNbJ3B2YyddKVxuICAgICAgICBwdmNbJ3N0YXR1cyddID0geydwaGFzZSc6ICdCb3VuZCd9XG4gICAgICAgIGFwcCA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQnLCAncmVzb3VyY2VWZXJzaW9uJzogJzE3J30sXG4gICAgICAgICAgICAgICAnc3BlYyc6IHsnc291cmNlJzogeydyZXBvVVJMJzogJ2h0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uLmdpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYXRoJzogJ2RlcGxveS9saWZlY3ljbGUnLCAndGFyZ2V0UmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZid9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2Rlc3RpbmF0aW9uJzogeyduYW1lc3BhY2UnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnc2VydmVyJzogJ2h0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yyd9fX1cbiAgICAgICAgb2JqZWN0cyA9IHsnZGVwbG95bWVudCc6IGxpdmUsICdjb25maWdtYXAnOiBjbSwgJ3B2Yyc6IHB2YywgJ2FwcGxpY2F0aW9uJzogYXBwfVxuICAgICAgICBwYXlsb2FkID0geydwaGFzZSc6ICdyZWxlYXNlJywgJ3NvdXJjZV9yZXZpc2lvbic6IFJFVklTSU9OLCAnYXBwcm92YWwnOiB7fSwgJ3NlYWxlZCc6IHNlYWxlZCxcbiAgICAgICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJzogZGVwZW5kZW5jaWVzLCAnY2FuZGlkYXRlJzogc2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAncmVhZG9ubHknOiAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSwncHVycG9zZV9jaGVja3MnOihDQVNFLydjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICAgICAncmVjZWlwdF9zYWZldHknOiAoUGF0aChfX2ZpbGVfXykucGFyZW50IC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCl9XG4gICAgICAgIHJldHVybiBvYmplY3RzLCBwYXlsb2FkXG5cbiAgICBkZWYgZXhlY3V0ZV9mYWtlKHNlbGYsIG9iamVjdHMsIHBheWxvYWQsIGFtYmlndW91cz1GYWxzZSwgc2NoZW1hX3JlZnVzZWQ9RmFsc2UpOlxuICAgICAgICB3cml0ZXMgPSBbXVxuICAgICAgICBjYWxscyA9IFtdXG5cbiAgICAgICAgZGVmIGZha2UoYXJndiwgaW5wdXQ9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgY2FsbHMuYXBwZW5kKGFyZ3YpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZ2V0J106XG4gICAgICAgICAgICAgICAga2luZCA9IGFyZ3ZbMl1cbiAgICAgICAgICAgICAgICBpZiBraW5kIGluIG9iamVjdHM6XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSBvYmplY3RzW2tpbmRdXG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdwb2RzJzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnaXRlbXMnOiBbeydtZXRhZGF0YSc6IHsnbmFtZSc6ICdmaXh0dXJlLXBvZCcsICd1aWQnOiAncG9kLXVpZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnb3duZXJSZWZlcmVuY2VzJzogW3sna2luZCc6ICdSZXBsaWNhU2V0JywgJ25hbWUnOiAnZml4dHVyZS1ycycsICd1aWQnOiAncnMtdWlkJ31dfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwZWMnOiBvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RhdHVzJzogeydwaGFzZSc6ICdSdW5uaW5nJywgJ2NvbnRhaW5lclN0YXR1c2VzJzogW3snbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywncmVhZHknOiBUcnVlfV19fV19XG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdyZXBsaWNhc2V0JzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICdycy11aWQnLCAnb3duZXJSZWZlcmVuY2VzJzogW1xuICAgICAgICAgICAgICAgICAgICAgICAgeydraW5kJzogJ0RlcGxveW1lbnQnLCAndWlkJzogcGF5bG9hZFsnc2VhbGVkJ11bJ21ldGFkYXRhJ11bJ3VpZCddfV19fVxuICAgICAgICAgICAgICAgIGVsaWYga2luZCA9PSAnbm9kZXMnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydpdGVtcyc6IFt7J21ldGFkYXRhJzogeyduYW1lJzogJ2ZpeHR1cmUtbm9kZSd9LCAnc3RhdHVzJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FkZHJlc3Nlcyc6IFt7J2FkZHJlc3MnOiAnOTIuMjA1LjYyLjIzOSd9XSwgJ2FsbG9jYXRhYmxlJzogeydjcHUnOiAnNCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbmRpdGlvbnMnOiBbeyd0eXBlJzoga2V5LCAnc3RhdHVzJzogJ1RydWUnIGlmIGtleSA9PSAnUmVhZHknIGVsc2UgJ0ZhbHNlJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBrZXkgaW4gKCdSZWFkeScsICdNZW1vcnlQcmVzc3VyZScsICdEaXNrUHJlc3N1cmUnLCAnUElEUHJlc3N1cmUnKV19fV19XG4gICAgICAgICAgICAgICAgZWxzZTpcbiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgZml4ZWQgbWV0YWRhdGEgcm91dGUnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhib2R5KSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddOlxuICAgICAgICAgICAgICAgIGlmIHNjaGVtYV9yZWZ1c2VkOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDEsICcnLCAnd2l0aGhlbGQnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyh7XG4gICAgICAgICAgICAgICAgICAgICdhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlLCAnbGl2ZV9yZWFkb25seV9zY2hlbWFfaW50ZWdyaXR5X2NvdW50cyc6IENPVU5UfSksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2FwcGx5J106XG4gICAgICAgICAgICAgICAgYWRtaXR0ZWQgPSBjb3B5LmRlZXBjb3B5KHBheWxvYWRbJ3NlYWxlZCddKVxuICAgICAgICAgICAgICAgIGFkbWl0dGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gKGFjdHVhdG9yLklNQUdFIGlmIHBheWxvYWRbJ3BoYXNlJ109PSdyZWxlYXNlJyBlbHNlIHBheWxvYWRbJ3NlYWxlZCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhhZG1pdHRlZCksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2Rlc2NyaWJlJ106XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnQWxsb2NhdGVkIHJlc291cmNlczpcXG4gY3B1IDM0NjBtICg4NiUpXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZGlmZiddOlxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJy1pbWFnZTogYmFzZVxcbitpbWFnZTogY2FuZGlkYXRlXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXTpcbiAgICAgICAgICAgICAgICBpZiAnLS1kcnktcnVuPXNlcnZlcicgbm90IGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgIHdyaXRlcy5hcHBlbmQoanNvbi5sb2FkcyhpbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIGlmIGFtYmlndW91czpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJycsICd3aXRoaGVsZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnYXBwbGljYXRpb24uYXJnb3Byb2ouaW8vaW5mb3JtZWQtZGVjaXNpb25cXG4nLCAnJylcbiAgICAgICAgICAgIHJhaXNlIEFzc2VydGlvbkVycm9yKCd1bmV4cGVjdGVkIGNvbW1hbmQnKVxuXG4gICAgICAgIHNvdXJjZSA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAgICAgJ19fR1VBUkRfXycsIHJlcHIoKENBU0UgLyAnY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpKVxuICAgICAgICBvdXRwdXQgPSBpby5TdHJpbmdJTygpXG4gICAgICAgIHdpdGggcGF0Y2goJ3N1YnByb2Nlc3MucnVuJywgc2lkZV9lZmZlY3Q9ZmFrZSksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIGV4ZWMoY29tcGlsZShzb3VyY2UsICdmaXhlZC1uYXRpdmUtZml4dHVyZScsICdleGVjJyksIHsnX19uYW1lX18nOiAnX19maXh0dXJlX18nfSlcbiAgICAgICAgICAgIGV4Y2VwdCAoVmFsdWVFcnJvciwgU3lzdGVtRXhpdCk6XG4gICAgICAgICAgICAgICAgcGFzc1xuICAgICAgICByZWNlaXB0ID0ganNvbi5sb2FkcyhvdXRwdXQuZ2V0dmFsdWUoKSkgaWYgb3V0cHV0LmdldHZhbHVlKCkgZWxzZSB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlfVxuICAgICAgICByZXR1cm4gcmVjZWlwdCwgd3JpdGVzLCBjYWxsc1xuXG4gICAgZGVmIHRlc3Rfb25seV9leGlzdGluZ19hcHBsaWNhdGlvbl9vcGVyYXRpb25fYW5kX2RlcGxveW1lbnRfYXJlX3JlcXVlc3RlZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBvcGVyYXRpb24gPSB3cml0ZXNbMF1bLTFdWyd2YWx1ZSddXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2Uob3BlcmF0aW9uWydzeW5jJ11bJ3BydW5lJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwob3BlcmF0aW9uWydzeW5jJ11bJ3Jlc291cmNlcyddLCBbXG4gICAgICAgICAgICB7J2dyb3VwJzogJ2FwcHMnLCAna2luZCc6ICdEZXBsb3ltZW50JywgJ25hbWUnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnbmFtZXNwYWNlJzogJ2luZm9ybWVkLWRlY2lzaW9uJ31dKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KCctLWRyeS1ydW49c2VydmVyJyBpbiBhcmd2IGFuZCBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXSBmb3IgYXJndiBpbiBjYWxscykpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzWzBdWzBdWydwYXRoJ10sICcvbWV0YWRhdGEvdWlkJylcblxuICAgIGRlZiB0ZXN0X3NvdXJjZV9vdmVycmlkZXNfYXV0b21hdGlvbl9hbmRfY3VzdG9keV9kcmlmdF9zdG9wX2JlZm9yZV93cml0ZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2FwcGxpY2F0aW9uJ11bJ3NwZWMnXS51cGRhdGUoc3luY1BvbGljeT17J2F1dG9tYXRlZCc6IHt9fSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXS51cGRhdGUoa3VzdG9taXplPXsnaW1hZ2VzJzogWydvdGhlciddfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddLnVwZGF0ZShzb3VyY2VzPVt7fV0pLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2NvbmZpZ21hcCddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ3B2YyddWydzcGVjJ10udXBkYXRlKHZvbHVtZU5hbWU9J3JlcGxhY2VkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgICAgICAgICBtdXRhdGUob2JqZWN0cylcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuICAgIGRlZiB0ZXN0X3ByZW9wZW5fc2NoZW1hX3JlZnVzYWxfcHJldmVudHNfaW1hZ2Vfb3BlcmF0aW9uKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIHNjaGVtYV9yZWZ1c2VkPVRydWUpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuXG4gICAgZGVmIHRlc3Rfcm9sbGJhY2tfdW5yZWFkeV9jYW5kaWRhdGVfbmV2ZXJfcmVhZHNfcG9kX29yX2RhdGFiYXNlKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wLCB1cGRhdGVkUmVwbGljYXM9MClcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gYWN0dWF0b3IuSU1BR0VcbiAgICAgICAgb2JqZWN0c1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXVsndGFyZ2V0UmV2aXNpb24nXSA9IFJFVklTSU9OXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBzY2hlbWFfcmVmdXNlZD1UcnVlKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBzZWxmLmFzc2VydEZhbHNlKGFueShhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddIG9yIGFyZ3ZbOjNdID09IFsna3ViZWN0bCcsICdnZXQnLCAncG9kcyddIGZvciBhcmd2IGluIGNhbGxzKSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXNbMF1bLTFdWyd2YWx1ZSddWydzeW5jJ11bJ3JldmlzaW9uJ10sICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJylcblxuICAgIGRlZiB0ZXN0X3JvbGxiYWNrX3N0aWxsX3JlZnVzZXNfY3VzdG9keV9vcl9ub25wYWlyX2ltYWdlX2RyaWZ0KHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnY20nLCAncHZjJywgJ2ltYWdlJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKCk7cGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgICAgICAgICAgaWYgZGVmZWN0ID09ICdjbSc6b2JqZWN0c1snY29uZmlnbWFwJ11bJ21ldGFkYXRhJ11bJ3VpZCddID0gJ3JlY3JlYXRlZCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdCA9PSAncHZjJzpvYmplY3RzWydwdmMnXVsnc3BlYyddWyd2b2x1bWVOYW1lJ10gPSAncmVwbGFjZWQnXG4gICAgICAgICAgICAgICAgZWxzZTpvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSAnZm9yZWlnbi1pbWFnZSdcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKTtzZWxmLmFzc2VydEVxdWFsKHdyaXRlcywgW10pXG5cbiAgICBkZWYgdGVzdF9yZWNvdmVyeV92ZXJpZmljYXRpb25faXNfc2VwYXJhdGVfcmVhZHlfb2xkX2ltYWdlX3NjaGVtYV9wcm9vZihzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpO3BheWxvYWRbJ3BoYXNlJ10gPSAncm9sbGJhY2stdmVyaWZ5J1xuICAgICAgICBvYmplY3RzWydhcHBsaWNhdGlvbiddWydzdGF0dXMnXSA9IHsnb3BlcmF0aW9uU3RhdGUnOiB7J3BoYXNlJzogJ1N1Y2NlZWRlZCcsICdvcGVyYXRpb24nOiB7J3N5bmMnOiB7XG4gICAgICAgICAgICAncmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZicsICdwcnVuZSc6IEZhbHNlLFxuICAgICAgICAgICAgJ3Jlc291cmNlcyc6IFt7J2dyb3VwJzonYXBwcycsJ2tpbmQnOidEZXBsb3ltZW50JywnbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywnbmFtZXNwYWNlJzonaW5mb3JtZWQtZGVjaXNpb24nfV19fX19XG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pO3NlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydyZWNvdmVyeV92ZXJpZmljYXRpb24nXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KGFyZ3ZbOjJdPT1bJ2t1YmVjdGwnLCdleGVjJ10gZm9yIGFyZ3YgaW4gY2FsbHMpKVxuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG5cbiAgICBkZWYgdGVzdF9hbWJpZ3VvdXNfcGF0Y2hfaXNfbmV2ZXJfcmV0cmllZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBhbWJpZ3VvdXM9VHJ1ZSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4od3JpdGVzKSwgMSlcblxuXG5pZiBfX25hbWVfXyA9PSAnX19tYWluX18nOlxuICAgIHVuaXR0ZXN0Lm1haW4oKVxuIgogICAgfSwKICAgICJ0ZXN0X3Jlc2N1ZV9leGVjdXRpb24ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiOGVjYmIwMjYwYTg3YTdhMTJiZDVjNGM5Njc4ZmIyYTlkNDNhNGVhNzMyMjEyOTczNGJjMjFmOGVlMzgzY2Q3MCIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIlN5bnRoZXRpYyByZWNvdmVyeSBndWFyZHM7IG5vIGFjdHVhbCBwcml2YXRlIGpvdXJuYWwvREIvbmF0aXZlIGNvbW1hbmQuXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaGFzaGxpYlxuaW1wb3J0IGpzb25cbmltcG9ydCBvc1xuZnJvbSBwYXRobGliIGltcG9ydCBQYXRoXG5pbXBvcnQgdGVtcGZpbGVcbmltcG9ydCB1bml0dGVzdFxuZnJvbSBhdXRob3JpdHlfam91cm5hbCBpbXBvcnQgSm91cm5hbCwgYXV0aG9yaXR5LCBvcmlnaW5hbF9hbmNob3JcbmZyb20gdGVzdF9leGVjdXRpb24gaW1wb3J0IGFjY2VwdGVkLCBOT1csIFJFVklTSU9OXG5cblJPT1Q9UGF0aChfX2ZpbGVfXykucGFyZW50XG5QTEFOPWpzb24ubG9hZHMoKFJPT1QvJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKS5yZWFkX3RleHQoKSlcbkNBU0U9Uk9PVC5wYXJlbnRcbkJBQ0tVUD1qc29uLmxvYWRzKChDQVNFLydvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKVxuXG5jbGFzcyBSZXNjdWVHdWFyZHModW5pdHRlc3QuVGVzdENhc2UpOlxuICAgIGRlZiBvcmlnaW5hbChzZWxmLHBhcmVudCk6XG4gICAgICAgIG9yaWdpbmFsPXsnaWRlbnRpdHknOlBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10sJ3BoYXNlcyc6e319XG4gICAgICAgIGZvciBuYW1lLG1ldGFkYXRhIGluIFBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2FuY2hvciddWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgICAgICBvcmlnaW5hbFsncGhhc2VzJ11bbmFtZV09eyoqbWV0YWRhdGEsJ3Jlc3VsdCc6QkFDS1VQIGlmIG5hbWU9PSdkcmlsbC1iYWNrdXAnIGVsc2UgeydhbGxfY2hlY2tzX3Bhc3MnOkZhbHNlfX1cbiAgICAgICAgcD1wYXJlbnQvJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nO3Aud3JpdGVfdGV4dChqc29uLmR1bXBzKG9yaWdpbmFsKSk7b3MuY2htb2QocCwwbzYwMClcbiAgICAgICAgYW5jaG9yPWNvcHkuZGVlcGNvcHkoUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10pO2FuY2hvclsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgcmV0dXJuIHAsb3JpZ2luYWwsYW5jaG9yXG5cbiAgICBkZWYgdGVzdF9leGFjdF9vcmlnaW5hbF9mYWlsZWRfam91cm5hbF9pc19saW5rZWRfd2l0aG91dF9tdXRhdGlvbihzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQ9UGF0aChkaXJlY3RvcnkpO29zLmNobW9kKHBhcmVudCwwbzcwMCk7cCxvcmlnaW5hbCxleHBlY3RlZD1zZWxmLm9yaWdpbmFsKHBhcmVudCk7YmVmb3JlPXAucmVhZF9ieXRlcygpXG4gICAgICAgICAgICBhbmNob3I9b3JpZ2luYWxfYW5jaG9yKHBhcmVudCxleHBlY3RlZCxCQUNLVVAsb3JpZ2luYWxbJ2lkZW50aXR5J10pXG4gICAgICAgICAgICBqPUpvdXJuYWwocGFyZW50LHsnZml4dHVyZSc6VHJ1ZSwncmVjb3ZlcnlfYW5jaG9yJzphbmNob3J9KTtqLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScse30pXG4gICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHAucmVhZF9ieXRlcygpLGJlZm9yZSk7c2VsZi5hc3NlcnRFcXVhbChqLnBhdGgubmFtZSwncmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24nKVxuICAgICAgICAgICAgai5maW5pc2goJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7J2FsbF9jaGVja3NfcGFzcyc6VHJ1ZX0pO2ouc3RhcnQoJ29mZmxpbmUtdmVyaWZ5Jyx7fSlcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocC5yZWFkX2J5dGVzKCksYmVmb3JlKTtqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X29yaWdpbmFsX21pc3NpbmdfdW5jZXJ0YWluX3JlY3JlYXRlZF9hdHRlbXB0X29yX3JvbGxvdXRfcmVmdXNlKHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnbWlzc2luZycsJ2NvbXBsZXRlJywnYXR0ZW1wdCcsJ3JvbGxvdXQnLCdoYXNoJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KSx0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgcGFyZW50PVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChwYXJlbnQsMG83MDApO3AsbyxlPXNlbGYub3JpZ2luYWwocGFyZW50KVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J21pc3NpbmcnOm9bJ3BoYXNlcyddLnBvcCgnZHJpbGwtY29weScpXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdjb21wbGV0ZSc6b1sncGhhc2VzJ11bJ2RyaWxsLWNvcHknXVsnc3RhdGUnXT0nQ09NUExFVEUnXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdhdHRlbXB0JzpvWydwaGFzZXMnXVsnZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ109J2RpZmZlcmVudCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdD09J3JvbGxvdXQnOm9bJ3BoYXNlcyddWydyZWxlYXNlJ109eydzdGF0ZSc6J1JVTk5JTkcnfVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdCE9J2hhc2gnOlxuICAgICAgICAgICAgICAgICAgICBwLndyaXRlX3RleHQoanNvbi5kdW1wcyhvKSk7ZVsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgICAgICAgICBlbHNlOmVbJ29yaWdpbmFsX2pvdXJuYWxfc2hhMjU2J109JzAnKjY0XG4gICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcygoVmFsdWVFcnJvcixLZXlFcnJvcikpOm9yaWdpbmFsX2FuY2hvcihwYXJlbnQsZSxCQUNLVVAsUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcblxuICAgIGRlZiB0ZXN0X3Jlc2N1ZV9yZXBsYXlfcmVmdXNlZF9hbmRfb2xkX3BoYXNlX25ldmVyX2FkbWl0dGVkKHNlbGYpOlxuICAgICAgICB3aXRoIHRlbXBmaWxlLlRlbXBvcmFyeURpcmVjdG9yeSgpIGFzIGRpcmVjdG9yeTpcbiAgICAgICAgICAgIG9zLmNobW9kKGRpcmVjdG9yeSwwbzcwMCk7aj1Kb3VybmFsKGRpcmVjdG9yeSx7J2ZpeHR1cmUnOlRydWV9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpqLnN0YXJ0KCdkcmlsbC1jb3B5Jyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnZHJpbGwtYmFja3VwJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHt9KTtqLmZpbmlzaCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZX0pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmouc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9uZXdfYXV0aG9yaXR5X3JlcXVpcmVzX3ZlcnNpb24yX29sZF9hcHByb3ZhbF9yZWZ1c2VzKHNlbGYpOlxuICAgICAgICByZWNlaXB0LG91dGNvbWU9YWNjZXB0ZWQoKTtyZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0yO291dGNvbWVbJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddWydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIGF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuICAgICAgICByZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyxOT1cpXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHknLE5PVylcbiAgICAgICAgcmVjZWlwdFsnbWVtb192ZXJzaW9uJ109MjtyZWNlaXB0WydvdXRjb21lX3F1ZXJ5J109Jy9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0xJ1xuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwbGljaXRfb2ZmbGluZV9pbnB1dF9tYXBwaW5nX2FuZF9hYnNlbmNlX2d1YXJkcyhzZWxmKTpcbiAgICAgICAgc291cmNlPShST09ULydhY3R1YXRvci5weScpLnJlYWRfdGV4dCgpXG4gICAgICAgIHNlbGYuYXNzZXJ0SW4oXCJwcmV2aW91cyA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2RyaWxsLWNvcHktcmVzY3VlLXIxJ11bJ3Jlc3VsdCddXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwibm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwiVk9MVU1FIG5vdCBpbiBsaXN0ZWQuc3Rkb3V0LnNwbGl0bGluZXMoKVwiLHNvdXJjZSlcbiAgICAgICAgc2VsZi5hc3NlcnROb3RJbihcIm9zLm1rZGlyKENVU1RPRFlcIixzb3VyY2UpXG4gICAgICAgIGltcG9ydCBhc3RcbiAgICAgICAgcHJvZ3JhbT1hc3QubGl0ZXJhbF9ldmFsKG5leHQobi52YWx1ZSBmb3IgbiBpbiBhc3QucGFyc2UoKFJPT1QvJ25hdGl2ZV9wcm9ncmFtLnB5JykucmVhZF90ZXh0KCkpLmJvZHkgaWYgaXNpbnN0YW5jZShuLGFzdC5Bc3NpZ24pKSlcbiAgICAgICAgY29tcGlsZShwcm9ncmFtLCduYXRpdmUtcmVzY3VlLWZpeHR1cmUnLCdleGVjJylcbiAgICAgICAgc2VsZi5hc3NlcnRJbihcInBoYXNlPT0nZHJpbGwtY29weS1yZXNjdWUtcjEnOnJlcXVpcmUocG9kWydtZXRhZGF0YSddWyd1aWQnXT09J2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNydcIixwcm9ncmFtKVxuXG5pZiBfX25hbWVfXz09J19fbWFpbl9fJzp1bml0dGVzdC5tYWluKClcbiIKICAgIH0sCiAgICAidmFsaWRhdGlvbi5qc29uIjogewogICAgICAic2hhMjU2IjogIjZmMzM3OWY2Mzk2OGU5YTAyOTRhYmE3YjViNTdlYTQ2NjJhZGRhNmIxZmExYjM3ZWZmMTFjMmY3MmE1ODkzMWYiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwic3RhdGVcIjogXCJwcmVwYXJlZC11bmFwcHJvdmVkLXZlcnNpb24yXCIsXG4gIFwiZXhlY3V0b3JfdGVzdHNcIjogMjEsXG4gIFwic25hcHNob3RfbW9ja190ZXN0c1wiOiA1LFxuICBcIm5hdGl2ZV9hY3Rpb25zXCI6IGZhbHNlLFxuICBcImRhdGFiYXNlX2FkbWluX2NvbW1hbmRzX2luX3ByZXBhcmF0aW9uXCI6IGZhbHNlLFxuICBcIm9sZF9qb3VybmFsX21vZGlmaWVkXCI6IGZhbHNlLFxuICBcIm9sZF9mYWlsZWRfcGhhc2VfcmV0cmllZFwiOiBmYWxzZSxcbiAgXCJvd25lcl9oZWFkX3VuY2hhbmdlZFwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIlxufVxuIgogICAgfQogIH0sCiAgIm5hdGl2ZV9leGVjdXRpb24iOiBmYWxzZSwKICAiY2FzZV9ldmlkZW5jZSI6IHsKICAgICJvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIwMjVkZGRmMWU5MzkzNmYzMWU5OGI5ZmJmYTg0YWEyYmRhYWEzMzU3M2Y5ZDNiMGUzMmQ5NDdmZDI4NmIxNzBlIiwKICAgICAgImNvbnRlbnQiOiAie1wicGhhc2VcIjogXCJkcmlsbC1iYWNrdXBcIiwgXCJhbGxfY2hlY2tzX3Bhc3NcIjogdHJ1ZSwgXCJyYXdfb3V0cHV0X3dpdGhoZWxkXCI6IHRydWUsIFwibmF0aXZlX2FwcHJvdmFsX3ZlcmlmaWVkX2J5X3Jvb3RcIjoge1wiYXBwcm92YWxfaWRcIjogXCJlYzkyODA2YS05YWE2LTQ5NGYtYTc2Yi0wMzg1ZjM5YmE2MDlcIiwgXCJkaXNwb3NpdGlvbl9pZFwiOiBcImRpc3AtMDk2ODM3M2QtMjk0ZC00MmJmLTg5NzktMzZhN2M1ZGQzOGNmXCIsIFwiYWNjZXB0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM0OjIwWlwiLCBcInZlcmlmaWVkX2F0XCI6IFwiMjAyNi0xMC0xMVQwMjozODo0MS43Nzc5NDkrMDA6MDBcIn0sIFwibmF0aXZlX2F1dGhlbnRpY2F0ZWRfZ3JhbnRcIjogZmFsc2UsIFwic291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXCI6IHtcInNjaGVtYV92ZXJzaW9uXCI6IDUsIFwibGlmZWN5Y2xlXCI6IHtcInJlY29yZHNcIjogMTUsIFwiZXZlbnRzXCI6IDUwLCBcInBlbmRpbmdcIjogMH0sIFwib3V0Ym94XCI6IHtcImRlbGl2ZXJlZFwiOiAzMjB9LCBcInN1Ym1pc3Npb25zXCI6IHtcImNvbmZpcm1lZFwiOiA0MX0sIFwiaW50ZWdyaXR5XCI6IFwib2tcIiwgXCJyZWFkX29ubHlfcHJlX29wZW5cIjogdHJ1ZSwgXCJzdG9yZV9jb25zdHJ1Y3RlZFwiOiBmYWxzZX0sIFwic25hcHNob3RfcmVhZG9ubHlcIjoge1wic2NoZW1hX3ZlcnNpb25cIjogNSwgXCJsaWZlY3ljbGVcIjoge1wicmVjb3Jkc1wiOiAxNSwgXCJldmVudHNcIjogNTAsIFwicGVuZGluZ1wiOiAwfSwgXCJvdXRib3hcIjoge1wiZGVsaXZlcmVkXCI6IDMyMH0sIFwic3VibWlzc2lvbnNcIjoge1wiY29uZmlybWVkXCI6IDQxfSwgXCJpbnRlZ3JpdHlcIjogXCJva1wiLCBcInJlYWRfb25seV9wcmVfb3BlblwiOiB0cnVlLCBcInN0b3JlX2NvbnN0cnVjdGVkXCI6IGZhbHNlfSwgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsIFwic25hcHNob3RfZmlsZVwiOiBcImRyaWxsLnNxbGl0ZVwiLCBcIm5hdGl2ZV9wYXJlbnRfcHJpdmF0ZVwiOiB0cnVlLCBcIm5hdGl2ZV91aWRcIjogMTAwMDEsIFwicG9kX25hbWVcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi1mNTU3NTU2ZGYtbXdwejdcIiwgXCJwb2RfdWlkXCI6IFwiZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XCJ9XG4iCiAgICB9LAogICAgIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWNvcHktZmFpbHVyZS5qc29uIjogewogICAgICAic2hhMjU2IjogImZiNzhmYjJlOGMzZDQxNjQ5MGNmMGY1NTliMmY1YmQwMTk0MDZhNDkwZjhmNWZhNmY1OTMyNDIxZjBiMWFjNTYiLAogICAgICAiY29udGVudCI6ICJ7XCJhbGxfY2hlY2tzX3Bhc3NcIjogZmFsc2UsIFwicGhhc2VcIjogXCJkcmlsbC1jb3B5XCIsIFwiZmFpbHVyZV9jbGFzc1wiOiBcIlZhbHVlRXJyb3JcIiwgXCJmYWlsdXJlXCI6IFwiZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeVwiLCBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZX1cbiIKICAgIH0sCiAgICAib3JpZ2luYWwtam91cm5hbC1zYW5pdGl6ZWQtYW5jaG9yLmpzb24iOiB7CiAgICAgICJzaGEyNTYiOiAiOTg4ZmNhNjFhZDhlYjlkNDNkOTMzOTBhODM1MzIzZjk1MjE5NmJiY2U4Y2MwYmRlNTFjNDJhMTdkNDExZjQ1NCIsCiAgICAgICJjb250ZW50IjogIntcbiAgXCJvcmlnaW5hbF9qb3VybmFsX3NoYTI1NlwiOiBcImQxODdiMDJkOThkNmU5NzQyOWZlMjBiNGZiZTFkMzA5YTZjNmM0YjU1MjMyYjRhZTEzYWMzOTg3MzAzOWYxYzFcIixcbiAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgXCJkcmlsbC1iYWNrdXBcIjoge1xuICAgICAgXCJzdGF0ZVwiOiBcIkNPTVBMRVRFXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzg6NDUuMzEwNjUzKzAwOjAwXCJcbiAgICB9LFxuICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICBcInN0YXRlXCI6IFwiVU5DRVJUQUlOXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCIzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2NcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICB9XG4gIH0sXG4gIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsXG4gIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsXG4gIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gIFwib2xkX3VuY2VydGFpbl9yZXRyeV9hdXRob3JpemVkXCI6IGZhbHNlXG59XG4iCiAgICB9CiAgfQp9Cg==" + }, + { + "digest": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509", + "media_type": "text/plain", + "content_base64": "IiIiUHJlLW9wZW4gc2NoZW1hL2ludGVncml0eS9jb3VudCBwcm9vZjsgc3RkbGliIG9ubHksIG5ldmVyIGNvbnN0cnVjdHMgU3RvcmUuIiIiCmltcG9ydCBhcmdwYXJzZQpmcm9tIGNvbnRleHRsaWIgaW1wb3J0IGNsb3NpbmcKaW1wb3J0IGhhc2hsaWIKaW1wb3J0IG9zCmltcG9ydCByZQppbXBvcnQgc3RhdAppbXBvcnQganNvbgpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaW1wb3J0IHNxbGl0ZTMKCgpkZWYgaW5zcGVjdF9yZWFkb25seShwYXRoLCAqLCBfY2xvc2VkX3NuYXBzaG90PUZhbHNlKToKICAgIHBhdGggPSBQYXRoKHBhdGgpCiAgICBpZiBub3QgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZXhpc3Rpbmcgbm9uc3ltbGluayBwcml2YXRlIGRhdGFiYXNlIHJlcXVpcmVkJykKICAgIHVyaSA9IHBhdGgucmVzb2x2ZSgpLmFzX3VyaSgpICsgJz9tb2RlPXJvJyArICgnJmltbXV0YWJsZT0xJyBpZiBfY2xvc2VkX3NuYXBzaG90IGVsc2UgJycpCiAgICAjIHNxbGl0ZTMuQ29ubmVjdGlvbiBjb250ZXh0IG1hbmFnZW1lbnQgZW5kcyB0cmFuc2FjdGlvbnM7IGl0IGRvZXMgbm90IGNsb3NlLgogICAgd2l0aCBjbG9zaW5nKHNxbGl0ZTMuY29ubmVjdCh1cmksIHVyaT1UcnVlLCB0aW1lb3V0PTUpKSBhcyBkYjoKICAgICAgICBkYi5leGVjdXRlKCdQUkFHTUEgcXVlcnlfb25seT1PTicpCiAgICAgICAgZGIuZXhlY3V0ZSgnQkVHSU4nKQogICAgICAgIHZlcnNpb24gPSBkYi5leGVjdXRlKCdQUkFHTUEgdXNlcl92ZXJzaW9uJykuZmV0Y2hvbmUoKVswXQogICAgICAgIGlmIHZlcnNpb24gIT0gNToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncHJlLW9wZW4gZGF0YWJhc2UgaXMgbm90IHNjaGVtYTU7IHJlZnVzZSBtaWdyYXRpb24nKQogICAgICAgIGlmIGRiLmV4ZWN1dGUoJ1BSQUdNQSBpbnRlZ3JpdHlfY2hlY2snKS5mZXRjaGFsbCgpICE9IFsoJ29rJywpXToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncmVhZC1vbmx5IGludGVncml0eSBjaGVjayByZWZ1c2VkJykKICAgICAgICBsaWZlY3ljbGUgPSB7bmFtZTogZGIuZXhlY3V0ZSgnU0VMRUNUIENPVU5UKCopIEZST00gJyArIHRhYmxlKS5mZXRjaG9uZSgpWzBdCiAgICAgICAgICAgICAgICAgICAgIGZvciBuYW1lLCB0YWJsZSBpbiAoKCdyZWNvcmRzJywgJ2xpZmVjeWNsZV9yZWNvcmRzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCdldmVudHMnLCAnbGlmZWN5Y2xlX2V2ZW50cycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgncGVuZGluZycsICdsaWZlY3ljbGVfcGVuZGluZycpKX0KICAgICAgICByZXN1bHQgPSB7J3NjaGVtYV92ZXJzaW9uJzogdmVyc2lvbiwgJ2xpZmVjeWNsZSc6IGxpZmVjeWNsZSwKICAgICAgICAgICAgICAgICAgJ291dGJveCc6IGRpY3QoZGIuZXhlY3V0ZSgnU0VMRUNUIHN0YXRlLENPVU5UKCopIEZST00gb3V0Ym94IEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnc3VibWlzc2lvbnMnOiBkaWN0KGRiLmV4ZWN1dGUoJ1NFTEVDVCBzdGF0ZSxDT1VOVCgqKSBGUk9NIHN1Ym1pc3Npb25zIEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlfQogICAgICAgIGRiLnJvbGxiYWNrKCkKICAgIHJldHVybiByZXN1bHQKCgpkZWYgaW5zcGVjdF9jbG9zZWRfc25hcHNob3QocGF0aCwgZXhwZWN0ZWRfc2hhMjU2KToKICAgICIiIk9ubHkgYSBwcml2YXRlbHkgcmV0YWluZWQsIGZyb3plbiBtYWluLWZpbGUgc25hcHNob3Qgd2l0aCBubyBXQUwgZnJhbWVzLgoKICAgIENhbGxlciBtdXN0IGVzdGFibGlzaCBleGNsdXNpdmUgc25hcHNob3QgY3JlYXRpb24vYWRtaW4gZXhpdC9ubyB3cml0ZXIsIGFuZAogICAgc3VwcGx5IHRoZSByZWNvcmRlZCBmcm96ZW4gbWFpbiBkaWdlc3QuIE5ldmVyIHVzZSBmb3IgdGhlIGxpdmUgZGF0YWJhc2UuCiAgICBJbW11dGFibGUgU1FMaXRlIHJlYWRzIGlnbm9yZSBzdGFsZSBTSE0gYW5kIG5ldmVyIGNyZWF0ZS9jaGFuZ2Ugc2lkZWNhcnMuCiAgICBFeGlzdGluZyBzaWRlY2FycyByZW1haW4gY3VzdG9keSBldmlkZW5jZTsgbm90aGluZyBpcyBkZWxldGVkL2NoZWNrcG9pbnRlZC4KICAgICIiIgogICAgcGF0aCA9IFBhdGgocGF0aCkKICAgIGlmIHJlLmZ1bGxtYXRjaChyJ1swLTlhLWZdezY0fScsIGV4cGVjdGVkX3NoYTI1NikgaXMgTm9uZToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdleGFjdCBmcm96ZW4gc25hcHNob3QgZGlnZXN0IHJlcXVpcmVkJykKICAgIGRlZiBtZXRhZGF0YSh0YXJnZXQpOgogICAgICAgIGluZm8gPSB0YXJnZXQubHN0YXQoKQogICAgICAgIGlmIG5vdCBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBvciBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKSAhPSAwbzYwMCBvciBpbmZvLnN0X25saW5rICE9IDE6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgc2luZ2xlLWxpbmsgc25hcHNob3QgY3VzdG9keSByZXF1aXJlZCcpCiAgICAgICAgcmV0dXJuIGluZm8KICAgIG1haW4gPSBtZXRhZGF0YShwYXRoKQogICAgaWYgbm90IDAgPCBtYWluLnN0X3NpemUgPD0gNTEyICogMTAyNCoqMjoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdib3VuZGVkIGZyb3plbiBzbmFwc2hvdCByZXF1aXJlZCcpCiAgICBkZWYgc2lkZWNhcnMoKToKICAgICAgICBpZGVudGl0aWVzID0ge30KICAgICAgICBmb3Igc3VmZml4IGluICgnLXdhbCcsICctc2htJyk6CiAgICAgICAgICAgIHRhcmdldCA9IFBhdGgoc3RyKHBhdGgpICsgc3VmZml4KQogICAgICAgICAgICBpZiBvcy5wYXRoLmxleGlzdHModGFyZ2V0KToKICAgICAgICAgICAgICAgIGluZm8gPSBtZXRhZGF0YSh0YXJnZXQpCiAgICAgICAgICAgICAgICBpZiBpbmZvLnN0X3VpZCAhPSBtYWluLnN0X3VpZCBvciBpbmZvLnN0X2dpZCAhPSBtYWluLnN0X2dpZDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBzaWRlY2FyIGN1c3RvZHkgY2hhbmdlZCcpCiAgICAgICAgICAgICAgICBpZiBzdWZmaXggPT0gJy13YWwnIGFuZCBpbmZvLnN0X3NpemUgIT0gMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBoYXMgV0FMIGZyYW1lczsgaW1tdXRhYmxlIHJlYWQgcmVmdXNlZCcpCiAgICAgICAgICAgICAgICBpZGVudGl0aWVzW3N1ZmZpeF0gPSAoaW5mby5zdF9kZXYsIGluZm8uc3RfaW5vLCBpbmZvLnN0X3NpemUsIGluZm8uc3RfbXRpbWVfbnMpCiAgICAgICAgcmV0dXJuIGlkZW50aXRpZXMKICAgIGJlZm9yZV9zaWRlY2FycyA9IHNpZGVjYXJzKCkKICAgIGRlZiBkaWdlc3QoKToKICAgICAgICB2YWx1ZSA9IGhhc2hsaWIuc2hhMjU2KCkKICAgICAgICB3aXRoIHBhdGgub3BlbigncmInKSBhcyBzdHJlYW06CiAgICAgICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6CiAgICAgICAgICAgICAgICB2YWx1ZS51cGRhdGUoYmxvY2spCiAgICAgICAgcmV0dXJuIHZhbHVlLmhleGRpZ2VzdCgpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTY6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIG1haW4tZmlsZSBkaWdlc3QgY2hhbmdlZCBiZWZvcmUgaW5zcGVjdGlvbicpCiAgICBwcm9vZiA9IGluc3BlY3RfcmVhZG9ubHkocGF0aCwgX2Nsb3NlZF9zbmFwc2hvdD1UcnVlKQogICAgYWZ0ZXIgPSBtZXRhZGF0YShwYXRoKQogICAgaWYgKGFmdGVyLnN0X2RldiwgYWZ0ZXIuc3RfaW5vLCBhZnRlci5zdF91aWQsIGFmdGVyLnN0X2dpZCwgYWZ0ZXIuc3Rfc2l6ZSkgIT0gKG1haW4uc3RfZGV2LCBtYWluLnN0X2lubywgbWFpbi5zdF91aWQsIG1haW4uc3RfZ2lkLCBtYWluLnN0X3NpemUpOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ2Zyb3plbiBtYWluLWZpbGUgaWRlbnRpdHkgY2hhbmdlZCcpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTYgb3Igc2lkZWNhcnMoKSAhPSBiZWZvcmVfc2lkZWNhcnM6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIHNuYXBzaG90IGNoYW5nZWQgZHVyaW5nIGluc3BlY3Rpb24nKQogICAgcmV0dXJuIHByb29mCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHBhcnNlciA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPV9fZG9jX18pCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWRiJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKICAgIHRyeToKICAgICAgICBwcmludChqc29uLmR1bXBzKGluc3BlY3RfcmVhZG9ubHkoYXJncy5kYiksIHNvcnRfa2V5cz1UcnVlKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmFpc2UgU3lzdGVtRXhpdCgncmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgcmVmdXNlZDsgbm8gU3RvcmUvYWRtaW4gb3BlbicpIGZyb20gTm9uZQo=" + }, + { + "digest": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "media_type": "application/json", + "content_base64": "ewogICJjb25maWdtYXAiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJ2MSIsCiAgICAiaW1tdXRhYmxlIjogdHJ1ZSwKICAgICJraW5kIjogIkNvbmZpZ01hcCIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOi9Db25maWdNYXA6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiLAogICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICB9LAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIsCiAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAidWlkIjogIjkwMTEzZDJkLTU0ZDktNGU4Mi1iMWQzLTkwYjQ5ZWJlZDJiNSIKICAgIH0sCiAgICAiY2Fub25pY2FsX2RhdGFfc2hhMjU2IjogIjhlYzQ2MmQxMjM0NzU0OGY1MDZlZWViZjFlM2M3Y2M0NzY0ODAxOWM4YTc4MzgwNGQwOWJjYzc5YjBmMjJhZjYiCiAgfSwKICAicHZjIjogewogICAgImFwaVZlcnNpb24iOiAidjEiLAogICAgImtpbmQiOiAiUGVyc2lzdGVudFZvbHVtZUNsYWltIiwKICAgICJtZXRhZGF0YSI6IHsKICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICJhcmdvY2QuYXJnb3Byb2ouaW8vdHJhY2tpbmctaWQiOiAiaW5mb3JtZWQtZGVjaXNpb246L1BlcnNpc3RlbnRWb2x1bWVDbGFpbTppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIsCiAgICAgICAgInB2Lmt1YmVybmV0ZXMuaW8vYmluZC1jb21wbGV0ZWQiOiAieWVzIiwKICAgICAgICAicHYua3ViZXJuZXRlcy5pby9ib3VuZC1ieS1jb250cm9sbGVyIjogInllcyIsCiAgICAgICAgInZvbHVtZS5iZXRhLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiLAogICAgICAgICJ2b2x1bWUua3ViZXJuZXRlcy5pby9zZWxlY3RlZC1ub2RlIjogIjIzOS42Mi4yMDUuOTIuaG9zdC5zZWN1cmVzZXJ2ZXIubmV0IiwKICAgICAgICAidm9sdW1lLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiCiAgICAgIH0sCiAgICAgICJmaW5hbGl6ZXJzIjogWwogICAgICAgICJrdWJlcm5ldGVzLmlvL3B2Yy1wcm90ZWN0aW9uIgogICAgICBdLAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICJ1aWQiOiAiZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfSwKICAgICJzcGVjIjogewogICAgICAiYWNjZXNzTW9kZXMiOiBbCiAgICAgICAgIlJlYWRXcml0ZU9uY2UiCiAgICAgIF0sCiAgICAgICJyZXNvdXJjZXMiOiB7CiAgICAgICAgInJlcXVlc3RzIjogewogICAgICAgICAgInN0b3JhZ2UiOiAiMUdpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInN0b3JhZ2VDbGFzc05hbWUiOiAibG9jYWwtcGF0aCIsCiAgICAgICJ2b2x1bWVNb2RlIjogIkZpbGVzeXN0ZW0iLAogICAgICAidm9sdW1lTmFtZSI6ICJwdmMtZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfQogIH0sCiAgInB2Y19waGFzZSI6ICJCb3VuZCIKfQo=" + }, + { + "digest": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5", + "media_type": "text/markdown", + "content_base64": "IyBWZXJzaW9uMiBwcm90ZWN0ZWQgZXhpc3Rpbmctc25hcHNob3QgcmVzY3VlIGFuZCBjb25kaXRpb25hbCBjb250aW51YXRpb24KClNhbWUgcHJvcG9zYWwgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEsIHRyaWFsIGluZmQtcHVycG9zZS0yMDI2MTAxMS1yMS4gT3JpZ2luYWwgdmVyc2lvbjEgZm91bmRlciBhY2NlcHRhbmNlIGFwcHJvdmVkIHNvdXJjZSBiYzY0OTRjZDFiMjkwNzgzZWYzYWVmMDc2M2JmMjhkMWRlYWJmNGIwLiBEcmlsbC1iYWNrdXAgY29tcGxldGVkOyBkcmlsbC1jb3B5IGZhaWxlZCBWYWx1ZUVycm9yIGJlZm9yZSBhbnkgbG9jYWxmaWxlLiBObyBpbWFnZSByb2xsb3V0IG9jY3VycmVkLiBUaGlzIGV4YWN0IGNoYW5nZWQgc291cmNlL3BsYW4vaGVscGVyIHJlcXVpcmVzIE5FVyBmb3VuZGVyIGFjY2VwdGFuY2Ugb2YgbWVtbyB2ZXJzaW9uMiBiZWZvcmUgcmVzY3VlL2NvbnRpbnVhdGlvbjsgcHJpb3IgYXBwcm92YWwgYW5kIHRlY2huaWNhbCByZXZpZXcgZG8gbm90IGFwcHJvdmUgaXQuCgojIyBGYWlsdXJlIGFuZCBuYXJyb3dseSBzZWxlY3RlZCByZXNjdWUKCk9yaWdpbmFsIHNuYXBzaG90IG1haW4xOTUzNzkyMGJ5dGVzIFNIQTg3NTZjZjgyNWRmOWU3YjViNzRiYjRhMDEwNmE1MDI3ZjVjZmYyYzU5ZmY0NWQ3YjQ4ZWVkODUyMmE3ZDMzZjMgaXMgdW5jaGFuZ2VkLiBSb290J3MgbWV0YWRhdGEtb25seSB2ZXJpZmljYXRpb24gc2hvd3MgV0FMMGJ5dGVzLCBTSE0zMjc2OGJ5dGVzLCBwcml2YXRlVUlEMTAwMDEvbW9kZTA2MDAvbmxpbmsxLCBhbmQgbm8gbG9jYWwgc25hcHNob3QuIFRoZSBvbGQgU1FMaXRlIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgZXhwbGljaXRseSBjbG9zZTsgaXRzIFdBTCByZWFkZXIgY2FuIGNyZWF0ZSBTSE0gaW5kZXhpbmcsIGFuZCB0aGUgbmV4dCBjb3B5IHJlamVjdGVkIHRoYXQgbm9uemVybyBpbmRleC4gUGxhdGZvcm0gaW5kZXBlbmRlbnRseSByZXByb2R1Y2VkIHRoaXMgb24gc3ludGhldGljIGRhdGEuIE5vIG5hdGl2ZSBEQiB3YXMgb3BlbmVkIHRvIGRpYWdub3NlIHRoZSBzaWRlY2FyIG1ldGFkYXRhLCBhbmQgbm8gbmF0aXZlIHNpZGVjYXIgaXMgZGVsZXRlZC9jaGVja3BvaW50ZWQuCgpSZXVzZSB0aGlzIGV4YWN0IGluZGVwZW5kZW50bHkgaGFzaC1ib3VuZCBmcm96ZW4gbWFpbiBzbmFwc2hvdCByYXRoZXIgdGhhbiBtYWtlIGFub3RoZXIgZHJpbGwgYmFja3VwLiBUaGUgYmFja3VwYWRtaW4gZXhpdGVkIGFmdGVyIGNyZWF0aW5nIHRoZSB1bmlxdWVseSBvd25lZCBwcml2YXRlIHNuYXBzaG90LiBPcmlnaW5hbCBzdWJzZXF1ZW50IHNuYXBzaG90IGFjY2VzcyB3YXMgcmVhZG9ubHk7IGFjdHVhbCBzZXJ2aWNlIERCIGlzIHRoZSBkaXN0aW5jdCAvZGF0YS9wcml2YXRlL3Jldmlldy5zcWxpdGUuIE9yaWdpbmFsIGpvdXJuYWwgaGFzIG9ubHkgQ09NUExFVEUgZHJpbGwtYmFja3VwIGQ2MzE4MmE3LWUxYTUtNGU4ZS1hNWYxLTJiZjMzMzNjZjE1MyBhbmQgVU5DRVJUQUlOIGRyaWxsLWNvcHkzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2MuIEl0cyBleGFjdCBTSEEgZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMSwgb3JpZ2luYWwgc291cmNlL21lbW8vcGxhbiBpZGVudGl0eSBhbmQgb3V0Y29tZXMgYXJlIHZlcmlmaWVkIGJlZm9yZS9hZnRlciBldmVyeSBuZXcgcGhhc2UuIE5vIG90aGVyIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0IGlzIGFsbG93ZWQuCgpUaGUgZXhwbGljaXRseSBuYW1lZCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBjcmVhdGVzIGEgc2VwYXJhdGUgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24vbG9jayBpbiBleGlzdGluZyBwcm90ZWN0ZWQgaWdub3JlZCBjdXN0b2R5OyBpdCBoYXNoLWxpbmtzIG9yaWdpbmFsIGF0dGVtcHRzIGFuZCBiYWNrdXByZXN1bHQgYW5kIG5ldmVyIHJld3JpdGVzL3N5bnRoZXNpemVzIHRoZSBvbGQgZmFpbGVkIHBoYXNlLiBBbnkgYXR0ZW1wdGVkIHJlc2N1ZSByZXN1bHQsIGNyYXNoIG9yIGFtYmlndW91cyBvdXRwdXQgaXMgZHVyYWJsZSBhbmQgc2FtZS1waGFzZSByZXRyeSBpcyByZWZ1c2VkLiBCZWZvcmUgcmVzY3VlOiBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgYW5kIGV4aXN0aW5nIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50OyBuYXRpdmUgb3JpZ2luYWxQb2RVSUQvY3VycmVudG9sZGltYWdlN2Y1L0FyZ283ZGIvc2VhbGVkRGVwbG95bWVudC9DTS9QVkMgbWF0Y2guIFRoZSBmaXhlZCBpbW11dGFibGUgc25hcHNob3QgcmVhZGVyIGNoZWNrcyByZWNvcmRlZCBkaWdlc3QvcHJpdmF0ZSBpZGVudGl0eS9ubyBXQUxmcmFtZXMgYmVmb3JlIGFuZCBhZnRlciBzY2hlbWE1L2ludGVncml0eS9jb3VudCB2YWxpZGF0aW9uLCByZXRhaW5pbmcgdW5jaGFuZ2VkIFNITS4gTm9uemVybyBXQUwgb3IgYW55IGlkZW50aXR5L2hhc2ggZHJpZnQgc3RvcHMgcmVzY3VlLiBTbmFwc2hvdCBiaW5hcnlzdGRvdXQgZmxvd3Mgb25seSB0byBhIG5ldzA2MDBwcml2YXRlIGZpbGUsIHdpdGggYm91bmRlZCBzaXplL2hhc2ggYW5kIHJlcGVhdCBzb3VyY2UgcHJvb2YuIEl0IG5ldmVyIHJlYWNoZXMgY2hhdC9sb2cvR2l0L1N0YXRlSHViLgoKIyMgTGl2ZS1XQUwgYW5kIGRhdGEgY29tcGF0aWJpbGl0eSBib3VuZGFyaWVzCgpMaXZlIHNvdXJjZSBhbmQgd3JpdGFibGUgb2ZmbGluZSBwcmUvcG9zdC1hZG1pbiByZWFkcyBNVVNUIHN0YXkgbW9kZT1yby9xdWVyeV9vbmx5IGFuZCBleHBsaWNpdGx5IGNsb3NlIFNRTGl0ZSBjb25uZWN0aW9ucy4gaW1tdXRhYmxlPTEgaWdub3JlcyBXQUwgYW5kIHdvdWxkIGxvc2UgY29tbWl0dGVkIGxpdmUgcm93czsgaXQgaXMgcmVzdHJpY3RlZCB0byB0aGUgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbmV2ZXIgdGhlIGxpdmVEQiBvciB3cml0YWJsZWNsb25lLiBCZWZvcmUgQU5ZIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5IFN0b3JlL2FkbWluIG9wZW4sIHJlcXVpcmUgc3RkbGliIHJlYWRvbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50czsgcmVmdXNlIG9sZHNjaGVtYXMgYmVmb3JlIGF1dG9tYXRpYyBtaWdyYXRpb24uIEZyb3plbiBzbmFwc2hvdC9jbG9uZSBjb3VudCBlcXVhbGl0eSBpcyBleGFjdDsgY3VycmVudGxpdmUgY291bnRlciBjaGFuZ2VzIG1heSByZWZsZWN0IGNvbmN1cnJlbnQgbGVnaXRpbWF0ZSBjb21taXRzIGFuZCBhcmUgcmV0YWluZWQuCgpPbmx5IGFmdGVyIENPTVBMRVRFIG5hbWVkIHJlc2N1ZSBkb2VzIG9mZmxpbmUtdmVyaWZ5IGNvbnN1bWUgaXRzIHJlc3VsdCB2aWEgZXhwbGljaXQgbWFwcGluZywgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGlzb2xhdGVkIGRpc3Bvc2FibGV2b2x1bWUgaW5mZC1wdXJwb3NlLXIxLXJlc3RvcmUtMjAyNjEwMTEgbXVzdCBiZSBhYnNlbnQvbmV3IG5vbmNlLWJvdW5kLiBPbmUgZXhhY3Q3NjNjIFVJRDAvQ0FQX0NIT1dOLW9ubHkgaW5pdGlhbGl6ZXIgcmVjZWl2ZXMgc25hcHNob3RzdGRpbiBpbnRvIHRoYXQgTkVXdm9sdW1lLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pLCBubyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50cy4gSXQgc2V0cyBmb2xkZXIwNzAwL2ZpbGUwNjAwVUlEMTAwMDEsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHByZS1vcGVuIHJlYWRvbmx5LCAtLWVudHJ5cG9pbnQgaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4gaW5zcGVjdCAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGUgYW5kIHBvc3QtYWRtaW4gcmVhZG9ubHkgZnVsbHByb29mOyBvcmlnaW5hbCBwcm90ZWN0ZWQgU0hBIG11c3QgcmVtYWluIHVuY2hhbmdlZC4gTm8gc2VydmljZWVudHJ5cG9pbnQgc3RhcnRzLiBDbGVhbnVwIG9ubHkgdGhpcyBkaXNwb3NhYmxlIHZvbHVtZSwgcmV0YWluaW5nIG9yaWdpbmFsIG5hdGl2ZS9vZmZjbHVzdGVyIHNuYXBzaG90cy9zaWRlY2Fycy4KCiMjIENvbmRpdGlvbmFsIHJlbWFpbmluZyBwaGFzZXMgYW5kIHJlbGVhc2UvcmVjb3ZlcnkKCk5ld2pvdXJuYWwgZml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnkuIGN1dG92ZXItYmFja3VwIHVzZXMgZGlzdGluY3QgbmV3Y3V0b3Zlci5zcWxpdGUgaW4gb3JpZ2luYWxwcml2YXRlY2FzZSBkaXJlY3RvcnksIGFmdGVyIHJlYWRvbmx5IGxpdmUgc2NoZW1hNS9jYXBhY2l0eSBnYXRlcywgU1FMaXRlYmFja3VwQVBJL2FkbWluIGNvbXBsZXRpb24sIGNsb3NlZC1tYWluIGltbXV0YWJsZSBwcm9vZjsgZG8gbm90IG92ZXJ3cml0ZSBvcmlnaW5hbHMgb3IgcmV0cnlmYWlsZWRwYXRocy4gVmVyc2lvbjIgYWNjZXB0YW5jZSBjb25kaXRpb25hbGx5IGFwcHJvdmVzIHRoZXNlIGV4YWN0IHVuY2hhbmdlZCByZW1haW5pbmcgb3BlcmF0aW9ucyBvbmx5IGFmdGVyIHJlc2N1ZStkcmlsbGdhdGVzLiBBbGwgZm91ciBjb21taXR0ZWQgS3VzdG9taXplIEdpdCBibG9icy9jdXJyZW50SEVBRCwgZXhhY3QgaGVscGVyL2Nhc2UgaGFzaGVzLCBDTS9QVkMvRGVwbG95bWVudCBzZWFscyBhbmQgbWFudWFsQXBwbGljYXRpb24obm8gYXV0b21hdGVke30gb3Igc291cmNlb3ZlcnJpZGUpIG11c3QgbWF0Y2guCgpSZWxlYXNlIHJldGFpbnMgZXhpc3RpbmcgcmVwbGljYTEvUmVjcmVhdGUvY29uZmlnNmMvc2NoZW1hNS9QVkMvY3JlZGVudGlhbHMvcG9saWNpZXM6IHNvdXJjZXBpbiBBcHBsaWNhdGlvbi5vcGVyYXRpb24gc2VydmVyZHJ5cnVuL1VJRCtyZXNvdXJjZVZlcnNpb24rc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5IGltYWdlNzYzYywgcHJ1bmU9ZmFsc2UuIE5vIHdob2xlLWFwcCBzeW5jL2Fkb3B0aW9uLiBWZXJpZnkgcmVxdWlyZXMgc3VjY2VlZGVkIGV4YWN0c2NvcGUvY29udHJvbGxlcmdlbmVyYXRpb24vUmVhZHkxLCBpbnN0YWxsZWRwb2xpY3loYXNoL21vZGVVSUQvMTBzeW50aGV0aWNwdXJwb3NldmFyaWFudHMrYm91bmRlZGhlYWx0aCwgc2FtZSBjdXJyZW50bGl2ZURCIHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50cy4gVGhvc2UgaW5zdGFsbGVkY2hlY2tzIHJlcG9ydCBuYXRpdmVfcHJvdmlkZXI9ZmFsc2U7IGFjdHVhbHByb3ZpZGVyL1BEUGF1dGhvcml0eSBldmlkZW5jZSByZW1haW5zIGEgc2VwYXJhdGUgVDA0Z2F0ZS4KClJvbGxiYWNrIGFmdGVyIHJlY29yZGVkIG5ld3JlbGVhc2UgYXR0ZW1wdCBwaW5zIHByaW9yN2RiLzdmNSBhbmQgcmV0YWlucyBsYXRlc3RzY2hlbWE1REIsIHdpdGhvdXQgcmVxdWlyaW5nIFJlYWR5IGZhaWxpbmdjYW5kaWRhdGUgb3IgY2FuZGlkYXRlREJleGVjLiBTZXBhcmF0ZSByb2xsYmFjay12ZXJpZnkgcHJvdmVzIG9sZGltYWdlUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9yZWFkb25seXNjaGVtYTUgY3VycmVudERCIGludGVncml0eS4gTmV2ZXIgcmVzdG9yZSBhbiBvbGRlciBzbmFwc2hvdCBvdmVyIHBvc3RjdXRvdmVycmVjb3Jkcy4gQW55IGRhdGEgcmVjb3ZlcnkgYmV5b25kIHRoaXMgc2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sgbmVlZHMgYW5vdGhlciBkZWNpc2lvbi4KCkFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZSwgdmVyaWZpY2F0aW9uIGFuZCByZWNvdmVyeSBtdXN0IGJlZ2luIGJlZm9yZTIwMjYtMTAtMTJUMjM6NTk6NTlaLiBTdGFydCBlYXJseSBlbm91Z2g7IGlmIGV4cGlyZWQgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbiwgd2hpY2ggbWF5IGRlbGF5IHJlY292ZXJ5LiBObyBhdXRvbWF0aWMgdGltZXIvY29udHJvbGxlci9leHRlbnNpb24uIFJvb3QgZnJlc2hseSBhdXRoZW50aWNhdGVzIGV4YWN0IGNvbmZpcm1lZCBwbGF0Zm9ybS1yb290IHBlcnNvbiBBQ0NFUFQgbWVtbyB2ZXJzaW9uMiBhdCBmaXhlZG5hdGl2ZW9yaWdpbiBiZWZvcmUgZXZlcnkgcGhhc2U7IHByb3RlY3RlZHJlY2VpcHRyZWxhdGlvbi9mcmVzaG5lc3MxMjBzZWMgaXMgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3QgYSBzaWduZWQvYXV0b25vbW91cyBncmFudC4KCkltYWdlNzYzYy9wb2xpY3k5ZDdjL2Jhc2U3ZjUgYW5kIGFjdHVhbHVuZmlsdGVyZWRzY2FuMEhJR0gvQ1JJVElDQUwvMWZpeGFibGVNRURJVU16bGliIHJlbWFpbiB1bmNoYW5nZWQsIG93bmVyIElORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxL1QwNSBkdWVPY3QxOC4gVGhlIGV4YWN0YnVuZGxlIGRpcmVjdGx5IGJpbmRzIGhlbHBlci9wbGFuL3Rlc3RzIHBsdXMgb3JpZ2luYWwgY291bnQtb25seWJhY2t1cC9mYWlsdXJlL2FuY2hvci4gRXhpc3RpbmdwdWJsaXNoZWRyZWNlaXB0IHN0aWxsIGJpbmRzIHVuY2hhbmdlZCByYXdzY2FuL1NCT00vYmFzZSBzY2FuOyBubyBzdXBwcmVzc2lvbi4gUHJlc2VydmUgb3JpZ2luYWxhcHByb3ZlZDIwZG9jcGFja2V0L2hlbHBlcnMvaGlzdG9yeSBpbiBpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkLiBObyB2ZXJzaW9uMiBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4uIEVVUjAgcmVjdXJyaW5naW5mcmFzdHJ1Y3R1cmU7IHByaXZhdGUgYm91bmRlZHN0b3JhZ2UvYXR0ZW5kZWR0aW1lIHVucHJpY2VkLCBubyBuZXdkcmlsbGJhY2t1cCBvciBhdXRvbm9teWdyYW50LgoKTmF0aXZlIHNvdXJjZSBwdWJsaWNhdGlvbiB1c2VzIGV4YWN0IHJldmlzaW9uLWNvbW1hbmQuanNvbiB2aWEgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMsIGV4cGVjdGVkX3ZlcnNpb24xLCBvbmx5IGFmdGVyIGZyZXNoIHVuYm91bmQtc291cmNlIHJlYWRiYWNrLiBObyB2ZXJzaW9uMiBpbnRha2UvcmVnaXN0ZXIuIFB1Ymxpc2gvcmV2aWV3IHNvdXJjZXZlcnNpb24yOyBuZXcgaHVtYW4gcmV2aWV3LUlEIGlzIG93bnZlcnNpb24xLCBzbyBpdHMgY29uZmlybWVkIG5lc3RlZCBkaXNwb3NpdGlvbiBtZW1vX3ZlcnNpb24xIGlzIGNvcnJlY3QuIFJvb3QgYWN0dWFsIG91dGNvbWVzIHF1ZXJ5IG11c3QgbmFtZSBTT1VSQ0UgdmVyc2lvbjIgYW5kIGV4YWN0IG5ld3Jldmlld0lEOyBvcmlnaW5hbCByZXZpZXcvYXBwcm92YWwgY2Fubm90IGJlIHJldXNlZC4K" + }, + { + "digest": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101", + "media_type": "application/json", + "content_base64": "ewogICJpZCI6ICJJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSIsCiAgImtpbmQiOiAib3duZXItdnVsbmVyYWJpbGl0eS1mb2xsb3ctdGhyb3VnaCIsCiAgIm93bmVyIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAidGFzayI6ICJJTkZELVdQLTAwMDktVDA1IiwKICAic3RhdHVzIjogIm9wZW4iLAogICJjcmVhdGVkIjogIjIwMjYtMTAtMTEiLAogICJyZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJmaW5kaW5nIjogIkNWRS0yMDI2LTg1MDkxIiwKICAic2Nhbm5lcl9zZXZlcml0eSI6ICJNRURJVU0iLAogICJlc3RhdGVfcmlza19ncmFkZSI6IG51bGwsCiAgImFmZmVjdGVkX3BhY2thZ2UiOiAiemxpYiIsCiAgImluc3RhbGxlZCI6ICIxLjMuMi1yMCIsCiAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAiYWN0dWFsX2N1cnJlbnRfYmFzZV9hbmRfY2FuZGlkYXRlX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgInNvdXJjZV9ldmlkZW5jZSI6ICJzZWN1cml0eS1zdW1tYXJ5Lmpzb24sIHRyaXZ5LWZ1bGwuanNvbiwgYmFzZS10cml2eS1mdWxsLmpzb24iLAogICJodW1hbl90ZW1wb3JhcnlfZGlzcG9zaXRpb24iOiAicGVuZGluZyIsCiAgImZvbGxvd190aHJvdWdoIjogIlByZXBhcmUgYSBzZXBhcmF0ZWx5IHNvdXJjZS1ib3VuZCBvZmZpY2lhbC1iYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCB0aHJvdWdoIG5vcm1hbCBvd25lciBDSSwgdmVyaWZ5IGZ1bGwgc2NhbiBhbmQgcnVudGltZSBjb21wYXRpYmlsaXR5LCBvYnRhaW4gZGlzdGluY3QgbmF0aXZlIHJlbGVhc2UgYXBwcm92YWwgYmVmb3JlIHVwZGF0aW5nIHRoaXMgd29ya2xvYWQiLAogICJtYW51YWxfcmV2aWV3X2V4cGlyeSI6ICJEdWUgZGF0ZSByZXF1aXJlcyBvd25lciByZXZpZXcvZXNjYWxhdGlvbiBpZiB1bnJlc29sdmVkOyBubyBhdXRvbWF0aWMgcm9sbGJhY2svY29udHJvbGxlciBpcyBpbnN0YWxsZWQiLAogICJjbG9zZV9jb25kaXRpb24iOiAiVmVyaWZpZWQgaW5zdGFsbGVkIG5hdGl2ZSBmaXhlZCBwYWNrYWdlIGFuZCBmdWxsIHVuZmlsdGVyZWQgcmVzY2FuOyBwcmVzZXJ2ZSBvcmlnaW5hbCBkZXRlY3Rpb24gYW5kIGFueSBodW1hbiBkaXNwb3NpdGlvbiIKfQo=" + }, + { + "digest": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "media_type": "application/json", + "content_base64": "ewogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjI1OjM4Ljc5MzU1NSswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibGl2ZV9yZWFkeV9yZXBsaWNhcyI6IDEsCiAgImFkbWl0dGVkX3VpZCI6ICJhNTg4ZTEwYS05MGQyLTQ4ODMtOTc1ZS02ZGQ4YjhmZWNhOTIiLAogICJzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWQiOiB0cnVlLAogICJhZG1pdHRlZF9zcGVjX2V4YWN0bHlfbGl2ZV9wbHVzX2ltYWdlIjogdHJ1ZSwKICAiY2xpZW50X2RpZmZfZXhpdCI6IDEsCiAgImNsaWVudF9kaWZmX3NoYTI1NiI6ICJhNGJjMDI0YThjZWM2NThmODM1Mjg1ZWQ1MTk2NGUyZTA4NGVkYmFmMTAzZDQ1YTQ4Yjg5YzA5NTBiY2QzZTdkIiwKICAibm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzIjogIihUb3RhbCBsaW1pdHMgbWF5IGJlIG92ZXIgMTAwIHBlcmNlbnQsIGkuZS4sIG92ZXJjb21taXR0ZWQuKVxuICBSZXNvdXJjZSAgICAgICAgICAgUmVxdWVzdHMgICAgICBMaW1pdHNcbiAgLS0tLS0tLS0gICAgICAgICAgIC0tLS0tLS0tICAgICAgLS0tLS0tXG4gIGNwdSAgICAgICAgICAgICAgICAzNDYwbSAoODYlKSAgIDM2MjAwbSAoOTA1JSlcbiAgbWVtb3J5ICAgICAgICAgICAgIDk0NzJNaSAoNTklKSAgMzI4OThNaSAoMjA1JSlcbiAgZXBoZW1lcmFsLXN0b3JhZ2UgIDAgKDAlKSAgICAgICAgMCAoMCUpXG4gIGh1Z2VwYWdlcy0xR2kgICAgICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMk1pICAgICAgMCAoMCUpICAgICAgICAwICgwJSkiLAogICJhbGxfY2hlY2tzX3Bhc3MiOiB0cnVlCn0K" + }, + { + "digest": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImFyZ29jZC5hcmdvcHJvai5pby90cmFja2luZy1pZCI6ICJpbmZvcm1lZC1kZWNpc2lvbjphcHBzL0RlcGxveW1lbnQ6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICJ1aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInJldmlzaW9uSGlzdG9yeUxpbWl0IjogMTAsCiAgICAic2VsZWN0b3IiOiB7CiAgICAgICJtYXRjaExhYmVscyI6IHsKICAgICAgICAiYXBwLmt1YmVybmV0ZXMuaW8vbmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIKICAgICAgfQogICAgfSwKICAgICJzdHJhdGVneSI6IHsKICAgICAgInR5cGUiOiAiUmVjcmVhdGUiCiAgICB9LAogICAgInRlbXBsYXRlIjogewogICAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiCiAgICAgICAgfSwKICAgICAgICAibGFiZWxzIjogewogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ICJyZXZpZXciLAogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgICAgfQogICAgICB9LAogICAgICAic3BlYyI6IHsKICAgICAgICAiYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbiI6IGZhbHNlLAogICAgICAgICJjb250YWluZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiZW52IjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIklORkRfS0VZQ0FQRV9JU1NVRVIiLAogICAgICAgICAgICAgICAgInZhbHVlIjogImh0dHBzOi8va2MuY291bG9tYi5zb2NpYWwiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0NPTlRBSU5FUl9DT05GSUciLAogICAgICAgICAgICAgICAgInZhbHVlIjogIi9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvbiIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICAgICAgICAgICAiaW1hZ2VQdWxsUG9saWN5IjogIklmTm90UHJlc2VudCIsCiAgICAgICAgICAgICJsaXZlbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICAgICAgICJwb3J0cyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODAsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJodHRwIiwKICAgICAgICAgICAgICAgICJwcm90b2NvbCI6ICJUQ1AiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIsCiAgICAgICAgICAgICAgICAicHJvdG9jb2wiOiAiVENQIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlYWRpbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVzb3VyY2VzIjogewogICAgICAgICAgICAgICJsaW1pdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjUwMG0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICIyNTZNaSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZXF1ZXN0cyI6IHsKICAgICAgICAgICAgICAgICJjcHUiOiAiNW0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICI2NE1pIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInNlY3VyaXR5Q29udGV4dCI6IHsKICAgICAgICAgICAgICAiYWxsb3dQcml2aWxlZ2VFc2NhbGF0aW9uIjogZmFsc2UsCiAgICAgICAgICAgICAgImNhcGFiaWxpdGllcyI6IHsKICAgICAgICAgICAgICAgICJkcm9wIjogWwogICAgICAgICAgICAgICAgICAiQUxMIgogICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInJlYWRPbmx5Um9vdEZpbGVzeXN0ZW0iOiB0cnVlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzdGFydHVwUHJvYmUiOiB7CiAgICAgICAgICAgICAgImZhaWx1cmVUaHJlc2hvbGQiOiAxMiwKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAidGVybWluYXRpb25NZXNzYWdlUGF0aCI6ICIvZGV2L3Rlcm1pbmF0aW9uLWxvZyIsCiAgICAgICAgICAgICJ0ZXJtaW5hdGlvbk1lc3NhZ2VQb2xpY3kiOiAiRmlsZSIsCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJkbnNQb2xpY3kiOiAiQ2x1c3RlckZpcnN0IiwKICAgICAgICAicmVzdGFydFBvbGljeSI6ICJBbHdheXMiLAogICAgICAgICJzY2hlZHVsZXJOYW1lIjogImRlZmF1bHQtc2NoZWR1bGVyIiwKICAgICAgICAic2VjdXJpdHlDb250ZXh0IjogewogICAgICAgICAgImZzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJmc0dyb3VwQ2hhbmdlUG9saWN5IjogIk9uUm9vdE1pc21hdGNoIiwKICAgICAgICAgICJydW5Bc0dyb3VwIjogMTAwMDEsCiAgICAgICAgICAicnVuQXNOb25Sb290IjogdHJ1ZSwKICAgICAgICAgICJydW5Bc1VzZXIiOiAxMDAwMSwKICAgICAgICAgICJzZWNjb21wUHJvZmlsZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiUnVudGltZURlZmF1bHQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic2VydmljZUFjY291bnQiOiAicmV2aWV3IiwKICAgICAgICAic2VydmljZUFjY291bnROYW1lIjogInJldmlldyIsCiAgICAgICAgInRlcm1pbmF0aW9uR3JhY2VQZXJpb2RTZWNvbmRzIjogNDUsCiAgICAgICAgInZvbHVtZXMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImRhdGEiLAogICAgICAgICAgICAicGVyc2lzdGVudFZvbHVtZUNsYWltIjogewogICAgICAgICAgICAgICJjbGFpbU5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tZGF0YSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImVtcHR5RGlyIjogewogICAgICAgICAgICAgICJtZWRpdW0iOiAiTWVtb3J5IiwKICAgICAgICAgICAgICAic2l6ZUxpbWl0IjogIjE2TWkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImNvbmZpZ3VyYXRpb24iCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJjYWxsZXIiLAogICAgICAgICAgICAicHJvamVjdGVkIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAic291cmNlcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgInNlcnZpY2VBY2NvdW50VG9rZW4iOiB7CiAgICAgICAgICAgICAgICAgICAgImF1ZGllbmNlIjogImZsZXgtYXV0aCIsCiAgICAgICAgICAgICAgICAgICAgImV4cGlyYXRpb25TZWNvbmRzIjogMzYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiYXVkaXQiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAidG9rZW4iLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJzZWNyZXROYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLWF1ZGl0IgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiA2MDAsCiAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAidG9rZW4iCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAia2V5IjogImNhLmNydCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXRoIjogImNhLmNydCIKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICJuYW1lIjogImt1YmUtcm9vdC1jYS5jcnQiCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjkyLAogICAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgInNlY3JldCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAia2V5IjogImNsaWVudC1zZWNyZXQiLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJjbGllbnQtc2VjcmV0IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm9wdGlvbmFsIjogZmFsc2UsCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy1yZXF1ZXN0ZXIiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0KICAgIH0KICB9Cn0K" + }, + { + "digest": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IGV4YWN0IERlcGxveW1lbnQgYW5kIGFkbWlzc2lvbiBib3VuZGFyaWVzOyBubyBtdXRhdGlvbiBhdXRob3JpdHkuIiIiCmltcG9ydCBjb3B5CmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCgpCQVNFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MycKQ0FORElEQVRFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYScKCgpkZWYgZGVwZW5kZW5jeV9wcm9qZWN0aW9uKGNvbmZpZ21hcCwgcHZjKToKICAgIGlmIChjb25maWdtYXAuZ2V0KCdraW5kJykgIT0gJ0NvbmZpZ01hcCcgb3IgY29uZmlnbWFwLmdldCgnaW1tdXRhYmxlJykgaXMgbm90IFRydWUKICAgICAgICAgICAgb3IgY29uZmlnbWFwWydtZXRhZGF0YSddWyduYW1lc3BhY2UnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24nCiAgICAgICAgICAgIG9yIGNvbmZpZ21hcFsnbWV0YWRhdGEnXVsnbmFtZSddICE9ICdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MScKICAgICAgICAgICAgb3Igc2V0KGNvbmZpZ21hcC5nZXQoJ2RhdGEnLCB7fSkpICE9IHsncnVudGltZS5qc29uJ30KICAgICAgICAgICAgb3IgY29uZmlnbWFwLmdldCgnYmluYXJ5RGF0YScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGltbXV0YWJsZSBydW50aW1lIGNvbmZpZyBpZGVudGl0eScpCiAgICBpZiAocHZjLmdldCgna2luZCcpICE9ICdQZXJzaXN0ZW50Vm9sdW1lQ2xhaW0nCiAgICAgICAgICAgIG9yIHB2Y1snbWV0YWRhdGEnXVsnbmFtZXNwYWNlJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJwogICAgICAgICAgICBvciBwdmNbJ21ldGFkYXRhJ11bJ25hbWUnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24tZGF0YScKICAgICAgICAgICAgb3IgcHZjLmdldCgnc3RhdHVzJywge30pLmdldCgncGhhc2UnKSAhPSAnQm91bmQnCiAgICAgICAgICAgIG9yIG5vdCBwdmMuZ2V0KCdzcGVjJywge30pLmdldCgndm9sdW1lTmFtZScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGJvdW5kIFBWQyBjdXN0b2R5JykKICAgIGNvbmZpZyA9IHByb2plY3Rpb24oY29uZmlnbWFwKQogICAgY29uZmlnLnBvcCgnZGF0YScpCiAgICBjb25maWdbJ2Nhbm9uaWNhbF9kYXRhX3NoYTI1NiddID0gaGFzaGxpYi5zaGEyNTYoanNvbi5kdW1wcygKICAgICAgICBjb25maWdtYXBbJ2RhdGEnXSwgc29ydF9rZXlzPVRydWUsIHNlcGFyYXRvcnM9KCcsJywgJzonKSkuZW5jb2RlKCkpLmhleGRpZ2VzdCgpCiAgICByZXR1cm4geydjb25maWdtYXAnOiBjb25maWcsICdwdmMnOiBwcm9qZWN0aW9uKHB2YyksICdwdmNfcGhhc2UnOiAnQm91bmQnfQoKCmRlZiBjaGVja19kZXBlbmRlbmNpZXMoY29uZmlnbWFwLCBwdmMsIHNlYWxlZCk6CiAgICBpZiBkZXBlbmRlbmN5X3Byb2plY3Rpb24oY29uZmlnbWFwLCBwdmMpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdydW50aW1lIGNvbmZpZyBvciBQVkMgaWRlbnRpdHkvY3VzdG9keSBjaGFuZ2VkJykKCgpkZWYgcHJvamVjdGlvbih2YWx1ZSk6CiAgICB2YWx1ZSA9IGNvcHkuZGVlcGNvcHkodmFsdWUpCiAgICB2YWx1ZS5wb3AoJ3N0YXR1cycsIE5vbmUpCiAgICBmb3Iga2V5IGluICgncmVzb3VyY2VWZXJzaW9uJywgJ2dlbmVyYXRpb24nLCAnY3JlYXRpb25UaW1lc3RhbXAnLCAnbWFuYWdlZEZpZWxkcycpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLnBvcChrZXksIE5vbmUpCiAgICBmb3Iga2V5IGluICgna3ViZWN0bC5rdWJlcm5ldGVzLmlvL2xhc3QtYXBwbGllZC1jb25maWd1cmF0aW9uJywgJ2RlcGxveW1lbnQua3ViZXJuZXRlcy5pby9yZXZpc2lvbicpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLmdldCgnYW5ub3RhdGlvbnMnLCB7fSkucG9wKGtleSwgTm9uZSkKICAgIHJldHVybiB2YWx1ZQoKCmRlZiBjaGVja19jdXJyZW50KGN1cnJlbnQsIHNlYWxlZCk6CiAgICBpZiBwcm9qZWN0aW9uKGN1cnJlbnQpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzZWFsZWQgbGl2ZSBVSUQgb3IgY29uZmlndXJhdGlvbiBjaGFuZ2VkJykKCgpkZWYgY2hlY2tfYWRtaXR0ZWQoYWRtaXR0ZWQsIHNlYWxlZCk6CiAgICBleHBlY3RlZCA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKQogICAgY29udGFpbmVycyA9IGV4cGVjdGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddCiAgICBpZiBsZW4oY29udGFpbmVycykgIT0gMSBvciBjb250YWluZXJzWzBdWyduYW1lJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJyBvciBjb250YWluZXJzWzBdWydpbWFnZSddICE9IEJBU0U6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigndW5leHBlY3RlZCBiYXNlbGluZSBjb250YWluZXIgaWRlbnRpdHknKQogICAgY29udGFpbmVyc1swXVsnaW1hZ2UnXSA9IENBTkRJREFURQogICAgaWYgcHJvamVjdGlvbihhZG1pdHRlZCkgIT0gZXhwZWN0ZWQ6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignYWRtaXNzaW9uIGNoYW5nZWQgY29uZmlndXJhdGlvbiBiZXlvbmQgdGhlIHNvbGUgaW1hZ2UgcGluJykKCgpkZWYgdHJhbnNwb3J0X3Jlc3VsdChleGl0X2NvZGUsIG91dHB1dCk6CiAgICBpbXBvcnQganNvbgogICAgdHJ5OgogICAgICAgIHZhbHVlID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6CiAgICAgICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdyZWFzb24nOiAnaW52YWxpZCB0cmFuc3BvcnQgcmVzdWx0J30KICAgIGlmIGV4aXRfY29kZSAhPSAwIG9yIG5vdCBpc2luc3RhbmNlKHZhbHVlLCBkaWN0KSBvciB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIG5vdCBUcnVlOgogICAgICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncmVhc29uJzogJ3JlYWQtb25seSBwcmVmbGlnaHQgcmVmdXNlZCd9CiAgICByZXR1cm4gdmFsdWUK" + }, + { + "digest": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IHJlZnJlc2g7IGV4YWN0IG9yaWdpbmFsIGNhcHR1cmUgcmVtYWlucyBpbW11dGFibGU7IG5ldmVyIGV4ZWN1dGUgY3V0b3Zlci4iIiIKaW1wb3J0IGFyZ3BhcnNlLGhhc2hsaWIsanNvbixzdWJwcm9jZXNzLHN5cwpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaWYgc3lzLmZsYWdzLm9wdGltaXplOgogcmFpc2UgU3lzdGVtRXhpdCgib3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQgYmVmb3JlIHNvdXJjZS90cmFuc3BvcnQgZXhlY3V0aW9uIikKUk9PVD1QYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50CnA9YXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKTtwLmFkZF9hcmd1bWVudCgnLS1yZWNlaXB0LW91dHB1dCcsdHlwZT1QYXRoLHJlcXVpcmVkPVRydWUpO3AuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yb290Jyx0eXBlPVBhdGgsZGVmYXVsdD1QYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24nKSk7YT1wLnBhcnNlX2FyZ3MoKQpvdXQ9YS5yZWNlaXB0X291dHB1dC5yZXNvbHZlKCkKaWYgbm90IGEucmVjZWlwdF9vdXRwdXQuaXNfYWJzb2x1dGUoKSBvciBvdXQ9PVJPT1Qgb3IgUk9PVCBpbiBvdXQucGFyZW50cyBvciBvdXQ9PWEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIG9yIGEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIGluIG91dC5wYXJlbnRzIG9yIG91dC5leGlzdHMoKToKIHJhaXNlIFN5c3RlbUV4aXQoJ3VuaXF1ZSBleGVjdXRpb24gcmVjZWlwdCBtdXN0IGJlIG91dHNpZGUgdGhlIHNlYWxlZCBwYWNrZXQnKQppbnB1dHM9anNvbi5sb2FkcygoUk9PVC8ncHJlZmxpZ2h0LWlucHV0cy5qc29uJykucmVhZF90ZXh0KCkpCmZvciByZWxhdGl2ZSxkaWdlc3QgaW4gaW5wdXRzWydwYWNrZXRfZmlsZXMnXS5pdGVtcygpOgogcGF0aD1ST09UL3JlbGF0aXZlCiBpZiBwYXRoLmlzX3N5bWxpbmsoKSBvciBoYXNobGliLnNoYTI1NihwYXRoLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCkhPWRpZ2VzdDpyYWlzZSBTeXN0ZW1FeGl0KCdzZWFsZWQgaGVscGVyL2lucHV0IGJ5dGVzIGNoYW5nZWQnKQpmb3IgcmVsYXRpdmUsZGlnZXN0IGluIGlucHV0c1snb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKToKIHBhdGg9YS5zb3VyY2Vfcm9vdC9yZWxhdGl2ZQogaWYgcGF0aC5pc19zeW1saW5rKCkgb3IgaGFzaGxpYi5zaGEyNTYocGF0aC5yZWFkX2J5dGVzKCkpLmhleGRpZ2VzdCgpIT1kaWdlc3Q6cmFpc2UgU3lzdGVtRXhpdCgnb3duZXIgc291cmNlIGJ5dGVzIGNoYW5nZWQnKQpmcm9tIGNoYW5nZV9ndWFyZCBpbXBvcnQgdHJhbnNwb3J0X3Jlc3VsdApwcm9ncmFtPSdpbXBvcnQgc3VicHJvY2Vzcyxqc29uLGhhc2hsaWIsZGF0ZXRpbWUsc3lzLGNvcHkscmVcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoIm9wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkIilcbmNhbmRpZGF0ZT1qc29uLmxvYWRzKENBTkRJREFURV9MSVRFUkFMKVxuc2VhbGVkX2RlcGVuZGVuY2llcz1qc29uLmxvYWRzKERFUEVOREVOQ0lFU19MSVRFUkFMKVxuc2VhbGVkX2Jhc2VsaW5lPWpzb24ubG9hZHMoU0VBTEVEX0xJVEVSQUwpXG5leGVjKEdVQVJEX0xJVEVSQUwpXG5kZWYgcnVuKGFyZ3MsZGF0YT1Ob25lKTpcbiBwPXN1YnByb2Nlc3MucnVuKGFyZ3MsaW5wdXQ9ZGF0YSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSlcbiBpZiBwLnJldHVybmNvZGU6IHJhaXNlIFZhbHVlRXJyb3IoXCdyZWFkLW9ubHkgY29tbWFuZCBmYWlsZWQ6IFwnK2FyZ3NbMV0rXCcgXCcrYXJnc1syXSlcbiByZXR1cm4gcC5zdGRvdXRcbmxpdmU9anNvbi5sb2FkcyhydW4oW1wna3ViZWN0bFwnLFwnZ2V0XCcsXCdkZXBsb3ltZW50XCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2luZm9ybWVkLWRlY2lzaW9uXCcsXCctb1wnLFwnanNvblwnXSkpXG5jbT1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2NvbmZpZ21hcFwnLFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcJyxcJy1uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW9cJyxcJ2pzb25cJ10pKVxucHZjPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwncHZjXCcsXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXCcsXCctblwnLFwnaW5mb3JtZWQtZGVjaXNpb25cJyxcJy1vXCcsXCdqc29uXCddKSlcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsc2VhbGVkX2RlcGVuZGVuY2llcylcbmNoZWNrX2N1cnJlbnQobGl2ZSxzZWFsZWRfYmFzZWxpbmUpXG5zcGVjPWxpdmVbXCdzcGVjXCddOyBjcz1zcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wnY29udGFpbmVyc1wnXTthc3NlcnQgbGVuKGNzKT09MSBhbmQgY3NbMF1bXCduYW1lXCddPT1cJ2luZm9ybWVkLWRlY2lzaW9uXCdcbmV4cGVjdGVkX2Vudj17XCdJTkZEX0tFWUNBUEVfSVNTVUVSXCc6XCdodHRwczovL2tjLmNvdWxvbWIuc29jaWFsXCcsXCdJTkZEX0NPTlRBSU5FUl9DT05GSUdcJzpcJy9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvblwnfVxuYXNzZXJ0IGNzWzBdLmdldChcJ2VudlwnKT09W3tcJ25hbWVcJzpcJ0lORkRfS0VZQ0FQRV9JU1NVRVJcJyxcJ3ZhbHVlXCc6ZXhwZWN0ZWRfZW52W1wnSU5GRF9LRVlDQVBFX0lTU1VFUlwnXX0se1wnbmFtZVwnOlwnSU5GRF9DT05UQUlORVJfQ09ORklHXCcsXCd2YWx1ZVwnOmV4cGVjdGVkX2VudltcJ0lORkRfQ09OVEFJTkVSX0NPTkZJR1wnXX1dXG5hc3NlcnQgY3NbMF1bXCdpbWFnZVwnXT09XCdmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcJ1xuYXNzZXJ0IHNwZWNbXCdyZXBsaWNhc1wnXT09MSBhbmQgc3BlY1tcJ3N0cmF0ZWd5XCddPT17XCd0eXBlXCc6XCdSZWNyZWF0ZVwnfVxuYXNzZXJ0IG5leHQodiBmb3IgdiBpbiBzcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wndm9sdW1lc1wnXSBpZiB2W1wnbmFtZVwnXT09XCdjb25maWd1cmF0aW9uXCcpW1wnY29uZmlnTWFwXCddW1wnbmFtZVwnXT09XCdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MVwnXG5hc3NlcnQgbGl2ZVtcJ3N0YXR1c1wnXS5nZXQoXCdyZWFkeVJlcGxpY2FzXCcpPT0xIGFuZCBsaXZlW1wnc3RhdHVzXCddLmdldChcJ3VwZGF0ZWRSZXBsaWNhc1wnKT09MVxuc2VhbGVkPXtcJ2FwaVZlcnNpb25cJzpsaXZlW1wnYXBpVmVyc2lvblwnXSxcJ2tpbmRcJzpsaXZlW1wna2luZFwnXSxcJ21ldGFkYXRhXCc6e2s6Y29weS5kZWVwY29weSh2KSBmb3Igayx2IGluIGxpdmVbXCdtZXRhZGF0YVwnXS5pdGVtcygpIGlmIGsgbm90IGluIChcJ3Jlc291cmNlVmVyc2lvblwnLFwnZ2VuZXJhdGlvblwnLFwnY3JlYXRpb25UaW1lc3RhbXBcJyxcJ21hbmFnZWRGaWVsZHNcJyl9LFwnc3BlY1wnOmNvcHkuZGVlcGNvcHkoc3BlYyl9XG5mb3Iga2V5IGluIChcJ2t1YmVjdGwua3ViZXJuZXRlcy5pby9sYXN0LWFwcGxpZWQtY29uZmlndXJhdGlvblwnLFwnZGVwbG95bWVudC5rdWJlcm5ldGVzLmlvL3JldmlzaW9uXCcpOnNlYWxlZFtcJ21ldGFkYXRhXCddLmdldChcJ2Fubm90YXRpb25zXCcse30pLnBvcChrZXksTm9uZSlcbmFkbWl0dGVkPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2FwcGx5XCcsXCctLWRyeS1ydW49c2VydmVyXCcsXCctZlwnLFwnLVwnLFwnLW9cJyxcJ2pzb25cJ10sanNvbi5kdW1wcyhjYW5kaWRhdGUpKSlcbmNoZWNrX2FkbWl0dGVkKGFkbWl0dGVkLHNlYWxlZF9iYXNlbGluZSlcbmFwcD1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2FwcGxpY2F0aW9uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2FyZ29jZFwnLFwnLW9cJyxcJ2pzb25cJ10pKVxuYXNzZXJ0IGFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCdwYXRoXCddPT1cJ2RlcGxveS9saWZlY3ljbGVcJyBhbmQgbm90IGFwcFtcJ3NwZWNcJ10uZ2V0KFwnc3luY1BvbGljeVwnLHt9KS5nZXQoXCdhdXRvbWF0ZWRcJylcbmFyZ289e1wndWlkXCc6YXBwW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdyZXBvVVJMXCc6YXBwW1wnc3BlY1wnXVtcJ3NvdXJjZVwnXVtcJ3JlcG9VUkxcJ10sXCd0YXJnZXRSZXZpc2lvblwnOmFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCd0YXJnZXRSZXZpc2lvblwnXSxcJ3BhdGhcJzphcHBbXCdzcGVjXCddW1wnc291cmNlXCddW1wncGF0aFwnXSxcJ2Rlc3RpbmF0aW9uXCc6YXBwW1wnc3BlY1wnXVtcJ2Rlc3RpbmF0aW9uXCddLFwnYXV0b21hdGVkXCc6RmFsc2UsXCdzeW5jXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdzeW5jXCcpLFwnaGVhbHRoXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdoZWFsdGhcJyl9XG5leHBlY3RlZF9hcmdvPWpzb24ubG9hZHMoQVJHT19MSVRFUkFMKVxuZm9yIGtleSBpbiAoXCd1aWRcJyxcJ3JlcG9VUkxcJyxcJ3RhcmdldFJldmlzaW9uXCcsXCdwYXRoXCcsXCdkZXN0aW5hdGlvblwnLFwnYXV0b21hdGVkXCcpOlxuIGFzc2VydCBhcmdvW2tleV09PWV4cGVjdGVkX2FyZ29ba2V5XVxuYXNzZXJ0IGFyZ29bXCdoZWFsdGhcJ11bXCdzdGF0dXNcJ109PVwnSGVhbHRoeVwnXG5kaWZmPXN1YnByb2Nlc3MucnVuKFtcJ2t1YmVjdGxcJyxcJ2RpZmZcJyxcJy1mXCcsXCctXCddLGlucHV0PWpzb24uZHVtcHMoY2FuZGlkYXRlKSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSk7YXNzZXJ0IGRpZmYucmV0dXJuY29kZSBpbiAoMCwxKVxuIyBEaWZmIGNhbiBjb250YWluIG9ubHkgbm9uc2VjcmV0IERlcGxveW1lbnQgcmVmZXJlbmNlczsgcHJlc2VydmUgZGlnZXN0IHJhdGhlciB0aGFuIHJhdyBzdGRvdXQuXG5ub2RlPXJ1bihbXCdrdWJlY3RsXCcsXCdkZXNjcmliZVwnLFwnbm9kZVwnXSk7YWxsb2NhdGVkPXJlLnNlYXJjaChyXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOi4qP0NQVSBSZXF1ZXN0c3xBbGxvY2F0ZWQgcmVzb3VyY2VzOlwnLG5vZGUscmUuUylcbnNlY3Rpb249bm9kZS5zcGxpdChcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcpWzFdLnNwbGl0KFwnRXZlbnRzOlwnKVswXSBpZiBcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcgaW4gbm9kZSBlbHNlIFwnXCdcbm5vZGVzPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwnbm9kZXNcJyxcJy1vXCcsXCdqc29uXCddKSlbXCdpdGVtc1wnXTthc3NlcnQgbGVuKG5vZGVzKT09MVxuYWxsb2M9bm9kZXNbMF1bXCdzdGF0dXNcJ11bXCdhbGxvY2F0YWJsZVwnXTtjcHU9YWxsb2NbXCdjcHVcJ107Y3B1X209aW50KGNwdVs6LTFdKSBpZiBjcHUuZW5kc3dpdGgoXCdtXCcpIGVsc2UgaW50KGNwdSkqMTAwMFxucmVxdWVzdGVkPWludChyZS5zZWFyY2goclwnY3B1XFxzKyhcXGQrKW1cJyxzZWN0aW9uKS5ncm91cCgxKSk7YXNzZXJ0IHJlcXVlc3RlZDw9Y3B1X21cbnJlY2VpcHQ9e1wnbm9kZV9hbGxvY2F0YWJsZV9jcHVfbVwnOmNwdV9tLFwnbm9kZV9yZXF1ZXN0ZWRfY3B1X21cJzpyZXF1ZXN0ZWQsXCdjYXB0dXJlZF9hdFwnOmRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpLmlzb2Zvcm1hdCgpLFwnbmF0aXZlX3dvcmtsb2FkX2NoYW5nZWRcJzpGYWxzZSxcJ25hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZFwnOkZhbHNlLFwnYXJnb1wnOmFyZ28sXCduYXRpdmVfZGVwZW5kZW5jaWVzX2NoZWNrZWRcJzpUcnVlLFwnY29uZmlnbWFwX3VpZFwnOmNtW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdwdmNfdWlkXCc6cHZjW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdsaXZlX3JlYWR5X3JlcGxpY2FzXCc6MSxcJ2FkbWl0dGVkX3VpZFwnOmFkbWl0dGVkW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWRcJzpUcnVlLFwnYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZVwnOlRydWUsXCdjbGllbnRfZGlmZl9leGl0XCc6ZGlmZi5yZXR1cm5jb2RlLFwnY2xpZW50X2RpZmZfc2hhMjU2XCc6aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpLFwnbm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzXCc6c2VjdGlvbi5zdHJpcCgpLFwnYWxsX2NoZWNrc19wYXNzXCc6VHJ1ZX1cbnByaW50KGpzb24uZHVtcHMocmVjZWlwdCkpXG4nCmZvciBtYXJrZXIsdmFsdWUgaW4gWygnREVQRU5ERU5DSUVTX0xJVEVSQUwnLChST09ULydzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLCgnQ0FORElEQVRFX0xJVEVSQUwnLChST09ULydjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLCgnU0VBTEVEX0xJVEVSQUwnLChST09ULydzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksKCdHVUFSRF9MSVRFUkFMJywoUk9PVC8nY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpLCgnQVJHT19MSVRFUkFMJyxqc29uLmR1bXBzKGpzb24ubG9hZHMoKFJPT1QvJ25hdGl2ZS1wcmVmbGlnaHQuanNvbicpLnJlYWRfdGV4dCgpKVsnYXJnbyddKSldOgogcHJvZ3JhbT1wcm9ncmFtLnJlcGxhY2UobWFya2VyLHJlcHIodmFsdWUpKQpwcm9ncmFtPSdpbXBvcnQgdHJhY2ViYWNrLGpzb25cbnRyeTpcbicrJycuam9pbignICAgICcrbGluZSsnXG4nIGZvciBsaW5lIGluIHByb2dyYW0uc3BsaXRsaW5lcygpKSsiZXhjZXB0IEV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICBwcmludChqc29uLmR1bXBzKHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZSwnZXhjZXB0aW9uX3R5cGUnOnR5cGUoZXJyb3IpLl9fbmFtZV9fLCdleGNlcHRpb25fbGluZSc6dHJhY2ViYWNrLmV4dHJhY3RfdGIoZXJyb3IuX190cmFjZWJhY2tfXylbLTFdLmxpbmVub30pKVxuIgpyPXN1YnByb2Nlc3MucnVuKFsnc3NoJywncmFpbGlhbmNlMDEnLCdweXRob24zIC0nXSxpbnB1dD1wcm9ncmFtLHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlKQpyZXN1bHQ9dHJhbnNwb3J0X3Jlc3VsdChyLnJldHVybmNvZGUsci5zdGRvdXQpO3Jlc3VsdFsnc2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2J109aGFzaGxpYi5zaGEyNTYoKFJPT1QvJ3ByZWZsaWdodC1pbnB1dHMuanNvbicpLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCk7cmVzdWx0WydmcmVzaF9leGVjdXRpb25fcmVjZWlwdCddPVRydWUKb3V0LndyaXRlX3RleHQoanNvbi5kdW1wcyhyZXN1bHQsaW5kZW50PTIpKydcbicpO3ByaW50KGpzb24uZHVtcHMocmVzdWx0LGluZGVudD0yKSk7c3lzLmV4aXQoMCBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgMSkK" + }, + { + "digest": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b", + "media_type": "application/json", + "content_base64": "ewogICJwYWNrZXRfZmlsZXMiOiB7CiAgICAiY2hhbmdlX2d1YXJkLnB5IjogImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmUiLAogICAgInByZWZsaWdodC5weSI6ICI2YjRjNjVmNzA4MjM4YzlhOWQxN2ZkMDY1ODc2YzdhMDBlMWYxNzQ1OTI2Zjk5MGExZGQ1ZTY2NzI5ODM0MGNkIiwKICAgICJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uIjogIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGUiLAogICAgInJvbGxiYWNrLWRlcGxveW1lbnQuanNvbiI6ICIzOWIzZjQzYmI4NGVmNDkyMWNjM2ExZmJjZGM0NDQ2MTA3NDFlZDg4MDkxNDlkOGY4ZjE3ZWQ4MDVmMjYyMTIxIiwKICAgICJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24iOiAiZDE4ZDI3MDYzZDA2ZjUzNWFlODg0ZWEwMWY5Njc0N2ZlMzAxNjg1NTE4YWI5NGIxY2JhMDcyYTFlMTUxOTM2MiIsCiAgICAibmF0aXZlLXByZWZsaWdodC5qc29uIjogImViNWY0MWFlZmI5NzY2NmJiMGMxMjc5NjE3ZTk1YTdjMDUwMTdhNjA5NDE1NjI0ZGFlZTcyNGM0OGI5MGQyNjIiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAic3FsaXRlX3JlYWRvbmx5LnB5IjogIjkwOTNjNjRmN2YwZTM5YjI0OWRhOWZlZmRmNWFhZjRlNDI1OGJjMzFlN2EyN2ZkODg4NDc5Y2UzMjlhMjA1MDkiCiAgfSwKICAib3duZXJfc291cmNlX2ZpbGVzIjogewogICAgImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uIjogIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTUiLAogICAgImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbiI6ICIzOGI3OGI5Y2JlZTVhZGU3NzUwYTU4ZDUxNTZjYTRjNTc3MzM1MmU5NDdhY2IzMDRlZTcxNGI1OWU3NDljZWI0IgogIH0KfQo=" + }, + { + "digest": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7", + "media_type": "application/json", + "content_base64": "ewogICJub2RlX2FsbG9jYXRhYmxlX2NwdV9tIjogNDAwMCwKICAibm9kZV9yZXF1ZXN0ZWRfY3B1X20iOiAzNDYwLAogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjM5OjE0LjIzNDI3NyswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibmF0aXZlX2RlcGVuZGVuY2llc19jaGVja2VkIjogdHJ1ZSwKICAiY29uZmlnbWFwX3VpZCI6ICI5MDExM2QyZC01NGQ5LTRlODItYjFkMy05MGI0OWViZWQyYjUiLAogICJwdmNfdWlkIjogImQ4MGIyNWIxLTE0MWEtNDQxYi1iMjA1LTk4ZmEyZmQ5OGI3YyIsCiAgImxpdmVfcmVhZHlfcmVwbGljYXMiOiAxLAogICJhZG1pdHRlZF91aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIiwKICAic2VydmVyX2RyeV9ydW5fcGFzc2VkIjogdHJ1ZSwKICAiYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZSI6IHRydWUsCiAgImNsaWVudF9kaWZmX2V4aXQiOiAxLAogICJjbGllbnRfZGlmZl9zaGEyNTYiOiAiODQwNzY5YzdkMmE5YzE2NTVjNDBhMzI1OWY4MzNkMWZjOGY2OTk1MGNlYjNiZWRiNzA3YTk1NWZlZDcxMTU2NiIsCiAgIm5vZGVfYWxsb2NhdGVkX3Jlc291cmNlcyI6ICIoVG90YWwgbGltaXRzIG1heSBiZSBvdmVyIDEwMCBwZXJjZW50LCBpLmUuLCBvdmVyY29tbWl0dGVkLilcbiAgUmVzb3VyY2UgICAgICAgICAgIFJlcXVlc3RzICAgICAgTGltaXRzXG4gIC0tLS0tLS0tICAgICAgICAgICAtLS0tLS0tLSAgICAgIC0tLS0tLVxuICBjcHUgICAgICAgICAgICAgICAgMzQ2MG0gKDg2JSkgICAzNjIwMG0gKDkwNSUpXG4gIG1lbW9yeSAgICAgICAgICAgICA5NDcyTWkgKDU5JSkgIDMyODk4TWkgKDIwNSUpXG4gIGVwaGVtZXJhbC1zdG9yYWdlICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMUdpICAgICAgMCAoMCUpICAgICAgICAwICgwJSlcbiAgaHVnZXBhZ2VzLTJNaSAgICAgIDAgKDAlKSAgICAgICAgMCAoMCUpIiwKICAiYWxsX2NoZWNrc19wYXNzIjogdHJ1ZSwKICAic2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2IjogIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDYiLAogICJmcmVzaF9leGVjdXRpb25fcmVjZWlwdCI6IHRydWUKfQo=" + } + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py new file mode 100644 index 0000000..64274bd --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py @@ -0,0 +1,95 @@ +"""Pre-open schema/integrity/count proof; stdlib only, never constructs Store.""" +import argparse +from contextlib import closing +import hashlib +import os +import re +import stat +import json +from pathlib import Path +import sqlite3 + + +def inspect_readonly(path, *, _closed_snapshot=False): + path = Path(path) + if not path.is_file() or path.is_symlink(): + raise ValueError('existing nonsymlink private database required') + uri = path.resolve().as_uri() + '?mode=ro' + ('&immutable=1' if _closed_snapshot else '') + # sqlite3.Connection context management ends transactions; it does not close. + with closing(sqlite3.connect(uri, uri=True, timeout=5)) as db: + db.execute('PRAGMA query_only=ON') + db.execute('BEGIN') + version = db.execute('PRAGMA user_version').fetchone()[0] + if version != 5: + raise ValueError('pre-open database is not schema5; refuse migration') + if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]: + raise ValueError('read-only integrity check refused') + lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0] + for name, table in (('records', 'lifecycle_records'), + ('events', 'lifecycle_events'), + ('pending', 'lifecycle_pending'))} + result = {'schema_version': version, 'lifecycle': lifecycle, + 'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')), + 'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')), + 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False} + db.rollback() + return result + + +def inspect_closed_snapshot(path, expected_sha256): + """Only a privately retained, frozen main-file snapshot with no WAL frames. + + Caller must establish exclusive snapshot creation/admin exit/no writer, and + supply the recorded frozen main digest. Never use for the live database. + Immutable SQLite reads ignore stale SHM and never create/change sidecars. + Existing sidecars remain custody evidence; nothing is deleted/checkpointed. + """ + path = Path(path) + if re.fullmatch(r'[0-9a-f]{64}', expected_sha256) is None: + raise ValueError('exact frozen snapshot digest required') + def metadata(target): + info = target.lstat() + if not stat.S_ISREG(info.st_mode) or stat.S_IMODE(info.st_mode) != 0o600 or info.st_nlink != 1: + raise ValueError('private single-link snapshot custody required') + return info + main = metadata(path) + if not 0 < main.st_size <= 512 * 1024**2: + raise ValueError('bounded frozen snapshot required') + def sidecars(): + identities = {} + for suffix in ('-wal', '-shm'): + target = Path(str(path) + suffix) + if os.path.lexists(target): + info = metadata(target) + if info.st_uid != main.st_uid or info.st_gid != main.st_gid: + raise ValueError('snapshot sidecar custody changed') + if suffix == '-wal' and info.st_size != 0: + raise ValueError('snapshot has WAL frames; immutable read refused') + identities[suffix] = (info.st_dev, info.st_ino, info.st_size, info.st_mtime_ns) + return identities + before_sidecars = sidecars() + def digest(): + value = hashlib.sha256() + with path.open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + value.update(block) + return value.hexdigest() + if digest() != expected_sha256: + raise ValueError('frozen main-file digest changed before inspection') + proof = inspect_readonly(path, _closed_snapshot=True) + after = metadata(path) + if (after.st_dev, after.st_ino, after.st_uid, after.st_gid, after.st_size) != (main.st_dev, main.st_ino, main.st_uid, main.st_gid, main.st_size): + raise ValueError('frozen main-file identity changed') + if digest() != expected_sha256 or sidecars() != before_sidecars: + raise ValueError('frozen snapshot changed during inspection') + return proof + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--db', type=Path, required=True) + args = parser.parse_args() + try: + print(json.dumps(inspect_readonly(args.db), sort_keys=True)) + except Exception: + raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py new file mode 100644 index 0000000..913ef29 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py @@ -0,0 +1,97 @@ +"""Mocked SQLite regression fixtures; no actual SQLite/admin/native command.""" +import hashlib +import os +from pathlib import Path +import tempfile +import unittest +from unittest.mock import patch +import sqlite_readonly as checker + + +class Cursor: + def __init__(self, one=None, rows=None):self.one=one;self.rows=rows + def fetchone(self):return self.one + def fetchall(self):return self.rows + def __iter__(self):return iter(self.rows or []) + + +class Connection: + def __init__(self, version=5):self.version=version;self.closed=False;self.queries=[] + def execute(self, sql): + self.queries.append(sql) + if sql=='PRAGMA user_version':return Cursor(one=(self.version,)) + if sql=='PRAGMA integrity_check':return Cursor(rows=[('ok',)]) + if 'GROUP BY' in sql:return Cursor(rows=[('confirmed',1)] if 'submissions' in sql else [('delivered',1)]) + return Cursor(one=(1,)) + def rollback(self):pass + def close(self):self.closed=True + + +class SnapshotRepair(unittest.TestCase): + def file(self, root, name='snapshot.sqlite', data=b'frozen synthetic main'): + p=Path(root)/name;p.write_bytes(data);os.chmod(p,0o600);return p + + def test_live_reader_remains_wal_aware_and_explicitly_closes(self): + for schema in (5,4): + with self.subTest(schema=schema),tempfile.TemporaryDirectory() as root: + p=self.file(root);connection=Connection(schema) + with patch.object(checker.sqlite3,'connect',return_value=connection) as connect: + if schema==5:checker.inspect_readonly(p) + else: + with self.assertRaises(ValueError):checker.inspect_readonly(p) + self.assertTrue(connection.closed) + self.assertTrue(connect.call_args.args[0].endswith('?mode=ro')) + self.assertNotIn('immutable',connect.call_args.args[0]) + self.assertIn('PRAGMA query_only=ON',connection.queries) + + def test_zero_wal_stale_shm_retained_immutable_main_proof_no_mutation(self): + with tempfile.TemporaryDirectory() as root: + p=self.file(root);wal=self.file(root,p.name+'-wal',b'');shm=self.file(root,p.name+'-shm',b'x'*32768) + before={q:(q.read_bytes(),q.stat().st_mtime_ns) for q in (p,wal,shm)};connection=Connection() + with patch.object(checker.sqlite3,'connect',return_value=connection) as connect: + result=checker.inspect_closed_snapshot(p,hashlib.sha256(p.read_bytes()).hexdigest()) + self.assertEqual(result['schema_version'],5);self.assertTrue(connection.closed) + self.assertTrue(connect.call_args.args[0].endswith('?mode=ro&immutable=1')) + for q,(data,mtime) in before.items():self.assertEqual((q.read_bytes(),q.stat().st_mtime_ns),(data,mtime)) + + def test_nonempty_wal_changed_digest_and_symlink_refuse_before_sqlite(self): + for defect in ('wal','digest','symlink'): + with self.subTest(defect=defect),tempfile.TemporaryDirectory() as root: + p=self.file(root);digest=hashlib.sha256(p.read_bytes()).hexdigest() + if defect=='wal':self.file(root,p.name+'-wal',b'frame') + elif defect=='digest':digest='0'*64 + else: + alias=Path(root)/'alias.sqlite';alias.symlink_to(p);p=alias + with patch.object(checker.sqlite3,'connect') as connect: + with self.assertRaises(ValueError):checker.inspect_closed_snapshot(p,digest) + connect.assert_not_called() + + def test_main_or_sidecar_change_during_inspection_refuses(self): + for defect in ('main','wal','shm'): + with self.subTest(defect=defect),tempfile.TemporaryDirectory() as root: + p=self.file(root);digest=hashlib.sha256(p.read_bytes()).hexdigest() + if defect=='shm':self.file(root,p.name+'-shm',b'x'*32768) + connection=Connection();original=connection.execute + def changed(sql): + result=original(sql) + if sql=='PRAGMA integrity_check': + if defect=='main':p.write_bytes(b'changed main') + elif defect=='wal':self.file(root,p.name+'-wal',b'frame') + else:Path(str(p)+'-shm').write_bytes(b'changed') + return result + connection.execute=changed + with patch.object(checker.sqlite3,'connect',return_value=connection): + with self.assertRaises(ValueError):checker.inspect_closed_snapshot(p,digest) + self.assertTrue(connection.closed) + + def test_inner_native_paths_use_immutable_only_for_snapshot_output(self): + import ast + p=Path(__file__).parent/'execution/native_program.py';tree=ast.parse(p.read_text());source=ast.literal_eval(next(n.value for n in tree.body if isinstance(n,ast.Assign))) + self.assertIn('baseline=counts(inspect_readonly(db))',source) + self.assertEqual(source.count('inspect_closed_snapshot(output,'),2) + self.assertNotIn('inspect_closed_snapshot(db',source) + self.assertIn("identity['snapshot_sha256']",source) + self.assertIn("size==identity['snapshot_bytes']",source) + + +if __name__=='__main__':unittest.main() diff --git a/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json new file mode 100644 index 0000000..a8830a2 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/initial-rescue-0867e27a/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json @@ -0,0 +1,26 @@ +{ + "version2_intake_refuses_as_required": true, + "submission_route": "POST /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions", + "expected_source_version": 1, + "source_must_be_unbound": true, + "typed_memo_documents_valid": 20, + "memo_version": 2, + "revision_command_digest": "sha256:745bc855bc9d392e0d390c9873d2765a3e546b7776580cbbdc33fa406f7839d1", + "packet_bytes_total": 173153, + "revision_json_bytes": 240027, + "negative_packet_cases_refused": [ + "helpercontentchanged", + "digestchanged", + "duplicatedigest" + ], + "executor_tests": 21, + "snapshot_mock_tests": 5, + "original_native_backup_completed": true, + "original_copy_uncertain_retained": true, + "original_approval_is_version1_only": true, + "new_version2_human_approval": false, + "version2_native_actions": false, + "live_submitted_version2": false, + "original_actual_image_source_and_scan_unchanged": true, + "same_proposal_trial": true +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json b/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json index 1df1d5b..35e3208 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json +++ b/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json @@ -1,14 +1,41 @@ [ { "id": "infd-20261011-purpose-overlay-r1", - "register": { + "publish": { + "version": 2, + "audience": { + "subjects": [], + "groups": [ + "net-kingdom-admins" + ] + } + }, + "review": { + "version": 2, + "options": { + "submitter": "state-hub", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + } + } + }, + "revise": { "memo": { "id": "infd-20261011-purpose-overlay-r1", - "version": 1, - "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", "requested_act": "approve", "binding_level": "organizational", - "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", "binding": { "principal": { "id": "pending-human-session", @@ -21,19 +48,19 @@ "label": "Informed Decision image-only purpose hardening on railiance01", "environment": "production" }, - "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." }, "step_kind": "approve", "packet": [ { "item_id": "decision-packet-md", "label": "decision-packet.md", - "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" }, { "item_id": "proposal-json", "label": "proposal.json", - "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + "hash": "sha256:e4d8fa77ce97f9cc190e9cae8f86478dba5e89cc7a13bf993e3b8d47a3160b36" }, { "item_id": "candidate-admission-json", @@ -58,7 +85,7 @@ { "item_id": "published-verification-json", "label": "published-verification.json", - "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" }, { "item_id": "registry-proof-json", @@ -73,12 +100,12 @@ { "item_id": "execution-bundle-json", "label": "execution-bundle.json", - "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" }, { "item_id": "sqlite-readonly-py", "label": "sqlite_readonly.py", - "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" }, { "item_id": "sealed-native-dependencies-json", @@ -88,7 +115,7 @@ { "item_id": "native-backup-restore-protocol-md", "label": "native-backup-restore-protocol.md", - "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" }, { "item_id": "inherited-vulnerability-follow-through-json", @@ -118,7 +145,7 @@ { "item_id": "preflight-inputs-json", "label": "preflight-inputs.json", - "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" }, { "item_id": "fresh-preflight-validation-json", @@ -143,16 +170,18 @@ "approval_id": null, "approval_binding_digest": null }, + "expected_version": 1, + "summary": "Same supervised trial: retain original approvedbackup and UNCERTAINcopy; correct explicitSQLiteclose/frozenimmutable reads and introduce exact named existing-snapshot rescue with separate hash-linked journal, fresh human review, unchanged image/scope.", "documents": [ { - "digest": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6", + "digest": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024", "media_type": "text/markdown", - "content_base64": "IyBJbmZvcm1lZCBEZWNpc2lvbiBwdXJwb3NlIG92ZXJsYXkgcmVsZWFzZQoKIyMgUmVxdWVzdGVkIGRlY2lzaW9uCgpBcHByb3ZlIHRoZSBleGFjdCBwdXJwb3NlLW9ubHkgaW1hZ2Ugcm9sbG91dCBhbmQgcHJvdGVjdGVkIHJlYWwtZGF0YSBiYWNrdXAvcmVzdG9yZSBwcm90b2NvbCBmb3IgdGhlIGV4aXN0aW5nIEluZm9ybWVkIERlY2lzaW9uIHNlcnZpY2Ugb24gcmFpbGlhbmNlMDEuIFRoaXMgcmVxdWVzdCBpcyBzZXBhcmF0ZSBmcm9tIHRoZSBhbHJlYWR5IGFwcHJvdmVkIGNvbmZpZy1vbmx5IHJlcGFpci4gT25seSB0aGUgZXhpc3RpbmcgRGVwbG95bWVudCBpbWFnZSBjaGFuZ2VzIHRocm91Z2ggdGhlIG93bmVyJ3MgbWFudWFsIEFyZ28gd29ya2Zsb3csIHdpdGggcHJ1bmUgZGlzYWJsZWQuIFJ1bnRpbWUgQ29uZmlnTWFwIGBpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MWAsIHNjaGVtYTUsIFBWQywgY3JlZGVudGlhbHMsIGF1ZGllbmNlLCBwb2xpY2llcywgcmVnaXN0cmllcywgYWNjZXNzLCByZXBsaWNhMSBhbmQgUmVjcmVhdGUgc3RyYXRlZ3kgcmVtYWluIGZpeGVkLiBFeGVjdXRlIGJ5IDIwMjYtMTAtMTJUMjM6NTk6NTlaLCBhZnRlciByZWZyZXNoZWQgc2VhbGVkLXNvdXJjZS9VSUQvY29uZmlndXJhdGlvbiBjaGVja3MgYW5kIGJhY2t1cC9yZXN0b3JlIGdhdGVzLiBBbGwgcGhhc2VzLCBpbmNsdWRpbmcgcmVjb3ZlcnkgYW5kIHZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUgdGhpcyBkZWFkbGluZS4gSWYgdGhlIHdpbmRvdyBpcyBleGhhdXN0ZWQsIHN0b3AgYW5kIG9idGFpbiBhIGZyZXNoIGZvdW5kZXIgZGVjaXNpb247IHRoaXMgbWF5IGRlbGF5IHJlY292ZXJ5LiBObyB0aW1lci9jb250cm9sbGVyIGF1dG9tYXRpY2FsbHkgY2hhbmdlcyB0aGUgcmVsZWFzZWQgaW1hZ2UuCgojIyBBcnRpZmFjdCBhbmQga25vd24gZmluZGluZwoKQWN0dWFsIG93bmVyIENJIHRhc2sxMTQ4NC9ydW4zIHB1Ymxpc2hlZCBpbW11dGFibGUgaW1hZ2UgYHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhYCBmcm9tIHNvdXJjZSBgM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OGAuIEFub255bW91cyByZWdpc3RyeSB2ZXJpZmljYXRpb24gcHJlc2VydmVzIGFsbCBlaWdodCBiYXNlIGNvbXByZXNzZWQgYmxvYnMvcm9vdGZzIGxheWVycyBhbmQgYWRkcyBvbmx5IHBvbGljeS5weSB3aXRoIGV4YWN0IHNvdXJjZSBoYXNoIGFuZCBtb2RlMDY0NC4gTGVnYWN5LWJ1aWxkZXIgbWVkaWEtdHlwZS9kZWZhdWx0IGNvbmZpZyBzZXJpYWxpemF0aW9uIGRpZmZlcmVuY2VzIGFyZSByZWNvcmRlZDsgdGhlIHJ1bnRpbWUgc2VtYW50aWNzIHJlbWFpbiB1bmNoYW5nZWQuIFB1bGxlZCBwdWJsaXNoZWQgaW1hZ2UgZXhlY3V0ZXMgYXMgVUlEMTAwMDEvR0lEMTAwMDEgYW5kIHBhc3NlcyB0ZW4gaW5zdGFsbGVkIGNoZWNrczogdHdvIHN1cHBvcnRlZCBiaW5kaW5nIGZvcm1zLCBlaWdodCBhZHZpc29yeS9tYWxmb3JtZWQgcmVmdXNhbHMuIFRlc3RzIHVzZSBzeW50aGV0aWMgdHJhbnNwb3J0IGFuZCBkbyBub3QgY2xhaW0gbmV3IG5hdGl2ZSBQRFAgYXV0aG9yaXphdGlvbiBwcm9vZi4gVGhlIHR3byBmYWlsZWQgQ0kgYXR0ZW1wdHMgcmVtYWluIGluIHRoZSBzYW1lIHRyaWFsIGhpc3RvcnkuCgpBY3R1YWwgdW5maWx0ZXJlZCBwaW5uZWQgc2Nhbm5lci9EQiBldmlkZW5jZSBjb3ZlcnM0NHBhY2thZ2VzOiB6ZXJvIEhJR0gvQ1JJVElDQUwsICoqb25lIGZpeGFibGUgTUVESVVNKiosIENWRS0yMDI2LTg1MDkxLCB6bGliMS4zLjItcjAgZml4ZWQgaW4xLjMuMi1yMS4gQWN0dWFsIGN1cnJlbnQtYmFzZSBzY2FuIGhhcyB0aGUgaWRlbnRpY2FsIGZpbmRpbmcuIEFwcHJvdmluZyB0aGlzIHBhY2tldCBleHBsaWNpdGx5IHBlcm1pdHMgdGhpcyBpbmhlcml0ZWQgZmluZGluZyBkdXJpbmcgdGhpcyBuYXJyb3cgcHVycG9zZSByZWxlYXNlOyBpdCBpcyBub3QgYSBSaXNrTmV4dXMgZXN0YXRlIHJpc2sgZ3JhZGUgb3IgemVyby1DVkUgY2xhaW0uIE93bmVyIHJlY29yZCBJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSBhbmQgbGl2ZSB0YXNrIElORkQtV1AtMDAwOS1UMDUgcmVxdWlyZSBzZXBhcmF0ZSBiYXNlIHJlZnJlc2ggYW5kIG5hdGl2ZSBhcHByb3ZhbCwgcmV2aWV3ZWQgYnkyMDI2LTEwLTE4LiBUaGF0IHJldmlldyBkYXRlIGlzIG1hbnVhbCBmb2xsb3ctdGhyb3VnaCwgd2l0aCBubyBhdXRvLWNvbnRyb2xsZXIgY2xhaW0uIFNjYW5uZXIgbm90ZXMgQWxwaW5lMy4yNCBhYnNlbnQgRU9MIGxpc3Q7IE9TIHZ1bG5lcmFiaWxpdHkgZGV0ZWN0aW9uIHJhbiBhZ2FpbnN0MzhPU3BhY2thZ2VzLiBVbmtub3duIHZ1bG5lcmFiaWxpdGllcyByZW1haW4gb3V0c2lkZSBzbmFwc2hvdCBrbm93bGVkZ2UuCgojIyBOYXRpdmUgYmFzZWxpbmUgYW5kIGdhdGVzCgpPcmlnaW5hbCByZWFkLW9ubHkgY2FwdHVyZTAxOjI1OjM4WjogZXhpc3RpbmcgRGVwbG95bWVudCBVSURhNTg4ZTEwYSwgUmVhZHkxLCBpbWFnZTdmNWMsIHVuY2hhbmdlZCBydW50aW1lNmM7IG5hdGl2ZSBhZG1pc3Npb24gcHJlc2VydmVzIHRoZSBmdWxsIGNvbmZpZ3VyYXRpb24gcGx1cyBleGFjdGx5IHRoZSBwcm9wb3NlZCBpbWFnZS4gQ2xpZW50ZGlmZiByZXR1cm5zMS4gUmVxdWVzdHMzNDYwLzQwMDBtQ1BVODYlLCBtZW1vcnk5NDcyTWk1OSU7IHJlZnJlc2ggYmVmb3JlIHJlbGVhc2UuIEV4aXN0aW5nIEFyZ28gQXBwbGljYXRpb24gVUlENDk5ODY4ZjIgaXMgbWFudWFsLCB0YXJnZXQ3ZGI4NDg1LCBIZWFsdGh5IHdpdGggcHJlLWV4aXN0aW5nIE91dE9mU3luYyBzdGF0dXMuIERvIG5vdCB0cmVhdCBhIHNjb3BlZCBEZXBsb3ltZW50IHJlbGVhc2UgYXMgZnVsbC1hcHAgcmVjb25jaWxpYXRpb24uIFByZXNlcnZlIGl0cyB0cmFja2luZy1pZDsgbm8gdW5yZWxhdGVkIHJlc291cmNlIHN5bmMvcHJ1bmUvYWRvcHRpb24uCgpUaGUgcmVmaW5lZCByZWFkLW9ubHkgaGVscGVyIGJpbmRzIG9yaWdpbmFsIHNvdXJjZS9oZWxwZXIvcmVuZGVyL2Jhc2VsaW5lIGhhc2hlcyBhbmQgYWN0dWFsIGltbXV0YWJsZSBDb25maWdNYXAvUFZDIFVJRHMsIHJ1bnRpbWUtZGF0YSBjaGVja3N1bSBhbmQgYm91bmQgdm9sdW1lIGlkZW50aXR5LCBleHBsaWNpdGx5IHJlZnVzZXMgb3B0aW1pemVkIGludGVycHJldGVycywgY2hlY2tzIGV4YWN0IGZyZXNoIGxpdmUgVUlEL2NvbmZpZ3VyYXRpb24gYW5kIGFkbWlzc2lvbiwgYW5kIHdyaXRlcyBhIHNlcGFyYXRlIGV4ZWN1dGlvbiByZWNlaXB0IG91dHNpZGUgdGhpcyBzZWFsZWQgcGFja2V0LiBGYWlsZWQgaW5pdGlhbCByYXcgS3VzdG9taXplIG1ldGFkYXRhIGNoZWNrIGlzIHJldGFpbmVkOiBkaXJlY3Qga3ViZWN0bCBhcHBseSB3b3VsZCBkcm9wIEFyZ28gdHJhY2tpbmctaWQuIFRoZSByZXZpZXdlZCBzZWxlY3RlZCBEZXBsb3ltZW50IGV4cGxpY2l0bHkgcmV0YWlucyB0aGF0IGV4aXN0aW5nIElELCBtYXRjaGluZyBBcmdvIG93bmVyc2hpcC4gQW55IHVucmVsYXRlZCBkcmlmdCwgZGlmZmVyZW50IFVJRCwgYWx0ZXJlZCBhZG1pc3Npb24sIHVuYXZhaWxhYmxlIHByb3RlY3RlZCBiYWNrdXAgY2FwYWNpdHksIHVuY2VydGFpbiBiYWNrdXAsIHJlc3RvcmUgbWlzbWF0Y2ggb3IgdW5oZWFsdGh5IGJhc2VsaW5lIHN0b3BzIHRoZSByZWxlYXNlLgoKIyMgUHJvdGVjdGVkIGJhY2t1cCBhbmQgcmVsZWFzZQoKQmVmb3JlICoqYW55KiogbmF0aXZlIHNvdXJjZSBvciBvZmZsaW5lLXJlc3RvcmVkIFN0b3JlL2FkbWluIG9wZW4sIHVzZSB0aGUgYXR0YWNoZWQgc3RkbGliIFNRTGl0ZSBtb2RlPXJvL3F1ZXJ5X29ubHkgY2hlY2tlciB0byByZXF1aXJlIHNjaGVtYTUsIGludGVncml0eT1vayBhbmQgY291bnQtb25seSBiYXNlbGluZS4gVGhlIGFkbWluIGF1dG9tYXRpY2FsbHkgbWlncmF0ZXMgb2xkc2NoZW1hcywgc28gYSBwb3N0LW9wZW4gcmVwb3J0IGFsb25lIGNhbm5vdCBwcm92ZSBubyBtaWdyYXRpb24uIFJlZnVzZSBvdGhlciBzY2hlbWFzIGJlZm9yZSBhZG1pbi4gVGhlbiB1c2UgdGhlIGV4aXN0aW5nIG93bmVyIGFkbWluJ3MgU1FMaXRlIGJhY2t1cCBBUEksIG5vdCBhIHJhdyBjb3B5IG9mIHRoZSBsaXZlIGRhdGFiYXNlL1dBTC4gUHJvdGVjdCBkaXJlY3RvcmllczA3MDAvZmlsZXMwNjAwLCBvd25lZCBieTEwMDAxLiBSZXRhaW4gaW5kZXBlbmRlbnRseSBwcm90ZWN0ZWQgb2ZmLWNsdXN0ZXIgc25hcHNob3QgY3VzdG9keSBhbmQgb25seSBjb3VudC9oYXNoIHJlY2VpcHRzLiBObyBkYXRhYmFzZSBjb250ZW50cywgY2FsbGVyIHRva2VucywgcmVxdWVzdGVyIFNlY3JldCBvciBydW50aW1lIGNyZWRlbnRpYWwgZmlsZXMgZW50ZXIgR2l0LCBTdGF0ZSBIdWIsIGxvZ3Mgb3IgdGhpcyBwYWNrZXQuIE5hdGl2ZSBiYWNrdXAgYW5kIG9mZmxpbmUgcmVhbC1kYXRhIHJlc3RvcmUgaGF2ZSBub3QgeWV0IG9jY3VycmVkLiBVc2UgYW4gaXNvbGF0ZWQgcHJpdmF0ZSBkaXNwb3NhYmxlIGNvcHksIG5ldHdvcmtub25lIGFuZCBubyBydW50aW1lIGNvbmZpZy90b2tlbiBtb3VudHMsIHJ1biB0aGUgcHJlLW9wZW4gY2hlY2tlciBhbmQgZXhhY3Qgb2ZmbGluZSBgLS1lbnRyeXBvaW50IGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGluc3BlY3QgLS1kYiAvcmVzdG9yZS9yZXZpZXcuc3FsaXRlYCBhZnRlciBpdCBwYXNzZXMsIGNvbXBhcmluZyBmcm96ZW4gc25hcHNob3QgY291bnRzIHdpdGhvdXQgc2VydmljZSBzdGFydHVwLCB0aGVuIGNsZWFuIG9ubHkgdGhlIGRpc3Bvc2FibGUgcmVzdG9yZWQgY29weS4gUmV0YWluIHRoZSBvcmlnaW5hbCBzbmFwc2hvdC4gVGhlIGF0dGFjaGVkIHByb3RvY29sIGJpbmRzIGNhc2Utc3BlY2lmaWMgcGF0aHMgYW5kIGZhaWwtY2xvc2VkIGNhcGFjaXR5L2N1c3RvZHkgY2hlY2tzLgoKUmVmcmVzaCBhIGNvbnNpc3RlbnQgb25saW5lIHNuYXBzaG90IGltbWVkaWF0ZWx5IGJlZm9yZSBpbWFnZS1vbmx5IGN1dG92ZXIuIFRoaXMgcHJvdG9jb2wgZG9lcyBub3QgYXNzZXJ0IHRyYWZmaWMvZGlzcGF0Y2hlciBxdWllc2NlbmNlLiBDdXJyZW50IGFuZCBjYW5kaWRhdGUgc2hhcmUgc2NoZW1hNSBhbmQgdW5jaGFuZ2VkIHN0b3JlIGNvZGU7IHJvbGxiYWNrIHJldGFpbnMgdGhlIGxhdGVzdCBsaXZlIGRhdGFiYXNlIGFuZCBhbGwgbmV3L3VuY2VydGFpbiBldmlkZW5jZS4gU3RvcCB0aGUgb2xkIHdyaXRlciBiZWZvcmUgdGhlIG5ldyBvbmUgd2l0aCBleGlzdGluZyBSZWNyZWF0ZSBhbmQgc2luZ2xlLXdyaXRlciBsb2NrLiBEbyBub3QgcmVzdG9yZSBhbiBvbGRlciBzbmFwc2hvdCBvdmVyIGxhdGVyIHdyaXRlcywgZGlzY2FyZCB1bnJlc29sdmVkIGV4dGVybmFsIGVmZmVjdHMsIHNjYWxlIG90aGVyIHdvcmtsb2FkcywgY2hhbmdlIHBvbGljaWVzL2lkZW50aXR5L2N1c3RvZHksIG9yIGNyZWF0ZSBodW1hbiBkaXNwb3NpdGlvbnMgdG8gbWFrZSBjaGVja3MgZ3JlZW4uCgpQaW4gdGhlIGV4aXN0aW5nIEFwcGxpY2F0aW9uIHRvIHRoZSBleGFjdCBvd25lciBjb21taXQgY29udGFpbmluZyB0aGUgYXBwcm92ZWQgY2FuZGlkYXRlIHNvdXJjZSBoYXNoZXMsIGFuZCBtYW51YWxseSBzeW5jIG9ubHkgRGVwbG95bWVudC9pbmZvcm1lZC1kZWNpc2lvbiB3aXRoIHBydW5lPWZhbHNlLiBWZXJpZnkgYWN0dWFsaW1hZ2UvbW9kdWxlL21vZGUvVUlELCBoZWFsdGgvcmVhZGluZXNzIGFuZCBpbnN0YWxsZWQgcHVycG9zZSByZWZ1c2FscyBvbiB0aGUgcmVhbCBwbGFjZW1lbnQ7IGV4cGxpY2l0bHkgZGlzdGluZ3Vpc2ggc3ludGhldGljLXRyYW5zcG9ydCBjaGVja3MgZnJvbSBhY3R1YWwgcHJvdmlkZXIgZXZpZGVuY2UuIEV4aXN0aW5nIG5hdGl2ZSBiaW5kaW5nL2xpZmVjeWNsZSBiZWhhdmlvciBtdXN0IHJlbWFpbiBhdmFpbGFibGUuIElmIHVuaGVhbHRoeSBvciB2ZXJpZmljYXRpb24gZmFpbHMsIHJldHVybiBBcHBsaWNhdGlvbiBzb3VyY2UgdG83ZGI4NDg1IGFuZCBzY29wZWQtc3luYyBwcmlvciBzYW1lLXNjaGVtYSBpbWFnZTdmNWMsIHByZXNlcnZpbmcgY3VycmVudCBldmlkZW5jZSBkYXRhYmFzZTsgcmV0YWluIGZhaWxlZCBvdXRjb21lcy4gQW55IGRhdGEgcmVjb3ZlcnkgYmV5b25kIHRoaXMgc2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sgaXMgYSBzZXBhcmF0ZSBmb3VuZGVyIGRlY2lzaW9uLgoKIyMgQWx0ZXJuYXRpdmVzIGFuZCBlc3RpbWF0ZXMKClByb2NlZWQgd2l0aCB0aGlzIG5hcnJvdyByZWxlYXNlIHBsdXMgZXhwbGljaXQgaW5oZXJpdGVkLW1lZGl1bSBmb2xsb3ctdGhyb3VnaCwgb3IgZGVmZXIgYW5kIHByZXBhcmUgYSBzZXBhcmF0ZSBiYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCBiZWZvcmUgYW55IHJlbGVhc2UuIE5vIGFkZGl0aW9uYWwgcmVjdXJyaW5nIGhvc3RpbmcgaXMgcHJvcG9zZWQ6IGVzdGltYXRlZCBpbmNyZW1lbnRhbCBpbmZyYXN0cnVjdHVyZSBFVVIwLCB3aXRoIHByaXZhdGUgc3RvcmFnZSBhbmQgYXR0ZW5kZWQgZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZC4gUmlza3MgaW5jbHVkZSBhIGJyaWVmIFJlY3JlYXRlIGludGVycnVwdGlvbiwgcHJpdmF0ZSBiYWNrdXAgY3VzdG9keSBlcnJvcnMsIGNhbGxlciByZWZ1c2FsIHdoZW4gYWR2aXNvcnkgcmVzcG9uc2VzIHdlcmUgaW1wcm9wZXJseSB0cmVhdGVkIGFzIGJpbmRpbmcsIGFuZCB0aGUgZGlzY2xvc2VkIGluaGVyaXRlZCBmaW5kaW5nLiBUaGlzIGRlY2lzaW9uIGRvZXMgbm90IHByb21vdGUgYWdlbnQgYXV0b25vbXkgb3IgZ3JhbnQgdW5yZWxhdGVkIHdvcmsuCgojIyBJbmRlcGVuZGVudCByZXZpZXcgcmVmaW5lbWVudHMKClRoZSBpbml0aWFsMzZwYXRoLzIwZG9jdW1lbnQgcGFja2V0IGF0IG1hbmlmZXN0N2M2NzM4YjMgYW5kIHN1Ym1pc3Npb25hYzQxYzhhZSBpcyBwcmVzZXJ2ZWQgaW4gc291cmNlIHByZXBhcmF0aW9uIGV2aWRlbmNlLCB3aXRoIHRoZSBmYWlsZWQvY29uZGl0aW9uYWwgcmV2aWV3LiBJbmRlcGVuZGVudCBQbGF0Zm9ybSByZXZpZXcgaWRlbnRpZmllZCBhZG1pbiBhdXRvLW1pZ3JhdGlvbiwgb3B0aW1pemF0aW9uIGJ5cGFzcywgYW5kIGFjdHVhbCBzYW1lLW5hbWUgQ29uZmlnTWFwL1BWQyByZXBsYWNlbWVudCBnYXBzLiBUaGUgYW1lbmRlZCBwYWNrZXQgYWRkcyBwcmUtb3BlbiBzdGRsaWIgcmVhZC1vbmx5IHNjaGVtYS9pbnRlZ3JpdHkvY291bnQgZ2F0ZXMsIGV4cGxpY2l0IGxvY2FsL3JlbW90ZSBvcHRpbWl6YXRpb24gcmVmdXNhbCwgYW5kIGluZGVwZW5kZW50bHkgc2VhbGVkIGFjdHVhbCBuYXRpdmUgY29uZmlnL1BWQyBjdXN0b2R5IGNoZWNrcy4gVGhlc2UgYXJlIHJlZmluZW1lbnRzIGluIHRoZSBzYW1lIHByb3Bvc2FsL3RyaWFsLCB3aXRoIG5vIG9yaWdpbmFsIG9yIGFtZW5kZWQgZm91bmRlciBhcHByb3ZhbCBjbGFpbWVkLgoKIyMgTWVjaGFuaWNhbGx5IGJvdW5kIGhlbHBlciBhbmQgcmVjb3ZlcnkgcmVmaW5lbWVudAoKVGhlIGRpcmVjdGx5IGF0dGFjaGVkIGV4ZWN1dGlvbi1idW5kbGUuanNvbiBiaW5kcyBleGFjdCBzdXBlcnZpc2VkIGhlbHBlciBzb3VyY2VzLCBwbGFuLCB0ZXN0cyBhbmQgUEVORElORyBhdXRob3JpdHkgdGVtcGxhdGUuIEl0IHZlcmlmaWVzIGFsbCBmb3VyIGNvbW1pdHRlZCBvd25lciBLdXN0b21pemUgaW5wdXRzIGFuZCByZWplY3RzIHByZXNlbnQgYXV0b21hdGVkOnt9IGFzIHdlbGwgYXMgc291cmNlIG92ZXJyaWRlcy4gUm9vdCBtdXN0IGZyZXNobHkgYXV0aGVudGljYXRlIHRoZSBleGFjdCBmb3VuZGVyIG5hdGl2ZSBkaXNwb3NpdGlvbiBiZWZvcmUgZXZlcnkgcGhhc2U7IHJlY2VpcHQgYm9va2tlZXBpbmcgaXMgbm90IGFuIGF1dG9ub21vdXMgc2lnbmVkIGdyYW50LiBUaGUgc2FtZSBwcm9wb3NhbC90cmlhbCBwcmVzZXJ2ZXMgdGhlIGVhcmxpZXIzNnBhdGg3YyBwYWNrZXQsIGFtZW5kZWQ3OHBhdGhiMSBwYWNrZXQgYW5kIG9yaWdpbmFsMTFmaWxlNjUzIGhlbHBlciBwbHVzIGNvbmRpdGlvbmFsIHJldmlldyBmaW5kaW5ncy4KClRoZSBvZmZsaW5lIGNvcHkgdXNlcyBvbmUgVUlEMC9DQVBfQ0hPV04tb25seSBpbml0aWFsaXplciBjb25maW5lZCB0byB0aGUgTkVXIG5vbmNlLWJvdW5kIGxvY2FsIHZvbHVtZSwgZXhhY3QgY2FuZGlkYXRlIGltYWdlLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pLCBubyBob3N0L2xpdmVQVkMvY29uZmlnL3Rva2VuIG1vdW50cy4gQWxsIGZvbGxvd2luZyBwcmUtb3Blbi9hZG1pbi9wb3N0LW9wZW4gY2hlY2tzIGFyZSBVSUQxMDAwMS4gUG9zdC1hZG1pbiByZWFkb25seSBzY2hlbWE1L2ludGVncml0eS9jb3VudHMgbXVzdCBtYXRjaCB0aGUgZnJvemVuIHNuYXBzaG90IGFuZCBvcmlnaW5hbCBzbmFwc2hvdCBTSEEgbXVzdCByZW1haW4gdW5jaGFuZ2VkLiBSb2xsYmFjayBkaXNwYXRjaCBuZXZlciByZXF1aXJlcyB0aGUgZmFpbGluZyBjYW5kaWRhdGUgdG8gYmUgUmVhZHkgb3Igb3BlbnMgaXRzIGRhdGFiYXNlOyBzZWFscy9zb3VyY2UvaW1hZ2UgcGFpci9hZG1pc3Npb24gQ0FTIHN0aWxsIGdhdGUgaXQuIEEgc2VwYXJhdGUgcm9sbGJhY2stdmVyaWZ5IHByb3ZlcyByZWNvdmVyZWQgb2xkLWltYWdlIFJlYWR5MS9zY29wZWQgb3BlcmF0aW9uL3NjaGVtYTUgcmV0YWluZWQtY3VycmVudC1EQiBpbnRlZ3JpdHkuIFNhbWUtcGhhc2UgcmV0cmllcyBhcmUgcmVmdXNlZCBhZnRlciBhbWJpZ3VvdXMgb3V0Y29tZXMuCgpSYXcgc2Nhbi9TQk9NL2Jhc2Utc2NhbiBieXRlcyByZW1haW4gcmV0YWluZWQgdW5jaGFuZ2VkLCBoYXNoLWJvdW5kIGJ5IHRoZSBkaXJlY3RseSBhdHRhY2hlZCBwdWJsaXNoZWQtdmVyaWZpY2F0aW9uIHJlY2VpcHQ7IHRoZSBidW5kbGUgcmVwbGFjZXMgb25seSB0aGUgZGlyZWN0IHJhdyBzY2FuIGF0dGFjaG1lbnQgdG8gc3RheSB3aXRoaW4gdHdlbnR5IGRvY3VtZW50cy4gS25vd24gZml4YWJsZSBpbmhlcml0ZWQgTUVESVVNIGFuZCBUMDUgZm9sbG93LXRocm91Z2ggcmVtYWluIHZpc2libGUuIFRlbiBpbnN0YWxsZWQgc3ludGhldGljIGNoZWNrcywgaW5jbHVkaW5nIHRob3NlIGxhdGVyIG9uIGFjdHVhbCBwbGFjZW1lbnQsIGV4cGxpY2l0bHkgaGF2ZSBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIEFjdHVhbCBwcm92aWRlci9QRFAgYXV0aG9yaXR5IGV2aWRlbmNlIGlzIGEgZGlzdGluY3QgVDA0IGNvbXBsZXRpb24gZ2F0ZSBhbmQgaXMgbm90IHN1cHBsaWVkIGJ5IHRoZXNlIGNoZWNrcy4gU291cmNlIHByZXBhcmF0aW9uIGJhc2lzIGUwMzU5YmNiNmNkZmFkOWFiM2U4NjgwNTQxMjFmZTBjZWJlYzJkNjggcGx1czkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUgaXMgcmVjb3JkZWQ7IHRoZSBmaW5hbCBhcHBsaWVkIG93bmVyIGNvbW1pdCBtdXN0IGJlIHBpbm5lZCBiZWZvcmUgZXhlY3V0aW9uLgo=" + "content_base64": "IyBJbmZvcm1lZCBEZWNpc2lvbiB2ZXJzaW9uMiBleGlzdGluZy1zbmFwc2hvdCByZXNjdWUgYW5kIGltYWdlIHJlbGVhc2UKCkFwcHJvdmUgdGhlIGV4YWN0IHNvdXJjZS1yZWZpbmVkIHJlY292ZXJ5IG9mIHRoZSBmYWlsZWQgZHJpbGwtY29weSBhbmQgY29uZGl0aW9uYWwgcmVtYWluaW5nIGJhY2t1cC9kcmlsbC9EZXBsb3ltZW50LW9ubHkgaW1hZ2Ugcm9sbG91dC4gVGhpcyBpcyBtZW1vIHZlcnNpb24yIGluIHRoZSBzYW1lIHByb3Bvc2FsL3RyaWFsLCByZXF1aXJpbmcgTkVXIGZvdW5kZXIgYWNjZXB0YW5jZTsgb3JpZ2luYWwgdmVyc2lvbjEgYWNjZXB0YW5jZSBpcyByZXRhaW5lZCBhbmQgY2Fubm90IGF1dGhvcml6ZSBjaGFuZ2VkIGhlbHBlcmJ5dGVzLgoKT3JpZ2luYWwgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCB0aGUgcHJvdGVjdGVkIG5hdGl2ZSBkcmlsbC1iYWNrdXAsIHRoZW4gY29weSBmYWlsZWQgYmVmb3JlIGFueSBsb2NhbGZpbGUuIE1ldGFkYXRhLW9ubHkgdmVyaWZpY2F0aW9uIHByb3ZlcyB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMC9wcml2YXRlU0hNMzI3NjguIFRoZSBvcmlnaW5hbCByZWFkZXIgY291bGQgbGVhdmUgU0hNIGluZGV4aW5nIGJlY2F1c2UgaXRzIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgY2xvc2UuIFRoZSBjb3JyZWN0aW9uIGV4cGxpY2l0bHljbG9zZXMgYWxsIHJlYWRlcnMgYW5kIHVzZXMgaW1tdXRhYmxlIHJlYWRzIE9OTFkgZm9yIGEgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbm90IGxpdmUgb3Igd3JpdGFibGVjbG9uZS4gU0hNIHN0YXlzIHVuY2hhbmdlZDsgbm9uemVyb1dBTC9oYXNoL2lkZW50aXR5IGRyaWZ0IHN0b3BzIHJlc2N1ZS4KCkRpc3RpbmN0IGRyaWxsLWNvcHktcmVzY3VlLXIxL25ld2xpbmtlZGpvdXJuYWwgcHJlc2VydmVzIG9yaWdpbmFsIFVOQ0VSVEFJTmNvcHkgYW5kIGV4YWN0IGpvdXJuYWxoYXNoL2F0dGVtcHRzLiBObyBvbGRyZXRyeS9vdmVyd3JpdGUsIG5vIG5ld2RyaWxsYmFja3VwLiBSZXF1aXJlIG9yaWdpbmFsQ09NUExFVEViYWNrdXAvVU5DRVJUQUlOY29weSBvbmx5LCBhYnNlbnRsb2NhbGZpbGVzL3Jlc3RvcmV2b2x1bWUsIG9yaWdpbmFsbmF0aXZlUG9kVUlEL2N1cnJlbnRvbGRpbWFnZStzb3VyY2VwaW4gYW5kIGFsbENNL1BWQy9EZXBsb3ltZW50IHNlYWxzLiBDb3B5IHNuYXBzaG90Ynl0ZXMgb25seSBpbnRvIGEgbmV3cHJpdmF0ZTA2MDBmaWxlLiBSZW1haW5pbmdvcmRlcmVkcGhhc2VzIGV4cGxpY2l0bHkgY29uc3VtZSBDT01QTEVURXJlc2N1ZXJlc3VsdDsgb25lIGlzb2xhdGVkIFVJRDAvQ0FQX0NIT1dOLW9ubHkgTkVXdm9sdW1lIGluaXRpYWxpemVyIHRoZW4gVUlEMTAwMDEgcHJlLW9wZW4vYWRtaW4vcG9zdC1hZG1pbiBjaGVja3MgcHJvdmVzIHJlYWwtZGF0YSBjb21wYXRpYmlsaXR5IGJlZm9yZSBjdXRvdmVyLiBObyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50czsgbm8gc2VydmljZSBzdGFydHVwLiBBbnkgYXR0ZW1wdGVkIGZhaWx1cmUvYW1iaWd1aXR5IGlzIGR1cmFibGUgYW5kIGNhbm5vdHJldHJ5LgoKSW1hZ2U3NjNjIGZyb20gYWN0dWFsQ0kzZTRiY2IyNiByZW1haW5zIHVuY2hhbmdlZDhiYXNlIGxheWVycyBwbHVzcG9saWN5LnB5OyBsZWdhY3lzZXJpYWxpemF0aW9uIGRpZmZlcmVuY2VzIGRpc2Nsb3NlZC4gQWN0dWFsaW5zdGFsbGVkVUlEMTAwMDEvMTBwdXJwb3NldmFyaWFudHMgcGFzczsgbmF0aXZlX3Byb3ZpZGVyPWZhbHNlL3N5bnRoZXRpY3RyYW5zcG9ydCBpcyBub3QgYWN0dWFsUERQYXV0aG9yaXR5IHByb29mLCB3aGljaCByZW1haW5zIHNlcGFyYXRlVDA0Z2F0ZS4gQWN0dWFsZnVsbDQ0cGFja2FnZXNjYW4wSElHSC9DUklUSUNBTCwgT05FZml4YWJsZWluaGVyaXRlZE1FRElVTXpsaWJDVkUtMjAyNi04NTA5MSgxLjMuMi1yMOKGknIxKSwgaWRlbnRpY2FsYmFzZWZpbmRpbmcuIEV4cGxpY2l0dGVtcG9yYXJ5cGVybWlzc2lvbiBmb3IgdGhpcyBmaW5kaW5nIGlzIHJlcXVlc3RlZCBhZ2Fpbiwgd2l0aCBvd25lclQwNS9yaXNrcmVjb3JkZHVlT2N0MTg7IG5vIHplcm8tQ1ZFL1Jpc2tOZXh1c2dyYWRlY2xhaW0uIFJhd3NjYW4vU0JPTS9iYXNlIHNjYW4gc3RheSB1bmNoYW5nZWRoYXNoYm91bmQgdmlhIHB1Ymxpc2hlZHJlY2VpcHQ7IGV4YWN0aGVscGVyYW5kb3JpZ2luYWxjb3VudC1vbmx5cmVjZWlwdHMgZGlyZWN0bHlidW5kbGUtYm91bmQgd2l0aGluMjBkb2NzLgoKQWZ0ZXIgcmVzY3VlK29mZmxpbmVnYXRlcywgZGlzdGluY3RjdXRvdmVyYmFja3VwL2NvcHkgYW5kIG1hbnVhbEFyZ29EZXBsb3ltZW50LW9ubHkgaW1hZ2U3NjNjL3BydW5lPWZhbHNlIHJlbWFpbiBjb25kaXRpb25hbC4gRm91cmNvbW1pdHRlZEt1c3RvbWl6ZWJsb2JzL2N1cnJlbnRmaW5hbHNvdXJjZUhFQUQvaGVscGVycy9jYXNlaGFzaGVzIG1hdGNoOyBhdXRvbWF0ZWR7fSBvciBvdmVycmlkZXMgcmVmdXNlLiBDb25maWc2Yy9zY2hlbWE1L1BWQy9pZGVudGl0eS9wb2xpY2llcy9yZXBsaWNhMVJlY3JlYXRlIHN0YXlmaXhlZC4gUm9sbGJhY2tkb2Vzbm90bmVlZCBSZWFkeWNhbmRpZGF0ZSBvciBpdHNEQmV4ZWM7IG9sZGltYWdlUmVhZHkvc2NvcGVkb3BlcmF0aW9uL3NjaGVtYTVjdXJyZW50REIgaXMgYSBzZXBhcmF0ZXByb29mLiBQcmVzZXJ2ZSBsYXRlc3RsaXZlREIvYWxsbmV3Y29tbWl0cyBhbmQgYWxsdW5jZXJ0YWlub3V0Y29tZXM7IG5ldmVycmVzdG9yZW9sZGVyYmFja3VwIG92ZXJsYXRlcnJlY29yZHMuCgpBbGxwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZS9yZWNvdmVyeS92ZXJpZnkgbXVzdGJlZ2luIGJlZm9yZU9jdDEyIDIzOjU5OjU5WjsgZXhwaXJ5cmVxdWlyZXNuZXdkZWNpc2lvbiBhbmQgbWF5ZGVsYXlyZWNvdmVyeS4gTm8gYXV0b21hdGljZXhwaXJ5Y29udHJvbGxlci4gRnJlc2hyb290LWF1dGhlbnRpY2F0ZWQgbmF0aXZlZm91bmRlcmFjY2VwdGFuY2UgdmVyc2lvbjIgYmVmb3JlZWFjaHBoYXNlOyByZWNlaXB0cyBhcmUgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3RzaWduZWRncmFudC9hdXRvbm9teS4gRVVSMCByZWN1cnJpbmdpbmZyYSwgZXhpc3Rpbmdwcml2YXRlY29weS9zdG9yYWdlL2F0dGVuZGVkdGltZSB1bnByaWNlZDsgbm8gc2Vjb25kbmF0aXZlIGRyaWxsYmFja3VwLiBFeGFjdG9yaWdpbmFsYXBwcm92ZWRwYWNrZXQvZmFpbHVyZS90ZWNobmljYWxyZWZpbmVtZW50cyBwcmVzZXJ2ZWQgc2FtZXByb3Bvc2FsL3RyaWFsLiBObyB2ZXJzaW9uMm5hdGl2ZW9wZXJhdGlvbiB5ZXQuCg==" }, { - "digest": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df", + "digest": "sha256:e4d8fa77ce97f9cc190e9cae8f86478dba5e89cc7a13bf993e3b8d47a3160b36", "media_type": "application/json", - "content_base64": "ewogICJwcm9wb3NhbF9pZCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgInRyaWFsX2lkIjogImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMSIsCiAgInN0YXRlIjogInByZXBhcmVkLXVuYXBwcm92ZWQiLAogICJ0YXJnZXQiOiAicmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbiIsCiAgImF1dGhvcml0eSI6ICJBRE1JTklTVEVSOyBhY3RpdmF0aW9uIEFQUFJPVkVEIG9ubHkgdXBvbiBleGFjdCBmb3VuZGVyIGRpc3Bvc2l0aW9uIiwKICAiY2FuZGlkYXRlX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYSIsCiAgInB1Ymxpc2hlZF9zb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInByaW9yX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgInByaW9yX2FyZ29fcmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgIm5hdGl2ZV9vYmplY3QiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJhcHBzL3YxIiwKICAgICJraW5kIjogIkRlcGxveW1lbnQiLAogICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAidWlkIjogImE1ODhlMTBhLTkwZDItNDg4My05NzVlLTZkZDhiOGZlY2E5MiIKICB9LAogICJhcmdvX2FwcGxpY2F0aW9uX3VpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICJzb3VyY2VfZ2F0ZSI6ICJBbGwgZm91ciBleGFjdCBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGluIGV4ZWN1dGlvbi1wbGFuLmpzb24gYW5kIGNsZWFuIGN1cnJlbnQgb3duZXIgSEVBRCBtdXN0IG1hdGNoOyBzb3VyY2UgcHJlcGFyYXRpb24gaXMgbm90IG5hdGl2ZSBhcHByb3ZhbCIsCiAgInN5bmNfc2NvcGUiOiBbCiAgICAiYXBwczpEZXBsb3ltZW50OmluZm9ybWVkLWRlY2lzaW9uIgogIF0sCiAgInBydW5lIjogZmFsc2UsCiAgImF1dG9tYXRlZF9zeW5jIjogZmFsc2UsCiAgInJ1bnRpbWVfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAic2NoZW1hIjogNSwKICAicmVxdWVzdGVkX29wZXJhdGlvbnMiOiBbCiAgICAiUHJvdGVjdGVkIFNRTGl0ZS1jb25zaXN0ZW50IG5hdGl2ZSBiYWNrdXAgYW5kIGluZGVwZW5kZW50bHkgcHJvdGVjdGVkIG9mZi1jbHVzdGVyIGN1c3RvZHkiLAogICAgIk9mZmxpbmUgcmVzdG9yZS9pbnRlZ3JpdHkvY291bnQgY29tcGFyaXNvbiBvbiBhIHByaXZhdGUgZGlzcG9zYWJsZSB2b2x1bWUgd2l0aCBleGFjdCBjYW5kaWRhdGUsIG5vIHJ1bnRpbWUgdG9rZW5zL2NvbmZpZy9uZXR3b3JrIiwKICAgICJSZWZyZXNoIGEgY29uc2lzdGVudCBwcmUtY3V0b3ZlciBzbmFwc2hvdCwgcmV0YWluIHByaXZhdGUgY29waWVzIGFuZCBjb3VudC1vbmx5L2hhc2ggcmVjZWlwdHMiLAogICAgIlBpbiBleGlzdGluZyBtYW51YWwgQXJnbyBBcHBsaWNhdGlvbiB0byBleGFjdCBhcHByb3ZlZCBvd25lciBzb3VyY2UgYW5kIG1hbnVhbGx5IHN5bmMgb25seSBleGlzdGluZyBEZXBsb3ltZW50IGltYWdlIiwKICAgICJWZXJpZnkgaGVhbHRoL3JlYWRpbmVzcy9pbWFnZS9tb2R1bGUvaW5zdGFsbGVkIGZhaWwtY2xvc2VkIHB1cnBvc2UgY2hlY2tzIGFuZCByZXRhaW5lZCBzY2hlbWEvY291bnQgZXZpZGVuY2U7IHJlY292ZXIgdG8gcHJpb3Igc2FtZS1zY2hlbWEgaW1hZ2UgaWYgbmVlZGVkIgogIF0sCiAgImV4ZWN1dGVfYnkiOiAiMjAyNi0xMC0xMlQyMzo1OTo1OVoiLAogICJ0ZW1wb3JhcnlfdnVsbmVyYWJpbGl0eV9yZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJrbm93bl9zY2FuX2ZpbmRpbmdzIjogIjBISUdIL0NSSVRJQ0FMLDFmaXhhYmxlIGluaGVyaXRlZE1FRElVTSB6bGliLCBhY3R1YWwgY3VycmVudGJhc2UrY2FuZGlkYXRlIGZpbmRpbmdzIGlkZW50aWNhbCIsCiAgInZ1bG5lcmFiaWxpdHlfcmVjb3JkIjogIklORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxIC8gSU5GRC1XUC0wMDA5LVQwNSIsCiAgImNvc3RfZXN0aW1hdGVfRVVSIjogMCwKICAiY29zdF9saW1pdHMiOiAiTm8gbmV3IHJlY3VycmluZyBpbmZyYXN0cnVjdHVyZTsgcHJpdmF0ZSBiYWNrdXAgc3RvcmFnZSBhbmQgYXR0ZW5kZWQgZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZCwgbm90IGFuIGF1dG9waWxvdCBjb3N0IGdyYW50IiwKICAicmlza19lc3RpbWF0ZXMiOiBbCiAgICAiQnJpZWYgUmVjcmVhdGUgc2VydmljZSBpbnRlcnJ1cHRpb247IG5vIGNvbmN1cnJlbnQgbmV3IHdyaXRlci9zdXJnZSIsCiAgICAiUHJpdmF0ZSBldmlkZW5jZSBzbmFwc2hvdCBjdXN0b2R5IGFuZCBkaXNwb3NhbCBlcnJvcnM7IG5vIHNuYXBzaG90cy90b2tlbnMgaW4gcHVibGljIGV2aWRlbmNlIiwKICAgICJDYW5kaWRhdGUgcHVycG9zZSByZWZ1c2FsIG1heSBleHBvc2UgY2FsbGVycyByZWx5aW5nIG9uIGFkdmlzb3J5IHJlc3VsdHMgYXMgYmluZGluZyIsCiAgICAiSW5oZXJpdGVkIGtub3duIGZpeGFibGUgTUVESVVNIHJlbWFpbnMgdW50aWwgc2VwYXJhdGVseSBhcHByb3ZlZCBvd25lciByZW1lZGlhdGlvbiIsCiAgICAiRXhpc3RpbmcgQXJnbyBPdXRPZlN5bmMgYmFzZWxpbmUgaXMgcmV0YWluZWQ7IG5vIHdob2xlLWFwcCBzeW5jIG9yIHVucmVsYXRlZCByZXBhaXJzIHBlcm1pdHRlZCIsCiAgICAiQWxsIHBoYXNlcywgaW5jbHVkaW5nIHJlY292ZXJ5L3ZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUgT2N0MTIgZGVhZGxpbmU7IGlmIHJlY292ZXJ5IHdpbmRvdyBpcyBleGhhdXN0ZWQgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gTm8gYXV0b21hdGljIGV4cGlyeSBjb250cm9sbGVyLiIKICBdLAogICJyb2xsYmFjayI6ICJNYW51YWwgQXJnbyBzb3VyY2UgcGluIGJhY2sgdG83ZGI4NDg1IGFuZCBzY29wZWQgRGVwbG95bWVudC1vbmx5IHN5bmMgdG83ZjVjIGltYWdlOyByZXRhaW4gY3VycmVudCBzY2hlbWE1IGRhdGFiYXNlIGFuZCBhbGwgcG9zdC1jdXRvdmVyIGV2aWRlbmNlLCBuZXZlciByZXN0b3JlIG9sZGVyIHNuYXBzaG90IG92ZXIgbGl2ZSB3cml0ZXMiLAogICJuYXRpdmVfZXhlY3V0ZWQiOiBmYWxzZSwKICAiaHVtYW5fYXBwcm92YWwiOiBmYWxzZSwKICAicmVmaW5lbWVudF9vZl9tYW5pZmVzdCI6ICI3YzY3MzhiMzllYThlNTRlNjFjOGVkNjI1ZTk0YWQwYjI3NTVlNjcyZTE1NzZlZmNkZjg0YTFkNjY1YWMzMzAwIiwKICAibWFuZGF0b3J5X3ByZV9vcGVuX2dhdGUiOiAic3RkbGliU1FMaXRlIG1vZGU9cm8vcXVlcnlfb25seTogc2NoZW1hNStpbnRlZ3JpdHkrY291bnQgYmFzZWxpbmUgYmVmb3JlIEFOWSBTdG9yZS9hZG1pbiBvbiBuYXRpdmUgc291cmNlIG9yIHJlc3RvcmVkY29weTsgcmVmdXNlb2xkc2NoZW1hcyB3aXRob3V0IG1pZ3JhdGlvbiIsCiAgIm9wdGltaXplZF9pbnRlcnByZXRlcnMiOiAibG9jYWwrcmVtb3RlIGV4cGxpY2l0bHlyZWZ1c2VkIGJlZm9yZWFzc2VydCBnYXRlcyIsCiAgIm5hdGl2ZV9kZXBlbmRlbmN5X2dhdGUiOiAic2VhbGVkIGFjdHVhbENNIFVJRC9pbW11dGFibGUvY2Fub25pY2FsZGF0YWhhc2grUFZDIFVJRC9mdWxsc3BlYy9Cb3VuZC92b2x1bWVOYW1lLCBubyByYXdDTWRhdGEgb3JTZWNyZXQgcmVhZHMiLAogICJsaXZlX2NvdW50cyI6ICJGcm96ZW4gc25hcHNob3QvY2xvbmUgZXhhY3Rjb3VudGVyIGVxdWFsaXR5OyBwb3N0Y3V0b3Zlci9yb2xsYmFjayBsaXZlY291bnRlcmNoYW5nZXMgbWF5IHJlZmxlY3QgbGVnaXRpbWF0ZSBjb25jdXJyZW50Y29tbWl0cy9zdGF0ZSB0cmFuc2l0aW9ucywgbGF0ZXN0REIgYWx3YXlzcmV0YWluZWQiLAogICJzb3VyY2VfYmFzaXMiOiB7CiAgICAicmV2aWV3ZWRfcHJvdG9jb2xfY29tbWl0IjogImUwMzU5YmNiNmNkZmFkOWFiM2U4NjgwNTQxMjFmZTBjZWJlYzJkNjgiLAogICAgIm93bmVyX2ZvbGxvd3Rocm91Z2hfY29tbWl0IjogIjkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUiLAogICAgImZpbmFsX2V4ZWN1dGlvbl9zb3VyY2UiOiAiZXhhY3Qgc3Vic2VxdWVudCByb290LWFwcGxpZWQgc291cmNlIGNvbW1pdCBtdXN0IGJlIGJvdW5kIGJ5IGZvdW5kZXIgcmVjZWlwdCBhbmQgdmVyaWZpZWQgYWdhaW5zdCBmb3VyIGFwcHJvdmVkIEdpdCBibG9icyIKICB9LAogICJhcHByb3ZlZF9vd25lcl9yZW5kZXJfYmxvYl9zaGEyNTYiOiB7CiAgICAiZGVwbG95L2xpZmVjeWNsZS9hZG1pc3Npb24uY2FuZGlkYXRlLmpzb24iOiAiOTIzODJhNTZiMzQ5YzNiODk1ZTU4MDZlOTc1MDgyNTI3YmI5OWQxYTAwMTE0MGU2OWQ4NTdlNWIwMzkxZmE1NSIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uIjogIjM4Yjc4YjljYmVlNWFkZTc3NTBhNThkNTE1NmNhNGM1NzczMzUyZTk0N2FjYjMwNGVlNzE0YjU5ZTc0OWNlYjQiLAogICAgImRlcGxveS9saWZlY3ljbGUva3VzdG9taXphdGlvbi55YW1sIjogIjFiYmNlODFiYzY3NTg0MzQzNTQxNTdmODYwMTUzNDMyMGM1ZDAyOTA1ODc5MDhmZDE1YTZkMjVlM2ZhNTdmNDciLAogICAgImRlcGxveS9saWZlY3ljbGUvcmVnaXN0cmllcy5jYW5kaWRhdGUuanNvbiI6ICI5YmFkNmRiNWZiYzIxNzhkMzFiMDQxMjAwMTZhNDE4MzBjMzU1MmZiYjllMjUxN2I3MThmOWJiZTg3Y2Y2NDllIgogIH0sCiAgImV4ZWN1dGlvbl9idW5kbGVfc2hhMjU2IjogIjI3ZDZkNmQzMTMzYzk2M2RhMWRkZTkyZDQ5OGQ2MzY2MTczODdjMTZlODUwYTE3YzU5ODE0OGFiYzM1Yzc3NWQiLAogICJleGVjdXRpb25faGVscGVyX21hbmlmZXN0X3NoYTI1NiI6ICJmMmZhZDZjMjUxZmJiNDQyMGUwN2MxMzI5ODAyZjUyMWI1MTNiYmY2NmU1MWY2NGM1ZDY3M2VmMDRmMTYyODRjIiwKICAiZXhlY3V0aW9uX3BsYW5fc2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiLAogICJleGVjdXRpb25fcGhhc2VzIjogWwogICAgImRyaWxsLWJhY2t1cCIsCiAgICAiZHJpbGwtY29weSIsCiAgICAib2ZmbGluZS12ZXJpZnkiLAogICAgImNsZWFudXAtb2ZmbGluZSIsCiAgICAiY3V0b3Zlci1iYWNrdXAiLAogICAgImN1dG92ZXItY29weSIsCiAgICAicmVsZWFzZSIsCiAgICAidmVyaWZ5IiwKICAgICJyb2xsYmFjayIsCiAgICAicm9sbGJhY2stdmVyaWZ5IgogIF0sCiAgImRlYWRsaW5lX3NlbWFudGljcyI6ICJBbGwgcGhhc2VzIGluY2x1ZGluZyB2ZXJpZmljYXRpb24vcmVjb3ZlcnkgbXVzdCBiZWdpbiBiZWZvcmUgZXhlY3V0ZV9ieS4gTm8gZXh0ZW5zaW9uIG9yIGF1dG9tYXRpYyBlbWVyZ2VuY3kgZ3JhbnQ7IGJleW9uZCBkZWFkbGluZSBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBDb21wbGV0ZSB0aGUgYm91bmRlZCBkcmlsbCBhbmQgcm9sbG91dCBlYXJseSBlbm91Z2ggdG8gYWxsb3cgcmVjb3Zlcnkgd2l0aGluIHRoZSB3aW5kb3cuIiwKICAib2ZmbGluZV9pbml0aWFsaXplciI6ICJPbmUgaXNvbGF0ZWQgbG9jYWwgVUlEMDowL0NBUF9DSE9XTi1vbmx5IGluaXRpYWxpemVyIG9mIHRoZSBuZXdseSBjcmVhdGVkIG5vbmNlLWJvdW5kIGRpc3Bvc2FibGUgdm9sdW1lLCBleGFjdCBjYW5kaWRhdGUgaW1hZ2UsIG5ldHdvcmtub25lL3JlYWRvbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzL0NQVTEvMTI4TWk7IG5vIGhvc3QvbGl2ZVBWQy90b2tlbi9jb25maWcgbW91bnQuIFN1YnNlcXVlbnQgcHJlLW9wZW4vYWRtaW4vcG9zdC1vcGVuIGNoZWNrcyBVSUQxMDAwMToxMDAwMS4iLAogICJyb2xsYmFja19kaXNwYXRjaCI6ICJTZWFsZWQgRGVwbG95bWVudC9DTS9QVkMgYW5kIHNhbWUtc2NoZW1hIHNvdXJjZS9pbWFnZSBwYWlyIHBsdXMgYWRtaXNzaW9uIENBUzsgbm8gUmVhZHkgY2FuZGlkYXRlIG9yIFBvZC9kYXRhYmFzZSBleGVjIHByZXJlcXVpc2l0ZS4gcm9sbGJhY2stdmVyaWZ5IHNlcGFyYXRlbHkgcHJvdmVzIHJlY292ZXJlZCBvbGQgaW1hZ2UvUmVhZHkxL3Njb3BlZCBvcGVyYXRpb24gYW5kIHJlYWRvbmx5IGN1cnJlbnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzLiIsCiAgInB1cnBvc2VfcHJvb2ZfbGltaXQiOiAiVGVuIGluc3RhbGxlZCBzeW50aGV0aWMtdHJhbnNwb3J0IGNoZWNrcyBvbiBhY3R1YWwgcGxhY2VtZW50OyBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIE5vdCBhY3R1YWwgcHJvdmlkZXIvUERQIGF1dGhvcml0eSBwcm9vZiwgd2hpY2ggcmVtYWlucyBhIGRpc3RpbmN0IFQwNCBjb21wbGV0aW9uIGdhdGUuIiwKICAicmVmaW5lbWVudF9vZl9hbWVuZGVkX21hbmlmZXN0IjogImIxZTNlNjZiYzQwMjNkYzgwYzZlYTU5NTY0YzM1NTdjNzY1M2ZiM2MzMDdmNDZhMDQ5OTk3Yjc2MTk4YTkwMzMiCn0K" + "content_base64": "ewogICJwcm9wb3NhbF9pZCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgInRyaWFsX2lkIjogImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMSIsCiAgInN0YXRlIjogInByZXBhcmVkLXVuYXBwcm92ZWQiLAogICJ0YXJnZXQiOiAicmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbiIsCiAgImF1dGhvcml0eSI6ICJBRE1JTklTVEVSOyBhY3RpdmF0aW9uIEFQUFJPVkVEIG9ubHkgdXBvbiBleGFjdCBmb3VuZGVyIGRpc3Bvc2l0aW9uIiwKICAiY2FuZGlkYXRlX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYSIsCiAgInB1Ymxpc2hlZF9zb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInByaW9yX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgInByaW9yX2FyZ29fcmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgIm5hdGl2ZV9vYmplY3QiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJhcHBzL3YxIiwKICAgICJraW5kIjogIkRlcGxveW1lbnQiLAogICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAidWlkIjogImE1ODhlMTBhLTkwZDItNDg4My05NzVlLTZkZDhiOGZlY2E5MiIKICB9LAogICJhcmdvX2FwcGxpY2F0aW9uX3VpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICJzb3VyY2VfZ2F0ZSI6ICJBbGwgZm91ciBleGFjdCBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGluIGV4ZWN1dGlvbi1wbGFuLmpzb24gYW5kIGNsZWFuIGN1cnJlbnQgb3duZXIgSEVBRCBtdXN0IG1hdGNoOyBzb3VyY2UgcHJlcGFyYXRpb24gaXMgbm90IG5hdGl2ZSBhcHByb3ZhbCIsCiAgInN5bmNfc2NvcGUiOiBbCiAgICAiYXBwczpEZXBsb3ltZW50OmluZm9ybWVkLWRlY2lzaW9uIgogIF0sCiAgInBydW5lIjogZmFsc2UsCiAgImF1dG9tYXRlZF9zeW5jIjogZmFsc2UsCiAgInJ1bnRpbWVfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAic2NoZW1hIjogNSwKICAicmVxdWVzdGVkX29wZXJhdGlvbnMiOiBbCiAgICAiUmVhZC1vbmx5IGltbXV0YWJsZSB2YWxpZGF0aW9uIG9mIGV4aXN0aW5nIGZyb3plbjE5NTM3OTIwYnl0ZSBuYXRpdmUgZHJpbGwgc25hcHNob3QsIFNIQTg3NTYuLi4sIHByaXZhdGVjdXN0b2R5L25vLXdyaXRlci96ZXJvV0FML3N0YWxlU0hNIHJldGFpbmVkIiwKICAgICJEaXN0aW5jdCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBiaW5hcnljb3B5IGludG8gYWJzZW50MDYwMHByb3RlY3RlZCBsb2NhbCBkZXN0aW5hdGlvbiwgbmV3IGhhc2gtbGlua2VkIHJlc2N1ZSBqb3VybmFsIHByZXNlcnZpbmcgb2xkIFVOQ0VSVEFJTiBjb3B5IiwKICAgICJFeGlzdGluZyBpc29sYXRlZCBvZmZsaW5lIHByZS1vcGVuL2FkbWluL3Bvc3Qtb3BlbiBjb21wYXRpYmlsaXR5IGRyaWxsIGFuZCBkaXNwb3NhYmxlLXZvbHVtZSBjbGVhbnVwIHVzaW5nIHJlc2N1ZWQgcmVzdWx0IiwKICAgICJEaXN0aW5jdCBjb25zaXN0ZW50IGN1dG92ZXIgc25hcHNob3QgcGx1cyBwcm90ZWN0ZWRjb3B5LCBmb2xsb3dlZCBvbmx5IGFmdGVyIGFsbGdhdGVzIGJ5IERlcGxveW1lbnQtb25seSBpbWFnZSByZWxlYXNlL3ZlcmlmeTsgc2FtZS1zY2hlbWEgcm9sbGJhY2svcmVjb3ZlcnkgcHJvb2YgaWYgbmVlZGVkIgogIF0sCiAgImV4ZWN1dGVfYnkiOiAiMjAyNi0xMC0xMlQyMzo1OTo1OVoiLAogICJ0ZW1wb3JhcnlfdnVsbmVyYWJpbGl0eV9yZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJrbm93bl9zY2FuX2ZpbmRpbmdzIjogIjBISUdIL0NSSVRJQ0FMLDFmaXhhYmxlIGluaGVyaXRlZE1FRElVTSB6bGliLCBhY3R1YWwgY3VycmVudGJhc2UrY2FuZGlkYXRlIGZpbmRpbmdzIGlkZW50aWNhbCIsCiAgInZ1bG5lcmFiaWxpdHlfcmVjb3JkIjogIklORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxIC8gSU5GRC1XUC0wMDA5LVQwNSIsCiAgImNvc3RfZXN0aW1hdGVfRVVSIjogMCwKICAiY29zdF9saW1pdHMiOiAiTm8gYWRkaXRpb25hbCByZWN1cnJpbmcgaW5mcmFzdHJ1Y3R1cmUgb3Igc2Vjb25kIGRyaWxsIGJhY2t1cC4gRXhpc3RpbmcgbmF0aXZlIHNuYXBzaG90MTk1Mzc5MjBieXRlcyByZXRhaW5lZDsgcHJvdGVjdGVkIGxvY2FsY29weS9vZmZsaW5lY2xvbmUgcGx1cyBkaXN0aW5jdCBjdXRvdmVyIHNuYXBzaG90cyBjb25zdW1lIGJvdW5kZWRleGlzdGluZ3N0b3JhZ2UuIEF0dGVuZGVkZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZDsgbm8gYXV0b3BpbG90IGdyYW50LiIsCiAgInJpc2tfZXN0aW1hdGVzIjogWwogICAgIkJyaWVmIFJlY3JlYXRlIHNlcnZpY2UgaW50ZXJydXB0aW9uOyBubyBjb25jdXJyZW50IG5ldyB3cml0ZXIvc3VyZ2UiLAogICAgIlByaXZhdGUgZXZpZGVuY2Ugc25hcHNob3QgY3VzdG9keSBhbmQgZGlzcG9zYWwgZXJyb3JzOyBubyBzbmFwc2hvdHMvdG9rZW5zIGluIHB1YmxpYyBldmlkZW5jZSIsCiAgICAiQ2FuZGlkYXRlIHB1cnBvc2UgcmVmdXNhbCBtYXkgZXhwb3NlIGNhbGxlcnMgcmVseWluZyBvbiBhZHZpc29yeSByZXN1bHRzIGFzIGJpbmRpbmciLAogICAgIkluaGVyaXRlZCBrbm93biBmaXhhYmxlIE1FRElVTSByZW1haW5zIHVudGlsIHNlcGFyYXRlbHkgYXBwcm92ZWQgb3duZXIgcmVtZWRpYXRpb24iLAogICAgIkV4aXN0aW5nIEFyZ28gT3V0T2ZTeW5jIGJhc2VsaW5lIGlzIHJldGFpbmVkOyBubyB3aG9sZS1hcHAgc3luYyBvciB1bnJlbGF0ZWQgcmVwYWlycyBwZXJtaXR0ZWQiLAogICAgIkFsbCBwaGFzZXMsIGluY2x1ZGluZyByZWNvdmVyeS92ZXJpZmljYXRpb24sIG11c3QgYmVnaW4gYmVmb3JlIE9jdDEyIGRlYWRsaW5lOyBpZiByZWNvdmVyeSB3aW5kb3cgaXMgZXhoYXVzdGVkIHN0b3AgYW5kIG9idGFpbiBhIGZyZXNoIGZvdW5kZXIgZGVjaXNpb24uIE5vIGF1dG9tYXRpYyBleHBpcnkgY29udHJvbGxlci4iCiAgXSwKICAicm9sbGJhY2siOiAiTWFudWFsIEFyZ28gc291cmNlIHBpbiBiYWNrIHRvN2RiODQ4NSBhbmQgc2NvcGVkIERlcGxveW1lbnQtb25seSBzeW5jIHRvN2Y1YyBpbWFnZTsgcmV0YWluIGN1cnJlbnQgc2NoZW1hNSBkYXRhYmFzZSBhbmQgYWxsIHBvc3QtY3V0b3ZlciBldmlkZW5jZSwgbmV2ZXIgcmVzdG9yZSBvbGRlciBzbmFwc2hvdCBvdmVyIGxpdmUgd3JpdGVzIiwKICAibmF0aXZlX2V4ZWN1dGVkIjogIk9yaWdpbmFsIGRyaWxsLWJhY2t1cCBleGVjdXRlZDsgb3JpZ2luYWwgZHJpbGwtY29weSBmYWlsZWQuIE5vIHZlcnNpb24yIGFjdGlvbiBleGVjdXRlZC4iLAogICJodW1hbl9hcHByb3ZhbCI6ICJWZXJzaW9uMSBhY2NlcHRlZCBvcmlnaW5hbHNvdXJjZTsgdmVyc2lvbjIgcmVxdWlyZXMgZnJlc2ggZXhhY3QgYWNjZXB0YW5jZS4iLAogICJyZWZpbmVtZW50X29mX21hbmlmZXN0IjogIjdjNjczOGIzOWVhOGU1NGU2MWM4ZWQ2MjVlOTRhZDBiMjc1NWU2NzJlMTU3NmVmY2RmODRhMWQ2NjVhYzMzMDAiLAogICJtYW5kYXRvcnlfcHJlX29wZW5fZ2F0ZSI6ICJzdGRsaWJTUUxpdGUgbW9kZT1yby9xdWVyeV9vbmx5OiBzY2hlbWE1K2ludGVncml0eStjb3VudCBiYXNlbGluZSBiZWZvcmUgQU5ZIFN0b3JlL2FkbWluIG9uIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5OyByZWZ1c2VvbGRzY2hlbWFzIHdpdGhvdXQgbWlncmF0aW9uIiwKICAib3B0aW1pemVkX2ludGVycHJldGVycyI6ICJsb2NhbCtyZW1vdGUgZXhwbGljaXRseXJlZnVzZWQgYmVmb3JlYXNzZXJ0IGdhdGVzIiwKICAibmF0aXZlX2RlcGVuZGVuY3lfZ2F0ZSI6ICJzZWFsZWQgYWN0dWFsQ00gVUlEL2ltbXV0YWJsZS9jYW5vbmljYWxkYXRhaGFzaCtQVkMgVUlEL2Z1bGxzcGVjL0JvdW5kL3ZvbHVtZU5hbWUsIG5vIHJhd0NNZGF0YSBvclNlY3JldCByZWFkcyIsCiAgImxpdmVfY291bnRzIjogIkZyb3plbiBzbmFwc2hvdC9jbG9uZSBleGFjdGNvdW50ZXIgZXF1YWxpdHk7IHBvc3RjdXRvdmVyL3JvbGxiYWNrIGxpdmVjb3VudGVyY2hhbmdlcyBtYXkgcmVmbGVjdCBsZWdpdGltYXRlIGNvbmN1cnJlbnRjb21taXRzL3N0YXRlIHRyYW5zaXRpb25zLCBsYXRlc3REQiBhbHdheXNyZXRhaW5lZCIsCiAgInNvdXJjZV9iYXNpcyI6IHsKICAgICJvcmlnaW5hbF9hcHByb3ZlZF9zb3VyY2UiOiAiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMCIsCiAgICAiZmluYWxfcmVjb3Zlcnlfc291cmNlIjogImV4YWN0IGZpbmFsIHJvb3QtYXBwbGllZCBvd25lciBIRUFEIHdpdGggYXBwcm92ZWQgZm91ciByZW5kZXIgYmxvYnMgbXVzdCBiZSBib3VuZCBieSBuZXcgZm91bmRlciByZWNlaXB0IgogIH0sCiAgImFwcHJvdmVkX293bmVyX3JlbmRlcl9ibG9iX3NoYTI1NiI6IHsKICAgICJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvbiI6ICI5MjM4MmE1NmIzNDljM2I4OTVlNTgwNmU5NzUwODI1MjdiYjk5ZDFhMDAxMTQwZTY5ZDg1N2U1YjAzOTFmYTU1IiwKICAgICJkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24iOiAiMzhiNzhiOWNiZWU1YWRlNzc1MGE1OGQ1MTU2Y2E0YzU3NzMzNTJlOTQ3YWNiMzA0ZWU3MTRiNTllNzQ5Y2ViNCIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwiOiAiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0NyIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uIjogIjliYWQ2ZGI1ZmJjMjE3OGQzMWIwNDEyMDAxNmE0MTgzMGMzNTUyZmJiOWUyNTE3YjcxOGY5YmJlODdjZjY0OWUiCiAgfSwKICAiZXhlY3V0aW9uX2J1bmRsZV9zaGEyNTYiOiAiNDljOWNiNzBmMzZmNmNlYjdiMGQyMjQwMGIyZWM5MjMyYTVlMWE4YTAwZDE3ZTkyYjkyZmUzNjdjOThlZmZiNSIsCiAgImV4ZWN1dGlvbl9wbGFuX3NoYTI1NiI6ICI5Y2U1NzI4YTU2MWU2ZDM4Zjg0OTcyMDFiYWEyYjg0MGQxMTQ0NGEwYWY4YWQ2MjM0ZGZjMzc0MjgxMTNmMjU4IiwKICAiZXhlY3V0aW9uX3BoYXNlcyI6IFsKICAgICJkcmlsbC1jb3B5LXJlc2N1ZS1yMSIsCiAgICAib2ZmbGluZS12ZXJpZnkiLAogICAgImNsZWFudXAtb2ZmbGluZSIsCiAgICAiY3V0b3Zlci1iYWNrdXAiLAogICAgImN1dG92ZXItY29weSIsCiAgICAicmVsZWFzZSIsCiAgICAidmVyaWZ5IiwKICAgICJyb2xsYmFjayIsCiAgICAicm9sbGJhY2stdmVyaWZ5IgogIF0sCiAgImRlYWRsaW5lX3NlbWFudGljcyI6ICJBbGwgcGhhc2VzIGluY2x1ZGluZyB2ZXJpZmljYXRpb24vcmVjb3ZlcnkgbXVzdCBiZWdpbiBiZWZvcmUgZXhlY3V0ZV9ieS4gTm8gZXh0ZW5zaW9uIG9yIGF1dG9tYXRpYyBlbWVyZ2VuY3kgZ3JhbnQ7IGJleW9uZCBkZWFkbGluZSBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBDb21wbGV0ZSB0aGUgYm91bmRlZCBkcmlsbCBhbmQgcm9sbG91dCBlYXJseSBlbm91Z2ggdG8gYWxsb3cgcmVjb3Zlcnkgd2l0aGluIHRoZSB3aW5kb3cuIiwKICAib2ZmbGluZV9pbml0aWFsaXplciI6ICJPbmUgaXNvbGF0ZWQgbG9jYWwgVUlEMDowL0NBUF9DSE9XTi1vbmx5IGluaXRpYWxpemVyIG9mIHRoZSBuZXdseSBjcmVhdGVkIG5vbmNlLWJvdW5kIGRpc3Bvc2FibGUgdm9sdW1lLCBleGFjdCBjYW5kaWRhdGUgaW1hZ2UsIG5ldHdvcmtub25lL3JlYWRvbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzL0NQVTEvMTI4TWk7IG5vIGhvc3QvbGl2ZVBWQy90b2tlbi9jb25maWcgbW91bnQuIFN1YnNlcXVlbnQgcHJlLW9wZW4vYWRtaW4vcG9zdC1vcGVuIGNoZWNrcyBVSUQxMDAwMToxMDAwMS4iLAogICJyb2xsYmFja19kaXNwYXRjaCI6ICJTZWFsZWQgRGVwbG95bWVudC9DTS9QVkMgYW5kIHNhbWUtc2NoZW1hIHNvdXJjZS9pbWFnZSBwYWlyIHBsdXMgYWRtaXNzaW9uIENBUzsgbm8gUmVhZHkgY2FuZGlkYXRlIG9yIFBvZC9kYXRhYmFzZSBleGVjIHByZXJlcXVpc2l0ZS4gcm9sbGJhY2stdmVyaWZ5IHNlcGFyYXRlbHkgcHJvdmVzIHJlY292ZXJlZCBvbGQgaW1hZ2UvUmVhZHkxL3Njb3BlZCBvcGVyYXRpb24gYW5kIHJlYWRvbmx5IGN1cnJlbnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzLiIsCiAgInB1cnBvc2VfcHJvb2ZfbGltaXQiOiAiVGVuIGluc3RhbGxlZCBzeW50aGV0aWMtdHJhbnNwb3J0IGNoZWNrcyBvbiBhY3R1YWwgcGxhY2VtZW50OyBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIE5vdCBhY3R1YWwgcHJvdmlkZXIvUERQIGF1dGhvcml0eSBwcm9vZiwgd2hpY2ggcmVtYWlucyBhIGRpc3RpbmN0IFQwNCBjb21wbGV0aW9uIGdhdGUuIiwKICAicmVmaW5lbWVudF9vZl9hbWVuZGVkX21hbmlmZXN0IjogImIxZTNlNjZiYzQwMjNkYzgwYzZlYTU5NTY0YzM1NTdjNzY1M2ZiM2MzMDdmNDZhMDQ5OTk3Yjc2MTk4YTkwMzMiLAogICJtZW1vX3ZlcnNpb24iOiAyLAogICJyZWNvdmVyeSI6IHsKICAgICJvcmlnaW5hbF9hbmNob3IiOiB7CiAgICAgICJvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiI6ICJkMTg3YjAyZDk4ZDZlOTc0MjlmZTIwYjRmYmUxZDMwOWE2YzZjNGI1NTIzMmI0YWUxM2FjMzk4NzMwMzlmMWMxIiwKICAgICAgInBoYXNlX21ldGFkYXRhIjogewogICAgICAgICJkcmlsbC1iYWNrdXAiOiB7CiAgICAgICAgICAic3RhdGUiOiAiQ09NUExFVEUiLAogICAgICAgICAgImF0dGVtcHRfaWQiOiAiZDYzMTgyYTctZTFhNS00ZThlLWE1ZjEtMmJmMzMzM2NmMTUzIiwKICAgICAgICAgICJzdGFydGVkX2F0IjogIjIwMjYtMTAtMTFUMDI6Mzg6NDUuMzEwNjUzKzAwOjAwIgogICAgICAgIH0sCiAgICAgICAgImRyaWxsLWNvcHkiOiB7CiAgICAgICAgICAic3RhdGUiOiAiVU5DRVJUQUlOIiwKICAgICAgICAgICJhdHRlbXB0X2lkIjogIjMyOWVmMTkwLTE2OTItNDI0Ni1iOTUzLWU2YTU5NjY0YWJjYyIsCiAgICAgICAgICAic3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAyOjM5OjUwLjE5ODc0MCswMDowMCIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJmcm96ZW5fYmFja3VwX3JlY2VpcHRfc2hhMjU2IjogIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGUiLAogICAgICAic25hcHNob3Rfc2hhMjU2IjogIjg3NTZjZjgyNWRmOWU3YjViNzRiYjRhMDEwNmE1MDI3ZjVjZmYyYzU5ZmY0NWQ3YjQ4ZWVkODUyMmE3ZDMzZjMiLAogICAgICAic25hcHNob3RfYnl0ZXMiOiAxOTUzNzkyMCwKICAgICAgIm9mZl9jbHVzdGVyX2ZpbGVfZXhpc3RzIjogZmFsc2UsCiAgICAgICJvbGRfdW5jZXJ0YWluX3JldHJ5X2F1dGhvcml6ZWQiOiBmYWxzZQogICAgfSwKICAgICJvcmlnaW5hbF9pZGVudGl0eSI6IHsKICAgICAgInByb3Bvc2FsIjogIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxIiwKICAgICAgInNvdXJjZV9yZXZpc2lvbiI6ICJiYzY0OTRjZDFiMjkwNzgzZWYzYWVmMDc2M2JmMjhkMWRlYWJmNGIwIiwKICAgICAgIm1lbW9fc2hhMjU2IjogIjUwNmQzOTU2YmViN2M2MmFiMmJiZGZkYTc4M2MwNTkwNWQxODM0NTJhMWY2N2ExODE3ZjNmYjhjMmU1MjI5MzciLAogICAgICAicGxhbl9zaGEyNTYiOiAiZjVlNWZhOTA2ZmYxOWQzYTQ1ZDEwZGNkYjI4MTAzNzNhZTIxZjljZjQ0YzA0NzJmZjJiZDQ3ZDNiYzMzMjhkNiIKICAgIH0sCiAgICAibmV3X2pvdXJuYWwiOiAicmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24iLAogICAgIm5ld19waGFzZSI6ICJkcmlsbC1jb3B5LXJlc2N1ZS1yMSIsCiAgICAib2xkX3VuY2VydGFpbl9waGFzZV9vdmVyd3JpdGVfb3JfcmV0cnkiOiBmYWxzZSwKICAgICJuZXdfc25hcHNob3RfYmFja3VwIjogZmFsc2UsCiAgICAic25hcHNob3Rfb3Jfc2lkZWNhcl9tdXRhdGlvbiI6IGZhbHNlLAogICAgIm1hcHBpbmciOiAib2ZmbGluZS12ZXJpZnkgY29uc3VtZXMgQ09NUExFVEUgZHJpbGwtY29weS1yZXNjdWUtcjEgcmVzdWx0OyBhbGwgbGF0ZXIgcGhhc2VzIG9yZGVyZWQgb25seSBpbiBuZXcgaGFzaC1saW5rZWQgcmVjb3Zlcnkgam91cm5hbCIKICB9LAogICJvcmlnaW5hbF9uYXRpdmVfb3V0Y29tZSI6IHsKICAgICJkcmlsbC1iYWNrdXAiOiAiQ09NUExFVEUiLAogICAgImRyaWxsLWNvcHkiOiAiVU5DRVJUQUlOIGJlZm9yZSBsb2NhbGZpbGUgY3JlYXRpb24iLAogICAgIm5hdGl2ZV9pbWFnZSI6ICJ1bmNoYW5nZWQ3ZjU7IG5vIHJvbGxvdXQiLAogICAgIm9yaWdpbmFsX2pvdXJuYWxfYW5kX3NpZGVjYXJzIjogInJldGFpbmVkIHVuY2hhbmdlZCIKICB9LAogICJyZXNjdWVfbGltaXRzIjogIk5vIGxpdmVEQndyaXRlcyBkdXJpbmcgcmVzY3VlIGluc3BlY3Rpb24vY29weSwgbm8gc2lkZWNhciBkZWxldGlvbi9jaGVja3BvaW50LCBubyByZXRyeS9vdmVyd3JpdGUgb3JpZ2luYWwgVU5DRVJUQUlOIHBoYXNlLiBMYXRlciBleGlzdGluZyBhZG1pbiBvZmZsaW5laW5zcGVjdC9jdXRvdmVyYmFja3VwIGFuZCBpbWFnZSBhY3Rpb25zIG5lZWQgbmV3IGV4YWN0dmVyc2lvbjIgYWNjZXB0YW5jZSBhbmRvcmRlcmVkZ3VhcmRzLiIsCiAgInN1Ym1pc3Npb25fcm91dGUiOiAiUE9TVCAvbGlmZWN5Y2xlL21lbW9zL2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxL3JldmlzaW9ucyBDQVMgZXhwZWN0ZWRfdmVyc2lvbjE7IHNvdXJjZSBtdXN0IHJlbWFpbiB1bmJvdW5kOyBwdWJsaXNoL3JldmlldyBzb3VyY2V2ZXJzaW9uMiwgcmVzdWx0aW5nIGh1bWFuIHJldmlldyBvd252ZXJzaW9uMSIsCiAgIm9yaWdpbmFsX2V4ZWN1dGlvbl9oZWxwZXJfbWFuaWZlc3Rfc2hhMjU2IjogImYyZmFkNmMyNTFmYmI0NDIwZTA3YzEzMjk4MDJmNTIxYjUxM2JiZjY2ZTUxZjY0YzVkNjczZWYwNGYxNjI4NGMiLAogICJvcmlnaW5hbF9leGVjdXRpb25faGVscGVyX21hbmlmZXN0X2NvbnRleHQiOiAiUmV0YWluZWQgaGlzdG9yaWNhbCBmMmZhZDYgaGVscGVyIHJldmlldyBiZWZvcmUgdGhlIGZhaWxlZCBhcHByb3ZlZCBiYWNrdXAvY29weSB0cmlhbDsgY3VycmVudCByZXNjdWUgZXhlY3V0aW9uIGJ5dGVzIGFyZSBib3VuZCBieSBleGVjdXRpb25fYnVuZGxlX3NoYTI1NiBhbmQgZXhlY3V0aW9uX3BsYW5fc2hhMjU2LiBUaGlzIGhpc3RvcmljYWwgbWFuaWZlc3QgZG9lcyBub3QgZGVzY3JpYmUgY3VycmVudCB2ZXJzaW9uMiByZXNjdWUgZmlsZXMuIgp9Cg==" }, { "digest": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", @@ -175,9 +204,9 @@ "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" }, { - "digest": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "digest": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd", "media_type": "application/json", - "content_base64": "ewogICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgIm9ic2VydmVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjQ6MDEuOTg1MTI4KzAwOjAwIiwKICAibmF0aXZlX293bmVyX3B1YmxpY2F0aW9uX2pvYiI6IHsKICAgICJpZCI6IDExNDg0LAogICAgIm5hbWUiOiAicHVibGlzaC1jYW5kaWRhdGUiLAogICAgImhlYWRfYnJhbmNoIjogIm1haW4iLAogICAgImhlYWRfc2hhIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgInJ1bl9udW1iZXIiOiAzLAogICAgImV2ZW50IjogInB1c2giLAogICAgImRpc3BsYXlfdGl0bGUiOiAiUHJlcGFyZSByZWFkYWJsZSBvdmVybGF5IGNvbnRleHQgd2l0aCB0aGUgYWRtaXR0ZWQgbGVnYWN5IGJ1aWxkZXIiLAogICAgInN0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJ3b3JrZmxvd19pZCI6ICJwdXJwb3NlLW92ZXJsYXktaW1hZ2UueWFtbCIsCiAgICAidXJsIjogImh0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uL2FjdGlvbnMvcnVucy8zIiwKICAgICJjcmVhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjA6NTlaIiwKICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjE6MDhaIiwKICAgICJydW5fc3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjIwOjU5WiIKICB9LAogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInBvbGljeV9zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgInJlZ2lzdHJ5X3Byb29mX3NoYTI1NiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAic291cmNlX3JlbmRlcl9jaGFuZ2Vfb25seSI6ICJEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHNwZWMudGVtcGxhdGUuc3BlYy5jb250YWluZXJzWzBdLmltYWdlIiwKICAicnVudGltZV9jb25maWdtYXBfdW5jaGFuZ2VkIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAiaW5zdGFsbGVkX2ltYWdlX2V4ZWN1dGlvbiI6IHsKICAgICJpbW11dGFibGVfcmVnaXN0cnlfYXJ0aWZhY3RfcHVsbGVkX2Fub255bW91c2x5IjogdHJ1ZSwKICAgICJVSUQiOiAxMDAwMSwKICAgICJHSUQiOiAxMDAwMSwKICAgICJwb2xpY3lfZmlsZV9VSUQiOiAwLAogICAgInBvbGljeV9maWxlX21vZGUiOiAiMDY0NCIsCiAgICAicHVycG9zZV92YXJpYW50cyI6IDEwLAogICAgImJpbmRpbmdfZm9ybXNfYWxsb3dlZCI6IDIsCiAgICAiYWR2aXNvcnlfb3JfbWFsZm9ybWVkX3JlZnVzZWQiOiA4LAogICAgIm5ldHdvcmsiOiAibm9uZSIsCiAgICAicmVhZF9vbmx5IjogdHJ1ZSwKICAgICJzeW50aGV0aWNfdHJhbnNwb3J0IjogdHJ1ZSwKICAgICJuYXRpdmVfUERQX3Rlc3QiOiBmYWxzZQogIH0sCiAgInNjYW5fc3VtbWFyeV9zaGEyNTYiOiAiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NCIsCiAgImhpc3RvcmljYWxfZmFpbGVkX3J1bnNfcmV0YWluZWQiOiBbCiAgICAiZjY2ZGU1MDUvdGFzazExNDgyL3J1bjEiLAogICAgImFjZWNhZDg4Ny90YXNrMTE0ODMvcnVuMiIKICBdLAogICJuYXRpdmVfaG9zdGluZ19jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJodW1hbl9hcHByb3ZhbCI6IGZhbHNlLAogICJldmlkZW5jZV9maWxlX3NoYTI1NiI6IHsKICAgICJpbWFnZS1tYW5pZmVzdC5qc29uIjogIjk3OGM1NzVkM2M3YmYwZGUzOWRiZTRlOTU2N2MzOWNkMzZmNzBiN2U1NWJjMTczNTdiZGIwM2ZiM2I5NmIwZmIiLAogICAgImltYWdlLWNvbmZpZy5qc29uIjogIjRhZDcyNDljNzVmZDlmYzAzOWNlYjE4Njc3MjQxOWUxY2JhNWZkOTc1OWM0MDQ1NTY0NTljODBhMmQyODVkMTAiLAogICAgImJhc2UtaW1hZ2UtY29uZmlnLmpzb24iOiAiYjcwNmM5MjA5ZTMyNGYzOWE4NmZmY2RhMmEzZTlkOTRjOTI2NDk3MzlhZDViMjFmZTQ2MTEwMDZlMzZmNmYwMCIsCiAgICAicmVnaXN0cnktcHJvb2YuanNvbiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAgICJ0cml2eS1mdWxsLmpzb24iOiAiZjM4YThmN2U2YzQxOWVlZDkxNTRkNzc2MmY5MzJiOWRlYjY2ODBhNjIyMjQ3YjA4MTk2Yjc0NThiODkzNDM0ZSIsCiAgICAic2JvbS5jZHguanNvbiI6ICJhNDI1Mjk1MWUyMDI3NDcyYzI2ZDg2NzljYjU0M2UzMDk4MzE4MDgwOWQ2ZGQzYzdjOTRiODgzZDYyODAzZTVkIiwKICAgICJiYXNlLXRyaXZ5LWZ1bGwuanNvbiI6ICJkNDRjNTU1YWVjYmIxYTQ1MThmNDEyN2Q0ODAxNWVhNDU5MzI1YzkzZThiMDM3MTkxMGE1NWRlNDcyOTNjYTgwIiwKICAgICJjaGVja19pbnN0YWxsZWQucHkiOiAiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZCIsCiAgICAidmVyaWZ5X3JlZ2lzdHJ5LnB5IjogIjQxM2Y1NzVjMjFhMmJkMThhMzY5NmY4ZjJkOTM5ZWVhZGM1MmQ3NmYyODJjNDI4MTNmNzZiYjBlM2VlOGEyYTQiLAogICAgInNxbGl0ZV9yZWFkb25seS5weSI6ICJlZWY1M2RkMjMzZWVlNzRjMTdmMjA4MjNiZDdmNTc4N2M2MGNhZDc5YWM2NDgwMjFjOTQ3OTY0M2M2Y2U5ZTM4IiwKICAgICJzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uIjogIjA0MjMyN2EwMzZlZDI1NGNmOTVkYmViMGMwNTZhYzI1YjAzYTZhODQ0Yjk1YTMzMmM5OTJkZjI5NDM2OTEzNjkiLAogICAgInJldmlldy1yZWZpbmVtZW50Lmpzb24iOiAiZWE2Mjg0NWNlZTVlZTZmNGY2Y2I3ZjVkY2QwYWY2MDFiYTI5YTIxYzhmZjgwZWZiYmMwMmFkMTZlMzViZWE3NSIsCiAgICAidGVzdF9jaGFuZ2VfZ3VhcmQucHkiOiAiZGE1MzUwNDM3MzU3YmEzMjkyMzZjYzEzNzYxMGMwMzg1NmYzOGY4MzZkZGYyODU2MDI1YmMxMjAxMWZhZDA3ZiIsCiAgICAidGVzdF9zcWxpdGVfcmVhZG9ubHkucHkiOiAiYzdhOTFkMGM2YTM3M2Q3MzhjODhiYjgxN2Q5YmZiMmZmOGExNzliYzYxYjkzMDYzYjg5Njc3YjU2NjUyMDMyMyIsCiAgICAidGVzdF9wcmVmbGlnaHRfb3B0aW1pemF0aW9uLnB5IjogImEwYzRmYTE4YzVkNmMyMTQ3NmEwNmM2ZDA1ZmU3NjU2MjU5ZDIwNDI5OTEzODg1MTU5OWU5MjE0ZDkxMTIwNmQiCiAgfQp9Cg==" + "content_base64": "ewogICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgIm9ic2VydmVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjQ6MDEuOTg1MTI4KzAwOjAwIiwKICAibmF0aXZlX293bmVyX3B1YmxpY2F0aW9uX2pvYiI6IHsKICAgICJpZCI6IDExNDg0LAogICAgIm5hbWUiOiAicHVibGlzaC1jYW5kaWRhdGUiLAogICAgImhlYWRfYnJhbmNoIjogIm1haW4iLAogICAgImhlYWRfc2hhIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgInJ1bl9udW1iZXIiOiAzLAogICAgImV2ZW50IjogInB1c2giLAogICAgImRpc3BsYXlfdGl0bGUiOiAiUHJlcGFyZSByZWFkYWJsZSBvdmVybGF5IGNvbnRleHQgd2l0aCB0aGUgYWRtaXR0ZWQgbGVnYWN5IGJ1aWxkZXIiLAogICAgInN0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJ3b3JrZmxvd19pZCI6ICJwdXJwb3NlLW92ZXJsYXktaW1hZ2UueWFtbCIsCiAgICAidXJsIjogImh0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uL2FjdGlvbnMvcnVucy8zIiwKICAgICJjcmVhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjA6NTlaIiwKICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjE6MDhaIiwKICAgICJydW5fc3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjIwOjU5WiIKICB9LAogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInBvbGljeV9zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgInJlZ2lzdHJ5X3Byb29mX3NoYTI1NiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAic291cmNlX3JlbmRlcl9jaGFuZ2Vfb25seSI6ICJEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHNwZWMudGVtcGxhdGUuc3BlYy5jb250YWluZXJzWzBdLmltYWdlIiwKICAicnVudGltZV9jb25maWdtYXBfdW5jaGFuZ2VkIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAiaW5zdGFsbGVkX2ltYWdlX2V4ZWN1dGlvbiI6IHsKICAgICJpbW11dGFibGVfcmVnaXN0cnlfYXJ0aWZhY3RfcHVsbGVkX2Fub255bW91c2x5IjogdHJ1ZSwKICAgICJVSUQiOiAxMDAwMSwKICAgICJHSUQiOiAxMDAwMSwKICAgICJwb2xpY3lfZmlsZV9VSUQiOiAwLAogICAgInBvbGljeV9maWxlX21vZGUiOiAiMDY0NCIsCiAgICAicHVycG9zZV92YXJpYW50cyI6IDEwLAogICAgImJpbmRpbmdfZm9ybXNfYWxsb3dlZCI6IDIsCiAgICAiYWR2aXNvcnlfb3JfbWFsZm9ybWVkX3JlZnVzZWQiOiA4LAogICAgIm5ldHdvcmsiOiAibm9uZSIsCiAgICAicmVhZF9vbmx5IjogdHJ1ZSwKICAgICJzeW50aGV0aWNfdHJhbnNwb3J0IjogdHJ1ZSwKICAgICJuYXRpdmVfUERQX3Rlc3QiOiBmYWxzZQogIH0sCiAgInNjYW5fc3VtbWFyeV9zaGEyNTYiOiAiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NCIsCiAgImhpc3RvcmljYWxfZmFpbGVkX3J1bnNfcmV0YWluZWQiOiBbCiAgICAiZjY2ZGU1MDUvdGFzazExNDgyL3J1bjEiLAogICAgImFjZWNhZDg4Ny90YXNrMTE0ODMvcnVuMiIKICBdLAogICJuYXRpdmVfaG9zdGluZ19jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJodW1hbl9hcHByb3ZhbCI6IGZhbHNlLAogICJldmlkZW5jZV9maWxlX3NoYTI1NiI6IHsKICAgICJpbWFnZS1tYW5pZmVzdC5qc29uIjogIjk3OGM1NzVkM2M3YmYwZGUzOWRiZTRlOTU2N2MzOWNkMzZmNzBiN2U1NWJjMTczNTdiZGIwM2ZiM2I5NmIwZmIiLAogICAgImltYWdlLWNvbmZpZy5qc29uIjogIjRhZDcyNDljNzVmZDlmYzAzOWNlYjE4Njc3MjQxOWUxY2JhNWZkOTc1OWM0MDQ1NTY0NTljODBhMmQyODVkMTAiLAogICAgImJhc2UtaW1hZ2UtY29uZmlnLmpzb24iOiAiYjcwNmM5MjA5ZTMyNGYzOWE4NmZmY2RhMmEzZTlkOTRjOTI2NDk3MzlhZDViMjFmZTQ2MTEwMDZlMzZmNmYwMCIsCiAgICAicmVnaXN0cnktcHJvb2YuanNvbiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAgICJ0cml2eS1mdWxsLmpzb24iOiAiZjM4YThmN2U2YzQxOWVlZDkxNTRkNzc2MmY5MzJiOWRlYjY2ODBhNjIyMjQ3YjA4MTk2Yjc0NThiODkzNDM0ZSIsCiAgICAic2JvbS5jZHguanNvbiI6ICJhNDI1Mjk1MWUyMDI3NDcyYzI2ZDg2NzljYjU0M2UzMDk4MzE4MDgwOWQ2ZGQzYzdjOTRiODgzZDYyODAzZTVkIiwKICAgICJiYXNlLXRyaXZ5LWZ1bGwuanNvbiI6ICJkNDRjNTU1YWVjYmIxYTQ1MThmNDEyN2Q0ODAxNWVhNDU5MzI1YzkzZThiMDM3MTkxMGE1NWRlNDcyOTNjYTgwIiwKICAgICJjaGVja19pbnN0YWxsZWQucHkiOiAiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZCIsCiAgICAidmVyaWZ5X3JlZ2lzdHJ5LnB5IjogIjQxM2Y1NzVjMjFhMmJkMThhMzY5NmY4ZjJkOTM5ZWVhZGM1MmQ3NmYyODJjNDI4MTNmNzZiYjBlM2VlOGEyYTQiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAicmV2aWV3LXJlZmluZW1lbnQuanNvbiI6ICJlYTYyODQ1Y2VlNWVlNmY0ZjZjYjdmNWRjZDBhZjYwMWJhMjlhMjFjOGZmODBlZmJiYzAyYWQxNmUzNWJlYTc1IiwKICAgICJ0ZXN0X2NoYW5nZV9ndWFyZC5weSI6ICJkYTUzNTA0MzczNTdiYTMyOTIzNmNjMTM3NjEwYzAzODU2ZjM4ZjgzNmRkZjI4NTYwMjViYzEyMDExZmFkMDdmIiwKICAgICJ0ZXN0X3NxbGl0ZV9yZWFkb25seS5weSI6ICJjN2E5MWQwYzZhMzczZDczOGM4OGJiODE3ZDliZmIyZmY4YTE3OWJjNjFiOTMwNjNiODk2NzdiNTY2NTIwMzIzIiwKICAgICJ0ZXN0X3ByZWZsaWdodF9vcHRpbWl6YXRpb24ucHkiOiAiYTBjNGZhMThjNWQ2YzIxNDc2YTA2YzZkMDVmZTc2NTYyNTlkMjA0Mjk5MTM4ODUxNTk5ZTkyMTRkOTExMjA2ZCIsCiAgICAiaW5pdGlhbC1hcHByb3ZlZC1iYzY0OTRjZC9zcWxpdGVfcmVhZG9ubHkucHkiOiAiZWVmNTNkZDIzM2VlZTc0YzE3ZjIwODIzYmQ3ZjU3ODdjNjBjYWQ3OWFjNjQ4MDIxYzk0Nzk2NDNjNmNlOWUzOCIKICB9LAogICJ2ZXJzaW9uMl9zb3VyY2VfcG9pbnRlcl9yZWZpbmVtZW50IjogewogICAgIm9yaWdpbmFsX3JlY2VpcHRfc2hhMjU2IjogIjhhNjc2YzM4Zjg5ZjljYTc2MmI4ZWJlOTQ1YjVhY2I5MGQ0N2E0Y2IzNTA2OTI2ODdhYmI5ODViYmIyZDhhZTIiLAogICAgIm9yaWdpbmFsX3JlY2VpcHRfYXJjaGl2ZSI6ICJpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkL3B1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvbiIsCiAgICAicmVhc29uIjogIktlZXAgaGlzdG9yaWNhbCBvcmlnaW5hbCBwcmUtb3BlbiBjaGVja2VyIGhhc2ggYm91bmQgdG8gZXhhY3QgYXJjaGl2ZWQgb3JpZ2luYWwgYnl0ZXM7IGN1cnJlbnQgdmVyc2lvbjIgY2hlY2tlciBpcyBpbmRlcGVuZGVudGx5IGRpcmVjdC1wYWNrZXQvcGxhbiBib3VuZC4gQWN0dWFsIGltYWdlL3JlZ2lzdHJ5L3NjYW4vU0JPTSBwcm9vZiB1bmNoYW5nZWQ7IG5vIG5ldyBhcnRpZmFjdCB2ZXJpZmljYXRpb24gb3IgbmF0aXZlIHZlcnNpb24yIGFjdGlvbiBjbGFpbWVkLiIKICB9Cn0K" }, { "digest": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", @@ -190,14 +219,14 @@ "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInNjYW5uZXIiOiAiYXF1YXNlYy90cml2eUBzaGEyNTY6NjJiMWU2NWU4ODY5YmM0YjRjNmFhNGZhMmIyMTU5NTI1NmM3YzJmNjAxOGE5ZDlhZDYxY2FmODcxODdjMTk2OSIsCiAgInZlcnNpb24iOiAiMC43NC4wIiwKICAiZGJfbWV0YWRhdGEiOiB7CiAgICAiVmVyc2lvbiI6IDIsCiAgICAiTmV4dFVwZGF0ZSI6ICIyMDI2LTEwLTExVDE4OjU5OjUwLjg4OTAxMDU3MloiLAogICAgIlVwZGF0ZWRBdCI6ICIyMDI2LTEwLTEwVDE4OjU5OjUwLjg4OTAxMDkyM1oiLAogICAgIkRvd25sb2FkZWRBdCI6ICIyMDI2LTEwLTEwVDIzOjMyOjMyLjM4MDAzMzEzMVoiCiAgfSwKICAic3VwcHJlc3Npb24iOiBmYWxzZSwKICAiaWdub3JlX3VuZml4ZWQiOiBmYWxzZSwKICAic2V2ZXJpdHlfZmlsdGVyIjogbnVsbCwKICAicGFja2FnZV9jb3VudCI6IDQ0LAogICJmaW5kaW5nc19ieV9zZXZlcml0eSI6IHsKICAgICJNRURJVU0iOiAxCiAgfSwKICAiZmluZGluZ3MiOiBbCiAgICB7CiAgICAgICJpZCI6ICJDVkUtMjAyNi04NTA5MSIsCiAgICAgICJwYWNrYWdlIjogInpsaWIiLAogICAgICAiaW5zdGFsbGVkIjogIjEuMy4yLXIwIiwKICAgICAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAgICAgInNldmVyaXR5IjogIk1FRElVTSIKICAgIH0KICBdLAogICJjb3ZlcmFnZV9saW1pdHMiOiBbCiAgICAiQWxwaW5lMy4yNCBhYnNlbnQgc2Nhbm5lciBFT0wgbGlzdDsgT1MgZGV0ZWN0b3IgcmFuIGFnYWluc3QgQWxwaW5lMy4yNCByZXBvc2l0b3J5IG9uMzhPUyBwYWNrYWdlcyIsCiAgICAiS25vd24gZmluZGluZ3MgYXNvZiBwaW5uZWREQiwgbm90IGNsYWltIGFic2VuY2Ugb2YgdW5rbm93biB2dWxuZXJhYmlsaXRpZXMiCiAgXSwKICAiaGlnaF9jcml0aWNhbCI6IDAsCiAgInNhbWVfc2Nhbm5lcl9hY3R1YWxfYmFzZV9zY2FuX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgImJhc2Vfc2Nhbl9maWxlIjogImJhc2UtdHJpdnktZnVsbC5qc29uIgp9Cg==" }, { - "digest": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", + "digest": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5", "media_type": "application/json", - "content_base64": "ewogICJraW5kIjogImluZm9ybWVkLWRlY2lzaW9uLmV4ZWN1dGlvbi1zb3VyY2UtYnVuZGxlIiwKICAidmVyc2lvbiI6IDEsCiAgInByb3Bvc2FsX2lkIjogIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxIiwKICAiZmlsZXMiOiB7CiAgICAiUkVBRE1FLm1kIjogewogICAgICAic2hhMjU2IjogImE2ZWNkYWJlYmNlMTJlZWFmZWE2MTE3M2VkYjZlNmQwZTM0OWE3NmUzNjY1NDY5NzhlMmVkMDJlN2IxMDlkZjIiLAogICAgICAiY29udGVudCI6ICIjIFN1cGVydmlzZWQgSW5mb3JtZWQgRGVjaXNpb24gcHVycG9zZSByZWxlYXNlIGV4ZWN1dG9yIOKAlCB1bmFwcHJvdmVkIHByZXBhcmF0aW9uXG5cbk5vIG5hdGl2ZSBkYXRhYmFzZSByZWFkLCBiYWNrdXAvZXhwb3J0L3Jlc3RvcmUgb3Igd29ya2xvYWQgYWN0aW9uIGhhcyBiZWVuIHJ1bi4gVGhpcyBzb3VyY2UgaW1wbGVtZW50cyB0aGUgcmV2aWV3ZWQgcHJvdG9jb2w7IGl0cyBhZGRpdGlvbmFsIG1lY2hhbmljYWwgZGV0YWlscyBuZWVkIHBlZXIgcmV2aWV3IGFuZCBhbiBhbWVuZGVkIGhhc2gtYm91bmQgcGFja2V0IGJlZm9yZSBmaXJzdCBodW1hbiBzdWJtaXNzaW9uLiBUaGUgb3JpZ2luYWw3OHBhdGggcGFja2V0L3Jldmlld3MgcmVtYWluIGhpc3RvcmljYWwgdGVjaG5pY2FsIGFncmVlbWVudCwgbm90IGZvdW5kZXIgYXBwcm92YWwgb2YgdGhpcyBleGVjdXRvci5cblxuUnVuIG9uZSBwaGFzZSBhdCBhIHRpbWUgb25seSBhZnRlciB0aGUgY29vcmRpbmF0b3IgaGFzIGZyZXNobHkgYXV0aGVudGljYXRlZCB0aGUgZXhhY3QgZm91bmRlciBkaXNwb3NpdGlvbiBhdCB0aGUgZXhpc3RpbmcgZml4ZWQgSW5mb3JtZWQgRGVjaXNpb24gb3JpZ2luLiBSb290IHdyaXRlcyB0aGUgcHJvdGVjdGVkMDYwMCBmaXhlZCBmaWxlcyBgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2Utcm9vdC1hdXRob3JpdHkuanNvbmAgYW5kIGAvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1uYXRpdmUtb3V0Y29tZS1sYXRlc3QuanNvbmAuIFRoZSByZWNlaXB0IHRlbXBsYXRlIGlzIFBFTkRJTkcgYW5kIGNhbm5vdCBhdXRob3JpemUgYW55dGhpbmcuIFRoZSBoZWxwZXIgY2hlY2tzIGV4YWN0IG5lc3RlZCBjb25maXJtZWQgcGVyc29uL3BsYXRmb3JtLXJvb3QgQUNDRVBUIHZlcnNpb24xLCBvcmlnaW5hbCBtZW1vIGlkZW50aXR5L2N1cnJlbnQgbWVtbyBTSEEsIHNvdXJjZSBjb21taXQsIHBsYW4gU0hBIGFuZCBmcmVzaG5lc3MxMjBzZWNvbmRzLiBUaGlzIGlzIHN1cGVydmlzZWQgcmVjZWlwdCBib29ra2VlcGluZywgbm90IGNyeXB0b2dyYXBoaWMgcHJvdmlkZXIgdmVyaWZpY2F0aW9uLCBhIHNpZ25lZCBncmFudCBvciBhZ2VudCBhdXRvbm9teSBwcm9tb3Rpb24uIFJvb3QvaGFybmVzcyBzdXBlcnZpc2lvbiByZW1haW5zIHRoZSBhdXRob3JpdHkgYm91bmRhcnkuIE5ldmVyIHN5bnRoZXNpemUgYW4gYXBwcm92YWwgcmVjZWlwdCBmcm9tIGEgdGVjaG5pY2FsIHJldmlldyBvciBjYWxsZXIgYXNzZXJ0aW9uLlxuXG5JbnZvY2F0aW9uIGFmdGVyIGFjdHVhbCBhcHByb3ZhbDogYHB5dGhvbjMgZXhlY3V0aW9uL2FjdHVhdG9yLnB5IC0tcGhhc2UgPGZpeGVkLXBoYXNlPiAtLXJvb3QtYXV0aG9yaXR5LXJlY2VpcHQgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2Utcm9vdC1hdXRob3JpdHkuanNvbiAtLXJvb3QtbmF0aXZlLW91dGNvbWUgL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2UtbmF0aXZlLW91dGNvbWUtbGF0ZXN0Lmpzb24gLS1zb3VyY2UtcmV2aXNpb24gPGV4YWN0LWZpbmFsLW93bmVyLWNvbW1pdD5gLiBPcmRlcjogZHJpbGwtYmFja3VwIOKGkiBkcmlsbC1jb3B5IOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnkuIFJvbGxiYWNrIGlzIGEgZGlzdGluY3QgYXV0aG9yaXplZCByZWNvdmVyeSBhZnRlciBhIHJlY29yZGVkIHJlbGVhc2UgYXR0ZW1wdCwgZm9sbG93ZWQgYnkgcm9sbGJhY2stdmVyaWZ5LiBSb2xsYmFjayBkaXNwYXRjaCBuZWVkcyBubyBSZWFkeSBQb2Qgb3IgY2FuZGlkYXRlIGRhdGFiYXNlIGV4ZWM6IHNlYWxlZCBEZXBsb3ltZW50L0NNL1BWQy9zb3VyY2UvaW1hZ2UgcGFpciBhbmQgYWRtaXNzaW9uIENBUyByZW1haW4gbWFuZGF0b3J5LiBJdHMgYWNrbm93bGVkZ21lbnQgaXMgbm90IHJlY292ZXJ5IGNvbXBsZXRpb247IHJvbGxiYWNrLXZlcmlmeSBzZXBhcmF0ZWx5IHJlcXVpcmVzIFJlYWR5MSBvZiB0aGUgb2xkIGltYWdlLCBzdWNjZWVkZWQgZXhhY3Qgc2NvcGVkIG9wZXJhdGlvbiBhbmQgcmVhZG9ubHkgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnQgcHJvb2Ygb2YgdGhlIGN1cnJlbnQgcmV0YWluZWQgZGF0YWJhc2UuIFJvb3QgcmVmcmVzaGVzIGFjdHVhbCBuYXRpdmUgYWNjZXB0YW5jZSBpbW1lZGlhdGVseSBiZWZvcmUgZWFjaCBwaGFzZS5cblxuVGhlIHByaXZhdGUgaWdub3JlZCBDdXN0b2RpYW4gY3VzdG9keSBwYXJlbnQgYC5wcml2YXRlLWJhY2t1cHNgIG11c3QgYWxyZWFkeSBleGlzdCwwNzAwIG93bmVkIGJ5IHRoZSB3b3Jrc3RhdGlvbiBhZ2VudCB1c2VyOyB0aGUgZXhhY3QgY2FzZSBjaGlsZDIwMjYxMDExLWluZmQtcHVycG9zZS1yMSBpcyBjcmVhdGVkIG9ubHkgYWZ0ZXIgYXV0aG9yaXR5IGNoZWNrcy4gTmF0aXZlIHBhcmVudCBgL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjFgIGlzIHVuaXF1ZWx5IGNyZWF0ZWQgYnkgVUlEMTAwMDEgZm9yIGRyaWxsL2N1dG92ZXIgU1FMaXRlLWNvbnNpc3RlbnQgc25hcHNob3RzLCBlYWNoMDYwMC9ub25zeW1saW5rL3NpbmdsZS1saW5rLiBUaGUgYXR0YWNoZWQgc3RkbGliIHJlYWRvbmx5IGNoZWNrZXIgbXVzdCByZXBvcnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzIGJlZm9yZSBhbnkgU3RvcmUvYWRtaW4gb24gbmF0aXZlIHNvdXJjZSBvciBvZmZsaW5lY2xvbmUuIEludmFsaWQgc3RhdGVzL2NvdW50IHNoYXBlcyBhbmQgYWxsIHJhdyBjaGlsZCBvdXRwdXRzIGFyZSB3aXRoaGVsZC4gTWFpbi1vbmx5IHNuYXBzaG90IGNsb3N1cmUgaXMgdmVyaWZpZWQgYmVmb3JlIGJpbmFyeSB0cmFuc2Zlcjsgc3RkaW4vc3Rkb3V0IHNuYXBzaG90IGJ5dGVzIHJlYWNoIG9ubHkgcHJpdmF0ZSBmaWxlcyBvciB0aGUgaXNvbGF0ZWQgcmVzdG9yZSBjb3B5LCBuZXZlciB0b29sL2NoYXQvbG9nIG91dHB1dC4gU3RyZWFtcyBzdG9wIGJleW9uZCBmcm96ZW4gYnl0ZSBjb3VudC81MTJNaUI7IGZhaWx1cmVzIHJldGFpbiBwYXJ0aWFsIHByaXZhdGUgZXZpZGVuY2UuXG5cbk5ldyBwcml2YXRlIG9mZmxpbmUgdm9sdW1lIGBpbmZkLXB1cnBvc2UtcjEtcmVzdG9yZS0yMDI2MTAxMWAgaXMgY3JlYXRlZCBvbmx5IG9uIHRoZSBwaW5uZWQgbG9jYWwgd29ya3N0YXRpb24gRG9ja2VyIHNvY2tldC9lbmdpbmUgYm50LWxhcDAwMSwgd2l0aCBsb2NhbGRyaXZlci9ub29wdGlvbnMgYW5kIGF0dGVtcHRub25jZSBsYWJlbHMuIE9uZS10aW1lIGluaXRpYWxpemVyIHJ1bnMgZXhhY3Q3NjNjIGFzIFVJRDAgd2l0aCBvbmx5IENBUF9DSE9XTiwgbmV0d29ya25vbmUvcmVhZC1vbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzLCBvbmUgTkVXIG5hbWVkdm9sdW1lIG1vdW50LCBubyBob3N0L2xpdmVQVkMvY3JlZGVudGlhbC9jb25maWcgbW91bnRzLiBJdCByZWNlaXZlcyBvbmx5IHRoZSBwcm90ZWN0ZWQgc25hcHNob3Qgb24gc3RkaW4sIHZlcmlmaWVzIGJ5dGVzLCBzZXRzIGZvbGRlcjA3MDAvZmlsZTA2MDAgb3duZWQxMDAwMS4gVGhlbiBVSUQxMDAwMSBwZXJmb3JtcyByZWFkb25seSBwcmUtb3BlbiB2YWxpZGF0aW9uLCBgLS1lbnRyeXBvaW50IGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGluc3BlY3QgLS1kYiAvcmVzdG9yZS9yZXZpZXcuc3FsaXRlYCwgbmV2ZXIgdGhlIHNlcnZpY2UgZW50cnlwb2ludC4gQSBzZWNvbmQgVUlEMTAwMDEvbmV0d29yay1ub25lIHJlYWRvbmx5IGludGVncml0eS9zY2hlbWEvY291bnQgY2hlY2sgYWZ0ZXIgYWRtaW4gbXVzdCBleGFjdGx5IGVxdWFsIHRoZSBmcm96ZW4gc25hcHNob3QgcHJvb2YsIGFuZCB0aGUgb3JpZ2luYWwgcHJvdGVjdGVkIHNuYXBzaG90IFNIQSBtdXN0IHJlbWFpbiB1bmNoYW5nZWQuIENsZWFudXAgY29tcGFyZXMgZXhhY3Qgbm9uY2UvY3JlYXRpb24gaWRlbnRpdHkgYW5kIHJlbW92ZXMgb25seSB0aGlzIGNsb25lIHZvbHVtZSwgcmV0YWluaW5nIGFsbCBuYXRpdmUvb2ZmY2x1c3RlciBvcmlnaW5hbHMuIENQVTEvbWVtb3J5MTI4TWlCOyBwcml2YXRlIG9mZmNsdXN0ZXIgY2FwYWNpdHkgYXQgbGVhc3QxR2lCKzE2TWlCIGFuZCBuYXRpdmUgZXN0aW1hdGVkIHR3by9vbmUtc25hcHNob3QgaGVhZHJvb20gcmVxdWlyZWQuXG5cbkV2ZXJ5IHBoYXNlIGZzeW5jcyBSVU5OSU5HIGludGVudCBiZWZvcmUgZGlzcGF0Y2guIEFueSBmYWlsdXJlL2ludGVycnVwdGlvbi9hbWJpZ3VvdXMgcmVzdWx0IHJlbWFpbnMgVU5DRVJUQUlOOyBzYW1lLXBoYXNlIHJldHJ5IGlzIHJlZnVzZWQuIFNlcGFyYXRlIG9wZXJhdG9yIGRpYWdub3NpcyBhbmQgYW55IG5lZWRlZCByZWNvdmVyeSBhcmUgcmVjb3JkZWQ7IG5laXRoZXIgc25hcHNob3RzIG5vciB1bnJlc29sdmVkL25ldyByZWNvcmRzIGFyZSByZW1vdmVkIHRvIG1ha2UgY2hlY2tzIGdyZWVuLiBGcm96ZW4gc25hcHNob3QvY2xvbmUgY291bnRlcnMgbXVzdCBhZ3JlZTsgbGl2ZSBwb3N0LWN1dG92ZXIvcm9sbGJhY2sgY291bnRlcnMgY2FuIGluY2x1ZGUgbGVnaXRpbWF0ZSBjb25jdXJyZW50IGNvbW1pdHMvc3RhdGUgdHJhbnNpdGlvbnMuXG5cbkV4aXN0aW5nIEFwcGxpY2F0aW9uIFVJRCBhbmQgYWN0dWFsIERlcGxveW1lbnQvUG9kL0NNL1BWQyBjdXN0b2R5L3NvdXJjZSBhcmUgY2hlY2tlZC4gQWxsIGZvdXIgb3duZXIgcmVuZGVyIEdpdCBibG9icyBtdXN0IG1hdGNoOyBvdmVycmlkZXMvcGx1Z2lucy9tdWx0aXBsZSBzb3VyY2VzIGFuZCBldmVuIGF1dG9tYXRlZDp7fSBhcmUgcmVqZWN0ZWQuIFRoZSBleGlzdGluZyBBcHBsaWNhdGlvbi5vcGVyYXRpb24gQVBJIGlzIHVzZWQgKG5hdGl2ZSBhcmdvY2QgQ0xJIGlzIGFic2VudCksIHdpdGggc2VydmVyIGRyeS1ydW4sIHJlc291cmNlVmVyc2lvbi9VSUQvc291cmNlIHRlc3RzLCBvbmUgRGVwbG95bWVudCBvbmx5LCBwcnVuZT1mYWxzZS4gRGlzcGF0Y2ggYWNrbm93bGVkZ21lbnQgaXMgbm90IHJvbGxvdXQgY29tcGxldGlvbi4gVmVyaWZ5IHJlcXVpcmVzIGV4YWN0IHN1Y2NlZWRlZCBvcGVyYXRpb24vY29udHJvbGxlciBnZW5lcmF0aW9uL1JlYWR5MSwgc2FtZSBzY2hlbWE1IERCLCBhY3R1YWwgaW5zdGFsbGVkIGhhc2gvbW9kZS9VSUQgYW5kMTBwdXJwb3NlIGNoZWNrcyBwbHVzIGJvdW5kZWQgbG9jYWxob3N0aGVhbHRoL3JlYWRpbmVzcy4gUHVycG9zZSB0cmFuc3BvcnQgcmVtYWlucyBzeW50aGV0aWMgYW5kIGlzIGV4cGxpY2l0bHkgbm90IGEgbmF0aXZlIFBEUCBhdXRob3JpdHkgdGVzdC4gUm9sbGJhY2sgcGlucyBwcmlvcjdkYi83ZjUgdGhyb3VnaCB0aGUgc2FtZSBzY29wZWQgd29ya2Zsb3cgYW5kIHJldGFpbnMgdGhlIGN1cnJlbnQgbGl2ZSBkYXRhYmFzZTsgaXQgbmV2ZXIgcmVzdG9yZXMgYW4gb2xkZXIgc25hcHNob3Qgb3ZlciBsYXRlciB3cml0ZXMuXG5cblNpeHRlZW4gc3ludGhldGljIHRlc3RzIHBhc3MgYWdhaW5zdCBmcm96ZW4gY2FzZSBtZXRhZGF0YTogYXV0aG9yaXR5L2V4cGlyeS9hY3Rvci9hbWJpZ3VpdHkgcmVmdXNhbHMsIGNyYXNoIGludGVudC9ubyByZXRyeS9vcmRlciwgY3JlZGVudGlhbC1vdXRwdXQgd2l0aGhvbGRpbmcsIHByaXZhdGUgYm91bmRlZCBiaW5hcnljb3B5LCB2b2x1bWUgcmVjcmVhdGlvbiBjbGVhbnVwIHJlZnVzYWwsIHNvdXJjZS9hdXRvbWF0aW9uL0NNL1BWQy9SZWFkeSBkcmlmdCwgcHJlLW9wZW4gZ2F0ZSByZWZ1c2FsIGFuZCBleGFjdCBEZXBsb3ltZW50LW9ubHkgb3BlcmF0aW9uL2RyeS1ydW4uIFRoZXNlIGFyZSBzb3VyY2UgdGVzdHMsIG5vdCBuYXRpdmUgYmFja3VwIG9yIHJlbGVhc2UgcHJvb2YuXG5cbkFsbCBwaGFzZXMsIGluY2x1ZGluZyByZWNvdmVyeSBhbmQgdmVyaWZpY2F0aW9uLCBhcmUgYm91bmRlZCBieSAyMDI2LTEwLTEyVDIzOjU5OjU5Wi4gVGhpcyBleHBsaWNpdGx5IHJlZmluZXMgdGhlIGVhcmxpZXIgcGFja2V0IGRlYWRsaW5lIHdvcmRpbmcgZm9yIHVuc3RhcnRlZCByZWxlYXNlOiB0aGUgaGVscGVyIGRvZXMgbm90IGV4dGVuZCBhdXRob3JpdHkgcGFzdCB0aGUgZGVhZGxpbmUuIFN0YXJ0IHN1ZmZpY2llbnRseSBlYXJseSB0byBjb21wbGV0ZSBkcmlsbC9jdXRvdmVyL3JlY292ZXJ5OyBhZnRlciBleHBpcnkgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gVGhpcyBtYXkgZGVsYXkgcmVjb3ZlcnkgaWYgdGhlIHdpbmRvdyBpcyBleGhhdXN0ZWQsIGFuZCBtdXN0IGJlIGRpc2Nsb3NlZCBiZWZvcmUgYWNjZXB0YW5jZS5cblxuVGhlIGluaXRpYWwgMTEtZmlsZSBoZWxwZXIgZnJlZXplIFNIQTY1M2I2OGMzODkxYzA2NmY0MGQxMDRiZmM2N2EzNWRhNWU0MzY2MDVjZDk5YWZkNTJmYmFjNGI0N2E5NTUzZmUgYW5kIGluZGVwZW5kZW50IGNvbmRpdGlvbmFsIGZpbmRpbmdzIHJlbWFpbiBhcmNoaXZlZCB1bmRlciBleGVjdXRpb24taGlzdG9yeS9pbml0aWFsLTY1M2I2OGMzLiBUaGlzIHJlZmluZW1lbnQgaXMgdGhlIHNhbWUgcHJvcG9zYWwvdHJpYWw7IG5vIG5hdGl2ZSBleGVjdXRpb24gb3IgaHVtYW4gYWNjZXB0YW5jZSBoYXMgb2NjdXJyZWQuXG4iCiAgICB9LAogICAgImFjdHVhdG9yLnB5IjogewogICAgICAic2hhMjU2IjogIjZiOWQ2NDM5ODYyNDU0ZjI2MWVlNzdmMDViMjY1MTlmODEwOTU5OWIxZjY3MDc4YmM0ZTFmN2M3YzQwNjFiYTUiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmUgZml4ZWQgc3VwZXJ2aXNlZCBwaGFzZTsgbmV2ZXIgcnVuIHRoaXMgZHVyaW5nIHNvdXJjZSBwcmVwYXJhdGlvbi5cIlwiXCJcbmltcG9ydCBhcmdwYXJzZVxuaW1wb3J0IGhhc2hsaWJcbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHJlXG5pbXBvcnQgc2VsZWN0b3JzXG5pbXBvcnQgc3RhdFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0aW1lXG5cbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KCdvcHRpbWl6ZWQgaW50ZXJwcmV0ZXIgcmVmdXNlZCcpXG5cblBIQVNFUyA9ICgnZHJpbGwtYmFja3VwJywgJ2RyaWxsLWNvcHknLCAnb2ZmbGluZS12ZXJpZnknLCAnY2xlYW51cC1vZmZsaW5lJyxcbiAgICAgICAgICAnY3V0b3Zlci1iYWNrdXAnLCAnY3V0b3Zlci1jb3B5JywgJ3JlbGVhc2UnLCAndmVyaWZ5JywgJ3JvbGxiYWNrJywgJ3JvbGxiYWNrLXZlcmlmeScpXG5cblxuZGVmIHJlcXVpcmUodmFsdWUsIHJlYXNvbik6XG4gICAgaWYgbm90IHZhbHVlOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcblxuXG5kZWYgc2hhKHBhdGgpOlxuICAgIGRpZ2VzdCA9IGhhc2hsaWIuc2hhMjU2KClcbiAgICB3aXRoIFBhdGgocGF0aCkub3BlbigncmInKSBhcyBzdHJlYW06XG4gICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6XG4gICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJsb2NrKVxuICAgIHJldHVybiBkaWdlc3QuaGV4ZGlnZXN0KClcblxuXG5kZWYgcHJpdmF0ZShwYXRoLCBkaXJlY3Rvcnk9RmFsc2UpOlxuICAgIGluZm8gPSBQYXRoKHBhdGgpLmxzdGF0KClcbiAgICByZXF1aXJlKChzdGF0LlNfSVNESVIoaW5mby5zdF9tb2RlKSBpZiBkaXJlY3RvcnkgZWxzZSBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSlcbiAgICAgICAgICAgIGFuZCBpbmZvLnN0X3VpZCA9PSBvcy5nZXR1aWQoKSBhbmQgc3RhdC5TX0lNT0RFKGluZm8uc3RfbW9kZSkgPT0gKDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxuICAgICAgICAgICAgYW5kIChkaXJlY3Rvcnkgb3IgaW5mby5zdF9ubGluayA9PSAxKSwgJ3ByaXZhdGUgb3duZWQgY3VzdG9keSByZXF1aXJlZCcpXG5cblJPT1QgPSBQYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50XG5DQVNFID0gUk9PVC5wYXJlbnRcbk9XTkVSID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uJylcbkNVU1RPRElBTiA9IFBhdGgoJy9ob21lL3dvcnNjaC90aGUtY3VzdG9kaWFuJylcbkNVU1RPRFkgPSBDVVNUT0RJQU4gLyAnLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjEnXG5TT0NLRVQgPSAndW5peDovLy92YXIvcnVuL2RvY2tlci5zb2NrJ1xuSU1BR0UgPSAnZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhJ1xuVk9MVU1FID0gJ2luZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExJ1xuTUFYX0JZVEVTID0gNTEyICogMTAyNCoqMlxuXG5cbmRlZiBydW4oYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTkwKTpcbiAgICByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndiwgaW5wdXQ9Ym9keSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIGpzb25fcmVzdWx0KHJlc3VsdCk6XG4gICAgdHJ5OlxuICAgICAgICB2YWx1ZSA9IGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcbiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhZmUgcGhhc2UgcmVjZWlwdCB1bmF2YWlsYWJsZTsgb3V0Y29tZSB1bmNlcnRhaW4nKSBmcm9tIE5vbmVcbiAgICByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlID09IDAgYW5kIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIFRydWUsXG4gICAgICAgICAgICAncGhhc2UgZGlkIG5vdCB2ZXJpZnkgY29tcGxldGU7IHJhdyBvdXRwdXQgd2l0aGhlbGQ7IG5vIHJldHJ5JylcbiAgICBwZXJtaXR0ZWQgPSB7J3BoYXNlJywgJ2FsbF9jaGVja3NfcGFzcycsICdyYXdfb3V0cHV0X3dpdGhoZWxkJywgJ25hdGl2ZV9hcHByb3ZhbF92ZXJpZmllZF9ieV9yb290JyxcbiAgICAgICAgICAgICAgICAgJ25hdGl2ZV9hdXRoZW50aWNhdGVkX2dyYW50JywgJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZScsICdzbmFwc2hvdF9yZWFkb25seScsXG4gICAgICAgICAgICAgICAgICdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICduYXRpdmVfcGFyZW50X3ByaXZhdGUnLFxuICAgICAgICAgICAgICAgICAnbmF0aXZlX3VpZCcsICdwb2RfbmFtZScsICdwb2RfdWlkJywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnLFxuICAgICAgICAgICAgICAgICAnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzJywgJ29wZXJhdGlvbl9yZXF1ZXN0ZWQnLCAnc291cmNlX3JldmlzaW9uJyxcbiAgICAgICAgICAgICAgICAgJ3Jlc291cmNlcycsICdwcnVuZScsICdyb2xsb3V0X3ZlcmlmaWVkJywgJ2xhdGVzdF9saXZlX2RhdGFiYXNlX3JldGFpbmVkJyxcbiAgICAgICAgICAgICAgICAgJ2NsaWVudF9kaWZmX3NoYTI1NicsICduYXRpdmVfcm9sbG91dF92ZXJpZmllZCcsICdjdXJyZW50X3NjaGVtYTVfZGF0YWJhc2VfcmV0YWluZWQnLFxuICAgICAgICAgICAgICAgICAncHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJywgJ2luc3RhbGxlZF9wdXJwb3NlX2NoZWNrcycsICdwb2xpY3lfc2hhMjU2JyxcbiAgICAgICAgICAgICAgICAgJ3BvbGljeV9tb2RlJywgJ3BvbGljeV91aWQnLCAnaGVhbHRoX3N0YXR1c2VzJywgJ25hdGl2ZV9wcm92aWRlcl9wcm9iZScsICdyZWNvdmVyeV92ZXJpZmljYXRpb24nfVxuICAgIHJlcXVpcmUoc2V0KHZhbHVlKSA8PSBwZXJtaXR0ZWQsICd1bmV4cGVjdGVkIG91dHB1dCBmaWVsZHMgd2l0aGhlbGQnKVxuICAgIGZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuICAgIGZvciBuYW1lIGluICgnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lJywgJ3NuYXBzaG90X3JlYWRvbmx5JywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIGNvdW50cyh2YWx1ZVtuYW1lXSlcbiAgICBmb3IgbmFtZSBpbiAoJ3NuYXBzaG90X3NoYTI1NicsICdjbGllbnRfZGlmZl9zaGEyNTYnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOV17NjR9JywgdmFsdWVbbmFtZV0pIGlzIG5vdCBOb25lLCAnaW52YWxpZCBvdXRwdXQgZGlnZXN0IHdpdGhoZWxkJylcbiAgICBpZiAnc25hcHNob3RfYnl0ZXMnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHR5cGUodmFsdWVbJ3NuYXBzaG90X2J5dGVzJ10pIGlzIGludCBhbmQgMCA8IHZhbHVlWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAnaW52YWxpZCBvdXRwdXQgc2l6ZSB3aXRoaGVsZCcpXG4gICAgaWYgJ3NuYXBzaG90X2ZpbGUnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHZhbHVlWydzbmFwc2hvdF9maWxlJ10gaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSwgJ2ludmFsaWQgb3V0cHV0IGZpbGUgd2l0aGhlbGQnKVxuICAgIHJldHVybiB2YWx1ZVxuXG5cbmRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTEyMCk6XG4gICAgcmV0dXJuIHJ1bihbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVF0gKyBhcmd2LFxuICAgICAgICAgICAgICAgYm9keT1ib2R5LCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKTpcbiAgICAjIEZpeGVkIG1vZHVsZSBpbXBvcnRlZCBvbmx5IGFmdGVyIG1haW4gdmVyaWZpZXMgZXZlcnkgZXhlY3V0b3Igc291cmNlIGhhc2guXG4gICAgZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuICAgIHBheWxvYWQgPSB7J3BoYXNlJzogcGhhc2UsICdzb3VyY2VfcmV2aXNpb24nOiByZXZpc2lvbiwgJ2FwcHJvdmFsJzogYXBwcm92ZWQsXG4gICAgICAgICAgICAgICAnc2VhbGVkJzoganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJzoganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ2NhbmRpZGF0ZSc6IGpzb24ubG9hZHMoKENBU0UgLyAnY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdyb2xsYmFjayc6IGpzb24ubG9hZHMoKENBU0UgLyAncm9sbGJhY2stZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ3JlY2VpcHRfc2FmZXR5JzogKFJPT1QgLyAncmVjZWlwdF9zYWZldHkucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICdwdXJwb3NlX2NoZWNrcyc6IChDQVNFIC8gJ2NoZWNrX2luc3RhbGxlZC5weScpLnJlYWRfdGV4dCgpLFxuICAgICAgICAgICAgICAgJ3JlYWRvbmx5JzogKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCl9XG4gICAgc2NyaXB0ID0gUFJPR1JBTS5yZXBsYWNlKCdfX1BBWUxPQURfXycsIHJlcHIoanNvbi5kdW1wcyhwYXlsb2FkKSkpLnJlcGxhY2UoXG4gICAgICAgICdfX0dVQVJEX18nLCByZXByKChDQVNFIC8gJ2NoYW5nZV9ndWFyZC5weScpLnJlYWRfdGV4dCgpKSlcbiAgICByZXR1cm4ganNvbl9yZXN1bHQocnVuKFsnc3NoJywgJ3JhaWxpYW5jZTAxJywgJ3B5dGhvbjMgLSddLCBzY3JpcHQsIHRpbWVvdXQ9MjAwKSlcblxuXG5kZWYgY29weV9zbmFwc2hvdChwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkLCBqb3VybmFsKTpcbiAgICBtZXRhZGF0YSA9IHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKVxuICAgIGJhY2t1cF9waGFzZSA9ICdkcmlsbC1iYWNrdXAnIGlmIHBoYXNlID09ICdkcmlsbC1jb3B5JyBlbHNlICdjdXRvdmVyLWJhY2t1cCdcbiAgICBwcmlvciA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bYmFja3VwX3BoYXNlXVsncmVzdWx0J11cbiAgICBmb3Iga2V5IGluICgnc25hcHNob3Rfc2hhMjU2JywgJ3NuYXBzaG90X2J5dGVzJywgJ3NuYXBzaG90X2ZpbGUnLCAnc25hcHNob3RfcmVhZG9ubHknKTpcbiAgICAgICAgcmVxdWlyZShtZXRhZGF0YVtrZXldID09IHByaW9yW2tleV0sICdjbG9zZWQgZnJvemVuIHNuYXBzaG90IGNoYW5nZWQnKVxuICAgIG5hbWUgPSBtZXRhZGF0YVsnc25hcHNob3RfZmlsZSddXG4gICAgcmVxdWlyZShuYW1lIGluICgnZHJpbGwuc3FsaXRlJywgJ2N1dG92ZXIuc3FsaXRlJykgYW5kIDAgPCBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXSA8PSBNQVhfQllURVMsXG4gICAgICAgICAgICAnZml4ZWQgYm91bmRlZCBzbmFwc2hvdCByZXF1aXJlZCcpXG4gICAgcG9kID0gbWV0YWRhdGFbJ3BvZF9uYW1lJ11cbiAgICByZXF1aXJlKHJlLmZ1bGxtYXRjaChyJ1thLXowLTldKFstYS16MC05XSpbYS16MC05XSk/JywgcG9kKSBpcyBub3QgTm9uZSwgJ2ZpeGVkIG93bmVyIHBvZCBuYW1lIHJlcXVpcmVkJylcbiAgICBsb2NhbCA9IENVU1RPRFkgLyBuYW1lXG4gICAgZmQgPSBvcy5vcGVuKGxvY2FsLCBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX0VYQ0wgfCBvcy5PX05PRk9MTE9XLCAwbzYwMClcbiAgICAjIEJpbmFyeSBzbmFwc2hvdCBzdGRvdXQgZ29lcyBvbmx5IHRvIGEgcHJpdmF0ZSBmaWxlLCBuZXZlciB0b29sL2NoYXQvbG9nIG91dHB1dC5cbiAgICAjIFNuYXBzaG90IHNjaGVtYS9jb3VudCBtZXRhZGF0YSB3YXMgdmFsaWRhdGVkIGJlZm9yZSBvcGVuaW5nIHRoaXMgZGVzdGluYXRpb24uXG4gICAgd2l0aCBvcy5mZG9wZW4oZmQsICd3YicpIGFzIGRlc3RpbmF0aW9uOlxuICAgICAgICBjb21tYW5kID0gKCdrdWJlY3RsIGV4ZWMgLW4gaW5mb3JtZWQtZGVjaXNpb24gJyArIHBvZCArXG4gICAgICAgICAgICAgICAgICAgJyAtYyBpbmZvcm1lZC1kZWNpc2lvbiAtLSBjYXQgL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjEvJyArIG5hbWUpXG4gICAgICAgIHRyYW5zZmVyID0gc3VicHJvY2Vzcy5Qb3BlbihbJ3NzaCcsICdyYWlsaWFuY2UwMScsIGNvbW1hbmRdLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTClcbiAgICAgICAgc2VsZWN0b3IgPSBzZWxlY3RvcnMuRGVmYXVsdFNlbGVjdG9yKClcbiAgICAgICAgc2VsZWN0b3IucmVnaXN0ZXIodHJhbnNmZXIuc3Rkb3V0LCBzZWxlY3RvcnMuRVZFTlRfUkVBRClcbiAgICAgICAgZGVhZGxpbmUgPSB0aW1lLm1vbm90b25pYygpICsgMTUwXG4gICAgICAgIHJlY2VpdmVkID0gMFxuICAgICAgICB0cnk6XG4gICAgICAgICAgICB3aGlsZSBUcnVlOlxuICAgICAgICAgICAgICAgIHJlbWFpbmluZyA9IGRlYWRsaW5lIC0gdGltZS5tb25vdG9uaWMoKVxuICAgICAgICAgICAgICAgIHJlcXVpcmUocmVtYWluaW5nID4gMCBhbmQgc2VsZWN0b3Iuc2VsZWN0KHJlbWFpbmluZyksICdwcml2YXRlIHRyYW5zZmVyIHRpbWVkIG91dCcpXG4gICAgICAgICAgICAgICAgYmxvY2sgPSBvcy5yZWFkKHRyYW5zZmVyLnN0ZG91dC5maWxlbm8oKSwgMTAyNCoqMilcbiAgICAgICAgICAgICAgICBpZiBub3QgYmxvY2s6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQgKz0gbGVuKGJsb2NrKVxuICAgICAgICAgICAgICAgIHJlcXVpcmUocmVjZWl2ZWQgPD0gbWV0YWRhdGFbJ3NuYXBzaG90X2J5dGVzJ10gYW5kIHJlY2VpdmVkIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdwcml2YXRlIGNvcHkgZXhjZWVkcyBmcm96ZW4gc25hcHNob3Qgc2l6ZScpXG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb24ud3JpdGUoYmxvY2spXG4gICAgICAgICAgICB0cmFuc2Zlci53YWl0KHRpbWVvdXQ9bWF4KDEsIGRlYWRsaW5lIC0gdGltZS5tb25vdG9uaWMoKSkpXG4gICAgICAgIGZpbmFsbHk6XG4gICAgICAgICAgICBzZWxlY3Rvci5jbG9zZSgpXG4gICAgICAgICAgICB0cmFuc2Zlci5zdGRvdXQuY2xvc2UoKVxuICAgICAgICAgICAgaWYgdHJhbnNmZXIucG9sbCgpIGlzIE5vbmU6XG4gICAgICAgICAgICAgICAgdHJhbnNmZXIua2lsbCgpXG4gICAgICAgICAgICAgICAgdHJhbnNmZXIud2FpdCgpXG4gICAgICAgIGRlc3RpbmF0aW9uLmZsdXNoKClcbiAgICAgICAgb3MuZnN5bmMoZGVzdGluYXRpb24uZmlsZW5vKCkpXG4gICAgcHJpdmF0ZShsb2NhbClcbiAgICByZXF1aXJlKHRyYW5zZmVyLnJldHVybmNvZGUgPT0gMCBhbmQgbG9jYWwuc3RhdCgpLnN0X3NpemUgPT0gbWV0YWRhdGFbJ3NuYXBzaG90X2J5dGVzJ11cbiAgICAgICAgICAgIGFuZCBzaGEobG9jYWwpID09IG1ldGFkYXRhWydzbmFwc2hvdF9zaGEyNTYnXSwgJ3ByaXZhdGUgY29weSBpbmNvbXBsZXRlL3VuY2VydGFpbjsgcmV0YWluLCBubyByZXRyeScpXG4gICAgIyBSZS1yZWFkIGlkZW50aXR5L2hhc2ggYWZ0ZXIgdHJhbnNmZXIuIFRoaXMgaXMgdmVyaWZpY2F0aW9uLCBub3QgYSB3cml0ZSByZXRyeS5cbiAgICBhZnRlciA9IHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkKVxuICAgIHJlcXVpcmUoYWZ0ZXJbJ3BvZF91aWQnXSA9PSBtZXRhZGF0YVsncG9kX3VpZCddIGFuZCBhZnRlclsnc25hcHNob3Rfc2hhMjU2J10gPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLFxuICAgICAgICAgICAgJ3NvdXJjZSBpZGVudGl0eS9zbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyB0cmFuc2ZlcicpXG4gICAgcmV0dXJuIHsqKm1ldGFkYXRhLCAnb2ZmX2NsdXN0ZXJfcHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJzogVHJ1ZSwgJ3NuYXBzaG90X2NvbnRlbnRzX291dHB1dCc6IEZhbHNlfVxuXG5cbmRlZiBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKTpcbiAgICBmcm9tIHJlY2VpcHRfc2FmZXR5IGltcG9ydCBjb3VudHNcbiAgICBzbmFwc2hvdCA9IENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJ1xuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcHJldmlvdXMgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydkcmlsbC1jb3B5J11bJ3Jlc3VsdCddXG4gICAgcmVxdWlyZShzaGEoc25hcHNob3QpID09IHByZXZpb3VzWydzbmFwc2hvdF9zaGEyNTYnXSwgJ3Byb3RlY3RlZCBzbmFwc2hvdCBieXRlcyBjaGFuZ2VkJylcbiAgICBpZGVudGl0eSA9IGRvY2tlcihbJ2luZm8nLCAnLS1mb3JtYXQnLCAne3tqc29uIC5OYW1lfX0nXSlcbiAgICByZXF1aXJlKGlkZW50aXR5LnJldHVybmNvZGUgPT0gMCBhbmQganNvbi5sb2FkcyhpZGVudGl0eS5zdGRvdXQpID09ICdibnQtbGFwMDAxJyxcbiAgICAgICAgICAgICdsb2NhbCBvZmZsaW5lIERvY2tlciBlbmdpbmUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgbGlzdGVkID0gZG9ja2VyKFsndm9sdW1lJywgJ2xzJywgJy0tZm9ybWF0JywgJ3t7Lk5hbWV9fSddKVxuICAgIHJlcXVpcmUobGlzdGVkLnJldHVybmNvZGUgPT0gMCBhbmQgVk9MVU1FIG5vdCBpbiBsaXN0ZWQuc3Rkb3V0LnNwbGl0bGluZXMoKSxcbiAgICAgICAgICAgICdkaXNwb3NhYmxlIHZvbHVtZSBhYnNlbmNlIG5vdCB2ZXJpZmllZCcpXG4gICAgbm9uY2UgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydvZmZsaW5lLXZlcmlmeSddWydhdHRlbXB0X2lkJ11cbiAgICBsYWJlbHMgPSB7J2luZm9ybWVkLWRlY2lzaW9uLmNhc2UnOiAnaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxJyxcbiAgICAgICAgICAgICAgJ2luZm9ybWVkLWRlY2lzaW9uLnVzZSc6ICdvZmZsaW5lLXJlc3RvcmUtb25seScsICdpbmZvcm1lZC1kZWNpc2lvbi5hdHRlbXB0Jzogbm9uY2V9XG4gICAgY3JlYXRlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdjcmVhdGUnLCAnLS1kcml2ZXInLCAnbG9jYWwnLCAnLS1sYWJlbCcsICdpbmZvcm1lZC1kZWNpc2lvbi5jYXNlPWluZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsXG4gICAgICAgICAgICAgICAgICAgICAgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdD0nICsgbm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24udXNlPW9mZmxpbmUtcmVzdG9yZS1vbmx5JywgVk9MVU1FXSlcbiAgICByZXF1aXJlKGNyZWF0ZWQucmV0dXJuY29kZSA9PSAwIGFuZCBjcmVhdGVkLnN0ZG91dC5zdHJpcCgpID09IFZPTFVNRSwgJ3ZvbHVtZSBjcmVhdGlvbiB1bmNlcnRhaW47IG5vIHJldHJ5JylcbiAgICBpbnNwZWN0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnaW5zcGVjdCcsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShpbnNwZWN0ZWQucmV0dXJuY29kZSA9PSAwLCAnbmV3IHZvbHVtZSBpZGVudGl0eSB1bmF2YWlsYWJsZScpXG4gICAgdm9sdW1lID0ganNvbi5sb2FkcyhpbnNwZWN0ZWQuc3Rkb3V0KVxuICAgIHJlcXVpcmUobGVuKHZvbHVtZSkgPT0gMSBhbmQgdm9sdW1lWzBdWydOYW1lJ10gPT0gVk9MVU1FIGFuZCB2b2x1bWVbMF0uZ2V0KCdMYWJlbHMnKSA9PSBsYWJlbHNcbiAgICAgICAgICAgIGFuZCB2b2x1bWVbMF0uZ2V0KCdEcml2ZXInKSA9PSAnbG9jYWwnIGFuZCBub3Qgdm9sdW1lWzBdLmdldCgnT3B0aW9ucycpXG4gICAgICAgICAgICBhbmQgdm9sdW1lWzBdLmdldCgnU2NvcGUnKSA9PSAnbG9jYWwnLCAnbmV3IGlzb2xhdGVkIHZvbHVtZSBpZGVudGl0eSBjaGFuZ2VkJylcbiAgICBpZGVudGl0eSA9IHtrZXk6IHZvbHVtZVswXVtrZXldIGZvciBrZXkgaW4gKCdOYW1lJywgJ0xhYmVscycsICdEcml2ZXInLCAnU2NvcGUnLCAnQ3JlYXRlZEF0Jyl9XG4gICAgam91cm5hbC5ub3RlKCdvZmZsaW5lLXZlcmlmeScsICdjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eScsIGlkZW50aXR5KVxuICAgICMgT25lLXRpbWUgVUlEMC9DQVBfQ0hPV04gaW5pdGlhbGl6YXRpb24gaXMgaXNvbGF0ZWQgdG8gdGhlIE5FVyBuYW1lZCB2b2x1bWUuXG4gICAgIyBObyBob3N0L2xpdmUgUFZDL2NvbmZpZy90b2tlbiBtb3VudCBleGlzdHM7IHRoaXMgZGV0YWlsIG5lZWRzIHBhY2tldCByZXZpZXcuXG4gICAgaW5pdGlhbGl6ZXIgPSBcIlwiXCJpbXBvcnQgaGFzaGxpYixvcyxzdGF0LHN5c1xuaWYgc3lzLmZsYWdzLm9wdGltaXplOnJhaXNlIFJ1bnRpbWVFcnJvcignb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQnKVxuZm9sZGVyPScvcmVzdG9yZSc7ZXhwZWN0ZWQ9RVhQRUNURURcbmlmIG9zLmxpc3RkaXIoZm9sZGVyKTpyYWlzZSBWYWx1ZUVycm9yKCduZXcgZW1wdHkgcHJpdmF0ZSB2b2x1bWUgcmVxdWlyZWQnKVxub3MuY2htb2QoZm9sZGVyLDBvNzAwKVxuZmQ9b3Mub3Blbihmb2xkZXIrJy9yZXZpZXcuc3FsaXRlJyxvcy5PX0NSRUFUfG9zLk9fRVhDTHxvcy5PX05PRk9MTE9XfG9zLk9fV1JPTkxZLDBvNjAwKVxuZGlnZXN0PWhhc2hsaWIuc2hhMjU2KCk7c2l6ZT0wXG53aXRoIG9zLmZkb3BlbihmZCwnd2InKSBhcyB0YXJnZXQ6XG4gd2hpbGUgVHJ1ZTpcbiAgYmxvY2s9c3lzLnN0ZGluLmJ1ZmZlci5yZWFkKDEwMjQqKjIpXG4gIGlmIG5vdCBibG9jazpicmVha1xuICBzaXplKz1sZW4oYmxvY2spXG4gIGlmIHNpemU+NTEyKjEwMjQqKjI6cmFpc2UgVmFsdWVFcnJvcigncHJpdmF0ZSByZXN0b3JlIHNpemUgZXhjZWVkcyBib3VuZCcpXG4gIHRhcmdldC53cml0ZShibG9jayk7ZGlnZXN0LnVwZGF0ZShibG9jaylcbiB0YXJnZXQuZmx1c2goKTtvcy5mc3luYyh0YXJnZXQuZmlsZW5vKCkpXG5pZiBkaWdlc3QuaGV4ZGlnZXN0KCkhPWV4cGVjdGVkOnJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgY29waWVkIHNuYXBzaG90IGRpZmZlcnMnKVxub3MuY2hvd24oZm9sZGVyKycvcmV2aWV3LnNxbGl0ZScsMTAwMDEsMTAwMDEpO29zLmNob3duKGZvbGRlciwxMDAwMSwxMDAwMSlcbnByaW50KCd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwicHJpdmF0ZV9jb3B5X3ZlcmlmaWVkXCI6dHJ1ZX0nKVxuXCJcIlwiLnJlcGxhY2UoJ0VYUEVDVEVEJywgcmVwcihwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10pKVxuICAgIHdpdGggc25hcHNob3Qub3BlbigncmInKSBhcyBzb3VyY2U6XG4gICAgICAgIGFyZ3YgPSBbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVCxcbiAgICAgICAgICAgICAgICAncnVuJywgJy0tcm0nLCAnLWknLCAnLS1uZXR3b3JrJywgJ25vbmUnLCAnLS1yZWFkLW9ubHknLCAnLS1jcHVzJywgJzEnLCAnLS1tZW1vcnknLCAnMTI4bScsXG4gICAgICAgICAgICAgICAgJy0tdXNlcicsICcwOjAnLCAnLS1jYXAtZHJvcCcsICdBTEwnLCAnLS1jYXAtYWRkJywgJ0NIT1dOJyxcbiAgICAgICAgICAgICAgICAnLS1zZWN1cml0eS1vcHQnLCAnbm8tbmV3LXByaXZpbGVnZXMnLCAnLS1tb3VudCcsICd0eXBlPXZvbHVtZSxzcmM9JyArIFZPTFVNRSArICcsZHN0PS9yZXN0b3JlJyxcbiAgICAgICAgICAgICAgICAnLS1lbnRyeXBvaW50JywgJ3B5dGhvbicsIElNQUdFLCAnLWMnLCBpbml0aWFsaXplcl1cbiAgICAgICAgY29waWVkID0gc3VicHJvY2Vzcy5ydW4oYXJndiwgc3RkaW49c291cmNlLCB0ZXh0PVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRpbWVvdXQ9MTUwKVxuICAgIGpzb25fcmVzdWx0KGNvcGllZClcbiAgICBvcHRpb25zID0gWydydW4nLCAnLS1ybScsICctaScsICctLW5ldHdvcmsnLCAnbm9uZScsICctLXJlYWQtb25seScsICctLWNwdXMnLCAnMScsICctLW1lbW9yeScsICcxMjhtJyxcbiAgICAgICAgICAgICAgICctLXVzZXInLCAnMTAwMDE6MTAwMDEnLCAnLS1jYXAtZHJvcCcsICdBTEwnLCAnLS1zZWN1cml0eS1vcHQnLCAnbm8tbmV3LXByaXZpbGVnZXMnLFxuICAgICAgICAgICAgICAgJy0tbW91bnQnLCAndHlwZT12b2x1bWUsc3JjPScgKyBWT0xVTUUgKyAnLGRzdD0vcmVzdG9yZSddXG4gICAgcmVhZG9ubHkgPSBkb2NrZXIob3B0aW9ucyArIFsnLS1lbnRyeXBvaW50JywgJ3B5dGhvbicsIElNQUdFLCAnLScsICctLWRiJywgJy9yZXN0b3JlL3Jldmlldy5zcWxpdGUnXSxcbiAgICAgICAgICAgICAgICAgICAgICAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlYWRvbmx5LnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgcHJlLW9wZW4gc2NoZW1hL2ludGVncml0eSBnYXRlIHJlZnVzZWQ7IG5ldmVyIG9wZW4gU3RvcmUnKVxuICAgIGNoZWNrZWQgPSBjb3VudHMoanNvbi5sb2FkcyhyZWFkb25seS5zdGRvdXQpKVxuICAgIHJlcXVpcmUoY2hlY2tlZCA9PSBwcmV2aW91c1snc25hcHNob3RfcmVhZG9ubHknXSwgJ2Zyb3plbiBzbmFwc2hvdC9jbG9uZSByZWFkb25seSBjb3VudHMgZGlmZmVyJylcbiAgICBhZG1pbiA9IGRvY2tlcihvcHRpb25zICsgWyctLWVudHJ5cG9pbnQnLCAnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4nLCBJTUFHRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpbnNwZWN0JywgJy0tZGInLCAnL3Jlc3RvcmUvcmV2aWV3LnNxbGl0ZSddKVxuICAgIHJlcXVpcmUoYWRtaW4ucmV0dXJuY29kZSA9PSAwLCAnb2ZmbGluZSBhZG1pbiByZXN1bHQgdW5jZXJ0YWluJylcbiAgICBhZG1pbl9jb3VudHMgPSBqc29uLmxvYWRzKGFkbWluLnN0ZG91dClcbiAgICByZXF1aXJlKGFkbWluX2NvdW50cyA9PSB7a2V5OiBjaGVja2VkW2tleV0gZm9yIGtleSBpbiAoJ3NjaGVtYV92ZXJzaW9uJywgJ2xpZmVjeWNsZScsICdvdXRib3gnLCAnc3VibWlzc2lvbnMnKX0sXG4gICAgICAgICAgICAnb2ZmbGluZSBhZG1pbiBjaGFuZ2VkIGZyb3plbiBzbmFwc2hvdCBjb3VudGVycycpXG4gICAgIyBBZG1pbiBTdG9yZSBjb25zdHJ1Y3Rpb24gbXVzdCBub3Qgc2lsZW50bHkgYWx0ZXIgc2NoZW1hL2ludGVncml0eS9jb3VudGVycy5cbiAgICBwb3N0ID0gZG9ja2VyKG9wdGlvbnMgKyBbJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy0nLCAnLS1kYicsICcvcmVzdG9yZS9yZXZpZXcuc3FsaXRlJ10sXG4gICAgICAgICAgICAgICAgICAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHBvc3QucmV0dXJuY29kZSA9PSAwLCAnb2ZmbGluZSBwb3N0LWFkbWluIHJlYWRvbmx5IGludGVncml0eSBnYXRlIHJlZnVzZWQnKVxuICAgIHBvc3RfY2hlY2tlZCA9IGNvdW50cyhqc29uLmxvYWRzKHBvc3Quc3Rkb3V0KSlcbiAgICByZXF1aXJlKHBvc3RfY2hlY2tlZCA9PSBjaGVja2VkID09IHByZXZpb3VzWydzbmFwc2hvdF9yZWFkb25seSddLFxuICAgICAgICAgICAgJ29mZmxpbmUgYWRtaW4gYWx0ZXJlZCBmcm96ZW4gc25hcHNob3QgcHJvb2YnKVxuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcmVxdWlyZShzaGEoc25hcHNob3QpID09IHByZXZpb3VzWydzbmFwc2hvdF9zaGEyNTYnXSwgJ29yaWdpbmFsIHByb3RlY3RlZCBzbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyBkcmlsbCcpXG4gICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ29mZmxpbmVfdm9sdW1lJzogVk9MVU1FLCAnb2ZmbGluZV9yZWFkb25seSc6IGNoZWNrZWQsXG4gICAgICAgICAgICAnb2ZmbGluZV9wb3N0X2FkbWluX3JlYWRvbmx5JzogcG9zdF9jaGVja2VkLCAnb3JpZ2luYWxfc25hcHNob3RfaGFzaF91bmNoYW5nZWQnOiBUcnVlLFxuICAgICAgICAgICAgJ2NyZWF0ZWRfdm9sdW1lX2lkZW50aXR5JzogaWRlbnRpdHksXG4gICAgICAgICAgICAnYWRtaW5fY291bnRzJzogYWRtaW5fY291bnRzLCAnbmV0d29yayc6ICdub25lJywgJ3J1bnRpbWVfdG9rZW5zX29yX2NvbmZpZ19tb3VudGVkJzogRmFsc2UsXG4gICAgICAgICAgICAnc2VydmljZV9lbnRyeXBvaW50X3N0YXJ0ZWQnOiBGYWxzZSwgJ29yaWdpbmFsX3NuYXBzaG90X3JldGFpbmVkJzogVHJ1ZX1cblxuXG5kZWYgY2xlYW51cF9vZmZsaW5lKGpvdXJuYWwpOlxuICAgIGluc3BlY3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdpbnNwZWN0JywgVk9MVU1FXSlcbiAgICByZXF1aXJlKGluc3BlY3RlZC5yZXR1cm5jb2RlID09IDAsICdvd25lZCBkaXNwb3NhYmxlIHZvbHVtZSBpZGVudGl0eSB1bnZlcmlmaWVkJylcbiAgICB2YWx1ZSA9IGpzb24ubG9hZHMoaW5zcGVjdGVkLnN0ZG91dClcbiAgICBleHBlY3RlZCA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ29mZmxpbmUtdmVyaWZ5J11bJ3Jlc3VsdCddWydjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eSddXG4gICAgcmVxdWlyZShsZW4odmFsdWUpID09IDEgYW5kIHtrZXk6IHZhbHVlWzBdLmdldChrZXkpIGZvciBrZXkgaW4gZXhwZWN0ZWR9ID09IGV4cGVjdGVkXG4gICAgICAgICAgICBhbmQgbm90IHZhbHVlWzBdLmdldCgnT3B0aW9ucycpLCAndm9sdW1lIG93bmVyc2hpcC9yZWNyZWF0aW9uIGNoYW5nZWQnKVxuICAgIHJlbW92ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAncm0nLCBWT0xVTUVdKVxuICAgIHJlcXVpcmUocmVtb3ZlZC5yZXR1cm5jb2RlID09IDAgYW5kIHJlbW92ZWQuc3Rkb3V0LnN0cmlwKCkgPT0gVk9MVU1FXG4gICAgICAgICAgICBhbmQgZG9ja2VyKFsndm9sdW1lJywgJ2luc3BlY3QnLCBWT0xVTUVdKS5yZXR1cm5jb2RlICE9IDAsXG4gICAgICAgICAgICAnY2xlYW51cCBvdXRjb21lIGFtYmlndW91czsgZG8gbm90IHJldHJ5JylcbiAgICByZXR1cm4geydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlLCAnb25seV9kaXNwb3NhYmxlX29mZmxpbmVfdm9sdW1lX3JlbW92ZWQnOiBWT0xVTUUsXG4gICAgICAgICAgICAnbmF0aXZlX2FuZF9vZmZjbHVzdGVyX29yaWdpbmFsX3NuYXBzaG90c19yZXRhaW5lZCc6IFRydWV9XG5cblxuZGVmIG1haW4oKTpcbiAgICBwYXJzZXIgPSBhcmdwYXJzZS5Bcmd1bWVudFBhcnNlcihkZXNjcmlwdGlvbj1fX2RvY19fKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tcGhhc2UnLCBjaG9pY2VzPVBIQVNFUywgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXJvb3QtYXV0aG9yaXR5LXJlY2VpcHQnLCB0eXBlPVBhdGgsIHJlcXVpcmVkPVRydWUpXG4gICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1yb290LW5hdGl2ZS1vdXRjb21lJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tc291cmNlLXJldmlzaW9uJywgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBhcmdzID0gcGFyc2VyLnBhcnNlX2FyZ3MoKVxuICAgIHJlcXVpcmUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0ID09IFBhdGgoJy90bXAvc2VjdXJpdHktaW5mZC1wdXJwb3NlLXJvb3QtYXV0aG9yaXR5Lmpzb24nKVxuICAgICAgICAgICAgYW5kIGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZSA9PSBQYXRoKCcvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1uYXRpdmUtb3V0Y29tZS1sYXRlc3QuanNvbicpLFxuICAgICAgICAgICAgJ2ZpeGVkIHN1cGVydmlzZWQgcmVjZWlwdCBwYXRocyByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShyZS5mdWxsbWF0Y2gocidbMC05YS1mXXs0MH0nLCBhcmdzLnNvdXJjZV9yZXZpc2lvbikgaXMgbm90IE5vbmUsICdleGFjdCBzb3VyY2UgY29tbWl0IHJlcXVpcmVkJylcbiAgICAjIFZlcmlmeSBhbGwgcHJlcGFyZWQgZXhlY3V0b3IvaW5wdXQgYnl0ZXMgYmVmb3JlIHJlYWRpbmcgYXV0aG9yaXR5IG9yIGRpc3BhdGNoaW5nLlxuICAgIHBsYW4gPSBqc29uLmxvYWRzKChST09UIC8gJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHNldChwbGFuWydleGVjdXRvcl9maWxlcyddKSA9PSB7J2FjdHVhdG9yLnB5JywgJ2F1dGhvcml0eV9qb3VybmFsLnB5JywgJ25hdGl2ZV9wcm9ncmFtLnB5JywgJ3JlY2VpcHRfc2FmZXR5LnB5J30sXG4gICAgICAgICAgICAnZml4ZWQgZXhlY3V0b3Igc291cmNlcyByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShzZXQocGxhblsnb3duZXJfc291cmNlX2ZpbGVzJ10pID09IHsnZGVwbG95L2xpZmVjeWNsZS9hZG1pc3Npb24uY2FuZGlkYXRlLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL2t1c3RvbWl6YXRpb24ueWFtbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RlcGxveS9saWZlY3ljbGUvcmVnaXN0cmllcy5jYW5kaWRhdGUuanNvbid9LFxuICAgICAgICAgICAgJ2ZpeGVkIG93bmVyIGltYWdlIHNvdXJjZXMgcmVxdWlyZWQnKVxuICAgIGZvciByZWxhdGl2ZSwgZGlnZXN0IGluIHBsYW5bJ2V4ZWN1dG9yX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgdGFyZ2V0ID0gUk9PVCAvIHJlbGF0aXZlXG4gICAgICAgIHJlcXVpcmUobm90IHRhcmdldC5pc19zeW1saW5rKCkgYW5kIHNoYSh0YXJnZXQpID09IGRpZ2VzdCwgJ2V4ZWN1dG9yIHNvdXJjZSBieXRlcyBjaGFuZ2VkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydjYXNlX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgcmVxdWlyZShub3QgUGF0aChyZWxhdGl2ZSkuaXNfYWJzb2x1dGUoKSBhbmQgJy4uJyBub3QgaW4gUGF0aChyZWxhdGl2ZSkucGFydHMsXG4gICAgICAgICAgICAgICAgJ2Nhc2Ugc291cmNlIHBhdGggZXNjYXBlZCcpXG4gICAgICAgIHRhcmdldCA9IENBU0UgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdjYXNlIHNvdXJjZSBieXRlcyBjaGFuZ2VkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydvd25lcl9zb3VyY2VfZmlsZXMnXS5pdGVtcygpOlxuICAgICAgICB0YXJnZXQgPSBPV05FUiAvIHJlbGF0aXZlXG4gICAgICAgIHJlcXVpcmUobm90IHRhcmdldC5pc19zeW1saW5rKCkgYW5kIHNoYSh0YXJnZXQpID09IGRpZ2VzdCwgJ293bmVyIGltYWdlLW9ubHkgc291cmNlIGNoYW5nZWQnKVxuICAgICAgICBjb21taXR0ZWQgPSBzdWJwcm9jZXNzLnJ1bihbJ2dpdCcsICctQycsIHN0cihPV05FUiksICdzaG93JywgYXJncy5zb3VyY2VfcmV2aXNpb24gKyAnOicgKyByZWxhdGl2ZV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVfb3V0cHV0PVRydWUpXG4gICAgICAgIHJlcXVpcmUoY29tbWl0dGVkLnJldHVybmNvZGUgPT0gMCBhbmQgaGFzaGxpYi5zaGEyNTYoY29tbWl0dGVkLnN0ZG91dCkuaGV4ZGlnZXN0KCkgPT0gZGlnZXN0LFxuICAgICAgICAgICAgICAgICdjb21taXR0ZWQgb3duZXIgcmVuZGVyIHNvdXJjZSBkaWZmZXJzIGZyb20gYXBwcm92ZWQgaW5wdXRzJylcbiAgICBoZWFkID0gcnVuKFsnZ2l0JywgJy1DJywgc3RyKE9XTkVSKSwgJ3Jldi1wYXJzZScsICdIRUFEJ10pXG4gICAgcmVxdWlyZShoZWFkLnJldHVybmNvZGUgPT0gMCBhbmQgaGVhZC5zdGRvdXQuc3RyaXAoKSA9PSBhcmdzLnNvdXJjZV9yZXZpc2lvbiwgJ293bmVyIHNvdXJjZSBIRUFEIGRpZmZlcnMnKVxuICAgIGZyb20gYXV0aG9yaXR5X2pvdXJuYWwgaW1wb3J0IEpvdXJuYWwsIGF1dGhvcml0eVxuICAgIHByaXZhdGUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0KVxuICAgIHByaXZhdGUoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKVxuICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlY2VpcHQuZ2V0KCduYXRpdmVfb3V0Y29tZV9zaGEyNTYnKSA9PSBzaGEoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKSwgJ25hdGl2ZSBvdXRjb21lIGJ5dGVzIGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ2V4ZWN1dG9yX3BsYW5fc2hhMjU2JykgPT0gc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgJ3Jvb3QgdmVyaWZpZWQgZXhlY3V0b3IgcGxhbiBkaWZmZXJzJylcbiAgICBhcHByb3ZlZCA9IGF1dGhvcml0eShyZWNlaXB0LCBqc29uLmxvYWRzKGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZS5yZWFkX3RleHQoKSksIHNoYShDQVNFIC8gJ21lbW8uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcmdzLnBoYXNlKVxuICAgIHBhcmVudCA9IENVU1RPRFkucGFyZW50XG4gICAgcHJpdmF0ZShwYXJlbnQsIGRpcmVjdG9yeT1UcnVlKVxuICAgIGlnbm9yZWQgPSBydW4oWydnaXQnLCAnLUMnLCBzdHIoQ1VTVE9ESUFOKSwgJ2NoZWNrLWlnbm9yZScsICctLW5vLWluZGV4Jywgc3RyKENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJyldKVxuICAgIHJlcXVpcmUoaWdub3JlZC5yZXR1cm5jb2RlID09IDAsICdvZmZjbHVzdGVyIGN1c3RvZHkgaXMgbm90IGlnbm9yZWQnKVxuICAgIGlmIG5vdCBDVVNUT0RZLmV4aXN0cygpOlxuICAgICAgICByZXF1aXJlKGFyZ3MucGhhc2UgPT0gJ2RyaWxsLWJhY2t1cCcsICdmaXJzdCBhcHByb3ZlZCBwaGFzZSBtdXN0IGNyZWF0ZSB1bmlxdWUgcHJpdmF0ZSBjdXN0b2R5JylcbiAgICAgICAgb3MubWtkaXIoQ1VTVE9EWSwgMG83MDApXG4gICAgcHJpdmF0ZShDVVNUT0RZLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICBjYXBhY2l0eSA9IG9zLnN0YXR2ZnMoQ1VTVE9EWSlcbiAgICByZXF1aXJlKGNhcGFjaXR5LmZfYmF2YWlsICogY2FwYWNpdHkuZl9mcnNpemUgPj0gMiAqIE1BWF9CWVRFUyArIDE2ICogMTAyNCoqMixcbiAgICAgICAgICAgICdpbmRlcGVuZGVudCBwcm90ZWN0ZWQgY3VzdG9keSBoZWFkcm9vbSBpbnN1ZmZpY2llbnQnKVxuICAgIG9zLm1ha2VkaXJzKENVU1RPRFkgLyAnZW1wdHktZG9ja2VyLWNvbmZpZycsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpXG4gICAgcHJpdmF0ZShDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICByZXF1aXJlKG5vdCBsaXN0KChDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKS5pdGVyZGlyKCkpLCAncHVibGljIERvY2tlciByZWFkIGNvbmZpZyBtdXN0IHN0YXkgZW1wdHknKVxuICAgIGpvdXJuYWwgPSBKb3VybmFsKENVU1RPRFksIHsncHJvcG9zYWwnOiBwbGFuWydwcm9wb3NhbF9pZCddLCAnc291cmNlX3JldmlzaW9uJzogYXJncy5zb3VyY2VfcmV2aXNpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21lbW9fc2hhMjU2Jzogc2hhKENBU0UgLyAnbWVtby5qc29uJyksICdwbGFuX3NoYTI1Nic6IHNoYShST09UIC8gJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKX0pXG4gICAgdHJ5OlxuICAgICAgICBqb3VybmFsLnN0YXJ0KGFyZ3MucGhhc2UsIGFwcHJvdmVkKSAjIGZzeW5jZWQgUlVOTklORyBiZWZvcmUgYW55IHBoYXNlIGVmZmVjdC5cbiAgICAgICAgaWYgYXJncy5waGFzZSBpbiAoJ2RyaWxsLWNvcHknLCAnY3V0b3Zlci1jb3B5Jyk6XG4gICAgICAgICAgICByZXN1bHQgPSBjb3B5X3NuYXBzaG90KGFyZ3MucGhhc2UsIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcHByb3ZlZCwgam91cm5hbClcbiAgICAgICAgZWxpZiBhcmdzLnBoYXNlID09ICdvZmZsaW5lLXZlcmlmeSc6XG4gICAgICAgICAgICByZXN1bHQgPSBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKVxuICAgICAgICBlbGlmIGFyZ3MucGhhc2UgPT0gJ2NsZWFudXAtb2ZmbGluZSc6XG4gICAgICAgICAgICByZXN1bHQgPSBjbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgZWxzZTpcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlbW90ZShhcmdzLnBoYXNlLCBhcmdzLnNvdXJjZV9yZXZpc2lvbiwgYXBwcm92ZWQpXG4gICAgICAgIGpvdXJuYWwuZmluaXNoKGFyZ3MucGhhc2UsIHJlc3VsdClcbiAgICAgICAgcHJpbnQoanNvbi5kdW1wcyhyZXN1bHQpKSAjIE9ubHkgY291bnQvaGFzaC9pZGVudGl0eSByZWNlaXB0cywgbmV2ZXIgc25hcHNob3QgYnl0ZXMuXG4gICAgZXhjZXB0IEJhc2VFeGNlcHRpb24gYXMgZXJyb3I6XG4gICAgICAgIHNhZmUgPSB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncGhhc2UnOiBhcmdzLnBoYXNlLCAnZmFpbHVyZV9jbGFzcyc6IHR5cGUoZXJyb3IpLl9fbmFtZV9fLFxuICAgICAgICAgICAgICAgICdmYWlsdXJlJzogJ2ZpeGVkIHBoYXNlIG91dGNvbWUgdW5jZXJ0YWluOyBvcmlnaW5hbCBldmlkZW5jZSByZXRhaW5lZDsgbm8gcmV0cnknLFxuICAgICAgICAgICAgICAgICdyYXdfb3V0cHV0X3dpdGhoZWxkJzogVHJ1ZX1cbiAgICAgICAgaWYgam91cm5hbC5kYXRhWydwaGFzZXMnXS5nZXQoYXJncy5waGFzZSwge30pLmdldCgnc3RhdGUnKSA9PSAnUlVOTklORyc6XG4gICAgICAgICAgICBqb3VybmFsLmZpbmlzaChhcmdzLnBoYXNlLCBzYWZlKVxuICAgICAgICBwcmludChqc29uLmR1bXBzKHNhZmUpKVxuICAgICAgICByYWlzZSBTeXN0ZW1FeGl0KDEpIGZyb20gTm9uZVxuICAgIGZpbmFsbHk6XG4gICAgICAgIGpvdXJuYWwuY2xvc2UoKVxuXG5cbmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6XG4gICAgdHJ5OlxuICAgICAgICBtYWluKClcbiAgICBleGNlcHQgRXhjZXB0aW9uOlxuICAgICAgICByYWlzZSBTeXN0ZW1FeGl0KCdzdXBlcnZpc2VkIGV4ZWN1dGlvbiByZWZ1c2VkIGJlZm9yZSBwaGFzZTsgcmF3IG91dHB1dCB3aXRoaGVsZCcpIGZyb20gTm9uZVxuIgogICAgfSwKICAgICJhdXRob3JpdHlfam91cm5hbC5weSI6IHsKICAgICAgInNoYTI1NiI6ICI3NGQ2YTkxMTY5Mjk2YTk5ZmE3ZGFjMmQwOTAyNTY3MjgwZjkxMGFmNzQzNTgwZWM0YjQ1NGYyYWJmODM3NGFhIiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiU3VwZXJ2aXNlZCByZWNlaXB0IGJvb2trZWVwaW5nLCBub3QgYW4gYXV0aGVudGljYXRlZCBhcHByb3ZhbCBwcm92aWRlci5cIlwiXCJcbmltcG9ydCBkYXRldGltZVxuaW1wb3J0IGZjbnRsXG5pbXBvcnQgaGFzaGxpYlxuaW1wb3J0IGpzb25cbmltcG9ydCBvc1xuaW1wb3J0IHJlXG5mcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGhcbmltcG9ydCBzdGF0XG5pbXBvcnQgdXVpZFxuXG5GT1VOREVSID0geydraW5kJzogJ3BlcnNvbicsICdzdWInOiAndWlkPXBsYXRmb3JtLXJvb3Qsb3U9cGVvcGxlLGRjPW5ldGtpbmdkb20sZGM9bG9jYWwnfVxuTUVNT19JRCA9ICdpbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMSdcblBST1BPU0FMID0gJ0lORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxJ1xuUEhBU0VTID0gKCdkcmlsbC1iYWNrdXAnLCAnZHJpbGwtY29weScsICdvZmZsaW5lLXZlcmlmeScsICdjbGVhbnVwLW9mZmxpbmUnLFxuICAgICAgICAgICdjdXRvdmVyLWJhY2t1cCcsICdjdXRvdmVyLWNvcHknLCAncmVsZWFzZScsICd2ZXJpZnknLCAncm9sbGJhY2snLCAncm9sbGJhY2stdmVyaWZ5JylcblxuXG5kZWYgcmVxdWlyZSh2YWx1ZSwgcmVhc29uKTpcbiAgICBpZiBub3QgdmFsdWU6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IocmVhc29uKVxuXG5cbmRlZiBzaGEocGF0aCk6XG4gICAgZGlnZXN0ID0gaGFzaGxpYi5zaGEyNTYoKVxuICAgIHdpdGggUGF0aChwYXRoKS5vcGVuKCdyYicpIGFzIHN0cmVhbTpcbiAgICAgICAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOiBzdHJlYW0ucmVhZCgxMDI0KioyKSwgYicnKTpcbiAgICAgICAgICAgIGRpZ2VzdC51cGRhdGUoYmxvY2spXG4gICAgcmV0dXJuIGRpZ2VzdC5oZXhkaWdlc3QoKVxuXG5cbmRlZiBwcml2YXRlKHBhdGgsIGRpcmVjdG9yeT1GYWxzZSk6XG4gICAgaW5mbyA9IFBhdGgocGF0aCkubHN0YXQoKVxuICAgIHJlcXVpcmUoKHN0YXQuU19JU0RJUihpbmZvLnN0X21vZGUpIGlmIGRpcmVjdG9yeSBlbHNlIHN0YXQuU19JU1JFRyhpbmZvLnN0X21vZGUpKVxuICAgICAgICAgICAgYW5kIGluZm8uc3RfdWlkID09IG9zLmdldHVpZCgpIGFuZCBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKSA9PSAoMG83MDAgaWYgZGlyZWN0b3J5IGVsc2UgMG82MDApXG4gICAgICAgICAgICBhbmQgKGRpcmVjdG9yeSBvciBpbmZvLnN0X25saW5rID09IDEpLCAncHJpdmF0ZSBvd25lZCBjdXN0b2R5IHJlcXVpcmVkJylcblxuXG5kZWYgYXV0aG9yaXR5KHJlY2VpcHQsIG91dGNvbWUsIG1lbW9fc2hhLCBzb3VyY2VfcmV2aXNpb24sIHBoYXNlLCBub3c9Tm9uZSk6XG4gICAgXCJcIlwiUm9vdCBtdXN0IGZyZXNobHkgdmVyaWZ5IG5hdGl2ZSBvdXRjb21lIGF0IGZpeGVkIE9SSUdJTiBvdXRzaWRlIHRoaXMgaGVscGVyLlxuXG4gICAgUmVjZWlwdCBmaWxlcy9mbGFncyBhcmUgbm90IHNpZ25lZCBncmFudHMuIFRoaXMgZnVuY3Rpb24gY2hlY2tzIHRoZSBleGFjdFxuICAgIHN1cGVydmlzZWQgcmVjZWlwdCByZWxhdGlvbjsgZXhpc3RpbmcgaGFybmVzcy9mb3VuZGVyIGF1dGhvcml0eSByZW1haW5zIHRoZVxuICAgIGFjdHVhbCBwZXJtaXNzaW9uIGJvdW5kYXJ5LiBJdCBuZXZlciBhdXRoZW50aWNhdGVzIGEgY2FsbGVyIGFzIGh1bWFuLlxuICAgIFwiXCJcIlxuICAgIG5vdyA9IG5vdyBvciBkYXRldGltZS5kYXRldGltZS5ub3coZGF0ZXRpbWUudGltZXpvbmUudXRjKVxuICAgIHJlcXVpcmUocGhhc2UgaW4gUEhBU0VTLCAnZml4ZWQgcGhhc2UgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ3Byb3Bvc2FsX2lkJykgPT0gUFJPUE9TQUwgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX2lkJykgPT0gTUVNT19JRFxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX3ZlcnNpb24nKSA9PSAxIGFuZCByZWNlaXB0LmdldCgnbWVtb19zaGEyNTYnKSA9PSBtZW1vX3NoYVxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdzb3VyY2VfcmV2aXNpb24nKSA9PSBzb3VyY2VfcmV2aXNpb25cbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgnYWN0aXZhdGlvbicpID09ICdBUFBST1ZFRCdcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgnYXV0aG9yaXR5X21vZGUnKSA9PSAnQURNSU5JU1RFUidcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgndGFyZ2V0JykgPT0gJ3JlYWxtOmt1YmVybmV0ZXMvcmFpbGlhbmNlMDEvaW5mb3JtZWQtZGVjaXNpb24nXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3ZlcmlmaWNhdGlvbl9tZXRob2QnKSA9PSAncm9vdC1maXhlZC1vcmlnaW4tbmF0aXZlLXJlYWRiYWNrJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdydW50aW1lX2F1dGhlbnRpY2F0ZWRfZ3JhbnQnKSBpcyBGYWxzZSxcbiAgICAgICAgICAgICdleGFjdCBleHRlcm5hbGx5IHZlcmlmaWVkIHN1cGVydmlzZWQgcmVjZWlwdCByZXF1aXJlZCcpXG4gICAgdmVyaWZpZWQgPSBkYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KHJlY2VpcHRbJ3ZlcmlmaWVkX2F0J10ucmVwbGFjZSgnWicsICcrMDA6MDAnKSlcbiAgICByZXF1aXJlKHZlcmlmaWVkLnR6aW5mbyBpcyBub3QgTm9uZSBhbmQgMCA8PSAobm93IC0gdmVyaWZpZWQpLnRvdGFsX3NlY29uZHMoKSA8PSAxMjAsXG4gICAgICAgICAgICAnZnJlc2ggcm9vdCBuYXRpdmUgcmVhZGJhY2sgcmVxdWlyZWQgYmVmb3JlIGV2ZXJ5IHBoYXNlJylcbiAgICBkZWFkbGluZSA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQoJzIwMjYtMTAtMTJUMjM6NTk6NTkrMDA6MDAnKVxuICAgIHJlcXVpcmUobm93IDwgZGVhZGxpbmUsICdhcHByb3ZlZCBleGVjdXRpb24gd2luZG93IGV4cGlyZWQnKVxuICAgIHJlcXVpcmUob3V0Y29tZS5nZXQoJ21lbW9faWQnKSA9PSBNRU1PX0lEIGFuZCBvdXRjb21lLmdldCgncmV2aWV3Jywge30pLmdldCgnc3RhbGUnKSBpcyBGYWxzZVxuICAgICAgICAgICAgYW5kIG91dGNvbWVbJ3JldmlldyddLmdldCgnaW50YWtlX3N0YXRlJykgPT0gJ3JlYWR5JywgJ25hdGl2ZSByZXZpZXcgaXMgbm90IHJlYWR5L2N1cnJlbnQnKVxuICAgIHJldmlld19pZCA9IG91dGNvbWVbJ3JldmlldyddWydtZW1vX2lkJ11cbiAgICByZXF1aXJlKHJldmlld19pZCA9PSByZWNlaXB0LmdldCgncmV2aWV3X21lbW9faWQnKSwgJ25hdGl2ZSByZXZpZXcgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgYWNjZXB0ZWQgPSBbeCBmb3IgeCBpbiBvdXRjb21lLmdldCgnZGlzcG9zaXRpb25zJywgW10pXG4gICAgICAgICAgICAgICAgaWYgeC5nZXQoJ3N1Ym1pc3Npb25fc3RhdGUnKSA9PSAnY29uZmlybWVkJ1xuICAgICAgICAgICAgICAgIGFuZCB4LmdldCgnZGlzcG9zaXRpb24nLCB7fSkuZ2V0KCd2ZXJiJykgPT0gJ2FjY2VwdCdcbiAgICAgICAgICAgICAgICBhbmQgeFsnZGlzcG9zaXRpb24nXS5nZXQoJ21lbW9fdmVyc2lvbicpID09IDFdXG4gICAgcmVxdWlyZShsZW4oYWNjZXB0ZWQpID09IDEsICdvbmUgY29uZmlybWVkIGZvdW5kZXIgYWNjZXB0YW5jZSByZXF1aXJlZCcpXG4gICAgYWNjZXB0ZWQgPSBhY2NlcHRlZFswXVsnZGlzcG9zaXRpb24nXVxuICAgIHJlcXVpcmUoYWNjZXB0ZWQuZ2V0KCdhY3RvcicpID09IEZPVU5ERVIgYW5kIGFjY2VwdGVkLmdldCgnbWVtb19pZCcpID09IHJldmlld19pZFxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnYXBwcm92YWxfaWQnKSA9PSByZWNlaXB0LmdldCgnYXBwcm92YWxfaWQnKVxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnaWQnKSA9PSByZWNlaXB0LmdldCgnZGlzcG9zaXRpb25faWQnKVxuICAgICAgICAgICAgYW5kIGFjY2VwdGVkLmdldCgnYXQnKSA9PSByZWNlaXB0LmdldCgnYWNjZXB0ZWRfYXQnKSwgJ2V4YWN0IGZvdW5kZXIgZGlzcG9zaXRpb24gbWlzbWF0Y2gnKVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOS1dezM2fScsIGFjY2VwdGVkWydhcHByb3ZhbF9pZCddKSBpcyBub3QgTm9uZVxuICAgICAgICAgICAgYW5kIHJlLmZ1bGxtYXRjaChyJ2Rpc3AtW2EtZjAtOS1dezM2fScsIGFjY2VwdGVkWydpZCddKSBpcyBub3QgTm9uZVxuICAgICAgICAgICAgYW5kIHJlLmZ1bGxtYXRjaChyJ3Jldmlldy1bYS1mMC05LV17MzZ9JywgcmV2aWV3X2lkKSBpcyBub3QgTm9uZSxcbiAgICAgICAgICAgICduYXRpdmUgZGlzcG9zaXRpb24gaWRlbnRpZmllcnMgYXJlIG1hbGZvcm1lZCcpXG4gICAgYWNjZXB0ZWRfYXQgPSBkYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KGFjY2VwdGVkWydhdCddLnJlcGxhY2UoJ1onLCAnKzAwOjAwJykpXG4gICAgcmVxdWlyZShhY2NlcHRlZF9hdC50emluZm8gaXMgbm90IE5vbmUgYW5kIGFjY2VwdGVkX2F0IDw9IHZlcmlmaWVkLCAnYWNjZXB0YW5jZSB0aW1lIG5vdCBib3VuZGVkJylcbiAgICByZXR1cm4ge2tleTogcmVjZWlwdFtrZXldIGZvciBrZXkgaW4gKCdhcHByb3ZhbF9pZCcsICdkaXNwb3NpdGlvbl9pZCcsICdhY2NlcHRlZF9hdCcsICd2ZXJpZmllZF9hdCcpfVxuXG5cbmNsYXNzIEpvdXJuYWw6XG4gICAgZGVmIF9faW5pdF9fKHNlbGYsIHBhcmVudCwgaWRlbnRpdHkpOlxuICAgICAgICBzZWxmLnBhcmVudCA9IFBhdGgocGFyZW50KVxuICAgICAgICBwcml2YXRlKHNlbGYucGFyZW50LCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICAgICAgc2VsZi5wYXRoID0gc2VsZi5wYXJlbnQgLyAnZXhlY3V0aW9uLWpvdXJuYWwuanNvbidcbiAgICAgICAgc2VsZi5sb2NrID0gb3Mub3BlbihzZWxmLnBhcmVudCAvICdleGVjdXRpb24ubG9jaycsIG9zLk9fQ1JFQVQgfCBvcy5PX05PRk9MTE9XIHwgb3MuT19SRFdSLCAwbzYwMClcbiAgICAgICAgZmNudGwuZmxvY2soc2VsZi5sb2NrLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQilcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCAvICdleGVjdXRpb24ubG9jaycpXG4gICAgICAgIGlmIHNlbGYucGF0aC5leGlzdHMoKTpcbiAgICAgICAgICAgIHByaXZhdGUoc2VsZi5wYXRoKVxuICAgICAgICAgICAgc2VsZi5kYXRhID0ganNvbi5sb2FkcyhzZWxmLnBhdGgucmVhZF90ZXh0KCkpXG4gICAgICAgICAgICByZXF1aXJlKHNlbGYuZGF0YVsnaWRlbnRpdHknXSA9PSBpZGVudGl0eSwgJ2pvdXJuYWwgY2FzZS9zb3VyY2UgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgICAgIGVsc2U6XG4gICAgICAgICAgICBzZWxmLmRhdGEgPSB7J2lkZW50aXR5JzogaWRlbnRpdHksICdwaGFzZXMnOiB7fX1cbiAgICAgICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgc2F2ZShzZWxmKTpcbiAgICAgICAgdGVtcG9yYXJ5ID0gc2VsZi5wYXJlbnQgLyAnZXhlY3V0aW9uLWpvdXJuYWwubmV3J1xuICAgICAgICBmZCA9IG9zLm9wZW4odGVtcG9yYXJ5LCBvcy5PX0NSRUFUIHwgb3MuT19FWENMIHwgb3MuT19OT0ZPTExPVyB8IG9zLk9fV1JPTkxZLCAwbzYwMClcbiAgICAgICAgdHJ5OlxuICAgICAgICAgICAgd2l0aCBvcy5mZG9wZW4oZmQsICd3JykgYXMgc3RyZWFtOlxuICAgICAgICAgICAgICAgIGpzb24uZHVtcChzZWxmLmRhdGEsIHN0cmVhbSwgaW5kZW50PTIpXG4gICAgICAgICAgICAgICAgc3RyZWFtLndyaXRlKCdcXG4nKVxuICAgICAgICAgICAgICAgIHN0cmVhbS5mbHVzaCgpXG4gICAgICAgICAgICAgICAgb3MuZnN5bmMoc3RyZWFtLmZpbGVubygpKVxuICAgICAgICAgICAgb3MucmVwbGFjZSh0ZW1wb3JhcnksIHNlbGYucGF0aClcbiAgICAgICAgICAgIGRpcmVjdG9yeSA9IG9zLm9wZW4oc2VsZi5wYXJlbnQsIG9zLk9fRElSRUNUT1JZIHwgb3MuT19SRE9OTFkpXG4gICAgICAgICAgICB0cnk6XG4gICAgICAgICAgICAgICAgb3MuZnN5bmMoZGlyZWN0b3J5KVxuICAgICAgICAgICAgZmluYWxseTpcbiAgICAgICAgICAgICAgICBvcy5jbG9zZShkaXJlY3RvcnkpXG4gICAgICAgIGV4Y2VwdCBCYXNlRXhjZXB0aW9uOlxuICAgICAgICAgICAgIyBSZXRhaW4gZXZpZGVuY2UgcmF0aGVyIHRoYW4gb3ZlcndyaXRpbmcgYW4gdW5jZXJ0YWluIGR1cmFibGUgaW50ZW50LlxuICAgICAgICAgICAgcmFpc2VcblxuICAgIGRlZiBzdGFydChzZWxmLCBwaGFzZSwgYXBwcm92YWwpOlxuICAgICAgICByZXF1aXJlKHBoYXNlIG5vdCBpbiBzZWxmLmRhdGFbJ3BoYXNlcyddLCAnYWxyZWFkeSBhdHRlbXB0ZWQgcGhhc2U7IG5vIHJldHJ5JylcbiAgICAgICAgcHJlZGVjZXNzb3JzID0gZGljdCh6aXAoUEhBU0VTWzE6OF0sIFBIQVNFU1s6N10pKVxuICAgICAgICBwcmVkZWNlc3NvcnNbJ3JvbGxiYWNrLXZlcmlmeSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICBpZiBwaGFzZSBpbiBwcmVkZWNlc3NvcnM6XG4gICAgICAgICAgICByZXF1aXJlKHNlbGYuZGF0YVsncGhhc2VzJ10uZ2V0KHByZWRlY2Vzc29yc1twaGFzZV0sIHt9KS5nZXQoJ3N0YXRlJykgPT0gJ0NPTVBMRVRFJyxcbiAgICAgICAgICAgICAgICAgICAgJ3ByZWNlZGluZyBwaGFzZSBpcyBub3QgdmVyaWZpZWQgY29tcGxldGUnKVxuICAgICAgICBpZiBwaGFzZSA9PSAncm9sbGJhY2snOlxuICAgICAgICAgICAgcmVxdWlyZSgncmVsZWFzZScgaW4gc2VsZi5kYXRhWydwaGFzZXMnXSwgJ3JvbGxiYWNrIHJlcXVpcmVzIGEgcmVjb3JkZWQgcmVsZWFzZSBhdHRlbXB0JylcbiAgICAgICAgc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV0gPSB7J3N0YXRlJzogJ1JVTk5JTkcnLCAnYXBwcm92YWwnOiBhcHByb3ZhbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2F0dGVtcHRfaWQnOiBzdHIodXVpZC51dWlkNCgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0YXJ0ZWRfYXQnOiBkYXRldGltZS5kYXRldGltZS5ub3coZGF0ZXRpbWUudGltZXpvbmUudXRjKS5pc29mb3JtYXQoKX1cbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBub3RlKHNlbGYsIHBoYXNlLCBrZXksIHZhbHVlKTpcbiAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVsnc3RhdGUnXSA9PSAnUlVOTklORycsICdwaGFzZSBpbnRlbnQgbWlzc2luZycpXG4gICAgICAgIHNlbGYuZGF0YVsncGhhc2VzJ11bcGhhc2VdW2tleV0gPSB2YWx1ZVxuICAgICAgICBzZWxmLnNhdmUoKVxuXG4gICAgZGVmIGZpbmlzaChzZWxmLCBwaGFzZSwgcmVzdWx0KTpcbiAgICAgICAgZW50cnkgPSBzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVxuICAgICAgICByZXF1aXJlKGVudHJ5WydzdGF0ZSddID09ICdSVU5OSU5HJywgJ3BoYXNlIGludGVudCBtaXNzaW5nJylcbiAgICAgICAgZW50cnlbJ3Jlc3VsdCddID0gcmVzdWx0XG4gICAgICAgIGVudHJ5WydzdGF0ZSddID0gJ0NPTVBMRVRFJyBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgJ1VOQ0VSVEFJTidcbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBjbG9zZShzZWxmKTpcbiAgICAgICAgb3MuY2xvc2Uoc2VsZi5sb2NrKVxuIgogICAgfSwKICAgICJleGVjdXRpb24tcGxhbi5qc29uIjogewogICAgICAic2hhMjU2IjogImY1ZTVmYTkwNmZmMTlkM2E0NWQxMGRjZGIyODEwMzczYWUyMWY5Y2Y0NGMwNDcyZmYyYmQ0N2QzYmMzMzI4ZDYiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwia2luZFwiOiBcImluZm9ybWVkLWRlY2lzaW9uLnN1cGVydmlzZWQtbWVjaGFuaWNhbC1yZWxlYXNlLXBsYW5cIixcbiAgXCJ2ZXJzaW9uXCI6IDEsXG4gIFwicHJvcG9zYWxfaWRcIjogXCJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MVwiLFxuICBcInRyaWFsX2lkXCI6IFwiaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxXCIsXG4gIFwic3RhdGVcIjogXCJwcmVwYXJlZC11bmFwcHJvdmVkXCIsXG4gIFwiZXhlY3V0b3JfZmlsZXNcIjoge1xuICAgIFwiYWN0dWF0b3IucHlcIjogXCI2YjlkNjQzOTg2MjQ1NGYyNjFlZTc3ZjA1YjI2NTE5ZjgxMDk1OTliMWY2NzA3OGJjNGUxZjdjN2M0MDYxYmE1XCIsXG4gICAgXCJhdXRob3JpdHlfam91cm5hbC5weVwiOiBcIjc0ZDZhOTExNjkyOTZhOTlmYTdkYWMyZDA5MDI1NjcyODBmOTEwYWY3NDM1ODBlYzRiNDU0ZjJhYmY4Mzc0YWFcIixcbiAgICBcIm5hdGl2ZV9wcm9ncmFtLnB5XCI6IFwiMzQ5ZjUxNmE0ZTU1ZjdmYjQ3NDcwMTQ0Y2U3ODFhNjY1ZmIwMDNlYmZmMzgwZDA1NGY2NDJiMjIxMzNkMWNkZVwiLFxuICAgIFwicmVjZWlwdF9zYWZldHkucHlcIjogXCI1YzU0MzczZjJkYzRiMDY0MDA4MjI1YzE4NmVmYjFkNWFmZGVlYzM2ZDE1MzUwYmRhMGExMmRlZDk3NjAyZDFiXCJcbiAgfSxcbiAgXCJjYXNlX2ZpbGVzXCI6IHtcbiAgICBcImNoYW5nZV9ndWFyZC5weVwiOiBcImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmVcIixcbiAgICBcInNxbGl0ZV9yZWFkb25seS5weVwiOiBcImVlZjUzZGQyMzNlZWU3NGMxN2YyMDgyM2JkN2Y1Nzg3YzYwY2FkNzlhYzY0ODAyMWM5NDc5NjQzYzZjZTllMzhcIixcbiAgICBcInByZWZsaWdodC1pbnB1dHMuanNvblwiOiBcIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDZcIixcbiAgICBcInNlYWxlZC1saXZlLWRlcGxveW1lbnQuanNvblwiOiBcImQxOGQyNzA2M2QwNmY1MzVhZTg4NGVhMDFmOTY3NDdmZTMwMTY4NTUxOGFiOTRiMWNiYTA3MmExZTE1MTkzNjJcIixcbiAgICBcInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb25cIjogXCIwNDIzMjdhMDM2ZWQyNTRjZjk1ZGJlYjBjMDU2YWMyNWIwM2E2YTg0NGI5NWEzMzJjOTkyZGYyOTQzNjkxMzY5XCIsXG4gICAgXCJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uXCI6IFwiNzIyYThlMmRjNTJiZWMyMTdiZjk2MGUyM2IyZmRkZmM3YWMyN2QzNDNhYzg3NDM3OTBlMzE4M2RiODFhNmEwZVwiLFxuICAgIFwicm9sbGJhY2stZGVwbG95bWVudC5qc29uXCI6IFwiMzliM2Y0M2JiODRlZjQ5MjFjYzNhMWZiY2RjNDQ0NjEwNzQxZWQ4ODA5MTQ5ZDhmOGYxN2VkODA1ZjI2MjEyMVwiLFxuICAgIFwiY2hlY2tfaW5zdGFsbGVkLnB5XCI6IFwiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZFwiLFxuICAgIFwicHVibGlzaGVkLXZlcmlmaWNhdGlvbi5qc29uXCI6IFwiOGE2NzZjMzhmODlmOWNhNzYyYjhlYmU5NDViNWFjYjkwZDQ3YTRjYjM1MDY5MjY4N2FiYjk4NWJiYjJkOGFlMlwiLFxuICAgIFwic2VjdXJpdHktc3VtbWFyeS5qc29uXCI6IFwiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NFwiXG4gIH0sXG4gIFwib3duZXJfc291cmNlX2ZpbGVzXCI6IHtcbiAgICBcImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uXCI6IFwiOTIzODJhNTZiMzQ5YzNiODk1ZTU4MDZlOTc1MDgyNTI3YmI5OWQxYTAwMTE0MGU2OWQ4NTdlNWIwMzkxZmE1NVwiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uXCI6IFwiMzhiNzhiOWNiZWU1YWRlNzc1MGE1OGQ1MTU2Y2E0YzU3NzMzNTJlOTQ3YWNiMzA0ZWU3MTRiNTllNzQ5Y2ViNFwiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWxcIjogXCIxYmJjZTgxYmM2NzU4NDM0MzU0MTU3Zjg2MDE1MzQzMjBjNWQwMjkwNTg3OTA4ZmQxNWE2ZDI1ZTNmYTU3ZjQ3XCIsXG4gICAgXCJkZXBsb3kvbGlmZWN5Y2xlL3JlZ2lzdHJpZXMuY2FuZGlkYXRlLmpzb25cIjogXCI5YmFkNmRiNWZiYzIxNzhkMzFiMDQxMjAwMTZhNDE4MzBjMzU1MmZiYjllMjUxN2I3MThmOWJiZTg3Y2Y2NDllXCJcbiAgfSxcbiAgXCJjYW5kaWRhdGVfaW1hZ2VcIjogXCJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2FcIixcbiAgXCJwcmlvcl9pbWFnZVwiOiBcImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3M1wiLFxuICBcInNvdXJjZV9yZXZpc2lvblwiOiBcIm11c3QtYmUtZXhhY3QtZmluYWwtb3duZXItSEVBRC13aXRoLWFwcHJvdmVkLWZvdXItR2l0LWJsb2JzXCIsXG4gIFwicGhhc2VzXCI6IFtcbiAgICBcImRyaWxsLWJhY2t1cFwiLFxuICAgIFwiZHJpbGwtY29weVwiLFxuICAgIFwib2ZmbGluZS12ZXJpZnlcIixcbiAgICBcImNsZWFudXAtb2ZmbGluZVwiLFxuICAgIFwiY3V0b3Zlci1iYWNrdXBcIixcbiAgICBcImN1dG92ZXItY29weVwiLFxuICAgIFwicmVsZWFzZVwiLFxuICAgIFwidmVyaWZ5XCIsXG4gICAgXCJyb2xsYmFja1wiLFxuICAgIFwicm9sbGJhY2stdmVyaWZ5XCJcbiAgXSxcbiAgXCJhdXRob3JpemF0aW9uXCI6IFwiZnJlc2ggZXh0ZXJuYWxseSBhdXRoZW50aWNhdGVkIHJvb3QgZml4ZWQtb3JpZ2luIG5hdGl2ZSByZWFkYmFjayBiZWZvcmUgZWFjaCBwaGFzZTsgZXhhY3QgY29uZmlybWVkIHBsYXRmb3JtLXJvb3QgZGlzcG9zaXRpb24gYW5kIGN1cnJlbnQgcGFja2V0IFNIQS9zb3VyY2UgY29tbWl0OyByZWNlaXB0IGJvb2trZWVwaW5nIGlzIG5vdCBhbiBhdXRvbm9tb3VzIHNpZ25lZCBncmFudFwiLFxuICBcImV4ZWN1dGVfYnlcIjogXCIyMDI2LTEwLTEyVDIzOjU5OjU5WlwiLFxuICBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZSxcbiAgXCJuYXRpdmVfZGF0YV9vcl93b3JrbG9hZF9hY3Rpb25fZXhlY3V0ZWRcIjogZmFsc2UsXG4gIFwiZGVhZGxpbmVfc2VtYW50aWNzXCI6IFwiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LlwiXG59XG4iCiAgICB9LAogICAgIm5hdGl2ZV9wcm9ncmFtLnB5IjogewogICAgICAic2hhMjU2IjogIjM0OWY1MTZhNGU1NWY3ZmI0NzQ3MDE0NGNlNzgxYTY2NWZiMDAzZWJmZjM4MGQwNTRmNjQyYjIyMTMzZDFjZGUiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJGaXhlZCByZW1vdGUgc291cmNlLCBwYXNzZWQgb25seSBhZnRlciBleGFjdCBzdXBlcnZpc2VkIGFwcHJvdmFsLlwiXCJcIlxuUFJPR1JBTSA9ICdcXG5pbXBvcnQgY29weSxkYXRldGltZSxoYXNobGliLGpzb24sb3MscmUsc3VicHJvY2VzcyxzeXNcXG5pZiBzeXMuZmxhZ3Mub3B0aW1pemU6cmFpc2UgUnVudGltZUVycm9yKFxcJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkXFwnKVxcbnBheWxvYWQ9anNvbi5sb2FkcyhfX1BBWUxPQURfXylcXG5leGVjKF9fR1VBUkRfXylcXG5waGFzZT1wYXlsb2FkW1xcJ3BoYXNlXFwnXVxcbmlmIHBoYXNlIG5vdCBpbiAoXFwnZHJpbGwtYmFja3VwXFwnLFxcJ2N1dG92ZXItYmFja3VwXFwnLFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnLFxcJ3JlbGVhc2VcXCcsXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrXFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6cmFpc2UgVmFsdWVFcnJvcihcXCdmaXhlZCBuYXRpdmUgcGhhc2UgcmVxdWlyZWRcXCcpXFxuZGVhZGxpbmU9ZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdChcXCcyMDI2LTEwLTEyVDIzOjU5OjU5KzAwOjAwXFwnKVxcbmRlZiByZXF1aXJlKHZhbHVlLHJlYXNvbik6XFxuIGlmIG5vdCB2YWx1ZTpyYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcXG5yZXF1aXJlKGRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpPGRlYWRsaW5lLFxcJ2V4ZWN1dGlvbiB3aW5kb3cgZXhwaXJlZFxcJylcXG5lbnY9eyoqb3MuZW52aXJvbixcXCdLVUJFQ09ORklHXFwnOlxcJy9ldGMvcmFuY2hlci9rM3MvazNzLnlhbWxcXCd9XFxuZGVmIHJ1bihhcmd2LGJvZHk9Tm9uZSx0aW1lb3V0PTkwKTpcXG4gcmV0dXJuIHN1YnByb2Nlc3MucnVuKGFyZ3YsaW5wdXQ9Ym9keSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0aW1lb3V0PXRpbWVvdXQsZW52PWVudilcXG5kZWYgcmVhZChraW5kLG5hbWUsbmFtZXNwYWNlKTpcXG4gcmVzdWx0PXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsa2luZCxuYW1lLFxcJy1uXFwnLG5hbWVzcGFjZSxcXCctb1xcJyxcXCdqc29uXFwnXSlcXG4gcmVxdWlyZShyZXN1bHQucmV0dXJuY29kZT09MCxcXCdmaXhlZCBtZXRhZGF0YSByZWFkIHJlZnVzZWRcXCcpXFxuIHJldHVybiBqc29uLmxvYWRzKHJlc3VsdC5zdGRvdXQpXFxuc2VhbGVkPXBheWxvYWRbXFwnc2VhbGVkXFwnXTsgZGVwZW5kZW5jaWVzPXBheWxvYWRbXFwnZGVwZW5kZW5jaWVzXFwnXVxcbmxpdmU9cmVhZChcXCdkZXBsb3ltZW50XFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbmNtPXJlYWQoXFwnY29uZmlnbWFwXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbnB2Yz1yZWFkKFxcJ3B2Y1xcJyxcXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsZGVwZW5kZW5jaWVzKVxcbmFwcD1yZWFkKFxcJ2FwcGxpY2F0aW9uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ2FyZ29jZFxcJylcXG5yZXF1aXJlKGFwcFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09XFwnNDk5ODY4ZjItZWFiYy00ZGY0LWFlMzEtYjg5Y2U1OGQ3NTBkXFwnLFxcJ0FwcGxpY2F0aW9uIFVJRCBjaGFuZ2VkXFwnKVxcbnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwncmVwb1VSTFxcJ109PVxcJ2h0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uLmdpdFxcJ1xcbiBhbmQgYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwncGF0aFxcJ109PVxcJ2RlcGxveS9saWZlY3ljbGVcXCdcXG4gYW5kIGFwcFtcXCdzcGVjXFwnXVtcXCdkZXN0aW5hdGlvblxcJ109PXtcXCduYW1lc3BhY2VcXCc6XFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnc2VydmVyXFwnOlxcJ2h0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Y1xcJ31cXG4gYW5kIGFwcFtcXCdzcGVjXFwnXS5nZXQoXFwnc3luY1BvbGljeVxcJyx7fSkuZ2V0KFxcJ2F1dG9tYXRlZFxcJykgaXMgTm9uZVxcbiBhbmQgc2V0KGFwcFtcXCdzcGVjXFwnXVtcXCdzb3VyY2VcXCddKT09e1xcJ3JlcG9VUkxcXCcsXFwncGF0aFxcJyxcXCd0YXJnZXRSZXZpc2lvblxcJ30gYW5kIG5vdCBhcHBbXFwnc3BlY1xcJ10uZ2V0KFxcJ3NvdXJjZXNcXCcpLFxcJ0FwcGxpY2F0aW9uIG93bmVyL3Njb3BlIGNoYW5nZWRcXCcpXFxuZXhwZWN0ZWQ9Y29weS5kZWVwY29weShzZWFsZWQpXFxuaWYgcGhhc2U9PVxcJ3ZlcmlmeVxcJzpleHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddPUNBTkRJREFURVxcbmlmIHBoYXNlPT1cXCdyb2xsYmFja1xcJzpcXG4gaW1hZ2U9bGl2ZVtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddXFxuIHJlcXVpcmUoaW1hZ2UgaW4gKEJBU0UsQ0FORElEQVRFKSxcXCdyb2xsYmFjayBpbWFnZSBpcyBvdXRzaWRlIHNhbWUtc2NoZW1hIHBhaXJcXCcpXFxuIGV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109aW1hZ2VcXG5jaGVja19jdXJyZW50KGxpdmUsZXhwZWN0ZWQpXFxuaWYgcGhhc2UhPVxcJ3JvbGxiYWNrXFwnOlxcbiByZXF1aXJlKGxpdmUuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ3JlYWR5UmVwbGljYXNcXCcpPT0xXFxuICBhbmQgbGl2ZVtcXCdzdGF0dXNcXCddLmdldChcXCd1cGRhdGVkUmVwbGljYXNcXCcpPT0xXFxuICBhbmQgbGl2ZVtcXCdzdGF0dXNcXCddLmdldChcXCdvYnNlcnZlZEdlbmVyYXRpb25cXCcpPT1saXZlW1xcJ21ldGFkYXRhXFwnXVtcXCdnZW5lcmF0aW9uXFwnXSxcXCdzZXJ2aWNlIG5vdCBSZWFkeTFcXCcpXFxudGFyZ2V0PXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwndmVyaWZ5XFwnIGVsc2UgXFwnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZlxcJ1xcbmlmIHBoYXNlPT1cXCdyb2xsYmFja1xcJzpyZXF1aXJlKGFwcFtcXCdzcGVjXFwnXVtcXCdzb3VyY2VcXCddW1xcJ3RhcmdldFJldmlzaW9uXFwnXSBpbiAodGFyZ2V0LHBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSksXFwncm9sbGJhY2sgc291cmNlIGlzIG91dHNpZGUgcGFpclxcJylcXG5lbHNlOnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwndGFyZ2V0UmV2aXNpb25cXCddPT10YXJnZXQsXFwndW5leHBlY3RlZCBzb3VyY2UgcGluXFwnKVxcbnJlc3VsdD17XFwncGhhc2VcXCc6cGhhc2UsXFwnYWxsX2NoZWNrc19wYXNzXFwnOkZhbHNlLFxcJ3Jhd19vdXRwdXRfd2l0aGhlbGRcXCc6VHJ1ZSxcXG4gXFwnbmF0aXZlX2FwcHJvdmFsX3ZlcmlmaWVkX2J5X3Jvb3RcXCc6cGF5bG9hZFtcXCdhcHByb3ZhbFxcJ10sXFwnbmF0aXZlX2F1dGhlbnRpY2F0ZWRfZ3JhbnRcXCc6RmFsc2V9XFxudHJ5OlxcbiBpZiBwaGFzZSBpbiAoXFwnZHJpbGwtYmFja3VwXFwnLFxcJ2N1dG92ZXItYmFja3VwXFwnLFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnLFxcJ3JlbGVhc2VcXCcsXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBwb2RsaXN0PXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwncG9kc1xcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctbFxcJyxcXCdhcHAua3ViZXJuZXRlcy5pby9uYW1lPWluZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddKVxcbiAgcmVxdWlyZShwb2RsaXN0LnJldHVybmNvZGU9PTAsXFwncG9kIG1ldGFkYXRhIHF1ZXJ5IHJlZnVzZWRcXCcpXFxuICBwb2RzPVtwIGZvciBwIGluIGpzb24ubG9hZHMocG9kbGlzdC5zdGRvdXQpW1xcJ2l0ZW1zXFwnXSBpZiBub3QgcFtcXCdtZXRhZGF0YVxcJ10uZ2V0KFxcJ2RlbGV0aW9uVGltZXN0YW1wXFwnKV1cXG4gIHJlcXVpcmUobGVuKHBvZHMpPT0xLFxcJ2V4YWN0IHNpbmdsZSBsaXZlIG93bmVyIHBvZCByZXF1aXJlZFxcJyk7cG9kPXBvZHNbMF1cXG4gIHJlcXVpcmUocG9kW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ3BoYXNlXFwnKT09XFwnUnVubmluZ1xcJyBhbmQgbGVuKHBvZFtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXSk9PTFcXG4gICBhbmQgcG9kW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXT09ZXhwZWN0ZWRbXFwnc3BlY1xcJ11bXFwndGVtcGxhdGVcXCddW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXVxcbiAgIGFuZCBsZW4ocG9kW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ2NvbnRhaW5lclN0YXR1c2VzXFwnLFtdKSk9PTFcXG4gICBhbmQgcG9kW1xcJ3N0YXR1c1xcJ11bXFwnY29udGFpbmVyU3RhdHVzZXNcXCddWzBdLmdldChcXCduYW1lXFwnKT09XFwnaW5mb3JtZWQtZGVjaXNpb25cXCdcXG4gICBhbmQgcG9kW1xcJ3N0YXR1c1xcJ11bXFwnY29udGFpbmVyU3RhdHVzZXNcXCddWzBdLmdldChcXCdyZWFkeVxcJykgaXMgVHJ1ZSxcXCdvd25lciBwb2QgcmVhZGluZXNzL2ltYWdlIGNoYW5nZWRcXCcpXFxuICB0ZW1wbGF0ZT1leHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11cXG4gIGNvbnRyb2xsZWQ9c2V0KHRlbXBsYXRlKXx7XFwnaW5pdENvbnRhaW5lcnNcXCcsXFwnaG9zdE5ldHdvcmtcXCcsXFwnaG9zdFBJRFxcJyxcXCdob3N0SVBDXFwnLFxcJ3J1bnRpbWVDbGFzc05hbWVcXCcsXFwnc2hhcmVQcm9jZXNzTmFtZXNwYWNlXFwnfVxcbiAgcmVxdWlyZShhbGwocG9kW1xcJ3NwZWNcXCddLmdldChrZXkpPT10ZW1wbGF0ZS5nZXQoa2V5KSBmb3Iga2V5IGluIGNvbnRyb2xsZWQpLFxcJ2FjdHVhbCBvd25lciBQb2QgY29uZmlndXJhdGlvbiBkcmlmdGVkXFwnKVxcbiAgb3duZXJzPXBvZFtcXCdtZXRhZGF0YVxcJ10uZ2V0KFxcJ293bmVyUmVmZXJlbmNlc1xcJyxbXSk7cmVxdWlyZShsZW4ob3duZXJzKT09MSBhbmQgb3duZXJzWzBdW1xcJ2tpbmRcXCddPT1cXCdSZXBsaWNhU2V0XFwnLFxcJ3BvZCBvd25lciBjaGFpbiBjaGFuZ2VkXFwnKVxcbiAgcnM9cmVhZChcXCdyZXBsaWNhc2V0XFwnLG93bmVyc1swXVtcXCduYW1lXFwnXSxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJylcXG4gIHJlcXVpcmUocnNbXFwnbWV0YWRhdGFcXCddW1xcJ3VpZFxcJ109PW93bmVyc1swXVtcXCd1aWRcXCddIGFuZCBhbnkoby5nZXQoXFwndWlkXFwnKT09c2VhbGVkW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddXFxuICAgYW5kIG8uZ2V0KFxcJ2tpbmRcXCcpPT1cXCdEZXBsb3ltZW50XFwnIGZvciBvIGluIHJzW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnb3duZXJSZWZlcmVuY2VzXFwnLFtdKSksXFwnUmVwbGljYVNldCBvd25lcnNoaXAgY2hhbmdlZFxcJylcXG4gIGlubmVyPXJcIlwiXCJcXG5pbXBvcnQgaGFzaGxpYixqc29uLG9zLHN0YXQsc3VicHJvY2VzcyxzeXNcXG5pZiBzeXMuZmxhZ3Mub3B0aW1pemU6cmFpc2UgUnVudGltZUVycm9yKFxcJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkXFwnKVxcbmV4ZWMoX19SRUFET05MWV9fKVxcbmV4ZWMoX19TQUZFVFlfXylcXG5hY3Rpb249X19BQ1RJT05fXztkYj1cXCcvZGF0YS9wcml2YXRlL3Jldmlldy5zcWxpdGVcXCc7Zm9sZGVyPVxcJy9kYXRhL3ByaXZhdGUvcHVycG9zZS1vdmVybGF5LXIxXFwnXFxuZGVmIHJlcXVpcmUodixyKTpcXG4gaWYgbm90IHY6cmFpc2UgVmFsdWVFcnJvcihyKVxcbnJlcXVpcmUob3MuZ2V0dWlkKCk9PTEwMDAxIGFuZCBvcy5nZXRnaWQoKT09MTAwMDEsXFwnbmF0aXZlIG93bmVyIFVJRC9HSUQgcmVxdWlyZWRcXCcpXFxuZGVmIHByaXZhdGUocCxkaXJlY3Rvcnk9RmFsc2UpOlxcbiBzPW9zLmxzdGF0KHApO3JlcXVpcmUoKHN0YXQuU19JU0RJUihzLnN0X21vZGUpIGlmIGRpcmVjdG9yeSBlbHNlIHN0YXQuU19JU1JFRyhzLnN0X21vZGUpKVxcbiAgYW5kIHMuc3RfdWlkPT0xMDAwMSBhbmQgc3RhdC5TX0lNT0RFKHMuc3RfbW9kZSk9PSgwbzcwMCBpZiBkaXJlY3RvcnkgZWxzZSAwbzYwMClcXG4gIGFuZCAoZGlyZWN0b3J5IG9yIHMuc3Rfbmxpbms9PTEpLFxcJ3ByaXZhdGUgbmF0aXZlIGN1c3RvZHkgcmVxdWlyZWRcXCcpXFxucHJpdmF0ZShcXCcvZGF0YS9wcml2YXRlXFwnLFRydWUpO3ByaXZhdGUoZGIpXFxuYmFzZWxpbmU9Y291bnRzKGluc3BlY3RfcmVhZG9ubHkoZGIpKSAjIE1VU1QgcHJlY2VkZSBhbnkgU3RvcmUvYWRtaW4gb3Blbi5cXG5pZiBhY3Rpb24gaW4gKFxcJ2RyaWxsLWJhY2t1cFxcJyxcXCdjdXRvdmVyLWJhY2t1cFxcJyk6XFxuIHNpemU9b3Muc3RhdChkYikuc3Rfc2l6ZVxcbiBpZiBvcy5wYXRoLmV4aXN0cyhkYitcXCctd2FsXFwnKTpzaXplKz1vcy5zdGF0KGRiK1xcJy13YWxcXCcpLnN0X3NpemVcXG4gdj1vcy5zdGF0dmZzKFxcJy9kYXRhL3ByaXZhdGVcXCcpO2ZyZWU9di5mX2JhdmFpbCp2LmZfZnJzaXplXFxuIHJlcXVpcmUoc2l6ZT4wIGFuZCBzaXplPD01MTIqMTAyNCoqMiBhbmQgZnJlZT49c2l6ZSooMiBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJyBlbHNlIDEpKzE2KjEwMjQqKjIsXFwnYm91bmRlZCBuYXRpdmUgc25hcHNob3QgY2FwYWNpdHkgcmVxdWlyZWRcXCcpXFxuIGlmIGFjdGlvbj09XFwnZHJpbGwtYmFja3VwXFwnOlxcbiAgcmVxdWlyZShub3Qgb3MucGF0aC5sZXhpc3RzKGZvbGRlciksXFwnbmF0aXZlIGNhc2UgZGlyZWN0b3J5IG11c3QgYmUgdW5pcXVlXFwnKVxcbiAgb3MubWtkaXIoZm9sZGVyLDBvNzAwKTtvcy5jaG1vZChmb2xkZXIsMG83MDApXFxuIHByaXZhdGUoZm9sZGVyLFRydWUpXFxuIGZpbGVuYW1lPVxcJ2RyaWxsLnNxbGl0ZVxcJyBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJyBlbHNlIFxcJ2N1dG92ZXIuc3FsaXRlXFwnO291dHB1dD1mb2xkZXIrXFwnL1xcJytmaWxlbmFtZVxcbiByZXF1aXJlKG5vdCBvcy5wYXRoLmxleGlzdHMob3V0cHV0KSxcXCdzbmFwc2hvdCBvdXRwdXQgbXVzdCBiZSB1bmlxdWVcXCcpXFxuIGFkbWluPXN1YnByb2Nlc3MucnVuKFtcXCdpbmZvcm1lZC1kZWNpc2lvbi1hZG1pblxcJyxcXCdiYWNrdXBcXCcsXFwnLS1kYlxcJyxkYixcXCctLW91dHB1dFxcJyxvdXRwdXRdLGNhcHR1cmVfb3V0cHV0PVRydWUsdGV4dD1UcnVlLHRpbWVvdXQ9MTIwKVxcbiByZXF1aXJlKGFkbWluLnJldHVybmNvZGU9PTAgYW5kIGpzb24ubG9hZHMoYWRtaW4uc3Rkb3V0KT09e1xcJ3N0YXR1c1xcJzpcXCdiYWNrZWRfdXBcXCcsXFwnY29uc2lzdGVudF9zbmFwc2hvdFxcJzpUcnVlfSxcXCdiYWNrdXAgY29tcGxldGlvbiBub3QgdmVyaWZpZWQ7IGRvIG5vdCByZXRyeVxcJylcXG4gcHJpdmF0ZShvdXRwdXQpXFxuIGZvciBzdWZmaXggaW4gKFxcJy13YWxcXCcsXFwnLXNobVxcJyk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnc25hcHNob3QgaXMgbm90IGNsb3NlZCBtYWluLWZpbGUgY3VzdG9keVxcJylcXG4gc25hcHNob3Q9Y291bnRzKGluc3BlY3RfcmVhZG9ubHkob3V0cHV0KSlcXG4gc2l6ZT1vcy5zdGF0KG91dHB1dCkuc3Rfc2l6ZTtyZXF1aXJlKDA8c2l6ZTw9NTEyKjEwMjQqKjIsXFwnc25hcHNob3Qgb3V0c2lkZSBib3VuZGVkIGNvcHkgc2l6ZVxcJylcXG4gZGlnZXN0PWhhc2hsaWIuc2hhMjU2KClcXG4gd2l0aCBvcGVuKG91dHB1dCxcXCdyYlxcJykgYXMgc3RyZWFtOlxcbiAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOnN0cmVhbS5yZWFkKDEwMjQqKjIpLGJcXCdcXCcpOmRpZ2VzdC51cGRhdGUoYmxvY2spXFxuIHByaW50KGpzb24uZHVtcHMoe1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZVxcJzpiYXNlbGluZSxcXCdzbmFwc2hvdF9yZWFkb25seVxcJzpzbmFwc2hvdCxcXCdzbmFwc2hvdF9zaGEyNTZcXCc6ZGlnZXN0LmhleGRpZ2VzdCgpLFxcJ3NuYXBzaG90X2J5dGVzXFwnOnNpemUsXFwnc25hcHNob3RfZmlsZVxcJzpmaWxlbmFtZSxcXCduYXRpdmVfcGFyZW50X3ByaXZhdGVcXCc6VHJ1ZSxcXCduYXRpdmVfdWlkXFwnOm9zLmdldHVpZCgpfSkpXFxuZWxpZiBhY3Rpb24gaW4gKFxcJ3ZlcmlmeVxcJyxcXCdyZWxlYXNlXFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuIHByb29mPXtcXCdhbGxfY2hlY2tzX3Bhc3NcXCc6VHJ1ZSxcXCdsaXZlX3JlYWRvbmx5X3NjaGVtYV9pbnRlZ3JpdHlfY291bnRzXFwnOmJhc2VsaW5lLFxcJ2xpdmVfY291bnRzX21heV9pbmNsdWRlX2NvbmN1cnJlbnRfY29tbWl0c1xcJzpUcnVlfVxcbiBpZiBhY3Rpb249PVxcJ3ZlcmlmeVxcJzpcXG4gIGltcG9ydCB1cmxsaWIucmVxdWVzdFxcbiAgbW9kdWxlPVxcJy9vcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weVxcJztpbmZvPW9zLmxzdGF0KG1vZHVsZSlcXG4gIHJlcXVpcmUoc3RhdC5TX0lTUkVHKGluZm8uc3RfbW9kZSkgYW5kIGluZm8uc3RfdWlkPT0wIGFuZCBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKT09MG82NDQsXFwnaW5zdGFsbGVkIHBvbGljeSBtZXRhZGF0YSBkaWZmZXJzXFwnKVxcbiAgd2l0aCBvcGVuKG1vZHVsZSxcXCdyYlxcJykgYXMgc291cmNlOm1vZHVsZV9kaWdlc3Q9aGFzaGxpYi5zaGEyNTYoc291cmNlLnJlYWQoKSkuaGV4ZGlnZXN0KClcXG4gIHJlcXVpcmUobW9kdWxlX2RpZ2VzdD09XFwnOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MlxcJyxcXCdpbnN0YWxsZWQgc291cmNlIG1vZHVsZSBkaWZmZXJzXFwnKVxcbiAgcHVycG9zZT1zdWJwcm9jZXNzLnJ1bihbc3lzLmV4ZWN1dGFibGUsXFwnLVxcJ10saW5wdXQ9X19QVVJQT1NFX18sdGV4dD1UcnVlLGNhcHR1cmVfb3V0cHV0PVRydWUsdGltZW91dD0zMClcXG4gIHJlcXVpcmUocHVycG9zZS5yZXR1cm5jb2RlPT0wLFxcJ2luc3RhbGxlZCBuYXRpdmUtcGxhY2VtZW50IHB1cnBvc2UgY2hlY2tzIGZhaWxlZFxcJylcXG4gIHRlc3RlZD1qc29uLmxvYWRzKHB1cnBvc2Uuc3Rkb3V0KVxcbiAgcmVxdWlyZSh0ZXN0ZWQ9PXtcXCdpbnN0YWxsZWRfaW1hZ2VfcHVycG9zZV92YXJpYW50c1xcJzoxMCxcXCdiaW5kaW5nX2Zvcm1zX2FsbG93ZWRcXCc6MixcXCdhZHZpc29yeV9vcl9tYWxmb3JtZWRfcmVmdXNlZFxcJzo4LFxcJ3N5bnRoZXRpY19vbmx5XFwnOlRydWUsXFwnbmF0aXZlX3Byb3ZpZGVyXFwnOkZhbHNlfSxcXCdwdXJwb3NlIHJlc3VsdCBkaWZmZXJzXFwnKVxcbiAgY2xhc3MgTm9SZWRpcmVjdCh1cmxsaWIucmVxdWVzdC5IVFRQUmVkaXJlY3RIYW5kbGVyKTpcXG4gICBkZWYgcmVkaXJlY3RfcmVxdWVzdChzZWxmLCphcmdzLCoqa3dhcmdzKTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2hlYWx0aCByZWRpcmVjdCByZWZ1c2VkXFwnKVxcbiAgb3BlbmVyPXVybGxpYi5yZXF1ZXN0LmJ1aWxkX29wZW5lcihOb1JlZGlyZWN0KCkpO3N0YXR1c2VzPXt9XFxuICBmb3Igcm91dGUgaW4gKFxcJy9oZWFsdGh6XFwnLFxcJy9yZWFkeXpcXCcpOlxcbiAgIHdpdGggb3BlbmVyLm9wZW4oXFwnaHR0cDovLzEyNy4wLjAuMTo4MDgwXFwnK3JvdXRlLHRpbWVvdXQ9MTApIGFzIHJlc3BvbnNlOlxcbiAgICByZXF1aXJlKHJlc3BvbnNlLnN0YXR1cz09MjAwIGFuZCBsZW4ocmVzcG9uc2UucmVhZCg4MTkzKSk8PTgxOTIsXFwnYm91bmRlZCBoZWFsdGggY2hlY2sgcmVmdXNlZFxcJyk7c3RhdHVzZXNbcm91dGVdPTIwMFxcbiAgcHJvb2YudXBkYXRlKGluc3RhbGxlZF9wdXJwb3NlX2NoZWNrcz10ZXN0ZWQscG9saWN5X3NoYTI1Nj1tb2R1bGVfZGlnZXN0LHBvbGljeV9tb2RlPVxcJzA2NDRcXCcscG9saWN5X3VpZD0wLGhlYWx0aF9zdGF0dXNlcz1zdGF0dXNlcyxuYXRpdmVfcHJvdmlkZXJfcHJvYmU9RmFsc2UpXFxuIHByaW50KGpzb24uZHVtcHMocHJvb2YpKVxcbmVsaWYgYWN0aW9uIGluIChcXCdkcmlsbC1jb3B5XFwnLFxcJ2N1dG92ZXItY29weVxcJyk6XFxuIHByaXZhdGUoZm9sZGVyLFRydWUpO2ZpbGVuYW1lPVxcJ2RyaWxsLnNxbGl0ZVxcJyBpZiBhY3Rpb249PVxcJ2RyaWxsLWNvcHlcXCcgZWxzZSBcXCdjdXRvdmVyLnNxbGl0ZVxcJztvdXRwdXQ9Zm9sZGVyK1xcJy9cXCcrZmlsZW5hbWU7cHJpdmF0ZShvdXRwdXQpXFxuIGZvciBzdWZmaXggaW4gKFxcJy13YWxcXCcsXFwnLXNobVxcJyk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnY2xvc2VkIG1haW4gc25hcHNob3QgcmVxdWlyZWRcXCcpXFxuIHNuYXBzaG90PWNvdW50cyhpbnNwZWN0X3JlYWRvbmx5KG91dHB1dCkpO3NpemU9b3Muc3RhdChvdXRwdXQpLnN0X3NpemU7cmVxdWlyZSgwPHNpemU8PTUxMioxMDI0KioyLFxcJ3NuYXBzaG90IHNpemUgb3V0c2lkZSBib3VuZFxcJylcXG4gZGlnZXN0PWhhc2hsaWIuc2hhMjU2KClcXG4gd2l0aCBvcGVuKG91dHB1dCxcXCdyYlxcJykgYXMgc3RyZWFtOlxcbiAgZm9yIGJsb2NrIGluIGl0ZXIobGFtYmRhOnN0cmVhbS5yZWFkKDEwMjQqKjIpLGJcXCdcXCcpOmRpZ2VzdC51cGRhdGUoYmxvY2spXFxuIHByaW50KGpzb24uZHVtcHMoe1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ3NuYXBzaG90X2ZpbGVcXCc6ZmlsZW5hbWUsXFwnc25hcHNob3RfYnl0ZXNcXCc6c2l6ZSxcXCdzbmFwc2hvdF9zaGEyNTZcXCc6ZGlnZXN0LmhleGRpZ2VzdCgpLFxcJ3NuYXBzaG90X3JlYWRvbmx5XFwnOnNuYXBzaG90fSkpXFxuZWxzZTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2ZpeGVkIG5hdGl2ZSBiYWNrdXAvdmVyaWZ5IHBoYXNlIHJlcXVpcmVkXFwnKVxcblwiXCJcIlxcbiAgIyBTdHJpcCB0aGUgQ0xJIGJyYW5jaDogZXhlYyBvbmx5IHRoZSB2ZXJpZmllZCBzdGRsaWIgZnVuY3Rpb24sIG5ldmVyIFN0b3JlLlxcbiAgcmVhZG9ubHk9cGF5bG9hZFtcXCdyZWFkb25seVxcJ10uc3BsaXQoXCJpZiBfX25hbWVfXyA9PSBcXCdfX21haW5fX1xcJzpcIiwxKVswXVxcbiAgaW5uZXI9aW5uZXIucmVwbGFjZShcXCdfX1JFQURPTkxZX19cXCcscmVwcihyZWFkb25seSkpLnJlcGxhY2UoXFwnX19TQUZFVFlfX1xcJyxyZXByKHBheWxvYWRbXFwncmVjZWlwdF9zYWZldHlcXCddKSkucmVwbGFjZShcXCdfX0FDVElPTl9fXFwnLHJlcHIocGhhc2UpKS5yZXBsYWNlKFxcJ19fUFVSUE9TRV9fXFwnLHJlcHIocGF5bG9hZFtcXCdwdXJwb3NlX2NoZWNrc1xcJ10pKVxcbiAgcD1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnZXhlY1xcJyxcXCctaVxcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxwb2RbXFwnbWV0YWRhdGFcXCddW1xcJ25hbWVcXCddLFxcJy1jXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy0tXFwnLFxcJ3B5dGhvblxcJyxcXCctXFwnXSxpbm5lciwxNTApXFxuICByZXF1aXJlKHAucmV0dXJuY29kZT09MCxcXCduYXRpdmUgcGhhc2Ugb3V0Y29tZSB1bnZlcmlmaWVkOyByYXcgb3V0cHV0IHdpdGhoZWxkLCBkbyBub3QgcmV0cnlcXCcpXFxuICBvdXRjb21lPWpzb24ubG9hZHMocC5zdGRvdXQpO3JlcXVpcmUob3V0Y29tZS5nZXQoXFwnYWxsX2NoZWNrc19wYXNzXFwnKSBpcyBUcnVlLFxcJ25hdGl2ZSBwaGFzZSBnYXRlIHJlZnVzZWRcXCcpXFxuICByZXN1bHQudXBkYXRlKG91dGNvbWUscG9kX25hbWU9cG9kW1xcJ21ldGFkYXRhXFwnXVtcXCduYW1lXFwnXSxwb2RfdWlkPXBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXSlcXG4gaWYgcGhhc2UgaW4gKFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2tcXCcpOlxcbiAgbm9kZV9yZWFkPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwnbm9kZXNcXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pO3JlcXVpcmUobm9kZV9yZWFkLnJldHVybmNvZGU9PTAsXFwnbm9kZSBtZXRhZGF0YSB1bmF2YWlsYWJsZVxcJylcXG4gIG5vZGVzPWpzb24ubG9hZHMobm9kZV9yZWFkLnN0ZG91dClbXFwnaXRlbXNcXCddO3JlcXVpcmUobGVuKG5vZGVzKT09MSxcXCdvbmUgdGFyZ2V0IG5vZGUgcmVxdWlyZWRcXCcpO25vZGU9bm9kZXNbMF1cXG4gIHJlcXVpcmUoYW55KGEuZ2V0KFxcJ2FkZHJlc3NcXCcpPT1cXCc5Mi4yMDUuNjIuMjM5XFwnIGZvciBhIGluIG5vZGVbXFwnc3RhdHVzXFwnXVtcXCdhZGRyZXNzZXNcXCddKSxcXCd0YXJnZXQgbm9kZSBhZGRyZXNzIGNoYW5nZWRcXCcpXFxuICBjb25kaXRpb25zPXtjW1xcJ3R5cGVcXCddOmNbXFwnc3RhdHVzXFwnXSBmb3IgYyBpbiBub2RlW1xcJ3N0YXR1c1xcJ11bXFwnY29uZGl0aW9uc1xcJ119XFxuICByZXF1aXJlKGNvbmRpdGlvbnMuZ2V0KFxcJ1JlYWR5XFwnKT09XFwnVHJ1ZVxcJyBhbmQgYWxsKGNvbmRpdGlvbnMuZ2V0KGspPT1cXCdGYWxzZVxcJyBmb3IgayBpbiAoXFwnTWVtb3J5UHJlc3N1cmVcXCcsXFwnRGlza1ByZXNzdXJlXFwnLFxcJ1BJRFByZXNzdXJlXFwnKSksXFwnbm9kZSB1bmhlYWx0aHkgb3IgcHJlc3N1cmVkXFwnKVxcbiAgZGVzY3JpcHRpb249cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2Rlc2NyaWJlXFwnLFxcJ25vZGVcXCcsbm9kZVtcXCdtZXRhZGF0YVxcJ11bXFwnbmFtZVxcJ11dKTtyZXF1aXJlKGRlc2NyaXB0aW9uLnJldHVybmNvZGU9PTAsXFwnaGVhZHJvb20gY2FwdHVyZSB1bmF2YWlsYWJsZVxcJylcXG4gIHRhYmxlPWRlc2NyaXB0aW9uLnN0ZG91dC5zcGxpdChcXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcJywxKVsxXTtyZXF1ZXN0ZWQ9aW50KHJlLnNlYXJjaChyXFwnY3B1XFxcXHMrKFxcXFxkKyltXFwnLHRhYmxlKS5ncm91cCgxKSk7YWxsb2M9bm9kZVtcXCdzdGF0dXNcXCddW1xcJ2FsbG9jYXRhYmxlXFwnXVtcXCdjcHVcXCddO2NhcGFjaXR5PWludChhbGxvY1s6LTFdKSBpZiBhbGxvYy5lbmRzd2l0aChcXCdtXFwnKSBlbHNlIGludChhbGxvYykqMTAwMFxcbiAgcmVxdWlyZShyZXF1ZXN0ZWQ8PWNhcGFjaXR5LFxcJ1JlY3JlYXRlIHJlcXVlc3RlZCBDUFUgZXhjZWVkcyBjYXBhY2l0eVxcJylcXG4gIHJlcXVpcmUobm90IGFwcC5nZXQoXFwnb3BlcmF0aW9uXFwnKSBhbmQgYXBwLmdldChcXCdzdGF0dXNcXCcse30pLmdldChcXCdvcGVyYXRpb25TdGF0ZVxcJyx7fSkuZ2V0KFxcJ3BoYXNlXFwnKSBub3QgaW4gKFxcJ1J1bm5pbmdcXCcsXFwnVGVybWluYXRpbmdcXCcpLFxcJ2V4aXN0aW5nIEFyZ28gb3BlcmF0aW9uIG11c3QgYmUgc2V0dGxlZFxcJylcXG4gIGRlc3RpbmF0aW9uPXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwncmVsZWFzZVxcJyBlbHNlIFxcJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmZcXCdcXG4gIGJvZHk9Y29weS5kZWVwY29weShwYXlsb2FkW1xcJ2NhbmRpZGF0ZVxcJ10gaWYgcGhhc2U9PVxcJ3JlbGVhc2VcXCcgZWxzZSBwYXlsb2FkW1xcJ3JvbGxiYWNrXFwnXSlcXG4gIGRyeT1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnYXBwbHlcXCcsXFwnLS1kcnktcnVuPXNlcnZlclxcJyxcXCctZlxcJyxcXCctXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddLGpzb24uZHVtcHMoYm9keSkpXFxuICByZXF1aXJlKGRyeS5yZXR1cm5jb2RlPT0wLFxcJ2ZyZXNoIG93bmVyIHNlcnZlciBhZG1pc3Npb24gcmVmdXNlZFxcJylcXG4gIGFkbWl0dGVkPWpzb24ubG9hZHMoZHJ5LnN0ZG91dCk7d2FudGVkPWNvcHkuZGVlcGNvcHkoc2VhbGVkKVxcbiAgd2FudGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFIGlmIHBoYXNlPT1cXCdyZWxlYXNlXFwnIGVsc2UgQkFTRVxcbiAgcmVxdWlyZShwcm9qZWN0aW9uKGFkbWl0dGVkKT09d2FudGVkLFxcJ2RyeS1ydW4gY2hhbmdlZCBhbnl0aGluZyBiZXlvbmQgZXhhY3QgaW1hZ2VcXCcpXFxuICBkaWZmPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdkaWZmXFwnLFxcJy1mXFwnLFxcJy1cXCddLGpzb24uZHVtcHMoYm9keSkpO3JlcXVpcmUoZGlmZi5yZXR1cm5jb2RlIGluICgwLDEpLFxcJ2NsaWVudCBkaWZmIHVuYXZhaWxhYmxlXFwnKVxcbiAgb3BlcmF0aW9uPXtcXCdpbml0aWF0ZWRCeVxcJzp7XFwndXNlcm5hbWVcXCc6XFwnY3VzdG9kaWFuLWNvZGV4XFwnfSxcXCdzeW5jXFwnOntcXCdyZXZpc2lvblxcJzpkZXN0aW5hdGlvbixcXCdwcnVuZVxcJzpGYWxzZSxcXG4gICBcXCdyZXNvdXJjZXNcXCc6W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dfX1cXG4gIHBhdGNoPVt7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS91aWRcXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS9yZXNvdXJjZVZlcnNpb25cXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCdyZXNvdXJjZVZlcnNpb25cXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9zcGVjL3NvdXJjZS90YXJnZXRSZXZpc2lvblxcJyxcXCd2YWx1ZVxcJzphcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ119LFxcbiAgIHtcXCdvcFxcJzpcXCdyZXBsYWNlXFwnLFxcJ3BhdGhcXCc6XFwnL3NwZWMvc291cmNlL3RhcmdldFJldmlzaW9uXFwnLFxcJ3ZhbHVlXFwnOmRlc3RpbmF0aW9ufSxcXG4gICB7XFwnb3BcXCc6XFwnYWRkXFwnLFxcJ3BhdGhcXCc6XFwnL29wZXJhdGlvblxcJyxcXCd2YWx1ZVxcJzpvcGVyYXRpb259XVxcbiAgYXJndj1bXFwna3ViZWN0bFxcJyxcXCdwYXRjaFxcJyxcXCdhcHBsaWNhdGlvblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctblxcJyxcXCdhcmdvY2RcXCcsXFwnLS10eXBlPWpzb25cXCcsXFwnLS1wYXRjaC1maWxlPS9kZXYvc3RkaW5cXCcsXFwnLW9cXCcsXFwnbmFtZVxcJ11cXG4gIHBhdGNoZHJ5PXJ1bihhcmd2K1tcXCctLWRyeS1ydW49c2VydmVyXFwnXSxqc29uLmR1bXBzKHBhdGNoKSk7cmVxdWlyZShwYXRjaGRyeS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIG9wZXJhdGlvbiBkcnktcnVuIHJlZnVzZWRcXCcpXFxuICBjaGFuZ2U9cnVuKGFyZ3YsanNvbi5kdW1wcyhwYXRjaCkpXFxuICByZXF1aXJlKGNoYW5nZS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIHBhdGNoIG91dGNvbWUgYW1iaWd1b3VzOyBkbyBub3QgcmV0cnlcXCcpXFxuICByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1UcnVlLG9wZXJhdGlvbl9yZXF1ZXN0ZWQ9VHJ1ZSxzb3VyY2VfcmV2aXNpb249ZGVzdGluYXRpb24sXFxuICAgcmVzb3VyY2VzPW9wZXJhdGlvbltcXCdzeW5jXFwnXVtcXCdyZXNvdXJjZXNcXCddLHBydW5lPUZhbHNlLHJvbGxvdXRfdmVyaWZpZWQ9RmFsc2UsXFxuICAgbGF0ZXN0X2xpdmVfZGF0YWJhc2VfcmV0YWluZWQ9VHJ1ZSxjbGllbnRfZGlmZl9zaGEyNTY9aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpKVxcbiBpZiBwaGFzZSBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBvcD1hcHAuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ29wZXJhdGlvblN0YXRlXFwnLHt9KTtzeW5jPW9wLmdldChcXCdvcGVyYXRpb25cXCcse30pLmdldChcXCdzeW5jXFwnLHt9KVxcbiAgcmVxdWlyZShvcC5nZXQoXFwncGhhc2VcXCcpPT1cXCdTdWNjZWVkZWRcXCcgYW5kIHN5bmMuZ2V0KFxcJ3JldmlzaW9uXFwnKT09dGFyZ2V0IGFuZCBzeW5jLmdldChcXCdwcnVuZVxcJykgaXMgRmFsc2VcXG4gICBhbmQgc3luYy5nZXQoXFwncmVzb3VyY2VzXFwnKT09W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dLFxcJ2V4YWN0IG5hdGl2ZSBBcmdvIG9wZXJhdGlvbiBjb21wbGV0aW9uIHVudmVyaWZpZWRcXCcpXFxuICByZXF1aXJlKGxpdmVbXFwnc3RhdHVzXFwnXS5nZXQoXFwnb2JzZXJ2ZWRHZW5lcmF0aW9uXFwnKT09bGl2ZVtcXCdtZXRhZGF0YVxcJ11bXFwnZ2VuZXJhdGlvblxcJ10sXFwnY29udHJvbGxlciBnZW5lcmF0aW9uIG5vdCBzZXR0bGVkXFwnKVxcbiAgcmVzdWx0LnVwZGF0ZShuYXRpdmVfcm9sbG91dF92ZXJpZmllZD1UcnVlLGN1cnJlbnRfc2NoZW1hNV9kYXRhYmFzZV9yZXRhaW5lZD1UcnVlLHJlY292ZXJ5X3ZlcmlmaWNhdGlvbj1waGFzZT09XFwncm9sbGJhY2stdmVyaWZ5XFwnKVxcbmV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGVycm9yOlxcbiByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1GYWxzZSxmYWlsdXJlX2NsYXNzPXR5cGUoZXJyb3IpLl9fbmFtZV9fLFxcbiAgZmFpbHVyZT1cXCdmaXhlZCBwaGFzZSBvdXRjb21lIHJlZnVzZWQgb3IgYW1iaWd1b3VzOyByYXcgb3V0cHV0IHdpdGhoZWxkOyBubyByZXRyeVxcJylcXG5wcmludChqc29uLmR1bXBzKHJlc3VsdCkpO3N5cy5leGl0KDAgaWYgcmVzdWx0LmdldChcXCdhbGxfY2hlY2tzX3Bhc3NcXCcpIGlzIFRydWUgZWxzZSAxKVxcbidcbiIKICAgIH0sCiAgICAicGFja2V0LXJlZmluZW1lbnQuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICJlZjM3MGE0OTE0NjhkZjI4NjgzZjMwMDJjYjZlOGJiYjdlNDdiNjVlOGU0ZDAyZmY0ZDA5ZTljMzlmMDIwYzhhIiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJwcmlvcl9yZXZpZXdlZF9wYWNrZXRfbWFuaWZlc3Rfc2hhMjU2XCI6IFwiYjFlM2U2NmJjNDAyM2RjODBjNmVhNTk1NjRjMzU1N2M3NjUzZmIzYzMwN2Y0NmEwNDk5OTdiNzYxOThhOTAzM1wiLFxuICBcImtpbmRcIjogXCJtZWNoYW5pY2FsLWFjdHVhdG9yLXBhY2tldC1yZWZpbmVtZW50LXJlcXVpcmVkLWJlZm9yZS1maXJzdC1odW1hbi1wb3N0XCIsXG4gIFwiY2hhbmdlc1wiOiBbXG4gICAgXCJIYXNoLWJpbmQgYWxsIGV4ZWN1dG9yIGJ5dGVzL2V4ZWN1dGlvbnBsYW4gaW4gYW1lbmRlZDIwZG9jIHBhY2tldCwgcHJlc2VydmUgcHJpb3I3OHBhdGggdGVjaG5pY2FsIHJldmlld3MgYXMgaGlzdG9yeVwiLFxuICAgIFwiUmVxdWlyZSBmcmVzaCByb290IGZpeGVkLW9yaWdpbiBjb25maXJtZWQgZm91bmRlciByZWNlaXB0IGJlZm9yZSBlYWNoIHBoYXNlLCBubyBzaWduZWQgYXV0b25vbW91cyBncmFudFwiLFxuICAgIFwiQmluZCBhbGwgZm91ciBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGFuZCByZWplY3QgQXBwbGljYXRpb24gc291cmNlIG92ZXJyaWRlcyBvciBhdXRvbWF0ZWQ6e31cIixcbiAgICBcIkV4cGxpY2l0IG5ldyBpc29sYXRlZCBvZmZsaW5lIHZvbHVtZSBVSUQwL0NBUF9DSE9XTiBpbml0aWFsaXplciwgbm8gaG9zdC9saXZlUFZDL3Rva2VuL2NvbmZpZyBtb3VudHMsIGJvdW5kZWQ1MTJNaUIgcHJpdmF0ZSBzbmFwc2hvdCBzdHJlYW0gYW5kIG5hbWVkVm9sdW1lIG5vbmNlIG93bmVyc2hpcFwiLFxuICAgIFwiRHVyYWJsZSBwZXItcGhhc2UgUlVOTklORyBiZWZvcmUgYWN0aW9uOyBubyBzYW1lLXBoYXNlIHJldHJpZXMgYWZ0ZXIgZmFpbHVyZXMvY3Jhc2gsIGRpc3RpbmN0IHN1cGVydmlzZWQgc2FtZS1zY2hlbWEgcm9sbGJhY2sgcmV0YWlucyBsYXRlc3REQlwiLFxuICAgIFwiQWN0dWFsIG5hdGl2ZSBwcmUtb3BlbiByZWFkb25seXNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgYmVmb3JlIGJhY2t1cC9hZG1pbiwgYWN0dWFsIFBvZC9DTS9QVkMvc291cmNlIHNlYWxzLCBvZmZsaW5lIHByZS1vcGVuIGNoZWNrIGJlZm9yZSBhZG1pbmluc3BlY3QsIG5hdGl2ZWluc3RhbGxlZDEwc3ludGhldGljcHVycG9zZSBjaGVja3MrYm91bmRlZGxvY2FsaG9zdGhlYWx0aCBhZnRlcmNvbnRyb2xsZXJjb21wbGV0aW9uXCJcbiAgXSxcbiAgXCJ1bmNoYW5nZWRcIjogW1xuICAgIFwiaW1tdXRhYmxlNzYzYyBwdXJwb3Nlb25seSBpbWFnZVwiLFxuICAgIFwiQ29uZmlnTWFwNmMvcnVudGltZS9wb2xpY3kgcGlucy9hdWRpZW5jZXMvY3JlZGVudGlhbHNcIixcbiAgICBcIkRlcGxveW1lbnQtb25seSBtYW51YWxBcmdvIHNjb3BlZCBvcGVyYXRpb24vcHJ1bmVmYWxzZVwiLFxuICAgIFwiZXhpc3RpbmdQVkMvc2luZ2xld3JpdGVyL1JlY3JlYXRlL3NjaGVtYTVcIixcbiAgICBcImV4cGxpY2l0IGluaGVyaXRlZDFmaXhhYmxlTUVEIG93bmVyVDA1IGZvbGxvdy10aHJvdWdoXCJcbiAgXSxcbiAgXCJuYXRpdmVfYWN0aW9uX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICBcImZvdW5kZXJfYXBwcm92YWxcIjogZmFsc2UsXG4gIFwibWVjaGFuaWNhbF9yZXZpZXdfcmVmaW5lbWVudFwiOiB7XG4gICAgXCJvcmlnaW5hbF9tYW5pZmVzdF9zaGEyNTZcIjogXCI2NTNiNjhjMzg5MWMwNjZmNDBkMTA0YmZjNjdhMzVkYTVlNDM2NjA1Y2Q5OWFmZDUyZmJhYzRiNDdhOTU1M2ZlXCIsXG4gICAgXCJhcmNoaXZlXCI6IFwiZXhlY3V0aW9uLWhpc3RvcnkvaW5pdGlhbC02NTNiNjhjM1wiLFxuICAgIFwiZmluZGluZ3NcIjogW1xuICAgICAgXCJyb2xsYmFjayBpbmNvcnJlY3RseSBkZXBlbmRlZCBvbiBSZWFkeSBjYW5kaWRhdGUgYW5kIGRhdGFiYXNlIGV4ZWNcIixcbiAgICAgIFwib2ZmbGluZSBhZG1pbiBsYWNrZWQgcG9zdC1vcGVuIHJlYWRvbmx5IGZ1bGwgcHJvb2YgYW5kIG9yaWdpbmFsIHNuYXBzaG90IFNIQSBjaGVja1wiLFxuICAgICAgXCJhbGwtcGhhc2UgaGVscGVyIGRlYWRsaW5lIHdhcyBub3QgZGlzY2xvc2VkIGJ5IHByaW9yIHVuc3RhcnRlZC1yZWxlYXNlIHBhY2tldCB3b3JkaW5nXCJcbiAgICBdLFxuICAgIFwicmVzb2x2ZWRfYnlcIjogW1xuICAgICAgXCJyb2xsYmFjayBkaXNwYXRjaCBleGNsdWRlcyBQb2QgbWV0YWRhdGEvZXhlYyBlbnRpcmVseTsgc2VwYXJhdGUgcm9sbGJhY2stdmVyaWZ5IHByb3ZlcyByZWNvdmVyZWQgb2xkLWltYWdlL3NjaGVtYTUgREJcIixcbiAgICAgIFwicG9zdC1hZG1pbiBVSUQxMDAwMSByZWFkb25seSBpbnRlZ3JpdHkvc2NoZW1hL2NvdW50IHByb29mIGVxdWFscyBmcm96ZW4gc25hcHNob3Q7IHJldGFpbmVkIG9yaWdpbmFsIFNIQSB1bmNoYW5nZWRcIixcbiAgICAgIFwiZXhwbGljaXQgYWxsLXBoYXNlIGluY2x1ZGluZyByZWNvdmVyeS92ZXJpZmljYXRpb24gZGVhZGxpbmUgYW5kIGZyZXNoLWZvdW5kZXItZGVjaXNpb24gcmVxdWlyZW1lbnQgYmV5b25kIGV4cGlyeVwiXG4gICAgXSxcbiAgICBcInNhbWVfcHJvcG9zYWxfdHJpYWxcIjogdHJ1ZSxcbiAgICBcIm5hdGl2ZV9hY3Rpb25zX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICAgIFwiaHVtYW5fYWNjZXB0YW5jZVwiOiBmYWxzZVxuICB9XG59XG4iCiAgICB9LAogICAgInJlY2VpcHRfc2FmZXR5LnB5IjogewogICAgICAic2hhMjU2IjogIjVjNTQzNzNmMmRjNGIwNjQwMDgyMjVjMTg2ZWZiMWQ1YWZkZWVjMzZkMTUzNTBiZGEwYTEyZGVkOTc2MDJkMWIiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmx5IHN0cnVjdHVyYWwgY291bnQvaGFzaCByZWNlaXB0cyBjYW4gbGVhdmUgdGhlIHByaXZhdGUgZXhlY3V0aW9uIHBoYXNlLlwiXCJcIlxuZGVmIGNvdW50cyh2YWx1ZSk6XG4gICAgaWYgKHNldCh2YWx1ZSkgIT0geydzY2hlbWFfdmVyc2lvbicsICdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJywgJ2ludGVncml0eScsXG4gICAgICAgICAgICAgICAgICAgICAgICdyZWFkX29ubHlfcHJlX29wZW4nLCAnc3RvcmVfY29uc3RydWN0ZWQnfVxuICAgICAgICAgICAgb3IgdmFsdWVbJ3NjaGVtYV92ZXJzaW9uJ10gIT0gNSBvciB2YWx1ZVsnaW50ZWdyaXR5J10gIT0gJ29rJ1xuICAgICAgICAgICAgb3IgdmFsdWVbJ3JlYWRfb25seV9wcmVfb3BlbiddIGlzIG5vdCBUcnVlIG9yIHZhbHVlWydzdG9yZV9jb25zdHJ1Y3RlZCddIGlzIG5vdCBGYWxzZVxuICAgICAgICAgICAgb3Igc2V0KHZhbHVlWydsaWZlY3ljbGUnXSkgIT0geydyZWNvcmRzJywgJ2V2ZW50cycsICdwZW5kaW5nJ31cbiAgICAgICAgICAgIG9yIG5vdCBzZXQodmFsdWVbJ291dGJveCddKSA8PSB7J3BlbmRpbmcnLCAnZGVsaXZlcmVkJywgJ2Jsb2NrZWQnfVxuICAgICAgICAgICAgb3Igbm90IHNldCh2YWx1ZVsnc3VibWlzc2lvbnMnXSkgPD0geydwcmVwYXJlZCcsICdpbl9mbGlnaHQnLCAnY29uZmlybWVkJywgJ3VucmVzb2x2ZWQnfSk6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ2NvdW50LW9ubHkgcmVjZWlwdCBzaGFwZS9zdGF0ZSByZWZ1c2VkOyB2YWx1ZXMgd2l0aGhlbGQnKVxuICAgIGZvciBncm91cCBpbiAoJ2xpZmVjeWNsZScsICdvdXRib3gnLCAnc3VibWlzc2lvbnMnKTpcbiAgICAgICAgaWYgYW55KHR5cGUobnVtYmVyKSBpcyBub3QgaW50IG9yIG51bWJlciA8IDAgb3IgbnVtYmVyID4gMTAqKjEyXG4gICAgICAgICAgICAgICBmb3IgbnVtYmVyIGluIHZhbHVlW2dyb3VwXS52YWx1ZXMoKSk6XG4gICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdjb3VudC1vbmx5IHJlY2VpcHQgdmFsdWVzIHJlZnVzZWQnKVxuICAgIHJldHVybiB2YWx1ZVxuIgogICAgfSwKICAgICJyb290LWF1dGhvcml0eS1yZWNlaXB0LXRlbXBsYXRlLmpzb24iOiB7CiAgICAgICJzaGEyNTYiOiAiMTU5NjZiN2M2ZjA4OGEwMzNiYWYxZmVmODc4ZGRiMzUxZGUyZmEyYWU0NmI1YmM3MTAyNjVlZDE3MmFiMjgxMyIsCiAgICAgICJjb250ZW50IjogIntcbiAgXCJwcm9wb3NhbF9pZFwiOiBcIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxXCIsXG4gIFwibWVtb19pZFwiOiBcImluZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxXCIsXG4gIFwibWVtb192ZXJzaW9uXCI6IDEsXG4gIFwibWVtb19zaGEyNTZcIjogbnVsbCxcbiAgXCJzb3VyY2VfcmV2aXNpb25cIjogbnVsbCxcbiAgXCJhY3RpdmF0aW9uXCI6IFwiUEVORElOR1wiLFxuICBcImF1dGhvcml0eV9tb2RlXCI6IFwiQURNSU5JU1RFUlwiLFxuICBcInRhcmdldFwiOiBcInJlYWxtOmt1YmVybmV0ZXMvcmFpbGlhbmNlMDEvaW5mb3JtZWQtZGVjaXNpb25cIixcbiAgXCJ2ZXJpZmljYXRpb25fbWV0aG9kXCI6IFwicm9vdC1maXhlZC1vcmlnaW4tbmF0aXZlLXJlYWRiYWNrXCIsXG4gIFwicnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50XCI6IGZhbHNlLFxuICBcInZlcmlmaWVkX2F0XCI6IG51bGwsXG4gIFwiYWNjZXB0ZWRfYXRcIjogbnVsbCxcbiAgXCJyZXZpZXdfbWVtb19pZFwiOiBudWxsLFxuICBcImFwcHJvdmFsX2lkXCI6IG51bGwsXG4gIFwiZGlzcG9zaXRpb25faWRcIjogbnVsbCxcbiAgXCJuYXRpdmVfb3V0Y29tZV9zaGEyNTZcIjogbnVsbCxcbiAgXCJleGVjdXRvcl9wbGFuX3NoYTI1NlwiOiBcIjRkNTUzMGU3NDE4ZjYzOGIxMGNjZmYwZTBkOWEwNzI3YWRjNjRhN2YzYTQ1OTA3ZjZkZWI1NzM5YWQyYWRjODVcIlxufVxuIgogICAgfSwKICAgICJ0ZXN0X2V4ZWN1dGlvbi5weSI6IHsKICAgICAgInNoYTI1NiI6ICI5Y2NmNmQ0MjFiZjIwZjBlODM1MGY2NzEzZDZkMWNlZTJiYTE5OWY0ODVkY2FmMjU1OGMzODc0MjFkOWEyYjQ4IiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiU3ludGhldGljIGN1c3RvZHkvdHJhbnNwb3J0IHRlc3RzLiBObyBuYXRpdmUgZGF0YSwgRG9ja2VyIG9yIGNsdXN0ZXIgYWN0aW9uLlwiXCJcIlxuaW1wb3J0IGNvcHlcbmltcG9ydCBkYXRldGltZVxuaW1wb3J0IGlvXG5pbXBvcnQganNvblxuaW1wb3J0IG9zXG5mcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGhcbmltcG9ydCBzdWJwcm9jZXNzXG5pbXBvcnQgc3lzXG5pbXBvcnQgdGVtcGZpbGVcbmltcG9ydCB1bml0dGVzdFxuZnJvbSB1bml0dGVzdC5tb2NrIGltcG9ydCBwYXRjaFxuZnJvbSBjb250ZXh0bGliIGltcG9ydCByZWRpcmVjdF9zdGRvdXRcblxuaW1wb3J0IGFjdHVhdG9yXG5mcm9tIGF1dGhvcml0eV9qb3VybmFsIGltcG9ydCBKb3VybmFsLCBhdXRob3JpdHlcbmZyb20gbmF0aXZlX3Byb2dyYW0gaW1wb3J0IFBST0dSQU1cbmZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuXG5DQVNFID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uL2RvY3MvZXZpZGVuY2UvMjAyNi0xMC0xMS1wdXJwb3NlLWltYWdlLXJlbGVhc2UnKVxuTk9XID0gZGF0ZXRpbWUuZGF0ZXRpbWUoMjAyNiwgMTAsIDExLCAyLCAwLCB0emluZm89ZGF0ZXRpbWUudGltZXpvbmUudXRjKVxuUkVWSVNJT04gPSAnZScgKiA0MFxuQ09VTlQgPSB7J3NjaGVtYV92ZXJzaW9uJzogNSwgJ2ludGVncml0eSc6ICdvaycsICdyZWFkX29ubHlfcHJlX29wZW4nOiBUcnVlLCAnc3RvcmVfY29uc3RydWN0ZWQnOiBGYWxzZSxcbiAgICAgICAgICdsaWZlY3ljbGUnOiB7J3JlY29yZHMnOiAzLCAnZXZlbnRzJzogOCwgJ3BlbmRpbmcnOiAxfSxcbiAgICAgICAgICdvdXRib3gnOiB7J3BlbmRpbmcnOiAyLCAnZGVsaXZlcmVkJzogMTB9LCAnc3VibWlzc2lvbnMnOiB7J2NvbmZpcm1lZCc6IDEsICd1bnJlc29sdmVkJzogMX19XG5cblxuZGVmIGFjY2VwdGVkKCk6XG4gICAgYXBwcm92YWwgPSAnMTExMTExMTEtMTExMS00MTExLTgxMTEtMTExMTExMTExMTExJ1xuICAgIHJldmlldyA9ICdyZXZpZXctMjIyMjIyMjItMjIyMi00MjIyLTgyMjItMjIyMjIyMjIyMjIyJ1xuICAgIGRpc3Bvc2l0aW9uID0gJ2Rpc3AtMzMzMzMzMzMtMzMzMy00MzMzLTgzMzMtMzMzMzMzMzMzMzMzJ1xuICAgIHJlY2VpcHQgPSB7J3Byb3Bvc2FsX2lkJzogJ0lORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxJyxcbiAgICAgICAgICAgICAgICdtZW1vX2lkJzogJ2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxJywgJ21lbW9fdmVyc2lvbic6IDEsXG4gICAgICAgICAgICAgICAnbWVtb19zaGEyNTYnOiAnYScgKiA2NCwgJ3NvdXJjZV9yZXZpc2lvbic6IFJFVklTSU9OLCAnYWN0aXZhdGlvbic6ICdBUFBST1ZFRCcsXG4gICAgICAgICAgICAgICAnYXV0aG9yaXR5X21vZGUnOiAnQURNSU5JU1RFUicsICd0YXJnZXQnOiAncmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbicsXG4gICAgICAgICAgICAgICAndmVyaWZpY2F0aW9uX21ldGhvZCc6ICdyb290LWZpeGVkLW9yaWdpbi1uYXRpdmUtcmVhZGJhY2snLCAncnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50JzogRmFsc2UsXG4gICAgICAgICAgICAgICAndmVyaWZpZWRfYXQnOiAnMjAyNi0xMC0xMVQwMjowMDowMFonLCAnYWNjZXB0ZWRfYXQnOiAnMjAyNi0xMC0xMVQwMTo1OTowMFonLFxuICAgICAgICAgICAgICAgJ3Jldmlld19tZW1vX2lkJzogcmV2aWV3LCAnYXBwcm92YWxfaWQnOiBhcHByb3ZhbCwgJ2Rpc3Bvc2l0aW9uX2lkJzogZGlzcG9zaXRpb259XG4gICAgb3V0Y29tZSA9IHsnbWVtb19pZCc6IHJlY2VpcHRbJ21lbW9faWQnXSwgJ3Jldmlldyc6IHsnbWVtb19pZCc6IHJldmlldywgJ3N0YWxlJzogRmFsc2UsICdpbnRha2Vfc3RhdGUnOiAncmVhZHknfSxcbiAgICAgICAgICAgICAgICdkaXNwb3NpdGlvbnMnOiBbeydhcHByb3ZhbF9pZCc6IE5vbmUsICdzdWJtaXNzaW9uX3N0YXRlJzogJ2NvbmZpcm1lZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGlzcG9zaXRpb24nOiB7J3ZlcmInOiAnYWNjZXB0JywgJ21lbW9fdmVyc2lvbic6IDEsICdtZW1vX2lkJzogcmV2aWV3LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhcHByb3ZhbF9pZCc6IGFwcHJvdmFsLCAnaWQnOiBkaXNwb3NpdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYWN0b3InOiB7J2tpbmQnOiAncGVyc29uJywgJ3N1Yic6ICd1aWQ9cGxhdGZvcm0tcm9vdCxvdT1wZW9wbGUsZGM9bmV0a2luZ2RvbSxkYz1sb2NhbCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhdCc6IHJlY2VpcHRbJ2FjY2VwdGVkX2F0J119fV19XG4gICAgcmV0dXJuIHJlY2VpcHQsIG91dGNvbWVcblxuXG5jbGFzcyBBdXRob3JpdHlBbmRDdXN0b2R5KHVuaXR0ZXN0LlRlc3RDYXNlKTpcbiAgICBkZWYgdGVzdF9leGFjdF9uZXN0ZWRfZm91bmRlcl9yZWNlaXB0X25vdF90b3BfbGV2ZWxfYXBwcm92YWwoc2VsZik6XG4gICAgICAgIHJlY2VpcHQsIG91dGNvbWUgPSBhY2NlcHRlZCgpXG4gICAgICAgIHJlc3VsdCA9IGF1dGhvcml0eShyZWNlaXB0LCBvdXRjb21lLCAnYScgKiA2NCwgUkVWSVNJT04sICdkcmlsbC1iYWNrdXAnLCBOT1cpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydhcHByb3ZhbF9pZCddLCByZWNlaXB0WydhcHByb3ZhbF9pZCddKVxuXG4gICAgZGVmIHRlc3RfcGVuZGluZ19zdGFsZV93cm9uZ19hY3Rvcl92ZXJzaW9uX2FuZF9iaW5kaW5nX3JlZnVzZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSByLCBvOiByLnVwZGF0ZShhY3RpdmF0aW9uPSdQRU5ESU5HJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUobWVtb19zaGEyNTY9J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZShzb3VyY2VfcmV2aXNpb249J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZSh0YXJnZXQ9J290aGVyJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpZWRfYXQ9JzIwMjYtMTAtMTFUMDE6MDA6MDBaJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpY2F0aW9uX21ldGhvZD0nY2FsbGVyLWFzc2VydGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUocnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50PVRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ3JldmlldyddLnVwZGF0ZShzdGFsZT1UcnVlKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydyZXZpZXcnXS51cGRhdGUoaW50YWtlX3N0YXRlPSdwZW5kaW5nJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ11bMF0udXBkYXRlKHN1Ym1pc3Npb25fc3RhdGU9J3VucmVzb2x2ZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydkaXNwb3NpdGlvbnMnXVswXVsnZGlzcG9zaXRpb24nXS51cGRhdGUobWVtb192ZXJzaW9uPTIpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddLnVwZGF0ZShhY3Rvcj17J2tpbmQnOiAnYWdlbnQnLCAnc3ViJzogJ3BsYXRmb3JtLXJvb3QnfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ10uYXBwZW5kKGNvcHkuZGVlcGNvcHkob1snZGlzcG9zaXRpb25zJ11bMF0pKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShyLCBvKVxuICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyZWxlYXNlJywgTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwaXJlZF93aW5kb3dfYW5kX3Vua25vd25fcGhhc2VfcmVmdXNlKHNlbGYpOlxuICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgYXV0aG9yaXR5KHIsIG8sICdhJyAqIDY0LCBSRVZJU0lPTiwgJ2FyYml0cmFyeScsIE5PVylcbiAgICAgICAgbGF0ZSA9IGRhdGV0aW1lLmRhdGV0aW1lKDIwMjYsIDEwLCAxMywgdHppbmZvPWRhdGV0aW1lLnRpbWV6b25lLnV0YylcbiAgICAgICAgclsndmVyaWZpZWRfYXQnXSA9IGxhdGUuaXNvZm9ybWF0KClcbiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyb2xsYmFjaycsIGxhdGUpXG5cbiAgICBkZWYgdGVzdF9kdXJhYmxlX2ludGVudF9wcmVjZWRlc19kaXNwYXRjaF9hbmRfbmV2ZXJfcmV0cmllcyhzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQgPSBQYXRoKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIG9zLmNobW9kKHBhcmVudCwgMG83MDApXG4gICAgICAgICAgICBqb3VybmFsID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICBqb3VybmFsLnN0YXJ0KCdkcmlsbC1iYWNrdXAnLCB7J2FwcHJvdmFsX2lkJzogJ2ZpeHR1cmUnfSlcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoanNvbi5sb2Fkcyhqb3VybmFsLnBhdGgucmVhZF90ZXh0KCkpWydwaGFzZXMnXVsnZHJpbGwtYmFja3VwJ11bJ3N0YXRlJ10sICdSVU5OSU5HJylcbiAgICAgICAgICAgIGpvdXJuYWwuY2xvc2UoKSAgIyBzaW11bGF0ZWQgY3Jhc2ggYmVmb3JlIHJlc3VsdFxuICAgICAgICAgICAgcmVjb3ZlcmVkID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtYmFja3VwJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtY29weScsIHt9KVxuICAgICAgICAgICAgcmVjb3ZlcmVkLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X3BoYXNlX29yZGVyX2FuZF91bmNlcnRhaW5fcmVsZWFzZV9hbGxvd3Nfb25seV9kaXN0aW5jdF9yZWNvdmVyeShzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBvcy5jaG1vZChkaXJlY3RvcnksIDBvNzAwKVxuICAgICAgICAgICAgaiA9IEpvdXJuYWwoZGlyZWN0b3J5LCB7J2Nhc2UnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICBmb3IgcGhhc2UgaW4gYWN0dWF0b3IuUEhBU0VTWzo2XTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KHBoYXNlLCB7fSlcbiAgICAgICAgICAgICAgICBqLmZpbmlzaChwaGFzZSwgeydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlfSlcbiAgICAgICAgICAgIGouc3RhcnQoJ3JlbGVhc2UnLCB7fSlcbiAgICAgICAgICAgIGouZmluaXNoKCdyZWxlYXNlJywgeydhbGxfY2hlY2tzX3Bhc3MnOiBGYWxzZX0pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGouc3RhcnQoJ3JlbGVhc2UnLCB7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgai5zdGFydCgndmVyaWZ5Jywge30pXG4gICAgICAgICAgICBqLnN0YXJ0KCdyb2xsYmFjaycsIHt9KVxuICAgICAgICAgICAgai5maW5pc2goJ3JvbGxiYWNrJywgeydhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlfSlcbiAgICAgICAgICAgIGouY2xvc2UoKVxuXG4gICAgZGVmIHRlc3Rfc2VjcmV0X29yX3Vua25vd25fY2hpbGRfb3V0cHV0X2lzX3dpdGhoZWxkKHNlbGYpOlxuICAgICAgICBmb3IgYm9keSBpbiAoJ25vdC1qc29uJywgJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJ0b2tlblwiOlwicHJpdmF0ZS12YWx1ZVwifScsXG4gICAgICAgICAgICAgICAgICAgICAne1wiYWxsX2NoZWNrc19wYXNzXCI6dHJ1ZSxcInNuYXBzaG90X3JlYWRvbmx5XCI6e1wic2NoZW1hX3ZlcnNpb25cIjo1fX0nKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgYWN0dWF0b3IuanNvbl9yZXN1bHQoc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBib2R5LCAnJykpXG4gICAgICAgIHdyb25nID0gY29weS5kZWVwY29weShDT1VOVClcbiAgICAgICAgd3JvbmdbJ291dGJveCddID0geydwcml2YXRlLXJvdy12YWx1ZSc6IDF9XG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICBjb3VudHMod3JvbmcpXG4gICAgICAgIGNvdW50cyhDT1VOVCkgICMgYmxvY2tlZC91bnJlc29sdmVkIGNvdW50cyBhcmUgbm90IHJlcXVpcmVkIHRvIGJlIHplcm8uXG5cbiAgICBkZWYgdGVzdF9iaW5hcnlfY29weV9pc19ib3VuZGVkX3ByaXZhdGVfYW5kX25ldmVyX2VjaG9lZChzZWxmKTpcbiAgICAgICAgYmxvYiA9IGInc3ludGhldGljIHByaXZhdGUgZml4dHVyZSBieXRlcydcbiAgICAgICAgZGlnZXN0ID0gX19pbXBvcnRfXygnaGFzaGxpYicpLnNoYTI1NihibG9iKS5oZXhkaWdlc3QoKVxuICAgICAgICBtZXRhZGF0YSA9IHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ3NuYXBzaG90X2ZpbGUnOiAnZHJpbGwuc3FsaXRlJywgJ3NuYXBzaG90X2J5dGVzJzogbGVuKGJsb2IpLFxuICAgICAgICAgICAgICAgICAgICAnc25hcHNob3Rfc2hhMjU2JzogZGlnZXN0LCAnc25hcHNob3RfcmVhZG9ubHknOiBDT1VOVCxcbiAgICAgICAgICAgICAgICAgICAgJ3BvZF9uYW1lJzogJ2ZpeHR1cmUtcG9kJywgJ3BvZF91aWQnOiAnZml4dHVyZS11aWQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7J2RyaWxsLWJhY2t1cCc6IHsncmVzdWx0JzogbWV0YWRhdGF9fX19KSgpXG4gICAgICAgIHJlYWxfcG9wZW4gPSBzdWJwcm9jZXNzLlBvcGVuXG4gICAgICAgIGZvciBleHRyYSBpbiAoYicnLCBiJ292ZXJzaXplZCcpOlxuICAgICAgICAgICAgd2l0aCBzZWxmLnN1YlRlc3QoZXh0cmE9ZXh0cmEpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBmb2xkZXI6XG4gICAgICAgICAgICAgICAgb3MuY2htb2QoZm9sZGVyLCAwbzcwMClcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSBpby5TdHJpbmdJTygpXG5cbiAgICAgICAgICAgICAgICBkZWYgY2hpbGQoKmFyZ3MsICoqa3dhcmdzKTpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWxfcG9wZW4oW3N5cy5leGVjdXRhYmxlLCAnLWMnLCAnaW1wb3J0IHN5cztzeXMuc3Rkb3V0LmJ1ZmZlci53cml0ZSgnICsgcmVwcihibG9iICsgZXh0cmEpICsgJyknXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTClcblxuICAgICAgICAgICAgICAgIHdpdGggcGF0Y2gub2JqZWN0KGFjdHVhdG9yLCAnQ1VTVE9EWScsIFBhdGgoZm9sZGVyKSksIHBhdGNoLm9iamVjdChhY3R1YXRvciwgJ3JlbW90ZScsIHJldHVybl92YWx1ZT1tZXRhZGF0YSksIFxcXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRjaCgnc3VicHJvY2Vzcy5Qb3BlbicsIHNpZGVfZWZmZWN0PWNoaWxkKSwgcmVkaXJlY3Rfc3Rkb3V0KG91dHB1dCk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGV4dHJhOlxuICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YXRvci5jb3B5X3NuYXBzaG90KCdkcmlsbC1jb3B5JywgUkVWSVNJT04sIHt9LCBqb3VybmFsKVxuICAgICAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYWN0dWF0b3IuY29weV9zbmFwc2hvdCgnZHJpbGwtY29weScsIFJFVklTSU9OLCB7fSwgam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29mZl9jbHVzdGVyX3ByaXZhdGVfY29weV92ZXJpZmllZCddKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoUGF0aChmb2xkZXIpIC8gJ2RyaWxsLnNxbGl0ZScpLnJlYWRfYnl0ZXMoKSwgYmxvYilcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG91dHB1dC5nZXR2YWx1ZSgpLCAnJylcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKChQYXRoKGZvbGRlcikgLyAnZHJpbGwuc3FsaXRlJykuc3RhdCgpLnN0X21vZGUgJiAwbzc3NywgMG82MDApXG5cbiAgICBkZWYgdGVzdF9yZWNyZWF0ZWRfb2ZmbGluZV92b2x1bWVfY2Fubm90X2JlX2RlbGV0ZWQoc2VsZik6XG4gICAgICAgIGlkZW50aXR5ID0geydOYW1lJzogYWN0dWF0b3IuVk9MVU1FLCAnTGFiZWxzJzogeydub25jZSc6ICdvbGQnfSwgJ0NyZWF0ZWRBdCc6ICdvbGQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7XG4gICAgICAgICAgICAnb2ZmbGluZS12ZXJpZnknOiB7J3Jlc3VsdCc6IHsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknOiBpZGVudGl0eX19fX19KSgpXG4gICAgICAgIGluc3BlY3RlZCA9IFt7KippZGVudGl0eSwgJ0NyZWF0ZWRBdCc6ICdyZWNyZWF0ZWQnfV1cbiAgICAgICAgd2l0aCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdkb2NrZXInLCByZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBqc29uLmR1bXBzKGluc3BlY3RlZCksICcnKSkgYXMgbW9ja2VkOlxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBhY3R1YXRvci5jbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobW9ja2VkLmNhbGxfY291bnQsIDEpXG5cbiAgICBkZWYgdGVzdF9vZmZsaW5lX3Bvc3RfYWRtaW5faW50ZWdyaXR5X2FuZF9vcmlnaW5hbF9oYXNoX2FyZV9yZWNoZWNrZWQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdub25lJywgJ3Bvc3QtaW50ZWdyaXR5JywgJ29yaWdpbmFsLWhhc2gnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgZm9sZGVyPVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChmb2xkZXIsMG83MDApXG4gICAgICAgICAgICAgICAgc25hcHNob3Q9Zm9sZGVyLydkcmlsbC5zcWxpdGUnO3NuYXBzaG90LndyaXRlX2J5dGVzKGIncHJpdmF0ZSBzeW50aGV0aWMgc25hcHNob3QnKTtvcy5jaG1vZChzbmFwc2hvdCwwbzYwMClcbiAgICAgICAgICAgICAgICBkaWdlc3Q9YWN0dWF0b3Iuc2hhKHNuYXBzaG90KVxuICAgICAgICAgICAgICAgIHByaW9yPXsnc25hcHNob3Rfc2hhMjU2JzpkaWdlc3QsJ3NuYXBzaG90X3JlYWRvbmx5JzpDT1VOVH1cbiAgICAgICAgICAgICAgICBqb3VybmFsPXR5cGUoJ0ZpeHR1cmVKb3VybmFsJywoKSx7J2RhdGEnOnsncGhhc2VzJzp7J2RyaWxsLWNvcHknOnsncmVzdWx0Jzpwcmlvcn0sJ29mZmxpbmUtdmVyaWZ5Jzp7J2F0dGVtcHRfaWQnOidub25jZSd9fX0sJ25vdGUnOmxhbWJkYSAqYXJnczpOb25lfSkoKVxuICAgICAgICAgICAgICAgIHJlYWRzPVtdXG4gICAgICAgICAgICAgICAgdm9sdW1lPXsnTmFtZSc6YWN0dWF0b3IuVk9MVU1FLCdMYWJlbHMnOnsnaW5mb3JtZWQtZGVjaXNpb24uY2FzZSc6J2luZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsJ2luZm9ybWVkLWRlY2lzaW9uLnVzZSc6J29mZmxpbmUtcmVzdG9yZS1vbmx5JywnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdCc6J25vbmNlJ30sJ0RyaXZlcic6J2xvY2FsJywnU2NvcGUnOidsb2NhbCcsJ0NyZWF0ZWRBdCc6J2ZpeHR1cmUnLCdPcHRpb25zJzpOb25lfVxuICAgICAgICAgICAgICAgIGRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCAqKmt3YXJncyk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGFyZ3ZbMF09PSdpbmZvJzpib2R5PWpzb24uZHVtcHMoJ2JudC1sYXAwMDEnKVxuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2xzJ106Ym9keT0nJ1xuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2NyZWF0ZSddOmJvZHk9YWN0dWF0b3IuVk9MVU1FXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgYXJndls6Ml09PVsndm9sdW1lJywnaW5zcGVjdCddOmJvZHk9anNvbi5kdW1wcyhbdm9sdW1lXSlcbiAgICAgICAgICAgICAgICAgICAgZWxpZiAnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4nIGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5PWpzb24uZHVtcHMoe2tleTpDT1VOVFtrZXldIGZvciBrZXkgaW4gKCdzY2hlbWFfdmVyc2lvbicsJ2xpZmVjeWNsZScsJ291dGJveCcsJ3N1Ym1pc3Npb25zJyl9KVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgZGVmZWN0PT0nb3JpZ2luYWwtaGFzaCc6c25hcHNob3Qud3JpdGVfYnl0ZXMoYidjaGFuZ2VkIHN5bnRoZXRpYyBvcmlnaW5hbCcpXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgJy0tZW50cnlwb2ludCcgaW4gYXJndiBhbmQgJ3B5dGhvbicgaW4gYXJndjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRzLmFwcGVuZChhcmd2KTtwcm9vZj1jb3B5LmRlZXBjb3B5KENPVU5UKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKHJlYWRzKT09MiBhbmQgZGVmZWN0PT0ncG9zdC1pbnRlZ3JpdHknOnByb29mWydpbnRlZ3JpdHknXT0nY29ycnVwdCdcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk9anNvbi5kdW1wcyhwcm9vZilcbiAgICAgICAgICAgICAgICAgICAgZWxzZTpyYWlzZSBBc3NlcnRpb25FcnJvcigndW5leHBlY3RlZCBvZmZsaW5lIGNvbW1hbmQnKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsMCxib2R5LCcnKVxuICAgICAgICAgICAgICAgIHdpdGggcGF0Y2gub2JqZWN0KGFjdHVhdG9yLCdDVVNUT0RZJyxmb2xkZXIpLHBhdGNoLm9iamVjdChhY3R1YXRvciwnQ0FTRScsQ0FTRSkscGF0Y2gub2JqZWN0KGFjdHVhdG9yLCdkb2NrZXInLHNpZGVfZWZmZWN0PWRvY2tlcikscGF0Y2goJ3N1YnByb2Nlc3MucnVuJyxyZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLDAsJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJwcml2YXRlX2NvcHlfdmVyaWZpZWRcIjp0cnVlfScsJycpKTpcbiAgICAgICAgICAgICAgICAgICAgaWYgZGVmZWN0PT0nbm9uZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ9YWN0dWF0b3Iub2ZmbGluZV92ZXJpZnkoam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydvZmZsaW5lX3Bvc3RfYWRtaW5fcmVhZG9ubHknXSxDT1VOVClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29yaWdpbmFsX3NuYXBzaG90X2hhc2hfdW5jaGFuZ2VkJ10pXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmFjdHVhdG9yLm9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVhZHMpLDIpXG5cblxuY2xhc3MgRml4ZWROYXRpdmVQcm9ncmFtKHVuaXR0ZXN0LlRlc3RDYXNlKTpcbiAgICBkZWYgZml4dHVyZShzZWxmKTpcbiAgICAgICAgc2VhbGVkID0ganNvbi5sb2FkcygoQ0FTRSAvICdzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgbGl2ZSA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKVxuICAgICAgICBsaXZlWydtZXRhZGF0YSddLnVwZGF0ZShnZW5lcmF0aW9uPTQyKVxuICAgICAgICBsaXZlWydzdGF0dXMnXSA9IHsncmVhZHlSZXBsaWNhcyc6IDEsICd1cGRhdGVkUmVwbGljYXMnOiAxLCAnb2JzZXJ2ZWRHZW5lcmF0aW9uJzogNDJ9XG4gICAgICAgIGRlcGVuZGVuY2llcyA9IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLW5hdGl2ZS1kZXBlbmRlbmNpZXMuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBjbSA9IGNvcHkuZGVlcGNvcHkoZGVwZW5kZW5jaWVzWydjb25maWdtYXAnXSlcbiAgICAgICAgY20ucG9wKCdjYW5vbmljYWxfZGF0YV9zaGEyNTYnKVxuICAgICAgICBzZXJ2aWNlID0ganNvbi5sb2FkcygoQ0FTRSAvICdjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgICAgIHNvdXJjZV9zZXJ2aWNlID0ganNvbi5sb2FkcygoQ0FTRS5wYXJlbnRzWzJdIC8gJ2RlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBjbVsnZGF0YSddID0gbmV4dCh4IGZvciB4IGluIHNvdXJjZV9zZXJ2aWNlWydpdGVtcyddIGlmIHhbJ2tpbmQnXSA9PSAnQ29uZmlnTWFwJylbJ2RhdGEnXVxuICAgICAgICBwdmMgPSBjb3B5LmRlZXBjb3B5KGRlcGVuZGVuY2llc1sncHZjJ10pXG4gICAgICAgIHB2Y1snc3RhdHVzJ10gPSB7J3BoYXNlJzogJ0JvdW5kJ31cbiAgICAgICAgYXBwID0geydtZXRhZGF0YSc6IHsndWlkJzogJzQ5OTg2OGYyLWVhYmMtNGRmNC1hZTMxLWI4OWNlNThkNzUwZCcsICdyZXNvdXJjZVZlcnNpb24nOiAnMTcnfSxcbiAgICAgICAgICAgICAgICdzcGVjJzogeydzb3VyY2UnOiB7J3JlcG9VUkwnOiAnaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhdGgnOiAnZGVwbG95L2xpZmVjeWNsZScsICd0YXJnZXRSZXZpc2lvbic6ICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJ30sXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGVzdGluYXRpb24nOiB7J25hbWVzcGFjZSc6ICdpbmZvcm1lZC1kZWNpc2lvbicsICdzZXJ2ZXInOiAnaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjJ319fVxuICAgICAgICBvYmplY3RzID0geydkZXBsb3ltZW50JzogbGl2ZSwgJ2NvbmZpZ21hcCc6IGNtLCAncHZjJzogcHZjLCAnYXBwbGljYXRpb24nOiBhcHB9XG4gICAgICAgIHBheWxvYWQgPSB7J3BoYXNlJzogJ3JlbGVhc2UnLCAnc291cmNlX3JldmlzaW9uJzogUkVWSVNJT04sICdhcHByb3ZhbCc6IHt9LCAnc2VhbGVkJzogc2VhbGVkLFxuICAgICAgICAgICAgICAgICAgICdkZXBlbmRlbmNpZXMnOiBkZXBlbmRlbmNpZXMsICdjYW5kaWRhdGUnOiBzZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICdyb2xsYmFjayc6IGpzb24ubG9hZHMoKENBU0UgLyAncm9sbGJhY2stZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgICAgICdyZWFkb25seSc6IChDQVNFIC8gJ3NxbGl0ZV9yZWFkb25seS5weScpLnJlYWRfdGV4dCgpLCdwdXJwb3NlX2NoZWNrcyc6KENBU0UvJ2NoZWNrX2luc3RhbGxlZC5weScpLnJlYWRfdGV4dCgpLFxuICAgICAgICAgICAgICAgICAgICdyZWNlaXB0X3NhZmV0eSc6IChQYXRoKF9fZmlsZV9fKS5wYXJlbnQgLyAncmVjZWlwdF9zYWZldHkucHknKS5yZWFkX3RleHQoKX1cbiAgICAgICAgcmV0dXJuIG9iamVjdHMsIHBheWxvYWRcblxuICAgIGRlZiBleGVjdXRlX2Zha2Uoc2VsZiwgb2JqZWN0cywgcGF5bG9hZCwgYW1iaWd1b3VzPUZhbHNlLCBzY2hlbWFfcmVmdXNlZD1GYWxzZSk6XG4gICAgICAgIHdyaXRlcyA9IFtdXG4gICAgICAgIGNhbGxzID0gW11cblxuICAgICAgICBkZWYgZmFrZShhcmd2LCBpbnB1dD1Ob25lLCAqKmt3YXJncyk6XG4gICAgICAgICAgICBjYWxscy5hcHBlbmQoYXJndilcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdnZXQnXTpcbiAgICAgICAgICAgICAgICBraW5kID0gYXJndlsyXVxuICAgICAgICAgICAgICAgIGlmIGtpbmQgaW4gb2JqZWN0czpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IG9iamVjdHNba2luZF1cbiAgICAgICAgICAgICAgICBlbGlmIGtpbmQgPT0gJ3BvZHMnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydpdGVtcyc6IFt7J21ldGFkYXRhJzogeyduYW1lJzogJ2ZpeHR1cmUtcG9kJywgJ3VpZCc6ICdwb2QtdWlkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvd25lclJlZmVyZW5jZXMnOiBbeydraW5kJzogJ1JlcGxpY2FTZXQnLCAnbmFtZSc6ICdmaXh0dXJlLXJzJywgJ3VpZCc6ICdycy11aWQnfV19LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BlYyc6IG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3BlYyddWyd0ZW1wbGF0ZSddWydzcGVjJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdGF0dXMnOiB7J3BoYXNlJzogJ1J1bm5pbmcnLCAnY29udGFpbmVyU3RhdHVzZXMnOiBbeyduYW1lJzonaW5mb3JtZWQtZGVjaXNpb24nLCdyZWFkeSc6IFRydWV9XX19XX1cbiAgICAgICAgICAgICAgICBlbGlmIGtpbmQgPT0gJ3JlcGxpY2FzZXQnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydtZXRhZGF0YSc6IHsndWlkJzogJ3JzLXVpZCcsICdvd25lclJlZmVyZW5jZXMnOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7J2tpbmQnOiAnRGVwbG95bWVudCcsICd1aWQnOiBwYXlsb2FkWydzZWFsZWQnXVsnbWV0YWRhdGEnXVsndWlkJ119XX19XG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdub2Rlcyc6XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSB7J2l0ZW1zJzogW3snbWV0YWRhdGEnOiB7J25hbWUnOiAnZml4dHVyZS1ub2RlJ30sICdzdGF0dXMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnYWRkcmVzc2VzJzogW3snYWRkcmVzcyc6ICc5Mi4yMDUuNjIuMjM5J31dLCAnYWxsb2NhdGFibGUnOiB7J2NwdSc6ICc0J30sXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZGl0aW9ucyc6IFt7J3R5cGUnOiBrZXksICdzdGF0dXMnOiAnVHJ1ZScgaWYga2V5ID09ICdSZWFkeScgZWxzZSAnRmFsc2UnfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIGtleSBpbiAoJ1JlYWR5JywgJ01lbW9yeVByZXNzdXJlJywgJ0Rpc2tQcmVzc3VyZScsICdQSURQcmVzc3VyZScpXX19XX1cbiAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICByYWlzZSBBc3NlcnRpb25FcnJvcigndW5leHBlY3RlZCBmaXhlZCBtZXRhZGF0YSByb3V0ZScpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKGJvZHkpLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdleGVjJ106XG4gICAgICAgICAgICAgICAgaWYgc2NoZW1hX3JlZnVzZWQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJycsICd3aXRoaGVsZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKHtcbiAgICAgICAgICAgICAgICAgICAgJ2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdsaXZlX3JlYWRvbmx5X3NjaGVtYV9pbnRlZ3JpdHlfY291bnRzJzogQ09VTlR9KSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnYXBwbHknXTpcbiAgICAgICAgICAgICAgICBhZG1pdHRlZCA9IGNvcHkuZGVlcGNvcHkocGF5bG9hZFsnc2VhbGVkJ10pXG4gICAgICAgICAgICAgICAgYWRtaXR0ZWRbJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSAoYWN0dWF0b3IuSU1BR0UgaWYgcGF5bG9hZFsncGhhc2UnXT09J3JlbGVhc2UnIGVsc2UgcGF5bG9hZFsnc2VhbGVkJ11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCBqc29uLmR1bXBzKGFkbWl0dGVkKSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZGVzY3JpYmUnXTpcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDAsICdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcbiBjcHUgMzQ2MG0gKDg2JSlcXG4nLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdkaWZmJ106XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAxLCAnLWltYWdlOiBiYXNlXFxuK2ltYWdlOiBjYW5kaWRhdGVcXG4nLCAnJylcbiAgICAgICAgICAgIGlmIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdwYXRjaCddOlxuICAgICAgICAgICAgICAgIGlmICctLWRyeS1ydW49c2VydmVyJyBub3QgaW4gYXJndjpcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVzLmFwcGVuZChqc29uLmxvYWRzKGlucHV0KSlcbiAgICAgICAgICAgICAgICAgICAgaWYgYW1iaWd1b3VzOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAxLCAnJywgJ3dpdGhoZWxkJylcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDAsICdhcHBsaWNhdGlvbi5hcmdvcHJvai5pby9pbmZvcm1lZC1kZWNpc2lvblxcbicsICcnKVxuICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgY29tbWFuZCcpXG5cbiAgICAgICAgc291cmNlID0gUFJPR1JBTS5yZXBsYWNlKCdfX1BBWUxPQURfXycsIHJlcHIoanNvbi5kdW1wcyhwYXlsb2FkKSkpLnJlcGxhY2UoXG4gICAgICAgICAgICAnX19HVUFSRF9fJywgcmVwcigoQ0FTRSAvICdjaGFuZ2VfZ3VhcmQucHknKS5yZWFkX3RleHQoKSkpXG4gICAgICAgIG91dHB1dCA9IGlvLlN0cmluZ0lPKClcbiAgICAgICAgd2l0aCBwYXRjaCgnc3VicHJvY2Vzcy5ydW4nLCBzaWRlX2VmZmVjdD1mYWtlKSwgcmVkaXJlY3Rfc3Rkb3V0KG91dHB1dCk6XG4gICAgICAgICAgICB0cnk6XG4gICAgICAgICAgICAgICAgZXhlYyhjb21waWxlKHNvdXJjZSwgJ2ZpeGVkLW5hdGl2ZS1maXh0dXJlJywgJ2V4ZWMnKSwgeydfX25hbWVfXyc6ICdfX2ZpeHR1cmVfXyd9KVxuICAgICAgICAgICAgZXhjZXB0IChWYWx1ZUVycm9yLCBTeXN0ZW1FeGl0KTpcbiAgICAgICAgICAgICAgICBwYXNzXG4gICAgICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKG91dHB1dC5nZXR2YWx1ZSgpKSBpZiBvdXRwdXQuZ2V0dmFsdWUoKSBlbHNlIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2V9XG4gICAgICAgIHJldHVybiByZWNlaXB0LCB3cml0ZXMsIGNhbGxzXG5cbiAgICBkZWYgdGVzdF9vbmx5X2V4aXN0aW5nX2FwcGxpY2F0aW9uX29wZXJhdGlvbl9hbmRfZGVwbG95bWVudF9hcmVfcmVxdWVzdGVkKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0Wydyb2xsb3V0X3ZlcmlmaWVkJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHdyaXRlcyksIDEpXG4gICAgICAgIG9wZXJhdGlvbiA9IHdyaXRlc1swXVstMV1bJ3ZhbHVlJ11cbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShvcGVyYXRpb25bJ3N5bmMnXVsncHJ1bmUnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChvcGVyYXRpb25bJ3N5bmMnXVsncmVzb3VyY2VzJ10sIFtcbiAgICAgICAgICAgIHsnZ3JvdXAnOiAnYXBwcycsICdraW5kJzogJ0RlcGxveW1lbnQnLCAnbmFtZSc6ICdpbmZvcm1lZC1kZWNpc2lvbicsICduYW1lc3BhY2UnOiAnaW5mb3JtZWQtZGVjaXNpb24nfV0pXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShhbnkoJy0tZHJ5LXJ1bj1zZXJ2ZXInIGluIGFyZ3YgYW5kIGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdwYXRjaCddIGZvciBhcmd2IGluIGNhbGxzKSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXNbMF1bMF1bJ3BhdGgnXSwgJy9tZXRhZGF0YS91aWQnKVxuXG4gICAgZGVmIHRlc3Rfc291cmNlX292ZXJyaWRlc19hdXRvbWF0aW9uX2FuZF9jdXN0b2R5X2RyaWZ0X3N0b3BfYmVmb3JlX3dyaXRlKHNlbGYpOlxuICAgICAgICBtdXRhdGlvbnMgPSBbbGFtYmRhIG86IG9bJ2FwcGxpY2F0aW9uJ11bJ21ldGFkYXRhJ10udXBkYXRlKHVpZD0ncmVjcmVhdGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddLnVwZGF0ZShzeW5jUG9saWN5PXsnYXV0b21hdGVkJzoge319KSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydzcGVjJ11bJ3NvdXJjZSddLnVwZGF0ZShrdXN0b21pemU9eydpbWFnZXMnOiBbJ290aGVyJ119KSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydzcGVjJ10udXBkYXRlKHNvdXJjZXM9W3t9XSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snY29uZmlnbWFwJ11bJ21ldGFkYXRhJ10udXBkYXRlKHVpZD0ncmVjcmVhdGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1sncHZjJ11bJ3NwZWMnXS51cGRhdGUodm9sdW1lTmFtZT0ncmVwbGFjZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSBvOiBvWydkZXBsb3ltZW50J11bJ3N0YXR1cyddLnVwZGF0ZShyZWFkeVJlcGxpY2FzPTApXVxuICAgICAgICBmb3IgbXV0YXRlIGluIG11dGF0aW9uczpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KG11dGF0ZT1tdXRhdGUpOlxuICAgICAgICAgICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShvYmplY3RzKVxuICAgICAgICAgICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuXG4gICAgZGVmIHRlc3RfcHJlb3Blbl9zY2hlbWFfcmVmdXNhbF9wcmV2ZW50c19pbWFnZV9vcGVyYXRpb24oc2VsZik6XG4gICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZCwgc2NoZW1hX3JlZnVzZWQ9VHJ1ZSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuXG5cbiAgICBkZWYgdGVzdF9yb2xsYmFja191bnJlYWR5X2NhbmRpZGF0ZV9uZXZlcl9yZWFkc19wb2Rfb3JfZGF0YWJhc2Uoc2VsZik6XG4gICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKVxuICAgICAgICBwYXlsb2FkWydwaGFzZSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddLnVwZGF0ZShyZWFkeVJlcGxpY2FzPTAsIHVwZGF0ZWRSZXBsaWNhcz0wKVxuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSBhY3R1YXRvci5JTUFHRVxuICAgICAgICBvYmplY3RzWydhcHBsaWNhdGlvbiddWydzcGVjJ11bJ3NvdXJjZSddWyd0YXJnZXRSZXZpc2lvbiddID0gUkVWSVNJT05cbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIHNjaGVtYV9yZWZ1c2VkPVRydWUpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0Wydyb2xsb3V0X3ZlcmlmaWVkJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHdyaXRlcyksIDEpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UoYW55KGFyZ3ZbOjJdID09IFsna3ViZWN0bCcsICdleGVjJ10gb3IgYXJndls6M10gPT0gWydrdWJlY3RsJywgJ2dldCcsICdwb2RzJ10gZm9yIGFyZ3YgaW4gY2FsbHMpKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHdyaXRlc1swXVstMV1bJ3ZhbHVlJ11bJ3N5bmMnXVsncmV2aXNpb24nXSwgJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYnKVxuXG4gICAgZGVmIHRlc3Rfcm9sbGJhY2tfc3RpbGxfcmVmdXNlc19jdXN0b2R5X29yX25vbnBhaXJfaW1hZ2VfZHJpZnQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdjbScsICdwdmMnLCAnaW1hZ2UnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpOlxuICAgICAgICAgICAgICAgIG9iamVjdHMsIHBheWxvYWQgPSBzZWxmLmZpeHR1cmUoKTtwYXlsb2FkWydwaGFzZSddID0gJ3JvbGxiYWNrJ1xuICAgICAgICAgICAgICAgIG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3RhdHVzJ11bJ3JlYWR5UmVwbGljYXMnXSA9IDBcbiAgICAgICAgICAgICAgICBpZiBkZWZlY3QgPT0gJ2NtJzpvYmplY3RzWydjb25maWdtYXAnXVsnbWV0YWRhdGEnXVsndWlkJ10gPSAncmVjcmVhdGVkJ1xuICAgICAgICAgICAgICAgIGVsaWYgZGVmZWN0ID09ICdwdmMnOm9iamVjdHNbJ3B2YyddWydzcGVjJ11bJ3ZvbHVtZU5hbWUnXSA9ICdyZXBsYWNlZCdcbiAgICAgICAgICAgICAgICBlbHNlOm9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3BlYyddWyd0ZW1wbGF0ZSddWydzcGVjJ11bJ2NvbnRhaW5lcnMnXVswXVsnaW1hZ2UnXSA9ICdmb3JlaWduLWltYWdlJ1xuICAgICAgICAgICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pO3NlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuICAgIGRlZiB0ZXN0X3JlY292ZXJ5X3ZlcmlmaWNhdGlvbl9pc19zZXBhcmF0ZV9yZWFkeV9vbGRfaW1hZ2Vfc2NoZW1hX3Byb29mKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKCk7cGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjay12ZXJpZnknXG4gICAgICAgIG9iamVjdHNbJ2FwcGxpY2F0aW9uJ11bJ3N0YXR1cyddID0geydvcGVyYXRpb25TdGF0ZSc6IHsncGhhc2UnOiAnU3VjY2VlZGVkJywgJ29wZXJhdGlvbic6IHsnc3luYyc6IHtcbiAgICAgICAgICAgICdyZXZpc2lvbic6ICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJywgJ3BydW5lJzogRmFsc2UsXG4gICAgICAgICAgICAncmVzb3VyY2VzJzogW3snZ3JvdXAnOidhcHBzJywna2luZCc6J0RlcGxveW1lbnQnLCduYW1lJzonaW5mb3JtZWQtZGVjaXNpb24nLCduYW1lc3BhY2UnOidpbmZvcm1lZC1kZWNpc2lvbid9XX19fX1cbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSk7c2VsZi5hc3NlcnRUcnVlKHJlY2VpcHRbJ3JlY292ZXJ5X3ZlcmlmaWNhdGlvbiddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHdyaXRlcywgW10pXG4gICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShhbnkoYXJndls6Ml09PVsna3ViZWN0bCcsJ2V4ZWMnXSBmb3IgYXJndiBpbiBjYWxscykpXG4gICAgICAgIG9iamVjdHNbJ2RlcGxveW1lbnQnXVsnc3RhdHVzJ11bJ3JlYWR5UmVwbGljYXMnXSA9IDBcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMscGF5bG9hZClcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcblxuICAgIGRlZiB0ZXN0X2FtYmlndW91c19wYXRjaF9pc19uZXZlcl9yZXRyaWVkKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIGFtYmlndW91cz1UcnVlKVxuICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuXG5cbmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6XG4gICAgdW5pdHRlc3QubWFpbigpXG4iCiAgICB9LAogICAgInZhbGlkYXRpb24uanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIyNmM1YWNmYTZlMmVmNTkwOWZmOWYzZmM4MTljYTE3NjNiNzlmM2NiNjViM2M0MzM3MWY3OTQ0YTI4NGNkZTI4IiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInRlc3RzXCI6IDE2LFxuICBcInJlc3VsdFwiOiBcInBhc3NlZFwiLFxuICBcInN5bnRoZXRpY190cmFuc3BvcnRfb25seVwiOiB0cnVlLFxuICBcInJlYWxfbmF0aXZlX2RhdGFfcmVhZFwiOiBmYWxzZSxcbiAgXCJuYXRpdmVfYmFja3VwX2V4cG9ydF9yZXN0b3JlX2V4ZWN1dGVkXCI6IGZhbHNlLFxuICBcIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkXCI6IGZhbHNlLFxuICBcImFjdHVhbF9mb3VuZGVyX2FwcHJvdmFsXCI6IGZhbHNlLFxuICBcImxvY2FsX3JlYWRfb25seV9jYXBhYmlsaXR5X2NoZWNrc1wiOiBbXG4gICAgXCJhcmdvY2RDTEkgYWJzZW50LCBleGlzdGluZ0FwcGxpY2F0aW9uLm9wZXJhdGlvbiBwYXRoIHJldGFpbmVkXCIsXG4gICAgXCJEb2NrZXJ1bml4c29ja2V0IGVuZ2luZU5hbWUgYm50LWxhcDAwMVwiXG4gIF0sXG4gIFwiY2FzZV9zb3VyY2VfY29tbWl0X2F0X3ByZXBhcmF0aW9uXCI6IFwiZTAzNTliYyAob3duZXIgb3JpZ2luYWw3OHNvdXJjZTsgZmluYWwgaGVscGVyY29tbWl0IG11c3RiZSBleHBsaWNpdGx5cGlubmVkKVwiLFxuICBcImFkZGl0aW9uYWxfcmVncmVzc2lvbnNcIjogW1xuICAgIFwiUmVhZHkwIGNhbmRpZGF0ZSByb2xsYmFjayBkaXNwYXRjaCBoYXMgbm8gUG9kIG1ldGFkYXRhL0RCIGV4ZWMgYW5kIG9uZSBzY29wZWQgQ0FTIG9wZXJhdGlvblwiLFxuICAgIFwicm9sbGJhY2sgc3RpbGwgcmVmdXNlcyBDTS9QVkMgb3Igbm9ucGFpci1pbWFnZSBkcmlmdFwiLFxuICAgIFwic2VwYXJhdGUgb2xkLWltYWdlIFJlYWR5L3NjaGVtYTUgcmVjb3ZlcnkgcHJvb2ZcIixcbiAgICBcInBvc3QtYWRtaW4gcmVhZG9ubHkgaW50ZWdyaXR5IHJlZnVzYWwgYW5kIG9yaWdpbmFsIHNuYXBzaG90IHRhbXBlciByZWZ1c2FsXCJcbiAgXVxufVxuIgogICAgfQogIH0sCiAgIm5hdGl2ZV9leGVjdXRpb24iOiBmYWxzZQp9Cg==" + "content_base64": "ewogICJraW5kIjogImluZm9ybWVkLWRlY2lzaW9uLnN1cGVydmlzZWQtZXhlY3V0aW9uLXNvdXJjZS1idW5kbGUiLAogICJ2ZXJzaW9uIjogMiwKICAicHJvcG9zYWxfaWQiOiAiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEiLAogICJmaWxlcyI6IHsKICAgICJSRUFETUUubWQiOiB7CiAgICAgICJzaGEyNTYiOiAiNTFiNTZjOGVjMmYzMGFkNjJmNmNkMDk3MzJjMGY3M2RkN2I1ZWJmMjA4MTMyMDIyM2M4NWJiY2JmMDBkMTVhOSIsCiAgICAgICJjb250ZW50IjogIiMgVmVyc2lvbjIgcHJvdGVjdGVkIGV4aXN0aW5nLXNuYXBzaG90IHJlc2N1ZSDigJQgcHJlcGFyZWQsIHVuYXBwcm92ZWRcblxuT3JpZ2luYWwgYXBwcm92ZWQgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCBkcmlsbC1iYWNrdXAsIHRoZW4gZHJpbGwtY29weSBmYWlsZWQgYmVmb3JlIGNyZWF0aW5nIGEgbG9jYWwgc25hcHNob3QuIE9yaWdpbmFsIGpvdXJuYWwgZHJpbGwtY29weSByZW1haW5zIFVOQ0VSVEFJTi4gTWV0YWRhdGEtb25seSBjYXB0dXJlIHByb3ZlcyBleGFjdCB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMCBhbmQgcHJpdmF0ZVNITTMyNzY4LiBTb3VyY2UgY2xvc2VzIFNRTGl0ZSBjb25uZWN0aW9ucyBleHBsaWNpdGx5OyBpbW11dGFibGUgcmVhZHMgYXJlIG9ubHkgZm9yIHRoZSBmcm96ZW4gbWFpbiBzbmFwc2hvdCB3aXRoIGV4YWN0IHByaW9yIGRpZ2VzdC9zaXplL3ByaXZhdGUgaWRlbnRpdHkgYW5kIG5vIFdBTCBmcmFtZXMuIExpdmUgc291cmNlIGFuZCBvZmZsaW5lIHByZS9wb3N0LWFkbWluIHJlYWRzIHJlbWFpbiBtb2RlPXJvL3F1ZXJ5X29ubHkgV0FMLWF3YXJlOyBpbW11dGFibGUgaXMgbmV2ZXIgYSBsaXZlIERCIG9yIHNjaGVtYS1taWdyYXRpb24gc2hvcnRjdXQuIFNpZGVjYXJzIHJlbWFpbiByZXRhaW5lZCwgbmV2ZXIgZGVsZXRlZC9jaGVja3BvaW50ZWQuXG5cbkZyZXNoIGZvdW5kZXIgYWNjZXB0YW5jZSBvZiB0aGUgZXhhY3QgbWVtbyB2ZXJzaW9uMiBpcyByZXF1aXJlZCBiZWZvcmUgYW55IHJlc2N1ZSBvciBjb250aW51YXRpb24uIE9sZCB2ZXJzaW9uMSBhY2NlcHRhbmNlIGNhbm5vdCBwYXNzIGF1dGhvcml0eSBjaGVja3MuIFJvb3QgbXVzdCBmcmVzaGx5IGF1dGhlbnRpY2F0ZSBhY3R1YWwgY29uZmlybWVkIHBlcnNvbi9wbGF0Zm9ybS1yb290IEFDQ0VQVCBhdCB0aGUgZml4ZWQgbmF0aXZlIG9yaWdpbiBiZWZvcmUgZWFjaCBwaGFzZTsgcHJvdGVjdGVkIHJlY2VpcHQgY2hlY2tpbmcgaXMgc3VwZXJ2aXNlZCBib29ra2VlcGluZywgbm90IGFuIGF1dGhlbnRpY2F0ZWQgc2lnbmVkL2F1dG9ub21vdXMgZ3JhbnQuIE5vIG5ldyBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4gaW4gdGhpcyBwcmVwYXJhdGlvbi5cblxuRml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnk7IHJvbGxiYWNrIOKGkiByb2xsYmFjay12ZXJpZnkgb25seSBhZnRlciByZWNvcmRlZCBuZXcgcmVsZWFzZSBhdHRlbXB0LiBOZXcgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24gYW5kIHJlc2N1ZS1leGVjdXRpb24tcjEubG9jayBjb2V4aXN0IHdpdGggdGhlIHVuY2hhbmdlZCBvcmlnaW5hbCBleGVjdXRpb24tam91cm5hbC5qc29uLiBUaGV5IGhhc2gtbGluayBpdHMgZXhhY3Qgb3JpZ2luYWwgYXBwcm92ZWQgaWRlbnRpdHksIENPTVBMRVRFIGJhY2t1cCBhbmQgVU5DRVJUQUlOIGNvcHkgYXR0ZW1wdCBJRHMvcmVzdWx0cy4gTm8gZXh0cmEgb3JpZ2luYWwgcGhhc2Ugb3IgcmVsZWFzZSBpcyBhbGxvd2VkOyBvcmlnaW5hbCBqb3VybmFsIGhhc2ggaXMgY2hlY2tlZCBiZWZvcmUgYW5kIGFmdGVyIGVhY2ggbmV3IHBoYXNlLiBObyBvbGQgZHJpbGwtY29weSByZXRyeS9vdmVyd3JpdGUgb3Igc3ludGhlc2l6ZWQgY29tcGxldGVkIHBoYXNlLlxuXG5CZWZvcmUgcmVzY3VlLCBvcmlnaW5hbCBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgbXVzdCBiZSBhYnNlbnQsIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50LCBhbmQgbG9jYWwgZW5naW5lIGJudC1sYXAwMDEvY3VycmVudCBuYXRpdmUgb2xkaW1hZ2U3ZjUvc291cmNlN2RiL3NlYWxlZERlcGxveW1lbnQrQ00vUFZDL29yaWdpbmFsUG9kVUlEIG11c3QgbWF0Y2guIFRoZSBvbGQgYmFja3VwIGFkbWluIGFscmVhZHkgZXhpdGVkIGFmdGVyIHVuaXF1ZWx5IGNyZWF0aW5nIHRoZSBwcml2YXRlIGZpeGVkIHNuYXBzaG90IHBhdGg7IHRoZSBvbmx5IGxhdGVyIG9yaWdpbmFsIGFjY2VzcyB3YXMgV0FMLWF3YXJlIHJlYWRvbmx5IGluc3BlY3Rpb24sIHdpdGggbm8gc25hcHNob3Qgd3JpdGVyLiBNYWluIGhhc2gsIHByaXZhdGUgaWRlbnRpdGllcyBhbmQgYWJzZW50L3plcm8gV0FMIGFyZSBjaGVja2VkIGJlZm9yZS9hZnRlciBpbW11dGFibGUgaW5zcGVjdGlvbiBhbmQgY29weS4gT3JpZ2luYWwgcHJpdmF0ZSBTSE0gaXMgaW5kZXhpbmcgYW5kIGlzIHJldGFpbmVkIHVuY2hhbmdlZC4gTm9uZW1wdHkgV0FMLCBjaGFuZ2VkIGhhc2gvbWV0YWRhdGEsIG1pc3NpbmcgZmFpbGVkIGpvdXJuYWwsIG1pc3Npbmcgb3JpZ2luIG9yIGFueSB1bnZlcmlmaWVkIG91dGNvbWUgc3RvcHMgcmVzY3VlLiBObyBuZXcgbmF0aXZlIGJhY2t1cCBpcyBtYWRlIGZvciB0aGUgZHJpbGwuIEJpbmFyeSBzbmFwc2hvdCBieXRlcyBmbG93IG9ubHkgaW50byBhIG5ldzA2MDAgbG9jYWxmaWxlLCBuZXZlciBjaGF0L2xvZy9wYWNrZXQuIFNhbWUgcmVzY3VlLXBoYXNlIHJldHJ5IGlzIHJlZnVzZWQgYWZ0ZXIgYW55IGF0dGVtcHRlZCBvdXRjb21lLlxuXG5PZmZsaW5lIHZlcmlmaWNhdGlvbiBleHBsaWNpdGx5IGNvbnN1bWVzIENPTVBMRVRFIGRyaWxsLWNvcHktcmVzY3VlLXIxIHJlc3VsdCwgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGV4YWN0IGlzb2xhdGVkIG5ldy12b2x1bWUgVUlEMC9DQVBfQ0hPV04gaW5pdGlhbGl6ZXIsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHJlYWRvbmx5L2FkbWluL3Bvc3QtYWRtaW4gY2hlY2tzIGFuZCByZXRhaW5lZCBvcmlnaW5hbCBTSEEsIHJlbWFpbnMgYm91bmRlZCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3QvQ1BVMS8xMjhNaSB3aXRoIG5vIGhvc3QvbmF0aXZlUFZDL3J1bnRpbWVjb25maWcvdG9rZW4gbW91bnRzLiBPbmx5IHRoZSBkaXNwb3NhYmxlIGNvcHkgdm9sdW1lIGNhbiBiZSByZW1vdmVkLiBDdXRvdmVyIHNuYXBzaG90IGlzIHRoZSBkaXN0aW5jdCBhbHJlYWR5LXNjb3BlZCBuZXcgY3V0b3Zlci5zcWxpdGU7IHJlc2N1ZSBuZXZlciBvdmVyd3JpdGVzIGRyaWxsLnNxbGl0ZSBvciBjcmVhdGVzIGFub3RoZXIgZHJpbGwgYmFja3VwLlxuXG5Gb3VyIGNvbW1pdHRlZCBvd25lciByZW5kZXIgR2l0IGJsb2JzIGFuZCBoZWxwZXIvY2FzZSBoYXNoZXMgbXVzdCBtYXRjaCBleGFjdCBmaW5hbCBzb3VyY2UgSEVBRC4gTWFudWFsQXBwbGljYXRpb24gcmVqZWN0cyBhbnkgYXV0b21hdGVkIGNvbmZpZ3VyYXRpb24gaW5jbHVkaW5nIHt9IG9yIHNvdXJjZSBvdmVycmlkZXMuIFNvdXJjZS1waW4gQXBwbGljYXRpb24ub3BlcmF0aW9uIHVzZXMgc2VydmVyIGRyeS1ydW4gYW5kIFVJRC9yZXNvdXJjZVZlcnNpb24vc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5L3BydW5lPWZhbHNlOyBubyB3aG9sZS1hcHAgc3luYy4gUm9sbGJhY2sgZGlzcGF0Y2ggaGFzIG5vIGZhaWxpbmctY2FuZGlkYXRlIFBvZC9EQiBkZXBlbmRlbmN5OyBzZXBhcmF0ZSByZWNvdmVyeSBwcm9vZiBjaGVja3Mgb2xkaW1hZ2UgUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9zY2hlbWE1IHJldGFpbmVkbGF0ZXN0REIuIEFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlY292ZXJ5L3ZlcmlmaWNhdGlvbiBtdXN0IGJlZ2luIGJ5MjAyNi0xMC0xMlQyMzo1OTo1OVo7IGFmdGVyIGV4cGlyeSBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBObyBleHBpcnkgY29udHJvbGxlciBvciBpbXBsaWNpdCBleHRlbnNpb24uXG5cbkltYWdlNzYzYy9wb2xpY3k5ZDdjIGFuZCBrbm93biBpbmhlcml0ZWQgZml4YWJsZSBNRURJVU0gcmVtYWluIHVuY2hhbmdlZDsgb3duZXIgVDA1IGR1ZU9jdDE4LiBUZW4gaW5zdGFsbGVkIGNoZWNrcyB1c2Ugc3ludGhldGljIHRyYW5zcG9ydC9uYXRpdmVfcHJvdmlkZXI9ZmFsc2UgYW5kIGRvIG5vdCBmdWxmaWxsIHNlcGFyYXRlIGFjdHVhbC1wcm92aWRlciBUMDQgZ2F0ZS4gUHJlc2VydmUgb3JpZ2luYWwgYWNjZXB0YW5jZS9iYWNrdXAvZmFpbHVyZS9oaXN0b3J5IGluIHRoaXMgc2FtZSB0cmlhbC4gVHdlbnR5LXNpeCBtb2NrZWQvc291cmNlIGV4ZWN1dG9yIHJlZ3Jlc3Npb25zIHBhc3M7IG5vIGFjdHVhbCBEQi9hZG1pbi9uYXRpdmUgY29tbWFuZCBkdXJpbmcgdGVzdHMvcHJlcGFyYXRpb24uXG5cbk5hdGl2ZSBwdWJsaWNhdGlvbiByb3V0ZTogUE9TVCBleGlzdGluZyBzb3VyY2UgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMgd2l0aCBleHBlY3RlZF92ZXJzaW9uMSBhbmQgZXhhY3QgbWVtbzIvZG9jdW1lbnRzL3N1bW1hcnksIHRoZW4gcHVibGljYXRpb25zL3Jldmlldy1yZXF1ZXN0cyB2ZXJzaW9uMi4gRnJlc2ggc291cmNlIHJlYWRiYWNrIG11c3QgcHJvdmUgY3VycmVudHZlcnNpb24xIGlzIHVuYm91bmQgYmVmb3JlIHJldmlzaW9uOyBib3VuZC9kaWZmZXJlbnQgc291cmNlIHN0b3BzLiBJbnRha2UvcmVnaXN0ZXIgcmVmdXNlIHZlcnNpb24yIGFzIGRlc2lnbmVkIGFuZCBhcmUgbm90IHVzZWQuIFJldmlldyBpbnRlZ3JhdGlvbiBjcmVhdGVzIGEgTkVXIHJldmlldy1JRCBhdCBpdHMgb3duIHZlcnNpb24xOyBmb3VuZGVyIGRpc3Bvc2l0aW9uIG1lbW9fdmVyc2lvbjEgYmVsb25ncyB0byB0aGF0IG5ldyByZXZpZXcuIFJvb3QgZnJlc2ggb3V0Y29tZXMgbXVzdCBiZSBxdWVyaWVkIGZvciBTT1VSQ0UgdmVyc2lvbjIsIGV4YWN0IG5ld3Jldmlld0lEL21lbW9TSEEgYW5kIGNvbmZpcm1lZCBuZXN0ZWQgcGVyc29uYXBwcm92YWwuIFJlY2VpcHQgb3V0Y29tZV9xdWVyeSBwaW5zIHRoYXQgc291cmNldmVyc2lvbjIgcm91dGU7IGl0IGRvZXMgbm90IGF1dGhlbnRpY2F0ZSBieSBpdHNlbGYuXG4iCiAgICB9LAogICAgImFjdHVhdG9yLnB5IjogewogICAgICAic2hhMjU2IjogIjg2YjY3ZDFhYmFkNmFmMmE4YzQ5NTI4ZmUxMjVhNWJhYjk0NDk3NWQzZTgwMTgyNmM1MTFlZTg4ODQ2NTcxYjIiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmUgZml4ZWQgc3VwZXJ2aXNlZCBwaGFzZTsgbmV2ZXIgcnVuIHRoaXMgZHVyaW5nIHNvdXJjZSBwcmVwYXJhdGlvbi5cIlwiXCJcbmltcG9ydCBhcmdwYXJzZVxuaW1wb3J0IGhhc2hsaWJcbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHJlXG5pbXBvcnQgc2VsZWN0b3JzXG5pbXBvcnQgc3RhdFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0aW1lXG5cbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KCdvcHRpbWl6ZWQgaW50ZXJwcmV0ZXIgcmVmdXNlZCcpXG5cblBIQVNFUyA9ICgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCAnb2ZmbGluZS12ZXJpZnknLCAnY2xlYW51cC1vZmZsaW5lJyxcbiAgICAgICAgICAnY3V0b3Zlci1iYWNrdXAnLCAnY3V0b3Zlci1jb3B5JywgJ3JlbGVhc2UnLCAndmVyaWZ5JywgJ3JvbGxiYWNrJywgJ3JvbGxiYWNrLXZlcmlmeScpXG5cblxuZGVmIHJlcXVpcmUodmFsdWUsIHJlYXNvbik6XG4gICAgaWYgbm90IHZhbHVlOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcblxuXG5kZWYgc2hhKHBhdGgpOlxuICAgIGRpZ2VzdCA9IGhhc2hsaWIuc2hhMjU2KClcbiAgICB3aXRoIFBhdGgocGF0aCkub3BlbigncmInKSBhcyBzdHJlYW06XG4gICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6XG4gICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJsb2NrKVxuICAgIHJldHVybiBkaWdlc3QuaGV4ZGlnZXN0KClcblxuXG5kZWYgcHJpdmF0ZShwYXRoLCBkaXJlY3Rvcnk9RmFsc2UpOlxuICAgIGluZm8gPSBQYXRoKHBhdGgpLmxzdGF0KClcbiAgICByZXF1aXJlKChzdGF0LlNfSVNESVIoaW5mby5zdF9tb2RlKSBpZiBkaXJlY3RvcnkgZWxzZSBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSlcbiAgICAgICAgICAgIGFuZCBpbmZvLnN0X3VpZCA9PSBvcy5nZXR1aWQoKSBhbmQgc3RhdC5TX0lNT0RFKGluZm8uc3RfbW9kZSkgPT0gKDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxuICAgICAgICAgICAgYW5kIChkaXJlY3Rvcnkgb3IgaW5mby5zdF9ubGluayA9PSAxKSwgJ3ByaXZhdGUgb3duZWQgY3VzdG9keSByZXF1aXJlZCcpXG5cblJPT1QgPSBQYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50XG5DQVNFID0gUk9PVC5wYXJlbnRcbk9XTkVSID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uJylcbkNVU1RPRElBTiA9IFBhdGgoJy9ob21lL3dvcnNjaC90aGUtY3VzdG9kaWFuJylcbkNVU1RPRFkgPSBDVVNUT0RJQU4gLyAnLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjEnXG5TT0NLRVQgPSAndW5peDovLy92YXIvcnVuL2RvY2tlci5zb2NrJ1xuSU1BR0UgPSAnZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhJ1xuVk9MVU1FID0gJ2luZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExJ1xuTUFYX0JZVEVTID0gNTEyICogMTAyNCoqMlxuXG5cbmRlZiBydW4oYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTkwKTpcbiAgICByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndiwgaW5wdXQ9Ym9keSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIGpzb25fcmVzdWx0KHJlc3VsdCk6XG4gICAgdHJ5OlxuICAgICAgICB2YWx1ZSA9IGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcbiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhZmUgcGhhc2UgcmVjZWlwdCB1bmF2YWlsYWJsZTsgb3V0Y29tZSB1bmNlcnRhaW4nKSBmcm9tIE5vbmVcbiAgICByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlID09IDAgYW5kIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIFRydWUsXG4gICAgICAgICAgICAncGhhc2UgZGlkIG5vdCB2ZXJpZnkgY29tcGxldGU7IHJhdyBvdXRwdXQgd2l0aGhlbGQ7IG5vIHJldHJ5JylcbiAgICBwZXJtaXR0ZWQgPSB7J3BoYXNlJywgJ2FsbF9jaGVja3NfcGFzcycsICdyYXdfb3V0cHV0X3dpdGhoZWxkJywgJ25hdGl2ZV9hcHByb3ZhbF92ZXJpZmllZF9ieV9yb290JyxcbiAgICAgICAgICAgICAgICAgJ25hdGl2ZV9hdXRoZW50aWNhdGVkX2dyYW50JywgJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZScsICdzbmFwc2hvdF9yZWFkb25seScsXG4gICAgICAgICAgICAgICAgICdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICduYXRpdmVfcGFyZW50X3ByaXZhdGUnLFxuICAgICAgICAgICAgICAgICAnbmF0aXZlX3VpZCcsICdwb2RfbmFtZScsICdwb2RfdWlkJywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnLFxuICAgICAgICAgICAgICAgICAnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzJywgJ29wZXJhdGlvbl9yZXF1ZXN0ZWQnLCAnc291cmNlX3JldmlzaW9uJyxcbiAgICAgICAgICAgICAgICAgJ3Jlc291cmNlcycsICdwcnVuZScsICdyb2xsb3V0X3ZlcmlmaWVkJywgJ2xhdGVzdF9saXZlX2RhdGFiYXNlX3JldGFpbmVkJyxcbiAgICAgICAgICAgICAgICAgJ2NsaWVudF9kaWZmX3NoYTI1NicsICduYXRpdmVfcm9sbG91dF92ZXJpZmllZCcsICdjdXJyZW50X3NjaGVtYTVfZGF0YWJhc2VfcmV0YWluZWQnLFxuICAgICAgICAgICAgICAgICAncHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJywgJ2luc3RhbGxlZF9wdXJwb3NlX2NoZWNrcycsICdwb2xpY3lfc2hhMjU2JyxcbiAgICAgICAgICAgICAgICAgJ3BvbGljeV9tb2RlJywgJ3BvbGljeV91aWQnLCAnaGVhbHRoX3N0YXR1c2VzJywgJ25hdGl2ZV9wcm92aWRlcl9wcm9iZScsICdyZWNvdmVyeV92ZXJpZmljYXRpb24nfVxuICAgIHJlcXVpcmUoc2V0KHZhbHVlKSA8PSBwZXJtaXR0ZWQsICd1bmV4cGVjdGVkIG91dHB1dCBmaWVsZHMgd2l0aGhlbGQnKVxuICAgIGZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuICAgIGZvciBuYW1lIGluICgnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lJywgJ3NuYXBzaG90X3JlYWRvbmx5JywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIGNvdW50cyh2YWx1ZVtuYW1lXSlcbiAgICBmb3IgbmFtZSBpbiAoJ3NuYXBzaG90X3NoYTI1NicsICdjbGllbnRfZGlmZl9zaGEyNTYnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOV17NjR9JywgdmFsdWVbbmFtZV0pIGlzIG5vdCBOb25lLCAnaW52YWxpZCBvdXRwdXQgZGlnZXN0IHdpdGhoZWxkJylcbiAgICBpZiAnc25hcHNob3RfYnl0ZXMnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHR5cGUodmFsdWVbJ3NuYXBzaG90X2J5dGVzJ10pIGlzIGludCBhbmQgMCA8IHZhbHVlWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAnaW52YWxpZCBvdXRwdXQgc2l6ZSB3aXRoaGVsZCcpXG4gICAgaWYgJ3NuYXBzaG90X2ZpbGUnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHZhbHVlWydzbmFwc2hvdF9maWxlJ10gaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSwgJ2ludmFsaWQgb3V0cHV0IGZpbGUgd2l0aGhlbGQnKVxuICAgIHJldHVybiB2YWx1ZVxuXG5cbmRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTEyMCk6XG4gICAgcmV0dXJuIHJ1bihbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVF0gKyBhcmd2LFxuICAgICAgICAgICAgICAgYm9keT1ib2R5LCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkLCBzbmFwc2hvdF9pZGVudGl0eT1Ob25lKTpcbiAgICAjIEZpeGVkIG1vZHVsZSBpbXBvcnRlZCBvbmx5IGFmdGVyIG1haW4gdmVyaWZpZXMgZXZlcnkgZXhlY3V0b3Igc291cmNlIGhhc2guXG4gICAgZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuICAgIHBheWxvYWQgPSB7J3NuYXBzaG90X2lkZW50aXR5Jzogc25hcHNob3RfaWRlbnRpdHksICdwaGFzZSc6IHBoYXNlLCAnc291cmNlX3JldmlzaW9uJzogcmV2aXNpb24sICdhcHByb3ZhbCc6IGFwcHJvdmVkLFxuICAgICAgICAgICAgICAgJ3NlYWxlZCc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ2RlcGVuZGVuY2llcyc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLW5hdGl2ZS1kZXBlbmRlbmNpZXMuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdjYW5kaWRhdGUnOiBqc29uLmxvYWRzKChDQVNFIC8gJ2NhbmRpZGF0ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdyZWNlaXB0X3NhZmV0eSc6IChST09UIC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCksXG4gICAgICAgICAgICAgICAncHVycG9zZV9jaGVja3MnOiAoQ0FTRSAvICdjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICdyZWFkb25seSc6IChDQVNFIC8gJ3NxbGl0ZV9yZWFkb25seS5weScpLnJlYWRfdGV4dCgpfVxuICAgIHNjcmlwdCA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAnX19HVUFSRF9fJywgcmVwcigoQ0FTRSAvICdjaGFuZ2VfZ3VhcmQucHknKS5yZWFkX3RleHQoKSkpXG4gICAgcmV0dXJuIGpzb25fcmVzdWx0KHJ1bihbJ3NzaCcsICdyYWlsaWFuY2UwMScsICdweXRob24zIC0nXSwgc2NyaXB0LCB0aW1lb3V0PTIwMCkpXG5cblxuZGVmIGNvcHlfc25hcHNob3QocGhhc2UsIHJldmlzaW9uLCBhcHByb3ZlZCwgam91cm5hbCk6XG4gICAgcHJpb3IgPSAoam91cm5hbC5kYXRhWydpZGVudGl0eSddWydyZWNvdmVyeV9hbmNob3InXVsnYmFja3VwX3Jlc3VsdCddXG4gICAgICAgICAgICAgaWYgcGhhc2UgPT0gJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyBlbHNlIGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2N1dG92ZXItYmFja3VwJ11bJ3Jlc3VsdCddKVxuICAgIG1ldGFkYXRhID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIGZvciBrZXkgaW4gKCdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICdzbmFwc2hvdF9yZWFkb25seScpOlxuICAgICAgICByZXF1aXJlKG1ldGFkYXRhW2tleV0gPT0gcHJpb3Jba2V5XSwgJ2Nsb3NlZCBmcm96ZW4gc25hcHNob3QgY2hhbmdlZCcpXG4gICAgbmFtZSA9IG1ldGFkYXRhWydzbmFwc2hvdF9maWxlJ11cbiAgICByZXF1aXJlKG5hbWUgaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSBhbmQgMCA8IG1ldGFkYXRhWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICdmaXhlZCBib3VuZGVkIHNuYXBzaG90IHJlcXVpcmVkJylcbiAgICBwb2QgPSBtZXRhZGF0YVsncG9kX25hbWUnXVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtejAtOV0oWy1hLXowLTldKlthLXowLTldKT8nLCBwb2QpIGlzIG5vdCBOb25lLCAnZml4ZWQgb3duZXIgcG9kIG5hbWUgcmVxdWlyZWQnKVxuICAgIGxvY2FsID0gQ1VTVE9EWSAvIG5hbWVcbiAgICBmZCA9IG9zLm9wZW4obG9jYWwsIG9zLk9fV1JPTkxZIHwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1csIDBvNjAwKVxuICAgICMgQmluYXJ5IHNuYXBzaG90IHN0ZG91dCBnb2VzIG9ubHkgdG8gYSBwcml2YXRlIGZpbGUsIG5ldmVyIHRvb2wvY2hhdC9sb2cgb3V0cHV0LlxuICAgICMgU25hcHNob3Qgc2NoZW1hL2NvdW50IG1ldGFkYXRhIHdhcyB2YWxpZGF0ZWQgYmVmb3JlIG9wZW5pbmcgdGhpcyBkZXN0aW5hdGlvbi5cbiAgICB3aXRoIG9zLmZkb3BlbihmZCwgJ3diJykgYXMgZGVzdGluYXRpb246XG4gICAgICAgIGNvbW1hbmQgPSAoJ2t1YmVjdGwgZXhlYyAtbiBpbmZvcm1lZC1kZWNpc2lvbiAnICsgcG9kICtcbiAgICAgICAgICAgICAgICAgICAnIC1jIGluZm9ybWVkLWRlY2lzaW9uIC0tIGNhdCAvZGF0YS9wcml2YXRlL3B1cnBvc2Utb3ZlcmxheS1yMS8nICsgbmFtZSlcbiAgICAgICAgdHJhbnNmZXIgPSBzdWJwcm9jZXNzLlBvcGVuKFsnc3NoJywgJ3JhaWxpYW5jZTAxJywgY29tbWFuZF0sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRlcnI9c3VicHJvY2Vzcy5ERVZOVUxMKVxuICAgICAgICBzZWxlY3RvciA9IHNlbGVjdG9ycy5EZWZhdWx0U2VsZWN0b3IoKVxuICAgICAgICBzZWxlY3Rvci5yZWdpc3Rlcih0cmFuc2Zlci5zdGRvdXQsIHNlbGVjdG9ycy5FVkVOVF9SRUFEKVxuICAgICAgICBkZWFkbGluZSA9IHRpbWUubW9ub3RvbmljKCkgKyAxNTBcbiAgICAgICAgcmVjZWl2ZWQgPSAwXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdoaWxlIFRydWU6XG4gICAgICAgICAgICAgICAgcmVtYWluaW5nID0gZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZW1haW5pbmcgPiAwIGFuZCBzZWxlY3Rvci5zZWxlY3QocmVtYWluaW5nKSwgJ3ByaXZhdGUgdHJhbnNmZXIgdGltZWQgb3V0JylcbiAgICAgICAgICAgICAgICBibG9jayA9IG9zLnJlYWQodHJhbnNmZXIuc3Rkb3V0LmZpbGVubygpLCAxMDI0KioyKVxuICAgICAgICAgICAgICAgIGlmIG5vdCBibG9jazpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICByZWNlaXZlZCArPSBsZW4oYmxvY2spXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZWNlaXZlZCA8PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXSBhbmQgcmVjZWl2ZWQgPD0gTUFYX0JZVEVTLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3ByaXZhdGUgY29weSBleGNlZWRzIGZyb3plbiBzbmFwc2hvdCBzaXplJylcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbi53cml0ZShibG9jaylcbiAgICAgICAgICAgIHRyYW5zZmVyLndhaXQodGltZW91dD1tYXgoMSwgZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpKSlcbiAgICAgICAgZmluYWxseTpcbiAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKClcbiAgICAgICAgICAgIHRyYW5zZmVyLnN0ZG91dC5jbG9zZSgpXG4gICAgICAgICAgICBpZiB0cmFuc2Zlci5wb2xsKCkgaXMgTm9uZTpcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci5raWxsKClcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci53YWl0KClcbiAgICAgICAgZGVzdGluYXRpb24uZmx1c2goKVxuICAgICAgICBvcy5mc3luYyhkZXN0aW5hdGlvbi5maWxlbm8oKSlcbiAgICBwcml2YXRlKGxvY2FsKVxuICAgIHJlcXVpcmUodHJhbnNmZXIucmV0dXJuY29kZSA9PSAwIGFuZCBsb2NhbC5zdGF0KCkuc3Rfc2l6ZSA9PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIHNoYShsb2NhbCkgPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLCAncHJpdmF0ZSBjb3B5IGluY29tcGxldGUvdW5jZXJ0YWluOyByZXRhaW4sIG5vIHJldHJ5JylcbiAgICAjIFJlLXJlYWQgaWRlbnRpdHkvaGFzaCBhZnRlciB0cmFuc2Zlci4gVGhpcyBpcyB2ZXJpZmljYXRpb24sIG5vdCBhIHdyaXRlIHJldHJ5LlxuICAgIGFmdGVyID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIHJlcXVpcmUoYWZ0ZXJbJ3BvZF91aWQnXSA9PSBtZXRhZGF0YVsncG9kX3VpZCddIGFuZCBhZnRlclsnc25hcHNob3Rfc2hhMjU2J10gPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLFxuICAgICAgICAgICAgJ3NvdXJjZSBpZGVudGl0eS9zbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyB0cmFuc2ZlcicpXG4gICAgcmV0dXJuIHsqKm1ldGFkYXRhLCAnb2ZmX2NsdXN0ZXJfcHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJzogVHJ1ZSwgJ3NuYXBzaG90X2NvbnRlbnRzX291dHB1dCc6IEZhbHNlfVxuXG5cbmRlZiBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKTpcbiAgICBmcm9tIHJlY2VpcHRfc2FmZXR5IGltcG9ydCBjb3VudHNcbiAgICBzbmFwc2hvdCA9IENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJ1xuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcHJldmlvdXMgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydyZXN1bHQnXVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdwcm90ZWN0ZWQgc25hcHNob3QgYnl0ZXMgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgcmVxdWlyZShpZGVudGl0eS5yZXR1cm5jb2RlID09IDAgYW5kIGpzb24ubG9hZHMoaWRlbnRpdHkuc3Rkb3V0KSA9PSAnYm50LWxhcDAwMScsXG4gICAgICAgICAgICAnbG9jYWwgb2ZmbGluZSBEb2NrZXIgZW5naW5lIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICByZXF1aXJlKGxpc3RlZC5yZXR1cm5jb2RlID09IDAgYW5kIFZPTFVNRSBub3QgaW4gbGlzdGVkLnN0ZG91dC5zcGxpdGxpbmVzKCksXG4gICAgICAgICAgICAnZGlzcG9zYWJsZSB2b2x1bWUgYWJzZW5jZSBub3QgdmVyaWZpZWQnKVxuICAgIG5vbmNlID0gam91cm5hbC5kYXRhWydwaGFzZXMnXVsnb2ZmbGluZS12ZXJpZnknXVsnYXR0ZW1wdF9pZCddXG4gICAgbGFiZWxzID0geydpbmZvcm1lZC1kZWNpc2lvbi5jYXNlJzogJ2luZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsXG4gICAgICAgICAgICAgICdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOiAnb2ZmbGluZS1yZXN0b3JlLW9ubHknLCAnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdCc6IG5vbmNlfVxuICAgIGNyZWF0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnY3JlYXRlJywgJy0tZHJpdmVyJywgJ2xvY2FsJywgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24uY2FzZT1pbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQ9JyArIG5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLnVzZT1vZmZsaW5lLXJlc3RvcmUtb25seScsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShjcmVhdGVkLnJldHVybmNvZGUgPT0gMCBhbmQgY3JlYXRlZC5zdGRvdXQuc3RyaXAoKSA9PSBWT0xVTUUsICd2b2x1bWUgY3JlYXRpb24gdW5jZXJ0YWluOyBubyByZXRyeScpXG4gICAgaW5zcGVjdGVkID0gZG9ja2VyKFsndm9sdW1lJywgJ2luc3BlY3QnLCBWT0xVTUVdKVxuICAgIHJlcXVpcmUoaW5zcGVjdGVkLnJldHVybmNvZGUgPT0gMCwgJ25ldyB2b2x1bWUgaWRlbnRpdHkgdW5hdmFpbGFibGUnKVxuICAgIHZvbHVtZSA9IGpzb24ubG9hZHMoaW5zcGVjdGVkLnN0ZG91dClcbiAgICByZXF1aXJlKGxlbih2b2x1bWUpID09IDEgYW5kIHZvbHVtZVswXVsnTmFtZSddID09IFZPTFVNRSBhbmQgdm9sdW1lWzBdLmdldCgnTGFiZWxzJykgPT0gbGFiZWxzXG4gICAgICAgICAgICBhbmQgdm9sdW1lWzBdLmdldCgnRHJpdmVyJykgPT0gJ2xvY2FsJyBhbmQgbm90IHZvbHVtZVswXS5nZXQoJ09wdGlvbnMnKVxuICAgICAgICAgICAgYW5kIHZvbHVtZVswXS5nZXQoJ1Njb3BlJykgPT0gJ2xvY2FsJywgJ25ldyBpc29sYXRlZCB2b2x1bWUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSB7a2V5OiB2b2x1bWVbMF1ba2V5XSBmb3Iga2V5IGluICgnTmFtZScsICdMYWJlbHMnLCAnRHJpdmVyJywgJ1Njb3BlJywgJ0NyZWF0ZWRBdCcpfVxuICAgIGpvdXJuYWwubm90ZSgnb2ZmbGluZS12ZXJpZnknLCAnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknLCBpZGVudGl0eSlcbiAgICAjIE9uZS10aW1lIFVJRDAvQ0FQX0NIT1dOIGluaXRpYWxpemF0aW9uIGlzIGlzb2xhdGVkIHRvIHRoZSBORVcgbmFtZWQgdm9sdW1lLlxuICAgICMgTm8gaG9zdC9saXZlIFBWQy9jb25maWcvdG9rZW4gbW91bnQgZXhpc3RzOyB0aGlzIGRldGFpbCBuZWVkcyBwYWNrZXQgcmV2aWV3LlxuICAgIGluaXRpYWxpemVyID0gXCJcIlwiaW1wb3J0IGhhc2hsaWIsb3Msc3RhdCxzeXNcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkJylcbmZvbGRlcj0nL3Jlc3RvcmUnO2V4cGVjdGVkPUVYUEVDVEVEXG5pZiBvcy5saXN0ZGlyKGZvbGRlcik6cmFpc2UgVmFsdWVFcnJvcignbmV3IGVtcHR5IHByaXZhdGUgdm9sdW1lIHJlcXVpcmVkJylcbm9zLmNobW9kKGZvbGRlciwwbzcwMClcbmZkPW9zLm9wZW4oZm9sZGVyKycvcmV2aWV3LnNxbGl0ZScsb3MuT19DUkVBVHxvcy5PX0VYQ0x8b3MuT19OT0ZPTExPV3xvcy5PX1dST05MWSwwbzYwMClcbmRpZ2VzdD1oYXNobGliLnNoYTI1NigpO3NpemU9MFxud2l0aCBvcy5mZG9wZW4oZmQsJ3diJykgYXMgdGFyZ2V0OlxuIHdoaWxlIFRydWU6XG4gIGJsb2NrPXN5cy5zdGRpbi5idWZmZXIucmVhZCgxMDI0KioyKVxuICBpZiBub3QgYmxvY2s6YnJlYWtcbiAgc2l6ZSs9bGVuKGJsb2NrKVxuICBpZiBzaXplPjUxMioxMDI0KioyOnJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgcmVzdG9yZSBzaXplIGV4Y2VlZHMgYm91bmQnKVxuICB0YXJnZXQud3JpdGUoYmxvY2spO2RpZ2VzdC51cGRhdGUoYmxvY2spXG4gdGFyZ2V0LmZsdXNoKCk7b3MuZnN5bmModGFyZ2V0LmZpbGVubygpKVxuaWYgZGlnZXN0LmhleGRpZ2VzdCgpIT1leHBlY3RlZDpyYWlzZSBWYWx1ZUVycm9yKCdwcml2YXRlIGNvcGllZCBzbmFwc2hvdCBkaWZmZXJzJylcbm9zLmNob3duKGZvbGRlcisnL3Jldmlldy5zcWxpdGUnLDEwMDAxLDEwMDAxKTtvcy5jaG93bihmb2xkZXIsMTAwMDEsMTAwMDEpXG5wcmludCgne1wiYWxsX2NoZWNrc19wYXNzXCI6dHJ1ZSxcInByaXZhdGVfY29weV92ZXJpZmllZFwiOnRydWV9JylcblwiXCJcIi5yZXBsYWNlKCdFWFBFQ1RFRCcsIHJlcHIocHJldmlvdXNbJ3NuYXBzaG90X3NoYTI1NiddKSlcbiAgICB3aXRoIHNuYXBzaG90Lm9wZW4oJ3JiJykgYXMgc291cmNlOlxuICAgICAgICBhcmd2ID0gWydkb2NrZXInLCAnLS1jb25maWcnLCBzdHIoQ1VTVE9EWSAvICdlbXB0eS1kb2NrZXItY29uZmlnJyksICctLWhvc3QnLCBTT0NLRVQsXG4gICAgICAgICAgICAgICAgJ3J1bicsICctLXJtJywgJy1pJywgJy0tbmV0d29yaycsICdub25lJywgJy0tcmVhZC1vbmx5JywgJy0tY3B1cycsICcxJywgJy0tbWVtb3J5JywgJzEyOG0nLFxuICAgICAgICAgICAgICAgICctLXVzZXInLCAnMDowJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tY2FwLWFkZCcsICdDSE9XTicsXG4gICAgICAgICAgICAgICAgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJywgJy0tbW91bnQnLCAndHlwZT12b2x1bWUsc3JjPScgKyBWT0xVTUUgKyAnLGRzdD0vcmVzdG9yZScsXG4gICAgICAgICAgICAgICAgJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy1jJywgaW5pdGlhbGl6ZXJdXG4gICAgICAgIGNvcGllZCA9IHN1YnByb2Nlc3MucnVuKGFyZ3YsIHN0ZGluPXNvdXJjZSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PTE1MClcbiAgICBqc29uX3Jlc3VsdChjb3BpZWQpXG4gICAgb3B0aW9ucyA9IFsncnVuJywgJy0tcm0nLCAnLWknLCAnLS1uZXR3b3JrJywgJ25vbmUnLCAnLS1yZWFkLW9ubHknLCAnLS1jcHVzJywgJzEnLCAnLS1tZW1vcnknLCAnMTI4bScsXG4gICAgICAgICAgICAgICAnLS11c2VyJywgJzEwMDAxOjEwMDAxJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJyxcbiAgICAgICAgICAgICAgICctLW1vdW50JywgJ3R5cGU9dm9sdW1lLHNyYz0nICsgVk9MVU1FICsgJyxkc3Q9L3Jlc3RvcmUnXVxuICAgIHJlYWRvbmx5ID0gZG9ja2VyKG9wdGlvbnMgKyBbJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy0nLCAnLS1kYicsICcvcmVzdG9yZS9yZXZpZXcuc3FsaXRlJ10sXG4gICAgICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShyZWFkb25seS5yZXR1cm5jb2RlID09IDAsICdvZmZsaW5lIHByZS1vcGVuIHNjaGVtYS9pbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkOyBuZXZlciBvcGVuIFN0b3JlJylcbiAgICBjaGVja2VkID0gY291bnRzKGpzb24ubG9hZHMocmVhZG9ubHkuc3Rkb3V0KSlcbiAgICByZXF1aXJlKGNoZWNrZWQgPT0gcHJldmlvdXNbJ3NuYXBzaG90X3JlYWRvbmx5J10sICdmcm96ZW4gc25hcHNob3QvY2xvbmUgcmVhZG9ubHkgY291bnRzIGRpZmZlcicpXG4gICAgYWRtaW4gPSBkb2NrZXIob3B0aW9ucyArIFsnLS1lbnRyeXBvaW50JywgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJywgSU1BR0UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaW5zcGVjdCcsICctLWRiJywgJy9yZXN0b3JlL3Jldmlldy5zcWxpdGUnXSlcbiAgICByZXF1aXJlKGFkbWluLnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgYWRtaW4gcmVzdWx0IHVuY2VydGFpbicpXG4gICAgYWRtaW5fY291bnRzID0ganNvbi5sb2FkcyhhZG1pbi5zdGRvdXQpXG4gICAgcmVxdWlyZShhZG1pbl9jb3VudHMgPT0ge2tleTogY2hlY2tlZFtrZXldIGZvciBrZXkgaW4gKCdzY2hlbWFfdmVyc2lvbicsICdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyl9LFxuICAgICAgICAgICAgJ29mZmxpbmUgYWRtaW4gY2hhbmdlZCBmcm96ZW4gc25hcHNob3QgY291bnRlcnMnKVxuICAgICMgQWRtaW4gU3RvcmUgY29uc3RydWN0aW9uIG11c3Qgbm90IHNpbGVudGx5IGFsdGVyIHNjaGVtYS9pbnRlZ3JpdHkvY291bnRlcnMuXG4gICAgcG9zdCA9IGRvY2tlcihvcHRpb25zICsgWyctLWVudHJ5cG9pbnQnLCAncHl0aG9uJywgSU1BR0UsICctJywgJy0tZGInLCAnL3Jlc3RvcmUvcmV2aWV3LnNxbGl0ZSddLFxuICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShwb3N0LnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgcG9zdC1hZG1pbiByZWFkb25seSBpbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkJylcbiAgICBwb3N0X2NoZWNrZWQgPSBjb3VudHMoanNvbi5sb2Fkcyhwb3N0LnN0ZG91dCkpXG4gICAgcmVxdWlyZShwb3N0X2NoZWNrZWQgPT0gY2hlY2tlZCA9PSBwcmV2aW91c1snc25hcHNob3RfcmVhZG9ubHknXSxcbiAgICAgICAgICAgICdvZmZsaW5lIGFkbWluIGFsdGVyZWQgZnJvemVuIHNuYXBzaG90IHByb29mJylcbiAgICBwcml2YXRlKHNuYXBzaG90KVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdvcmlnaW5hbCBwcm90ZWN0ZWQgc25hcHNob3QgY2hhbmdlZCBkdXJpbmcgZHJpbGwnKVxuICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdvZmZsaW5lX3ZvbHVtZSc6IFZPTFVNRSwgJ29mZmxpbmVfcmVhZG9ubHknOiBjaGVja2VkLFxuICAgICAgICAgICAgJ29mZmxpbmVfcG9zdF9hZG1pbl9yZWFkb25seSc6IHBvc3RfY2hlY2tlZCwgJ29yaWdpbmFsX3NuYXBzaG90X2hhc2hfdW5jaGFuZ2VkJzogVHJ1ZSxcbiAgICAgICAgICAgICdjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eSc6IGlkZW50aXR5LFxuICAgICAgICAgICAgJ2FkbWluX2NvdW50cyc6IGFkbWluX2NvdW50cywgJ25ldHdvcmsnOiAnbm9uZScsICdydW50aW1lX3Rva2Vuc19vcl9jb25maWdfbW91bnRlZCc6IEZhbHNlLFxuICAgICAgICAgICAgJ3NlcnZpY2VfZW50cnlwb2ludF9zdGFydGVkJzogRmFsc2UsICdvcmlnaW5hbF9zbmFwc2hvdF9yZXRhaW5lZCc6IFRydWV9XG5cblxuZGVmIGNsZWFudXBfb2ZmbGluZShqb3VybmFsKTpcbiAgICBpbnNwZWN0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnaW5zcGVjdCcsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShpbnNwZWN0ZWQucmV0dXJuY29kZSA9PSAwLCAnb3duZWQgZGlzcG9zYWJsZSB2b2x1bWUgaWRlbnRpdHkgdW52ZXJpZmllZCcpXG4gICAgdmFsdWUgPSBqc29uLmxvYWRzKGluc3BlY3RlZC5zdGRvdXQpXG4gICAgZXhwZWN0ZWQgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydvZmZsaW5lLXZlcmlmeSddWydyZXN1bHQnXVsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknXVxuICAgIHJlcXVpcmUobGVuKHZhbHVlKSA9PSAxIGFuZCB7a2V5OiB2YWx1ZVswXS5nZXQoa2V5KSBmb3Iga2V5IGluIGV4cGVjdGVkfSA9PSBleHBlY3RlZFxuICAgICAgICAgICAgYW5kIG5vdCB2YWx1ZVswXS5nZXQoJ09wdGlvbnMnKSwgJ3ZvbHVtZSBvd25lcnNoaXAvcmVjcmVhdGlvbiBjaGFuZ2VkJylcbiAgICByZW1vdmVkID0gZG9ja2VyKFsndm9sdW1lJywgJ3JtJywgVk9MVU1FXSlcbiAgICByZXF1aXJlKHJlbW92ZWQucmV0dXJuY29kZSA9PSAwIGFuZCByZW1vdmVkLnN0ZG91dC5zdHJpcCgpID09IFZPTFVNRVxuICAgICAgICAgICAgYW5kIGRvY2tlcihbJ3ZvbHVtZScsICdpbnNwZWN0JywgVk9MVU1FXSkucmV0dXJuY29kZSAhPSAwLFxuICAgICAgICAgICAgJ2NsZWFudXAgb3V0Y29tZSBhbWJpZ3VvdXM7IGRvIG5vdCByZXRyeScpXG4gICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ29ubHlfZGlzcG9zYWJsZV9vZmZsaW5lX3ZvbHVtZV9yZW1vdmVkJzogVk9MVU1FLFxuICAgICAgICAgICAgJ25hdGl2ZV9hbmRfb2ZmY2x1c3Rlcl9vcmlnaW5hbF9zbmFwc2hvdHNfcmV0YWluZWQnOiBUcnVlfVxuXG5cbmRlZiBtYWluKCk6XG4gICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249X19kb2NfXylcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXBoYXNlJywgY2hvaWNlcz1QSEFTRVMsIHJlcXVpcmVkPVRydWUpXG4gICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1yb290LWF1dGhvcml0eS1yZWNlaXB0JywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tcm9vdC1uYXRpdmUtb3V0Y29tZScsIHR5cGU9UGF0aCwgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yZXZpc2lvbicsIHJlcXVpcmVkPVRydWUpXG4gICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKClcbiAgICByZXF1aXJlKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdCA9PSBQYXRoKCcvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1yb290LWF1dGhvcml0eS5qc29uJylcbiAgICAgICAgICAgIGFuZCBhcmdzLnJvb3RfbmF0aXZlX291dGNvbWUgPT0gUGF0aCgnL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2UtbmF0aXZlLW91dGNvbWUtbGF0ZXN0Lmpzb24nKSxcbiAgICAgICAgICAgICdmaXhlZCBzdXBlcnZpc2VkIHJlY2VpcHQgcGF0aHMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInWzAtOWEtZl17NDB9JywgYXJncy5zb3VyY2VfcmV2aXNpb24pIGlzIG5vdCBOb25lLCAnZXhhY3Qgc291cmNlIGNvbW1pdCByZXF1aXJlZCcpXG4gICAgIyBWZXJpZnkgYWxsIHByZXBhcmVkIGV4ZWN1dG9yL2lucHV0IGJ5dGVzIGJlZm9yZSByZWFkaW5nIGF1dGhvcml0eSBvciBkaXNwYXRjaGluZy5cbiAgICBwbGFuID0ganNvbi5sb2FkcygoUk9PVCAvICdleGVjdXRpb24tcGxhbi5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShzZXQocGxhblsnZXhlY3V0b3JfZmlsZXMnXSkgPT0geydhY3R1YXRvci5weScsICdhdXRob3JpdHlfam91cm5hbC5weScsICduYXRpdmVfcHJvZ3JhbS5weScsICdyZWNlaXB0X3NhZmV0eS5weSd9LFxuICAgICAgICAgICAgJ2ZpeGVkIGV4ZWN1dG9yIHNvdXJjZXMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUoc2V0KHBsYW5bJ293bmVyX3NvdXJjZV9maWxlcyddKSA9PSB7J2RlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL3JlZ2lzdHJpZXMuY2FuZGlkYXRlLmpzb24nfSxcbiAgICAgICAgICAgICdmaXhlZCBvd25lciBpbWFnZSBzb3VyY2VzIHJlcXVpcmVkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydleGVjdXRvcl9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHRhcmdldCA9IFJPT1QgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdleGVjdXRvciBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnY2FzZV9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUobm90IFBhdGgocmVsYXRpdmUpLmlzX2Fic29sdXRlKCkgYW5kICcuLicgbm90IGluIFBhdGgocmVsYXRpdmUpLnBhcnRzLFxuICAgICAgICAgICAgICAgICdjYXNlIHNvdXJjZSBwYXRoIGVzY2FwZWQnKVxuICAgICAgICB0YXJnZXQgPSBDQVNFIC8gcmVsYXRpdmVcbiAgICAgICAgcmVxdWlyZShub3QgdGFyZ2V0LmlzX3N5bWxpbmsoKSBhbmQgc2hhKHRhcmdldCkgPT0gZGlnZXN0LCAnY2FzZSBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgdGFyZ2V0ID0gT1dORVIgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdvd25lciBpbWFnZS1vbmx5IHNvdXJjZSBjaGFuZ2VkJylcbiAgICAgICAgY29tbWl0dGVkID0gc3VicHJvY2Vzcy5ydW4oWydnaXQnLCAnLUMnLCBzdHIoT1dORVIpLCAnc2hvdycsIGFyZ3Muc291cmNlX3JldmlzaW9uICsgJzonICsgcmVsYXRpdmVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlKVxuICAgICAgICByZXF1aXJlKGNvbW1pdHRlZC5yZXR1cm5jb2RlID09IDAgYW5kIGhhc2hsaWIuc2hhMjU2KGNvbW1pdHRlZC5zdGRvdXQpLmhleGRpZ2VzdCgpID09IGRpZ2VzdCxcbiAgICAgICAgICAgICAgICAnY29tbWl0dGVkIG93bmVyIHJlbmRlciBzb3VyY2UgZGlmZmVycyBmcm9tIGFwcHJvdmVkIGlucHV0cycpXG4gICAgaGVhZCA9IHJ1bihbJ2dpdCcsICctQycsIHN0cihPV05FUiksICdyZXYtcGFyc2UnLCAnSEVBRCddKVxuICAgIHJlcXVpcmUoaGVhZC5yZXR1cm5jb2RlID09IDAgYW5kIGhlYWQuc3Rkb3V0LnN0cmlwKCkgPT0gYXJncy5zb3VyY2VfcmV2aXNpb24sICdvd25lciBzb3VyY2UgSEVBRCBkaWZmZXJzJylcbiAgICBmcm9tIGF1dGhvcml0eV9qb3VybmFsIGltcG9ydCBKb3VybmFsLCBhdXRob3JpdHksIG9yaWdpbmFsX2FuY2hvclxuICAgIHByaXZhdGUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0KVxuICAgIHByaXZhdGUoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKVxuICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlY2VpcHQuZ2V0KCduYXRpdmVfb3V0Y29tZV9zaGEyNTYnKSA9PSBzaGEoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKSwgJ25hdGl2ZSBvdXRjb21lIGJ5dGVzIGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ2V4ZWN1dG9yX3BsYW5fc2hhMjU2JykgPT0gc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgJ3Jvb3QgdmVyaWZpZWQgZXhlY3V0b3IgcGxhbiBkaWZmZXJzJylcbiAgICBhcHByb3ZlZCA9IGF1dGhvcml0eShyZWNlaXB0LCBqc29uLmxvYWRzKGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZS5yZWFkX3RleHQoKSksIHNoYShDQVNFIC8gJ21lbW8uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcmdzLnBoYXNlKVxuICAgIHBhcmVudCA9IENVU1RPRFkucGFyZW50XG4gICAgcHJpdmF0ZShwYXJlbnQsIGRpcmVjdG9yeT1UcnVlKVxuICAgIGlnbm9yZWQgPSBydW4oWydnaXQnLCAnLUMnLCBzdHIoQ1VTVE9ESUFOKSwgJ2NoZWNrLWlnbm9yZScsICctLW5vLWluZGV4Jywgc3RyKENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJyldKVxuICAgIHJlcXVpcmUoaWdub3JlZC5yZXR1cm5jb2RlID09IDAsICdvZmZjbHVzdGVyIGN1c3RvZHkgaXMgbm90IGlnbm9yZWQnKVxuICAgIHJlcXVpcmUoQ1VTVE9EWS5leGlzdHMoKSwgJ29yaWdpbmFsIHByb3RlY3RlZCBjdXN0b2R5IG11c3QgYWxyZWFkeSBleGlzdCcpXG4gICAgcHJpdmF0ZShDVVNUT0RZLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICBjYXBhY2l0eSA9IG9zLnN0YXR2ZnMoQ1VTVE9EWSlcbiAgICByZXF1aXJlKGNhcGFjaXR5LmZfYmF2YWlsICogY2FwYWNpdHkuZl9mcnNpemUgPj0gMiAqIE1BWF9CWVRFUyArIDE2ICogMTAyNCoqMixcbiAgICAgICAgICAgICdpbmRlcGVuZGVudCBwcm90ZWN0ZWQgY3VzdG9keSBoZWFkcm9vbSBpbnN1ZmZpY2llbnQnKVxuICAgIG9zLm1ha2VkaXJzKENVU1RPRFkgLyAnZW1wdHktZG9ja2VyLWNvbmZpZycsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpXG4gICAgcHJpdmF0ZShDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICByZXF1aXJlKG5vdCBsaXN0KChDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKS5pdGVyZGlyKCkpLCAncHVibGljIERvY2tlciByZWFkIGNvbmZpZyBtdXN0IHN0YXkgZW1wdHknKVxuICAgIGFuY2hvciA9IG9yaWdpbmFsX2FuY2hvcihDVVNUT0RZLCBwbGFuWydyZWNvdmVyeSddWydvcmlnaW5hbF9hbmNob3InXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5sb2FkcygoQ0FTRSAvICdvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcbiAgICBpZiBhcmdzLnBoYXNlID09ICdkcmlsbC1jb3B5LXJlc2N1ZS1yMSc6XG4gICAgICAgIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXG4gICAgICAgICAgICAgICAgYW5kIG5vdCBvcy5wYXRoLmxleGlzdHMoQ1VTVE9EWSAvICdjdXRvdmVyLnNxbGl0ZScpLCAncmVzY3VlIGRlc3RpbmF0aW9uIG11c3QgYmUgYWJzZW50JylcbiAgICAgICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgICAgIHJlcXVpcmUoaWRlbnRpdHkucmV0dXJuY29kZSA9PSAwIGFuZCBqc29uLmxvYWRzKGlkZW50aXR5LnN0ZG91dCkgPT0gJ2JudC1sYXAwMDEnLFxuICAgICAgICAgICAgICAgICdsb2NhbCBlbmdpbmUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICAgICAgcmVxdWlyZShsaXN0ZWQucmV0dXJuY29kZSA9PSAwIGFuZCBWT0xVTUUgbm90IGluIGxpc3RlZC5zdGRvdXQuc3BsaXRsaW5lcygpLFxuICAgICAgICAgICAgICAgICdleGlzdGluZyByZXN0b3JlIHZvbHVtZSBmb3JiaWRzIHJlc2N1ZScpXG4gICAgam91cm5hbCA9IEpvdXJuYWwoQ1VTVE9EWSwgeydwcm9wb3NhbCc6IHBsYW5bJ3Byb3Bvc2FsX2lkJ10sICdzb3VyY2VfcmV2aXNpb24nOiBhcmdzLnNvdXJjZV9yZXZpc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWVtb19zaGEyNTYnOiBzaGEoQ0FTRSAvICdtZW1vLmpzb24nKSwgJ3BsYW5fc2hhMjU2Jzogc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZWNvdmVyeV9hbmNob3InOiBhbmNob3J9KVxuICAgIHRyeTpcbiAgICAgICAgam91cm5hbC5zdGFydChhcmdzLnBoYXNlLCBhcHByb3ZlZCkgIyBmc3luY2VkIFJVTk5JTkcgYmVmb3JlIGFueSBwaGFzZSBlZmZlY3QuXG4gICAgICAgIGlmIGFyZ3MucGhhc2UgaW4gKCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsICdjdXRvdmVyLWNvcHknKTpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNvcHlfc25hcHNob3QoYXJncy5waGFzZSwgYXJncy5zb3VyY2VfcmV2aXNpb24sIGFwcHJvdmVkLCBqb3VybmFsKVxuICAgICAgICBlbGlmIGFyZ3MucGhhc2UgPT0gJ29mZmxpbmUtdmVyaWZ5JzpcbiAgICAgICAgICAgIHJlc3VsdCA9IG9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgIGVsaWYgYXJncy5waGFzZSA9PSAnY2xlYW51cC1vZmZsaW5lJzpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNsZWFudXBfb2ZmbGluZShqb3VybmFsKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgcmVzdWx0ID0gcmVtb3RlKGFyZ3MucGhhc2UsIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcHByb3ZlZClcbiAgICAgICAgcmVxdWlyZShvcmlnaW5hbF9hbmNob3IoQ1VTVE9EWSwgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubG9hZHMoKENBU0UgLyAnb3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtYmFja3VwLmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYW5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10pID09IGFuY2hvcixcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkIGpvdXJuYWwgY2hhbmdlZCBkdXJpbmcgbmV3IHBoYXNlJylcbiAgICAgICAgam91cm5hbC5maW5pc2goYXJncy5waGFzZSwgcmVzdWx0KVxuICAgICAgICBwcmludChqc29uLmR1bXBzKHJlc3VsdCkpICMgT25seSBjb3VudC9oYXNoL2lkZW50aXR5IHJlY2VpcHRzLCBuZXZlciBzbmFwc2hvdCBieXRlcy5cbiAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICAgICAgc2FmZSA9IHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdwaGFzZSc6IGFyZ3MucGhhc2UsICdmYWlsdXJlX2NsYXNzJzogdHlwZShlcnJvcikuX19uYW1lX18sXG4gICAgICAgICAgICAgICAgJ2ZhaWx1cmUnOiAnZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeScsXG4gICAgICAgICAgICAgICAgJ3Jhd19vdXRwdXRfd2l0aGhlbGQnOiBUcnVlfVxuICAgICAgICBpZiBqb3VybmFsLmRhdGFbJ3BoYXNlcyddLmdldChhcmdzLnBoYXNlLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdSVU5OSU5HJzpcbiAgICAgICAgICAgIGpvdXJuYWwuZmluaXNoKGFyZ3MucGhhc2UsIHNhZmUpXG4gICAgICAgIHByaW50KGpzb24uZHVtcHMoc2FmZSkpXG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoMSkgZnJvbSBOb25lXG4gICAgZmluYWxseTpcbiAgICAgICAgam91cm5hbC5jbG9zZSgpXG5cblxuaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzpcbiAgICB0cnk6XG4gICAgICAgIG1haW4oKVxuICAgIGV4Y2VwdCBFeGNlcHRpb246XG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoJ3N1cGVydmlzZWQgZXhlY3V0aW9uIHJlZnVzZWQgYmVmb3JlIHBoYXNlOyByYXcgb3V0cHV0IHdpdGhoZWxkJykgZnJvbSBOb25lXG4iCiAgICB9LAogICAgImF1dGhvcml0eV9qb3VybmFsLnB5IjogewogICAgICAic2hhMjU2IjogIjA1MzU5NzVhZTYzMTIxOWY5MGZjZTdlNTJmOGI1NGU2MWU4YWZkNGVmNjhiYjc0NzM4NjM0NzhmMGY1MTlmNjgiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTdXBlcnZpc2VkIHJlY2VpcHQgYm9va2tlZXBpbmcsIG5vdCBhbiBhdXRoZW50aWNhdGVkIGFwcHJvdmFsIHByb3ZpZGVyLlwiXCJcIlxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgZmNudGxcbmltcG9ydCBoYXNobGliXG5pbXBvcnQganNvblxuaW1wb3J0IG9zXG5pbXBvcnQgcmVcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN0YXRcbmltcG9ydCB1dWlkXG5cbkZPVU5ERVIgPSB7J2tpbmQnOiAncGVyc29uJywgJ3N1Yic6ICd1aWQ9cGxhdGZvcm0tcm9vdCxvdT1wZW9wbGUsZGM9bmV0a2luZ2RvbSxkYz1sb2NhbCd9XG5NRU1PX0lEID0gJ2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxJ1xuUFJPUE9TQUwgPSAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnXG5QSEFTRVMgPSAoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywgJ29mZmxpbmUtdmVyaWZ5JywgJ2NsZWFudXAtb2ZmbGluZScsXG4gICAgICAgICAgJ2N1dG92ZXItYmFja3VwJywgJ2N1dG92ZXItY29weScsICdyZWxlYXNlJywgJ3ZlcmlmeScsICdyb2xsYmFjaycsICdyb2xsYmFjay12ZXJpZnknKVxuXG5cbmRlZiByZXF1aXJlKHZhbHVlLCByZWFzb24pOlxuICAgIGlmIG5vdCB2YWx1ZTpcbiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcihyZWFzb24pXG5cblxuZGVmIHNoYShwYXRoKTpcbiAgICBkaWdlc3QgPSBoYXNobGliLnNoYTI1NigpXG4gICAgd2l0aCBQYXRoKHBhdGgpLm9wZW4oJ3JiJykgYXMgc3RyZWFtOlxuICAgICAgICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6IHN0cmVhbS5yZWFkKDEwMjQqKjIpLCBiJycpOlxuICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZShibG9jaylcbiAgICByZXR1cm4gZGlnZXN0LmhleGRpZ2VzdCgpXG5cblxuZGVmIHByaXZhdGUocGF0aCwgZGlyZWN0b3J5PUZhbHNlKTpcbiAgICBpbmZvID0gUGF0aChwYXRoKS5sc3RhdCgpXG4gICAgcmVxdWlyZSgoc3RhdC5TX0lTRElSKGluZm8uc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKGluZm8uc3RfbW9kZSkpXG4gICAgICAgICAgICBhbmQgaW5mby5zdF91aWQgPT0gb3MuZ2V0dWlkKCkgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpID09ICgwbzcwMCBpZiBkaXJlY3RvcnkgZWxzZSAwbzYwMClcbiAgICAgICAgICAgIGFuZCAoZGlyZWN0b3J5IG9yIGluZm8uc3RfbmxpbmsgPT0gMSksICdwcml2YXRlIG93bmVkIGN1c3RvZHkgcmVxdWlyZWQnKVxuXG5cbmRlZiBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgbWVtb19zaGEsIHNvdXJjZV9yZXZpc2lvbiwgcGhhc2UsIG5vdz1Ob25lKTpcbiAgICBcIlwiXCJSb290IG11c3QgZnJlc2hseSB2ZXJpZnkgbmF0aXZlIG91dGNvbWUgYXQgZml4ZWQgT1JJR0lOIG91dHNpZGUgdGhpcyBoZWxwZXIuXG5cbiAgICBSZWNlaXB0IGZpbGVzL2ZsYWdzIGFyZSBub3Qgc2lnbmVkIGdyYW50cy4gVGhpcyBmdW5jdGlvbiBjaGVja3MgdGhlIGV4YWN0XG4gICAgc3VwZXJ2aXNlZCByZWNlaXB0IHJlbGF0aW9uOyBleGlzdGluZyBoYXJuZXNzL2ZvdW5kZXIgYXV0aG9yaXR5IHJlbWFpbnMgdGhlXG4gICAgYWN0dWFsIHBlcm1pc3Npb24gYm91bmRhcnkuIEl0IG5ldmVyIGF1dGhlbnRpY2F0ZXMgYSBjYWxsZXIgYXMgaHVtYW4uXG4gICAgXCJcIlwiXG4gICAgbm93ID0gbm93IG9yIGRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpXG4gICAgcmVxdWlyZShwaGFzZSBpbiBQSEFTRVMsICdmaXhlZCBwaGFzZSByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShyZWNlaXB0LmdldCgncHJvcG9zYWxfaWQnKSA9PSBQUk9QT1NBTCBhbmQgcmVjZWlwdC5nZXQoJ21lbW9faWQnKSA9PSBNRU1PX0lEXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ21lbW9fdmVyc2lvbicpID09IDIgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX3NoYTI1NicpID09IG1lbW9fc2hhXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3NvdXJjZV9yZXZpc2lvbicpID09IHNvdXJjZV9yZXZpc2lvblxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhY3RpdmF0aW9uJykgPT0gJ0FQUFJPVkVEJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhdXRob3JpdHlfbW9kZScpID09ICdBRE1JTklTVEVSJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCd0YXJnZXQnKSA9PSAncmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbidcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgndmVyaWZpY2F0aW9uX21ldGhvZCcpID09ICdyb290LWZpeGVkLW9yaWdpbi1uYXRpdmUtcmVhZGJhY2snXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3J1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudCcpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ291dGNvbWVfcXVlcnknKSA9PSAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgJ2V4YWN0IGV4dGVybmFsbHkgdmVyaWZpZWQgc3VwZXJ2aXNlZCByZWNlaXB0IHJlcXVpcmVkJylcbiAgICB2ZXJpZmllZCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQocmVjZWlwdFsndmVyaWZpZWRfYXQnXS5yZXBsYWNlKCdaJywgJyswMDowMCcpKVxuICAgIHJlcXVpcmUodmVyaWZpZWQudHppbmZvIGlzIG5vdCBOb25lIGFuZCAwIDw9IChub3cgLSB2ZXJpZmllZCkudG90YWxfc2Vjb25kcygpIDw9IDEyMCxcbiAgICAgICAgICAgICdmcmVzaCByb290IG5hdGl2ZSByZWFkYmFjayByZXF1aXJlZCBiZWZvcmUgZXZlcnkgcGhhc2UnKVxuICAgIGRlYWRsaW5lID0gZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdCgnMjAyNi0xMC0xMlQyMzo1OTo1OSswMDowMCcpXG4gICAgcmVxdWlyZShub3cgPCBkZWFkbGluZSwgJ2FwcHJvdmVkIGV4ZWN1dGlvbiB3aW5kb3cgZXhwaXJlZCcpXG4gICAgcmVxdWlyZShvdXRjb21lLmdldCgnbWVtb19pZCcpID09IE1FTU9fSUQgYW5kIG91dGNvbWUuZ2V0KCdyZXZpZXcnLCB7fSkuZ2V0KCdzdGFsZScpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgb3V0Y29tZVsncmV2aWV3J10uZ2V0KCdpbnRha2Vfc3RhdGUnKSA9PSAncmVhZHknLCAnbmF0aXZlIHJldmlldyBpcyBub3QgcmVhZHkvY3VycmVudCcpXG4gICAgcmV2aWV3X2lkID0gb3V0Y29tZVsncmV2aWV3J11bJ21lbW9faWQnXVxuICAgIHJlcXVpcmUocmV2aWV3X2lkID09IHJlY2VpcHQuZ2V0KCdyZXZpZXdfbWVtb19pZCcpLCAnbmF0aXZlIHJldmlldyBpZGVudGl0eSBjaGFuZ2VkJylcbiAgICBhY2NlcHRlZCA9IFt4IGZvciB4IGluIG91dGNvbWUuZ2V0KCdkaXNwb3NpdGlvbnMnLCBbXSlcbiAgICAgICAgICAgICAgICBpZiB4LmdldCgnc3VibWlzc2lvbl9zdGF0ZScpID09ICdjb25maXJtZWQnXG4gICAgICAgICAgICAgICAgYW5kIHguZ2V0KCdkaXNwb3NpdGlvbicsIHt9KS5nZXQoJ3ZlcmInKSA9PSAnYWNjZXB0J1xuICAgICAgICAgICAgICAgIGFuZCB4WydkaXNwb3NpdGlvbiddLmdldCgnbWVtb192ZXJzaW9uJykgPT0gMV1cbiAgICByZXF1aXJlKGxlbihhY2NlcHRlZCkgPT0gMSwgJ29uZSBjb25maXJtZWQgZm91bmRlciBhY2NlcHRhbmNlIHJlcXVpcmVkJylcbiAgICBhY2NlcHRlZCA9IGFjY2VwdGVkWzBdWydkaXNwb3NpdGlvbiddXG4gICAgcmVxdWlyZShhY2NlcHRlZC5nZXQoJ2FjdG9yJykgPT0gRk9VTkRFUiBhbmQgYWNjZXB0ZWQuZ2V0KCdtZW1vX2lkJykgPT0gcmV2aWV3X2lkXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhcHByb3ZhbF9pZCcpID09IHJlY2VpcHQuZ2V0KCdhcHByb3ZhbF9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdpZCcpID09IHJlY2VpcHQuZ2V0KCdkaXNwb3NpdGlvbl9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhdCcpID09IHJlY2VpcHQuZ2V0KCdhY2NlcHRlZF9hdCcpLCAnZXhhY3QgZm91bmRlciBkaXNwb3NpdGlvbiBtaXNtYXRjaCcpXG4gICAgcmVxdWlyZShyZS5mdWxsbWF0Y2gocidbYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2FwcHJvdmFsX2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHInZGlzcC1bYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHIncmV2aWV3LVthLWYwLTktXXszNn0nLCByZXZpZXdfaWQpIGlzIG5vdCBOb25lLFxuICAgICAgICAgICAgJ25hdGl2ZSBkaXNwb3NpdGlvbiBpZGVudGlmaWVycyBhcmUgbWFsZm9ybWVkJylcbiAgICBhY2NlcHRlZF9hdCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQoYWNjZXB0ZWRbJ2F0J10ucmVwbGFjZSgnWicsICcrMDA6MDAnKSlcbiAgICByZXF1aXJlKGFjY2VwdGVkX2F0LnR6aW5mbyBpcyBub3QgTm9uZSBhbmQgYWNjZXB0ZWRfYXQgPD0gdmVyaWZpZWQsICdhY2NlcHRhbmNlIHRpbWUgbm90IGJvdW5kZWQnKVxuICAgIHJldHVybiB7a2V5OiByZWNlaXB0W2tleV0gZm9yIGtleSBpbiAoJ2FwcHJvdmFsX2lkJywgJ2Rpc3Bvc2l0aW9uX2lkJywgJ2FjY2VwdGVkX2F0JywgJ3ZlcmlmaWVkX2F0Jyl9XG5cblxuZGVmIG9yaWdpbmFsX2FuY2hvcihwYXJlbnQsIGV4cGVjdGVkLCBiYWNrdXBfcmVzdWx0LCBvcmlnaW5hbF9pZGVudGl0eSk6XG4gICAgXCJcIlwiUmVhZCBvbmx5IHNhbml0aXplZCBvcmlnaW5hbCBqb3VybmFsOyBuZXZlciByZXdyaXRlL3N5bnRoZXNpemUgaXRzIHBoYXNlcy5cIlwiXCJcbiAgICBwYXRoID0gUGF0aChwYXJlbnQpIC8gJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nXG4gICAgcHJpdmF0ZShwYXRoKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBieXRlcyBjaGFuZ2VkJylcbiAgICBvcmlnaW5hbCA9IGpzb24ubG9hZHMocGF0aC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKG9yaWdpbmFsLmdldCgnaWRlbnRpdHknKSA9PSBvcmlnaW5hbF9pZGVudGl0eSwgJ29yaWdpbmFsIGFwcHJvdmVkIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHBoYXNlcyA9IG9yaWdpbmFsLmdldCgncGhhc2VzJywge30pXG4gICAgcmVxdWlyZShzZXQocGhhc2VzKSA9PSB7J2RyaWxsLWJhY2t1cCcsICdkcmlsbC1jb3B5J30sICd1bmV4cGVjdGVkIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0JylcbiAgICBmb3IgbmFtZSwgZmllbGRzIGluIGV4cGVjdGVkWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUoYWxsKHBoYXNlc1tuYW1lXS5nZXQoa2V5KSA9PSB2YWx1ZSBmb3Iga2V5LHZhbHVlIGluIGZpZWxkcy5pdGVtcygpKSxcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkL2NvbXBsZXRlZCBhdHRlbXB0IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocGhhc2VzWydkcmlsbC1iYWNrdXAnXS5nZXQoJ3Jlc3VsdCcpID09IGJhY2t1cF9yZXN1bHRcbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZVxuICAgICAgICAgICAgYW5kIHBoYXNlc1snZHJpbGwtY29weSddLmdldCgncmVzdWx0Jywge30pLmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgRmFsc2UsXG4gICAgICAgICAgICAnb3JpZ2luYWwgYmFja3VwL2NvcHkgb3V0Y29tZSBjaGFuZ2VkJylcbiAgICByZXF1aXJlKGJhY2t1cF9yZXN1bHQuZ2V0KCdzbmFwc2hvdF9zaGEyNTYnKSA9PSBleHBlY3RlZFsnc25hcHNob3Rfc2hhMjU2J11cbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnc25hcHNob3RfYnl0ZXMnKSA9PSBleHBlY3RlZFsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIGJhY2t1cF9yZXN1bHQuZ2V0KCdwb2RfdWlkJykgPT0gJ2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNycsXG4gICAgICAgICAgICAnb3JpZ2luYWwgZnJvemVuIHNuYXBzaG90IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBjaGFuZ2VkIGR1cmluZyByZWFkJylcbiAgICByZXR1cm4geydvcmlnaW5hbF9qb3VybmFsX3NoYTI1Nic6IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLFxuICAgICAgICAgICAgJ29yaWdpbmFsX2NvcHlfYXR0ZW1wdF9pZCc6IHBoYXNlc1snZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnb3JpZ2luYWxfYmFja3VwX2F0dGVtcHRfaWQnOiBwaGFzZXNbJ2RyaWxsLWJhY2t1cCddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnYmFja3VwX3Jlc3VsdCc6IGJhY2t1cF9yZXN1bHQsICdvbGRfdW5jZXJ0YWluX3BoYXNlX3JldGFpbmVkJzogVHJ1ZX1cblxuXG5jbGFzcyBKb3VybmFsOlxuICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXJlbnQsIGlkZW50aXR5KTpcbiAgICAgICAgc2VsZi5wYXJlbnQgPSBQYXRoKHBhcmVudClcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCwgZGlyZWN0b3J5PVRydWUpXG4gICAgICAgIHNlbGYucGF0aCA9IHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tam91cm5hbC1yMS5qc29uJ1xuICAgICAgICBzZWxmLmxvY2sgPSBvcy5vcGVuKHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tcjEubG9jaycsIG9zLk9fQ1JFQVQgfCBvcy5PX05PRk9MTE9XIHwgb3MuT19SRFdSLCAwbzYwMClcbiAgICAgICAgZmNudGwuZmxvY2soc2VsZi5sb2NrLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQilcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCAvICdyZXNjdWUtZXhlY3V0aW9uLXIxLmxvY2snKVxuICAgICAgICBpZiBzZWxmLnBhdGguZXhpc3RzKCk6XG4gICAgICAgICAgICBwcml2YXRlKHNlbGYucGF0aClcbiAgICAgICAgICAgIHNlbGYuZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5wYXRoLnJlYWRfdGV4dCgpKVxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ2lkZW50aXR5J10gPT0gaWRlbnRpdHksICdqb3VybmFsIGNhc2Uvc291cmNlIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgc2VsZi5kYXRhID0geydpZGVudGl0eSc6IGlkZW50aXR5LCAncGhhc2VzJzoge319XG4gICAgICAgICAgICBzZWxmLnNhdmUoKVxuXG4gICAgZGVmIHNhdmUoc2VsZik6XG4gICAgICAgIHRlbXBvcmFyeSA9IHNlbGYucGFyZW50IC8gJ2V4ZWN1dGlvbi1qb3VybmFsLm5ldydcbiAgICAgICAgZmQgPSBvcy5vcGVuKHRlbXBvcmFyeSwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1cgfCBvcy5PX1dST05MWSwgMG82MDApXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAndycpIGFzIHN0cmVhbTpcbiAgICAgICAgICAgICAgICBqc29uLmR1bXAoc2VsZi5kYXRhLCBzdHJlYW0sIGluZGVudD0yKVxuICAgICAgICAgICAgICAgIHN0cmVhbS53cml0ZSgnXFxuJylcbiAgICAgICAgICAgICAgICBzdHJlYW0uZmx1c2goKVxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKHN0cmVhbS5maWxlbm8oKSlcbiAgICAgICAgICAgIG9zLnJlcGxhY2UodGVtcG9yYXJ5LCBzZWxmLnBhdGgpXG4gICAgICAgICAgICBkaXJlY3RvcnkgPSBvcy5vcGVuKHNlbGYucGFyZW50LCBvcy5PX0RJUkVDVE9SWSB8IG9zLk9fUkRPTkxZKVxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIGZpbmFsbHk6XG4gICAgICAgICAgICAgICAgb3MuY2xvc2UoZGlyZWN0b3J5KVxuICAgICAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbjpcbiAgICAgICAgICAgICMgUmV0YWluIGV2aWRlbmNlIHJhdGhlciB0aGFuIG92ZXJ3cml0aW5nIGFuIHVuY2VydGFpbiBkdXJhYmxlIGludGVudC5cbiAgICAgICAgICAgIHJhaXNlXG5cbiAgICBkZWYgc3RhcnQoc2VsZiwgcGhhc2UsIGFwcHJvdmFsKTpcbiAgICAgICAgcmVxdWlyZShwaGFzZSBub3QgaW4gc2VsZi5kYXRhWydwaGFzZXMnXSwgJ2FscmVhZHkgYXR0ZW1wdGVkIHBoYXNlOyBubyByZXRyeScpXG4gICAgICAgIHJlcXVpcmUocGhhc2UgaW4gUEhBU0VTLCAnZml4ZWQgcmVzY3VlIG9yIHJlbWFpbmluZyBwaGFzZSByZXF1aXJlZCcpXG4gICAgICAgIHByZWRlY2Vzc29ycyA9IGRpY3QoemlwKFBIQVNFU1sxOjddLCBQSEFTRVNbOjZdKSlcbiAgICAgICAgcHJlZGVjZXNzb3JzWydyb2xsYmFjay12ZXJpZnknXSA9ICdyb2xsYmFjaydcbiAgICAgICAgaWYgcGhhc2UgaW4gcHJlZGVjZXNzb3JzOlxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ3BoYXNlcyddLmdldChwcmVkZWNlc3NvcnNbcGhhc2VdLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdDT01QTEVURScsXG4gICAgICAgICAgICAgICAgICAgICdwcmVjZWRpbmcgcGhhc2UgaXMgbm90IHZlcmlmaWVkIGNvbXBsZXRlJylcbiAgICAgICAgaWYgcGhhc2UgPT0gJ3JvbGxiYWNrJzpcbiAgICAgICAgICAgIHJlcXVpcmUoJ3JlbGVhc2UnIGluIHNlbGYuZGF0YVsncGhhc2VzJ10sICdyb2xsYmFjayByZXF1aXJlcyBhIHJlY29yZGVkIHJlbGVhc2UgYXR0ZW1wdCcpXG4gICAgICAgIHNlbGYuZGF0YVsncGhhc2VzJ11bcGhhc2VdID0geydzdGF0ZSc6ICdSVU5OSU5HJywgJ2FwcHJvdmFsJzogYXBwcm92YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhdHRlbXB0X2lkJzogc3RyKHV1aWQudXVpZDQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdGFydGVkX2F0JzogZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0YykuaXNvZm9ybWF0KCl9XG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgbm90ZShzZWxmLCBwaGFzZSwga2V5LCB2YWx1ZSk6XG4gICAgICAgIHJlcXVpcmUoc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1bJ3N0YXRlJ10gPT0gJ1JVTk5JTkcnLCAncGhhc2UgaW50ZW50IG1pc3NpbmcnKVxuICAgICAgICBzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVtrZXldID0gdmFsdWVcbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBmaW5pc2goc2VsZiwgcGhhc2UsIHJlc3VsdCk6XG4gICAgICAgIGVudHJ5ID0gc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1cbiAgICAgICAgcmVxdWlyZShlbnRyeVsnc3RhdGUnXSA9PSAnUlVOTklORycsICdwaGFzZSBpbnRlbnQgbWlzc2luZycpXG4gICAgICAgIGVudHJ5WydyZXN1bHQnXSA9IHJlc3VsdFxuICAgICAgICBlbnRyeVsnc3RhdGUnXSA9ICdDT01QTEVURScgaWYgcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZSBlbHNlICdVTkNFUlRBSU4nXG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgY2xvc2Uoc2VsZik6XG4gICAgICAgIG9zLmNsb3NlKHNlbGYubG9jaylcbiIKICAgIH0sCiAgICAiZXhlY3V0aW9uLXBsYW4uanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICI5Y2U1NzI4YTU2MWU2ZDM4Zjg0OTcyMDFiYWEyYjg0MGQxMTQ0NGEwYWY4YWQ2MjM0ZGZjMzc0MjgxMTNmMjU4IiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcImtpbmRcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi5zdXBlcnZpc2VkLW1lY2hhbmljYWwtcmVsZWFzZS1wbGFuXCIsXG4gIFwidmVyc2lvblwiOiAyLFxuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcInN0YXRlXCI6IFwicHJlcGFyZWQtdW5hcHByb3ZlZFwiLFxuICBcImV4ZWN1dG9yX2ZpbGVzXCI6IHtcbiAgICBcImFjdHVhdG9yLnB5XCI6IFwiODZiNjdkMWFiYWQ2YWYyYThjNDk1MjhmZTEyNWE1YmFiOTQ0OTc1ZDNlODAxODI2YzUxMWVlODg4NDY1NzFiMlwiLFxuICAgIFwiYXV0aG9yaXR5X2pvdXJuYWwucHlcIjogXCIwNTM1OTc1YWU2MzEyMTlmOTBmY2U3ZTUyZjhiNTRlNjFlOGFmZDRlZjY4YmI3NDczODYzNDc4ZjBmNTE5ZjY4XCIsXG4gICAgXCJuYXRpdmVfcHJvZ3JhbS5weVwiOiBcIjc4OGRjOTlmN2VkZmJmZDU0MmEzYmIwOGZjMzFmNjBjYWY0ZjhmZDVkNjU0YTZhOTFiNDVlMTk3ZWNmZjlmOTFcIixcbiAgICBcInJlY2VpcHRfc2FmZXR5LnB5XCI6IFwiNWM1NDM3M2YyZGM0YjA2NDAwODIyNWMxODZlZmIxZDVhZmRlZWMzNmQxNTM1MGJkYTBhMTJkZWQ5NzYwMmQxYlwiXG4gIH0sXG4gIFwiY2FzZV9maWxlc1wiOiB7XG4gICAgXCJjaGFuZ2VfZ3VhcmQucHlcIjogXCJmMzQ4ZTQ0OWM0OWY0ZDllNDlhZjllODJlMDE3NjRlNzE5NzgzN2ZkM2RmOWQ3NTZmNTg5MWQ5YjhkOWIzOGJlXCIsXG4gICAgXCJzcWxpdGVfcmVhZG9ubHkucHlcIjogXCI5MDkzYzY0ZjdmMGUzOWIyNDlkYTlmZWZkZjVhYWY0ZTQyNThiYzMxZTdhMjdmZDg4ODQ3OWNlMzI5YTIwNTA5XCIsXG4gICAgXCJwcmVmbGlnaHQtaW5wdXRzLmpzb25cIjogXCIwM2JiNGI0MmZlMWFhNTFiODQ2ZTk1N2E5ZTIzOTI2ZmFlNzJmMDJhMmNiNWUyOTczNjgwNDdmYjI1YzE3ZTliXCIsXG4gICAgXCJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb25cIjogXCJkMThkMjcwNjNkMDZmNTM1YWU4ODRlYTAxZjk2NzQ3ZmUzMDE2ODU1MThhYjk0YjFjYmEwNzJhMWUxNTE5MzYyXCIsXG4gICAgXCJzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uXCI6IFwiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OVwiLFxuICAgIFwiY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvblwiOiBcIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGVcIixcbiAgICBcInJvbGxiYWNrLWRlcGxveW1lbnQuanNvblwiOiBcIjM5YjNmNDNiYjg0ZWY0OTIxY2MzYTFmYmNkYzQ0NDYxMDc0MWVkODgwOTE0OWQ4ZjhmMTdlZDgwNWYyNjIxMjFcIixcbiAgICBcImNoZWNrX2luc3RhbGxlZC5weVwiOiBcImEzNGE1MWJlOWM5ZjJiMTZhMDZhODgxNzNiNWM2YzQ5MmM5OTU3ZmUwMjFjZjQxMmE4NmExNzM3NzMwNjQwYWRcIixcbiAgICBcInB1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvblwiOiBcImU1OWFiNDRiMWFhZjI4MTQwNTA5NTkzYWFlNGFiOWI5N2FiNjJjYzhiNTg5ZTNmMTU1MmJhYzc4NjE4ODk2ZGRcIixcbiAgICBcInNlY3VyaXR5LXN1bW1hcnkuanNvblwiOiBcIjBlZTU2NDAwZGM3MDNmN2M5OTY4YzJhMGEzZWEwMzkwZDgzNjJmOGQwYmJmODAwMmEyYmQ3ZmE1OGYxOWNiNDRcIixcbiAgICBcIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWJhY2t1cC5qc29uXCI6IFwiMDI1ZGRkZjFlOTM5MzZmMzFlOThiOWZiZmE4NGFhMmJkYWFhMzM1NzNmOWQzYjBlMzJkOTQ3ZmQyODZiMTcwZVwiLFxuICAgIFwib3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtY29weS1mYWlsdXJlLmpzb25cIjogXCJmYjc4ZmIyZThjM2Q0MTY0OTBjZjBmNTU5YjJmNWJkMDE5NDA2YTQ5MGY4ZjVmYTZmNTkzMjQyMWYwYjFhYzU2XCIsXG4gICAgXCJvcmlnaW5hbC1qb3VybmFsLXNhbml0aXplZC1hbmNob3IuanNvblwiOiBcIjk4OGZjYTYxYWQ4ZWI5ZDQzZDkzMzkwYTgzNTMyM2Y5NTIxOTZiYmNlOGNjMGJkZTUxYzQyYTE3ZDQxMWY0NTRcIlxuICB9LFxuICBcIm93bmVyX3NvdXJjZV9maWxlc1wiOiB7XG4gICAgXCJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvblwiOiBcIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTVcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvblwiOiBcIjM4Yjc4YjljYmVlNWFkZTc3NTBhNThkNTE1NmNhNGM1NzczMzUyZTk0N2FjYjMwNGVlNzE0YjU5ZTc0OWNlYjRcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUva3VzdG9taXphdGlvbi55YW1sXCI6IFwiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0N1wiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uXCI6IFwiOWJhZDZkYjVmYmMyMTc4ZDMxYjA0MTIwMDE2YTQxODMwYzM1NTJmYmI5ZTI1MTdiNzE4ZjliYmU4N2NmNjQ5ZVwiXG4gIH0sXG4gIFwiY2FuZGlkYXRlX2ltYWdlXCI6IFwiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhXCIsXG4gIFwicHJpb3JfaW1hZ2VcIjogXCJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcIixcbiAgXCJzb3VyY2VfcmV2aXNpb25cIjogXCJtdXN0LWJlLWV4YWN0LWZpbmFsLW93bmVyLUhFQUQtd2l0aC1hcHByb3ZlZC1mb3VyLUdpdC1ibG9ic1wiLFxuICBcInBoYXNlc1wiOiBbXG4gICAgXCJkcmlsbC1jb3B5LXJlc2N1ZS1yMVwiLFxuICAgIFwib2ZmbGluZS12ZXJpZnlcIixcbiAgICBcImNsZWFudXAtb2ZmbGluZVwiLFxuICAgIFwiY3V0b3Zlci1iYWNrdXBcIixcbiAgICBcImN1dG92ZXItY29weVwiLFxuICAgIFwicmVsZWFzZVwiLFxuICAgIFwidmVyaWZ5XCIsXG4gICAgXCJyb2xsYmFja1wiLFxuICAgIFwicm9sbGJhY2stdmVyaWZ5XCJcbiAgXSxcbiAgXCJhdXRob3JpemF0aW9uXCI6IFwiZnJlc2ggZXh0ZXJuYWxseSBhdXRoZW50aWNhdGVkIHJvb3QgZml4ZWQtb3JpZ2luIG5hdGl2ZSByZWFkYmFjayBiZWZvcmUgZWFjaCBwaGFzZTsgZXhhY3QgY29uZmlybWVkIHBsYXRmb3JtLXJvb3QgZGlzcG9zaXRpb24gYW5kIGN1cnJlbnQgcGFja2V0IFNIQS9zb3VyY2UgY29tbWl0OyByZWNlaXB0IGJvb2trZWVwaW5nIGlzIG5vdCBhbiBhdXRvbm9tb3VzIHNpZ25lZCBncmFudFwiLFxuICBcImV4ZWN1dGVfYnlcIjogXCIyMDI2LTEwLTEyVDIzOjU5OjU5WlwiLFxuICBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZSxcbiAgXCJuYXRpdmVfZGF0YV9vcl93b3JrbG9hZF9hY3Rpb25fZXhlY3V0ZWRcIjogZmFsc2UsXG4gIFwiZGVhZGxpbmVfc2VtYW50aWNzXCI6IFwiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LlwiLFxuICBcInJlY292ZXJ5XCI6IHtcbiAgICBcIm9yaWdpbmFsX2FuY2hvclwiOiB7XG4gICAgICBcIm9yaWdpbmFsX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICAgICAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgICAgIFwiZHJpbGwtYmFja3VwXCI6IHtcbiAgICAgICAgICBcInN0YXRlXCI6IFwiQ09NUExFVEVcIixcbiAgICAgICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgICAgICBcInN0YXJ0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM4OjQ1LjMxMDY1MyswMDowMFwiXG4gICAgICAgIH0sXG4gICAgICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICAgICAgXCJzdGF0ZVwiOiBcIlVOQ0VSVEFJTlwiLFxuICAgICAgICAgIFwiYXR0ZW1wdF9pZFwiOiBcIjMyOWVmMTkwLTE2OTItNDI0Ni1iOTUzLWU2YTU5NjY0YWJjY1wiLFxuICAgICAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgICAgIFwic25hcHNob3Rfc2hhMjU2XCI6IFwiODc1NmNmODI1ZGY5ZTdiNWI3NGJiNGEwMTA2YTUwMjdmNWNmZjJjNTlmZjQ1ZDdiNDhlZWQ4NTIyYTdkMzNmM1wiLFxuICAgICAgXCJzbmFwc2hvdF9ieXRlc1wiOiAxOTUzNzkyMCxcbiAgICAgIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gICAgICBcIm9sZF91bmNlcnRhaW5fcmV0cnlfYXV0aG9yaXplZFwiOiBmYWxzZVxuICAgIH0sXG4gICAgXCJvcmlnaW5hbF9pZGVudGl0eVwiOiB7XG4gICAgICBcInByb3Bvc2FsXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgICAgIFwic291cmNlX3JldmlzaW9uXCI6IFwiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMFwiLFxuICAgICAgXCJtZW1vX3NoYTI1NlwiOiBcIjUwNmQzOTU2YmViN2M2MmFiMmJiZGZkYTc4M2MwNTkwNWQxODM0NTJhMWY2N2ExODE3ZjNmYjhjMmU1MjI5MzdcIixcbiAgICAgIFwicGxhbl9zaGEyNTZcIjogXCJmNWU1ZmE5MDZmZjE5ZDNhNDVkMTBkY2RiMjgxMDM3M2FlMjFmOWNmNDRjMDQ3MmZmMmJkNDdkM2JjMzMyOGQ2XCJcbiAgICB9LFxuICAgIFwibmV3X2pvdXJuYWxcIjogXCJyZXNjdWUtZXhlY3V0aW9uLWpvdXJuYWwtcjEuanNvblwiLFxuICAgIFwibmV3X3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgICBcIm9sZF91bmNlcnRhaW5fcGhhc2Vfb3ZlcndyaXRlX29yX3JldHJ5XCI6IGZhbHNlLFxuICAgIFwibmV3X3NuYXBzaG90X2JhY2t1cFwiOiBmYWxzZSxcbiAgICBcInNuYXBzaG90X29yX3NpZGVjYXJfbXV0YXRpb25cIjogZmFsc2UsXG4gICAgXCJtYXBwaW5nXCI6IFwib2ZmbGluZS12ZXJpZnkgY29uc3VtZXMgQ09NUExFVEUgZHJpbGwtY29weS1yZXNjdWUtcjEgcmVzdWx0OyBhbGwgbGF0ZXIgcGhhc2VzIG9yZGVyZWQgb25seSBpbiBuZXcgaGFzaC1saW5rZWQgcmVjb3Zlcnkgam91cm5hbFwiXG4gIH0sXG4gIFwic291cmNlX21lbW9fdmVyc2lvblwiOiAyLFxuICBcIm5hdGl2ZV9yZXZpZXdfbWVtb192ZXJzaW9uXCI6IDFcbn1cbiIKICAgIH0sCiAgICAibmF0aXZlX3Byb2dyYW0ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiNzg4ZGM5OWY3ZWRmYmZkNTQyYTNiYjA4ZmMzMWY2MGNhZjRmOGZkNWQ2NTRhNmE5MWI0NWUxOTdlY2ZmOWY5MSIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIkZpeGVkIHZlcnNpb24yIHJlY292ZXJ5IHJlbW90ZSBzb3VyY2U7IHJlcXVpcmVzIGZyZXNoIGV4YWN0IGFjY2VwdGFuY2UuXCJcIlwiXG5QUk9HUkFNID0gJ1xcbmltcG9ydCBjb3B5LGRhdGV0aW1lLGhhc2hsaWIsanNvbixvcyxyZSxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxucGF5bG9hZD1qc29uLmxvYWRzKF9fUEFZTE9BRF9fKVxcbmV4ZWMoX19HVUFSRF9fKVxcbnBoYXNlPXBheWxvYWRbXFwncGhhc2VcXCddXFxuaWYgcGhhc2Ugbm90IGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2tcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2ZpeGVkIG5hdGl2ZSBwaGFzZSByZXF1aXJlZFxcJylcXG5kZWFkbGluZT1kYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KFxcJzIwMjYtMTAtMTJUMjM6NTk6NTkrMDA6MDBcXCcpXFxuZGVmIHJlcXVpcmUodmFsdWUscmVhc29uKTpcXG4gaWYgbm90IHZhbHVlOnJhaXNlIFZhbHVlRXJyb3IocmVhc29uKVxcbnJlcXVpcmUoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0Yyk8ZGVhZGxpbmUsXFwnZXhlY3V0aW9uIHdpbmRvdyBleHBpcmVkXFwnKVxcbmVudj17Kipvcy5lbnZpcm9uLFxcJ0tVQkVDT05GSUdcXCc6XFwnL2V0Yy9yYW5jaGVyL2szcy9rM3MueWFtbFxcJ31cXG5kZWYgcnVuKGFyZ3YsYm9keT1Ob25lLHRpbWVvdXQ9OTApOlxcbiByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndixpbnB1dD1ib2R5LHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlLHRpbWVvdXQ9dGltZW91dCxlbnY9ZW52KVxcbmRlZiByZWFkKGtpbmQsbmFtZSxuYW1lc3BhY2UpOlxcbiByZXN1bHQ9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxraW5kLG5hbWUsXFwnLW5cXCcsbmFtZXNwYWNlLFxcJy1vXFwnLFxcJ2pzb25cXCddKVxcbiByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlPT0wLFxcJ2ZpeGVkIG1ldGFkYXRhIHJlYWQgcmVmdXNlZFxcJylcXG4gcmV0dXJuIGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcXG5zZWFsZWQ9cGF5bG9hZFtcXCdzZWFsZWRcXCddOyBkZXBlbmRlbmNpZXM9cGF5bG9hZFtcXCdkZXBlbmRlbmNpZXNcXCddXFxubGl2ZT1yZWFkKFxcJ2RlcGxveW1lbnRcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY209cmVhZChcXCdjb25maWdtYXBcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxucHZjPXJlYWQoXFwncHZjXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uLWRhdGFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY2hlY2tfZGVwZW5kZW5jaWVzKGNtLHB2YyxkZXBlbmRlbmNpZXMpXFxuYXBwPXJlYWQoXFwnYXBwbGljYXRpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnYXJnb2NkXFwnKVxcbnJlcXVpcmUoYXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddPT1cXCc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGRcXCcsXFwnQXBwbGljYXRpb24gVUlEIGNoYW5nZWRcXCcpXFxucmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdyZXBvVVJMXFwnXT09XFwnaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0XFwnXFxuIGFuZCBhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdwYXRoXFwnXT09XFwnZGVwbG95L2xpZmVjeWNsZVxcJ1xcbiBhbmQgYXBwW1xcJ3NwZWNcXCddW1xcJ2Rlc3RpbmF0aW9uXFwnXT09e1xcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCdzZXJ2ZXJcXCc6XFwnaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjXFwnfVxcbiBhbmQgYXBwW1xcJ3NwZWNcXCddLmdldChcXCdzeW5jUG9saWN5XFwnLHt9KS5nZXQoXFwnYXV0b21hdGVkXFwnKSBpcyBOb25lXFxuIGFuZCBzZXQoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ10pPT17XFwncmVwb1VSTFxcJyxcXCdwYXRoXFwnLFxcJ3RhcmdldFJldmlzaW9uXFwnfSBhbmQgbm90IGFwcFtcXCdzcGVjXFwnXS5nZXQoXFwnc291cmNlc1xcJyksXFwnQXBwbGljYXRpb24gb3duZXIvc2NvcGUgY2hhbmdlZFxcJylcXG5leHBlY3RlZD1jb3B5LmRlZXBjb3B5KHNlYWxlZClcXG5pZiBwaGFzZT09XFwndmVyaWZ5XFwnOmV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOlxcbiBpbWFnZT1saXZlW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ11cXG4gcmVxdWlyZShpbWFnZSBpbiAoQkFTRSxDQU5ESURBVEUpLFxcJ3JvbGxiYWNrIGltYWdlIGlzIG91dHNpZGUgc2FtZS1zY2hlbWEgcGFpclxcJylcXG4gZXhwZWN0ZWRbXFwnc3BlY1xcJ11bXFwndGVtcGxhdGVcXCddW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXT1pbWFnZVxcbmNoZWNrX2N1cnJlbnQobGl2ZSxleHBlY3RlZClcXG5pZiBwaGFzZSE9XFwncm9sbGJhY2tcXCc6XFxuIHJlcXVpcmUobGl2ZS5nZXQoXFwnc3RhdHVzXFwnLHt9KS5nZXQoXFwncmVhZHlSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ3VwZGF0ZWRSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ29ic2VydmVkR2VuZXJhdGlvblxcJyk9PWxpdmVbXFwnbWV0YWRhdGFcXCddW1xcJ2dlbmVyYXRpb25cXCddLFxcJ3NlcnZpY2Ugbm90IFJlYWR5MVxcJylcXG50YXJnZXQ9cGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddIGlmIHBoYXNlPT1cXCd2ZXJpZnlcXCcgZWxzZSBcXCc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmXFwnXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwndGFyZ2V0UmV2aXNpb25cXCddIGluICh0YXJnZXQscGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddKSxcXCdyb2xsYmFjayBzb3VyY2UgaXMgb3V0c2lkZSBwYWlyXFwnKVxcbmVsc2U6cmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ109PXRhcmdldCxcXCd1bmV4cGVjdGVkIHNvdXJjZSBwaW5cXCcpXFxucmVzdWx0PXtcXCdwaGFzZVxcJzpwaGFzZSxcXCdhbGxfY2hlY2tzX3Bhc3NcXCc6RmFsc2UsXFwncmF3X291dHB1dF93aXRoaGVsZFxcJzpUcnVlLFxcbiBcXCduYXRpdmVfYXBwcm92YWxfdmVyaWZpZWRfYnlfcm9vdFxcJzpwYXlsb2FkW1xcJ2FwcHJvdmFsXFwnXSxcXCduYXRpdmVfYXV0aGVudGljYXRlZF9ncmFudFxcJzpGYWxzZX1cXG50cnk6XFxuIGlmIHBoYXNlIGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gIHBvZGxpc3Q9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxcXCdwb2RzXFwnLFxcJy1uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy1sXFwnLFxcJ2FwcC5rdWJlcm5ldGVzLmlvL25hbWU9aW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pXFxuICByZXF1aXJlKHBvZGxpc3QucmV0dXJuY29kZT09MCxcXCdwb2QgbWV0YWRhdGEgcXVlcnkgcmVmdXNlZFxcJylcXG4gIHBvZHM9W3AgZm9yIHAgaW4ganNvbi5sb2Fkcyhwb2RsaXN0LnN0ZG91dClbXFwnaXRlbXNcXCddIGlmIG5vdCBwW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnZGVsZXRpb25UaW1lc3RhbXBcXCcpXVxcbiAgcmVxdWlyZShsZW4ocG9kcyk9PTEsXFwnZXhhY3Qgc2luZ2xlIGxpdmUgb3duZXIgcG9kIHJlcXVpcmVkXFwnKTtwb2Q9cG9kc1swXVxcbiAgcmVxdWlyZShwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwncGhhc2VcXCcpPT1cXCdSdW5uaW5nXFwnIGFuZCBsZW4ocG9kW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddKT09MVxcbiAgIGFuZCBwb2RbXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddPT1leHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddXFxuICAgYW5kIGxlbihwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwnY29udGFpbmVyU3RhdHVzZXNcXCcsW10pKT09MVxcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ25hbWVcXCcpPT1cXCdpbmZvcm1lZC1kZWNpc2lvblxcJ1xcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ3JlYWR5XFwnKSBpcyBUcnVlLFxcJ293bmVyIHBvZCByZWFkaW5lc3MvaW1hZ2UgY2hhbmdlZFxcJylcXG4gIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJzpyZXF1aXJlKHBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09XFwnZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XFwnLFxcJ29yaWdpbmFsIGJhY2t1cCBQb2QgaWRlbnRpdHkgY2hhbmdlZFxcJylcXG4gIHRlbXBsYXRlPWV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVxcbiAgY29udHJvbGxlZD1zZXQodGVtcGxhdGUpfHtcXCdpbml0Q29udGFpbmVyc1xcJyxcXCdob3N0TmV0d29ya1xcJyxcXCdob3N0UElEXFwnLFxcJ2hvc3RJUENcXCcsXFwncnVudGltZUNsYXNzTmFtZVxcJyxcXCdzaGFyZVByb2Nlc3NOYW1lc3BhY2VcXCd9XFxuICByZXF1aXJlKGFsbChwb2RbXFwnc3BlY1xcJ10uZ2V0KGtleSk9PXRlbXBsYXRlLmdldChrZXkpIGZvciBrZXkgaW4gY29udHJvbGxlZCksXFwnYWN0dWFsIG93bmVyIFBvZCBjb25maWd1cmF0aW9uIGRyaWZ0ZWRcXCcpXFxuICBvd25lcnM9cG9kW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnb3duZXJSZWZlcmVuY2VzXFwnLFtdKTtyZXF1aXJlKGxlbihvd25lcnMpPT0xIGFuZCBvd25lcnNbMF1bXFwna2luZFxcJ109PVxcJ1JlcGxpY2FTZXRcXCcsXFwncG9kIG93bmVyIGNoYWluIGNoYW5nZWRcXCcpXFxuICBycz1yZWFkKFxcJ3JlcGxpY2FzZXRcXCcsb3duZXJzWzBdW1xcJ25hbWVcXCddLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbiAgcmVxdWlyZShyc1tcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09b3duZXJzWzBdW1xcJ3VpZFxcJ10gYW5kIGFueShvLmdldChcXCd1aWRcXCcpPT1zZWFsZWRbXFwnbWV0YWRhdGFcXCddW1xcJ3VpZFxcJ11cXG4gICBhbmQgby5nZXQoXFwna2luZFxcJyk9PVxcJ0RlcGxveW1lbnRcXCcgZm9yIG8gaW4gcnNbXFwnbWV0YWRhdGFcXCddLmdldChcXCdvd25lclJlZmVyZW5jZXNcXCcsW10pKSxcXCdSZXBsaWNhU2V0IG93bmVyc2hpcCBjaGFuZ2VkXFwnKVxcbiAgaW5uZXI9clwiXCJcIlxcbmltcG9ydCBoYXNobGliLGpzb24sb3Msc3RhdCxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxuZXhlYyhfX1JFQURPTkxZX18pXFxuZXhlYyhfX1NBRkVUWV9fKVxcbmFjdGlvbj1fX0FDVElPTl9fO2RiPVxcJy9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZVxcJztmb2xkZXI9XFwnL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjFcXCdcXG5kZWYgcmVxdWlyZSh2LHIpOlxcbiBpZiBub3QgdjpyYWlzZSBWYWx1ZUVycm9yKHIpXFxucmVxdWlyZShvcy5nZXR1aWQoKT09MTAwMDEgYW5kIG9zLmdldGdpZCgpPT0xMDAwMSxcXCduYXRpdmUgb3duZXIgVUlEL0dJRCByZXF1aXJlZFxcJylcXG5kZWYgcHJpdmF0ZShwLGRpcmVjdG9yeT1GYWxzZSk6XFxuIHM9b3MubHN0YXQocCk7cmVxdWlyZSgoc3RhdC5TX0lTRElSKHMuc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKHMuc3RfbW9kZSkpXFxuICBhbmQgcy5zdF91aWQ9PTEwMDAxIGFuZCBzdGF0LlNfSU1PREUocy5zdF9tb2RlKT09KDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxcbiAgYW5kIChkaXJlY3Rvcnkgb3Igcy5zdF9ubGluaz09MSksXFwncHJpdmF0ZSBuYXRpdmUgY3VzdG9keSByZXF1aXJlZFxcJylcXG5wcml2YXRlKFxcJy9kYXRhL3ByaXZhdGVcXCcsVHJ1ZSk7cHJpdmF0ZShkYilcXG5iYXNlbGluZT1jb3VudHMoaW5zcGVjdF9yZWFkb25seShkYikpICMgTVVTVCBwcmVjZWRlIGFueSBTdG9yZS9hZG1pbiBvcGVuLlxcbmlmIGFjdGlvbiBpbiAoXFwnY3V0b3Zlci1iYWNrdXBcXCcpOlxcbiBzaXplPW9zLnN0YXQoZGIpLnN0X3NpemVcXG4gaWYgb3MucGF0aC5leGlzdHMoZGIrXFwnLXdhbFxcJyk6c2l6ZSs9b3Muc3RhdChkYitcXCctd2FsXFwnKS5zdF9zaXplXFxuIHY9b3Muc3RhdHZmcyhcXCcvZGF0YS9wcml2YXRlXFwnKTtmcmVlPXYuZl9iYXZhaWwqdi5mX2Zyc2l6ZVxcbiByZXF1aXJlKHNpemU+MCBhbmQgc2l6ZTw9NTEyKjEwMjQqKjIgYW5kIGZyZWU+PXNpemUqKDIgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSAxKSsxNioxMDI0KioyLFxcJ2JvdW5kZWQgbmF0aXZlIHNuYXBzaG90IGNhcGFjaXR5IHJlcXVpcmVkXFwnKVxcbiBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJzpcXG4gIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhmb2xkZXIpLFxcJ25hdGl2ZSBjYXNlIGRpcmVjdG9yeSBtdXN0IGJlIHVuaXF1ZVxcJylcXG4gIG9zLm1rZGlyKGZvbGRlciwwbzcwMCk7b3MuY2htb2QoZm9sZGVyLDBvNzAwKVxcbiBwcml2YXRlKGZvbGRlcixUcnVlKVxcbiBmaWxlbmFtZT1cXCdkcmlsbC5zcWxpdGVcXCcgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSBcXCdjdXRvdmVyLnNxbGl0ZVxcJztvdXRwdXQ9Zm9sZGVyK1xcJy9cXCcrZmlsZW5hbWVcXG4gcmVxdWlyZShub3Qgb3MucGF0aC5sZXhpc3RzKG91dHB1dCksXFwnc25hcHNob3Qgb3V0cHV0IG11c3QgYmUgdW5pcXVlXFwnKVxcbiBhZG1pbj1zdWJwcm9jZXNzLnJ1bihbXFwnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW5cXCcsXFwnYmFja3VwXFwnLFxcJy0tZGJcXCcsZGIsXFwnLS1vdXRwdXRcXCcsb3V0cHV0XSxjYXB0dXJlX291dHB1dD1UcnVlLHRleHQ9VHJ1ZSx0aW1lb3V0PTEyMClcXG4gcmVxdWlyZShhZG1pbi5yZXR1cm5jb2RlPT0wIGFuZCBqc29uLmxvYWRzKGFkbWluLnN0ZG91dCk9PXtcXCdzdGF0dXNcXCc6XFwnYmFja2VkX3VwXFwnLFxcJ2NvbnNpc3RlbnRfc25hcHNob3RcXCc6VHJ1ZX0sXFwnYmFja3VwIGNvbXBsZXRpb24gbm90IHZlcmlmaWVkOyBkbyBub3QgcmV0cnlcXCcpXFxuIHByaXZhdGUob3V0cHV0KVxcbiBmb3Igc3VmZml4IGluIChcXCctd2FsXFwnLCk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnc25hcHNob3QgaGFzIFdBTCBmcmFtZXM7IGltbXV0YWJsZSByZWFkIHJlZnVzZWRcXCcpXFxuIGRpZ2VzdD1oYXNobGliLnNoYTI1NigpXFxuIHdpdGggb3BlbihvdXRwdXQsXFwncmJcXCcpIGFzIHN0cmVhbTpcXG4gIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTpzdHJlYW0ucmVhZCgxMDI0KioyKSxiXFwnXFwnKTpkaWdlc3QudXBkYXRlKGJsb2NrKVxcbiBmcm96ZW5fZGlnZXN0PWRpZ2VzdC5oZXhkaWdlc3QoKVxcbiBzbmFwc2hvdD1jb3VudHMoaW5zcGVjdF9jbG9zZWRfc25hcHNob3Qob3V0cHV0LGZyb3plbl9kaWdlc3QpKVxcbiBzaXplPW9zLnN0YXQob3V0cHV0KS5zdF9zaXplO3JlcXVpcmUoMDxzaXplPD01MTIqMTAyNCoqMixcXCdzbmFwc2hvdCBvdXRzaWRlIGJvdW5kZWQgY29weSBzaXplXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXFwnOmJhc2VsaW5lLFxcJ3NuYXBzaG90X3JlYWRvbmx5XFwnOnNuYXBzaG90LFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfYnl0ZXNcXCc6c2l6ZSxcXCdzbmFwc2hvdF9maWxlXFwnOmZpbGVuYW1lLFxcJ25hdGl2ZV9wYXJlbnRfcHJpdmF0ZVxcJzpUcnVlLFxcJ25hdGl2ZV91aWRcXCc6b3MuZ2V0dWlkKCl9KSlcXG5lbGlmIGFjdGlvbiBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gcHJvb2Y9e1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHNcXCc6YmFzZWxpbmUsXFwnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzXFwnOlRydWV9XFxuIGlmIGFjdGlvbj09XFwndmVyaWZ5XFwnOlxcbiAgaW1wb3J0IHVybGxpYi5yZXF1ZXN0XFxuICBtb2R1bGU9XFwnL29wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24vcG9saWN5LnB5XFwnO2luZm89b3MubHN0YXQobW9kdWxlKVxcbiAgcmVxdWlyZShzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBhbmQgaW5mby5zdF91aWQ9PTAgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpPT0wbzY0NCxcXCdpbnN0YWxsZWQgcG9saWN5IG1ldGFkYXRhIGRpZmZlcnNcXCcpXFxuICB3aXRoIG9wZW4obW9kdWxlLFxcJ3JiXFwnKSBhcyBzb3VyY2U6bW9kdWxlX2RpZ2VzdD1oYXNobGliLnNoYTI1Nihzb3VyY2UucmVhZCgpKS5oZXhkaWdlc3QoKVxcbiAgcmVxdWlyZShtb2R1bGVfZGlnZXN0PT1cXCc5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyXFwnLFxcJ2luc3RhbGxlZCBzb3VyY2UgbW9kdWxlIGRpZmZlcnNcXCcpXFxuICBwdXJwb3NlPXN1YnByb2Nlc3MucnVuKFtzeXMuZXhlY3V0YWJsZSxcXCctXFwnXSxpbnB1dD1fX1BVUlBPU0VfXyx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0aW1lb3V0PTMwKVxcbiAgcmVxdWlyZShwdXJwb3NlLnJldHVybmNvZGU9PTAsXFwnaW5zdGFsbGVkIG5hdGl2ZS1wbGFjZW1lbnQgcHVycG9zZSBjaGVja3MgZmFpbGVkXFwnKVxcbiAgdGVzdGVkPWpzb24ubG9hZHMocHVycG9zZS5zdGRvdXQpXFxuICByZXF1aXJlKHRlc3RlZD09e1xcJ2luc3RhbGxlZF9pbWFnZV9wdXJwb3NlX3ZhcmlhbnRzXFwnOjEwLFxcJ2JpbmRpbmdfZm9ybXNfYWxsb3dlZFxcJzoyLFxcJ2Fkdmlzb3J5X29yX21hbGZvcm1lZF9yZWZ1c2VkXFwnOjgsXFwnc3ludGhldGljX29ubHlcXCc6VHJ1ZSxcXCduYXRpdmVfcHJvdmlkZXJcXCc6RmFsc2V9LFxcJ3B1cnBvc2UgcmVzdWx0IGRpZmZlcnNcXCcpXFxuICBjbGFzcyBOb1JlZGlyZWN0KHVybGxpYi5yZXF1ZXN0LkhUVFBSZWRpcmVjdEhhbmRsZXIpOlxcbiAgIGRlZiByZWRpcmVjdF9yZXF1ZXN0KHNlbGYsKmFyZ3MsKiprd2FyZ3MpOnJhaXNlIFZhbHVlRXJyb3IoXFwnaGVhbHRoIHJlZGlyZWN0IHJlZnVzZWRcXCcpXFxuICBvcGVuZXI9dXJsbGliLnJlcXVlc3QuYnVpbGRfb3BlbmVyKE5vUmVkaXJlY3QoKSk7c3RhdHVzZXM9e31cXG4gIGZvciByb3V0ZSBpbiAoXFwnL2hlYWx0aHpcXCcsXFwnL3JlYWR5elxcJyk6XFxuICAgd2l0aCBvcGVuZXIub3BlbihcXCdodHRwOi8vMTI3LjAuMC4xOjgwODBcXCcrcm91dGUsdGltZW91dD0xMCkgYXMgcmVzcG9uc2U6XFxuICAgIHJlcXVpcmUocmVzcG9uc2Uuc3RhdHVzPT0yMDAgYW5kIGxlbihyZXNwb25zZS5yZWFkKDgxOTMpKTw9ODE5MixcXCdib3VuZGVkIGhlYWx0aCBjaGVjayByZWZ1c2VkXFwnKTtzdGF0dXNlc1tyb3V0ZV09MjAwXFxuICBwcm9vZi51cGRhdGUoaW5zdGFsbGVkX3B1cnBvc2VfY2hlY2tzPXRlc3RlZCxwb2xpY3lfc2hhMjU2PW1vZHVsZV9kaWdlc3QscG9saWN5X21vZGU9XFwnMDY0NFxcJyxwb2xpY3lfdWlkPTAsaGVhbHRoX3N0YXR1c2VzPXN0YXR1c2VzLG5hdGl2ZV9wcm92aWRlcl9wcm9iZT1GYWxzZSlcXG4gcHJpbnQoanNvbi5kdW1wcyhwcm9vZikpXFxuZWxpZiBhY3Rpb24gaW4gKFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnKTpcXG4gcHJpdmF0ZShmb2xkZXIsVHJ1ZSk7ZmlsZW5hbWU9XFwnZHJpbGwuc3FsaXRlXFwnIGlmIGFjdGlvbj09XFwnZHJpbGwtY29weVxcJyBlbHNlIFxcJ2N1dG92ZXIuc3FsaXRlXFwnO291dHB1dD1mb2xkZXIrXFwnL1xcJytmaWxlbmFtZTtwcml2YXRlKG91dHB1dClcXG4gaWRlbnRpdHk9X19TTkFQU0hPVF9fO3JlcXVpcmUoaXNpbnN0YW5jZShpZGVudGl0eSxkaWN0KSBhbmQgaWRlbnRpdHkuZ2V0KFxcJ3NuYXBzaG90X2ZpbGVcXCcpPT1maWxlbmFtZSxcXCdyZWNvcmRlZCBvcmlnaW5hbCBmcm96ZW4gc25hcHNob3QgaWRlbnRpdHkgcmVxdWlyZWRcXCcpXFxuIHNuYXBzaG90PWNvdW50cyhpbnNwZWN0X2Nsb3NlZF9zbmFwc2hvdChvdXRwdXQsaWRlbnRpdHlbXFwnc25hcHNob3Rfc2hhMjU2XFwnXSkpO3NpemU9b3Muc3RhdChvdXRwdXQpLnN0X3NpemU7cmVxdWlyZShzaXplPT1pZGVudGl0eVtcXCdzbmFwc2hvdF9ieXRlc1xcJ10gYW5kIDA8c2l6ZTw9NTEyKjEwMjQqKjIsXFwnc25hcHNob3Qgc2l6ZSBvdXRzaWRlIGZyb3plbiBib3VuZFxcJylcXG4gcmVxdWlyZShzbmFwc2hvdD09aWRlbnRpdHlbXFwnc25hcHNob3RfcmVhZG9ubHlcXCddLFxcJ2Zyb3plbiBzbmFwc2hvdCBwcm9vZiBkaWZmZXJzXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc25hcHNob3RfZmlsZVxcJzpmaWxlbmFtZSxcXCdzbmFwc2hvdF9ieXRlc1xcJzpzaXplLFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfcmVhZG9ubHlcXCc6c25hcHNob3R9KSlcXG5lbHNlOnJhaXNlIFZhbHVlRXJyb3IoXFwnZml4ZWQgbmF0aXZlIGJhY2t1cC92ZXJpZnkgcGhhc2UgcmVxdWlyZWRcXCcpXFxuXCJcIlwiXFxuICAjIFN0cmlwIHRoZSBDTEkgYnJhbmNoOiBleGVjIG9ubHkgdGhlIHZlcmlmaWVkIHN0ZGxpYiBmdW5jdGlvbiwgbmV2ZXIgU3RvcmUuXFxuICByZWFkb25seT1wYXlsb2FkW1xcJ3JlYWRvbmx5XFwnXS5zcGxpdChcImlmIF9fbmFtZV9fID09IFxcJ19fbWFpbl9fXFwnOlwiLDEpWzBdXFxuICBpbm5lcj1pbm5lci5yZXBsYWNlKFxcJ19fUkVBRE9OTFlfX1xcJyxyZXByKHJlYWRvbmx5KSkucmVwbGFjZShcXCdfX1NBRkVUWV9fXFwnLHJlcHIocGF5bG9hZFtcXCdyZWNlaXB0X3NhZmV0eVxcJ10pKS5yZXBsYWNlKFxcJ19fQUNUSU9OX19cXCcscmVwcihcXCdkcmlsbC1jb3B5XFwnIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyBlbHNlIHBoYXNlKSkucmVwbGFjZShcXCdfX1BVUlBPU0VfX1xcJyxyZXByKHBheWxvYWRbXFwncHVycG9zZV9jaGVja3NcXCddKSkucmVwbGFjZShcXCdfX1NOQVBTSE9UX19cXCcscmVwcihwYXlsb2FkLmdldChcXCdzbmFwc2hvdF9pZGVudGl0eVxcJykpKVxcbiAgcD1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnZXhlY1xcJyxcXCctaVxcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxwb2RbXFwnbWV0YWRhdGFcXCddW1xcJ25hbWVcXCddLFxcJy1jXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy0tXFwnLFxcJ3B5dGhvblxcJyxcXCctXFwnXSxpbm5lciwxNTApXFxuICByZXF1aXJlKHAucmV0dXJuY29kZT09MCxcXCduYXRpdmUgcGhhc2Ugb3V0Y29tZSB1bnZlcmlmaWVkOyByYXcgb3V0cHV0IHdpdGhoZWxkLCBkbyBub3QgcmV0cnlcXCcpXFxuICBvdXRjb21lPWpzb24ubG9hZHMocC5zdGRvdXQpO3JlcXVpcmUob3V0Y29tZS5nZXQoXFwnYWxsX2NoZWNrc19wYXNzXFwnKSBpcyBUcnVlLFxcJ25hdGl2ZSBwaGFzZSBnYXRlIHJlZnVzZWRcXCcpXFxuICByZXN1bHQudXBkYXRlKG91dGNvbWUscG9kX25hbWU9cG9kW1xcJ21ldGFkYXRhXFwnXVtcXCduYW1lXFwnXSxwb2RfdWlkPXBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXSlcXG4gaWYgcGhhc2UgaW4gKFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2tcXCcpOlxcbiAgbm9kZV9yZWFkPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwnbm9kZXNcXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pO3JlcXVpcmUobm9kZV9yZWFkLnJldHVybmNvZGU9PTAsXFwnbm9kZSBtZXRhZGF0YSB1bmF2YWlsYWJsZVxcJylcXG4gIG5vZGVzPWpzb24ubG9hZHMobm9kZV9yZWFkLnN0ZG91dClbXFwnaXRlbXNcXCddO3JlcXVpcmUobGVuKG5vZGVzKT09MSxcXCdvbmUgdGFyZ2V0IG5vZGUgcmVxdWlyZWRcXCcpO25vZGU9bm9kZXNbMF1cXG4gIHJlcXVpcmUoYW55KGEuZ2V0KFxcJ2FkZHJlc3NcXCcpPT1cXCc5Mi4yMDUuNjIuMjM5XFwnIGZvciBhIGluIG5vZGVbXFwnc3RhdHVzXFwnXVtcXCdhZGRyZXNzZXNcXCddKSxcXCd0YXJnZXQgbm9kZSBhZGRyZXNzIGNoYW5nZWRcXCcpXFxuICBjb25kaXRpb25zPXtjW1xcJ3R5cGVcXCddOmNbXFwnc3RhdHVzXFwnXSBmb3IgYyBpbiBub2RlW1xcJ3N0YXR1c1xcJ11bXFwnY29uZGl0aW9uc1xcJ119XFxuICByZXF1aXJlKGNvbmRpdGlvbnMuZ2V0KFxcJ1JlYWR5XFwnKT09XFwnVHJ1ZVxcJyBhbmQgYWxsKGNvbmRpdGlvbnMuZ2V0KGspPT1cXCdGYWxzZVxcJyBmb3IgayBpbiAoXFwnTWVtb3J5UHJlc3N1cmVcXCcsXFwnRGlza1ByZXNzdXJlXFwnLFxcJ1BJRFByZXNzdXJlXFwnKSksXFwnbm9kZSB1bmhlYWx0aHkgb3IgcHJlc3N1cmVkXFwnKVxcbiAgZGVzY3JpcHRpb249cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2Rlc2NyaWJlXFwnLFxcJ25vZGVcXCcsbm9kZVtcXCdtZXRhZGF0YVxcJ11bXFwnbmFtZVxcJ11dKTtyZXF1aXJlKGRlc2NyaXB0aW9uLnJldHVybmNvZGU9PTAsXFwnaGVhZHJvb20gY2FwdHVyZSB1bmF2YWlsYWJsZVxcJylcXG4gIHRhYmxlPWRlc2NyaXB0aW9uLnN0ZG91dC5zcGxpdChcXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcJywxKVsxXTtyZXF1ZXN0ZWQ9aW50KHJlLnNlYXJjaChyXFwnY3B1XFxcXHMrKFxcXFxkKyltXFwnLHRhYmxlKS5ncm91cCgxKSk7YWxsb2M9bm9kZVtcXCdzdGF0dXNcXCddW1xcJ2FsbG9jYXRhYmxlXFwnXVtcXCdjcHVcXCddO2NhcGFjaXR5PWludChhbGxvY1s6LTFdKSBpZiBhbGxvYy5lbmRzd2l0aChcXCdtXFwnKSBlbHNlIGludChhbGxvYykqMTAwMFxcbiAgcmVxdWlyZShyZXF1ZXN0ZWQ8PWNhcGFjaXR5LFxcJ1JlY3JlYXRlIHJlcXVlc3RlZCBDUFUgZXhjZWVkcyBjYXBhY2l0eVxcJylcXG4gIHJlcXVpcmUobm90IGFwcC5nZXQoXFwnb3BlcmF0aW9uXFwnKSBhbmQgYXBwLmdldChcXCdzdGF0dXNcXCcse30pLmdldChcXCdvcGVyYXRpb25TdGF0ZVxcJyx7fSkuZ2V0KFxcJ3BoYXNlXFwnKSBub3QgaW4gKFxcJ1J1bm5pbmdcXCcsXFwnVGVybWluYXRpbmdcXCcpLFxcJ2V4aXN0aW5nIEFyZ28gb3BlcmF0aW9uIG11c3QgYmUgc2V0dGxlZFxcJylcXG4gIGRlc3RpbmF0aW9uPXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwncmVsZWFzZVxcJyBlbHNlIFxcJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmZcXCdcXG4gIGJvZHk9Y29weS5kZWVwY29weShwYXlsb2FkW1xcJ2NhbmRpZGF0ZVxcJ10gaWYgcGhhc2U9PVxcJ3JlbGVhc2VcXCcgZWxzZSBwYXlsb2FkW1xcJ3JvbGxiYWNrXFwnXSlcXG4gIGRyeT1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnYXBwbHlcXCcsXFwnLS1kcnktcnVuPXNlcnZlclxcJyxcXCctZlxcJyxcXCctXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddLGpzb24uZHVtcHMoYm9keSkpXFxuICByZXF1aXJlKGRyeS5yZXR1cm5jb2RlPT0wLFxcJ2ZyZXNoIG93bmVyIHNlcnZlciBhZG1pc3Npb24gcmVmdXNlZFxcJylcXG4gIGFkbWl0dGVkPWpzb24ubG9hZHMoZHJ5LnN0ZG91dCk7d2FudGVkPWNvcHkuZGVlcGNvcHkoc2VhbGVkKVxcbiAgd2FudGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFIGlmIHBoYXNlPT1cXCdyZWxlYXNlXFwnIGVsc2UgQkFTRVxcbiAgcmVxdWlyZShwcm9qZWN0aW9uKGFkbWl0dGVkKT09d2FudGVkLFxcJ2RyeS1ydW4gY2hhbmdlZCBhbnl0aGluZyBiZXlvbmQgZXhhY3QgaW1hZ2VcXCcpXFxuICBkaWZmPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdkaWZmXFwnLFxcJy1mXFwnLFxcJy1cXCddLGpzb24uZHVtcHMoYm9keSkpO3JlcXVpcmUoZGlmZi5yZXR1cm5jb2RlIGluICgwLDEpLFxcJ2NsaWVudCBkaWZmIHVuYXZhaWxhYmxlXFwnKVxcbiAgb3BlcmF0aW9uPXtcXCdpbml0aWF0ZWRCeVxcJzp7XFwndXNlcm5hbWVcXCc6XFwnY3VzdG9kaWFuLWNvZGV4XFwnfSxcXCdzeW5jXFwnOntcXCdyZXZpc2lvblxcJzpkZXN0aW5hdGlvbixcXCdwcnVuZVxcJzpGYWxzZSxcXG4gICBcXCdyZXNvdXJjZXNcXCc6W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dfX1cXG4gIHBhdGNoPVt7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS91aWRcXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS9yZXNvdXJjZVZlcnNpb25cXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCdyZXNvdXJjZVZlcnNpb25cXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9zcGVjL3NvdXJjZS90YXJnZXRSZXZpc2lvblxcJyxcXCd2YWx1ZVxcJzphcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ119LFxcbiAgIHtcXCdvcFxcJzpcXCdyZXBsYWNlXFwnLFxcJ3BhdGhcXCc6XFwnL3NwZWMvc291cmNlL3RhcmdldFJldmlzaW9uXFwnLFxcJ3ZhbHVlXFwnOmRlc3RpbmF0aW9ufSxcXG4gICB7XFwnb3BcXCc6XFwnYWRkXFwnLFxcJ3BhdGhcXCc6XFwnL29wZXJhdGlvblxcJyxcXCd2YWx1ZVxcJzpvcGVyYXRpb259XVxcbiAgYXJndj1bXFwna3ViZWN0bFxcJyxcXCdwYXRjaFxcJyxcXCdhcHBsaWNhdGlvblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctblxcJyxcXCdhcmdvY2RcXCcsXFwnLS10eXBlPWpzb25cXCcsXFwnLS1wYXRjaC1maWxlPS9kZXYvc3RkaW5cXCcsXFwnLW9cXCcsXFwnbmFtZVxcJ11cXG4gIHBhdGNoZHJ5PXJ1bihhcmd2K1tcXCctLWRyeS1ydW49c2VydmVyXFwnXSxqc29uLmR1bXBzKHBhdGNoKSk7cmVxdWlyZShwYXRjaGRyeS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIG9wZXJhdGlvbiBkcnktcnVuIHJlZnVzZWRcXCcpXFxuICBjaGFuZ2U9cnVuKGFyZ3YsanNvbi5kdW1wcyhwYXRjaCkpXFxuICByZXF1aXJlKGNoYW5nZS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIHBhdGNoIG91dGNvbWUgYW1iaWd1b3VzOyBkbyBub3QgcmV0cnlcXCcpXFxuICByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1UcnVlLG9wZXJhdGlvbl9yZXF1ZXN0ZWQ9VHJ1ZSxzb3VyY2VfcmV2aXNpb249ZGVzdGluYXRpb24sXFxuICAgcmVzb3VyY2VzPW9wZXJhdGlvbltcXCdzeW5jXFwnXVtcXCdyZXNvdXJjZXNcXCddLHBydW5lPUZhbHNlLHJvbGxvdXRfdmVyaWZpZWQ9RmFsc2UsXFxuICAgbGF0ZXN0X2xpdmVfZGF0YWJhc2VfcmV0YWluZWQ9VHJ1ZSxjbGllbnRfZGlmZl9zaGEyNTY9aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpKVxcbiBpZiBwaGFzZSBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBvcD1hcHAuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ29wZXJhdGlvblN0YXRlXFwnLHt9KTtzeW5jPW9wLmdldChcXCdvcGVyYXRpb25cXCcse30pLmdldChcXCdzeW5jXFwnLHt9KVxcbiAgcmVxdWlyZShvcC5nZXQoXFwncGhhc2VcXCcpPT1cXCdTdWNjZWVkZWRcXCcgYW5kIHN5bmMuZ2V0KFxcJ3JldmlzaW9uXFwnKT09dGFyZ2V0IGFuZCBzeW5jLmdldChcXCdwcnVuZVxcJykgaXMgRmFsc2VcXG4gICBhbmQgc3luYy5nZXQoXFwncmVzb3VyY2VzXFwnKT09W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dLFxcJ2V4YWN0IG5hdGl2ZSBBcmdvIG9wZXJhdGlvbiBjb21wbGV0aW9uIHVudmVyaWZpZWRcXCcpXFxuICByZXF1aXJlKGxpdmVbXFwnc3RhdHVzXFwnXS5nZXQoXFwnb2JzZXJ2ZWRHZW5lcmF0aW9uXFwnKT09bGl2ZVtcXCdtZXRhZGF0YVxcJ11bXFwnZ2VuZXJhdGlvblxcJ10sXFwnY29udHJvbGxlciBnZW5lcmF0aW9uIG5vdCBzZXR0bGVkXFwnKVxcbiAgcmVzdWx0LnVwZGF0ZShuYXRpdmVfcm9sbG91dF92ZXJpZmllZD1UcnVlLGN1cnJlbnRfc2NoZW1hNV9kYXRhYmFzZV9yZXRhaW5lZD1UcnVlLHJlY292ZXJ5X3ZlcmlmaWNhdGlvbj1waGFzZT09XFwncm9sbGJhY2stdmVyaWZ5XFwnKVxcbmV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGVycm9yOlxcbiByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1GYWxzZSxmYWlsdXJlX2NsYXNzPXR5cGUoZXJyb3IpLl9fbmFtZV9fLFxcbiAgZmFpbHVyZT1cXCdmaXhlZCBwaGFzZSBvdXRjb21lIHJlZnVzZWQgb3IgYW1iaWd1b3VzOyByYXcgb3V0cHV0IHdpdGhoZWxkOyBubyByZXRyeVxcJylcXG5wcmludChqc29uLmR1bXBzKHJlc3VsdCkpO3N5cy5leGl0KDAgaWYgcmVzdWx0LmdldChcXCdhbGxfY2hlY2tzX3Bhc3NcXCcpIGlzIFRydWUgZWxzZSAxKVxcbidcbiIKICAgIH0sCiAgICAicGFja2V0LXJlZmluZW1lbnQuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIzMWI3MThhNDllZDQ3NTg2NWVkZWExYjJmNmQ3NDlhNTBhM2U2NmY1NmRiYzRmYTliNWZmMTE1OGFjYWVmNTYzIiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm9yaWdpbmFsX2FwcHJvdmVkX3NvdXJjZVwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIixcbiAgXCJvcmlnaW5hbF9wYWNrZXRfYXJjaGl2ZVwiOiBcImluaXRpYWwtYXBwcm92ZWQtYmM2NDk0Y2RcIixcbiAgXCJvcmlnaW5hbF9hcHByb3ZlZF9zdWJtaXNzaW9uX2RpZ2VzdFwiOiBcInNoYTI1NjpmZDc4ZDQ4NjE3NDY3MGUxMmVmYjJmODEyYmFjMDJlNjhmMjk0ZTc3OTFiOTMwMmQwZDQ1OGMwNTMyNDBmNWE5XCIsXG4gIFwib3JpZ2luYWxfZmFpbGVkX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICBcIm9yaWdpbmFsX29sZF91bmNlcnRhaW5fcmV0cnlcIjogZmFsc2UsXG4gIFwicmVzY3VlX3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgXCJyZWZpbmVtZW50c1wiOiBbXG4gICAgXCJleHBsaWNpdGNsb3NlIGxpdmUgV0FMLWF3YXJlIGluc3BlY3RvclwiLFxuICAgIFwiaW1tdXRhYmxlIGZpeGVkIGhhc2gtYm91bmQgZnJvemVuIHNuYXBzaG90IGFsbG93aW5nIHJldGFpbmVkIHN0YWxlU0hNIG9ubHkgd2l0aCB6ZXJvV0FMXCIsXG4gICAgXCJuZXcgc2VwYXJhdGVseSBsaW5rZWQgam91cm5hbCBhbmQgZGlzdGluY3QgbmFtZWQgcmVzY3VlLWNvcHkgYXR0ZW1wdFwiLFxuICAgIFwicmVtYWluaW5nIHBoYXNlIGlucHV0IGV4cGxpY2l0bHkgcmVzY3VlZCByZXN1bHRcIlxuICBdLFxuICBcIm5ld19uYXRpdmVfYWN0aW9uc1wiOiBmYWxzZSxcbiAgXCJuZXdfZm91bmRlcl9hcHByb3ZhbFwiOiBmYWxzZVxufVxuIgogICAgfSwKICAgICJyZWNlaXB0X3NhZmV0eS5weSI6IHsKICAgICAgInNoYTI1NiI6ICI1YzU0MzczZjJkYzRiMDY0MDA4MjI1YzE4NmVmYjFkNWFmZGVlYzM2ZDE1MzUwYmRhMGExMmRlZDk3NjAyZDFiIiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiT25seSBzdHJ1Y3R1cmFsIGNvdW50L2hhc2ggcmVjZWlwdHMgY2FuIGxlYXZlIHRoZSBwcml2YXRlIGV4ZWN1dGlvbiBwaGFzZS5cIlwiXCJcbmRlZiBjb3VudHModmFsdWUpOlxuICAgIGlmIChzZXQodmFsdWUpICE9IHsnc2NoZW1hX3ZlcnNpb24nLCAnbGlmZWN5Y2xlJywgJ291dGJveCcsICdzdWJtaXNzaW9ucycsICdpbnRlZ3JpdHknLFxuICAgICAgICAgICAgICAgICAgICAgICAncmVhZF9vbmx5X3ByZV9vcGVuJywgJ3N0b3JlX2NvbnN0cnVjdGVkJ31cbiAgICAgICAgICAgIG9yIHZhbHVlWydzY2hlbWFfdmVyc2lvbiddICE9IDUgb3IgdmFsdWVbJ2ludGVncml0eSddICE9ICdvaydcbiAgICAgICAgICAgIG9yIHZhbHVlWydyZWFkX29ubHlfcHJlX29wZW4nXSBpcyBub3QgVHJ1ZSBvciB2YWx1ZVsnc3RvcmVfY29uc3RydWN0ZWQnXSBpcyBub3QgRmFsc2VcbiAgICAgICAgICAgIG9yIHNldCh2YWx1ZVsnbGlmZWN5Y2xlJ10pICE9IHsncmVjb3JkcycsICdldmVudHMnLCAncGVuZGluZyd9XG4gICAgICAgICAgICBvciBub3Qgc2V0KHZhbHVlWydvdXRib3gnXSkgPD0geydwZW5kaW5nJywgJ2RlbGl2ZXJlZCcsICdibG9ja2VkJ31cbiAgICAgICAgICAgIG9yIG5vdCBzZXQodmFsdWVbJ3N1Ym1pc3Npb25zJ10pIDw9IHsncHJlcGFyZWQnLCAnaW5fZmxpZ2h0JywgJ2NvbmZpcm1lZCcsICd1bnJlc29sdmVkJ30pOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdjb3VudC1vbmx5IHJlY2VpcHQgc2hhcGUvc3RhdGUgcmVmdXNlZDsgdmFsdWVzIHdpdGhoZWxkJylcbiAgICBmb3IgZ3JvdXAgaW4gKCdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyk6XG4gICAgICAgIGlmIGFueSh0eXBlKG51bWJlcikgaXMgbm90IGludCBvciBudW1iZXIgPCAwIG9yIG51bWJlciA+IDEwKioxMlxuICAgICAgICAgICAgICAgZm9yIG51bWJlciBpbiB2YWx1ZVtncm91cF0udmFsdWVzKCkpOlxuICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignY291bnQtb25seSByZWNlaXB0IHZhbHVlcyByZWZ1c2VkJylcbiAgICByZXR1cm4gdmFsdWVcbiIKICAgIH0sCiAgICAicm9vdC1hdXRob3JpdHktcmVjZWlwdC10ZW1wbGF0ZS5qc29uIjogewogICAgICAic2hhMjU2IjogImRiMjhkMDNlM2M0NmI0ZGU1MmRjNDA0YzkxMjA1NDQ4M2Y0YTJhYWE2YzRmNDc2Yjc4OTJjYWIyYTVmNDA4ZDQiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwicHJvcG9zYWxfaWRcIjogXCJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MVwiLFxuICBcIm1lbW9faWRcIjogXCJpbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm1lbW9fc2hhMjU2XCI6IG51bGwsXG4gIFwic291cmNlX3JldmlzaW9uXCI6IG51bGwsXG4gIFwiYWN0aXZhdGlvblwiOiBcIlBFTkRJTkdcIixcbiAgXCJhdXRob3JpdHlfbW9kZVwiOiBcIkFETUlOSVNURVJcIixcbiAgXCJ0YXJnZXRcIjogXCJyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uXCIsXG4gIFwidmVyaWZpY2F0aW9uX21ldGhvZFwiOiBcInJvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFja1wiLFxuICBcInJ1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudFwiOiBmYWxzZSxcbiAgXCJ2ZXJpZmllZF9hdFwiOiBudWxsLFxuICBcImFjY2VwdGVkX2F0XCI6IG51bGwsXG4gIFwicmV2aWV3X21lbW9faWRcIjogbnVsbCxcbiAgXCJhcHByb3ZhbF9pZFwiOiBudWxsLFxuICBcImRpc3Bvc2l0aW9uX2lkXCI6IG51bGwsXG4gIFwibmF0aXZlX291dGNvbWVfc2hhMjU2XCI6IG51bGwsXG4gIFwiZXhlY3V0b3JfcGxhbl9zaGEyNTZcIjogXCI0ZDU1MzBlNzQxOGY2MzhiMTBjY2ZmMGUwZDlhMDcyN2FkYzY0YTdmM2E0NTkwN2Y2ZGViNTczOWFkMmFkYzg1XCIsXG4gIFwib3V0Y29tZV9xdWVyeVwiOiBcIi9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0yXCIsXG4gIFwicmV2aWV3X21lbW9fdmVyc2lvblwiOiAxXG59XG4iCiAgICB9LAogICAgInRlc3RfZXhlY3V0aW9uLnB5IjogewogICAgICAic2hhMjU2IjogImIyNTA0NDEyODI1MTM4NjJlZWI5OTBiMThkMDFiYjFlYWZlNzg3YjkzNGQ2NzBhNzVhMmJmYWE5ZjVjZmI4OWMiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTeW50aGV0aWMgY3VzdG9keS90cmFuc3BvcnQgdGVzdHMuIE5vIG5hdGl2ZSBkYXRhLCBEb2NrZXIgb3IgY2x1c3RlciBhY3Rpb24uXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaW9cbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0ZW1wZmlsZVxuaW1wb3J0IHVuaXR0ZXN0XG5mcm9tIHVuaXR0ZXN0Lm1vY2sgaW1wb3J0IHBhdGNoXG5mcm9tIGNvbnRleHRsaWIgaW1wb3J0IHJlZGlyZWN0X3N0ZG91dFxuXG5pbXBvcnQgYWN0dWF0b3JcbmZyb20gYXV0aG9yaXR5X2pvdXJuYWwgaW1wb3J0IEpvdXJuYWwsIGF1dGhvcml0eVxuZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuZnJvbSByZWNlaXB0X3NhZmV0eSBpbXBvcnQgY291bnRzXG5cbkNBU0UgPSBQYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24vZG9jcy9ldmlkZW5jZS8yMDI2LTEwLTExLXB1cnBvc2UtaW1hZ2UtcmVsZWFzZScpXG5OT1cgPSBkYXRldGltZS5kYXRldGltZSgyMDI2LCAxMCwgMTEsIDIsIDAsIHR6aW5mbz1kYXRldGltZS50aW1lem9uZS51dGMpXG5SRVZJU0lPTiA9ICdlJyAqIDQwXG5DT1VOVCA9IHsnc2NoZW1hX3ZlcnNpb24nOiA1LCAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlLFxuICAgICAgICAgJ2xpZmVjeWNsZSc6IHsncmVjb3Jkcyc6IDMsICdldmVudHMnOiA4LCAncGVuZGluZyc6IDF9LFxuICAgICAgICAgJ291dGJveCc6IHsncGVuZGluZyc6IDIsICdkZWxpdmVyZWQnOiAxMH0sICdzdWJtaXNzaW9ucyc6IHsnY29uZmlybWVkJzogMSwgJ3VucmVzb2x2ZWQnOiAxfX1cblxuXG5kZWYgYWNjZXB0ZWQoKTpcbiAgICBhcHByb3ZhbCA9ICcxMTExMTExMS0xMTExLTQxMTEtODExMS0xMTExMTExMTExMTEnXG4gICAgcmV2aWV3ID0gJ3Jldmlldy0yMjIyMjIyMi0yMjIyLTQyMjItODIyMi0yMjIyMjIyMjIyMjInXG4gICAgZGlzcG9zaXRpb24gPSAnZGlzcC0zMzMzMzMzMy0zMzMzLTQzMzMtODMzMy0zMzMzMzMzMzMzMzMnXG4gICAgcmVjZWlwdCA9IHsncHJvcG9zYWxfaWQnOiAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnLFxuICAgICAgICAgICAgICAgJ21lbW9faWQnOiAnaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEnLCAnbWVtb192ZXJzaW9uJzogMixcbiAgICAgICAgICAgICAgICdtZW1vX3NoYTI1Nic6ICdhJyAqIDY0LCAnc291cmNlX3JldmlzaW9uJzogUkVWSVNJT04sICdhY3RpdmF0aW9uJzogJ0FQUFJPVkVEJyxcbiAgICAgICAgICAgICAgICdhdXRob3JpdHlfbW9kZSc6ICdBRE1JTklTVEVSJywgJ3RhcmdldCc6ICdyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uJyxcbiAgICAgICAgICAgICAgICd2ZXJpZmljYXRpb25fbWV0aG9kJzogJ3Jvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFjaycsICdydW50aW1lX2F1dGhlbnRpY2F0ZWRfZ3JhbnQnOiBGYWxzZSwgJ291dGNvbWVfcXVlcnknOiAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgICAgJ3ZlcmlmaWVkX2F0JzogJzIwMjYtMTAtMTFUMDI6MDA6MDBaJywgJ2FjY2VwdGVkX2F0JzogJzIwMjYtMTAtMTFUMDE6NTk6MDBaJyxcbiAgICAgICAgICAgICAgICdyZXZpZXdfbWVtb19pZCc6IHJldmlldywgJ2FwcHJvdmFsX2lkJzogYXBwcm92YWwsICdkaXNwb3NpdGlvbl9pZCc6IGRpc3Bvc2l0aW9ufVxuICAgIG91dGNvbWUgPSB7J21lbW9faWQnOiByZWNlaXB0WydtZW1vX2lkJ10sICdyZXZpZXcnOiB7J21lbW9faWQnOiByZXZpZXcsICdzdGFsZSc6IEZhbHNlLCAnaW50YWtlX3N0YXRlJzogJ3JlYWR5J30sXG4gICAgICAgICAgICAgICAnZGlzcG9zaXRpb25zJzogW3snYXBwcm92YWxfaWQnOiBOb25lLCAnc3VibWlzc2lvbl9zdGF0ZSc6ICdjb25maXJtZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Rpc3Bvc2l0aW9uJzogeyd2ZXJiJzogJ2FjY2VwdCcsICdtZW1vX3ZlcnNpb24nOiAxLCAnbWVtb19pZCc6IHJldmlldyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXBwcm92YWxfaWQnOiBhcHByb3ZhbCwgJ2lkJzogZGlzcG9zaXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FjdG9yJzogeydraW5kJzogJ3BlcnNvbicsICdzdWInOiAndWlkPXBsYXRmb3JtLXJvb3Qsb3U9cGVvcGxlLGRjPW5ldGtpbmdkb20sZGM9bG9jYWwnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXQnOiByZWNlaXB0WydhY2NlcHRlZF9hdCddfX1dfVxuICAgIHJldHVybiByZWNlaXB0LCBvdXRjb21lXG5cblxuY2xhc3MgQXV0aG9yaXR5QW5kQ3VzdG9keSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIHRlc3RfZXhhY3RfbmVzdGVkX2ZvdW5kZXJfcmVjZWlwdF9ub3RfdG9wX2xldmVsX2FwcHJvdmFsKHNlbGYpOlxuICAgICAgICByZWNlaXB0LCBvdXRjb21lID0gYWNjZXB0ZWQoKVxuICAgICAgICByZXN1bHQgPSBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgJ2EnICogNjQsIFJFVklTSU9OLCAnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBOT1cpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydhcHByb3ZhbF9pZCddLCByZWNlaXB0WydhcHByb3ZhbF9pZCddKVxuXG4gICAgZGVmIHRlc3RfcGVuZGluZ19zdGFsZV93cm9uZ19hY3Rvcl92ZXJzaW9uX2FuZF9iaW5kaW5nX3JlZnVzZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSByLCBvOiByLnVwZGF0ZShhY3RpdmF0aW9uPSdQRU5ESU5HJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUobWVtb19zaGEyNTY9J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZShzb3VyY2VfcmV2aXNpb249J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZSh0YXJnZXQ9J290aGVyJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpZWRfYXQ9JzIwMjYtMTAtMTFUMDE6MDA6MDBaJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpY2F0aW9uX21ldGhvZD0nY2FsbGVyLWFzc2VydGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUocnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50PVRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ3JldmlldyddLnVwZGF0ZShzdGFsZT1UcnVlKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydyZXZpZXcnXS51cGRhdGUoaW50YWtlX3N0YXRlPSdwZW5kaW5nJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ11bMF0udXBkYXRlKHN1Ym1pc3Npb25fc3RhdGU9J3VucmVzb2x2ZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydkaXNwb3NpdGlvbnMnXVswXVsnZGlzcG9zaXRpb24nXS51cGRhdGUobWVtb192ZXJzaW9uPTMpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddLnVwZGF0ZShhY3Rvcj17J2tpbmQnOiAnYWdlbnQnLCAnc3ViJzogJ3BsYXRmb3JtLXJvb3QnfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ10uYXBwZW5kKGNvcHkuZGVlcGNvcHkob1snZGlzcG9zaXRpb25zJ11bMF0pKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShyLCBvKVxuICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyZWxlYXNlJywgTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwaXJlZF93aW5kb3dfYW5kX3Vua25vd25fcGhhc2VfcmVmdXNlKHNlbGYpOlxuICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgYXV0aG9yaXR5KHIsIG8sICdhJyAqIDY0LCBSRVZJU0lPTiwgJ2FyYml0cmFyeScsIE5PVylcbiAgICAgICAgbGF0ZSA9IGRhdGV0aW1lLmRhdGV0aW1lKDIwMjYsIDEwLCAxMywgdHppbmZvPWRhdGV0aW1lLnRpbWV6b25lLnV0YylcbiAgICAgICAgclsndmVyaWZpZWRfYXQnXSA9IGxhdGUuaXNvZm9ybWF0KClcbiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyb2xsYmFjaycsIGxhdGUpXG5cbiAgICBkZWYgdGVzdF9kdXJhYmxlX2ludGVudF9wcmVjZWRlc19kaXNwYXRjaF9hbmRfbmV2ZXJfcmV0cmllcyhzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQgPSBQYXRoKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIG9zLmNobW9kKHBhcmVudCwgMG83MDApXG4gICAgICAgICAgICBqb3VybmFsID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICBqb3VybmFsLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIHsnYXBwcm92YWxfaWQnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChqc29uLmxvYWRzKGpvdXJuYWwucGF0aC5yZWFkX3RleHQoKSlbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydzdGF0ZSddLCAnUlVOTklORycpXG4gICAgICAgICAgICBqb3VybmFsLmNsb3NlKCkgICMgc2ltdWxhdGVkIGNyYXNoIGJlZm9yZSByZXN1bHRcbiAgICAgICAgICAgIHJlY292ZXJlZCA9IEpvdXJuYWwocGFyZW50LCB7J2Nhc2UnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICByZWNvdmVyZWQuc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCB7fSlcbiAgICAgICAgICAgIHJlY292ZXJlZC5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9waGFzZV9vcmRlcl9hbmRfdW5jZXJ0YWluX3JlbGVhc2VfYWxsb3dzX29ubHlfZGlzdGluY3RfcmVjb3Zlcnkoc2VsZik6XG4gICAgICAgIHdpdGggdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZGlyZWN0b3J5OlxuICAgICAgICAgICAgb3MuY2htb2QoZGlyZWN0b3J5LCAwbzcwMClcbiAgICAgICAgICAgIGogPSBKb3VybmFsKGRpcmVjdG9yeSwgeydjYXNlJzogJ2ZpeHR1cmUnfSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgai5zdGFydCgncmVsZWFzZScsIHt9KVxuICAgICAgICAgICAgZm9yIHBoYXNlIGluIGFjdHVhdG9yLlBIQVNFU1s6NV06XG4gICAgICAgICAgICAgICAgai5zdGFydChwaGFzZSwge30pXG4gICAgICAgICAgICAgICAgai5maW5pc2gocGhhc2UsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICBqLmZpbmlzaCgncmVsZWFzZScsIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2V9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGouc3RhcnQoJ3ZlcmlmeScsIHt9KVxuICAgICAgICAgICAgai5zdGFydCgncm9sbGJhY2snLCB7fSlcbiAgICAgICAgICAgIGouZmluaXNoKCdyb2xsYmFjaycsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X3NlY3JldF9vcl91bmtub3duX2NoaWxkX291dHB1dF9pc193aXRoaGVsZChzZWxmKTpcbiAgICAgICAgZm9yIGJvZHkgaW4gKCdub3QtanNvbicsICd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwidG9rZW5cIjpcInByaXZhdGUtdmFsdWVcIn0nLFxuICAgICAgICAgICAgICAgICAgICAgJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJzbmFwc2hvdF9yZWFkb25seVwiOntcInNjaGVtYV92ZXJzaW9uXCI6NX19Jyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGFjdHVhdG9yLmpzb25fcmVzdWx0KHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwgMCwgYm9keSwgJycpKVxuICAgICAgICB3cm9uZyA9IGNvcHkuZGVlcGNvcHkoQ09VTlQpXG4gICAgICAgIHdyb25nWydvdXRib3gnXSA9IHsncHJpdmF0ZS1yb3ctdmFsdWUnOiAxfVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgY291bnRzKHdyb25nKVxuICAgICAgICBjb3VudHMoQ09VTlQpICAjIGJsb2NrZWQvdW5yZXNvbHZlZCBjb3VudHMgYXJlIG5vdCByZXF1aXJlZCB0byBiZSB6ZXJvLlxuXG4gICAgZGVmIHRlc3RfYmluYXJ5X2NvcHlfaXNfYm91bmRlZF9wcml2YXRlX2FuZF9uZXZlcl9lY2hvZWQoc2VsZik6XG4gICAgICAgIGJsb2IgPSBiJ3N5bnRoZXRpYyBwcml2YXRlIGZpeHR1cmUgYnl0ZXMnXG4gICAgICAgIGRpZ2VzdCA9IF9faW1wb3J0X18oJ2hhc2hsaWInKS5zaGEyNTYoYmxvYikuaGV4ZGlnZXN0KClcbiAgICAgICAgbWV0YWRhdGEgPSB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdzbmFwc2hvdF9maWxlJzogJ2RyaWxsLnNxbGl0ZScsICdzbmFwc2hvdF9ieXRlcyc6IGxlbihibG9iKSxcbiAgICAgICAgICAgICAgICAgICAgJ3NuYXBzaG90X3NoYTI1Nic6IGRpZ2VzdCwgJ3NuYXBzaG90X3JlYWRvbmx5JzogQ09VTlQsXG4gICAgICAgICAgICAgICAgICAgICdwb2RfbmFtZSc6ICdmaXh0dXJlLXBvZCcsICdwb2RfdWlkJzogJ2ZpeHR1cmUtdWlkJ31cbiAgICAgICAgam91cm5hbCA9IHR5cGUoJ0ZpeHR1cmVKb3VybmFsJywgKCksIHsnZGF0YSc6IHsnaWRlbnRpdHknOiB7J3JlY292ZXJ5X2FuY2hvcic6IHsnYmFja3VwX3Jlc3VsdCc6IG1ldGFkYXRhfX19fSkoKVxuICAgICAgICByZWFsX3BvcGVuID0gc3VicHJvY2Vzcy5Qb3BlblxuICAgICAgICBmb3IgZXh0cmEgaW4gKGInJywgYidvdmVyc2l6ZWQnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGV4dHJhPWV4dHJhKSwgdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZm9sZGVyOlxuICAgICAgICAgICAgICAgIG9zLmNobW9kKGZvbGRlciwgMG83MDApXG4gICAgICAgICAgICAgICAgb3V0cHV0ID0gaW8uU3RyaW5nSU8oKVxuXG4gICAgICAgICAgICAgICAgZGVmIGNoaWxkKCphcmdzLCAqKmt3YXJncyk6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFsX3BvcGVuKFtzeXMuZXhlY3V0YWJsZSwgJy1jJywgJ2ltcG9ydCBzeXM7c3lzLnN0ZG91dC5idWZmZXIud3JpdGUoJyArIHJlcHIoYmxvYiArIGV4dHJhKSArICcpJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwpXG5cbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwgJ0NVU1RPRFknLCBQYXRoKGZvbGRlcikpLCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdyZW1vdGUnLCByZXR1cm5fdmFsdWU9bWV0YWRhdGEpLCBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2goJ3N1YnByb2Nlc3MuUG9wZW4nLCBzaWRlX2VmZmVjdD1jaGlsZCksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgICAgICAgICBpZiBleHRyYTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWF0b3IuY29weV9zbmFwc2hvdCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBSRVZJU0lPTiwge30sIGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBhY3R1YXRvci5jb3B5X3NuYXBzaG90KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIFJFVklTSU9OLCB7fSwgam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29mZl9jbHVzdGVyX3ByaXZhdGVfY29weV92ZXJpZmllZCddKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoUGF0aChmb2xkZXIpIC8gJ2RyaWxsLnNxbGl0ZScpLnJlYWRfYnl0ZXMoKSwgYmxvYilcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG91dHB1dC5nZXR2YWx1ZSgpLCAnJylcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKChQYXRoKGZvbGRlcikgLyAnZHJpbGwuc3FsaXRlJykuc3RhdCgpLnN0X21vZGUgJiAwbzc3NywgMG82MDApXG5cbiAgICBkZWYgdGVzdF9yZWNyZWF0ZWRfb2ZmbGluZV92b2x1bWVfY2Fubm90X2JlX2RlbGV0ZWQoc2VsZik6XG4gICAgICAgIGlkZW50aXR5ID0geydOYW1lJzogYWN0dWF0b3IuVk9MVU1FLCAnTGFiZWxzJzogeydub25jZSc6ICdvbGQnfSwgJ0NyZWF0ZWRBdCc6ICdvbGQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7XG4gICAgICAgICAgICAnb2ZmbGluZS12ZXJpZnknOiB7J3Jlc3VsdCc6IHsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknOiBpZGVudGl0eX19fX19KSgpXG4gICAgICAgIGluc3BlY3RlZCA9IFt7KippZGVudGl0eSwgJ0NyZWF0ZWRBdCc6ICdyZWNyZWF0ZWQnfV1cbiAgICAgICAgd2l0aCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdkb2NrZXInLCByZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBqc29uLmR1bXBzKGluc3BlY3RlZCksICcnKSkgYXMgbW9ja2VkOlxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBhY3R1YXRvci5jbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobW9ja2VkLmNhbGxfY291bnQsIDEpXG5cbiAgICBkZWYgdGVzdF9vZmZsaW5lX3Bvc3RfYWRtaW5faW50ZWdyaXR5X2FuZF9vcmlnaW5hbF9oYXNoX2FyZV9yZWNoZWNrZWQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdub25lJywgJ3Bvc3QtaW50ZWdyaXR5JywgJ29yaWdpbmFsLWhhc2gnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgZm9sZGVyPVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChmb2xkZXIsMG83MDApXG4gICAgICAgICAgICAgICAgc25hcHNob3Q9Zm9sZGVyLydkcmlsbC5zcWxpdGUnO3NuYXBzaG90LndyaXRlX2J5dGVzKGIncHJpdmF0ZSBzeW50aGV0aWMgc25hcHNob3QnKTtvcy5jaG1vZChzbmFwc2hvdCwwbzYwMClcbiAgICAgICAgICAgICAgICBkaWdlc3Q9YWN0dWF0b3Iuc2hhKHNuYXBzaG90KVxuICAgICAgICAgICAgICAgIHByaW9yPXsnc25hcHNob3Rfc2hhMjU2JzpkaWdlc3QsJ3NuYXBzaG90X3JlYWRvbmx5JzpDT1VOVH1cbiAgICAgICAgICAgICAgICBqb3VybmFsPXR5cGUoJ0ZpeHR1cmVKb3VybmFsJywoKSx7J2RhdGEnOnsncGhhc2VzJzp7J2RyaWxsLWNvcHktcmVzY3VlLXIxJzp7J3Jlc3VsdCc6cHJpb3J9LCdvZmZsaW5lLXZlcmlmeSc6eydhdHRlbXB0X2lkJzonbm9uY2UnfX19LCdub3RlJzpsYW1iZGEgKmFyZ3M6Tm9uZX0pKClcbiAgICAgICAgICAgICAgICByZWFkcz1bXVxuICAgICAgICAgICAgICAgIHZvbHVtZT17J05hbWUnOmFjdHVhdG9yLlZPTFVNRSwnTGFiZWxzJzp7J2luZm9ybWVkLWRlY2lzaW9uLmNhc2UnOidpbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLCdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOidvZmZsaW5lLXJlc3RvcmUtb25seScsJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQnOidub25jZSd9LCdEcml2ZXInOidsb2NhbCcsJ1Njb3BlJzonbG9jYWwnLCdDcmVhdGVkQXQnOidmaXh0dXJlJywnT3B0aW9ucyc6Tm9uZX1cbiAgICAgICAgICAgICAgICBkZWYgZG9ja2VyKGFyZ3YsIGJvZHk9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgICAgICAgICBpZiBhcmd2WzBdPT0naW5mbyc6Ym9keT1qc29uLmR1bXBzKCdibnQtbGFwMDAxJylcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdscyddOmJvZHk9JydcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdjcmVhdGUnXTpib2R5PWFjdHVhdG9yLlZPTFVNRVxuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2luc3BlY3QnXTpib2R5PWpzb24uZHVtcHMoW3ZvbHVtZV0pXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJyBpbiBhcmd2OlxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keT1qc29uLmR1bXBzKHtrZXk6Q09VTlRba2V5XSBmb3Iga2V5IGluICgnc2NoZW1hX3ZlcnNpb24nLCdsaWZlY3ljbGUnLCdvdXRib3gnLCdzdWJtaXNzaW9ucycpfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J29yaWdpbmFsLWhhc2gnOnNuYXBzaG90LndyaXRlX2J5dGVzKGInY2hhbmdlZCBzeW50aGV0aWMgb3JpZ2luYWwnKVxuICAgICAgICAgICAgICAgICAgICBlbGlmICctLWVudHJ5cG9pbnQnIGluIGFyZ3YgYW5kICdweXRob24nIGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkcy5hcHBlbmQoYXJndik7cHJvb2Y9Y29weS5kZWVwY29weShDT1VOVClcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihyZWFkcyk9PTIgYW5kIGRlZmVjdD09J3Bvc3QtaW50ZWdyaXR5Jzpwcm9vZlsnaW50ZWdyaXR5J109J2NvcnJ1cHQnXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5PWpzb24uZHVtcHMocHJvb2YpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6cmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgb2ZmbGluZSBjb21tYW5kJylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LDAsYm9keSwnJylcbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwnQ1VTVE9EWScsZm9sZGVyKSxwYXRjaC5vYmplY3QoYWN0dWF0b3IsJ0NBU0UnLENBU0UpLHBhdGNoLm9iamVjdChhY3R1YXRvciwnZG9ja2VyJyxzaWRlX2VmZmVjdD1kb2NrZXIpLHBhdGNoKCdzdWJwcm9jZXNzLnJ1bicscmV0dXJuX3ZhbHVlPXN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwwLCd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwicHJpdmF0ZV9jb3B5X3ZlcmlmaWVkXCI6dHJ1ZX0nLCcnKSk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J25vbmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0PWFjdHVhdG9yLm9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlc3VsdFsnb2ZmbGluZV9wb3N0X2FkbWluX3JlYWRvbmx5J10sQ09VTlQpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydFRydWUocmVzdWx0WydvcmlnaW5hbF9zbmFwc2hvdF9oYXNoX3VuY2hhbmdlZCddKVxuICAgICAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTphY3R1YXRvci5vZmZsaW5lX3ZlcmlmeShqb3VybmFsKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlYWRzKSwyKVxuXG5cbmNsYXNzIEZpeGVkTmF0aXZlUHJvZ3JhbSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIGZpeHR1cmUoc2VsZik6XG4gICAgICAgIHNlYWxlZCA9IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgICAgIGxpdmUgPSBjb3B5LmRlZXBjb3B5KHNlYWxlZClcbiAgICAgICAgbGl2ZVsnbWV0YWRhdGEnXS51cGRhdGUoZ2VuZXJhdGlvbj00MilcbiAgICAgICAgbGl2ZVsnc3RhdHVzJ10gPSB7J3JlYWR5UmVwbGljYXMnOiAxLCAndXBkYXRlZFJlcGxpY2FzJzogMSwgJ29ic2VydmVkR2VuZXJhdGlvbic6IDQyfVxuICAgICAgICBkZXBlbmRlbmNpZXMgPSBqc29uLmxvYWRzKChDQVNFIC8gJ3NlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY20gPSBjb3B5LmRlZXBjb3B5KGRlcGVuZGVuY2llc1snY29uZmlnbWFwJ10pXG4gICAgICAgIGNtLnBvcCgnY2Fub25pY2FsX2RhdGFfc2hhMjU2JylcbiAgICAgICAgc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UgLyAnY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBzb3VyY2Vfc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UucGFyZW50c1syXSAvICdkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY21bJ2RhdGEnXSA9IG5leHQoeCBmb3IgeCBpbiBzb3VyY2Vfc2VydmljZVsnaXRlbXMnXSBpZiB4WydraW5kJ10gPT0gJ0NvbmZpZ01hcCcpWydkYXRhJ11cbiAgICAgICAgcHZjID0gY29weS5kZWVwY29weShkZXBlbmRlbmNpZXNbJ3B2YyddKVxuICAgICAgICBwdmNbJ3N0YXR1cyddID0geydwaGFzZSc6ICdCb3VuZCd9XG4gICAgICAgIGFwcCA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQnLCAncmVzb3VyY2VWZXJzaW9uJzogJzE3J30sXG4gICAgICAgICAgICAgICAnc3BlYyc6IHsnc291cmNlJzogeydyZXBvVVJMJzogJ2h0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uLmdpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYXRoJzogJ2RlcGxveS9saWZlY3ljbGUnLCAndGFyZ2V0UmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZid9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2Rlc3RpbmF0aW9uJzogeyduYW1lc3BhY2UnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnc2VydmVyJzogJ2h0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yyd9fX1cbiAgICAgICAgb2JqZWN0cyA9IHsnZGVwbG95bWVudCc6IGxpdmUsICdjb25maWdtYXAnOiBjbSwgJ3B2Yyc6IHB2YywgJ2FwcGxpY2F0aW9uJzogYXBwfVxuICAgICAgICBwYXlsb2FkID0geydwaGFzZSc6ICdyZWxlYXNlJywgJ3NvdXJjZV9yZXZpc2lvbic6IFJFVklTSU9OLCAnYXBwcm92YWwnOiB7fSwgJ3NlYWxlZCc6IHNlYWxlZCxcbiAgICAgICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJzogZGVwZW5kZW5jaWVzLCAnY2FuZGlkYXRlJzogc2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAncmVhZG9ubHknOiAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSwncHVycG9zZV9jaGVja3MnOihDQVNFLydjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICAgICAncmVjZWlwdF9zYWZldHknOiAoUGF0aChfX2ZpbGVfXykucGFyZW50IC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCl9XG4gICAgICAgIHJldHVybiBvYmplY3RzLCBwYXlsb2FkXG5cbiAgICBkZWYgZXhlY3V0ZV9mYWtlKHNlbGYsIG9iamVjdHMsIHBheWxvYWQsIGFtYmlndW91cz1GYWxzZSwgc2NoZW1hX3JlZnVzZWQ9RmFsc2UpOlxuICAgICAgICB3cml0ZXMgPSBbXVxuICAgICAgICBjYWxscyA9IFtdXG5cbiAgICAgICAgZGVmIGZha2UoYXJndiwgaW5wdXQ9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgY2FsbHMuYXBwZW5kKGFyZ3YpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZ2V0J106XG4gICAgICAgICAgICAgICAga2luZCA9IGFyZ3ZbMl1cbiAgICAgICAgICAgICAgICBpZiBraW5kIGluIG9iamVjdHM6XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSBvYmplY3RzW2tpbmRdXG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdwb2RzJzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnaXRlbXMnOiBbeydtZXRhZGF0YSc6IHsnbmFtZSc6ICdmaXh0dXJlLXBvZCcsICd1aWQnOiAncG9kLXVpZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnb3duZXJSZWZlcmVuY2VzJzogW3sna2luZCc6ICdSZXBsaWNhU2V0JywgJ25hbWUnOiAnZml4dHVyZS1ycycsICd1aWQnOiAncnMtdWlkJ31dfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwZWMnOiBvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RhdHVzJzogeydwaGFzZSc6ICdSdW5uaW5nJywgJ2NvbnRhaW5lclN0YXR1c2VzJzogW3snbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywncmVhZHknOiBUcnVlfV19fV19XG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdyZXBsaWNhc2V0JzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICdycy11aWQnLCAnb3duZXJSZWZlcmVuY2VzJzogW1xuICAgICAgICAgICAgICAgICAgICAgICAgeydraW5kJzogJ0RlcGxveW1lbnQnLCAndWlkJzogcGF5bG9hZFsnc2VhbGVkJ11bJ21ldGFkYXRhJ11bJ3VpZCddfV19fVxuICAgICAgICAgICAgICAgIGVsaWYga2luZCA9PSAnbm9kZXMnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydpdGVtcyc6IFt7J21ldGFkYXRhJzogeyduYW1lJzogJ2ZpeHR1cmUtbm9kZSd9LCAnc3RhdHVzJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FkZHJlc3Nlcyc6IFt7J2FkZHJlc3MnOiAnOTIuMjA1LjYyLjIzOSd9XSwgJ2FsbG9jYXRhYmxlJzogeydjcHUnOiAnNCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbmRpdGlvbnMnOiBbeyd0eXBlJzoga2V5LCAnc3RhdHVzJzogJ1RydWUnIGlmIGtleSA9PSAnUmVhZHknIGVsc2UgJ0ZhbHNlJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBrZXkgaW4gKCdSZWFkeScsICdNZW1vcnlQcmVzc3VyZScsICdEaXNrUHJlc3N1cmUnLCAnUElEUHJlc3N1cmUnKV19fV19XG4gICAgICAgICAgICAgICAgZWxzZTpcbiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgZml4ZWQgbWV0YWRhdGEgcm91dGUnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhib2R5KSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddOlxuICAgICAgICAgICAgICAgIGlmIHNjaGVtYV9yZWZ1c2VkOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDEsICcnLCAnd2l0aGhlbGQnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyh7XG4gICAgICAgICAgICAgICAgICAgICdhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlLCAnbGl2ZV9yZWFkb25seV9zY2hlbWFfaW50ZWdyaXR5X2NvdW50cyc6IENPVU5UfSksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2FwcGx5J106XG4gICAgICAgICAgICAgICAgYWRtaXR0ZWQgPSBjb3B5LmRlZXBjb3B5KHBheWxvYWRbJ3NlYWxlZCddKVxuICAgICAgICAgICAgICAgIGFkbWl0dGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gKGFjdHVhdG9yLklNQUdFIGlmIHBheWxvYWRbJ3BoYXNlJ109PSdyZWxlYXNlJyBlbHNlIHBheWxvYWRbJ3NlYWxlZCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhhZG1pdHRlZCksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2Rlc2NyaWJlJ106XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnQWxsb2NhdGVkIHJlc291cmNlczpcXG4gY3B1IDM0NjBtICg4NiUpXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZGlmZiddOlxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJy1pbWFnZTogYmFzZVxcbitpbWFnZTogY2FuZGlkYXRlXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXTpcbiAgICAgICAgICAgICAgICBpZiAnLS1kcnktcnVuPXNlcnZlcicgbm90IGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgIHdyaXRlcy5hcHBlbmQoanNvbi5sb2FkcyhpbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIGlmIGFtYmlndW91czpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJycsICd3aXRoaGVsZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnYXBwbGljYXRpb24uYXJnb3Byb2ouaW8vaW5mb3JtZWQtZGVjaXNpb25cXG4nLCAnJylcbiAgICAgICAgICAgIHJhaXNlIEFzc2VydGlvbkVycm9yKCd1bmV4cGVjdGVkIGNvbW1hbmQnKVxuXG4gICAgICAgIHNvdXJjZSA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAgICAgJ19fR1VBUkRfXycsIHJlcHIoKENBU0UgLyAnY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpKVxuICAgICAgICBvdXRwdXQgPSBpby5TdHJpbmdJTygpXG4gICAgICAgIHdpdGggcGF0Y2goJ3N1YnByb2Nlc3MucnVuJywgc2lkZV9lZmZlY3Q9ZmFrZSksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIGV4ZWMoY29tcGlsZShzb3VyY2UsICdmaXhlZC1uYXRpdmUtZml4dHVyZScsICdleGVjJyksIHsnX19uYW1lX18nOiAnX19maXh0dXJlX18nfSlcbiAgICAgICAgICAgIGV4Y2VwdCAoVmFsdWVFcnJvciwgU3lzdGVtRXhpdCk6XG4gICAgICAgICAgICAgICAgcGFzc1xuICAgICAgICByZWNlaXB0ID0ganNvbi5sb2FkcyhvdXRwdXQuZ2V0dmFsdWUoKSkgaWYgb3V0cHV0LmdldHZhbHVlKCkgZWxzZSB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlfVxuICAgICAgICByZXR1cm4gcmVjZWlwdCwgd3JpdGVzLCBjYWxsc1xuXG4gICAgZGVmIHRlc3Rfb25seV9leGlzdGluZ19hcHBsaWNhdGlvbl9vcGVyYXRpb25fYW5kX2RlcGxveW1lbnRfYXJlX3JlcXVlc3RlZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBvcGVyYXRpb24gPSB3cml0ZXNbMF1bLTFdWyd2YWx1ZSddXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2Uob3BlcmF0aW9uWydzeW5jJ11bJ3BydW5lJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwob3BlcmF0aW9uWydzeW5jJ11bJ3Jlc291cmNlcyddLCBbXG4gICAgICAgICAgICB7J2dyb3VwJzogJ2FwcHMnLCAna2luZCc6ICdEZXBsb3ltZW50JywgJ25hbWUnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnbmFtZXNwYWNlJzogJ2luZm9ybWVkLWRlY2lzaW9uJ31dKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KCctLWRyeS1ydW49c2VydmVyJyBpbiBhcmd2IGFuZCBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXSBmb3IgYXJndiBpbiBjYWxscykpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzWzBdWzBdWydwYXRoJ10sICcvbWV0YWRhdGEvdWlkJylcblxuICAgIGRlZiB0ZXN0X3NvdXJjZV9vdmVycmlkZXNfYXV0b21hdGlvbl9hbmRfY3VzdG9keV9kcmlmdF9zdG9wX2JlZm9yZV93cml0ZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2FwcGxpY2F0aW9uJ11bJ3NwZWMnXS51cGRhdGUoc3luY1BvbGljeT17J2F1dG9tYXRlZCc6IHt9fSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXS51cGRhdGUoa3VzdG9taXplPXsnaW1hZ2VzJzogWydvdGhlciddfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddLnVwZGF0ZShzb3VyY2VzPVt7fV0pLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2NvbmZpZ21hcCddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ3B2YyddWydzcGVjJ10udXBkYXRlKHZvbHVtZU5hbWU9J3JlcGxhY2VkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgICAgICAgICBtdXRhdGUob2JqZWN0cylcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuICAgIGRlZiB0ZXN0X3ByZW9wZW5fc2NoZW1hX3JlZnVzYWxfcHJldmVudHNfaW1hZ2Vfb3BlcmF0aW9uKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIHNjaGVtYV9yZWZ1c2VkPVRydWUpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuXG4gICAgZGVmIHRlc3Rfcm9sbGJhY2tfdW5yZWFkeV9jYW5kaWRhdGVfbmV2ZXJfcmVhZHNfcG9kX29yX2RhdGFiYXNlKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wLCB1cGRhdGVkUmVwbGljYXM9MClcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gYWN0dWF0b3IuSU1BR0VcbiAgICAgICAgb2JqZWN0c1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXVsndGFyZ2V0UmV2aXNpb24nXSA9IFJFVklTSU9OXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBzY2hlbWFfcmVmdXNlZD1UcnVlKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBzZWxmLmFzc2VydEZhbHNlKGFueShhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddIG9yIGFyZ3ZbOjNdID09IFsna3ViZWN0bCcsICdnZXQnLCAncG9kcyddIGZvciBhcmd2IGluIGNhbGxzKSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXNbMF1bLTFdWyd2YWx1ZSddWydzeW5jJ11bJ3JldmlzaW9uJ10sICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJylcblxuICAgIGRlZiB0ZXN0X3JvbGxiYWNrX3N0aWxsX3JlZnVzZXNfY3VzdG9keV9vcl9ub25wYWlyX2ltYWdlX2RyaWZ0KHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnY20nLCAncHZjJywgJ2ltYWdlJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKCk7cGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgICAgICAgICAgaWYgZGVmZWN0ID09ICdjbSc6b2JqZWN0c1snY29uZmlnbWFwJ11bJ21ldGFkYXRhJ11bJ3VpZCddID0gJ3JlY3JlYXRlZCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdCA9PSAncHZjJzpvYmplY3RzWydwdmMnXVsnc3BlYyddWyd2b2x1bWVOYW1lJ10gPSAncmVwbGFjZWQnXG4gICAgICAgICAgICAgICAgZWxzZTpvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSAnZm9yZWlnbi1pbWFnZSdcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKTtzZWxmLmFzc2VydEVxdWFsKHdyaXRlcywgW10pXG5cbiAgICBkZWYgdGVzdF9yZWNvdmVyeV92ZXJpZmljYXRpb25faXNfc2VwYXJhdGVfcmVhZHlfb2xkX2ltYWdlX3NjaGVtYV9wcm9vZihzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpO3BheWxvYWRbJ3BoYXNlJ10gPSAncm9sbGJhY2stdmVyaWZ5J1xuICAgICAgICBvYmplY3RzWydhcHBsaWNhdGlvbiddWydzdGF0dXMnXSA9IHsnb3BlcmF0aW9uU3RhdGUnOiB7J3BoYXNlJzogJ1N1Y2NlZWRlZCcsICdvcGVyYXRpb24nOiB7J3N5bmMnOiB7XG4gICAgICAgICAgICAncmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZicsICdwcnVuZSc6IEZhbHNlLFxuICAgICAgICAgICAgJ3Jlc291cmNlcyc6IFt7J2dyb3VwJzonYXBwcycsJ2tpbmQnOidEZXBsb3ltZW50JywnbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywnbmFtZXNwYWNlJzonaW5mb3JtZWQtZGVjaXNpb24nfV19fX19XG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pO3NlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydyZWNvdmVyeV92ZXJpZmljYXRpb24nXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KGFyZ3ZbOjJdPT1bJ2t1YmVjdGwnLCdleGVjJ10gZm9yIGFyZ3YgaW4gY2FsbHMpKVxuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG5cbiAgICBkZWYgdGVzdF9hbWJpZ3VvdXNfcGF0Y2hfaXNfbmV2ZXJfcmV0cmllZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBhbWJpZ3VvdXM9VHJ1ZSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4od3JpdGVzKSwgMSlcblxuXG5pZiBfX25hbWVfXyA9PSAnX19tYWluX18nOlxuICAgIHVuaXR0ZXN0Lm1haW4oKVxuIgogICAgfSwKICAgICJ0ZXN0X3Jlc2N1ZV9leGVjdXRpb24ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiOGVjYmIwMjYwYTg3YTdhMTJiZDVjNGM5Njc4ZmIyYTlkNDNhNGVhNzMyMjEyOTczNGJjMjFmOGVlMzgzY2Q3MCIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIlN5bnRoZXRpYyByZWNvdmVyeSBndWFyZHM7IG5vIGFjdHVhbCBwcml2YXRlIGpvdXJuYWwvREIvbmF0aXZlIGNvbW1hbmQuXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaGFzaGxpYlxuaW1wb3J0IGpzb25cbmltcG9ydCBvc1xuZnJvbSBwYXRobGliIGltcG9ydCBQYXRoXG5pbXBvcnQgdGVtcGZpbGVcbmltcG9ydCB1bml0dGVzdFxuZnJvbSBhdXRob3JpdHlfam91cm5hbCBpbXBvcnQgSm91cm5hbCwgYXV0aG9yaXR5LCBvcmlnaW5hbF9hbmNob3JcbmZyb20gdGVzdF9leGVjdXRpb24gaW1wb3J0IGFjY2VwdGVkLCBOT1csIFJFVklTSU9OXG5cblJPT1Q9UGF0aChfX2ZpbGVfXykucGFyZW50XG5QTEFOPWpzb24ubG9hZHMoKFJPT1QvJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKS5yZWFkX3RleHQoKSlcbkNBU0U9Uk9PVC5wYXJlbnRcbkJBQ0tVUD1qc29uLmxvYWRzKChDQVNFLydvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKVxuXG5jbGFzcyBSZXNjdWVHdWFyZHModW5pdHRlc3QuVGVzdENhc2UpOlxuICAgIGRlZiBvcmlnaW5hbChzZWxmLHBhcmVudCk6XG4gICAgICAgIG9yaWdpbmFsPXsnaWRlbnRpdHknOlBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10sJ3BoYXNlcyc6e319XG4gICAgICAgIGZvciBuYW1lLG1ldGFkYXRhIGluIFBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2FuY2hvciddWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgICAgICBvcmlnaW5hbFsncGhhc2VzJ11bbmFtZV09eyoqbWV0YWRhdGEsJ3Jlc3VsdCc6QkFDS1VQIGlmIG5hbWU9PSdkcmlsbC1iYWNrdXAnIGVsc2UgeydhbGxfY2hlY2tzX3Bhc3MnOkZhbHNlfX1cbiAgICAgICAgcD1wYXJlbnQvJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nO3Aud3JpdGVfdGV4dChqc29uLmR1bXBzKG9yaWdpbmFsKSk7b3MuY2htb2QocCwwbzYwMClcbiAgICAgICAgYW5jaG9yPWNvcHkuZGVlcGNvcHkoUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10pO2FuY2hvclsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgcmV0dXJuIHAsb3JpZ2luYWwsYW5jaG9yXG5cbiAgICBkZWYgdGVzdF9leGFjdF9vcmlnaW5hbF9mYWlsZWRfam91cm5hbF9pc19saW5rZWRfd2l0aG91dF9tdXRhdGlvbihzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQ9UGF0aChkaXJlY3RvcnkpO29zLmNobW9kKHBhcmVudCwwbzcwMCk7cCxvcmlnaW5hbCxleHBlY3RlZD1zZWxmLm9yaWdpbmFsKHBhcmVudCk7YmVmb3JlPXAucmVhZF9ieXRlcygpXG4gICAgICAgICAgICBhbmNob3I9b3JpZ2luYWxfYW5jaG9yKHBhcmVudCxleHBlY3RlZCxCQUNLVVAsb3JpZ2luYWxbJ2lkZW50aXR5J10pXG4gICAgICAgICAgICBqPUpvdXJuYWwocGFyZW50LHsnZml4dHVyZSc6VHJ1ZSwncmVjb3ZlcnlfYW5jaG9yJzphbmNob3J9KTtqLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScse30pXG4gICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHAucmVhZF9ieXRlcygpLGJlZm9yZSk7c2VsZi5hc3NlcnRFcXVhbChqLnBhdGgubmFtZSwncmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24nKVxuICAgICAgICAgICAgai5maW5pc2goJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7J2FsbF9jaGVja3NfcGFzcyc6VHJ1ZX0pO2ouc3RhcnQoJ29mZmxpbmUtdmVyaWZ5Jyx7fSlcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocC5yZWFkX2J5dGVzKCksYmVmb3JlKTtqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X29yaWdpbmFsX21pc3NpbmdfdW5jZXJ0YWluX3JlY3JlYXRlZF9hdHRlbXB0X29yX3JvbGxvdXRfcmVmdXNlKHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnbWlzc2luZycsJ2NvbXBsZXRlJywnYXR0ZW1wdCcsJ3JvbGxvdXQnLCdoYXNoJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KSx0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgcGFyZW50PVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChwYXJlbnQsMG83MDApO3AsbyxlPXNlbGYub3JpZ2luYWwocGFyZW50KVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J21pc3NpbmcnOm9bJ3BoYXNlcyddLnBvcCgnZHJpbGwtY29weScpXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdjb21wbGV0ZSc6b1sncGhhc2VzJ11bJ2RyaWxsLWNvcHknXVsnc3RhdGUnXT0nQ09NUExFVEUnXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdhdHRlbXB0JzpvWydwaGFzZXMnXVsnZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ109J2RpZmZlcmVudCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdD09J3JvbGxvdXQnOm9bJ3BoYXNlcyddWydyZWxlYXNlJ109eydzdGF0ZSc6J1JVTk5JTkcnfVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdCE9J2hhc2gnOlxuICAgICAgICAgICAgICAgICAgICBwLndyaXRlX3RleHQoanNvbi5kdW1wcyhvKSk7ZVsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgICAgICAgICBlbHNlOmVbJ29yaWdpbmFsX2pvdXJuYWxfc2hhMjU2J109JzAnKjY0XG4gICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcygoVmFsdWVFcnJvcixLZXlFcnJvcikpOm9yaWdpbmFsX2FuY2hvcihwYXJlbnQsZSxCQUNLVVAsUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcblxuICAgIGRlZiB0ZXN0X3Jlc2N1ZV9yZXBsYXlfcmVmdXNlZF9hbmRfb2xkX3BoYXNlX25ldmVyX2FkbWl0dGVkKHNlbGYpOlxuICAgICAgICB3aXRoIHRlbXBmaWxlLlRlbXBvcmFyeURpcmVjdG9yeSgpIGFzIGRpcmVjdG9yeTpcbiAgICAgICAgICAgIG9zLmNobW9kKGRpcmVjdG9yeSwwbzcwMCk7aj1Kb3VybmFsKGRpcmVjdG9yeSx7J2ZpeHR1cmUnOlRydWV9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpqLnN0YXJ0KCdkcmlsbC1jb3B5Jyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnZHJpbGwtYmFja3VwJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHt9KTtqLmZpbmlzaCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZX0pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmouc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9uZXdfYXV0aG9yaXR5X3JlcXVpcmVzX3ZlcnNpb24yX29sZF9hcHByb3ZhbF9yZWZ1c2VzKHNlbGYpOlxuICAgICAgICByZWNlaXB0LG91dGNvbWU9YWNjZXB0ZWQoKTtyZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0yO291dGNvbWVbJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddWydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIGF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuICAgICAgICByZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyxOT1cpXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHknLE5PVylcbiAgICAgICAgcmVjZWlwdFsnbWVtb192ZXJzaW9uJ109MjtyZWNlaXB0WydvdXRjb21lX3F1ZXJ5J109Jy9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0xJ1xuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwbGljaXRfb2ZmbGluZV9pbnB1dF9tYXBwaW5nX2FuZF9hYnNlbmNlX2d1YXJkcyhzZWxmKTpcbiAgICAgICAgc291cmNlPShST09ULydhY3R1YXRvci5weScpLnJlYWRfdGV4dCgpXG4gICAgICAgIHNlbGYuYXNzZXJ0SW4oXCJwcmV2aW91cyA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2RyaWxsLWNvcHktcmVzY3VlLXIxJ11bJ3Jlc3VsdCddXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwibm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwiVk9MVU1FIG5vdCBpbiBsaXN0ZWQuc3Rkb3V0LnNwbGl0bGluZXMoKVwiLHNvdXJjZSlcbiAgICAgICAgc2VsZi5hc3NlcnROb3RJbihcIm9zLm1rZGlyKENVU1RPRFlcIixzb3VyY2UpXG4gICAgICAgIGltcG9ydCBhc3RcbiAgICAgICAgcHJvZ3JhbT1hc3QubGl0ZXJhbF9ldmFsKG5leHQobi52YWx1ZSBmb3IgbiBpbiBhc3QucGFyc2UoKFJPT1QvJ25hdGl2ZV9wcm9ncmFtLnB5JykucmVhZF90ZXh0KCkpLmJvZHkgaWYgaXNpbnN0YW5jZShuLGFzdC5Bc3NpZ24pKSlcbiAgICAgICAgY29tcGlsZShwcm9ncmFtLCduYXRpdmUtcmVzY3VlLWZpeHR1cmUnLCdleGVjJylcbiAgICAgICAgc2VsZi5hc3NlcnRJbihcInBoYXNlPT0nZHJpbGwtY29weS1yZXNjdWUtcjEnOnJlcXVpcmUocG9kWydtZXRhZGF0YSddWyd1aWQnXT09J2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNydcIixwcm9ncmFtKVxuXG5pZiBfX25hbWVfXz09J19fbWFpbl9fJzp1bml0dGVzdC5tYWluKClcbiIKICAgIH0sCiAgICAidmFsaWRhdGlvbi5qc29uIjogewogICAgICAic2hhMjU2IjogIjZmMzM3OWY2Mzk2OGU5YTAyOTRhYmE3YjViNTdlYTQ2NjJhZGRhNmIxZmExYjM3ZWZmMTFjMmY3MmE1ODkzMWYiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwic3RhdGVcIjogXCJwcmVwYXJlZC11bmFwcHJvdmVkLXZlcnNpb24yXCIsXG4gIFwiZXhlY3V0b3JfdGVzdHNcIjogMjEsXG4gIFwic25hcHNob3RfbW9ja190ZXN0c1wiOiA1LFxuICBcIm5hdGl2ZV9hY3Rpb25zXCI6IGZhbHNlLFxuICBcImRhdGFiYXNlX2FkbWluX2NvbW1hbmRzX2luX3ByZXBhcmF0aW9uXCI6IGZhbHNlLFxuICBcIm9sZF9qb3VybmFsX21vZGlmaWVkXCI6IGZhbHNlLFxuICBcIm9sZF9mYWlsZWRfcGhhc2VfcmV0cmllZFwiOiBmYWxzZSxcbiAgXCJvd25lcl9oZWFkX3VuY2hhbmdlZFwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIlxufVxuIgogICAgfQogIH0sCiAgIm5hdGl2ZV9leGVjdXRpb24iOiBmYWxzZSwKICAiY2FzZV9ldmlkZW5jZSI6IHsKICAgICJvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIwMjVkZGRmMWU5MzkzNmYzMWU5OGI5ZmJmYTg0YWEyYmRhYWEzMzU3M2Y5ZDNiMGUzMmQ5NDdmZDI4NmIxNzBlIiwKICAgICAgImNvbnRlbnQiOiAie1wicGhhc2VcIjogXCJkcmlsbC1iYWNrdXBcIiwgXCJhbGxfY2hlY2tzX3Bhc3NcIjogdHJ1ZSwgXCJyYXdfb3V0cHV0X3dpdGhoZWxkXCI6IHRydWUsIFwibmF0aXZlX2FwcHJvdmFsX3ZlcmlmaWVkX2J5X3Jvb3RcIjoge1wiYXBwcm92YWxfaWRcIjogXCJlYzkyODA2YS05YWE2LTQ5NGYtYTc2Yi0wMzg1ZjM5YmE2MDlcIiwgXCJkaXNwb3NpdGlvbl9pZFwiOiBcImRpc3AtMDk2ODM3M2QtMjk0ZC00MmJmLTg5NzktMzZhN2M1ZGQzOGNmXCIsIFwiYWNjZXB0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM0OjIwWlwiLCBcInZlcmlmaWVkX2F0XCI6IFwiMjAyNi0xMC0xMVQwMjozODo0MS43Nzc5NDkrMDA6MDBcIn0sIFwibmF0aXZlX2F1dGhlbnRpY2F0ZWRfZ3JhbnRcIjogZmFsc2UsIFwic291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXCI6IHtcInNjaGVtYV92ZXJzaW9uXCI6IDUsIFwibGlmZWN5Y2xlXCI6IHtcInJlY29yZHNcIjogMTUsIFwiZXZlbnRzXCI6IDUwLCBcInBlbmRpbmdcIjogMH0sIFwib3V0Ym94XCI6IHtcImRlbGl2ZXJlZFwiOiAzMjB9LCBcInN1Ym1pc3Npb25zXCI6IHtcImNvbmZpcm1lZFwiOiA0MX0sIFwiaW50ZWdyaXR5XCI6IFwib2tcIiwgXCJyZWFkX29ubHlfcHJlX29wZW5cIjogdHJ1ZSwgXCJzdG9yZV9jb25zdHJ1Y3RlZFwiOiBmYWxzZX0sIFwic25hcHNob3RfcmVhZG9ubHlcIjoge1wic2NoZW1hX3ZlcnNpb25cIjogNSwgXCJsaWZlY3ljbGVcIjoge1wicmVjb3Jkc1wiOiAxNSwgXCJldmVudHNcIjogNTAsIFwicGVuZGluZ1wiOiAwfSwgXCJvdXRib3hcIjoge1wiZGVsaXZlcmVkXCI6IDMyMH0sIFwic3VibWlzc2lvbnNcIjoge1wiY29uZmlybWVkXCI6IDQxfSwgXCJpbnRlZ3JpdHlcIjogXCJva1wiLCBcInJlYWRfb25seV9wcmVfb3BlblwiOiB0cnVlLCBcInN0b3JlX2NvbnN0cnVjdGVkXCI6IGZhbHNlfSwgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsIFwic25hcHNob3RfZmlsZVwiOiBcImRyaWxsLnNxbGl0ZVwiLCBcIm5hdGl2ZV9wYXJlbnRfcHJpdmF0ZVwiOiB0cnVlLCBcIm5hdGl2ZV91aWRcIjogMTAwMDEsIFwicG9kX25hbWVcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi1mNTU3NTU2ZGYtbXdwejdcIiwgXCJwb2RfdWlkXCI6IFwiZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XCJ9XG4iCiAgICB9LAogICAgIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWNvcHktZmFpbHVyZS5qc29uIjogewogICAgICAic2hhMjU2IjogImZiNzhmYjJlOGMzZDQxNjQ5MGNmMGY1NTliMmY1YmQwMTk0MDZhNDkwZjhmNWZhNmY1OTMyNDIxZjBiMWFjNTYiLAogICAgICAiY29udGVudCI6ICJ7XCJhbGxfY2hlY2tzX3Bhc3NcIjogZmFsc2UsIFwicGhhc2VcIjogXCJkcmlsbC1jb3B5XCIsIFwiZmFpbHVyZV9jbGFzc1wiOiBcIlZhbHVlRXJyb3JcIiwgXCJmYWlsdXJlXCI6IFwiZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeVwiLCBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZX1cbiIKICAgIH0sCiAgICAib3JpZ2luYWwtam91cm5hbC1zYW5pdGl6ZWQtYW5jaG9yLmpzb24iOiB7CiAgICAgICJzaGEyNTYiOiAiOTg4ZmNhNjFhZDhlYjlkNDNkOTMzOTBhODM1MzIzZjk1MjE5NmJiY2U4Y2MwYmRlNTFjNDJhMTdkNDExZjQ1NCIsCiAgICAgICJjb250ZW50IjogIntcbiAgXCJvcmlnaW5hbF9qb3VybmFsX3NoYTI1NlwiOiBcImQxODdiMDJkOThkNmU5NzQyOWZlMjBiNGZiZTFkMzA5YTZjNmM0YjU1MjMyYjRhZTEzYWMzOTg3MzAzOWYxYzFcIixcbiAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgXCJkcmlsbC1iYWNrdXBcIjoge1xuICAgICAgXCJzdGF0ZVwiOiBcIkNPTVBMRVRFXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzg6NDUuMzEwNjUzKzAwOjAwXCJcbiAgICB9LFxuICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICBcInN0YXRlXCI6IFwiVU5DRVJUQUlOXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCIzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2NcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICB9XG4gIH0sXG4gIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsXG4gIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsXG4gIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gIFwib2xkX3VuY2VydGFpbl9yZXRyeV9hdXRob3JpemVkXCI6IGZhbHNlXG59XG4iCiAgICB9CiAgfQp9Cg==" }, { - "digest": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", + "digest": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509", "media_type": "text/plain", - "content_base64": "IiIiUHJlLW9wZW4gc2NoZW1hL2ludGVncml0eS9jb3VudCBwcm9vZjsgc3RkbGliIG9ubHksIG5ldmVyIGNvbnN0cnVjdHMgU3RvcmUuIiIiCmltcG9ydCBhcmdwYXJzZQppbXBvcnQganNvbgpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaW1wb3J0IHNxbGl0ZTMKCgpkZWYgaW5zcGVjdF9yZWFkb25seShwYXRoKToKICAgIHBhdGggPSBQYXRoKHBhdGgpCiAgICBpZiBub3QgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZXhpc3Rpbmcgbm9uc3ltbGluayBwcml2YXRlIGRhdGFiYXNlIHJlcXVpcmVkJykKICAgIHdpdGggc3FsaXRlMy5jb25uZWN0KHBhdGgucmVzb2x2ZSgpLmFzX3VyaSgpICsgJz9tb2RlPXJvJywgdXJpPVRydWUsIHRpbWVvdXQ9NSkgYXMgZGI6CiAgICAgICAgZGIuZXhlY3V0ZSgnUFJBR01BIHF1ZXJ5X29ubHk9T04nKQogICAgICAgIGRiLmV4ZWN1dGUoJ0JFR0lOJykKICAgICAgICB2ZXJzaW9uID0gZGIuZXhlY3V0ZSgnUFJBR01BIHVzZXJfdmVyc2lvbicpLmZldGNob25lKClbMF0KICAgICAgICBpZiB2ZXJzaW9uICE9IDU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3ByZS1vcGVuIGRhdGFiYXNlIGlzIG5vdCBzY2hlbWE1OyByZWZ1c2UgbWlncmF0aW9uJykKICAgICAgICBpZiBkYi5leGVjdXRlKCdQUkFHTUEgaW50ZWdyaXR5X2NoZWNrJykuZmV0Y2hhbGwoKSAhPSBbKCdvaycsKV06CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3JlYWQtb25seSBpbnRlZ3JpdHkgY2hlY2sgcmVmdXNlZCcpCiAgICAgICAgbGlmZWN5Y2xlID0ge25hbWU6IGRiLmV4ZWN1dGUoJ1NFTEVDVCBDT1VOVCgqKSBGUk9NICcgKyB0YWJsZSkuZmV0Y2hvbmUoKVswXQogICAgICAgICAgICAgICAgICAgICBmb3IgbmFtZSwgdGFibGUgaW4gKCgncmVjb3JkcycsICdsaWZlY3ljbGVfcmVjb3JkcycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgnZXZlbnRzJywgJ2xpZmVjeWNsZV9ldmVudHMnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJ3BlbmRpbmcnLCAnbGlmZWN5Y2xlX3BlbmRpbmcnKSl9CiAgICAgICAgcmVzdWx0ID0geydzY2hlbWFfdmVyc2lvbic6IHZlcnNpb24sICdsaWZlY3ljbGUnOiBsaWZlY3ljbGUsCiAgICAgICAgICAgICAgICAgICdvdXRib3gnOiBkaWN0KGRiLmV4ZWN1dGUoJ1NFTEVDVCBzdGF0ZSxDT1VOVCgqKSBGUk9NIG91dGJveCBHUk9VUCBCWSBzdGF0ZScpKSwKICAgICAgICAgICAgICAgICAgJ3N1Ym1pc3Npb25zJzogZGljdChkYi5leGVjdXRlKCdTRUxFQ1Qgc3RhdGUsQ09VTlQoKikgRlJPTSBzdWJtaXNzaW9ucyBHUk9VUCBCWSBzdGF0ZScpKSwKICAgICAgICAgICAgICAgICAgJ2ludGVncml0eSc6ICdvaycsICdyZWFkX29ubHlfcHJlX29wZW4nOiBUcnVlLCAnc3RvcmVfY29uc3RydWN0ZWQnOiBGYWxzZX0KICAgICAgICBkYi5yb2xsYmFjaygpCiAgICByZXR1cm4gcmVzdWx0CgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHBhcnNlciA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPV9fZG9jX18pCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWRiJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKICAgIHRyeToKICAgICAgICBwcmludChqc29uLmR1bXBzKGluc3BlY3RfcmVhZG9ubHkoYXJncy5kYiksIHNvcnRfa2V5cz1UcnVlKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmFpc2UgU3lzdGVtRXhpdCgncmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgcmVmdXNlZDsgbm8gU3RvcmUvYWRtaW4gb3BlbicpIGZyb20gTm9uZQo=" + "content_base64": "IiIiUHJlLW9wZW4gc2NoZW1hL2ludGVncml0eS9jb3VudCBwcm9vZjsgc3RkbGliIG9ubHksIG5ldmVyIGNvbnN0cnVjdHMgU3RvcmUuIiIiCmltcG9ydCBhcmdwYXJzZQpmcm9tIGNvbnRleHRsaWIgaW1wb3J0IGNsb3NpbmcKaW1wb3J0IGhhc2hsaWIKaW1wb3J0IG9zCmltcG9ydCByZQppbXBvcnQgc3RhdAppbXBvcnQganNvbgpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaW1wb3J0IHNxbGl0ZTMKCgpkZWYgaW5zcGVjdF9yZWFkb25seShwYXRoLCAqLCBfY2xvc2VkX3NuYXBzaG90PUZhbHNlKToKICAgIHBhdGggPSBQYXRoKHBhdGgpCiAgICBpZiBub3QgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZXhpc3Rpbmcgbm9uc3ltbGluayBwcml2YXRlIGRhdGFiYXNlIHJlcXVpcmVkJykKICAgIHVyaSA9IHBhdGgucmVzb2x2ZSgpLmFzX3VyaSgpICsgJz9tb2RlPXJvJyArICgnJmltbXV0YWJsZT0xJyBpZiBfY2xvc2VkX3NuYXBzaG90IGVsc2UgJycpCiAgICAjIHNxbGl0ZTMuQ29ubmVjdGlvbiBjb250ZXh0IG1hbmFnZW1lbnQgZW5kcyB0cmFuc2FjdGlvbnM7IGl0IGRvZXMgbm90IGNsb3NlLgogICAgd2l0aCBjbG9zaW5nKHNxbGl0ZTMuY29ubmVjdCh1cmksIHVyaT1UcnVlLCB0aW1lb3V0PTUpKSBhcyBkYjoKICAgICAgICBkYi5leGVjdXRlKCdQUkFHTUEgcXVlcnlfb25seT1PTicpCiAgICAgICAgZGIuZXhlY3V0ZSgnQkVHSU4nKQogICAgICAgIHZlcnNpb24gPSBkYi5leGVjdXRlKCdQUkFHTUEgdXNlcl92ZXJzaW9uJykuZmV0Y2hvbmUoKVswXQogICAgICAgIGlmIHZlcnNpb24gIT0gNToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncHJlLW9wZW4gZGF0YWJhc2UgaXMgbm90IHNjaGVtYTU7IHJlZnVzZSBtaWdyYXRpb24nKQogICAgICAgIGlmIGRiLmV4ZWN1dGUoJ1BSQUdNQSBpbnRlZ3JpdHlfY2hlY2snKS5mZXRjaGFsbCgpICE9IFsoJ29rJywpXToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncmVhZC1vbmx5IGludGVncml0eSBjaGVjayByZWZ1c2VkJykKICAgICAgICBsaWZlY3ljbGUgPSB7bmFtZTogZGIuZXhlY3V0ZSgnU0VMRUNUIENPVU5UKCopIEZST00gJyArIHRhYmxlKS5mZXRjaG9uZSgpWzBdCiAgICAgICAgICAgICAgICAgICAgIGZvciBuYW1lLCB0YWJsZSBpbiAoKCdyZWNvcmRzJywgJ2xpZmVjeWNsZV9yZWNvcmRzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCdldmVudHMnLCAnbGlmZWN5Y2xlX2V2ZW50cycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgncGVuZGluZycsICdsaWZlY3ljbGVfcGVuZGluZycpKX0KICAgICAgICByZXN1bHQgPSB7J3NjaGVtYV92ZXJzaW9uJzogdmVyc2lvbiwgJ2xpZmVjeWNsZSc6IGxpZmVjeWNsZSwKICAgICAgICAgICAgICAgICAgJ291dGJveCc6IGRpY3QoZGIuZXhlY3V0ZSgnU0VMRUNUIHN0YXRlLENPVU5UKCopIEZST00gb3V0Ym94IEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnc3VibWlzc2lvbnMnOiBkaWN0KGRiLmV4ZWN1dGUoJ1NFTEVDVCBzdGF0ZSxDT1VOVCgqKSBGUk9NIHN1Ym1pc3Npb25zIEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlfQogICAgICAgIGRiLnJvbGxiYWNrKCkKICAgIHJldHVybiByZXN1bHQKCgpkZWYgaW5zcGVjdF9jbG9zZWRfc25hcHNob3QocGF0aCwgZXhwZWN0ZWRfc2hhMjU2KToKICAgICIiIk9ubHkgYSBwcml2YXRlbHkgcmV0YWluZWQsIGZyb3plbiBtYWluLWZpbGUgc25hcHNob3Qgd2l0aCBubyBXQUwgZnJhbWVzLgoKICAgIENhbGxlciBtdXN0IGVzdGFibGlzaCBleGNsdXNpdmUgc25hcHNob3QgY3JlYXRpb24vYWRtaW4gZXhpdC9ubyB3cml0ZXIsIGFuZAogICAgc3VwcGx5IHRoZSByZWNvcmRlZCBmcm96ZW4gbWFpbiBkaWdlc3QuIE5ldmVyIHVzZSBmb3IgdGhlIGxpdmUgZGF0YWJhc2UuCiAgICBJbW11dGFibGUgU1FMaXRlIHJlYWRzIGlnbm9yZSBzdGFsZSBTSE0gYW5kIG5ldmVyIGNyZWF0ZS9jaGFuZ2Ugc2lkZWNhcnMuCiAgICBFeGlzdGluZyBzaWRlY2FycyByZW1haW4gY3VzdG9keSBldmlkZW5jZTsgbm90aGluZyBpcyBkZWxldGVkL2NoZWNrcG9pbnRlZC4KICAgICIiIgogICAgcGF0aCA9IFBhdGgocGF0aCkKICAgIGlmIHJlLmZ1bGxtYXRjaChyJ1swLTlhLWZdezY0fScsIGV4cGVjdGVkX3NoYTI1NikgaXMgTm9uZToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdleGFjdCBmcm96ZW4gc25hcHNob3QgZGlnZXN0IHJlcXVpcmVkJykKICAgIGRlZiBtZXRhZGF0YSh0YXJnZXQpOgogICAgICAgIGluZm8gPSB0YXJnZXQubHN0YXQoKQogICAgICAgIGlmIG5vdCBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBvciBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKSAhPSAwbzYwMCBvciBpbmZvLnN0X25saW5rICE9IDE6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgc2luZ2xlLWxpbmsgc25hcHNob3QgY3VzdG9keSByZXF1aXJlZCcpCiAgICAgICAgcmV0dXJuIGluZm8KICAgIG1haW4gPSBtZXRhZGF0YShwYXRoKQogICAgaWYgbm90IDAgPCBtYWluLnN0X3NpemUgPD0gNTEyICogMTAyNCoqMjoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdib3VuZGVkIGZyb3plbiBzbmFwc2hvdCByZXF1aXJlZCcpCiAgICBkZWYgc2lkZWNhcnMoKToKICAgICAgICBpZGVudGl0aWVzID0ge30KICAgICAgICBmb3Igc3VmZml4IGluICgnLXdhbCcsICctc2htJyk6CiAgICAgICAgICAgIHRhcmdldCA9IFBhdGgoc3RyKHBhdGgpICsgc3VmZml4KQogICAgICAgICAgICBpZiBvcy5wYXRoLmxleGlzdHModGFyZ2V0KToKICAgICAgICAgICAgICAgIGluZm8gPSBtZXRhZGF0YSh0YXJnZXQpCiAgICAgICAgICAgICAgICBpZiBpbmZvLnN0X3VpZCAhPSBtYWluLnN0X3VpZCBvciBpbmZvLnN0X2dpZCAhPSBtYWluLnN0X2dpZDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBzaWRlY2FyIGN1c3RvZHkgY2hhbmdlZCcpCiAgICAgICAgICAgICAgICBpZiBzdWZmaXggPT0gJy13YWwnIGFuZCBpbmZvLnN0X3NpemUgIT0gMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBoYXMgV0FMIGZyYW1lczsgaW1tdXRhYmxlIHJlYWQgcmVmdXNlZCcpCiAgICAgICAgICAgICAgICBpZGVudGl0aWVzW3N1ZmZpeF0gPSAoaW5mby5zdF9kZXYsIGluZm8uc3RfaW5vLCBpbmZvLnN0X3NpemUsIGluZm8uc3RfbXRpbWVfbnMpCiAgICAgICAgcmV0dXJuIGlkZW50aXRpZXMKICAgIGJlZm9yZV9zaWRlY2FycyA9IHNpZGVjYXJzKCkKICAgIGRlZiBkaWdlc3QoKToKICAgICAgICB2YWx1ZSA9IGhhc2hsaWIuc2hhMjU2KCkKICAgICAgICB3aXRoIHBhdGgub3BlbigncmInKSBhcyBzdHJlYW06CiAgICAgICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6CiAgICAgICAgICAgICAgICB2YWx1ZS51cGRhdGUoYmxvY2spCiAgICAgICAgcmV0dXJuIHZhbHVlLmhleGRpZ2VzdCgpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTY6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIG1haW4tZmlsZSBkaWdlc3QgY2hhbmdlZCBiZWZvcmUgaW5zcGVjdGlvbicpCiAgICBwcm9vZiA9IGluc3BlY3RfcmVhZG9ubHkocGF0aCwgX2Nsb3NlZF9zbmFwc2hvdD1UcnVlKQogICAgYWZ0ZXIgPSBtZXRhZGF0YShwYXRoKQogICAgaWYgKGFmdGVyLnN0X2RldiwgYWZ0ZXIuc3RfaW5vLCBhZnRlci5zdF91aWQsIGFmdGVyLnN0X2dpZCwgYWZ0ZXIuc3Rfc2l6ZSkgIT0gKG1haW4uc3RfZGV2LCBtYWluLnN0X2lubywgbWFpbi5zdF91aWQsIG1haW4uc3RfZ2lkLCBtYWluLnN0X3NpemUpOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ2Zyb3plbiBtYWluLWZpbGUgaWRlbnRpdHkgY2hhbmdlZCcpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTYgb3Igc2lkZWNhcnMoKSAhPSBiZWZvcmVfc2lkZWNhcnM6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIHNuYXBzaG90IGNoYW5nZWQgZHVyaW5nIGluc3BlY3Rpb24nKQogICAgcmV0dXJuIHByb29mCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHBhcnNlciA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPV9fZG9jX18pCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWRiJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKICAgIHRyeToKICAgICAgICBwcmludChqc29uLmR1bXBzKGluc3BlY3RfcmVhZG9ubHkoYXJncy5kYiksIHNvcnRfa2V5cz1UcnVlKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmFpc2UgU3lzdGVtRXhpdCgncmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgcmVmdXNlZDsgbm8gU3RvcmUvYWRtaW4gb3BlbicpIGZyb20gTm9uZQo=" }, { "digest": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", @@ -205,9 +234,9 @@ "content_base64": "ewogICJjb25maWdtYXAiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJ2MSIsCiAgICAiaW1tdXRhYmxlIjogdHJ1ZSwKICAgICJraW5kIjogIkNvbmZpZ01hcCIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOi9Db25maWdNYXA6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiLAogICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICB9LAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIsCiAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAidWlkIjogIjkwMTEzZDJkLTU0ZDktNGU4Mi1iMWQzLTkwYjQ5ZWJlZDJiNSIKICAgIH0sCiAgICAiY2Fub25pY2FsX2RhdGFfc2hhMjU2IjogIjhlYzQ2MmQxMjM0NzU0OGY1MDZlZWViZjFlM2M3Y2M0NzY0ODAxOWM4YTc4MzgwNGQwOWJjYzc5YjBmMjJhZjYiCiAgfSwKICAicHZjIjogewogICAgImFwaVZlcnNpb24iOiAidjEiLAogICAgImtpbmQiOiAiUGVyc2lzdGVudFZvbHVtZUNsYWltIiwKICAgICJtZXRhZGF0YSI6IHsKICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICJhcmdvY2QuYXJnb3Byb2ouaW8vdHJhY2tpbmctaWQiOiAiaW5mb3JtZWQtZGVjaXNpb246L1BlcnNpc3RlbnRWb2x1bWVDbGFpbTppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIsCiAgICAgICAgInB2Lmt1YmVybmV0ZXMuaW8vYmluZC1jb21wbGV0ZWQiOiAieWVzIiwKICAgICAgICAicHYua3ViZXJuZXRlcy5pby9ib3VuZC1ieS1jb250cm9sbGVyIjogInllcyIsCiAgICAgICAgInZvbHVtZS5iZXRhLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiLAogICAgICAgICJ2b2x1bWUua3ViZXJuZXRlcy5pby9zZWxlY3RlZC1ub2RlIjogIjIzOS42Mi4yMDUuOTIuaG9zdC5zZWN1cmVzZXJ2ZXIubmV0IiwKICAgICAgICAidm9sdW1lLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiCiAgICAgIH0sCiAgICAgICJmaW5hbGl6ZXJzIjogWwogICAgICAgICJrdWJlcm5ldGVzLmlvL3B2Yy1wcm90ZWN0aW9uIgogICAgICBdLAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICJ1aWQiOiAiZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfSwKICAgICJzcGVjIjogewogICAgICAiYWNjZXNzTW9kZXMiOiBbCiAgICAgICAgIlJlYWRXcml0ZU9uY2UiCiAgICAgIF0sCiAgICAgICJyZXNvdXJjZXMiOiB7CiAgICAgICAgInJlcXVlc3RzIjogewogICAgICAgICAgInN0b3JhZ2UiOiAiMUdpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInN0b3JhZ2VDbGFzc05hbWUiOiAibG9jYWwtcGF0aCIsCiAgICAgICJ2b2x1bWVNb2RlIjogIkZpbGVzeXN0ZW0iLAogICAgICAidm9sdW1lTmFtZSI6ICJwdmMtZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfQogIH0sCiAgInB2Y19waGFzZSI6ICJCb3VuZCIKfQo=" }, { - "digest": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478", + "digest": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5", "media_type": "text/markdown", - "content_base64": "IyBQcm90ZWN0ZWQgbmF0aXZlIGJhY2t1cC9yZXN0b3JlIGFuZCBpbWFnZS1vbmx5IHJlbGVhc2UgcHJvdG9jb2wKClByZXBhcmVkIHByb3RvY29sIGZvciBgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFgLiBObyBhY3R1YWwgbmF0aXZlIGJhY2t1cCwgZGF0YSBleHBvcnQsIHJlc3RvcmUsIHdvcmtsb2FkIGNoYW5nZSBvciBhcHByb3ZhbCBpcyByZWNvcmRlZCBoZXJlLiBDYW5kaWRhdGUgcmVnaXN0cnkgaW1hZ2UgaWRlbnRpdHkgcmVtYWlucyBhIHByZXJlcXVpc2l0ZTsgb25seSBhZnRlciBhY3R1YWwgYXJ0aWZhY3QgcHJvb2YgbWF5IHRoZSBmb3VuZGVyIGFwcHJvdmUgb25lIGV4YWN0IGNvbmRpdGlvbmFsIHByb3RvY29sL3JvbGxvdXQgcGFja2V0LiBUaGUgY29uZmlnLW9ubHk3ZGI4NDg1IGFwcHJvdmFsIGlzIG91dHNpZGUgdGhpcyBzY29wZS4KCiMjIFByZWNvbmRpdGlvbnMgYW5kIHByb3RlY3RlZCBjdXN0b2R5CgpGcmVlemUgZXhhY3QgY2FuZGlkYXRlIGFuZCBwcmlvcjdmNWM2Y2IgaW1hZ2UgZGlnZXN0cywgc291cmNlL2luc3RhbGxlZCBwb2xpY3kgaGFzaGVzLCBjdXJyZW50IG1hbnVhbGx5IG1hbmFnZWQgQXJnbyBBcHBsaWNhdGlvbi9yZXZpc2lvbiwgcnVudGltZSBDb25maWdNYXA2YzIyMTg3OGQwNTEsIERlcGxveW1lbnQgVUlEL3RlbXBsYXRlL3NwZWMsIHNjaGVtYTUsIHBvbGljeSBwYWNrYWdlIHBpbnMsIGRhdGFiYXNlIHBhdGggYC9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZWAsIFBWQyBiaW5kaW5nLCByZXBsaWNhczEvUmVjcmVhdGUgYW5kIHN0YWJsZSBrZXlzIGZvciBpbnRlbmRlZCB2ZXJpZmljYXRpb24uIENvbmZpcm0gbm8gY29uY3VycmVudCB3cml0ZXIgb3IgY3VzdG9keSBjaGFuZ2UuIFVzZSBmaXhlZCBtZXRhZGF0YTsgbmV2ZXIgZmV0Y2ggU2VjcmV0IG9iamVjdHMgb3IgdG9rZW4gdmFsdWVzLiBBIGNoYW5nZWQgaW1hZ2UvY29uZmlnL3NjaGVtYS9vd25lciBpbnZhbGlkYXRlcyB0aGUgcGFja2V0LiBGcmVzaCByZXNvdXJjZXMvaGVhZHJvb20gYW5kIGV4YWN0IHNvdXJjZS9uYXRpdmUgc2VydmVyLWRyeS1ydW4vZGlmZiByZW1haW4gcmVxdWlyZWQuCgpCYWNrdXBzIGFyZSBwcml2YXRlIGV2aWRlbmNlIGNvbnRhaW5pbmcgcmVhbCBkZWNpc2lvbiByZWNvcmRzLCBub3QgbG9ncyBvciBwYWNrZXQgYXR0YWNobWVudHMuIEFsbG9jYXRlIGEgdW5pcXVlIGJhY2t1cCBkaXJlY3RvcnkgdW5kZXIgZXhpc3RpbmcgcHJvdGVjdGVkIFBWQyBjdXN0b2R5LCBvd25lZDEwMDAxLCBtb2RlMDcwMCwgc25hcHNob3QgZmlsZTA2MDAsIG5vIHN5bWxpbmsvaGFyZGxpbmsvcmV1c2VkIG91dHB1dCBwYXRoLiBBbiBvZmYtY2x1c3RlciBjb3B5IGJlbG9uZ3Mgb25seSBpbiB0aGUgYWxyZWFkeSBlc3RhYmxpc2hlZCBpZ25vcmVkIGAucHJpdmF0ZS1iYWNrdXBzLzx1bmlxdWUtdHJpYWwtZGlyZWN0b3J5PmAgY3VzdG9keSB3aXRoMDcwMC8wNjAwIHBlcm1pc3Npb25zOyBubyBHaXQsIFN0YXRlSHViLCBwdWJsaWMgb2JqZWN0IHN0b3JlIG9yIHRlcm1pbmFsLWNvbnRlbnQgZHVtcC4gUmVjb3JkIG9ubHkgc2NoZW1hLCBpbnRlZ3JpdHkgcGFzcy9mYWlsLCBib3VuZGVkIHRhYmxlL3N0YXRlIGNvdW50cyBhbmQgcHJvdGVjdGVkIHJlY2VpcHQgaWRlbnRpZmllcjsgcmV0YWluIGJ5dGUgZGlnZXN0cyBpbiBwcm90ZWN0ZWQgY3VzdG9keSBpZiBuZWVkZWQgZm9yIGludGVybmFsIGNvcHkgaWRlbnRpdHkuIE5vIGNyZWRlbnRpYWwsIHJlY29yZCBwYXlsb2FkIG9yIHRva2VuIGZpbmdlcnByaW50IGVudGVycyBwdWJsaWMgZXZpZGVuY2UuCgojIyBBcHByb3ZlZCBvbmxpbmUgY29tcGF0aWJpbGl0eSBkcmlsbAoKV2l0aGluIHRoZSBleHBsaWNpdCBmb3VuZGVyLWFwcHJvdmVkIGFjdGlvbiwgcnVuIHRoZSBleGlzdGluZyBiYXNlIGltYWdlJ3MgYGluZm9ybWVkLWRlY2lzaW9uLWFkbWluIGJhY2t1cCAtLWRiIC9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZSAtLW91dHB1dCA8bmV3LXByaXZhdGUtc25hcHNob3Q+YCBpbiB0aGUgYWN0dWFsIHNlcnZpbmcgd29ya2xvYWQuIFRoaXMgdXNlcyBTUUxpdGUncyBiYWNrdXAgQVBJIGZvciBhIHRyYW5zYWN0aW9uYWxseSBjb25zaXN0ZW50IHNuYXBzaG90OyBjb3B5aW5nIGEgbGl2ZSBtYWluIGRhdGFiYXNlIHdoaWxlIGlnbm9yaW5nIFdBTCBpcyBwcm9oaWJpdGVkLiBTdXBwcmVzcyByYXcgZmFpbHVyZXMvb3V0cHV0IGFuZCByZXRhaW4gb25seSBzYW5pdGl6ZWQgc3RhdHVzLiBPYnNlcnZlIHNjaGVtYS9pbnRlZ3JpdHkgYW5kIGNvdW50LW9ubHkgbWV0YWRhdGEgZnJvbSB0aGUgcmVzdWx0aW5nIHNuYXBzaG90LCBub3QgcmVjb3JkIGNvbnRlbnQuCgpUcmFuc2ZlciB0aGF0IGNvbnNpc3RlbnQgc25hcHNob3Qgb25seSBpbnRvIHByb3RlY3RlZCBvZmYtY2x1c3RlciBjdXN0b2R5IHRocm91Z2ggdGhlIGV4aXN0aW5nIGF1dGhvcml6ZWQgb3BlcmF0b3IgbGFuZS4gVGhlIGNvcHkgaXMgcmVhbCBwcm9kdWN0aW9uIGRhdGEgZXZlbiBpbiBidWlsZCBtb2RlLiBWZXJpZnkgcHJpdmF0ZSBwZXJtaXNzaW9ucywgdW5pcXVlIGlkZW50aXR5IGFuZCBwcm90ZWN0ZWQgaW50ZXJuYWwgZGlnZXN0IGFncmVlbWVudC4gRG8gbm90IGV4cG9ydCBtb3VudGVkIHdvcmtsb2FkIGNyZWRlbnRpYWxzIG9yIGRpcmVjdG9yeSB0cmVlczsgY29weSBvbmx5IHRoZSBleGFjdCBzbmFwc2hvdC4KCkNyZWF0ZSBhIHNlcGFyYXRlIHByaXZhdGUgZGlzcG9zYWJsZSByZXN0b3JlIHZvbHVtZS9kaXJlY3Rvcnk7IHJldGFpbiB0aGUgb3JpZ2luYWwgc25hcHNob3QgdW5jaGFuZ2VkLiBSdW4gdGhlIGV4YWN0IHB1Ymxpc2hlZCBjYW5kaWRhdGUgd2l0aCBuZXR3b3JrIGRpc2FibGVkLCBubyBwcm9kdWN0aW9uIENvbmZpZ01hcC90b2tlbiBtb3VudHMsIHJlYWQtb25seSBpbWFnZSBhbmQgb25seSB0aGF0IGlzb2xhdGVkIHZvbHVtZSB3cml0YWJsZS4gT3ZlcnJpZGUgdGhlIHNlcnZpY2UgZW50cnlwb2ludCB3aXRoIHRoZSBvd25lcidzIGNvdW50LW9ubHkgYWRtaW5pc3RyYXRpdmUgaW5zcGVjdGlvbi9pbnRlZ3JpdHkgY2hlY2s7IGRvIG5vdCBzdGFydCBIVFRQIGxpc3RlbmVycywgYXVkaXQgZGVsaXZlcnksIHJlcXVlc3RlciBleGNoYW5nZXMgb3IgYXBwcm92YWwgb3BlcmF0aW9ucy4gVGhlIGN1cnJlbnQgY2FuZGlkYXRlIGNoYW5nZXMgcG9saWN5LnB5IG9ubHkgYW5kIHJldGFpbnMgdGhlIHNjaGVtYS9zdG9yZSBtb2R1bGUgYnl0ZXM7IHN0aWxsIHByb3ZlIHNjaGVtYTUsIFNRTGl0ZSBpbnRlZ3JpdHkgYW5kIGV4YWN0IGJvdW5kZWQgY291bnRzIGJlZm9yZS9hZnRlciBvcGVuaW5nIHRoZSByZXN0b3JlZCBjb3B5LiBSZWZ1c2UgYW55IG1pZ3JhdGlvbi9kb3duZ3JhZGUsIGxvc3QvY2hhbmdlZCBjb3VudHMsIHVuZXhwZWN0ZWQgd3JpdGUgY2xhc3Mgb3IgdW5rbm93biBvdXRjb21lLiBLZWVwIHBlbmRpbmcvdW5jZXJ0YWluIHN1Ym1pc3Npb24gYW5kIG91dGJveCBzdGF0ZXM7IG5ldmVyIHJlcGxheSwgZGlzY2FyZCBvciBtYXJrIHRoZW0gZGVsaXZlcmVkIHRvIGdyZWVuIHRoZSBkcmlsbC4gQ2xlYW51cCBvbmx5IHRoZSBkaXNwb3NhYmxlIGNvcHkvdm9sdW1lIGFmdGVyIHZlcmlmaWVkIHJlY2VpcHQ7IHJldGFpbiB0aGUgb3JpZ2luYWwgcHJvdGVjdGVkIGJhY2t1cCBmb3IgdGhlIGFwcHJvdmVkIHJlY292ZXJ5IGludGVydmFsLgoKVGhpcyBzdGVwIGlzIGFjdHVhbCBuYXRpdmUtZGF0YSBjb21wYXRpYmlsaXR5IGV2aWRlbmNlIG9uY2UgcGVyZm9ybWVkLiBJdHMgcHJldmlvdXMgc3ludGhldGljIGZpeHR1cmUgY2hlY2tzIHJlbWFpbiBtZWNoYW5pc20gZXZpZGVuY2UgYW5kIGNhbm5vdCBiZSByZW5hbWVkIG5hdGl2ZSBzdWNjZXNzLiBBIGZhaWxlZCBkcmlsbCBzdG9wcyByb2xsb3V0IGFuZCByZW1haW5zIGEgZmFpbGVkL3VudmVyaWZpZWQgb3V0Y29tZSBpbiB0aGUgc2FtZSB0cmlhbC4KCiMjIEZyZXNoIGN1dG92ZXIgc25hcHNob3QgYW5kIHNpbmdsZS13cml0ZXIgcm9sbG91dAoKQWZ0ZXIgc3VjY2Vzc2Z1bCBhY3R1YWwtZGF0YSBjb21wYXRpYmlsaXR5IGNoZWNrcywgY3JlYXRlIGFub3RoZXIgdW5pcXVlIFNRTGl0ZS1jb25zaXN0ZW50IG9ubGluZSBzbmFwc2hvdCBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGltYWdlIGN1dG92ZXIsIHJldGFpbmluZyBpdHMgcG9pbnQtaW4tdGltZSBzY2hlbWEvaW50ZWdyaXR5L2NvdW50IHJlY2VpcHQuIFRoaXMgaXMgYW4gb25saW5lIHRyYW5zYWN0aW9uYWwgc25hcHNob3QsIG5vdCBhIGNsYWltIHRoYXQgZGlzcGF0Y2hlcnMgb3IgaHVtYW4gd3JpdGVzIHdlcmUgcXVpZXNjZWQuIEV2ZXJ5IGxhdGVyIGNvbW1pdHRlZCByZWNvcmQgcmVtYWlucyBpbiB0aGUgbGl2ZSBkYXRhYmFzZTsgc2FtZS1zY2hlbWEgcm9sbGJhY2sgcmV0YWlucyB0aGF0IGRhdGFiYXNlIGFuZCBuZXZlciByZXN0b3JlcyB0aGUgZWFybGllciBzbmFwc2hvdCBvdmVyIGl0LiBUaGUgbmFycm93IGltYWdlLW9ubHkgdXBkYXRlIGRvZXMgbm90IG5lZWQgZGlzcGF0Y2hlci9jb25maWd1cmF0aW9uL1BWQy90ZW1wb3JhcnktcG9kIGNoYW5nZXMgb3IgYSBzY2hlbWEgY3V0b3Zlci4gSWYgZnJlc2ggdmVyaWZpY2F0aW9uIHNob3dzIGEgbWlncmF0aW9uIG9yIGFueSBkYXRhLXJlc3RvcmF0aW9uIHJlcXVpcmVtZW50LCBzdG9wIGFuZCByZWZpbmUgdGhlIHByb3Bvc2FsIHJhdGhlciB0aGFuIGFwcGx5aW5nIHRoaXMgcHJvdG9jb2wuCgpUaGUgZXhpc3RpbmcgUmVjcmVhdGUgcm9sbG91dCBkcmFpbnMvc3RvcHMgdGhlIHNpbmdsZSBvbGQgd3JpdGVyIGJlZm9yZSBzdGFydGluZyB0aGUgbmV3IGltYWdlIG9uIHRoZSBzYW1lIFBWQzsgdGhlIGluaGVyaXRlZCBzaW5nbGUtd3JpdGVyIGxvY2sgaW5kZXBlbmRlbnRseSByZWZ1c2VzIGNvbmN1cnJlbnQgc2VydmluZyBwcm9jZXNzZXMuIERvIG5vdCBhZGQgYW4gYWRtaW4gcG9kLCBzY2FsZS10by16ZXJvLCBkaXNwYXRjaGVyIHN0b3AsIG5ldHdvcmstcG9saWN5IHJld3JpdGUgb3Igc25hcHNob3Qgb3ZlcndyaXRlIGFzIGFuIGltcHJvdmlzZWQgaW1hZ2Utb25seSBzdGVwLiBUaGUgZXhpc3Rpbmcgb3duZXIgYWRtaW4gYmFja3VwIG9wZXJhdGlvbiBydW5zIGluc2lkZSB0aGUgYWRtaXR0ZWQgc2VydmluZyB3b3JrbG9hZCwgYW5kIGl0cyBzZXBhcmF0ZSBwcm90ZWN0ZWQgcmVzdG9yZSBkcmlsbCBydW5zIG9mZi1jbHVzdGVyIHdpdGggbmV0d29yayBkaXNhYmxlZCBhbmQgbm8gd29ya2xvYWQgY3JlZGVudGlhbHMuIFRob3NlIGV4YWN0IGN1c3RvZHkgb3BlcmF0aW9ucyBtdXN0IGJlIGVudW1lcmF0ZWQgaW4gdGhlIGZvdW5kZXIgcGFja2V0IGFsb25nc2lkZSB0aGUgb25lIERlcGxveW1lbnQgaW1hZ2UgY2hhbmdlLgoKT25jZSBiYWNrdXAvY29tcGF0aWJpbGl0eS9wcmVmbGlnaHQgZ2F0ZXMgcGFzcywgbWFudWFsbHkgcGluIHRoZSBleGlzdGluZyBBcmdvIEFwcGxpY2F0aW9uIHRvIHRoZSBleGFjdCByZXZpZXdlZCBzb3VyY2UgcmV2aXNpb24gYW5kIHN5bmMgb25seSBEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHdpdGggcHJ1bmUgZmFsc2UsIGtlZXBpbmcgdGhlIGN1cnJlbnQgaW1tdXRhYmxlIHJ1bnRpbWUgQ29uZmlnTWFwIGFuZCBhbGwgb3RoZXIgcmVzb3VyY2VzLiBUaGUgc291cmNlIHBhdGNoIGNoYW5nZXMgb25seSB0aGUgaW1hZ2UgaW4gYWRtaXNzaW9uL3JlbmRlcmVkIERlcGxveW1lbnQ7IG5vIFNlY3JldCwgUFZDLCBwb2xpY3ksIGRhdGFiYXNlIG9yIGRpc3BhdGNoZXIgY2hhbmdlIGlzIGluY2x1ZGVkIHVubGVzcyBzZXBhcmF0ZWx5IGVudW1lcmF0ZWQgaW4gdGhlIGZpbmFsIHByb3Bvc2FsLiBPYnNlcnZlIGZpdmUtbWludXRlIHJlYWRpbmVzcyBhbmQgZXhhY3QgaW1hZ2UvY29uZmlnL3NjaGVtYS9waW5zLiBSdW4gdGhlIHRlbiBpbnN0YWxsZWQgcHVycG9zZSB2YXJpYW50cyBvbiB0aGUgYWN0dWFsIG5hdGl2ZSBwbGFjZW1lbnQgdXNpbmcgc3ludGhldGljIHRyYW5zcG9ydDsgdGhleSBwcm92ZSBleGFjdCBpbnN0YWxsZWQgbW9kdWxlIHJlZnVzYWwgYmVoYXZpb3IgYW5kIGV4cGxpY2l0bHkgcmVwb3J0IG5hdGl2ZV9wcm92aWRlcj1mYWxzZS4gVGhleSBkbyBub3QgcHJvdmUgYW4gYWN0dWFsIHByb3ZpZGVyIHJlc3BvbnNlLCBQRFAgYXV0aG9yaXR5IG9yIG5hdGl2ZSBsaWZlY3ljbGUgYmluZGluZzsgYW55IHJlcXVpcmVkIGFjdHVhbC1wcm92aWRlciBwcm9vZiByZW1haW5zIGEgZGlzdGluY3QgVDA0IGNvbXBsZXRpb24gZ2F0ZSB3aXRoIHNlcGFyYXRlIGF1dGhvcml6ZWQgcHJlcGFyYXRpb24sIGFuZCBtdXN0IG5vdCBiZSBjbGFpbWVkIGJ5IHRoaXMgaGVscGVyLiBEbyBub3QgY29udGFtaW5hdGUgdGhlIGxpdmUgUERQLCBjcmVhdGUgaHVtYW4gYXBwcm92YWxzLCByZWFkIGNyZWRlbnRpYWxzIHRocm91Z2ggQ0xJLCBvciByZXBsYXkgdW5rbm93biBleHRlcm5hbCBvdXRjb21lcyBmb3IgdGVzdGluZy4KCiMjIFNhbWUtc2NoZW1hIHJvbGxiYWNrIGFuZCBldmlkZW5jZSByZXRlbnRpb24KCk9uIHN0YXJ0dXAvcmVhZGluZXNzL2JpbmRpbmcvcmVmdXNhbCBmYWlsdXJlLCByZXRhaW4gY3VycmVudCBkYXRhYmFzZSwgY3V0b3ZlciBiYWNrdXAgYW5kIGV2ZXJ5IHBvc3QtY3V0b3ZlciBldmlkZW5jZS91bmNlcnRhaW4gb3V0Y29tZS4gUmVzdG9yZSBvbmx5IHRoZSBwcmlvcjdmNWM2Y2IgaW1hZ2UgdGhyb3VnaCB0aGUgc2FtZSBtYW51YWwgQXJnbyBvd25lciBwYXRoLCByZXRhaW5pbmcgc2NoZW1hNSBhbmQgY3VycmVudCBEQi9jb25maWd1cmF0aW9uOyBuZXZlciByZXN0b3JlIGFuIG9sZCBzbmFwc2hvdCBvdmVyIGN1cnJlbnQgbGl2ZSBldmlkZW5jZSBqdXN0IHRvIHJvbGwgdGhlIGltYWdlIGJhY2suIFZlcmlmeSBvbGQgaW1hZ2UvUmVhZHkxLCBzYW1lIHNjaGVtYS9jb3VudHMgYW5kIHByaW9yIGJlaGF2aW9yLCBhbmQgcmVjb25jaWxlIGFueSBleHRlcm5hbCBlZmZlY3RzIHVzaW5nIGV4aXN0aW5nIGxpZmVjeWNsZS9hdWRpdCBvd25lcnNoaXAuIFRoZSBuYXJyb3cgb3ZlcmxheSdzIGlkZW50aWNhbCBzdG9yZS9zY2hlbWEvZGVwZW5kZW5jeSBieXRlcyBwZXJtaXQgdGhpcyBpbWFnZS1vbmx5IHJvbGxiYWNrOyBpdCBpcyBub3QgcGVybWlzc2lvbiBmb3IgYSBzY2hlbWEgZG93bmdyYWRlIG9yIGRhdGEgbG9zcy4KClJlY29yZCBvcmlnaW5hbC9hcHByb3ZlZC9leGVjdXRlZCBzb3VyY2UgYW5kIGltYWdlIHJldmlzaW9ucywgYmFja3VwL2RyaWxsL2N1dG92ZXIvcm9sbG91dCB0aW1lc3RhbXBzLCBleGFjdCBkaXNwb3NpdGlvbiBhbmQgc2FuaXRpemVkIG91dGNvbWVzIGluIHRoZSBleGlzdGluZyBzdXBlcnZpc2VkIHRyaWFsIHJlY2VpcHQuIEVVUjAgaW5jcmVtZW50YWwgaW5mcmFzdHJ1Y3R1cmUgZXN0aW1hdGUgdXNlcyBleGlzdGluZyBzZXJ2aWNlL3N0b3JhZ2Uvb3BlcmF0b3IgbGFuZTsgcHJvdGVjdGVkIHRlbXBvcmFyeSBjb3B5L3N0b3JhZ2UgY29uc3VtcHRpb24gYW5kMTXigJMzMG1pbnV0ZSByZWNvdmVyeSB0aW1lIHJlbWFpbiBvcGVyYXRpb25hbCBjb3N0cy4gTm8gRVVSIGluY2lkZW50LWxvc3MgY2FwIG9yIGF1dG9ub215IGdyYW50IGlzIGluZmVycmVkLiBUYXNrVDA0IGNhbm5vdCBjbG9zZSB1bnRpbCBhY3R1YWwgcHVibGlzaGVkIGltYWdlLCBhcHByb3ZlZCBuYXRpdmUgY29tcGF0aWJpbGl0eSBhbmQgcmVsZWFzZSBwbHVzIHBvc3QtcmVsZWFzZSByZWZ1c2FsL2JpbmRpbmcgZXZpZGVuY2UgYWxsIGV4aXN0LgoKIyMgRXhhY3QgcmVsZWFzZSBjYXNlIGlkZW50aWZpZXJzCgpQcm9wb3NhbCBgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFgLCB0cmlhbCBgaW5mZC1wdXJwb3NlLTIwMjYxMDExLXIxYC4KUHJvdGVjdGVkIG5hdGl2ZSBwYXJlbnQgYC9kYXRhL3ByaXZhdGUvcHVycG9zZS1vdmVybGF5LXIxYCBtdXN0IGJlIHVuaXF1ZS9ub24tc3ltbGluaywgb3duZWQxMDAwMSBhbmQwNzAwLiBUaGUgZHJpbGwgc25hcHNob3QgaXMgYGRyaWxsLnNxbGl0ZWAsIHRoZSByZWZyZXNoZWQgcHJlLWN1dG92ZXIgc25hcHNob3QgYGN1dG92ZXIuc3FsaXRlYCwgZWFjaCBuZXcwNjAwIGZpbGU7IHJlZnVzZSBhbnkgZXhpc3Rpbmcgb3V0cHV0LiBPZmYtY2x1c3RlciBjdXN0b2R5IGlzIHRoZSBleGlzdGluZyBpZ25vcmVkIEN1c3RvZGlhbiBgLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjFgIHBhcmVudDA3MDAsIGZpbGVzMDYwMDsgbm8gc25hcHNob3QgaXMgYW4gZXZpZGVuY2UgYXR0YWNobWVudC4gQ2hlY2sgb3duZXIgVUlELCBubyBzeW1saW5rcywgaWdub3JlZCBzdGF0dXMgYW5kIGZyZWUgY2FwYWNpdHkgZm9yIGJvdGggbmF0aXZlIHNuYXBzaG90cyBwbHVzIGluZGVwZW5kZW50bHkgcHJvdGVjdGVkIGNvcGllcyBiZWZvcmUgbWFraW5nIGFueSBzbmFwc2hvdC4KClRoZSBkaXNwb3NhYmxlIG9mZmxpbmUgcmVzdG9yZSB2b2x1bWUgaXMgYGluZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExYDsgcmVmdXNlIGFuIGV4aXN0aW5nIHZvbHVtZSwgY29weSBvbmx5IHRoZSBzZWxlY3RlZCBmcm96ZW4gc25hcHNob3QsIGFuZCBydW4gZXhhY3QgcHVibGlzaGVkIGNhbmRpZGF0ZTc2M2Mgd2l0aCBuZXR3b3Jrbm9uZS9yZWFkLW9ubHkgaW1hZ2UsMTI4TWlCL2NvcmUxIGFuZCBubyBydW50aW1lIGNvbmZpZy90b2tlbiBtb3VudHMuIFNRTGl0ZSBgUFJBR01BIGludGVncml0eV9jaGVja2AgbXVzdCByZXR1cm4gYG9rYCwgYFBSQUdNQSB1c2VyX3ZlcnNpb25gL1N0b3JlIGluc3BlY3Rpb24gbXVzdCBhZ3JlZSB3aXRoIGFjdHVhbCBzY2hlbWE1IHNlbWFudGljcywgYW5kIGluc3RhbGxlZCBhZG1pbiBjb3VudC1vbmx5IGluc3BlY3Rpb24gbXVzdCBtYXRjaCB0aGUgZnJvemVuIHNuYXBzaG90LiBWYWxpZGF0ZSB0aGUgYWN0dWFsIHNjaGVtYSByZXByZXNlbnRhdGlvbiByYXRoZXIgdGhhbiBhc3N1bWUgUFJBR01BIHVzZXJfdmVyc2lvbiBpcyB0aGUgc2NoZW1hIGF1dGhvcml0eS4gTm8gc3ludGhldGljIHJlc3RvcmF0aW9uIGlzIHJlcG9ydGVkIGFzIG5hdGl2ZSByZXN0b3JhdGlvbi4gTmF0aXZlIG9yaWdpbmFsL29mZi1jbHVzdGVyIGNvcGllcyByZW1haW4gcmV0YWluZWQ7IG9ubHkgdGhlIGRpc3Bvc2FibGUgcmVzdG9yZSBjb3B5L3ZvbHVtZSBtYXkgYmUgcmVtb3ZlZCB1bmRlciB0aGUgZXhhY3QgYXBwcm92ZWQgY2xlYW51cCBzY29wZS4KCiMjIE1hbmRhdG9yeSBwcmUtb3BlbiBzY2hlbWEgZ2F0ZSBhbmQgb2ZmbGluZSBjb21tYW5kCgpgaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4gaW5zcGVjdGAgYW5kIGBiYWNrdXBgIGNvbnN0cnVjdCBTdG9yZSwgd2hpY2ggY2FuIG1pZ3JhdGUgc2NoZW1hczHigJM0IHRvNS4gVGhlcmVmb3JlICoqYmVmb3JlIGFueSBTdG9yZS9hZG1pbiBvcGVuKiosIHJ1biB0aGUgZXhhY3QgYXR0YWNoZWQgc3RkbGliLW9ubHkgYHNxbGl0ZV9yZWFkb25seS5weWAgYWdhaW5zdCB0aGUgbmF0aXZlIHNvdXJjZSBkYXRhYmFzZSB1c2luZyBTUUxpdGUgVVJJIG1vZGU9cm8sIHF1ZXJ5X29ubHkgYW5kIG9uZSByZWFkIHRyYW5zYWN0aW9uLiBSZXF1aXJlIFBSQUdNQSB1c2VyX3ZlcnNpb241LCBpbnRlZ3JpdHlfY2hlY2s9b2sgYW5kIHJldGFpbiBjb3VudC1vbmx5IGJhc2VsaW5lLiBSZWZ1c2UgYW55IG90aGVyL3Vua25vd24gc2NoZW1hIG9yIGluY29tcGxldGUgaW50ZWdyaXR5L2NvdW50IGNoZWNrIGJlZm9yZSBjb25zdHJ1Y3RpbmcgU3RvcmU7IGRvIG5vdCBpbmZlciBubyBtaWdyYXRpb24gZnJvbSBhIHBvc3Qtb3BlbiBhZG1pbiByZXBvcnQuIFRoaXMgbmF0aXZlIGdhdGUgaGFzIG5vdCBiZWVuIGV4ZWN1dGVkIGluIHRoaXMgc291cmNlLXByZXBhcmF0aW9uIHN0YWdlLiBSZXBlYXQgYmVmb3JlIGVhY2ggbmF0aXZlIGJhY2t1cC9hZG1pbiBvcGVyYXRpb24uCgpBZnRlciBjb3B5aW5nIHRoZSBzZWxlY3RlZCBjb25zaXN0ZW50IHNuYXBzaG90IHRvIHRoZSBpc29sYXRlZCByZXN0b3JlZCBwcml2YXRlIHBhdGggYC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgLCBydW4gdGhlIHNhbWUgcmVhZC1vbmx5IGNoZWNrZXIgKipiZWZvcmUqKiBhbnkgb2ZmbGluZSBjYW5kaWRhdGUgYWRtaW4vU3RvcmUgb3BlbnMgdGhhdCBjb3B5LiBGcm96ZW4gc25hcHNob3QgYW5kIHJlc3RvcmVkLWNvcHkgc2NoZW1hL2ludGVncml0eS9jb3VudCByZXBvcnRzIG11c3QgYWdyZWUgZXhhY3RseTsgdGhlIGNvcGllZCBtYWluLWZpbGUgZGlnZXN0IG11c3QgbWF0Y2ggdGhlIHNlbGVjdGVkIGNsb3NlZCBzbmFwc2hvdC4gUmVqZWN0IG9sZHNjaGVtYSBmaXh0dXJlcyByYXRoZXIgdGhhbiBhbGxvdyBtaWdyYXRpb24uIE9ubHkgYWZ0ZXIgdGhpcyBwcmUtb3BlbiBnYXRlIG1heSB0aGUgb2ZmbGluZSBjYW5kaWRhdGUgYWRtaW4gaW5zcGVjdCBydW4uCgpPZmZsaW5lIGNvbW1hbmQgdmVjdG9ycyB1c2UgZXhhY3RpbWFnZSBgZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhYCwgYC0tbmV0d29yayBub25lIC0tcmVhZC1vbmx5IC0tY3B1cyAxIC0tbWVtb3J5IDEyOG1gLCBwcml2YXRlIHJlc3RvcmVkIHZvbHVtZSBtb3VudGVkIGF0IGAvcmVzdG9yZWAsIGFuZCAqKm5vIHJ1bnRpbWUgY29uZmlnL2NyZWRlbnRpYWwvdG9rZW4gbW91bnRzKiouIEZpcnN0IG92ZXJyaWRlIGVudHJ5cG9pbnQgdG8gYHB5dGhvbmAsIGFyZ3VtZW50cyBgLSAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgLCBzdHJlYW1pbmcgb25seSB0aGUgdmVyaWZpZWQgYXR0YWNoZWQgY2hlY2tlciBvbiBzdGRpbi4gVGhlbiBvdmVycmlkZSBlbnRyeXBvaW50IHRvICoqYGluZm9ybWVkLWRlY2lzaW9uLWFkbWluYCoqLCBhcmd1bWVudHMgKipgaW5zcGVjdCAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGVgKiouIFRoaXMgZG9lcyBub3Qgc3RhcnQgYGluZm9ybWVkLWRlY2lzaW9uLWNvbnRhaW5lcmAsIHRoZSBIVFRQIHNlcnZpY2UsIGRpc3BhdGNoZXIgb3IgZGVsaXZlcnkgd29ya2Vycy4gQ29tcGFyZSB0aGUgYWRtaW4ncyBzY2hlbWEvbGlmZWN5Y2xlL291dGJveC9zdWJtaXNzaW9uIGNvdW50ZXJzIHRvIHRoZSBmcm96ZW4gcHJlLW9wZW4gc25hcHNob3QgcmVwb3J0OyBpbnRlZ3JpdHkgYW5kIG1pZ3JhdGlvbi1mcmVlIHByZS1vcGVuIHByb29mIGNvbWUgZnJvbSB0aGUgc3RkbGliIGNoZWNrZXIsIG5vdCBhZG1pbiBvdXRwdXQgYWxvbmUuCgpMaXZlIHJlYWRzIGFuZCBvbmxpbmUgc25hcHNob3RzIG1heSBsZWdpdGltYXRlbHkgZGlmZmVyIGJlY2F1c2UgcmV2aWV3cywgaW50YWtlIGFuZCBkZWxpdmVyeSBjYW4gY29tbWl0IGNvbmN1cnJlbnRseS4gRXhhY3QgY291bnRlciBlcXVhbGl0eSBpcyByZXF1aXJlZCBiZXR3ZWVuIHRoZSBmcm96ZW4gc2VsZWN0ZWQgc25hcHNob3QgYW5kIGl0cyBvZmZsaW5lIHJlc3RvcmVkIGNsb25lOyBpdCBpcyAqKm5vdCoqIHJlcXVpcmVkIGJldHdlZW4gYSBydW5uaW5nIHBvc3QtY3V0b3Zlci9yb2xsYmFjayBkYXRhYmFzZSBhbmQgYW4gZWFybGllciBzbmFwc2hvdC4gTGl2ZSBjb3VudCBjaGFuZ2VzIG11c3QgYmUgYWNjb3VudGVkIGZvciBhcyBsZWdpdGltYXRlIGNvbW1pdHRlZCByZWNvcmRzL3N0YXRlIHRyYW5zaXRpb25zOyBwcmVzZXJ2ZSBhbGwgY3VycmVudCBhbmQgdW5jZXJ0YWluIGVudHJpZXMuIERvIG5vdCBkaXNjYXJkIG5ldyBjb21taXRzIG9yIHJlc3RvcmUgdGhlIG9sZCBzbmFwc2hvdCB0byBmb3JjZSBlcXVhbGl0eS4gU2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sga2VlcHMgdGhlIGN1cnJlbnQgbGl2ZSBEQiwgZm9sbG93ZWQgYnkgcmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5IGFuZCBjb3VudC1vbmx5IGhlYWx0aCBjaGVja3M7IGFueSB1bmV4cGxhaW5lZCBldmlkZW5jZSBsb3NzIG9yIHJlcXVpcmVkIGRhdGEgcmVjb3Zlcnkgc3RvcHMgYW5kIHJlcXVpcmVzIGEgc2VwYXJhdGUgZm91bmRlciBkZWNpc2lvbi4KClRoZSBmcmVzaCBwcmVmbGlnaHQgYWxzbyBpbmRlcGVuZGVudGx5IHJlYWRzIHRoZSBhY3R1YWwgaW1tdXRhYmxlIG5vbnNlY3JldCBDb25maWdNYXAgYW5kIGJvdW5kIFBWQzogY29tcGFyZXMgc2VhbGVkIFVJRHMvZnVsbG1ldGFkYXRhL1BWQ3NwZWMrdm9sdW1lTmFtZSBhbmQgY2Fub25pY2FsIHJ1bnRpbWUgZGF0YSBjaGVja3N1bSwgcmV0dXJuaW5nIG5vIHJhdyBydW50aW1lIGRhdGEuIFNhbWUtbmFtZSBkZWxldGlvbi9yZWNyZWF0aW9uIG9yIGNvbnRlbnQvY3VzdG9keSBkcmlmdCBzdG9wcyBiZWZvcmUgYWRtaXNzaW9uLiBTZWNyZXQgdmFsdWVzIHJlbWFpbiBleGNsdWRlZC4gQm90aCBsb2NhbCBhbmQgcmVtb3RlIG9wdGltaXplZCBQeXRob24gaW50ZXJwcmV0ZXJzIGFyZSBleHBsaWNpdGx5IHJlZnVzZWQgYmVmb3JlIGFzc2VydGlvbi1iYXNlZCBnYXRlcy4KCiMjIEV4YWN0IHN1cGVydmlzZWQgbWVjaGFuaWNhbCBleGVjdXRpb24gcmVmaW5lbWVudAoKVGhlIGRpcmVjdGx5IGF0dGFjaGVkIGBleGVjdXRpb24tYnVuZGxlLmpzb25gIGNvbnRhaW5zIHRoZSBleGFjdCBoZWxwZXIgc291cmNlLCBwbGFuLCB0ZXN0cyBhbmQgUEVORElORyByZWNlaXB0IHRlbXBsYXRlLiBJdCByZXBsYWNlcyB0aGUgZGlyZWN0IHJhdyBzY2FuIGF0dGFjaG1lbnQgd2l0aGluIHRoZSB0d2VudHktZG9jdW1lbnQgbGltaXQ7IGBwdWJsaXNoZWQtdmVyaWZpY2F0aW9uLmpzb25gIHN0aWxsIGJpbmRzIHRoZSB1bmNoYW5nZWQgYWN0dWFsIHVuZmlsdGVyZWQgcmF3IHNjYW4sIHJhdyBTQk9NIGFuZCBiYXNlIHNjYW4gU0hBMjU2IHZhbHVlcywgcmV0YWluZWQgaW4gdGhlIG93bmVyIGV2aWRlbmNlIHBhY2thZ2UuIFRoZSBrbm93biBpbmhlcml0ZWQgZml4YWJsZSBNRURJVU0gcmVtYWlucyBleHBsaWNpdCwgd2l0aCBvd25lciBUMDUvcmlzayBmb2xsb3ctdGhyb3VnaC4gTmVpdGhlciBhcmNoaXZlIG5vciB0ZWNobmljYWwgYWdyZWVtZW50IHN1cHBsaWVzIGh1bWFuIGFwcHJvdmFsLgoKVGhlIHJldmlld2VkIHByb3RvY29sIGJhc2lzIGlzIG93bmVyIGNvbW1pdCBlMDM1OWJjYjZjZGZhZDlhYjNlODY4MDU0MTIxZmUwY2ViZWMyZDY4LCB3aXRoIHNvdXJjZSBmb2xsb3ctdGhyb3VnaDkyNjhjOWFjMGJiZWU1MDhmZTM1YzBiOTBkY2VmZWY0YzI0ZGEyZjUuIFRoZSBzdWJzZXF1ZW50IGV4YWN0IGFwcGxpZWQgaGVscGVyL3BhY2tldCBvd25lciBjb21taXQgbXVzdCBiZSBuYW1lZCBpbiB0aGUgZXh0ZXJuYWxseSB2ZXJpZmllZCBmb3VuZGVyIHJlY2VpcHQgYmVmb3JlIGV4ZWN1dGlvbi4gVmVyaWZ5IHRoZSBmb3VyIGNvbW1pdHRlZCBHaXQgYmxvYnMgKGFkbWlzc2lvbi5jYW5kaWRhdGUuanNvbiwgc2VydmljZS5jYW5kaWRhdGUuanNvbiwga3VzdG9taXphdGlvbi55YW1sLCByZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uKSBhZ2FpbnN0IGV4ZWN1dGlvbi1wbGFuLmpzb24gYXMgd2VsbCBhcyBjdXJyZW50IHdvcmt0cmVlL0hFQUQ7IHJlamVjdCBvdmVycmlkZXMvcGx1Z2lucy9tdWx0aXBsZSBBcHBsaWNhdGlvbiBzb3VyY2VzIGFuZCBhbnkgcHJlc2VudCBhdXRvbWF0ZWQgY29uZmlndXJhdGlvbiwgaW5jbHVkaW5nIGF1dG9tYXRlZDp7fS4KClJvb3QgZnJlc2hseSBhdXRoZW50aWNhdGVzIHRoZSBleGFjdCBjb25maXJtZWQgZm91bmRlciBwZXJzb24vcGxhdGZvcm0tcm9vdCBBQ0NFUFQgb2YgdGhpcyBzdGFibGUgbWVtby92ZXJzaW9uMSBhdCB0aGUgZml4ZWQgbmF0aXZlIEluZm9ybWVkIERlY2lzaW9uIG9yaWdpbiBiZWZvcmUgZWFjaCBwaGFzZSwgYW5kIHN1cHBsaWVzIHByb3RlY3RlZDA2MDAgcmVjZWlwdC9vdXRjb21lIGZpbGVzLiBUaGUgaGVscGVyIGNoZWNrcyB0aGVpciBleGFjdCByZWxhdGlvbiBhbmQgZnJlc2huZXNzMTIwc2Vjb25kczsgdGhlc2UgZmlsZXMgYXJlIHN1cGVydmlzZWQgYm9va2tlZXBpbmcsIG5vdCBzaWduZWQgYXV0aGVudGljYXRlZCBncmFudHMsIGEgaHVtYW4tcHJvdmlkZXIgaW1wbGVtZW50YXRpb24sIG9yIGF1dG9ub21vdXMgYWdlbnQgYXV0aG9yaXR5LiBEbyBub3QgZGVyaXZlIHRoZW0gZnJvbSB0ZWNobmljYWwgcmV2aWV3cyBvciBjYWxsZXIgYXNzZXJ0aW9ucy4KCkZpeGVkIG9yZGVyOiBkcmlsbC1iYWNrdXAg4oaSIGRyaWxsLWNvcHkg4oaSIG9mZmxpbmUtdmVyaWZ5IOKGkiBjbGVhbnVwLW9mZmxpbmUg4oaSIGN1dG92ZXItYmFja3VwIOKGkiBjdXRvdmVyLWNvcHkg4oaSIHJlbGVhc2Ug4oaSIHZlcmlmeS4gQSBzZXBhcmF0ZSByZWNvcmRlZCByZWxlYXNlIGF0dGVtcHQgcGVybWl0cyByb2xsYmFjayDihpIgcm9sbGJhY2stdmVyaWZ5LiBFdmVyeSBwaGFzZSBmc3luY3MgYW4gYXR0ZW1wdCBub25jZS9SVU5OSU5HIGpvdXJuYWwgYmVmb3JlIGVmZmVjdHMuIEZhaWx1cmUvaW50ZXJydXB0aW9uL2FtYmlndW91cyBhY3R1YXRpb24gc3RheXMgVU5DRVJUQUlOIGFuZCB0aGUgc2FtZSBwaGFzZSBjYW5ub3QgYmUgcmV0cmllZC4gTm8gaW1wcm92aXNlZCBhZGFwdGVyIG9yIHdob2xlLUFwcGxpY2F0aW9uIHN5bmMgaXMgcGVybWl0dGVkLgoKVGhlIE5FVyBub25jZS1sYWJlbGxlZCBsb2NhbCB2b2x1bWUgcmVxdWlyZXMgb25lIGV4cGxpY2l0IGlzb2xhdGVkIGluaXRpYWxpemVyIGFzIFVJRDA6MCB3aXRoIG9ubHkgQ0FQX0NIT1dOLCBleGFjdDc2M2MgaW1hZ2UsIC0tbmV0d29yayBub25lIC0tcmVhZC1vbmx5IC0tY3B1cyAxIC0tbWVtb3J5IDEyOG0gLS1jYXAtZHJvcCBBTEwgLS1jYXAtYWRkIENIT1dOIC0tc2VjdXJpdHktb3B0IG5vLW5ldy1wcml2aWxlZ2VzLiBJdHMgb25seSBtb3VudCBpcyB0aGF0IG5ldyBuYW1lZCB2b2x1bWUgYXQgL3Jlc3RvcmU7IG5vIGhvc3QgbW91bnQsIG5hdGl2ZSBQVkMsIHJ1bnRpbWUgY29uZmlnIG9yIHRva2VuIG1vdW50LiBQcm90ZWN0ZWQgc25hcHNob3Qgc3RkaW4gZ29lcyBvbmx5IHRvIGEgdW5pcXVlMDYwMCBtYWluIGZpbGUgd2l0aCBleGFjdCBkaWdlc3QsIGFuZCBkaXJlY3RvcnkvZmlsZSBjdXN0b2R5IGlzIHNldDA3MDAvMDYwMCBVSUQvR0lEMTAwMDEuIFRoZW4gYWxsIHByZS1vcGVuLCBhZG1pbiBhbmQgcG9zdC1hZG1pbiBjaGVja3MgcnVuIFVJRDEwMDAxOjEwMDAxLCBjYXBhYmlsaXRpZXMgZHJvcHBlZCwgbmV0d29ya25vbmUuIFRoZSBzZWNvbmQgc3RkbGliIHJlYWRvbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IHByb29mIGFmdGVyIGFkbWluIG11c3QgZXhhY3RseSBlcXVhbCB0aGUgZnJvemVuIHNuYXBzaG90IHByb29mOyBpbmRlcGVuZGVudGx5IHJlY2hlY2sgdGhlIHJldGFpbmVkIG9yaWdpbmFsIHByb3RlY3RlZCBzbmFwc2hvdCBTSEEuIE5vIHNlcnZpY2Ugc3RhcnR1cCBvY2N1cnMuCgpSb2xsYmFjayBkaXNwYXRjaCBtdXN0IGJlIGF2YWlsYWJsZSBpZiB0aGUgY2FuZGlkYXRlIGlzIHVucmVhZHkgb3IgY2Fubm90IHN0YXJ0OiBpdCBjaGVja3Mgc2VhbGVkIERlcGxveW1lbnQvQ00vUFZDIGN1c3RvZHksIG9ubHkgcHJpb3IvY2FuZGlkYXRlIHNvdXJjZS9pbWFnZSBwYWlyLCBub2RlIGhlYWx0aC9oZWFkcm9vbSBhbmQgZnJlc2ggb2xkLWltYWdlIHNlcnZlciBhZG1pc3Npb24gcGx1cyBBcHBsaWNhdGlvbiBVSUQvcmVzb3VyY2VWZXJzaW9uL3NvdXJjZSBDQVMsIHdpdGggbm8gZmFpbGluZyBjYW5kaWRhdGUgUG9kL2V4ZWMvZGF0YWJhc2UgcHJlcmVxdWlzaXRlLiBEaXNwYXRjaCBhY2tub3dsZWRnbWVudCBpcyBub3QgcmVjb3ZlcmVkIGhlYWx0aC4gYHJvbGxiYWNrLXZlcmlmeWAgc2VwYXJhdGVseSByZXF1aXJlcyBvbGQgaW1hZ2UgUmVhZHkxLCBzdWNjZWVkZWQgZXhhY3QgRGVwbG95bWVudC1vbmx5L3BydW5lPWZhbHNlIG9wZXJhdGlvbiBhbmQgcmVhZG9ubHkgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnQgcHJvb2Ygb2YgdGhlIGxhdGVzdCByZXRhaW5lZCBsaXZlIGRhdGFiYXNlLiBObyBzbmFwc2hvdCByZXBsYWNlcyB0aGUgY3VycmVudCBkYXRhYmFzZS4KCioqRGVhZGxpbmUgcmVmaW5lbWVudDoqKiBhbGwgcGhhc2VzLCBpbmNsdWRpbmcgcm9sbGJhY2sgYW5kIHZlcmlmaWNhdGlvbiwgbXVzdCBiZWdpbiBiZWZvcmUyMDI2LTEwLTEyVDIzOjU5OjU5Wi4gVGhlIGVhcmxpZXIgYW1lbmRlZCBwYWNrZXQgZGVzY3JpYmVkIHVuc3RhcnRlZC1yZWxlYXNlIGV4cGlyeTsgdGhpcyBleGFjdCBoZWxwZXIgYWxzbyBib3VuZHMgcmVjb3ZlcnkvdmVyaWZpY2F0aW9uLiBTdGFydCBlYXJseSBlbm91Z2ggdG8gY29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIGFueSByZWNvdmVyeSB3aXRoaW4gdGhlIHdpbmRvdy4gSWYgZXhoYXVzdGVkLCBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uIHJhdGhlciB0aGFuIHNpbGVudGx5IGV4dGVuZCBhIGdyYW50LiBUaGlzIG1heSBkZWxheSByZWNvdmVyeSBhbmQgaXMgYW4gZXhwbGljaXQgb3BlcmF0aW9uYWwgcmlzay4gTm8gdGltZXIvY29udHJvbGxlciBhdXRvbWF0aWNhbGx5IHJvbGxzIGJhY2sgb3IgY2hhbmdlcyBzZXJ2aWNlIGF0IGV4cGlyeS4K" + "content_base64": "IyBWZXJzaW9uMiBwcm90ZWN0ZWQgZXhpc3Rpbmctc25hcHNob3QgcmVzY3VlIGFuZCBjb25kaXRpb25hbCBjb250aW51YXRpb24KClNhbWUgcHJvcG9zYWwgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEsIHRyaWFsIGluZmQtcHVycG9zZS0yMDI2MTAxMS1yMS4gT3JpZ2luYWwgdmVyc2lvbjEgZm91bmRlciBhY2NlcHRhbmNlIGFwcHJvdmVkIHNvdXJjZSBiYzY0OTRjZDFiMjkwNzgzZWYzYWVmMDc2M2JmMjhkMWRlYWJmNGIwLiBEcmlsbC1iYWNrdXAgY29tcGxldGVkOyBkcmlsbC1jb3B5IGZhaWxlZCBWYWx1ZUVycm9yIGJlZm9yZSBhbnkgbG9jYWxmaWxlLiBObyBpbWFnZSByb2xsb3V0IG9jY3VycmVkLiBUaGlzIGV4YWN0IGNoYW5nZWQgc291cmNlL3BsYW4vaGVscGVyIHJlcXVpcmVzIE5FVyBmb3VuZGVyIGFjY2VwdGFuY2Ugb2YgbWVtbyB2ZXJzaW9uMiBiZWZvcmUgcmVzY3VlL2NvbnRpbnVhdGlvbjsgcHJpb3IgYXBwcm92YWwgYW5kIHRlY2huaWNhbCByZXZpZXcgZG8gbm90IGFwcHJvdmUgaXQuCgojIyBGYWlsdXJlIGFuZCBuYXJyb3dseSBzZWxlY3RlZCByZXNjdWUKCk9yaWdpbmFsIHNuYXBzaG90IG1haW4xOTUzNzkyMGJ5dGVzIFNIQTg3NTZjZjgyNWRmOWU3YjViNzRiYjRhMDEwNmE1MDI3ZjVjZmYyYzU5ZmY0NWQ3YjQ4ZWVkODUyMmE3ZDMzZjMgaXMgdW5jaGFuZ2VkLiBSb290J3MgbWV0YWRhdGEtb25seSB2ZXJpZmljYXRpb24gc2hvd3MgV0FMMGJ5dGVzLCBTSE0zMjc2OGJ5dGVzLCBwcml2YXRlVUlEMTAwMDEvbW9kZTA2MDAvbmxpbmsxLCBhbmQgbm8gbG9jYWwgc25hcHNob3QuIFRoZSBvbGQgU1FMaXRlIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgZXhwbGljaXRseSBjbG9zZTsgaXRzIFdBTCByZWFkZXIgY2FuIGNyZWF0ZSBTSE0gaW5kZXhpbmcsIGFuZCB0aGUgbmV4dCBjb3B5IHJlamVjdGVkIHRoYXQgbm9uemVybyBpbmRleC4gUGxhdGZvcm0gaW5kZXBlbmRlbnRseSByZXByb2R1Y2VkIHRoaXMgb24gc3ludGhldGljIGRhdGEuIE5vIG5hdGl2ZSBEQiB3YXMgb3BlbmVkIHRvIGRpYWdub3NlIHRoZSBzaWRlY2FyIG1ldGFkYXRhLCBhbmQgbm8gbmF0aXZlIHNpZGVjYXIgaXMgZGVsZXRlZC9jaGVja3BvaW50ZWQuCgpSZXVzZSB0aGlzIGV4YWN0IGluZGVwZW5kZW50bHkgaGFzaC1ib3VuZCBmcm96ZW4gbWFpbiBzbmFwc2hvdCByYXRoZXIgdGhhbiBtYWtlIGFub3RoZXIgZHJpbGwgYmFja3VwLiBUaGUgYmFja3VwYWRtaW4gZXhpdGVkIGFmdGVyIGNyZWF0aW5nIHRoZSB1bmlxdWVseSBvd25lZCBwcml2YXRlIHNuYXBzaG90LiBPcmlnaW5hbCBzdWJzZXF1ZW50IHNuYXBzaG90IGFjY2VzcyB3YXMgcmVhZG9ubHk7IGFjdHVhbCBzZXJ2aWNlIERCIGlzIHRoZSBkaXN0aW5jdCAvZGF0YS9wcml2YXRlL3Jldmlldy5zcWxpdGUuIE9yaWdpbmFsIGpvdXJuYWwgaGFzIG9ubHkgQ09NUExFVEUgZHJpbGwtYmFja3VwIGQ2MzE4MmE3LWUxYTUtNGU4ZS1hNWYxLTJiZjMzMzNjZjE1MyBhbmQgVU5DRVJUQUlOIGRyaWxsLWNvcHkzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2MuIEl0cyBleGFjdCBTSEEgZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMSwgb3JpZ2luYWwgc291cmNlL21lbW8vcGxhbiBpZGVudGl0eSBhbmQgb3V0Y29tZXMgYXJlIHZlcmlmaWVkIGJlZm9yZS9hZnRlciBldmVyeSBuZXcgcGhhc2UuIE5vIG90aGVyIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0IGlzIGFsbG93ZWQuCgpUaGUgZXhwbGljaXRseSBuYW1lZCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBjcmVhdGVzIGEgc2VwYXJhdGUgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24vbG9jayBpbiBleGlzdGluZyBwcm90ZWN0ZWQgaWdub3JlZCBjdXN0b2R5OyBpdCBoYXNoLWxpbmtzIG9yaWdpbmFsIGF0dGVtcHRzIGFuZCBiYWNrdXByZXN1bHQgYW5kIG5ldmVyIHJld3JpdGVzL3N5bnRoZXNpemVzIHRoZSBvbGQgZmFpbGVkIHBoYXNlLiBBbnkgYXR0ZW1wdGVkIHJlc2N1ZSByZXN1bHQsIGNyYXNoIG9yIGFtYmlndW91cyBvdXRwdXQgaXMgZHVyYWJsZSBhbmQgc2FtZS1waGFzZSByZXRyeSBpcyByZWZ1c2VkLiBCZWZvcmUgcmVzY3VlOiBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgYW5kIGV4aXN0aW5nIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50OyBuYXRpdmUgb3JpZ2luYWxQb2RVSUQvY3VycmVudG9sZGltYWdlN2Y1L0FyZ283ZGIvc2VhbGVkRGVwbG95bWVudC9DTS9QVkMgbWF0Y2guIFRoZSBmaXhlZCBpbW11dGFibGUgc25hcHNob3QgcmVhZGVyIGNoZWNrcyByZWNvcmRlZCBkaWdlc3QvcHJpdmF0ZSBpZGVudGl0eS9ubyBXQUxmcmFtZXMgYmVmb3JlIGFuZCBhZnRlciBzY2hlbWE1L2ludGVncml0eS9jb3VudCB2YWxpZGF0aW9uLCByZXRhaW5pbmcgdW5jaGFuZ2VkIFNITS4gTm9uemVybyBXQUwgb3IgYW55IGlkZW50aXR5L2hhc2ggZHJpZnQgc3RvcHMgcmVzY3VlLiBTbmFwc2hvdCBiaW5hcnlzdGRvdXQgZmxvd3Mgb25seSB0byBhIG5ldzA2MDBwcml2YXRlIGZpbGUsIHdpdGggYm91bmRlZCBzaXplL2hhc2ggYW5kIHJlcGVhdCBzb3VyY2UgcHJvb2YuIEl0IG5ldmVyIHJlYWNoZXMgY2hhdC9sb2cvR2l0L1N0YXRlSHViLgoKIyMgTGl2ZS1XQUwgYW5kIGRhdGEgY29tcGF0aWJpbGl0eSBib3VuZGFyaWVzCgpMaXZlIHNvdXJjZSBhbmQgd3JpdGFibGUgb2ZmbGluZSBwcmUvcG9zdC1hZG1pbiByZWFkcyBNVVNUIHN0YXkgbW9kZT1yby9xdWVyeV9vbmx5IGFuZCBleHBsaWNpdGx5IGNsb3NlIFNRTGl0ZSBjb25uZWN0aW9ucy4gaW1tdXRhYmxlPTEgaWdub3JlcyBXQUwgYW5kIHdvdWxkIGxvc2UgY29tbWl0dGVkIGxpdmUgcm93czsgaXQgaXMgcmVzdHJpY3RlZCB0byB0aGUgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbmV2ZXIgdGhlIGxpdmVEQiBvciB3cml0YWJsZWNsb25lLiBCZWZvcmUgQU5ZIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5IFN0b3JlL2FkbWluIG9wZW4sIHJlcXVpcmUgc3RkbGliIHJlYWRvbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50czsgcmVmdXNlIG9sZHNjaGVtYXMgYmVmb3JlIGF1dG9tYXRpYyBtaWdyYXRpb24uIEZyb3plbiBzbmFwc2hvdC9jbG9uZSBjb3VudCBlcXVhbGl0eSBpcyBleGFjdDsgY3VycmVudGxpdmUgY291bnRlciBjaGFuZ2VzIG1heSByZWZsZWN0IGNvbmN1cnJlbnQgbGVnaXRpbWF0ZSBjb21taXRzIGFuZCBhcmUgcmV0YWluZWQuCgpPbmx5IGFmdGVyIENPTVBMRVRFIG5hbWVkIHJlc2N1ZSBkb2VzIG9mZmxpbmUtdmVyaWZ5IGNvbnN1bWUgaXRzIHJlc3VsdCB2aWEgZXhwbGljaXQgbWFwcGluZywgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGlzb2xhdGVkIGRpc3Bvc2FibGV2b2x1bWUgaW5mZC1wdXJwb3NlLXIxLXJlc3RvcmUtMjAyNjEwMTEgbXVzdCBiZSBhYnNlbnQvbmV3IG5vbmNlLWJvdW5kLiBPbmUgZXhhY3Q3NjNjIFVJRDAvQ0FQX0NIT1dOLW9ubHkgaW5pdGlhbGl6ZXIgcmVjZWl2ZXMgc25hcHNob3RzdGRpbiBpbnRvIHRoYXQgTkVXdm9sdW1lLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pLCBubyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50cy4gSXQgc2V0cyBmb2xkZXIwNzAwL2ZpbGUwNjAwVUlEMTAwMDEsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHByZS1vcGVuIHJlYWRvbmx5LCAtLWVudHJ5cG9pbnQgaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4gaW5zcGVjdCAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGUgYW5kIHBvc3QtYWRtaW4gcmVhZG9ubHkgZnVsbHByb29mOyBvcmlnaW5hbCBwcm90ZWN0ZWQgU0hBIG11c3QgcmVtYWluIHVuY2hhbmdlZC4gTm8gc2VydmljZWVudHJ5cG9pbnQgc3RhcnRzLiBDbGVhbnVwIG9ubHkgdGhpcyBkaXNwb3NhYmxlIHZvbHVtZSwgcmV0YWluaW5nIG9yaWdpbmFsIG5hdGl2ZS9vZmZjbHVzdGVyIHNuYXBzaG90cy9zaWRlY2Fycy4KCiMjIENvbmRpdGlvbmFsIHJlbWFpbmluZyBwaGFzZXMgYW5kIHJlbGVhc2UvcmVjb3ZlcnkKCk5ld2pvdXJuYWwgZml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnkuIGN1dG92ZXItYmFja3VwIHVzZXMgZGlzdGluY3QgbmV3Y3V0b3Zlci5zcWxpdGUgaW4gb3JpZ2luYWxwcml2YXRlY2FzZSBkaXJlY3RvcnksIGFmdGVyIHJlYWRvbmx5IGxpdmUgc2NoZW1hNS9jYXBhY2l0eSBnYXRlcywgU1FMaXRlYmFja3VwQVBJL2FkbWluIGNvbXBsZXRpb24sIGNsb3NlZC1tYWluIGltbXV0YWJsZSBwcm9vZjsgZG8gbm90IG92ZXJ3cml0ZSBvcmlnaW5hbHMgb3IgcmV0cnlmYWlsZWRwYXRocy4gVmVyc2lvbjIgYWNjZXB0YW5jZSBjb25kaXRpb25hbGx5IGFwcHJvdmVzIHRoZXNlIGV4YWN0IHVuY2hhbmdlZCByZW1haW5pbmcgb3BlcmF0aW9ucyBvbmx5IGFmdGVyIHJlc2N1ZStkcmlsbGdhdGVzLiBBbGwgZm91ciBjb21taXR0ZWQgS3VzdG9taXplIEdpdCBibG9icy9jdXJyZW50SEVBRCwgZXhhY3QgaGVscGVyL2Nhc2UgaGFzaGVzLCBDTS9QVkMvRGVwbG95bWVudCBzZWFscyBhbmQgbWFudWFsQXBwbGljYXRpb24obm8gYXV0b21hdGVke30gb3Igc291cmNlb3ZlcnJpZGUpIG11c3QgbWF0Y2guCgpSZWxlYXNlIHJldGFpbnMgZXhpc3RpbmcgcmVwbGljYTEvUmVjcmVhdGUvY29uZmlnNmMvc2NoZW1hNS9QVkMvY3JlZGVudGlhbHMvcG9saWNpZXM6IHNvdXJjZXBpbiBBcHBsaWNhdGlvbi5vcGVyYXRpb24gc2VydmVyZHJ5cnVuL1VJRCtyZXNvdXJjZVZlcnNpb24rc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5IGltYWdlNzYzYywgcHJ1bmU9ZmFsc2UuIE5vIHdob2xlLWFwcCBzeW5jL2Fkb3B0aW9uLiBWZXJpZnkgcmVxdWlyZXMgc3VjY2VlZGVkIGV4YWN0c2NvcGUvY29udHJvbGxlcmdlbmVyYXRpb24vUmVhZHkxLCBpbnN0YWxsZWRwb2xpY3loYXNoL21vZGVVSUQvMTBzeW50aGV0aWNwdXJwb3NldmFyaWFudHMrYm91bmRlZGhlYWx0aCwgc2FtZSBjdXJyZW50bGl2ZURCIHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50cy4gVGhvc2UgaW5zdGFsbGVkY2hlY2tzIHJlcG9ydCBuYXRpdmVfcHJvdmlkZXI9ZmFsc2U7IGFjdHVhbHByb3ZpZGVyL1BEUGF1dGhvcml0eSBldmlkZW5jZSByZW1haW5zIGEgc2VwYXJhdGUgVDA0Z2F0ZS4KClJvbGxiYWNrIGFmdGVyIHJlY29yZGVkIG5ld3JlbGVhc2UgYXR0ZW1wdCBwaW5zIHByaW9yN2RiLzdmNSBhbmQgcmV0YWlucyBsYXRlc3RzY2hlbWE1REIsIHdpdGhvdXQgcmVxdWlyaW5nIFJlYWR5IGZhaWxpbmdjYW5kaWRhdGUgb3IgY2FuZGlkYXRlREJleGVjLiBTZXBhcmF0ZSByb2xsYmFjay12ZXJpZnkgcHJvdmVzIG9sZGltYWdlUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9yZWFkb25seXNjaGVtYTUgY3VycmVudERCIGludGVncml0eS4gTmV2ZXIgcmVzdG9yZSBhbiBvbGRlciBzbmFwc2hvdCBvdmVyIHBvc3RjdXRvdmVycmVjb3Jkcy4gQW55IGRhdGEgcmVjb3ZlcnkgYmV5b25kIHRoaXMgc2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sgbmVlZHMgYW5vdGhlciBkZWNpc2lvbi4KCkFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZSwgdmVyaWZpY2F0aW9uIGFuZCByZWNvdmVyeSBtdXN0IGJlZ2luIGJlZm9yZTIwMjYtMTAtMTJUMjM6NTk6NTlaLiBTdGFydCBlYXJseSBlbm91Z2g7IGlmIGV4cGlyZWQgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbiwgd2hpY2ggbWF5IGRlbGF5IHJlY292ZXJ5LiBObyBhdXRvbWF0aWMgdGltZXIvY29udHJvbGxlci9leHRlbnNpb24uIFJvb3QgZnJlc2hseSBhdXRoZW50aWNhdGVzIGV4YWN0IGNvbmZpcm1lZCBwbGF0Zm9ybS1yb290IHBlcnNvbiBBQ0NFUFQgbWVtbyB2ZXJzaW9uMiBhdCBmaXhlZG5hdGl2ZW9yaWdpbiBiZWZvcmUgZXZlcnkgcGhhc2U7IHByb3RlY3RlZHJlY2VpcHRyZWxhdGlvbi9mcmVzaG5lc3MxMjBzZWMgaXMgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3QgYSBzaWduZWQvYXV0b25vbW91cyBncmFudC4KCkltYWdlNzYzYy9wb2xpY3k5ZDdjL2Jhc2U3ZjUgYW5kIGFjdHVhbHVuZmlsdGVyZWRzY2FuMEhJR0gvQ1JJVElDQUwvMWZpeGFibGVNRURJVU16bGliIHJlbWFpbiB1bmNoYW5nZWQsIG93bmVyIElORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxL1QwNSBkdWVPY3QxOC4gVGhlIGV4YWN0YnVuZGxlIGRpcmVjdGx5IGJpbmRzIGhlbHBlci9wbGFuL3Rlc3RzIHBsdXMgb3JpZ2luYWwgY291bnQtb25seWJhY2t1cC9mYWlsdXJlL2FuY2hvci4gRXhpc3RpbmdwdWJsaXNoZWRyZWNlaXB0IHN0aWxsIGJpbmRzIHVuY2hhbmdlZCByYXdzY2FuL1NCT00vYmFzZSBzY2FuOyBubyBzdXBwcmVzc2lvbi4gUHJlc2VydmUgb3JpZ2luYWxhcHByb3ZlZDIwZG9jcGFja2V0L2hlbHBlcnMvaGlzdG9yeSBpbiBpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkLiBObyB2ZXJzaW9uMiBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4uIEVVUjAgcmVjdXJyaW5naW5mcmFzdHJ1Y3R1cmU7IHByaXZhdGUgYm91bmRlZHN0b3JhZ2UvYXR0ZW5kZWR0aW1lIHVucHJpY2VkLCBubyBuZXdkcmlsbGJhY2t1cCBvciBhdXRvbm9teWdyYW50LgoKTmF0aXZlIHNvdXJjZSBwdWJsaWNhdGlvbiB1c2VzIGV4YWN0IHJldmlzaW9uLWNvbW1hbmQuanNvbiB2aWEgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMsIGV4cGVjdGVkX3ZlcnNpb24xLCBvbmx5IGFmdGVyIGZyZXNoIHVuYm91bmQtc291cmNlIHJlYWRiYWNrLiBObyB2ZXJzaW9uMiBpbnRha2UvcmVnaXN0ZXIuIFB1Ymxpc2gvcmV2aWV3IHNvdXJjZXZlcnNpb24yOyBuZXcgaHVtYW4gcmV2aWV3LUlEIGlzIG93bnZlcnNpb24xLCBzbyBpdHMgY29uZmlybWVkIG5lc3RlZCBkaXNwb3NpdGlvbiBtZW1vX3ZlcnNpb24xIGlzIGNvcnJlY3QuIFJvb3QgYWN0dWFsIG91dGNvbWVzIHF1ZXJ5IG11c3QgbmFtZSBTT1VSQ0UgdmVyc2lvbjIgYW5kIGV4YWN0IG5ld3Jldmlld0lEOyBvcmlnaW5hbCByZXZpZXcvYXBwcm92YWwgY2Fubm90IGJlIHJldXNlZC4K" }, { "digest": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101", @@ -235,9 +264,9 @@ "content_base64": "IiIiUmVhZC1vbmx5IHJlZnJlc2g7IGV4YWN0IG9yaWdpbmFsIGNhcHR1cmUgcmVtYWlucyBpbW11dGFibGU7IG5ldmVyIGV4ZWN1dGUgY3V0b3Zlci4iIiIKaW1wb3J0IGFyZ3BhcnNlLGhhc2hsaWIsanNvbixzdWJwcm9jZXNzLHN5cwpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaWYgc3lzLmZsYWdzLm9wdGltaXplOgogcmFpc2UgU3lzdGVtRXhpdCgib3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQgYmVmb3JlIHNvdXJjZS90cmFuc3BvcnQgZXhlY3V0aW9uIikKUk9PVD1QYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50CnA9YXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKTtwLmFkZF9hcmd1bWVudCgnLS1yZWNlaXB0LW91dHB1dCcsdHlwZT1QYXRoLHJlcXVpcmVkPVRydWUpO3AuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yb290Jyx0eXBlPVBhdGgsZGVmYXVsdD1QYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24nKSk7YT1wLnBhcnNlX2FyZ3MoKQpvdXQ9YS5yZWNlaXB0X291dHB1dC5yZXNvbHZlKCkKaWYgbm90IGEucmVjZWlwdF9vdXRwdXQuaXNfYWJzb2x1dGUoKSBvciBvdXQ9PVJPT1Qgb3IgUk9PVCBpbiBvdXQucGFyZW50cyBvciBvdXQ9PWEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIG9yIGEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIGluIG91dC5wYXJlbnRzIG9yIG91dC5leGlzdHMoKToKIHJhaXNlIFN5c3RlbUV4aXQoJ3VuaXF1ZSBleGVjdXRpb24gcmVjZWlwdCBtdXN0IGJlIG91dHNpZGUgdGhlIHNlYWxlZCBwYWNrZXQnKQppbnB1dHM9anNvbi5sb2FkcygoUk9PVC8ncHJlZmxpZ2h0LWlucHV0cy5qc29uJykucmVhZF90ZXh0KCkpCmZvciByZWxhdGl2ZSxkaWdlc3QgaW4gaW5wdXRzWydwYWNrZXRfZmlsZXMnXS5pdGVtcygpOgogcGF0aD1ST09UL3JlbGF0aXZlCiBpZiBwYXRoLmlzX3N5bWxpbmsoKSBvciBoYXNobGliLnNoYTI1NihwYXRoLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCkhPWRpZ2VzdDpyYWlzZSBTeXN0ZW1FeGl0KCdzZWFsZWQgaGVscGVyL2lucHV0IGJ5dGVzIGNoYW5nZWQnKQpmb3IgcmVsYXRpdmUsZGlnZXN0IGluIGlucHV0c1snb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKToKIHBhdGg9YS5zb3VyY2Vfcm9vdC9yZWxhdGl2ZQogaWYgcGF0aC5pc19zeW1saW5rKCkgb3IgaGFzaGxpYi5zaGEyNTYocGF0aC5yZWFkX2J5dGVzKCkpLmhleGRpZ2VzdCgpIT1kaWdlc3Q6cmFpc2UgU3lzdGVtRXhpdCgnb3duZXIgc291cmNlIGJ5dGVzIGNoYW5nZWQnKQpmcm9tIGNoYW5nZV9ndWFyZCBpbXBvcnQgdHJhbnNwb3J0X3Jlc3VsdApwcm9ncmFtPSdpbXBvcnQgc3VicHJvY2Vzcyxqc29uLGhhc2hsaWIsZGF0ZXRpbWUsc3lzLGNvcHkscmVcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoIm9wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkIilcbmNhbmRpZGF0ZT1qc29uLmxvYWRzKENBTkRJREFURV9MSVRFUkFMKVxuc2VhbGVkX2RlcGVuZGVuY2llcz1qc29uLmxvYWRzKERFUEVOREVOQ0lFU19MSVRFUkFMKVxuc2VhbGVkX2Jhc2VsaW5lPWpzb24ubG9hZHMoU0VBTEVEX0xJVEVSQUwpXG5leGVjKEdVQVJEX0xJVEVSQUwpXG5kZWYgcnVuKGFyZ3MsZGF0YT1Ob25lKTpcbiBwPXN1YnByb2Nlc3MucnVuKGFyZ3MsaW5wdXQ9ZGF0YSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSlcbiBpZiBwLnJldHVybmNvZGU6IHJhaXNlIFZhbHVlRXJyb3IoXCdyZWFkLW9ubHkgY29tbWFuZCBmYWlsZWQ6IFwnK2FyZ3NbMV0rXCcgXCcrYXJnc1syXSlcbiByZXR1cm4gcC5zdGRvdXRcbmxpdmU9anNvbi5sb2FkcyhydW4oW1wna3ViZWN0bFwnLFwnZ2V0XCcsXCdkZXBsb3ltZW50XCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2luZm9ybWVkLWRlY2lzaW9uXCcsXCctb1wnLFwnanNvblwnXSkpXG5jbT1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2NvbmZpZ21hcFwnLFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcJyxcJy1uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW9cJyxcJ2pzb25cJ10pKVxucHZjPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwncHZjXCcsXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXCcsXCctblwnLFwnaW5mb3JtZWQtZGVjaXNpb25cJyxcJy1vXCcsXCdqc29uXCddKSlcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsc2VhbGVkX2RlcGVuZGVuY2llcylcbmNoZWNrX2N1cnJlbnQobGl2ZSxzZWFsZWRfYmFzZWxpbmUpXG5zcGVjPWxpdmVbXCdzcGVjXCddOyBjcz1zcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wnY29udGFpbmVyc1wnXTthc3NlcnQgbGVuKGNzKT09MSBhbmQgY3NbMF1bXCduYW1lXCddPT1cJ2luZm9ybWVkLWRlY2lzaW9uXCdcbmV4cGVjdGVkX2Vudj17XCdJTkZEX0tFWUNBUEVfSVNTVUVSXCc6XCdodHRwczovL2tjLmNvdWxvbWIuc29jaWFsXCcsXCdJTkZEX0NPTlRBSU5FUl9DT05GSUdcJzpcJy9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvblwnfVxuYXNzZXJ0IGNzWzBdLmdldChcJ2VudlwnKT09W3tcJ25hbWVcJzpcJ0lORkRfS0VZQ0FQRV9JU1NVRVJcJyxcJ3ZhbHVlXCc6ZXhwZWN0ZWRfZW52W1wnSU5GRF9LRVlDQVBFX0lTU1VFUlwnXX0se1wnbmFtZVwnOlwnSU5GRF9DT05UQUlORVJfQ09ORklHXCcsXCd2YWx1ZVwnOmV4cGVjdGVkX2VudltcJ0lORkRfQ09OVEFJTkVSX0NPTkZJR1wnXX1dXG5hc3NlcnQgY3NbMF1bXCdpbWFnZVwnXT09XCdmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcJ1xuYXNzZXJ0IHNwZWNbXCdyZXBsaWNhc1wnXT09MSBhbmQgc3BlY1tcJ3N0cmF0ZWd5XCddPT17XCd0eXBlXCc6XCdSZWNyZWF0ZVwnfVxuYXNzZXJ0IG5leHQodiBmb3IgdiBpbiBzcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wndm9sdW1lc1wnXSBpZiB2W1wnbmFtZVwnXT09XCdjb25maWd1cmF0aW9uXCcpW1wnY29uZmlnTWFwXCddW1wnbmFtZVwnXT09XCdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MVwnXG5hc3NlcnQgbGl2ZVtcJ3N0YXR1c1wnXS5nZXQoXCdyZWFkeVJlcGxpY2FzXCcpPT0xIGFuZCBsaXZlW1wnc3RhdHVzXCddLmdldChcJ3VwZGF0ZWRSZXBsaWNhc1wnKT09MVxuc2VhbGVkPXtcJ2FwaVZlcnNpb25cJzpsaXZlW1wnYXBpVmVyc2lvblwnXSxcJ2tpbmRcJzpsaXZlW1wna2luZFwnXSxcJ21ldGFkYXRhXCc6e2s6Y29weS5kZWVwY29weSh2KSBmb3Igayx2IGluIGxpdmVbXCdtZXRhZGF0YVwnXS5pdGVtcygpIGlmIGsgbm90IGluIChcJ3Jlc291cmNlVmVyc2lvblwnLFwnZ2VuZXJhdGlvblwnLFwnY3JlYXRpb25UaW1lc3RhbXBcJyxcJ21hbmFnZWRGaWVsZHNcJyl9LFwnc3BlY1wnOmNvcHkuZGVlcGNvcHkoc3BlYyl9XG5mb3Iga2V5IGluIChcJ2t1YmVjdGwua3ViZXJuZXRlcy5pby9sYXN0LWFwcGxpZWQtY29uZmlndXJhdGlvblwnLFwnZGVwbG95bWVudC5rdWJlcm5ldGVzLmlvL3JldmlzaW9uXCcpOnNlYWxlZFtcJ21ldGFkYXRhXCddLmdldChcJ2Fubm90YXRpb25zXCcse30pLnBvcChrZXksTm9uZSlcbmFkbWl0dGVkPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2FwcGx5XCcsXCctLWRyeS1ydW49c2VydmVyXCcsXCctZlwnLFwnLVwnLFwnLW9cJyxcJ2pzb25cJ10sanNvbi5kdW1wcyhjYW5kaWRhdGUpKSlcbmNoZWNrX2FkbWl0dGVkKGFkbWl0dGVkLHNlYWxlZF9iYXNlbGluZSlcbmFwcD1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2FwcGxpY2F0aW9uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2FyZ29jZFwnLFwnLW9cJyxcJ2pzb25cJ10pKVxuYXNzZXJ0IGFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCdwYXRoXCddPT1cJ2RlcGxveS9saWZlY3ljbGVcJyBhbmQgbm90IGFwcFtcJ3NwZWNcJ10uZ2V0KFwnc3luY1BvbGljeVwnLHt9KS5nZXQoXCdhdXRvbWF0ZWRcJylcbmFyZ289e1wndWlkXCc6YXBwW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdyZXBvVVJMXCc6YXBwW1wnc3BlY1wnXVtcJ3NvdXJjZVwnXVtcJ3JlcG9VUkxcJ10sXCd0YXJnZXRSZXZpc2lvblwnOmFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCd0YXJnZXRSZXZpc2lvblwnXSxcJ3BhdGhcJzphcHBbXCdzcGVjXCddW1wnc291cmNlXCddW1wncGF0aFwnXSxcJ2Rlc3RpbmF0aW9uXCc6YXBwW1wnc3BlY1wnXVtcJ2Rlc3RpbmF0aW9uXCddLFwnYXV0b21hdGVkXCc6RmFsc2UsXCdzeW5jXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdzeW5jXCcpLFwnaGVhbHRoXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdoZWFsdGhcJyl9XG5leHBlY3RlZF9hcmdvPWpzb24ubG9hZHMoQVJHT19MSVRFUkFMKVxuZm9yIGtleSBpbiAoXCd1aWRcJyxcJ3JlcG9VUkxcJyxcJ3RhcmdldFJldmlzaW9uXCcsXCdwYXRoXCcsXCdkZXN0aW5hdGlvblwnLFwnYXV0b21hdGVkXCcpOlxuIGFzc2VydCBhcmdvW2tleV09PWV4cGVjdGVkX2FyZ29ba2V5XVxuYXNzZXJ0IGFyZ29bXCdoZWFsdGhcJ11bXCdzdGF0dXNcJ109PVwnSGVhbHRoeVwnXG5kaWZmPXN1YnByb2Nlc3MucnVuKFtcJ2t1YmVjdGxcJyxcJ2RpZmZcJyxcJy1mXCcsXCctXCddLGlucHV0PWpzb24uZHVtcHMoY2FuZGlkYXRlKSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSk7YXNzZXJ0IGRpZmYucmV0dXJuY29kZSBpbiAoMCwxKVxuIyBEaWZmIGNhbiBjb250YWluIG9ubHkgbm9uc2VjcmV0IERlcGxveW1lbnQgcmVmZXJlbmNlczsgcHJlc2VydmUgZGlnZXN0IHJhdGhlciB0aGFuIHJhdyBzdGRvdXQuXG5ub2RlPXJ1bihbXCdrdWJlY3RsXCcsXCdkZXNjcmliZVwnLFwnbm9kZVwnXSk7YWxsb2NhdGVkPXJlLnNlYXJjaChyXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOi4qP0NQVSBSZXF1ZXN0c3xBbGxvY2F0ZWQgcmVzb3VyY2VzOlwnLG5vZGUscmUuUylcbnNlY3Rpb249bm9kZS5zcGxpdChcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcpWzFdLnNwbGl0KFwnRXZlbnRzOlwnKVswXSBpZiBcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcgaW4gbm9kZSBlbHNlIFwnXCdcbm5vZGVzPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwnbm9kZXNcJyxcJy1vXCcsXCdqc29uXCddKSlbXCdpdGVtc1wnXTthc3NlcnQgbGVuKG5vZGVzKT09MVxuYWxsb2M9bm9kZXNbMF1bXCdzdGF0dXNcJ11bXCdhbGxvY2F0YWJsZVwnXTtjcHU9YWxsb2NbXCdjcHVcJ107Y3B1X209aW50KGNwdVs6LTFdKSBpZiBjcHUuZW5kc3dpdGgoXCdtXCcpIGVsc2UgaW50KGNwdSkqMTAwMFxucmVxdWVzdGVkPWludChyZS5zZWFyY2goclwnY3B1XFxzKyhcXGQrKW1cJyxzZWN0aW9uKS5ncm91cCgxKSk7YXNzZXJ0IHJlcXVlc3RlZDw9Y3B1X21cbnJlY2VpcHQ9e1wnbm9kZV9hbGxvY2F0YWJsZV9jcHVfbVwnOmNwdV9tLFwnbm9kZV9yZXF1ZXN0ZWRfY3B1X21cJzpyZXF1ZXN0ZWQsXCdjYXB0dXJlZF9hdFwnOmRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpLmlzb2Zvcm1hdCgpLFwnbmF0aXZlX3dvcmtsb2FkX2NoYW5nZWRcJzpGYWxzZSxcJ25hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZFwnOkZhbHNlLFwnYXJnb1wnOmFyZ28sXCduYXRpdmVfZGVwZW5kZW5jaWVzX2NoZWNrZWRcJzpUcnVlLFwnY29uZmlnbWFwX3VpZFwnOmNtW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdwdmNfdWlkXCc6cHZjW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdsaXZlX3JlYWR5X3JlcGxpY2FzXCc6MSxcJ2FkbWl0dGVkX3VpZFwnOmFkbWl0dGVkW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWRcJzpUcnVlLFwnYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZVwnOlRydWUsXCdjbGllbnRfZGlmZl9leGl0XCc6ZGlmZi5yZXR1cm5jb2RlLFwnY2xpZW50X2RpZmZfc2hhMjU2XCc6aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpLFwnbm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzXCc6c2VjdGlvbi5zdHJpcCgpLFwnYWxsX2NoZWNrc19wYXNzXCc6VHJ1ZX1cbnByaW50KGpzb24uZHVtcHMocmVjZWlwdCkpXG4nCmZvciBtYXJrZXIsdmFsdWUgaW4gWygnREVQRU5ERU5DSUVTX0xJVEVSQUwnLChST09ULydzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLCgnQ0FORElEQVRFX0xJVEVSQUwnLChST09ULydjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLCgnU0VBTEVEX0xJVEVSQUwnLChST09ULydzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksKCdHVUFSRF9MSVRFUkFMJywoUk9PVC8nY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpLCgnQVJHT19MSVRFUkFMJyxqc29uLmR1bXBzKGpzb24ubG9hZHMoKFJPT1QvJ25hdGl2ZS1wcmVmbGlnaHQuanNvbicpLnJlYWRfdGV4dCgpKVsnYXJnbyddKSldOgogcHJvZ3JhbT1wcm9ncmFtLnJlcGxhY2UobWFya2VyLHJlcHIodmFsdWUpKQpwcm9ncmFtPSdpbXBvcnQgdHJhY2ViYWNrLGpzb25cbnRyeTpcbicrJycuam9pbignICAgICcrbGluZSsnXG4nIGZvciBsaW5lIGluIHByb2dyYW0uc3BsaXRsaW5lcygpKSsiZXhjZXB0IEV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICBwcmludChqc29uLmR1bXBzKHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZSwnZXhjZXB0aW9uX3R5cGUnOnR5cGUoZXJyb3IpLl9fbmFtZV9fLCdleGNlcHRpb25fbGluZSc6dHJhY2ViYWNrLmV4dHJhY3RfdGIoZXJyb3IuX190cmFjZWJhY2tfXylbLTFdLmxpbmVub30pKVxuIgpyPXN1YnByb2Nlc3MucnVuKFsnc3NoJywncmFpbGlhbmNlMDEnLCdweXRob24zIC0nXSxpbnB1dD1wcm9ncmFtLHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlKQpyZXN1bHQ9dHJhbnNwb3J0X3Jlc3VsdChyLnJldHVybmNvZGUsci5zdGRvdXQpO3Jlc3VsdFsnc2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2J109aGFzaGxpYi5zaGEyNTYoKFJPT1QvJ3ByZWZsaWdodC1pbnB1dHMuanNvbicpLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCk7cmVzdWx0WydmcmVzaF9leGVjdXRpb25fcmVjZWlwdCddPVRydWUKb3V0LndyaXRlX3RleHQoanNvbi5kdW1wcyhyZXN1bHQsaW5kZW50PTIpKydcbicpO3ByaW50KGpzb24uZHVtcHMocmVzdWx0LGluZGVudD0yKSk7c3lzLmV4aXQoMCBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgMSkK" }, { - "digest": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06", + "digest": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b", "media_type": "application/json", - "content_base64": "ewogICJwYWNrZXRfZmlsZXMiOiB7CiAgICAiY2hhbmdlX2d1YXJkLnB5IjogImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmUiLAogICAgInByZWZsaWdodC5weSI6ICI2YjRjNjVmNzA4MjM4YzlhOWQxN2ZkMDY1ODc2YzdhMDBlMWYxNzQ1OTI2Zjk5MGExZGQ1ZTY2NzI5ODM0MGNkIiwKICAgICJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uIjogIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGUiLAogICAgInJvbGxiYWNrLWRlcGxveW1lbnQuanNvbiI6ICIzOWIzZjQzYmI4NGVmNDkyMWNjM2ExZmJjZGM0NDQ2MTA3NDFlZDg4MDkxNDlkOGY4ZjE3ZWQ4MDVmMjYyMTIxIiwKICAgICJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24iOiAiZDE4ZDI3MDYzZDA2ZjUzNWFlODg0ZWEwMWY5Njc0N2ZlMzAxNjg1NTE4YWI5NGIxY2JhMDcyYTFlMTUxOTM2MiIsCiAgICAibmF0aXZlLXByZWZsaWdodC5qc29uIjogImViNWY0MWFlZmI5NzY2NmJiMGMxMjc5NjE3ZTk1YTdjMDUwMTdhNjA5NDE1NjI0ZGFlZTcyNGM0OGI5MGQyNjIiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAic3FsaXRlX3JlYWRvbmx5LnB5IjogImVlZjUzZGQyMzNlZWU3NGMxN2YyMDgyM2JkN2Y1Nzg3YzYwY2FkNzlhYzY0ODAyMWM5NDc5NjQzYzZjZTllMzgiCiAgfSwKICAib3duZXJfc291cmNlX2ZpbGVzIjogewogICAgImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uIjogIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTUiLAogICAgImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbiI6ICIzOGI3OGI5Y2JlZTVhZGU3NzUwYTU4ZDUxNTZjYTRjNTc3MzM1MmU5NDdhY2IzMDRlZTcxNGI1OWU3NDljZWI0IgogIH0KfQo=" + "content_base64": "ewogICJwYWNrZXRfZmlsZXMiOiB7CiAgICAiY2hhbmdlX2d1YXJkLnB5IjogImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmUiLAogICAgInByZWZsaWdodC5weSI6ICI2YjRjNjVmNzA4MjM4YzlhOWQxN2ZkMDY1ODc2YzdhMDBlMWYxNzQ1OTI2Zjk5MGExZGQ1ZTY2NzI5ODM0MGNkIiwKICAgICJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uIjogIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGUiLAogICAgInJvbGxiYWNrLWRlcGxveW1lbnQuanNvbiI6ICIzOWIzZjQzYmI4NGVmNDkyMWNjM2ExZmJjZGM0NDQ2MTA3NDFlZDg4MDkxNDlkOGY4ZjE3ZWQ4MDVmMjYyMTIxIiwKICAgICJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24iOiAiZDE4ZDI3MDYzZDA2ZjUzNWFlODg0ZWEwMWY5Njc0N2ZlMzAxNjg1NTE4YWI5NGIxY2JhMDcyYTFlMTUxOTM2MiIsCiAgICAibmF0aXZlLXByZWZsaWdodC5qc29uIjogImViNWY0MWFlZmI5NzY2NmJiMGMxMjc5NjE3ZTk1YTdjMDUwMTdhNjA5NDE1NjI0ZGFlZTcyNGM0OGI5MGQyNjIiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAic3FsaXRlX3JlYWRvbmx5LnB5IjogIjkwOTNjNjRmN2YwZTM5YjI0OWRhOWZlZmRmNWFhZjRlNDI1OGJjMzFlN2EyN2ZkODg4NDc5Y2UzMjlhMjA1MDkiCiAgfSwKICAib3duZXJfc291cmNlX2ZpbGVzIjogewogICAgImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uIjogIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTUiLAogICAgImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbiI6ICIzOGI3OGI5Y2JlZTVhZGU3NzUwYTU4ZDUxNTZjYTRjNTc3MzM1MmU5NDdhY2IzMDRlZTcxNGI1OWU3NDljZWI0IgogIH0KfQo=" }, { "digest": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7", @@ -245,33 +274,6 @@ "content_base64": "ewogICJub2RlX2FsbG9jYXRhYmxlX2NwdV9tIjogNDAwMCwKICAibm9kZV9yZXF1ZXN0ZWRfY3B1X20iOiAzNDYwLAogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjM5OjE0LjIzNDI3NyswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibmF0aXZlX2RlcGVuZGVuY2llc19jaGVja2VkIjogdHJ1ZSwKICAiY29uZmlnbWFwX3VpZCI6ICI5MDExM2QyZC01NGQ5LTRlODItYjFkMy05MGI0OWViZWQyYjUiLAogICJwdmNfdWlkIjogImQ4MGIyNWIxLTE0MWEtNDQxYi1iMjA1LTk4ZmEyZmQ5OGI3YyIsCiAgImxpdmVfcmVhZHlfcmVwbGljYXMiOiAxLAogICJhZG1pdHRlZF91aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIiwKICAic2VydmVyX2RyeV9ydW5fcGFzc2VkIjogdHJ1ZSwKICAiYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZSI6IHRydWUsCiAgImNsaWVudF9kaWZmX2V4aXQiOiAxLAogICJjbGllbnRfZGlmZl9zaGEyNTYiOiAiODQwNzY5YzdkMmE5YzE2NTVjNDBhMzI1OWY4MzNkMWZjOGY2OTk1MGNlYjNiZWRiNzA3YTk1NWZlZDcxMTU2NiIsCiAgIm5vZGVfYWxsb2NhdGVkX3Jlc291cmNlcyI6ICIoVG90YWwgbGltaXRzIG1heSBiZSBvdmVyIDEwMCBwZXJjZW50LCBpLmUuLCBvdmVyY29tbWl0dGVkLilcbiAgUmVzb3VyY2UgICAgICAgICAgIFJlcXVlc3RzICAgICAgTGltaXRzXG4gIC0tLS0tLS0tICAgICAgICAgICAtLS0tLS0tLSAgICAgIC0tLS0tLVxuICBjcHUgICAgICAgICAgICAgICAgMzQ2MG0gKDg2JSkgICAzNjIwMG0gKDkwNSUpXG4gIG1lbW9yeSAgICAgICAgICAgICA5NDcyTWkgKDU5JSkgIDMyODk4TWkgKDIwNSUpXG4gIGVwaGVtZXJhbC1zdG9yYWdlICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMUdpICAgICAgMCAoMCUpICAgICAgICAwICgwJSlcbiAgaHVnZXBhZ2VzLTJNaSAgICAgIDAgKDAlKSAgICAgICAgMCAoMCUpIiwKICAiYWxsX2NoZWNrc19wYXNzIjogdHJ1ZSwKICAic2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2IjogIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDYiLAogICJmcmVzaF9leGVjdXRpb25fcmVjZWlwdCI6IHRydWUKfQo=" } ] - }, - "publish": { - "version": 1, - "audience": { - "subjects": [], - "groups": [ - "net-kingdom-admins" - ] - } - }, - "review": { - "version": 1, - "options": { - "submitter": "state-hub", - "memo_class": "decision-record", - "review_group": "net-kingdom-admins", - "approval_intent": { - "action": "administer", - "principal": "informed-decision", - "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", - "target": { - "id": "INFD-WP-0009-T04/purpose-overlay-v1", - "type": "runtime-change", - "system": "railiance01" - } - } - } } } ] diff --git a/docs/evidence/2026-10-11-purpose-image-release/memo.json b/docs/evidence/2026-10-11-purpose-image-release/memo.json index f83c393..522f9ca 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/memo.json +++ b/docs/evidence/2026-10-11-purpose-image-release/memo.json @@ -1,10 +1,10 @@ { "id": "infd-20261011-purpose-overlay-r1", - "version": 1, - "question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", "requested_act": "approve", "binding_level": "organizational", - "brief": "Actual CI763c purpose-only image; eight base layers unchanged, legacy serialization disclosed. Scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib/T05 dueOct18. Exact helper binds four Git blobs, protected real-data backup/offline drill (isolated new-volume UID0/CAP_CHOWN init, then UID10001 readonly/admin/postcheck), Deployment-only manualArgo/prune=false, currentDB retention. Rollback needs no Ready candidate; separate recovery verification. ALL phases incl recovery must begin byOct12, fresh founder decision beyond. Ten installed checks are synthetic/native_provider=false. No native backup/image action yet.", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", "binding": { "principal": { "id": "pending-human-session", @@ -17,19 +17,19 @@ "label": "Informed Decision image-only purpose hardening on railiance01", "environment": "production" }, - "terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/offcluster custody/isolated offline restore with explicit NEW-volume UID0 CAP_CHOWN-only initializer followed by UID10001 readonly schema5/admin/postproof; exact four committed source blobs and helper-bound manual Deployment-only image763c/prune=false. Fresh root-authenticated confirmed founder disposition before each phase; supervised receipt is not signed/autonomous grant. ALL phases including rollback/rollback-verify must begin before2026-10-12T23:59:59Z, new founder decision beyond; no expiry controller. Rollbackprior7f5 retains latestschema5DB and does not need Ready candidate; separate old-image/schema recovery proof. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 reviewdueOct18. Syntheticinstallednative_provider=false is not actualPDP authority proof; actualproviderT04gate distinct. No credential/policy/grant change, humanbinding or wholeAppsync." + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." }, "step_kind": "approve", "packet": [ { "item_id": "decision-packet-md", "label": "decision-packet.md", - "hash": "sha256:a542235221890fa9ffb9c78f65d5e93227f5215d3ac68f0d1fa4addfd17bdaf6" + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" }, { "item_id": "proposal-json", "label": "proposal.json", - "hash": "sha256:7cca98a6c159201823a42fe05218d32e46152031b3f8a2ee26795454df0016df" + "hash": "sha256:e4d8fa77ce97f9cc190e9cae8f86478dba5e89cc7a13bf993e3b8d47a3160b36" }, { "item_id": "candidate-admission-json", @@ -54,7 +54,7 @@ { "item_id": "published-verification-json", "label": "published-verification.json", - "hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2" + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" }, { "item_id": "registry-proof-json", @@ -69,12 +69,12 @@ { "item_id": "execution-bundle-json", "label": "execution-bundle.json", - "hash": "sha256:27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d" + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" }, { "item_id": "sqlite-readonly-py", "label": "sqlite_readonly.py", - "hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" }, { "item_id": "sealed-native-dependencies-json", @@ -84,7 +84,7 @@ { "item_id": "native-backup-restore-protocol-md", "label": "native-backup-restore-protocol.md", - "hash": "sha256:440932f5975f42f8bc3ef5c7b281f42cf843246ffc8faba64a1d80b43ffa7478" + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" }, { "item_id": "inherited-vulnerability-follow-through-json", @@ -114,7 +114,7 @@ { "item_id": "preflight-inputs-json", "label": "preflight-inputs.json", - "hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06" + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" }, { "item_id": "fresh-preflight-validation-json", diff --git a/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md b/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md index e9374f6..d2b86de 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md +++ b/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md @@ -1,68 +1,31 @@ -# Protected native backup/restore and image-only release protocol +# Version2 protected existing-snapshot rescue and conditional continuation -Prepared protocol for `INFD-WP-0009-T04/purpose-overlay-v1`. No actual native backup, data export, restore, workload change or approval is recorded here. Candidate registry image identity remains a prerequisite; only after actual artifact proof may the founder approve one exact conditional protocol/rollout packet. The config-only7db8485 approval is outside this scope. +Same proposal INFD-WP-0009-T04/purpose-overlay-v1, trial infd-purpose-20261011-r1. Original version1 founder acceptance approved source bc6494cd1b290783ef3aef0763bf28d1deabf4b0. Drill-backup completed; drill-copy failed ValueError before any localfile. No image rollout occurred. This exact changed source/plan/helper requires NEW founder acceptance of memo version2 before rescue/continuation; prior approval and technical review do not approve it. -## Preconditions and protected custody +## Failure and narrowly selected rescue -Freeze exact candidate and prior7f5c6cb image digests, source/installed policy hashes, current manually managed Argo Application/revision, runtime ConfigMap6c221878d051, Deployment UID/template/spec, schema5, policy package pins, database path `/data/private/review.sqlite`, PVC binding, replicas1/Recreate and stable keys for intended verification. Confirm no concurrent writer or custody change. Use fixed metadata; never fetch Secret objects or token values. A changed image/config/schema/owner invalidates the packet. Fresh resources/headroom and exact source/native server-dry-run/diff remain required. +Original snapshot main19537920bytes SHA8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3 is unchanged. Root's metadata-only verification shows WAL0bytes, SHM32768bytes, privateUID10001/mode0600/nlink1, and no local snapshot. The old SQLite connection context manager did not explicitly close; its WAL reader can create SHM indexing, and the next copy rejected that nonzero index. Platform independently reproduced this on synthetic data. No native DB was opened to diagnose the sidecar metadata, and no native sidecar is deleted/checkpointed. -Backups are private evidence containing real decision records, not logs or packet attachments. Allocate a unique backup directory under existing protected PVC custody, owned10001, mode0700, snapshot file0600, no symlink/hardlink/reused output path. An off-cluster copy belongs only in the already established ignored `.private-backups/` custody with0700/0600 permissions; no Git, StateHub, public object store or terminal-content dump. Record only schema, integrity pass/fail, bounded table/state counts and protected receipt identifier; retain byte digests in protected custody if needed for internal copy identity. No credential, record payload or token fingerprint enters public evidence. +Reuse this exact independently hash-bound frozen main snapshot rather than make another drill backup. The backupadmin exited after creating the uniquely owned private snapshot. Original subsequent snapshot access was readonly; actual service DB is the distinct /data/private/review.sqlite. Original journal has only COMPLETE drill-backup d63182a7-e1a5-4e8e-a5f1-2bf3333cf153 and UNCERTAIN drill-copy329ef190-1692-4246-b953-e6a59664abcc. Its exact SHA d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1, original source/memo/plan identity and outcomes are verified before/after every new phase. No other original action or rollout is allowed. -## Approved online compatibility drill +The explicitly named drill-copy-rescue-r1 creates a separate rescue-execution-journal-r1.json/lock in existing protected ignored custody; it hash-links original attempts and backupresult and never rewrites/synthesizes the old failed phase. Any attempted rescue result, crash or ambiguous output is durable and same-phase retry is refused. Before rescue: local drill.sqlite/cutover.sqlite and existing restore volume must be absent; native originalPodUID/currentoldimage7f5/Argo7db/sealedDeployment/CM/PVC match. The fixed immutable snapshot reader checks recorded digest/private identity/no WALframes before and after schema5/integrity/count validation, retaining unchanged SHM. Nonzero WAL or any identity/hash drift stops rescue. Snapshot binarystdout flows only to a new0600private file, with bounded size/hash and repeat source proof. It never reaches chat/log/Git/StateHub. -Within the explicit founder-approved action, run the existing base image's `informed-decision-admin backup --db /data/private/review.sqlite --output ` in the actual serving workload. This uses SQLite's backup API for a transactionally consistent snapshot; copying a live main database while ignoring WAL is prohibited. Suppress raw failures/output and retain only sanitized status. Observe schema/integrity and count-only metadata from the resulting snapshot, not record content. +## Live-WAL and data compatibility boundaries -Transfer that consistent snapshot only into protected off-cluster custody through the existing authorized operator lane. The copy is real production data even in build mode. Verify private permissions, unique identity and protected internal digest agreement. Do not export mounted workload credentials or directory trees; copy only the exact snapshot. +Live source and writable offline pre/post-admin reads MUST stay mode=ro/query_only and explicitly close SQLite connections. immutable=1 ignores WAL and would lose committed live rows; it is restricted to the proven frozen closed-main snapshot, never the liveDB or writableclone. Before ANY native source or restoredcopy Store/admin open, require stdlib readonly schema5/integrity/counts; refuse oldschemas before automatic migration. Frozen snapshot/clone count equality is exact; currentlive counter changes may reflect concurrent legitimate commits and are retained. -Create a separate private disposable restore volume/directory; retain the original snapshot unchanged. Run the exact published candidate with network disabled, no production ConfigMap/token mounts, read-only image and only that isolated volume writable. Override the service entrypoint with the owner's count-only administrative inspection/integrity check; do not start HTTP listeners, audit delivery, requester exchanges or approval operations. The current candidate changes policy.py only and retains the schema/store module bytes; still prove schema5, SQLite integrity and exact bounded counts before/after opening the restored copy. Refuse any migration/downgrade, lost/changed counts, unexpected write class or unknown outcome. Keep pending/uncertain submission and outbox states; never replay, discard or mark them delivered to green the drill. Cleanup only the disposable copy/volume after verified receipt; retain the original protected backup for the approved recovery interval. +Only after COMPLETE named rescue does offline-verify consume its result via explicit mapping, not the old UNCERTAIN drill-copy. Existing isolated disposablevolume infd-purpose-r1-restore-20261011 must be absent/new nonce-bound. One exact763c UID0/CAP_CHOWN-only initializer receives snapshotstdin into that NEWvolume, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/nativePVC/runtimeconfig/token mounts. It sets folder0700/file0600UID10001, followed by UID10001 pre-open readonly, --entrypoint informed-decision-admin inspect --db /restore/review.sqlite and post-admin readonly fullproof; original protected SHA must remain unchanged. No serviceentrypoint starts. Cleanup only this disposable volume, retaining original native/offcluster snapshots/sidecars. -This step is actual native-data compatibility evidence once performed. Its previous synthetic fixture checks remain mechanism evidence and cannot be renamed native success. A failed drill stops rollout and remains a failed/unverified outcome in the same trial. +## Conditional remaining phases and release/recovery -## Fresh cutover snapshot and single-writer rollout +Newjournal fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. cutover-backup uses distinct newcutover.sqlite in originalprivatecase directory, after readonly live schema5/capacity gates, SQLitebackupAPI/admin completion, closed-main immutable proof; do not overwrite originals or retryfailedpaths. Version2 acceptance conditionally approves these exact unchanged remaining operations only after rescue+drillgates. All four committed Kustomize Git blobs/currentHEAD, exact helper/case hashes, CM/PVC/Deployment seals and manualApplication(no automated{} or sourceoverride) must match. -After successful actual-data compatibility checks, create another unique SQLite-consistent online snapshot immediately before the image cutover, retaining its point-in-time schema/integrity/count receipt. This is an online transactional snapshot, not a claim that dispatchers or human writes were quiesced. Every later committed record remains in the live database; same-schema rollback retains that database and never restores the earlier snapshot over it. The narrow image-only update does not need dispatcher/configuration/PVC/temporary-pod changes or a schema cutover. If fresh verification shows a migration or any data-restoration requirement, stop and refine the proposal rather than applying this protocol. +Release retains existing replica1/Recreate/config6c/schema5/PVC/credentials/policies: sourcepin Application.operation serverdryrun/UID+resourceVersion+source CAS, Deployment-only image763c, prune=false. No whole-app sync/adoption. Verify requires succeeded exactscope/controllergeneration/Ready1, installedpolicyhash/modeUID/10syntheticpurposevariants+boundedhealth, same currentliveDB schema5/integrity/counts. Those installedchecks report native_provider=false; actualprovider/PDPauthority evidence remains a separate T04gate. -The existing Recreate rollout drains/stops the single old writer before starting the new image on the same PVC; the inherited single-writer lock independently refuses concurrent serving processes. Do not add an admin pod, scale-to-zero, dispatcher stop, network-policy rewrite or snapshot overwrite as an improvised image-only step. The existing owner admin backup operation runs inside the admitted serving workload, and its separate protected restore drill runs off-cluster with network disabled and no workload credentials. Those exact custody operations must be enumerated in the founder packet alongside the one Deployment image change. +Rollback after recorded newrelease attempt pins prior7db/7f5 and retains latestschema5DB, without requiring Ready failingcandidate or candidateDBexec. Separate rollback-verify proves oldimageReady1/scopedoperation/readonlyschema5 currentDB integrity. Never restore an older snapshot over postcutoverrecords. Any data recovery beyond this same-schema image rollback needs another decision. -Once backup/compatibility/preflight gates pass, manually pin the existing Argo Application to the exact reviewed source revision and sync only Deployment/informed-decision with prune false, keeping the current immutable runtime ConfigMap and all other resources. The source patch changes only the image in admission/rendered Deployment; no Secret, PVC, policy, database or dispatcher change is included unless separately enumerated in the final proposal. Observe five-minute readiness and exact image/config/schema/pins. Run the ten installed purpose variants on the actual native placement using synthetic transport; they prove exact installed module refusal behavior and explicitly report native_provider=false. They do not prove an actual provider response, PDP authority or native lifecycle binding; any required actual-provider proof remains a distinct T04 completion gate with separate authorized preparation, and must not be claimed by this helper. Do not contaminate the live PDP, create human approvals, read credentials through CLI, or replay unknown external outcomes for testing. +All phases including rescue, verification and recovery must begin before2026-10-12T23:59:59Z. Start early enough; if expired stop and obtain a fresh founder decision, which may delay recovery. No automatic timer/controller/extension. Root freshly authenticates exact confirmed platform-root person ACCEPT memo version2 at fixednativeorigin before every phase; protectedreceiptrelation/freshness120sec is supervisedbookkeeping, not a signed/autonomous grant. -## Same-schema rollback and evidence retention +Image763c/policy9d7c/base7f5 and actualunfilteredscan0HIGH/CRITICAL/1fixableMEDIUMzlib remain unchanged, owner INFD-RISK-20261011-ZLIB-85091/T05 dueOct18. The exactbundle directly binds helper/plan/tests plus original count-onlybackup/failure/anchor. Existingpublishedreceipt still binds unchanged rawscan/SBOM/base scan; no suppression. Preserve originalapproved20docpacket/helpers/history in initial-approved-bc6494cd. No version2 native operation has run. EUR0 recurringinfrastructure; private boundedstorage/attendedtime unpriced, no newdrillbackup or autonomygrant. -On startup/readiness/binding/refusal failure, retain current database, cutover backup and every post-cutover evidence/uncertain outcome. Restore only the prior7f5c6cb image through the same manual Argo owner path, retaining schema5 and current DB/configuration; never restore an old snapshot over current live evidence just to roll the image back. Verify old image/Ready1, same schema/counts and prior behavior, and reconcile any external effects using existing lifecycle/audit ownership. The narrow overlay's identical store/schema/dependency bytes permit this image-only rollback; it is not permission for a schema downgrade or data loss. - -Record original/approved/executed source and image revisions, backup/drill/cutover/rollout timestamps, exact disposition and sanitized outcomes in the existing supervised trial receipt. EUR0 incremental infrastructure estimate uses existing service/storage/operator lane; protected temporary copy/storage consumption and15–30minute recovery time remain operational costs. No EUR incident-loss cap or autonomy grant is inferred. TaskT04 cannot close until actual published image, approved native compatibility and release plus post-release refusal/binding evidence all exist. - -## Exact release case identifiers - -Proposal `INFD-WP-0009-T04/purpose-overlay-v1`, trial `infd-purpose-20261011-r1`. -Protected native parent `/data/private/purpose-overlay-r1` must be unique/non-symlink, owned10001 and0700. The drill snapshot is `drill.sqlite`, the refreshed pre-cutover snapshot `cutover.sqlite`, each new0600 file; refuse any existing output. Off-cluster custody is the existing ignored Custodian `.private-backups/20261011-infd-purpose-r1` parent0700, files0600; no snapshot is an evidence attachment. Check owner UID, no symlinks, ignored status and free capacity for both native snapshots plus independently protected copies before making any snapshot. - -The disposable offline restore volume is `infd-purpose-r1-restore-20261011`; refuse an existing volume, copy only the selected frozen snapshot, and run exact published candidate763c with networknone/read-only image,128MiB/core1 and no runtime config/token mounts. SQLite `PRAGMA integrity_check` must return `ok`, `PRAGMA user_version`/Store inspection must agree with actual schema5 semantics, and installed admin count-only inspection must match the frozen snapshot. Validate the actual schema representation rather than assume PRAGMA user_version is the schema authority. No synthetic restoration is reported as native restoration. Native original/off-cluster copies remain retained; only the disposable restore copy/volume may be removed under the exact approved cleanup scope. - -## Mandatory pre-open schema gate and offline command - -`informed-decision-admin inspect` and `backup` construct Store, which can migrate schemas1–4 to5. Therefore **before any Store/admin open**, run the exact attached stdlib-only `sqlite_readonly.py` against the native source database using SQLite URI mode=ro, query_only and one read transaction. Require PRAGMA user_version5, integrity_check=ok and retain count-only baseline. Refuse any other/unknown schema or incomplete integrity/count check before constructing Store; do not infer no migration from a post-open admin report. This native gate has not been executed in this source-preparation stage. Repeat before each native backup/admin operation. - -After copying the selected consistent snapshot to the isolated restored private path `/restore/review.sqlite`, run the same read-only checker **before** any offline candidate admin/Store opens that copy. Frozen snapshot and restored-copy schema/integrity/count reports must agree exactly; the copied main-file digest must match the selected closed snapshot. Reject oldschema fixtures rather than allow migration. Only after this pre-open gate may the offline candidate admin inspect run. - -Offline command vectors use exactimage `forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a`, `--network none --read-only --cpus 1 --memory 128m`, private restored volume mounted at `/restore`, and **no runtime config/credential/token mounts**. First override entrypoint to `python`, arguments `- --db /restore/review.sqlite`, streaming only the verified attached checker on stdin. Then override entrypoint to **`informed-decision-admin`**, arguments **`inspect --db /restore/review.sqlite`**. This does not start `informed-decision-container`, the HTTP service, dispatcher or delivery workers. Compare the admin's schema/lifecycle/outbox/submission counters to the frozen pre-open snapshot report; integrity and migration-free pre-open proof come from the stdlib checker, not admin output alone. - -Live reads and online snapshots may legitimately differ because reviews, intake and delivery can commit concurrently. Exact counter equality is required between the frozen selected snapshot and its offline restored clone; it is **not** required between a running post-cutover/rollback database and an earlier snapshot. Live count changes must be accounted for as legitimate committed records/state transitions; preserve all current and uncertain entries. Do not discard new commits or restore the old snapshot to force equality. Same-schema image rollback keeps the current live DB, followed by read-only schema5/integrity and count-only health checks; any unexplained evidence loss or required data recovery stops and requires a separate founder decision. - -The fresh preflight also independently reads the actual immutable nonsecret ConfigMap and bound PVC: compares sealed UIDs/fullmetadata/PVCspec+volumeName and canonical runtime data checksum, returning no raw runtime data. Same-name deletion/recreation or content/custody drift stops before admission. Secret values remain excluded. Both local and remote optimized Python interpreters are explicitly refused before assertion-based gates. - -## Exact supervised mechanical execution refinement - -The directly attached `execution-bundle.json` contains the exact helper source, plan, tests and PENDING receipt template. It replaces the direct raw scan attachment within the twenty-document limit; `published-verification.json` still binds the unchanged actual unfiltered raw scan, raw SBOM and base scan SHA256 values, retained in the owner evidence package. The known inherited fixable MEDIUM remains explicit, with owner T05/risk follow-through. Neither archive nor technical agreement supplies human approval. - -The reviewed protocol basis is owner commit e0359bcb6cdfad9ab3e868054121fe0cebec2d68, with source follow-through9268c9ac0bbee508fe35c0b90dcefef4c24da2f5. The subsequent exact applied helper/packet owner commit must be named in the externally verified founder receipt before execution. Verify the four committed Git blobs (admission.candidate.json, service.candidate.json, kustomization.yaml, registries.candidate.json) against execution-plan.json as well as current worktree/HEAD; reject overrides/plugins/multiple Application sources and any present automated configuration, including automated:{}. - -Root freshly authenticates the exact confirmed founder person/platform-root ACCEPT of this stable memo/version1 at the fixed native Informed Decision origin before each phase, and supplies protected0600 receipt/outcome files. The helper checks their exact relation and freshness120seconds; these files are supervised bookkeeping, not signed authenticated grants, a human-provider implementation, or autonomous agent authority. Do not derive them from technical reviews or caller assertions. - -Fixed order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. A separate recorded release attempt permits rollback → rollback-verify. Every phase fsyncs an attempt nonce/RUNNING journal before effects. Failure/interruption/ambiguous actuation stays UNCERTAIN and the same phase cannot be retried. No improvised adapter or whole-Application sync is permitted. - -The NEW nonce-labelled local volume requires one explicit isolated initializer as UID0:0 with only CAP_CHOWN, exact763c image, --network none --read-only --cpus 1 --memory 128m --cap-drop ALL --cap-add CHOWN --security-opt no-new-privileges. Its only mount is that new named volume at /restore; no host mount, native PVC, runtime config or token mount. Protected snapshot stdin goes only to a unique0600 main file with exact digest, and directory/file custody is set0700/0600 UID/GID10001. Then all pre-open, admin and post-admin checks run UID10001:10001, capabilities dropped, networknone. The second stdlib readonly schema5/integrity/count proof after admin must exactly equal the frozen snapshot proof; independently recheck the retained original protected snapshot SHA. No service startup occurs. - -Rollback dispatch must be available if the candidate is unready or cannot start: it checks sealed Deployment/CM/PVC custody, only prior/candidate source/image pair, node health/headroom and fresh old-image server admission plus Application UID/resourceVersion/source CAS, with no failing candidate Pod/exec/database prerequisite. Dispatch acknowledgment is not recovered health. `rollback-verify` separately requires old image Ready1, succeeded exact Deployment-only/prune=false operation and readonly schema5/integrity/count proof of the latest retained live database. No snapshot replaces the current database. - -**Deadline refinement:** all phases, including rollback and verification, must begin before2026-10-12T23:59:59Z. The earlier amended packet described unstarted-release expiry; this exact helper also bounds recovery/verification. Start early enough to complete the bounded drill and any recovery within the window. If exhausted, stop and obtain a fresh founder decision rather than silently extend a grant. This may delay recovery and is an explicit operational risk. No timer/controller automatically rolls back or changes service at expiry. +Native source publication uses exact revision-command.json via /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions, expected_version1, only after fresh unbound-source readback. No version2 intake/register. Publish/review sourceversion2; new human review-ID is ownversion1, so its confirmed nested disposition memo_version1 is correct. Root actual outcomes query must name SOURCE version2 and exact newreviewID; original review/approval cannot be reused. diff --git a/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json b/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json new file mode 100644 index 0000000..a9b779f --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-backup.json @@ -0,0 +1 @@ +{"phase": "drill-backup", "all_checks_pass": true, "raw_output_withheld": true, "native_approval_verified_by_root": {"approval_id": "ec92806a-9aa6-494f-a76b-0385f39ba609", "disposition_id": "disp-0968373d-294d-42bf-8979-36a7c5dd38cf", "accepted_at": "2026-10-11T02:34:20Z", "verified_at": "2026-10-11T02:38:41.777949+00:00"}, "native_authenticated_grant": false, "source_readonly_baseline": {"schema_version": 5, "lifecycle": {"records": 15, "events": 50, "pending": 0}, "outbox": {"delivered": 320}, "submissions": {"confirmed": 41}, "integrity": "ok", "read_only_pre_open": true, "store_constructed": false}, "snapshot_readonly": {"schema_version": 5, "lifecycle": {"records": 15, "events": 50, "pending": 0}, "outbox": {"delivered": 320}, "submissions": {"confirmed": 41}, "integrity": "ok", "read_only_pre_open": true, "store_constructed": false}, "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", "snapshot_bytes": 19537920, "snapshot_file": "drill.sqlite", "native_parent_private": true, "native_uid": 10001, "pod_name": "informed-decision-f557556df-mwpz7", "pod_uid": "e8561ae0-4b09-4455-924d-64c27b625fc7"} diff --git a/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json b/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json new file mode 100644 index 0000000..ca6f2c3 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/original-approved-drill-copy-failure.json @@ -0,0 +1 @@ +{"all_checks_pass": false, "phase": "drill-copy", "failure_class": "ValueError", "failure": "fixed phase outcome uncertain; original evidence retained; no retry", "raw_output_withheld": true} diff --git a/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json b/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json new file mode 100644 index 0000000..b643e77 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/original-journal-sanitized-anchor.json @@ -0,0 +1,20 @@ +{ + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json b/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json index d7ded46..580ec6c 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json +++ b/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json @@ -7,7 +7,7 @@ "sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", "native-preflight.json": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", - "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + "sqlite_readonly.py": "9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" }, "owner_source_files": { "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", diff --git a/docs/evidence/2026-10-11-purpose-image-release/proposal.json b/docs/evidence/2026-10-11-purpose-image-release/proposal.json index 3dcc48a..902f5bc 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/proposal.json +++ b/docs/evidence/2026-10-11-purpose-image-release/proposal.json @@ -25,18 +25,17 @@ "runtime_configmap": "informed-decision-runtime-6c221878d051", "schema": 5, "requested_operations": [ - "Protected SQLite-consistent native backup and independently protected off-cluster custody", - "Offline restore/integrity/count comparison on a private disposable volume with exact candidate, no runtime tokens/config/network", - "Refresh a consistent pre-cutover snapshot, retain private copies and count-only/hash receipts", - "Pin existing manual Argo Application to exact approved owner source and manually sync only existing Deployment image", - "Verify health/readiness/image/module/installed fail-closed purpose checks and retained schema/count evidence; recover to prior same-schema image if needed" + "Read-only immutable validation of existing frozen19537920byte native drill snapshot, SHA8756..., privatecustody/no-writer/zeroWAL/staleSHM retained", + "Distinct drill-copy-rescue-r1 binarycopy into absent0600protected local destination, new hash-linked rescue journal preserving old UNCERTAIN copy", + "Existing isolated offline pre-open/admin/post-open compatibility drill and disposable-volume cleanup using rescued result", + "Distinct consistent cutover snapshot plus protectedcopy, followed only after allgates by Deployment-only image release/verify; same-schema rollback/recovery proof if needed" ], "execute_by": "2026-10-12T23:59:59Z", "temporary_vulnerability_review_due": "2026-10-18", "known_scan_findings": "0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical", "vulnerability_record": "INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05", "cost_estimate_EUR": 0, - "cost_limits": "No new recurring infrastructure; private backup storage and attended engineering/recovery time unpriced, not an autopilot cost grant", + "cost_limits": "No additional recurring infrastructure or second drill backup. Existing native snapshot19537920bytes retained; protected localcopy/offlineclone plus distinct cutover snapshots consume boundedexistingstorage. Attendedengineering/recovery time unpriced; no autopilot grant.", "risk_estimates": [ "Brief Recreate service interruption; no concurrent new writer/surge", "Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence", @@ -46,17 +45,16 @@ "All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller." ], "rollback": "Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes", - "native_executed": false, - "human_approval": false, + "native_executed": "Original drill-backup executed; original drill-copy failed. No version2 action executed.", + "human_approval": "Version1 accepted originalsource; version2 requires fresh exact acceptance.", "refinement_of_manifest": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300", "mandatory_pre_open_gate": "stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration", "optimized_interpreters": "local+remote explicitlyrefused beforeassert gates", "native_dependency_gate": "sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads", "live_counts": "Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained", "source_basis": { - "reviewed_protocol_commit": "e0359bcb6cdfad9ab3e868054121fe0cebec2d68", - "owner_followthrough_commit": "9268c9ac0bbee508fe35c0b90dcefef4c24da2f5", - "final_execution_source": "exact subsequent root-applied source commit must be bound by founder receipt and verified against four approved Git blobs" + "original_approved_source": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "final_recovery_source": "exact final root-applied owner HEAD with approved four render blobs must be bound by new founder receipt" }, "approved_owner_render_blob_sha256": { "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", @@ -64,12 +62,10 @@ "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" }, - "execution_bundle_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", - "execution_helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", - "execution_plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6", + "execution_bundle_sha256": "49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5", + "execution_plan_sha256": "9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258", "execution_phases": [ - "drill-backup", - "drill-copy", + "drill-copy-rescue-r1", "offline-verify", "cleanup-offline", "cutover-backup", @@ -83,5 +79,50 @@ "offline_initializer": "One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.", "rollback_dispatch": "Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.", "purpose_proof_limit": "Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.", - "refinement_of_amended_manifest": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033" + "refinement_of_amended_manifest": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033", + "memo_version": 2, + "recovery": { + "original_anchor": { + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false + }, + "original_identity": { + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "memo_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937", + "plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + "new_journal": "rescue-execution-journal-r1.json", + "new_phase": "drill-copy-rescue-r1", + "old_uncertain_phase_overwrite_or_retry": false, + "new_snapshot_backup": false, + "snapshot_or_sidecar_mutation": false, + "mapping": "offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal" + }, + "original_native_outcome": { + "drill-backup": "COMPLETE", + "drill-copy": "UNCERTAIN before localfile creation", + "native_image": "unchanged7f5; no rollout", + "original_journal_and_sidecars": "retained unchanged" + }, + "rescue_limits": "No liveDBwrites during rescue inspection/copy, no sidecar deletion/checkpoint, no retry/overwrite original UNCERTAIN phase. Later existing admin offlineinspect/cutoverbackup and image actions need new exactversion2 acceptance andorderedguards.", + "submission_route": "POST /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions CAS expected_version1; source must remain unbound; publish/review sourceversion2, resulting human review ownversion1", + "original_execution_helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", + "original_execution_helper_manifest_context": "Retained historical f2fad6 helper review before the failed approved backup/copy trial; current rescue execution bytes are bound by execution_bundle_sha256 and execution_plan_sha256. This historical manifest does not describe current version2 rescue files." } diff --git a/docs/evidence/2026-10-11-purpose-image-release/published-verification.json b/docs/evidence/2026-10-11-purpose-image-release/published-verification.json index 5db68f7..a608e79 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/published-verification.json +++ b/docs/evidence/2026-10-11-purpose-image-release/published-verification.json @@ -54,11 +54,16 @@ "base-trivy-full.json": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80", "check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad", "verify_registry.py": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4", - "sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38", "sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", "review-refinement.json": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75", "test_change_guard.py": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f", "test_sqlite_readonly.py": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323", - "test_preflight_optimization.py": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d" + "test_preflight_optimization.py": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d", + "initial-approved-bc6494cd/sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38" + }, + "version2_source_pointer_refinement": { + "original_receipt_sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2", + "original_receipt_archive": "initial-approved-bc6494cd/published-verification.json", + "reason": "Keep historical original pre-open checker hash bound to exact archived original bytes; current version2 checker is independently direct-packet/plan bound. Actual image/registry/scan/SBOM proof unchanged; no new artifact verification or native version2 action claimed." } } diff --git a/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json b/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json new file mode 100644 index 0000000..bdf6184 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/recovery-intake-rejection-fixture.json @@ -0,0 +1,261 @@ +{ + "kind": "informed-decision.memo-intake", + "version": 1, + "idempotency_key": "infd-20261011-purpose-overlay-r1-v2", + "memo_class": "decision-record", + "review_group": "net-kingdom-admins", + "drafted_by": "custodian-codex", + "approval_intent": { + "action": "administer", + "principal": "informed-decision", + "purpose": "Approve exact image-only purpose overlay release plus protected native evidence backup/restore gates and explicit inherited fixable-medium owner follow-through; no unrelated grant.", + "target": { + "id": "INFD-WP-0009-T04/purpose-overlay-v1", + "type": "runtime-change", + "system": "railiance01" + } + }, + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:e4d8fa77ce97f9cc190e9cae8f86478dba5e89cc7a13bf993e3b8d47a3160b36" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "packet": [ + { + "item_id": "decision-packet-md", + "media_type": "text/markdown", + "content": "# Informed Decision version2 existing-snapshot rescue and image release\n\nApprove the exact source-refined recovery of the failed drill-copy and conditional remaining backup/drill/Deployment-only image rollout. This is memo version2 in the same proposal/trial, requiring NEW founder acceptance; original version1 acceptance is retained and cannot authorize changed helperbytes.\n\nOriginal source bc6494cd completed the protected native drill-backup, then copy failed before any localfile. Metadata-only verification proves unchanged main19537920bytes/SHA8756..., WAL0/privateSHM32768. The original reader could leave SHM indexing because its connection context manager did not close. The correction explicitlycloses all readers and uses immutable reads ONLY for a proven frozen closed-main snapshot, not live or writableclone. SHM stays unchanged; nonzeroWAL/hash/identity drift stops rescue.\n\nDistinct drill-copy-rescue-r1/newlinkedjournal preserves original UNCERTAINcopy and exact journalhash/attempts. No oldretry/overwrite, no newdrillbackup. Require originalCOMPLETEbackup/UNCERTAINcopy only, absentlocalfiles/restorevolume, originalnativePodUID/currentoldimage+sourcepin and allCM/PVC/Deployment seals. Copy snapshotbytes only into a newprivate0600file. Remainingorderedphases explicitly consume COMPLETErescueresult; one isolated UID0/CAP_CHOWN-only NEWvolume initializer then UID10001 pre-open/admin/post-admin checks proves real-data compatibility before cutover. No host/nativePVC/runtimeconfig/token mounts; no service startup. Any attempted failure/ambiguity is durable and cannotretry.\n\nImage763c from actualCI3e4bcb26 remains unchanged8base layers pluspolicy.py; legacyserialization differences disclosed. ActualinstalledUID10001/10purposevariants pass; native_provider=false/synthetictransport is not actualPDPauthority proof, which remains separateT04gate. Actualfull44packagescan0HIGH/CRITICAL, ONEfixableinheritedMEDIUMzlibCVE-2026-85091(1.3.2-r0→r1), identicalbasefinding. Explicittemporarypermission for this finding is requested again, with ownerT05/riskrecorddueOct18; no zero-CVE/RiskNexusgradeclaim. Rawscan/SBOM/base scan stay unchangedhashbound via publishedreceipt; exacthelperandoriginalcount-onlyreceipts directlybundle-bound within20docs.\n\nAfter rescue+offlinegates, distinctcutoverbackup/copy and manualArgoDeployment-only image763c/prune=false remain conditional. FourcommittedKustomizeblobs/currentfinalsourceHEAD/helpers/casehashes match; automated{} or overrides refuse. Config6c/schema5/PVC/identity/policies/replica1Recreate stayfixed. Rollbackdoesnotneed Readycandidate or itsDBexec; oldimageReady/scopedoperation/schema5currentDB is a separateproof. Preserve latestliveDB/allnewcommits and alluncertainoutcomes; neverrestoreolderbackup overlaterrecords.\n\nAllphases including rescue/recovery/verify mustbegin beforeOct12 23:59:59Z; expiryrequiresnewdecision and maydelayrecovery. No automaticexpirycontroller. Freshroot-authenticated nativefounderacceptance version2 beforeeachphase; receipts are supervisedbookkeeping, notsignedgrant/autonomy. EUR0 recurringinfra, existingprivatecopy/storage/attendedtime unpriced; no secondnative drillbackup. Exactoriginalapprovedpacket/failure/technicalrefinements preserved sameproposal/trial. No version2nativeoperation yet.\n" + }, + { + "item_id": "proposal-json", + "media_type": "application/json", + "content": "{\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"trial_id\": \"infd-purpose-20261011-r1\",\n \"state\": \"prepared-unapproved\",\n \"target\": \"realm:kubernetes/railiance01/informed-decision\",\n \"authority\": \"ADMINISTER; activation APPROVED only upon exact founder disposition\",\n \"candidate_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"published_source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"prior_image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"prior_argo_revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"native_object\": {\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"namespace\": \"informed-decision\",\n \"name\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"argo_application_uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"source_gate\": \"All four exact committed owner Kustomize input blobs in execution-plan.json and clean current owner HEAD must match; source preparation is not native approval\",\n \"sync_scope\": [\n \"apps:Deployment:informed-decision\"\n ],\n \"prune\": false,\n \"automated_sync\": false,\n \"runtime_configmap\": \"informed-decision-runtime-6c221878d051\",\n \"schema\": 5,\n \"requested_operations\": [\n \"Read-only immutable validation of existing frozen19537920byte native drill snapshot, SHA8756..., privatecustody/no-writer/zeroWAL/staleSHM retained\",\n \"Distinct drill-copy-rescue-r1 binarycopy into absent0600protected local destination, new hash-linked rescue journal preserving old UNCERTAIN copy\",\n \"Existing isolated offline pre-open/admin/post-open compatibility drill and disposable-volume cleanup using rescued result\",\n \"Distinct consistent cutover snapshot plus protectedcopy, followed only after allgates by Deployment-only image release/verify; same-schema rollback/recovery proof if needed\"\n ],\n \"execute_by\": \"2026-10-12T23:59:59Z\",\n \"temporary_vulnerability_review_due\": \"2026-10-18\",\n \"known_scan_findings\": \"0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical\",\n \"vulnerability_record\": \"INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05\",\n \"cost_estimate_EUR\": 0,\n \"cost_limits\": \"No additional recurring infrastructure or second drill backup. Existing native snapshot19537920bytes retained; protected localcopy/offlineclone plus distinct cutover snapshots consume boundedexistingstorage. Attendedengineering/recovery time unpriced; no autopilot grant.\",\n \"risk_estimates\": [\n \"Brief Recreate service interruption; no concurrent new writer/surge\",\n \"Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence\",\n \"Candidate purpose refusal may expose callers relying on advisory results as binding\",\n \"Inherited known fixable MEDIUM remains until separately approved owner remediation\",\n \"Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted\",\n \"All phases, including recovery/verification, must begin before Oct12 deadline; if recovery window is exhausted stop and obtain a fresh founder decision. No automatic expiry controller.\"\n ],\n \"rollback\": \"Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes\",\n \"native_executed\": \"Original drill-backup executed; original drill-copy failed. No version2 action executed.\",\n \"human_approval\": \"Version1 accepted originalsource; version2 requires fresh exact acceptance.\",\n \"refinement_of_manifest\": \"7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300\",\n \"mandatory_pre_open_gate\": \"stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration\",\n \"optimized_interpreters\": \"local+remote explicitlyrefused beforeassert gates\",\n \"native_dependency_gate\": \"sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads\",\n \"live_counts\": \"Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained\",\n \"source_basis\": {\n \"original_approved_source\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\",\n \"final_recovery_source\": \"exact final root-applied owner HEAD with approved four render blobs must be bound by new founder receipt\"\n },\n \"approved_owner_render_blob_sha256\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\",\n \"deploy/lifecycle/kustomization.yaml\": \"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\",\n \"deploy/lifecycle/registries.candidate.json\": \"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\"\n },\n \"execution_bundle_sha256\": \"49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5\",\n \"execution_plan_sha256\": \"9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258\",\n \"execution_phases\": [\n \"drill-copy-rescue-r1\",\n \"offline-verify\",\n \"cleanup-offline\",\n \"cutover-backup\",\n \"cutover-copy\",\n \"release\",\n \"verify\",\n \"rollback\",\n \"rollback-verify\"\n ],\n \"deadline_semantics\": \"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\",\n \"offline_initializer\": \"One isolated local UID0:0/CAP_CHOWN-only initializer of the newly created nonce-bound disposable volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi; no host/livePVC/token/config mount. Subsequent pre-open/admin/post-open checks UID10001:10001.\",\n \"rollback_dispatch\": \"Sealed Deployment/CM/PVC and same-schema source/image pair plus admission CAS; no Ready candidate or Pod/database exec prerequisite. rollback-verify separately proves recovered old image/Ready1/scoped operation and readonly current schema5/integrity/counts.\",\n \"purpose_proof_limit\": \"Ten installed synthetic-transport checks on actual placement; native_provider=false. Not actual provider/PDP authority proof, which remains a distinct T04 completion gate.\",\n \"refinement_of_amended_manifest\": \"b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033\",\n \"memo_version\": 2,\n \"recovery\": {\n \"original_anchor\": {\n \"original_journal_sha256\": \"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\",\n \"phase_metadata\": {\n \"drill-backup\": {\n \"state\": \"COMPLETE\",\n \"attempt_id\": \"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\",\n \"started_at\": \"2026-10-11T02:38:45.310653+00:00\"\n },\n \"drill-copy\": {\n \"state\": \"UNCERTAIN\",\n \"attempt_id\": \"329ef190-1692-4246-b953-e6a59664abcc\",\n \"started_at\": \"2026-10-11T02:39:50.198740+00:00\"\n }\n },\n \"frozen_backup_receipt_sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"snapshot_sha256\": \"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\",\n \"snapshot_bytes\": 19537920,\n \"off_cluster_file_exists\": false,\n \"old_uncertain_retry_authorized\": false\n },\n \"original_identity\": {\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"source_revision\": \"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\",\n \"memo_sha256\": \"506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937\",\n \"plan_sha256\": \"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\"\n },\n \"new_journal\": \"rescue-execution-journal-r1.json\",\n \"new_phase\": \"drill-copy-rescue-r1\",\n \"old_uncertain_phase_overwrite_or_retry\": false,\n \"new_snapshot_backup\": false,\n \"snapshot_or_sidecar_mutation\": false,\n \"mapping\": \"offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal\"\n },\n \"original_native_outcome\": {\n \"drill-backup\": \"COMPLETE\",\n \"drill-copy\": \"UNCERTAIN before localfile creation\",\n \"native_image\": \"unchanged7f5; no rollout\",\n \"original_journal_and_sidecars\": \"retained unchanged\"\n },\n \"rescue_limits\": \"No liveDBwrites during rescue inspection/copy, no sidecar deletion/checkpoint, no retry/overwrite original UNCERTAIN phase. Later existing admin offlineinspect/cutoverbackup and image actions need new exactversion2 acceptance andorderedguards.\",\n \"submission_route\": \"POST /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions CAS expected_version1; source must remain unbound; publish/review sourceversion2, resulting human review ownversion1\",\n \"original_execution_helper_manifest_sha256\": \"f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c\",\n \"original_execution_helper_manifest_context\": \"Retained historical f2fad6 helper review before the failed approved backup/copy trial; current rescue execution bytes are bound by execution_bundle_sha256 and execution_plan_sha256. This historical manifest does not describe current version2 rescue files.\"\n}\n" + }, + { + "item_id": "candidate-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "rollback-admission-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"policy\": {\n \"origin\": \"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\n \"package\": \"informed-decision.compact-sitting\",\n \"version\": \"v13\",\n \"package_digest\": \"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\n \"pod_name\": \"flex-auth-informed-decision-sitting\"\n },\n \"keycape_egress_ips\": [\n \"92.205.62.239\"\n ],\n \"storage_class\": \"local-path\",\n \"ordinary_approval_ids\": [\n \"2ce76d7f-01c3-4b63-8476-8d1230679769\",\n \"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\n \"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"\n ],\n \"lifecycle_policy\": {\n \"package\": \"informed-decision.lifecycle\",\n \"version\": \"v2\",\n \"package_digest\": \"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\n \"origin\": \"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\n \"pod_name\": \"flex-auth-informed-decision-lifecycle\"\n },\n \"lifecycle_delivery\": true,\n \"intake_attributes\": true,\n \"intake_delivery\": {\n \"hub_origin\": \"http://state-hub.state-hub.svc.cluster.local:8000\"\n },\n \"workload_api\": {\n \"registries_configmap\": \"informed-decision-workload-registry\",\n \"peers\": [\n {\n \"namespace\": \"state-hub\",\n \"app\": \"state-hub\"\n }\n ],\n \"api_egress\": [\n {\n \"ip\": \"10.43.0.1\",\n \"port\": 443\n },\n {\n \"ip\": \"92.205.62.239\",\n \"port\": 6443\n }\n ],\n \"intake\": true,\n \"lifecycle\": true\n }\n}\n" + }, + { + "item_id": "candidate-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "rollback-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"livenessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\"\n }\n ],\n \"readinessProbe\": {\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\"\n },\n \"periodSeconds\": 10,\n \"timeoutSeconds\": 2\n },\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "published-verification-json", + "media_type": "application/json", + "content": "{\n \"proposal\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"observed_at\": \"2026-10-11T01:24:01.985128+00:00\",\n \"native_owner_publication_job\": {\n \"id\": 11484,\n \"name\": \"publish-candidate\",\n \"head_branch\": \"main\",\n \"head_sha\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"run_number\": 3,\n \"event\": \"push\",\n \"display_title\": \"Prepare readable overlay context with the admitted legacy builder\",\n \"status\": \"success\",\n \"workflow_id\": \"purpose-overlay-image.yaml\",\n \"url\": \"https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3\",\n \"created_at\": \"2026-10-11T01:20:59Z\",\n \"updated_at\": \"2026-10-11T01:21:08Z\",\n \"run_started_at\": \"2026-10-11T01:20:59Z\"\n },\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"registry_proof_sha256\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"source_render_change_only\": \"Deployment/informed-decision spec.template.spec.containers[0].image\",\n \"runtime_configmap_unchanged\": \"informed-decision-runtime-6c221878d051\",\n \"installed_image_execution\": {\n \"immutable_registry_artifact_pulled_anonymously\": true,\n \"UID\": 10001,\n \"GID\": 10001,\n \"policy_file_UID\": 0,\n \"policy_file_mode\": \"0644\",\n \"purpose_variants\": 10,\n \"binding_forms_allowed\": 2,\n \"advisory_or_malformed_refused\": 8,\n \"network\": \"none\",\n \"read_only\": true,\n \"synthetic_transport\": true,\n \"native_PDP_test\": false\n },\n \"scan_summary_sha256\": \"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\",\n \"historical_failed_runs_retained\": [\n \"f66de505/task11482/run1\",\n \"acecad887/task11483/run2\"\n ],\n \"native_hosting_changed\": false,\n \"native_backup_restore_executed\": false,\n \"human_approval\": false,\n \"evidence_file_sha256\": {\n \"image-manifest.json\": \"978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb\",\n \"image-config.json\": \"4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10\",\n \"base-image-config.json\": \"b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00\",\n \"registry-proof.json\": \"5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213\",\n \"trivy-full.json\": \"f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e\",\n \"sbom.cdx.json\": \"a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d\",\n \"base-trivy-full.json\": \"d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80\",\n \"check_installed.py\": \"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\",\n \"verify_registry.py\": \"413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"review-refinement.json\": \"ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75\",\n \"test_change_guard.py\": \"da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f\",\n \"test_sqlite_readonly.py\": \"c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323\",\n \"test_preflight_optimization.py\": \"a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d\",\n \"initial-approved-bc6494cd/sqlite_readonly.py\": \"eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38\"\n },\n \"version2_source_pointer_refinement\": {\n \"original_receipt_sha256\": \"8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2\",\n \"original_receipt_archive\": \"initial-approved-bc6494cd/published-verification.json\",\n \"reason\": \"Keep historical original pre-open checker hash bound to exact archived original bytes; current version2 checker is independently direct-packet/plan bound. Actual image/registry/scan/SBOM proof unchanged; no new artifact verification or native version2 action claimed.\"\n }\n}\n" + }, + { + "item_id": "registry-proof-json", + "media_type": "application/json", + "content": "{\n \"image_digest\": \"sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"base_image_digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"base_layer_bytes_identical\": true,\n \"layer_media_type_conversion\": \"OCI gzip to Docker gzip, same digest and size\",\n \"base_runtime_config_semantics_identical\": true,\n \"legacy_builder_config_additions\": {\n \"Hostname\": \"\",\n \"Domainname\": \"\",\n \"AttachStdin\": false,\n \"AttachStdout\": false,\n \"AttachStderr\": false,\n \"Tty\": false,\n \"OpenStdin\": false,\n \"StdinOnce\": false,\n \"Cmd\": null,\n \"Volumes\": null,\n \"OnBuild\": null,\n \"Image\": \"sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883\"\n },\n \"base_rootfs_prefix_identical\": true,\n \"overlay_regular_files\": [\n \"opt/venv/lib/python3.12/site-packages/informed_decision/policy.py\"\n ],\n \"overlay_directories\": [\n \"opt\",\n \"opt/venv\",\n \"opt/venv/lib\",\n \"opt/venv/lib/python3.12\",\n \"opt/venv/lib/python3.12/site-packages\",\n \"opt/venv/lib/python3.12/site-packages/informed_decision\"\n ],\n \"policy_sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"policy_mode\": \"0644\",\n \"base_user\": \"10001:10001\",\n \"source_scope_labels\": {\n \"org.opencontainers.image.revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"org.opencontainers.image.base.digest\": \"sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"social.coulomb.source.policy.sha256\": \"9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62\",\n \"social.coulomb.release.scope\": \"INFD-WP-0009-T04/purpose-overlay-v1\"\n },\n \"registry_read_route\": \"anonymous public scoped bearer challenge, no token retention\",\n \"image_executed\": false,\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false\n}\n" + }, + { + "item_id": "security-summary-json", + "media_type": "application/json", + "content": "{\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\",\n \"source_revision\": \"3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168\",\n \"scanner\": \"aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969\",\n \"version\": \"0.74.0\",\n \"db_metadata\": {\n \"Version\": 2,\n \"NextUpdate\": \"2026-10-11T18:59:50.889010572Z\",\n \"UpdatedAt\": \"2026-10-10T18:59:50.889010923Z\",\n \"DownloadedAt\": \"2026-10-10T23:32:32.380033131Z\"\n },\n \"suppression\": false,\n \"ignore_unfixed\": false,\n \"severity_filter\": null,\n \"package_count\": 44,\n \"findings_by_severity\": {\n \"MEDIUM\": 1\n },\n \"findings\": [\n {\n \"id\": \"CVE-2026-85091\",\n \"package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"severity\": \"MEDIUM\"\n }\n ],\n \"coverage_limits\": [\n \"Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages\",\n \"Known findings asof pinnedDB, not claim absence of unknown vulnerabilities\"\n ],\n \"high_critical\": 0,\n \"same_scanner_actual_base_scan_findings_identical\": true,\n \"base_scan_file\": \"base-trivy-full.json\"\n}\n" + }, + { + "item_id": "execution-bundle-json", + "media_type": "application/json", + "content": "{\n \"kind\": \"informed-decision.supervised-execution-source-bundle\",\n \"version\": 2,\n \"proposal_id\": \"INFD-WP-0009-T04/purpose-overlay-v1\",\n \"files\": {\n \"README.md\": {\n \"sha256\": \"51b56c8ec2f30ad62f6cd09732c0f73dd7b5ebf2081320223c85bbcbf00d15a9\",\n \"content\": \"# Version2 protected existing-snapshot rescue — prepared, unapproved\\n\\nOriginal approved source bc6494cd completed drill-backup, then drill-copy failed before creating a local snapshot. Original journal drill-copy remains UNCERTAIN. Metadata-only capture proves exact unchanged main19537920bytes/SHA8756..., WAL0 and privateSHM32768. Source closes SQLite connections explicitly; immutable reads are only for the frozen main snapshot with exact prior digest/size/private identity and no WAL frames. Live source and offline pre/post-admin reads remain mode=ro/query_only WAL-aware; immutable is never a live DB or schema-migration shortcut. Sidecars remain retained, never deleted/checkpointed.\\n\\nFresh founder acceptance of the exact memo version2 is required before any rescue or continuation. Old version1 acceptance cannot pass authority checks. Root must freshly authenticate actual confirmed person/platform-root ACCEPT at the fixed native origin before each phase; protected receipt checking is supervised bookkeeping, not an authenticated signed/autonomous grant. No new native operation has run in this preparation.\\n\\nFixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify; rollback → rollback-verify only after recorded new release attempt. New rescue-execution-journal-r1.json and rescue-execution-r1.lock coexist with the unchanged original execution-journal.json. They hash-link its exact original approved identity, COMPLETE backup and UNCERTAIN copy attempt IDs/results. No extra original phase or release is allowed; original journal hash is checked before and after each new phase. No old drill-copy retry/overwrite or synthesized completed phase.\\n\\nBefore rescue, original local drill.sqlite/cutover.sqlite must be absent, restore volume must be absent, and local engine bnt-lap001/current native oldimage7f5/source7db/sealedDeployment+CM/PVC/originalPodUID must match. The old backup admin already exited after uniquely creating the private fixed snapshot path; the only later original access was WAL-aware readonly inspection, with no snapshot writer. Main hash, private identities and absent/zero WAL are checked before/after immutable inspection and copy. Original private SHM is indexing and is retained unchanged. Nonempty WAL, changed hash/metadata, missing failed journal, missing origin or any unverified outcome stops rescue. No new native backup is made for the drill. Binary snapshot bytes flow only into a new0600 localfile, never chat/log/packet. Same rescue-phase retry is refused after any attempted outcome.\\n\\nOffline verification explicitly consumes COMPLETE drill-copy-rescue-r1 result, not the old UNCERTAIN drill-copy. Existing exact isolated new-volume UID0/CAP_CHOWN initializer, followed by UID10001 readonly/admin/post-admin checks and retained original SHA, remains bounded networknone/readonlyroot/CPU1/128Mi with no host/nativePVC/runtimeconfig/token mounts. Only the disposable copy volume can be removed. Cutover snapshot is the distinct already-scoped new cutover.sqlite; rescue never overwrites drill.sqlite or creates another drill backup.\\n\\nFour committed owner render Git blobs and helper/case hashes must match exact final source HEAD. ManualApplication rejects any automated configuration including {} or source overrides. Source-pin Application.operation uses server dry-run and UID/resourceVersion/source CAS, Deployment-only/prune=false; no whole-app sync. Rollback dispatch has no failing-candidate Pod/DB dependency; separate recovery proof checks oldimage Ready1/scopedoperation/schema5 retainedlatestDB. All phases including recovery/verification must begin by2026-10-12T23:59:59Z; after expiry obtain a fresh founder decision. No expiry controller or implicit extension.\\n\\nImage763c/policy9d7c and known inherited fixable MEDIUM remain unchanged; owner T05 dueOct18. Ten installed checks use synthetic transport/native_provider=false and do not fulfill separate actual-provider T04 gate. Preserve original acceptance/backup/failure/history in this same trial. Twenty-six mocked/source executor regressions pass; no actual DB/admin/native command during tests/preparation.\\n\\nNative publication route: POST existing source /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions with expected_version1 and exact memo2/documents/summary, then publications/review-requests version2. Fresh source readback must prove currentversion1 is unbound before revision; bound/different source stops. Intake/register refuse version2 as designed and are not used. Review integration creates a NEW review-ID at its own version1; founder disposition memo_version1 belongs to that new review. Root fresh outcomes must be queried for SOURCE version2, exact newreviewID/memoSHA and confirmed nested personapproval. Receipt outcome_query pins that sourceversion2 route; it does not authenticate by itself.\\n\"\n },\n \"actuator.py\": {\n \"sha256\": \"86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2\",\n \"content\": \"\\\"\\\"\\\"One fixed supervised phase; never run this during source preparation.\\\"\\\"\\\"\\nimport argparse\\nimport hashlib\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport re\\nimport selectors\\nimport stat\\nimport subprocess\\nimport sys\\nimport time\\n\\nif sys.flags.optimize:\\n raise SystemExit('optimized interpreter refused')\\n\\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\nROOT = Path(__file__).resolve().parent\\nCASE = ROOT.parent\\nOWNER = Path('/home/worsch/informed-decision')\\nCUSTODIAN = Path('/home/worsch/the-custodian')\\nCUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'\\nSOCKET = 'unix:///var/run/docker.sock'\\nIMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\\nVOLUME = 'infd-purpose-r1-restore-20261011'\\nMAX_BYTES = 512 * 1024**2\\n\\n\\ndef run(argv, body=None, timeout=90):\\n return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)\\n\\n\\ndef json_result(result):\\n try:\\n value = json.loads(result.stdout)\\n except (ValueError, TypeError):\\n raise ValueError('safe phase receipt unavailable; outcome uncertain') from None\\n require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,\\n 'phase did not verify complete; raw output withheld; no retry')\\n permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',\\n 'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',\\n 'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',\\n 'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',\\n 'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',\\n 'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',\\n 'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',\\n 'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',\\n 'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}\\n require(set(value) <= permitted, 'unexpected output fields withheld')\\n from receipt_safety import counts\\n for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):\\n if name in value:\\n counts(value[name])\\n for name in ('snapshot_sha256', 'client_diff_sha256'):\\n if name in value:\\n require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')\\n if 'snapshot_bytes' in value:\\n require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,\\n 'invalid output size withheld')\\n if 'snapshot_file' in value:\\n require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')\\n return value\\n\\n\\ndef docker(argv, body=None, timeout=120):\\n return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,\\n body=body, timeout=timeout)\\n\\n\\ndef remote(phase, revision, approved, snapshot_identity=None):\\n # Fixed module imported only after main verifies every executor source hash.\\n from native_program import PROGRAM\\n payload = {'snapshot_identity': snapshot_identity, 'phase': phase, 'source_revision': revision, 'approval': approved,\\n 'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),\\n 'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),\\n 'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),\\n 'purpose_checks': (CASE / 'check_installed.py').read_text(),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text()}\\n script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))\\n\\n\\ndef copy_snapshot(phase, revision, approved, journal):\\n prior = (journal.data['identity']['recovery_anchor']['backup_result']\\n if phase == 'drill-copy-rescue-r1' else journal.data['phases']['cutover-backup']['result'])\\n metadata = remote(phase, revision, approved, snapshot_identity=prior)\\n for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):\\n require(metadata[key] == prior[key], 'closed frozen snapshot changed')\\n name = metadata['snapshot_file']\\n require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,\\n 'fixed bounded snapshot required')\\n pod = metadata['pod_name']\\n require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')\\n local = CUSTODY / name\\n fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)\\n # Binary snapshot stdout goes only to a private file, never tool/chat/log output.\\n # Snapshot schema/count metadata was validated before opening this destination.\\n with os.fdopen(fd, 'wb') as destination:\\n command = ('kubectl exec -n informed-decision ' + pod +\\n ' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)\\n transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,\\n stderr=subprocess.DEVNULL)\\n selector = selectors.DefaultSelector()\\n selector.register(transfer.stdout, selectors.EVENT_READ)\\n deadline = time.monotonic() + 150\\n received = 0\\n try:\\n while True:\\n remaining = deadline - time.monotonic()\\n require(remaining > 0 and selector.select(remaining), 'private transfer timed out')\\n block = os.read(transfer.stdout.fileno(), 1024**2)\\n if not block:\\n break\\n received += len(block)\\n require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,\\n 'private copy exceeds frozen snapshot size')\\n destination.write(block)\\n transfer.wait(timeout=max(1, deadline - time.monotonic()))\\n finally:\\n selector.close()\\n transfer.stdout.close()\\n if transfer.poll() is None:\\n transfer.kill()\\n transfer.wait()\\n destination.flush()\\n os.fsync(destination.fileno())\\n private(local)\\n require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']\\n and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')\\n # Re-read identity/hash after transfer. This is verification, not a write retry.\\n after = remote(phase, revision, approved, snapshot_identity=prior)\\n require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],\\n 'source identity/snapshot changed during transfer')\\n return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}\\n\\n\\ndef offline_verify(journal):\\n from receipt_safety import counts\\n snapshot = CUSTODY / 'drill.sqlite'\\n private(snapshot)\\n previous = journal.data['phases']['drill-copy-rescue-r1']['result']\\n require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')\\n identity = docker(['info', '--format', '{{json .Name}}'])\\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\\n 'local offline Docker engine identity changed')\\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\\n 'disposable volume absence not verified')\\n nonce = journal.data['phases']['offline-verify']['attempt_id']\\n labels = {'informed-decision.case': 'infd-purpose-20261011-r1',\\n 'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}\\n created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',\\n '--label', 'informed-decision.attempt=' + nonce,\\n '--label', 'informed-decision.use=offline-restore-only', VOLUME])\\n require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'new volume identity unavailable')\\n volume = json.loads(inspected.stdout)\\n require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels\\n and volume[0].get('Driver') == 'local' and not volume[0].get('Options')\\n and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')\\n identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}\\n journal.note('offline-verify', 'created_volume_identity', identity)\\n # One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.\\n # No host/live PVC/config/token mount exists; this detail needs packet review.\\n initializer = \\\"\\\"\\\"import hashlib,os,stat,sys\\nif sys.flags.optimize:raise RuntimeError('optimized interpreter refused')\\nfolder='/restore';expected=EXPECTED\\nif os.listdir(folder):raise ValueError('new empty private volume required')\\nos.chmod(folder,0o700)\\nfd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)\\ndigest=hashlib.sha256();size=0\\nwith os.fdopen(fd,'wb') as target:\\n while True:\\n block=sys.stdin.buffer.read(1024**2)\\n if not block:break\\n size+=len(block)\\n if size>512*1024**2:raise ValueError('private restore size exceeds bound')\\n target.write(block);digest.update(block)\\n target.flush();os.fsync(target.fileno())\\nif digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')\\nos.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)\\nprint('{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}')\\n\\\"\\\"\\\".replace('EXPECTED', repr(previous['snapshot_sha256']))\\n with snapshot.open('rb') as source:\\n argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,\\n 'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',\\n '--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',\\n '--entrypoint', 'python', IMAGE, '-c', initializer]\\n copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)\\n json_result(copied)\\n options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',\\n '--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',\\n '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']\\n readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')\\n checked = counts(json.loads(readonly.stdout))\\n require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')\\n admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,\\n 'inspect', '--db', '/restore/review.sqlite'])\\n require(admin.returncode == 0, 'offline admin result uncertain')\\n admin_counts = json.loads(admin.stdout)\\n require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},\\n 'offline admin changed frozen snapshot counters')\\n # Admin Store construction must not silently alter schema/integrity/counters.\\n post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],\\n (CASE / 'sqlite_readonly.py').read_text())\\n require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')\\n post_checked = counts(json.loads(post.stdout))\\n require(post_checked == checked == previous['snapshot_readonly'],\\n 'offline admin altered frozen snapshot proof')\\n private(snapshot)\\n require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')\\n return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,\\n 'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,\\n 'created_volume_identity': identity,\\n 'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,\\n 'service_entrypoint_started': False, 'original_snapshot_retained': True}\\n\\n\\ndef cleanup_offline(journal):\\n inspected = docker(['volume', 'inspect', VOLUME])\\n require(inspected.returncode == 0, 'owned disposable volume identity unverified')\\n value = json.loads(inspected.stdout)\\n expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']\\n require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected\\n and not value[0].get('Options'), 'volume ownership/recreation changed')\\n removed = docker(['volume', 'rm', VOLUME])\\n require(removed.returncode == 0 and removed.stdout.strip() == VOLUME\\n and docker(['volume', 'inspect', VOLUME]).returncode != 0,\\n 'cleanup outcome ambiguous; do not retry')\\n return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,\\n 'native_and_offcluster_original_snapshots_retained': True}\\n\\n\\ndef main():\\n parser = argparse.ArgumentParser(description=__doc__)\\n parser.add_argument('--phase', choices=PHASES, required=True)\\n parser.add_argument('--root-authority-receipt', type=Path, required=True)\\n parser.add_argument('--root-native-outcome', type=Path, required=True)\\n parser.add_argument('--source-revision', required=True)\\n args = parser.parse_args()\\n require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')\\n and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),\\n 'fixed supervised receipt paths required')\\n require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')\\n # Verify all prepared executor/input bytes before reading authority or dispatching.\\n plan = json.loads((ROOT / 'execution-plan.json').read_text())\\n require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},\\n 'fixed executor sources required')\\n require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',\\n 'deploy/lifecycle/service.candidate.json',\\n 'deploy/lifecycle/kustomization.yaml',\\n 'deploy/lifecycle/registries.candidate.json'},\\n 'fixed owner image sources required')\\n for relative, digest in plan['executor_files'].items():\\n target = ROOT / relative\\n require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')\\n for relative, digest in plan['case_files'].items():\\n require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,\\n 'case source path escaped')\\n target = CASE / relative\\n require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')\\n for relative, digest in plan['owner_source_files'].items():\\n target = OWNER / relative\\n require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')\\n committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],\\n capture_output=True)\\n require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,\\n 'committed owner render source differs from approved inputs')\\n head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])\\n require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')\\n from authority_journal import Journal, authority, original_anchor\\n private(args.root_authority_receipt)\\n private(args.root_native_outcome)\\n receipt = json.loads(args.root_authority_receipt.read_text())\\n require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')\\n require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),\\n 'root verified executor plan differs')\\n approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),\\n args.source_revision, args.phase)\\n parent = CUSTODY.parent\\n private(parent, directory=True)\\n ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])\\n require(ignored.returncode == 0, 'offcluster custody is not ignored')\\n require(CUSTODY.exists(), 'original protected custody must already exist')\\n private(CUSTODY, directory=True)\\n capacity = os.statvfs(CUSTODY)\\n require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,\\n 'independent protected custody headroom insufficient')\\n os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)\\n private(CUSTODY / 'empty-docker-config', directory=True)\\n require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')\\n anchor = original_anchor(CUSTODY, plan['recovery']['original_anchor'],\\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\\n plan['recovery']['original_identity'])\\n if args.phase == 'drill-copy-rescue-r1':\\n require(not os.path.lexists(CUSTODY / 'drill.sqlite')\\n and not os.path.lexists(CUSTODY / 'cutover.sqlite'), 'rescue destination must be absent')\\n identity = docker(['info', '--format', '{{json .Name}}'])\\n require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',\\n 'local engine identity changed')\\n listed = docker(['volume', 'ls', '--format', '{{.Name}}'])\\n require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),\\n 'existing restore volume forbids rescue')\\n journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,\\n 'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json'),\\n 'recovery_anchor': anchor})\\n try:\\n journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.\\n if args.phase in ('drill-copy-rescue-r1', 'cutover-copy'):\\n result = copy_snapshot(args.phase, args.source_revision, approved, journal)\\n elif args.phase == 'offline-verify':\\n result = offline_verify(journal)\\n elif args.phase == 'cleanup-offline':\\n result = cleanup_offline(journal)\\n else:\\n result = remote(args.phase, args.source_revision, approved)\\n require(original_anchor(CUSTODY, plan['recovery']['original_anchor'],\\n json.loads((CASE / 'original-approved-drill-backup.json').read_text()),\\n plan['recovery']['original_identity']) == anchor,\\n 'original failed journal changed during new phase')\\n journal.finish(args.phase, result)\\n print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.\\n except BaseException as error:\\n safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,\\n 'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',\\n 'raw_output_withheld': True}\\n if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':\\n journal.finish(args.phase, safe)\\n print(json.dumps(safe))\\n raise SystemExit(1) from None\\n finally:\\n journal.close()\\n\\n\\nif __name__ == '__main__':\\n try:\\n main()\\n except Exception:\\n raise SystemExit('supervised execution refused before phase; raw output withheld') from None\\n\"\n },\n \"authority_journal.py\": {\n \"sha256\": \"0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68\",\n \"content\": \"\\\"\\\"\\\"Supervised receipt bookkeeping, not an authenticated approval provider.\\\"\\\"\\\"\\nimport datetime\\nimport fcntl\\nimport hashlib\\nimport json\\nimport os\\nimport re\\nfrom pathlib import Path\\nimport stat\\nimport uuid\\n\\nFOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}\\nMEMO_ID = 'infd-20261011-purpose-overlay-r1'\\nPROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'\\nPHASES = ('drill-copy-rescue-r1', 'offline-verify', 'cleanup-offline',\\n 'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')\\n\\n\\ndef require(value, reason):\\n if not value:\\n raise ValueError(reason)\\n\\n\\ndef sha(path):\\n digest = hashlib.sha256()\\n with Path(path).open('rb') as stream:\\n for block in iter(lambda: stream.read(1024**2), b''):\\n digest.update(block)\\n return digest.hexdigest()\\n\\n\\ndef private(path, directory=False):\\n info = Path(path).lstat()\\n require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))\\n and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)\\n and (directory or info.st_nlink == 1), 'private owned custody required')\\n\\n\\ndef authority(receipt, outcome, memo_sha, source_revision, phase, now=None):\\n \\\"\\\"\\\"Root must freshly verify native outcome at fixed ORIGIN outside this helper.\\n\\n Receipt files/flags are not signed grants. This function checks the exact\\n supervised receipt relation; existing harness/founder authority remains the\\n actual permission boundary. It never authenticates a caller as human.\\n \\\"\\\"\\\"\\n now = now or datetime.datetime.now(datetime.timezone.utc)\\n require(phase in PHASES, 'fixed phase required')\\n require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID\\n and receipt.get('memo_version') == 2 and receipt.get('memo_sha256') == memo_sha\\n and receipt.get('source_revision') == source_revision\\n and receipt.get('activation') == 'APPROVED'\\n and receipt.get('authority_mode') == 'ADMINISTER'\\n and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'\\n and receipt.get('verification_method') == 'root-fixed-origin-native-readback'\\n and receipt.get('runtime_authenticated_grant') is False\\n and receipt.get('outcome_query') == '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\\n 'exact externally verified supervised receipt required')\\n verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))\\n require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,\\n 'fresh root native readback required before every phase')\\n deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')\\n require(now < deadline, 'approved execution window expired')\\n require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False\\n and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')\\n review_id = outcome['review']['memo_id']\\n require(review_id == receipt.get('review_memo_id'), 'native review identity changed')\\n accepted = [x for x in outcome.get('dispositions', [])\\n if x.get('submission_state') == 'confirmed'\\n and x.get('disposition', {}).get('verb') == 'accept'\\n and x['disposition'].get('memo_version') == 1]\\n require(len(accepted) == 1, 'one confirmed founder acceptance required')\\n accepted = accepted[0]['disposition']\\n require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id\\n and accepted.get('approval_id') == receipt.get('approval_id')\\n and accepted.get('id') == receipt.get('disposition_id')\\n and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')\\n require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None\\n and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None\\n and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,\\n 'native disposition identifiers are malformed')\\n accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))\\n require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')\\n return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}\\n\\n\\ndef original_anchor(parent, expected, backup_result, original_identity):\\n \\\"\\\"\\\"Read only sanitized original journal; never rewrite/synthesize its phases.\\\"\\\"\\\"\\n path = Path(parent) / 'execution-journal.json'\\n private(path)\\n require(sha(path) == expected['original_journal_sha256'], 'original journal bytes changed')\\n original = json.loads(path.read_text())\\n require(original.get('identity') == original_identity, 'original approved identity changed')\\n phases = original.get('phases', {})\\n require(set(phases) == {'drill-backup', 'drill-copy'}, 'unexpected original action or rollout')\\n for name, fields in expected['phase_metadata'].items():\\n require(all(phases[name].get(key) == value for key,value in fields.items()),\\n 'original failed/completed attempt identity changed')\\n require(phases['drill-backup'].get('result') == backup_result\\n and backup_result.get('all_checks_pass') is True\\n and phases['drill-copy'].get('result', {}).get('all_checks_pass') is False,\\n 'original backup/copy outcome changed')\\n require(backup_result.get('snapshot_sha256') == expected['snapshot_sha256']\\n and backup_result.get('snapshot_bytes') == expected['snapshot_bytes']\\n and backup_result.get('pod_uid') == 'e8561ae0-4b09-4455-924d-64c27b625fc7',\\n 'original frozen snapshot identity changed')\\n require(sha(path) == expected['original_journal_sha256'], 'original journal changed during read')\\n return {'original_journal_sha256': expected['original_journal_sha256'],\\n 'original_copy_attempt_id': phases['drill-copy']['attempt_id'],\\n 'original_backup_attempt_id': phases['drill-backup']['attempt_id'],\\n 'backup_result': backup_result, 'old_uncertain_phase_retained': True}\\n\\n\\nclass Journal:\\n def __init__(self, parent, identity):\\n self.parent = Path(parent)\\n private(self.parent, directory=True)\\n self.path = self.parent / 'rescue-execution-journal-r1.json'\\n self.lock = os.open(self.parent / 'rescue-execution-r1.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)\\n fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)\\n private(self.parent / 'rescue-execution-r1.lock')\\n if self.path.exists():\\n private(self.path)\\n self.data = json.loads(self.path.read_text())\\n require(self.data['identity'] == identity, 'journal case/source identity changed')\\n else:\\n self.data = {'identity': identity, 'phases': {}}\\n self.save()\\n\\n def save(self):\\n temporary = self.parent / 'execution-journal.new'\\n fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)\\n try:\\n with os.fdopen(fd, 'w') as stream:\\n json.dump(self.data, stream, indent=2)\\n stream.write('\\\\n')\\n stream.flush()\\n os.fsync(stream.fileno())\\n os.replace(temporary, self.path)\\n directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)\\n try:\\n os.fsync(directory)\\n finally:\\n os.close(directory)\\n except BaseException:\\n # Retain evidence rather than overwriting an uncertain durable intent.\\n raise\\n\\n def start(self, phase, approval):\\n require(phase not in self.data['phases'], 'already attempted phase; no retry')\\n require(phase in PHASES, 'fixed rescue or remaining phase required')\\n predecessors = dict(zip(PHASES[1:7], PHASES[:6]))\\n predecessors['rollback-verify'] = 'rollback'\\n if phase in predecessors:\\n require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',\\n 'preceding phase is not verified complete')\\n if phase == 'rollback':\\n require('release' in self.data['phases'], 'rollback requires a recorded release attempt')\\n self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,\\n 'attempt_id': str(uuid.uuid4()),\\n 'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}\\n self.save()\\n\\n def note(self, phase, key, value):\\n require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')\\n self.data['phases'][phase][key] = value\\n self.save()\\n\\n def finish(self, phase, result):\\n entry = self.data['phases'][phase]\\n require(entry['state'] == 'RUNNING', 'phase intent missing')\\n entry['result'] = result\\n entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'\\n self.save()\\n\\n def close(self):\\n os.close(self.lock)\\n\"\n },\n \"execution-plan.json\": {\n \"sha256\": \"9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258\",\n \"content\": \"{\\n \\\"kind\\\": \\\"informed-decision.supervised-mechanical-release-plan\\\",\\n \\\"version\\\": 2,\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"trial_id\\\": \\\"infd-purpose-20261011-r1\\\",\\n \\\"state\\\": \\\"prepared-unapproved\\\",\\n \\\"executor_files\\\": {\\n \\\"actuator.py\\\": \\\"86b67d1abad6af2a8c49528fe125a5bab944975d3e801826c511ee88846571b2\\\",\\n \\\"authority_journal.py\\\": \\\"0535975ae631219f90fce7e52f8b54e61e8afd4ef68bb7473863478f0f519f68\\\",\\n \\\"native_program.py\\\": \\\"788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91\\\",\\n \\\"receipt_safety.py\\\": \\\"5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b\\\"\\n },\\n \\\"case_files\\\": {\\n \\\"change_guard.py\\\": \\\"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\\\",\\n \\\"sqlite_readonly.py\\\": \\\"9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509\\\",\\n \\\"preflight-inputs.json\\\": \\\"03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b\\\",\\n \\\"sealed-live-deployment.json\\\": \\\"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\\\",\\n \\\"sealed-native-dependencies.json\\\": \\\"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\\\",\\n \\\"candidate-deployment.json\\\": \\\"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\\\",\\n \\\"rollback-deployment.json\\\": \\\"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\\\",\\n \\\"check_installed.py\\\": \\\"a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad\\\",\\n \\\"published-verification.json\\\": \\\"e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd\\\",\\n \\\"security-summary.json\\\": \\\"0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44\\\",\\n \\\"original-approved-drill-backup.json\\\": \\\"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\\\",\\n \\\"original-approved-drill-copy-failure.json\\\": \\\"fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56\\\",\\n \\\"original-journal-sanitized-anchor.json\\\": \\\"988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454\\\"\\n },\\n \\\"owner_source_files\\\": {\\n \\\"deploy/lifecycle/admission.candidate.json\\\": \\\"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\\\",\\n \\\"deploy/lifecycle/service.candidate.json\\\": \\\"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\\\",\\n \\\"deploy/lifecycle/kustomization.yaml\\\": \\\"1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47\\\",\\n \\\"deploy/lifecycle/registries.candidate.json\\\": \\\"9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e\\\"\\n },\\n \\\"candidate_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a\\\",\\n \\\"prior_image\\\": \\\"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\\",\\n \\\"source_revision\\\": \\\"must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs\\\",\\n \\\"phases\\\": [\\n \\\"drill-copy-rescue-r1\\\",\\n \\\"offline-verify\\\",\\n \\\"cleanup-offline\\\",\\n \\\"cutover-backup\\\",\\n \\\"cutover-copy\\\",\\n \\\"release\\\",\\n \\\"verify\\\",\\n \\\"rollback\\\",\\n \\\"rollback-verify\\\"\\n ],\\n \\\"authorization\\\": \\\"fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant\\\",\\n \\\"execute_by\\\": \\\"2026-10-12T23:59:59Z\\\",\\n \\\"raw_output_withheld\\\": true,\\n \\\"native_data_or_workload_action_executed\\\": false,\\n \\\"deadline_semantics\\\": \\\"All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window.\\\",\\n \\\"recovery\\\": {\\n \\\"original_anchor\\\": {\\n \\\"original_journal_sha256\\\": \\\"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\\\",\\n \\\"phase_metadata\\\": {\\n \\\"drill-backup\\\": {\\n \\\"state\\\": \\\"COMPLETE\\\",\\n \\\"attempt_id\\\": \\\"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:38:45.310653+00:00\\\"\\n },\\n \\\"drill-copy\\\": {\\n \\\"state\\\": \\\"UNCERTAIN\\\",\\n \\\"attempt_id\\\": \\\"329ef190-1692-4246-b953-e6a59664abcc\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:39:50.198740+00:00\\\"\\n }\\n },\\n \\\"frozen_backup_receipt_sha256\\\": \\\"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\\\",\\n \\\"snapshot_sha256\\\": \\\"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\\\",\\n \\\"snapshot_bytes\\\": 19537920,\\n \\\"off_cluster_file_exists\\\": false,\\n \\\"old_uncertain_retry_authorized\\\": false\\n },\\n \\\"original_identity\\\": {\\n \\\"proposal\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"source_revision\\\": \\\"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\\\",\\n \\\"memo_sha256\\\": \\\"506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937\\\",\\n \\\"plan_sha256\\\": \\\"f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6\\\"\\n },\\n \\\"new_journal\\\": \\\"rescue-execution-journal-r1.json\\\",\\n \\\"new_phase\\\": \\\"drill-copy-rescue-r1\\\",\\n \\\"old_uncertain_phase_overwrite_or_retry\\\": false,\\n \\\"new_snapshot_backup\\\": false,\\n \\\"snapshot_or_sidecar_mutation\\\": false,\\n \\\"mapping\\\": \\\"offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal\\\"\\n },\\n \\\"source_memo_version\\\": 2,\\n \\\"native_review_memo_version\\\": 1\\n}\\n\"\n },\n \"native_program.py\": {\n \"sha256\": \"788dc99f7edfbfd542a3bb08fc31f60caf4f8fd5d654a6a91b45e197ecff9f91\",\n \"content\": \"\\\"\\\"\\\"Fixed version2 recovery remote source; requires fresh exact acceptance.\\\"\\\"\\\"\\nPROGRAM = '\\\\nimport copy,datetime,hashlib,json,os,re,subprocess,sys\\\\nif sys.flags.optimize:raise RuntimeError(\\\\'optimized interpreter refused\\\\')\\\\npayload=json.loads(__PAYLOAD__)\\\\nexec(__GUARD__)\\\\nphase=payload[\\\\'phase\\\\']\\\\nif phase not in (\\\\'cutover-backup\\\\',\\\\'drill-copy-rescue-r1\\\\',\\\\'cutover-copy\\\\',\\\\'release\\\\',\\\\'verify\\\\',\\\\'rollback\\\\',\\\\'rollback-verify\\\\'):raise ValueError(\\\\'fixed native phase required\\\\')\\\\ndeadline=datetime.datetime.fromisoformat(\\\\'2026-10-12T23:59:59+00:00\\\\')\\\\ndef require(value,reason):\\\\n if not value:raise ValueError(reason)\\\\nrequire(datetime.datetime.now(datetime.timezone.utc)0 and size<=512*1024**2 and free>=size*(2 if action==\\\\'drill-backup\\\\' else 1)+16*1024**2,\\\\'bounded native snapshot capacity required\\\\')\\\\n if action==\\\\'drill-backup\\\\':\\\\n require(not os.path.lexists(folder),\\\\'native case directory must be unique\\\\')\\\\n os.mkdir(folder,0o700);os.chmod(folder,0o700)\\\\n private(folder,True)\\\\n filename=\\\\'drill.sqlite\\\\' if action==\\\\'drill-backup\\\\' else \\\\'cutover.sqlite\\\\';output=folder+\\\\'/\\\\'+filename\\\\n require(not os.path.lexists(output),\\\\'snapshot output must be unique\\\\')\\\\n admin=subprocess.run([\\\\'informed-decision-admin\\\\',\\\\'backup\\\\',\\\\'--db\\\\',db,\\\\'--output\\\\',output],capture_output=True,text=True,timeout=120)\\\\n require(admin.returncode==0 and json.loads(admin.stdout)=={\\\\'status\\\\':\\\\'backed_up\\\\',\\\\'consistent_snapshot\\\\':True},\\\\'backup completion not verified; do not retry\\\\')\\\\n private(output)\\\\n for suffix in (\\\\'-wal\\\\',):\\\\n require(not os.path.exists(output+suffix) or os.stat(output+suffix).st_size==0,\\\\'snapshot has WAL frames; immutable read refused\\\\')\\\\n digest=hashlib.sha256()\\\\n with open(output,\\\\'rb\\\\') as stream:\\\\n for block in iter(lambda:stream.read(1024**2),b\\\\'\\\\'):digest.update(block)\\\\n frozen_digest=digest.hexdigest()\\\\n snapshot=counts(inspect_closed_snapshot(output,frozen_digest))\\\\n size=os.stat(output).st_size;require(0 10**12\\n for number in value[group].values()):\\n raise ValueError('count-only receipt values refused')\\n return value\\n\"\n },\n \"root-authority-receipt-template.json\": {\n \"sha256\": \"db28d03e3c46b4de52dc404c912054483f4a2aaa6c4f476b7892cab2a5f408d4\",\n \"content\": \"{\\n \\\"proposal_id\\\": \\\"INFD-WP-0009-T04/purpose-overlay-v1\\\",\\n \\\"memo_id\\\": \\\"infd-20261011-purpose-overlay-r1\\\",\\n \\\"memo_version\\\": 2,\\n \\\"memo_sha256\\\": null,\\n \\\"source_revision\\\": null,\\n \\\"activation\\\": \\\"PENDING\\\",\\n \\\"authority_mode\\\": \\\"ADMINISTER\\\",\\n \\\"target\\\": \\\"realm:kubernetes/railiance01/informed-decision\\\",\\n \\\"verification_method\\\": \\\"root-fixed-origin-native-readback\\\",\\n \\\"runtime_authenticated_grant\\\": false,\\n \\\"verified_at\\\": null,\\n \\\"accepted_at\\\": null,\\n \\\"review_memo_id\\\": null,\\n \\\"approval_id\\\": null,\\n \\\"disposition_id\\\": null,\\n \\\"native_outcome_sha256\\\": null,\\n \\\"executor_plan_sha256\\\": \\\"4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85\\\",\\n \\\"outcome_query\\\": \\\"/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2\\\",\\n \\\"review_memo_version\\\": 1\\n}\\n\"\n },\n \"test_execution.py\": {\n \"sha256\": \"b250441282513862eeb990b18d01bb1eafe787b934d670a75a2bfaa9f5cfb89c\",\n \"content\": \"\\\"\\\"\\\"Synthetic custody/transport tests. No native data, Docker or cluster action.\\\"\\\"\\\"\\nimport copy\\nimport datetime\\nimport io\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport subprocess\\nimport sys\\nimport tempfile\\nimport unittest\\nfrom unittest.mock import patch\\nfrom contextlib import redirect_stdout\\n\\nimport actuator\\nfrom authority_journal import Journal, authority\\nfrom native_program import PROGRAM\\nfrom receipt_safety import counts\\n\\nCASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')\\nNOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)\\nREVISION = 'e' * 40\\nCOUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,\\n 'lifecycle': {'records': 3, 'events': 8, 'pending': 1},\\n 'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}\\n\\n\\ndef accepted():\\n approval = '11111111-1111-4111-8111-111111111111'\\n review = 'review-22222222-2222-4222-8222-222222222222'\\n disposition = 'disp-33333333-3333-4333-8333-333333333333'\\n receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',\\n 'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 2,\\n 'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',\\n 'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',\\n 'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False, 'outcome_query': '/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=2',\\n 'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',\\n 'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}\\n outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},\\n 'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',\\n 'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,\\n 'approval_id': approval, 'id': disposition,\\n 'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},\\n 'at': receipt['accepted_at']}}]}\\n return receipt, outcome\\n\\n\\nclass AuthorityAndCustody(unittest.TestCase):\\n def test_exact_nested_founder_receipt_not_top_level_approval(self):\\n receipt, outcome = accepted()\\n result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-copy-rescue-r1', NOW)\\n self.assertEqual(result['approval_id'], receipt['approval_id'])\\n\\n def test_pending_stale_wrong_actor_version_and_binding_refuse(self):\\n mutations = [lambda r, o: r.update(activation='PENDING'),\\n lambda r, o: r.update(memo_sha256='changed'),\\n lambda r, o: r.update(source_revision='changed'),\\n lambda r, o: r.update(target='other'),\\n lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),\\n lambda r, o: r.update(verification_method='caller-asserted'),\\n lambda r, o: r.update(runtime_authenticated_grant=True),\\n lambda r, o: o['review'].update(stale=True),\\n lambda r, o: o['review'].update(intake_state='pending'),\\n lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),\\n lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=3),\\n lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),\\n lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n r, o = accepted()\\n mutate(r, o)\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'release', NOW)\\n\\n def test_expired_window_and_unknown_phase_refuse(self):\\n r, o = accepted()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)\\n late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)\\n r['verified_at'] = late.isoformat()\\n with self.assertRaises(ValueError):\\n authority(r, o, 'a' * 64, REVISION, 'rollback', late)\\n\\n def test_durable_intent_precedes_dispatch_and_never_retries(self):\\n with tempfile.TemporaryDirectory() as directory:\\n parent = Path(directory)\\n os.chmod(parent, 0o700)\\n journal = Journal(parent, {'case': 'fixture'})\\n journal.start('drill-copy-rescue-r1', {'approval_id': 'fixture'})\\n self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-copy-rescue-r1']['state'], 'RUNNING')\\n journal.close() # simulated crash before result\\n recovered = Journal(parent, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-copy-rescue-r1', {})\\n with self.assertRaises(ValueError):\\n recovered.start('drill-copy-rescue-r1', {})\\n recovered.close()\\n\\n def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):\\n with tempfile.TemporaryDirectory() as directory:\\n os.chmod(directory, 0o700)\\n j = Journal(directory, {'case': 'fixture'})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n for phase in actuator.PHASES[:5]:\\n j.start(phase, {})\\n j.finish(phase, {'all_checks_pass': True})\\n j.start('release', {})\\n j.finish('release', {'all_checks_pass': False})\\n with self.assertRaises(ValueError):\\n j.start('release', {})\\n with self.assertRaises(ValueError):\\n j.start('verify', {})\\n j.start('rollback', {})\\n j.finish('rollback', {'all_checks_pass': True})\\n j.close()\\n\\n def test_secret_or_unknown_child_output_is_withheld(self):\\n for body in ('not-json', '{\\\"all_checks_pass\\\":true,\\\"token\\\":\\\"private-value\\\"}',\\n '{\\\"all_checks_pass\\\":true,\\\"snapshot_readonly\\\":{\\\"schema_version\\\":5}}'):\\n with self.assertRaises(ValueError):\\n actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))\\n wrong = copy.deepcopy(COUNT)\\n wrong['outbox'] = {'private-row-value': 1}\\n with self.assertRaises(ValueError):\\n counts(wrong)\\n counts(COUNT) # blocked/unresolved counts are not required to be zero.\\n\\n def test_binary_copy_is_bounded_private_and_never_echoed(self):\\n blob = b'synthetic private fixture bytes'\\n digest = __import__('hashlib').sha256(blob).hexdigest()\\n metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),\\n 'snapshot_sha256': digest, 'snapshot_readonly': COUNT,\\n 'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}\\n journal = type('FixtureJournal', (), {'data': {'identity': {'recovery_anchor': {'backup_result': metadata}}}})()\\n real_popen = subprocess.Popen\\n for extra in (b'', b'oversized'):\\n with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:\\n os.chmod(folder, 0o700)\\n output = io.StringIO()\\n\\n def child(*args, **kwargs):\\n return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],\\n stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\\n\\n with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \\\\\\n patch('subprocess.Popen', side_effect=child), redirect_stdout(output):\\n if extra:\\n with self.assertRaises(ValueError):\\n actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\\n else:\\n result = actuator.copy_snapshot('drill-copy-rescue-r1', REVISION, {}, journal)\\n self.assertTrue(result['off_cluster_private_copy_verified'])\\n self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)\\n self.assertEqual(output.getvalue(), '')\\n self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)\\n\\n def test_recreated_offline_volume_cannot_be_deleted(self):\\n identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}\\n journal = type('FixtureJournal', (), {'data': {'phases': {\\n 'offline-verify': {'result': {'created_volume_identity': identity}}}}})()\\n inspected = [{**identity, 'CreatedAt': 'recreated'}]\\n with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:\\n with self.assertRaises(ValueError):\\n actuator.cleanup_offline(journal)\\n self.assertEqual(mocked.call_count, 1)\\n\\n def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):\\n for defect in ('none', 'post-integrity', 'original-hash'):\\n with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:\\n folder=Path(directory);os.chmod(folder,0o700)\\n snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)\\n digest=actuator.sha(snapshot)\\n prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}\\n journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy-rescue-r1':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()\\n reads=[]\\n volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}\\n def docker(argv, body=None, **kwargs):\\n if argv[0]=='info':body=json.dumps('bnt-lap001')\\n elif argv[:2]==['volume','ls']:body=''\\n elif argv[:2]==['volume','create']:body=actuator.VOLUME\\n elif argv[:2]==['volume','inspect']:body=json.dumps([volume])\\n elif 'informed-decision-admin' in argv:\\n body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})\\n if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')\\n elif '--entrypoint' in argv and 'python' in argv:\\n reads.append(argv);proof=copy.deepcopy(COUNT)\\n if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'\\n body=json.dumps(proof)\\n else:raise AssertionError('unexpected offline command')\\n return subprocess.CompletedProcess(argv,0,body,'')\\n with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{\\\"all_checks_pass\\\":true,\\\"private_copy_verified\\\":true}','')):\\n if defect=='none':\\n result=actuator.offline_verify(journal)\\n self.assertEqual(result['offline_post_admin_readonly'],COUNT)\\n self.assertTrue(result['original_snapshot_hash_unchanged'])\\n else:\\n with self.assertRaises(ValueError):actuator.offline_verify(journal)\\n self.assertEqual(len(reads),2)\\n\\n\\nclass FixedNativeProgram(unittest.TestCase):\\n def fixture(self):\\n sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())\\n live = copy.deepcopy(sealed)\\n live['metadata'].update(generation=42)\\n live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}\\n dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())\\n cm = copy.deepcopy(dependencies['configmap'])\\n cm.pop('canonical_data_sha256')\\n service = json.loads((CASE / 'candidate-deployment.json').read_text())\\n source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())\\n cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']\\n pvc = copy.deepcopy(dependencies['pvc'])\\n pvc['status'] = {'phase': 'Bound'}\\n app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},\\n 'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',\\n 'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},\\n 'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}\\n objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}\\n payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,\\n 'dependencies': dependencies, 'candidate': service,\\n 'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),\\n 'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),\\n 'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}\\n return objects, payload\\n\\n def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):\\n writes = []\\n calls = []\\n\\n def fake(argv, input=None, **kwargs):\\n calls.append(argv)\\n if argv[:2] == ['kubectl', 'get']:\\n kind = argv[2]\\n if kind in objects:\\n body = objects[kind]\\n elif kind == 'pods':\\n body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',\\n 'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},\\n 'spec': objects['deployment']['spec']['template']['spec'],\\n 'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}\\n elif kind == 'replicaset':\\n body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [\\n {'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}\\n elif kind == 'nodes':\\n body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {\\n 'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},\\n 'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}\\n for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}\\n else:\\n raise AssertionError('unexpected fixed metadata route')\\n return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')\\n if argv[:2] == ['kubectl', 'exec']:\\n if schema_refused:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, json.dumps({\\n 'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')\\n if argv[:2] == ['kubectl', 'apply']:\\n admitted = copy.deepcopy(payload['sealed'])\\n admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])\\n return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')\\n if argv[:2] == ['kubectl', 'describe']:\\n return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\\\\n cpu 3460m (86%)\\\\n', '')\\n if argv[:2] == ['kubectl', 'diff']:\\n return subprocess.CompletedProcess(argv, 1, '-image: base\\\\n+image: candidate\\\\n', '')\\n if argv[:2] == ['kubectl', 'patch']:\\n if '--dry-run=server' not in argv:\\n writes.append(json.loads(input))\\n if ambiguous:\\n return subprocess.CompletedProcess(argv, 1, '', 'withheld')\\n return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\\\\n', '')\\n raise AssertionError('unexpected command')\\n\\n source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(\\n '__GUARD__', repr((CASE / 'change_guard.py').read_text()))\\n output = io.StringIO()\\n with patch('subprocess.run', side_effect=fake), redirect_stdout(output):\\n try:\\n exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})\\n except (ValueError, SystemExit):\\n pass\\n receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}\\n return receipt, writes, calls\\n\\n def test_only_existing_application_operation_and_deployment_are_requested(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n operation = writes[0][-1]['value']\\n self.assertFalse(operation['sync']['prune'])\\n self.assertEqual(operation['sync']['resources'], [\\n {'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])\\n self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))\\n self.assertEqual(writes[0][0]['path'], '/metadata/uid')\\n\\n def test_source_overrides_automation_and_custody_drift_stop_before_write(self):\\n mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),\\n lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),\\n lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),\\n lambda o: o['application']['spec'].update(sources=[{}]),\\n lambda o: o['configmap']['metadata'].update(uid='recreated'),\\n lambda o: o['pvc']['spec'].update(volumeName='replaced'),\\n lambda o: o['deployment']['status'].update(readyReplicas=0)]\\n for mutate in mutations:\\n with self.subTest(mutate=mutate):\\n objects, payload = self.fixture()\\n mutate(objects)\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n def test_preopen_schema_refusal_prevents_image_operation(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(writes, [])\\n\\n\\n def test_rollback_unready_candidate_never_reads_pod_or_database(self):\\n objects, payload = self.fixture()\\n payload['phase'] = 'rollback'\\n objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)\\n objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE\\n objects['application']['spec']['source']['targetRevision'] = REVISION\\n receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)\\n self.assertTrue(receipt['all_checks_pass'])\\n self.assertFalse(receipt['rollout_verified'])\\n self.assertEqual(len(writes), 1)\\n self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))\\n self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')\\n\\n def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):\\n for defect in ('cm', 'pvc', 'image'):\\n with self.subTest(defect=defect):\\n objects, payload = self.fixture();payload['phase'] = 'rollback'\\n objects['deployment']['status']['readyReplicas'] = 0\\n if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'\\n elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'\\n else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])\\n\\n def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):\\n objects, payload = self.fixture();payload['phase'] = 'rollback-verify'\\n objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {\\n 'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,\\n 'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}\\n receipt, writes, calls = self.execute_fake(objects, payload)\\n self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])\\n self.assertEqual(writes, [])\\n self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))\\n objects['deployment']['status']['readyReplicas'] = 0\\n receipt, writes, calls = self.execute_fake(objects,payload)\\n self.assertFalse(receipt['all_checks_pass'])\\n\\n def test_ambiguous_patch_is_never_retried(self):\\n objects, payload = self.fixture()\\n receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)\\n self.assertFalse(receipt['all_checks_pass'])\\n self.assertEqual(len(writes), 1)\\n\\n\\nif __name__ == '__main__':\\n unittest.main()\\n\"\n },\n \"test_rescue_execution.py\": {\n \"sha256\": \"8ecbb0260a87a7a12bd5c4c9678fb2a9d43a4ea7322129734bc21f8ee383cd70\",\n \"content\": \"\\\"\\\"\\\"Synthetic recovery guards; no actual private journal/DB/native command.\\\"\\\"\\\"\\nimport copy\\nimport datetime\\nimport hashlib\\nimport json\\nimport os\\nfrom pathlib import Path\\nimport tempfile\\nimport unittest\\nfrom authority_journal import Journal, authority, original_anchor\\nfrom test_execution import accepted, NOW, REVISION\\n\\nROOT=Path(__file__).parent\\nPLAN=json.loads((ROOT/'execution-plan.json').read_text())\\nCASE=ROOT.parent\\nBACKUP=json.loads((CASE/'original-approved-drill-backup.json').read_text())\\n\\nclass RescueGuards(unittest.TestCase):\\n def original(self,parent):\\n original={'identity':PLAN['recovery']['original_identity'],'phases':{}}\\n for name,metadata in PLAN['recovery']['original_anchor']['phase_metadata'].items():\\n original['phases'][name]={**metadata,'result':BACKUP if name=='drill-backup' else {'all_checks_pass':False}}\\n p=parent/'execution-journal.json';p.write_text(json.dumps(original));os.chmod(p,0o600)\\n anchor=copy.deepcopy(PLAN['recovery']['original_anchor']);anchor['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\\n return p,original,anchor\\n\\n def test_exact_original_failed_journal_is_linked_without_mutation(self):\\n with tempfile.TemporaryDirectory() as directory:\\n parent=Path(directory);os.chmod(parent,0o700);p,original,expected=self.original(parent);before=p.read_bytes()\\n anchor=original_anchor(parent,expected,BACKUP,original['identity'])\\n j=Journal(parent,{'fixture':True,'recovery_anchor':anchor});j.start('drill-copy-rescue-r1',{})\\n self.assertEqual(p.read_bytes(),before);self.assertEqual(j.path.name,'rescue-execution-journal-r1.json')\\n j.finish('drill-copy-rescue-r1',{'all_checks_pass':True});j.start('offline-verify',{})\\n self.assertEqual(p.read_bytes(),before);j.close()\\n\\n def test_original_missing_uncertain_recreated_attempt_or_rollout_refuse(self):\\n for defect in ('missing','complete','attempt','rollout','hash'):\\n with self.subTest(defect=defect),tempfile.TemporaryDirectory() as directory:\\n parent=Path(directory);os.chmod(parent,0o700);p,o,e=self.original(parent)\\n if defect=='missing':o['phases'].pop('drill-copy')\\n elif defect=='complete':o['phases']['drill-copy']['state']='COMPLETE'\\n elif defect=='attempt':o['phases']['drill-copy']['attempt_id']='different'\\n elif defect=='rollout':o['phases']['release']={'state':'RUNNING'}\\n if defect!='hash':\\n p.write_text(json.dumps(o));e['original_journal_sha256']=hashlib.sha256(p.read_bytes()).hexdigest()\\n else:e['original_journal_sha256']='0'*64\\n with self.assertRaises((ValueError,KeyError)):original_anchor(parent,e,BACKUP,PLAN['recovery']['original_identity'])\\n\\n def test_rescue_replay_refused_and_old_phase_never_admitted(self):\\n with tempfile.TemporaryDirectory() as directory:\\n os.chmod(directory,0o700);j=Journal(directory,{'fixture':True})\\n with self.assertRaises(ValueError):j.start('drill-copy',{})\\n with self.assertRaises(ValueError):j.start('drill-backup',{})\\n with self.assertRaises(ValueError):j.start('offline-verify',{})\\n j.start('drill-copy-rescue-r1',{});j.finish('drill-copy-rescue-r1',{'all_checks_pass':False})\\n with self.assertRaises(ValueError):j.start('drill-copy-rescue-r1',{})\\n with self.assertRaises(ValueError):j.start('offline-verify',{})\\n j.close()\\n\\n def test_new_authority_requires_version2_old_approval_refuses(self):\\n receipt,outcome=accepted();receipt['memo_version']=2;outcome['dispositions'][0]['disposition']['memo_version']=1\\n authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\\n receipt['memo_version']=1\\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy',NOW)\\n receipt['memo_version']=2;receipt['outcome_query']='/lifecycle/memos/infd-20261011-purpose-overlay-r1/outcomes?version=1'\\n with self.assertRaises(ValueError):authority(receipt,outcome,'a'*64,REVISION,'drill-copy-rescue-r1',NOW)\\n\\n def test_explicit_offline_input_mapping_and_absence_guards(self):\\n source=(ROOT/'actuator.py').read_text()\\n self.assertIn(\\\"previous = journal.data['phases']['drill-copy-rescue-r1']['result']\\\",source)\\n self.assertIn(\\\"not os.path.lexists(CUSTODY / 'drill.sqlite')\\\",source)\\n self.assertIn(\\\"VOLUME not in listed.stdout.splitlines()\\\",source)\\n self.assertNotIn(\\\"os.mkdir(CUSTODY\\\",source)\\n import ast\\n program=ast.literal_eval(next(n.value for n in ast.parse((ROOT/'native_program.py').read_text()).body if isinstance(n,ast.Assign)))\\n compile(program,'native-rescue-fixture','exec')\\n self.assertIn(\\\"phase=='drill-copy-rescue-r1':require(pod['metadata']['uid']=='e8561ae0-4b09-4455-924d-64c27b625fc7'\\\",program)\\n\\nif __name__=='__main__':unittest.main()\\n\"\n },\n \"validation.json\": {\n \"sha256\": \"6f3379f63968e9a0294aba7b5b57ea4662adda6b1fa1b37eff11c2f72a58931f\",\n \"content\": \"{\\n \\\"state\\\": \\\"prepared-unapproved-version2\\\",\\n \\\"executor_tests\\\": 21,\\n \\\"snapshot_mock_tests\\\": 5,\\n \\\"native_actions\\\": false,\\n \\\"database_admin_commands_in_preparation\\\": false,\\n \\\"old_journal_modified\\\": false,\\n \\\"old_failed_phase_retried\\\": false,\\n \\\"owner_head_unchanged\\\": \\\"bc6494cd1b290783ef3aef0763bf28d1deabf4b0\\\"\\n}\\n\"\n }\n },\n \"native_execution\": false,\n \"case_evidence\": {\n \"original-approved-drill-backup.json\": {\n \"sha256\": \"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\",\n \"content\": \"{\\\"phase\\\": \\\"drill-backup\\\", \\\"all_checks_pass\\\": true, \\\"raw_output_withheld\\\": true, \\\"native_approval_verified_by_root\\\": {\\\"approval_id\\\": \\\"ec92806a-9aa6-494f-a76b-0385f39ba609\\\", \\\"disposition_id\\\": \\\"disp-0968373d-294d-42bf-8979-36a7c5dd38cf\\\", \\\"accepted_at\\\": \\\"2026-10-11T02:34:20Z\\\", \\\"verified_at\\\": \\\"2026-10-11T02:38:41.777949+00:00\\\"}, \\\"native_authenticated_grant\\\": false, \\\"source_readonly_baseline\\\": {\\\"schema_version\\\": 5, \\\"lifecycle\\\": {\\\"records\\\": 15, \\\"events\\\": 50, \\\"pending\\\": 0}, \\\"outbox\\\": {\\\"delivered\\\": 320}, \\\"submissions\\\": {\\\"confirmed\\\": 41}, \\\"integrity\\\": \\\"ok\\\", \\\"read_only_pre_open\\\": true, \\\"store_constructed\\\": false}, \\\"snapshot_readonly\\\": {\\\"schema_version\\\": 5, \\\"lifecycle\\\": {\\\"records\\\": 15, \\\"events\\\": 50, \\\"pending\\\": 0}, \\\"outbox\\\": {\\\"delivered\\\": 320}, \\\"submissions\\\": {\\\"confirmed\\\": 41}, \\\"integrity\\\": \\\"ok\\\", \\\"read_only_pre_open\\\": true, \\\"store_constructed\\\": false}, \\\"snapshot_sha256\\\": \\\"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\\\", \\\"snapshot_bytes\\\": 19537920, \\\"snapshot_file\\\": \\\"drill.sqlite\\\", \\\"native_parent_private\\\": true, \\\"native_uid\\\": 10001, \\\"pod_name\\\": \\\"informed-decision-f557556df-mwpz7\\\", \\\"pod_uid\\\": \\\"e8561ae0-4b09-4455-924d-64c27b625fc7\\\"}\\n\"\n },\n \"original-approved-drill-copy-failure.json\": {\n \"sha256\": \"fb78fb2e8c3d416490cf0f559b2f5bd019406a490f8f5fa6f5932421f0b1ac56\",\n \"content\": \"{\\\"all_checks_pass\\\": false, \\\"phase\\\": \\\"drill-copy\\\", \\\"failure_class\\\": \\\"ValueError\\\", \\\"failure\\\": \\\"fixed phase outcome uncertain; original evidence retained; no retry\\\", \\\"raw_output_withheld\\\": true}\\n\"\n },\n \"original-journal-sanitized-anchor.json\": {\n \"sha256\": \"988fca61ad8eb9d43d93390a835323f952196bbce8cc0bde51c42a17d411f454\",\n \"content\": \"{\\n \\\"original_journal_sha256\\\": \\\"d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1\\\",\\n \\\"phase_metadata\\\": {\\n \\\"drill-backup\\\": {\\n \\\"state\\\": \\\"COMPLETE\\\",\\n \\\"attempt_id\\\": \\\"d63182a7-e1a5-4e8e-a5f1-2bf3333cf153\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:38:45.310653+00:00\\\"\\n },\\n \\\"drill-copy\\\": {\\n \\\"state\\\": \\\"UNCERTAIN\\\",\\n \\\"attempt_id\\\": \\\"329ef190-1692-4246-b953-e6a59664abcc\\\",\\n \\\"started_at\\\": \\\"2026-10-11T02:39:50.198740+00:00\\\"\\n }\\n },\\n \\\"frozen_backup_receipt_sha256\\\": \\\"025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e\\\",\\n \\\"snapshot_sha256\\\": \\\"8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3\\\",\\n \\\"snapshot_bytes\\\": 19537920,\\n \\\"off_cluster_file_exists\\\": false,\\n \\\"old_uncertain_retry_authorized\\\": false\\n}\\n\"\n }\n }\n}\n" + }, + { + "item_id": "sqlite-readonly-py", + "media_type": "text/plain", + "content": "\"\"\"Pre-open schema/integrity/count proof; stdlib only, never constructs Store.\"\"\"\nimport argparse\nfrom contextlib import closing\nimport hashlib\nimport os\nimport re\nimport stat\nimport json\nfrom pathlib import Path\nimport sqlite3\n\n\ndef inspect_readonly(path, *, _closed_snapshot=False):\n path = Path(path)\n if not path.is_file() or path.is_symlink():\n raise ValueError('existing nonsymlink private database required')\n uri = path.resolve().as_uri() + '?mode=ro' + ('&immutable=1' if _closed_snapshot else '')\n # sqlite3.Connection context management ends transactions; it does not close.\n with closing(sqlite3.connect(uri, uri=True, timeout=5)) as db:\n db.execute('PRAGMA query_only=ON')\n db.execute('BEGIN')\n version = db.execute('PRAGMA user_version').fetchone()[0]\n if version != 5:\n raise ValueError('pre-open database is not schema5; refuse migration')\n if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]:\n raise ValueError('read-only integrity check refused')\n lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0]\n for name, table in (('records', 'lifecycle_records'),\n ('events', 'lifecycle_events'),\n ('pending', 'lifecycle_pending'))}\n result = {'schema_version': version, 'lifecycle': lifecycle,\n 'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')),\n 'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')),\n 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False}\n db.rollback()\n return result\n\n\ndef inspect_closed_snapshot(path, expected_sha256):\n \"\"\"Only a privately retained, frozen main-file snapshot with no WAL frames.\n\n Caller must establish exclusive snapshot creation/admin exit/no writer, and\n supply the recorded frozen main digest. Never use for the live database.\n Immutable SQLite reads ignore stale SHM and never create/change sidecars.\n Existing sidecars remain custody evidence; nothing is deleted/checkpointed.\n \"\"\"\n path = Path(path)\n if re.fullmatch(r'[0-9a-f]{64}', expected_sha256) is None:\n raise ValueError('exact frozen snapshot digest required')\n def metadata(target):\n info = target.lstat()\n if not stat.S_ISREG(info.st_mode) or stat.S_IMODE(info.st_mode) != 0o600 or info.st_nlink != 1:\n raise ValueError('private single-link snapshot custody required')\n return info\n main = metadata(path)\n if not 0 < main.st_size <= 512 * 1024**2:\n raise ValueError('bounded frozen snapshot required')\n def sidecars():\n identities = {}\n for suffix in ('-wal', '-shm'):\n target = Path(str(path) + suffix)\n if os.path.lexists(target):\n info = metadata(target)\n if info.st_uid != main.st_uid or info.st_gid != main.st_gid:\n raise ValueError('snapshot sidecar custody changed')\n if suffix == '-wal' and info.st_size != 0:\n raise ValueError('snapshot has WAL frames; immutable read refused')\n identities[suffix] = (info.st_dev, info.st_ino, info.st_size, info.st_mtime_ns)\n return identities\n before_sidecars = sidecars()\n def digest():\n value = hashlib.sha256()\n with path.open('rb') as stream:\n for block in iter(lambda: stream.read(1024**2), b''):\n value.update(block)\n return value.hexdigest()\n if digest() != expected_sha256:\n raise ValueError('frozen main-file digest changed before inspection')\n proof = inspect_readonly(path, _closed_snapshot=True)\n after = metadata(path)\n if (after.st_dev, after.st_ino, after.st_uid, after.st_gid, after.st_size) != (main.st_dev, main.st_ino, main.st_uid, main.st_gid, main.st_size):\n raise ValueError('frozen main-file identity changed')\n if digest() != expected_sha256 or sidecars() != before_sidecars:\n raise ValueError('frozen snapshot changed during inspection')\n return proof\n\n\nif __name__ == '__main__':\n parser = argparse.ArgumentParser(description=__doc__)\n parser.add_argument('--db', type=Path, required=True)\n args = parser.parse_args()\n try:\n print(json.dumps(inspect_readonly(args.db), sort_keys=True))\n except Exception:\n raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None\n" + }, + { + "item_id": "sealed-native-dependencies-json", + "media_type": "application/json", + "content": "{\n \"configmap\": {\n \"apiVersion\": \"v1\",\n \"immutable\": true,\n \"kind\": \"ConfigMap\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/ConfigMap:informed-decision/informed-decision-runtime-6c221878d051\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision-runtime-6c221878d051\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\"\n },\n \"canonical_data_sha256\": \"8ec462d12347548f506eeebf1e3c7cc47648019c8a783804d09bcc79b0f22af6\"\n },\n \"pvc\": {\n \"apiVersion\": \"v1\",\n \"kind\": \"PersistentVolumeClaim\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:/PersistentVolumeClaim:informed-decision/informed-decision-data\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\",\n \"pv.kubernetes.io/bind-completed\": \"yes\",\n \"pv.kubernetes.io/bound-by-controller\": \"yes\",\n \"volume.beta.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\",\n \"volume.kubernetes.io/selected-node\": \"239.62.205.92.host.secureserver.net\",\n \"volume.kubernetes.io/storage-provisioner\": \"rancher.io/local-path\"\n },\n \"finalizers\": [\n \"kubernetes.io/pvc-protection\"\n ],\n \"name\": \"informed-decision-data\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n },\n \"spec\": {\n \"accessModes\": [\n \"ReadWriteOnce\"\n ],\n \"resources\": {\n \"requests\": {\n \"storage\": \"1Gi\"\n }\n },\n \"storageClassName\": \"local-path\",\n \"volumeMode\": \"Filesystem\",\n \"volumeName\": \"pvc-d80b25b1-141a-441b-b205-98fa2fd98b7c\"\n }\n },\n \"pvc_phase\": \"Bound\"\n}\n" + }, + { + "item_id": "native-backup-restore-protocol-md", + "media_type": "text/markdown", + "content": "# Version2 protected existing-snapshot rescue and conditional continuation\n\nSame proposal INFD-WP-0009-T04/purpose-overlay-v1, trial infd-purpose-20261011-r1. Original version1 founder acceptance approved source bc6494cd1b290783ef3aef0763bf28d1deabf4b0. Drill-backup completed; drill-copy failed ValueError before any localfile. No image rollout occurred. This exact changed source/plan/helper requires NEW founder acceptance of memo version2 before rescue/continuation; prior approval and technical review do not approve it.\n\n## Failure and narrowly selected rescue\n\nOriginal snapshot main19537920bytes SHA8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3 is unchanged. Root's metadata-only verification shows WAL0bytes, SHM32768bytes, privateUID10001/mode0600/nlink1, and no local snapshot. The old SQLite connection context manager did not explicitly close; its WAL reader can create SHM indexing, and the next copy rejected that nonzero index. Platform independently reproduced this on synthetic data. No native DB was opened to diagnose the sidecar metadata, and no native sidecar is deleted/checkpointed.\n\nReuse this exact independently hash-bound frozen main snapshot rather than make another drill backup. The backupadmin exited after creating the uniquely owned private snapshot. Original subsequent snapshot access was readonly; actual service DB is the distinct /data/private/review.sqlite. Original journal has only COMPLETE drill-backup d63182a7-e1a5-4e8e-a5f1-2bf3333cf153 and UNCERTAIN drill-copy329ef190-1692-4246-b953-e6a59664abcc. Its exact SHA d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1, original source/memo/plan identity and outcomes are verified before/after every new phase. No other original action or rollout is allowed.\n\nThe explicitly named drill-copy-rescue-r1 creates a separate rescue-execution-journal-r1.json/lock in existing protected ignored custody; it hash-links original attempts and backupresult and never rewrites/synthesizes the old failed phase. Any attempted rescue result, crash or ambiguous output is durable and same-phase retry is refused. Before rescue: local drill.sqlite/cutover.sqlite and existing restore volume must be absent; native originalPodUID/currentoldimage7f5/Argo7db/sealedDeployment/CM/PVC match. The fixed immutable snapshot reader checks recorded digest/private identity/no WALframes before and after schema5/integrity/count validation, retaining unchanged SHM. Nonzero WAL or any identity/hash drift stops rescue. Snapshot binarystdout flows only to a new0600private file, with bounded size/hash and repeat source proof. It never reaches chat/log/Git/StateHub.\n\n## Live-WAL and data compatibility boundaries\n\nLive source and writable offline pre/post-admin reads MUST stay mode=ro/query_only and explicitly close SQLite connections. immutable=1 ignores WAL and would lose committed live rows; it is restricted to the proven frozen closed-main snapshot, never the liveDB or writableclone. Before ANY native source or restoredcopy Store/admin open, require stdlib readonly schema5/integrity/counts; refuse oldschemas before automatic migration. Frozen snapshot/clone count equality is exact; currentlive counter changes may reflect concurrent legitimate commits and are retained.\n\nOnly after COMPLETE named rescue does offline-verify consume its result via explicit mapping, not the old UNCERTAIN drill-copy. Existing isolated disposablevolume infd-purpose-r1-restore-20261011 must be absent/new nonce-bound. One exact763c UID0/CAP_CHOWN-only initializer receives snapshotstdin into that NEWvolume, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/nativePVC/runtimeconfig/token mounts. It sets folder0700/file0600UID10001, followed by UID10001 pre-open readonly, --entrypoint informed-decision-admin inspect --db /restore/review.sqlite and post-admin readonly fullproof; original protected SHA must remain unchanged. No serviceentrypoint starts. Cleanup only this disposable volume, retaining original native/offcluster snapshots/sidecars.\n\n## Conditional remaining phases and release/recovery\n\nNewjournal fixed order: drill-copy-rescue-r1 → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. cutover-backup uses distinct newcutover.sqlite in originalprivatecase directory, after readonly live schema5/capacity gates, SQLitebackupAPI/admin completion, closed-main immutable proof; do not overwrite originals or retryfailedpaths. Version2 acceptance conditionally approves these exact unchanged remaining operations only after rescue+drillgates. All four committed Kustomize Git blobs/currentHEAD, exact helper/case hashes, CM/PVC/Deployment seals and manualApplication(no automated{} or sourceoverride) must match.\n\nRelease retains existing replica1/Recreate/config6c/schema5/PVC/credentials/policies: sourcepin Application.operation serverdryrun/UID+resourceVersion+source CAS, Deployment-only image763c, prune=false. No whole-app sync/adoption. Verify requires succeeded exactscope/controllergeneration/Ready1, installedpolicyhash/modeUID/10syntheticpurposevariants+boundedhealth, same currentliveDB schema5/integrity/counts. Those installedchecks report native_provider=false; actualprovider/PDPauthority evidence remains a separate T04gate.\n\nRollback after recorded newrelease attempt pins prior7db/7f5 and retains latestschema5DB, without requiring Ready failingcandidate or candidateDBexec. Separate rollback-verify proves oldimageReady1/scopedoperation/readonlyschema5 currentDB integrity. Never restore an older snapshot over postcutoverrecords. Any data recovery beyond this same-schema image rollback needs another decision.\n\nAll phases including rescue, verification and recovery must begin before2026-10-12T23:59:59Z. Start early enough; if expired stop and obtain a fresh founder decision, which may delay recovery. No automatic timer/controller/extension. Root freshly authenticates exact confirmed platform-root person ACCEPT memo version2 at fixednativeorigin before every phase; protectedreceiptrelation/freshness120sec is supervisedbookkeeping, not a signed/autonomous grant.\n\nImage763c/policy9d7c/base7f5 and actualunfilteredscan0HIGH/CRITICAL/1fixableMEDIUMzlib remain unchanged, owner INFD-RISK-20261011-ZLIB-85091/T05 dueOct18. The exactbundle directly binds helper/plan/tests plus original count-onlybackup/failure/anchor. Existingpublishedreceipt still binds unchanged rawscan/SBOM/base scan; no suppression. Preserve originalapproved20docpacket/helpers/history in initial-approved-bc6494cd. No version2 native operation has run. EUR0 recurringinfrastructure; private boundedstorage/attendedtime unpriced, no newdrillbackup or autonomygrant.\n\nNative source publication uses exact revision-command.json via /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions, expected_version1, only after fresh unbound-source readback. No version2 intake/register. Publish/review sourceversion2; new human review-ID is ownversion1, so its confirmed nested disposition memo_version1 is correct. Root actual outcomes query must name SOURCE version2 and exact newreviewID; original review/approval cannot be reused.\n" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "media_type": "application/json", + "content": "{\n \"id\": \"INFD-RISK-20261011-ZLIB-85091\",\n \"kind\": \"owner-vulnerability-follow-through\",\n \"owner\": \"informed-decision\",\n \"task\": \"INFD-WP-0009-T05\",\n \"status\": \"open\",\n \"created\": \"2026-10-11\",\n \"review_due\": \"2026-10-18\",\n \"finding\": \"CVE-2026-85091\",\n \"scanner_severity\": \"MEDIUM\",\n \"estate_risk_grade\": null,\n \"affected_package\": \"zlib\",\n \"installed\": \"1.3.2-r0\",\n \"fixed\": \"1.3.2-r1\",\n \"actual_current_base_and_candidate_findings_identical\": true,\n \"source_evidence\": \"security-summary.json, trivy-full.json, base-trivy-full.json\",\n \"human_temporary_disposition\": \"pending\",\n \"follow_through\": \"Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload\",\n \"manual_review_expiry\": \"Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed\",\n \"close_condition\": \"Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition\"\n}\n" + }, + { + "item_id": "native-preflight-json", + "media_type": "application/json", + "content": "{\n \"captured_at\": \"2026-10-11T01:25:38.793555+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true\n}\n" + }, + { + "item_id": "sealed-live-deployment-json", + "media_type": "application/json", + "content": "{\n \"apiVersion\": \"apps/v1\",\n \"kind\": \"Deployment\",\n \"metadata\": {\n \"annotations\": {\n \"argocd.argoproj.io/tracking-id\": \"informed-decision:apps/Deployment:informed-decision/informed-decision\",\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"name\": \"informed-decision\",\n \"namespace\": \"informed-decision\",\n \"uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\"\n },\n \"spec\": {\n \"progressDeadlineSeconds\": 600,\n \"replicas\": 1,\n \"revisionHistoryLimit\": 10,\n \"selector\": {\n \"matchLabels\": {\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"strategy\": {\n \"type\": \"Recreate\"\n },\n \"template\": {\n \"metadata\": {\n \"annotations\": {\n \"informed-decision.coulomb.social/admission\": \"approved; INFD-WP-0007 cutover\"\n },\n \"labels\": {\n \"app.kubernetes.io/component\": \"review\",\n \"app.kubernetes.io/name\": \"informed-decision\"\n }\n },\n \"spec\": {\n \"automountServiceAccountToken\": false,\n \"containers\": [\n {\n \"env\": [\n {\n \"name\": \"INFD_KEYCAPE_ISSUER\",\n \"value\": \"https://kc.coulomb.social\"\n },\n {\n \"name\": \"INFD_CONTAINER_CONFIG\",\n \"value\": \"/configuration/runtime.json\"\n }\n ],\n \"image\": \"forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\",\n \"imagePullPolicy\": \"IfNotPresent\",\n \"livenessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"name\": \"informed-decision\",\n \"ports\": [\n {\n \"containerPort\": 8080,\n \"name\": \"http\",\n \"protocol\": \"TCP\"\n },\n {\n \"containerPort\": 8081,\n \"name\": \"workload\",\n \"protocol\": \"TCP\"\n }\n ],\n \"readinessProbe\": {\n \"failureThreshold\": 3,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"resources\": {\n \"limits\": {\n \"cpu\": \"500m\",\n \"memory\": \"256Mi\"\n },\n \"requests\": {\n \"cpu\": \"5m\",\n \"memory\": \"64Mi\"\n }\n },\n \"securityContext\": {\n \"allowPrivilegeEscalation\": false,\n \"capabilities\": {\n \"drop\": [\n \"ALL\"\n ]\n },\n \"readOnlyRootFilesystem\": true\n },\n \"startupProbe\": {\n \"failureThreshold\": 12,\n \"httpGet\": {\n \"path\": \"/healthz\",\n \"port\": \"http\",\n \"scheme\": \"HTTP\"\n },\n \"periodSeconds\": 10,\n \"successThreshold\": 1,\n \"timeoutSeconds\": 2\n },\n \"terminationMessagePath\": \"/dev/termination-log\",\n \"terminationMessagePolicy\": \"File\",\n \"volumeMounts\": [\n {\n \"mountPath\": \"/data\",\n \"name\": \"data\"\n },\n {\n \"mountPath\": \"/run/informed-decision\",\n \"name\": \"runtime\"\n },\n {\n \"mountPath\": \"/tmp\",\n \"name\": \"tmp\"\n },\n {\n \"mountPath\": \"/configuration\",\n \"name\": \"configuration\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/policy\",\n \"name\": \"caller\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/audit\",\n \"name\": \"audit\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/kubernetes\",\n \"name\": \"kubernetes-api\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/workload-registry\",\n \"name\": \"workload-registry\",\n \"readOnly\": true\n },\n {\n \"mountPath\": \"/var/run/secrets/informed-decision/requester\",\n \"name\": \"sitting-requester\",\n \"readOnly\": true\n }\n ]\n }\n ],\n \"dnsPolicy\": \"ClusterFirst\",\n \"restartPolicy\": \"Always\",\n \"schedulerName\": \"default-scheduler\",\n \"securityContext\": {\n \"fsGroup\": 10001,\n \"fsGroupChangePolicy\": \"OnRootMismatch\",\n \"runAsGroup\": 10001,\n \"runAsNonRoot\": true,\n \"runAsUser\": 10001,\n \"seccompProfile\": {\n \"type\": \"RuntimeDefault\"\n }\n },\n \"serviceAccount\": \"review\",\n \"serviceAccountName\": \"review\",\n \"terminationGracePeriodSeconds\": 45,\n \"volumes\": [\n {\n \"name\": \"data\",\n \"persistentVolumeClaim\": {\n \"claimName\": \"informed-decision-data\"\n }\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"runtime\"\n },\n {\n \"emptyDir\": {\n \"medium\": \"Memory\",\n \"sizeLimit\": \"16Mi\"\n },\n \"name\": \"tmp\"\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-runtime-6c221878d051\"\n },\n \"name\": \"configuration\"\n },\n {\n \"name\": \"caller\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"audience\": \"flex-auth\",\n \"expirationSeconds\": 3600,\n \"path\": \"token\"\n }\n }\n ]\n }\n },\n {\n \"name\": \"audit\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"token\",\n \"path\": \"token\"\n }\n ],\n \"secretName\": \"informed-decision-audit\"\n }\n },\n {\n \"name\": \"kubernetes-api\",\n \"projected\": {\n \"defaultMode\": 288,\n \"sources\": [\n {\n \"serviceAccountToken\": {\n \"expirationSeconds\": 600,\n \"path\": \"token\"\n }\n },\n {\n \"configMap\": {\n \"items\": [\n {\n \"key\": \"ca.crt\",\n \"path\": \"ca.crt\"\n }\n ],\n \"name\": \"kube-root-ca.crt\"\n }\n }\n ]\n }\n },\n {\n \"configMap\": {\n \"defaultMode\": 292,\n \"name\": \"informed-decision-workload-registry\"\n },\n \"name\": \"workload-registry\"\n },\n {\n \"name\": \"sitting-requester\",\n \"secret\": {\n \"defaultMode\": 288,\n \"items\": [\n {\n \"key\": \"client-secret\",\n \"path\": \"client-secret\"\n }\n ],\n \"optional\": false,\n \"secretName\": \"informed-decision-sitting-requester\"\n }\n }\n ]\n }\n }\n }\n}\n" + }, + { + "item_id": "change-guard-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only exact Deployment and admission boundaries; no mutation authority.\"\"\"\nimport copy\nimport hashlib\nimport json\n\nBASE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'\nCANDIDATE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'\n\n\ndef dependency_projection(configmap, pvc):\n if (configmap.get('kind') != 'ConfigMap' or configmap.get('immutable') is not True\n or configmap['metadata']['namespace'] != 'informed-decision'\n or configmap['metadata']['name'] != 'informed-decision-runtime-6c221878d051'\n or set(configmap.get('data', {})) != {'runtime.json'}\n or configmap.get('binaryData')):\n raise ValueError('unexpected immutable runtime config identity')\n if (pvc.get('kind') != 'PersistentVolumeClaim'\n or pvc['metadata']['namespace'] != 'informed-decision'\n or pvc['metadata']['name'] != 'informed-decision-data'\n or pvc.get('status', {}).get('phase') != 'Bound'\n or not pvc.get('spec', {}).get('volumeName')):\n raise ValueError('unexpected bound PVC custody')\n config = projection(configmap)\n config.pop('data')\n config['canonical_data_sha256'] = hashlib.sha256(json.dumps(\n configmap['data'], sort_keys=True, separators=(',', ':')).encode()).hexdigest()\n return {'configmap': config, 'pvc': projection(pvc), 'pvc_phase': 'Bound'}\n\n\ndef check_dependencies(configmap, pvc, sealed):\n if dependency_projection(configmap, pvc) != sealed:\n raise ValueError('runtime config or PVC identity/custody changed')\n\n\ndef projection(value):\n value = copy.deepcopy(value)\n value.pop('status', None)\n for key in ('resourceVersion', 'generation', 'creationTimestamp', 'managedFields'):\n value['metadata'].pop(key, None)\n for key in ('kubectl.kubernetes.io/last-applied-configuration', 'deployment.kubernetes.io/revision'):\n value['metadata'].get('annotations', {}).pop(key, None)\n return value\n\n\ndef check_current(current, sealed):\n if projection(current) != sealed:\n raise ValueError('sealed live UID or configuration changed')\n\n\ndef check_admitted(admitted, sealed):\n expected = copy.deepcopy(sealed)\n containers = expected['spec']['template']['spec']['containers']\n if len(containers) != 1 or containers[0]['name'] != 'informed-decision' or containers[0]['image'] != BASE:\n raise ValueError('unexpected baseline container identity')\n containers[0]['image'] = CANDIDATE\n if projection(admitted) != expected:\n raise ValueError('admission changed configuration beyond the sole image pin')\n\n\ndef transport_result(exit_code, output):\n import json\n try:\n value = json.loads(output)\n except (ValueError, TypeError):\n return {'all_checks_pass': False, 'reason': 'invalid transport result'}\n if exit_code != 0 or not isinstance(value, dict) or value.get('all_checks_pass') is not True:\n return {'all_checks_pass': False, 'reason': 'read-only preflight refused'}\n return value\n" + }, + { + "item_id": "preflight-py", + "media_type": "text/plain", + "content": "\"\"\"Read-only refresh; exact original capture remains immutable; never execute cutover.\"\"\"\nimport argparse,hashlib,json,subprocess,sys\nfrom pathlib import Path\nif sys.flags.optimize:\n raise SystemExit(\"optimized interpreter refused before source/transport execution\")\nROOT=Path(__file__).resolve().parent\np=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args()\nout=a.receipt_output.resolve()\nif not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists():\n raise SystemExit('unique execution receipt must be outside the sealed packet')\ninputs=json.loads((ROOT/'preflight-inputs.json').read_text())\nfor relative,digest in inputs['packet_files'].items():\n path=ROOT/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed')\nfor relative,digest in inputs['owner_source_files'].items():\n path=a.source_root/relative\n if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed')\nfrom change_guard import transport_result\nprogram='import subprocess,json,hashlib,datetime,sys,copy,re\\nif sys.flags.optimize:raise RuntimeError(\"optimized interpreter refused\")\\ncandidate=json.loads(CANDIDATE_LITERAL)\\nsealed_dependencies=json.loads(DEPENDENCIES_LITERAL)\\nsealed_baseline=json.loads(SEALED_LITERAL)\\nexec(GUARD_LITERAL)\\ndef run(args,data=None):\\n p=subprocess.run(args,input=data,text=True,capture_output=True)\\n if p.returncode: raise ValueError(\\'read-only command failed: \\'+args[1]+\\' \\'+args[2])\\n return p.stdout\\nlive=json.loads(run([\\'kubectl\\',\\'get\\',\\'deployment\\',\\'informed-decision\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncm=json.loads(run([\\'kubectl\\',\\'get\\',\\'configmap\\',\\'informed-decision-runtime-6c221878d051\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\npvc=json.loads(run([\\'kubectl\\',\\'get\\',\\'pvc\\',\\'informed-decision-data\\',\\'-n\\',\\'informed-decision\\',\\'-o\\',\\'json\\']))\\ncheck_dependencies(cm,pvc,sealed_dependencies)\\ncheck_current(live,sealed_baseline)\\nspec=live[\\'spec\\']; cs=spec[\\'template\\'][\\'spec\\'][\\'containers\\'];assert len(cs)==1 and cs[0][\\'name\\']==\\'informed-decision\\'\\nexpected_env={\\'INFD_KEYCAPE_ISSUER\\':\\'https://kc.coulomb.social\\',\\'INFD_CONTAINER_CONFIG\\':\\'/configuration/runtime.json\\'}\\nassert cs[0].get(\\'env\\')==[{\\'name\\':\\'INFD_KEYCAPE_ISSUER\\',\\'value\\':expected_env[\\'INFD_KEYCAPE_ISSUER\\']},{\\'name\\':\\'INFD_CONTAINER_CONFIG\\',\\'value\\':expected_env[\\'INFD_CONTAINER_CONFIG\\']}]\\nassert cs[0][\\'image\\']==\\'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\\'\\nassert spec[\\'replicas\\']==1 and spec[\\'strategy\\']=={\\'type\\':\\'Recreate\\'}\\nassert next(v for v in spec[\\'template\\'][\\'spec\\'][\\'volumes\\'] if v[\\'name\\']==\\'configuration\\')[\\'configMap\\'][\\'name\\']==\\'informed-decision-runtime-6c221878d051\\'\\nassert live[\\'status\\'].get(\\'readyReplicas\\')==1 and live[\\'status\\'].get(\\'updatedReplicas\\')==1\\nsealed={\\'apiVersion\\':live[\\'apiVersion\\'],\\'kind\\':live[\\'kind\\'],\\'metadata\\':{k:copy.deepcopy(v) for k,v in live[\\'metadata\\'].items() if k not in (\\'resourceVersion\\',\\'generation\\',\\'creationTimestamp\\',\\'managedFields\\')},\\'spec\\':copy.deepcopy(spec)}\\nfor key in (\\'kubectl.kubernetes.io/last-applied-configuration\\',\\'deployment.kubernetes.io/revision\\'):sealed[\\'metadata\\'].get(\\'annotations\\',{}).pop(key,None)\\nadmitted=json.loads(run([\\'kubectl\\',\\'apply\\',\\'--dry-run=server\\',\\'-f\\',\\'-\\',\\'-o\\',\\'json\\'],json.dumps(candidate)))\\ncheck_admitted(admitted,sealed_baseline)\\napp=json.loads(run([\\'kubectl\\',\\'get\\',\\'application\\',\\'informed-decision\\',\\'-n\\',\\'argocd\\',\\'-o\\',\\'json\\']))\\nassert app[\\'spec\\'][\\'source\\'][\\'path\\']==\\'deploy/lifecycle\\' and not app[\\'spec\\'].get(\\'syncPolicy\\',{}).get(\\'automated\\')\\nargo={\\'uid\\':app[\\'metadata\\'][\\'uid\\'],\\'repoURL\\':app[\\'spec\\'][\\'source\\'][\\'repoURL\\'],\\'targetRevision\\':app[\\'spec\\'][\\'source\\'][\\'targetRevision\\'],\\'path\\':app[\\'spec\\'][\\'source\\'][\\'path\\'],\\'destination\\':app[\\'spec\\'][\\'destination\\'],\\'automated\\':False,\\'sync\\':app.get(\\'status\\',{}).get(\\'sync\\'),\\'health\\':app.get(\\'status\\',{}).get(\\'health\\')}\\nexpected_argo=json.loads(ARGO_LITERAL)\\nfor key in (\\'uid\\',\\'repoURL\\',\\'targetRevision\\',\\'path\\',\\'destination\\',\\'automated\\'):\\n assert argo[key]==expected_argo[key]\\nassert argo[\\'health\\'][\\'status\\']==\\'Healthy\\'\\ndiff=subprocess.run([\\'kubectl\\',\\'diff\\',\\'-f\\',\\'-\\'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\\nnode=run([\\'kubectl\\',\\'describe\\',\\'node\\']);allocated=re.search(r\\'Allocated resources:.*?CPU Requests|Allocated resources:\\',node,re.S)\\nsection=node.split(\\'Allocated resources:\\')[1].split(\\'Events:\\')[0] if \\'Allocated resources:\\' in node else \\'\\'\\nnodes=json.loads(run([\\'kubectl\\',\\'get\\',\\'nodes\\',\\'-o\\',\\'json\\']))[\\'items\\'];assert len(nodes)==1\\nalloc=nodes[0][\\'status\\'][\\'allocatable\\'];cpu=alloc[\\'cpu\\'];cpu_m=int(cpu[:-1]) if cpu.endswith(\\'m\\') else int(cpu)*1000\\nrequested=int(re.search(r\\'cpu\\\\s+(\\\\d+)m\\',section).group(1));assert requested<=cpu_m\\nreceipt={\\'node_allocatable_cpu_m\\':cpu_m,\\'node_requested_cpu_m\\':requested,\\'captured_at\\':datetime.datetime.now(datetime.timezone.utc).isoformat(),\\'native_workload_changed\\':False,\\'native_backup_restore_executed\\':False,\\'argo\\':argo,\\'native_dependencies_checked\\':True,\\'configmap_uid\\':cm[\\'metadata\\'][\\'uid\\'],\\'pvc_uid\\':pvc[\\'metadata\\'][\\'uid\\'],\\'live_ready_replicas\\':1,\\'admitted_uid\\':admitted[\\'metadata\\'][\\'uid\\'],\\'server_dry_run_passed\\':True,\\'admitted_spec_exactly_live_plus_image\\':True,\\'client_diff_exit\\':diff.returncode,\\'client_diff_sha256\\':hashlib.sha256(diff.stdout.encode()).hexdigest(),\\'node_allocated_resources\\':section.strip(),\\'all_checks_pass\\':True}\\nprint(json.dumps(receipt))\\n'\nfor marker,value in [('DEPENDENCIES_LITERAL',(ROOT/'sealed-native-dependencies.json').read_text()),('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]:\n program=program.replace(marker,repr(value))\nprogram='import traceback,json\\ntry:\\n'+''.join(' '+line+'\\n' for line in program.splitlines())+\"except Exception as error:\\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\\n\"\nr=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True)\nresult=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True\nout.write_text(json.dumps(result,indent=2)+'\\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1)\n" + }, + { + "item_id": "preflight-inputs-json", + "media_type": "application/json", + "content": "{\n \"packet_files\": {\n \"change_guard.py\": \"f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be\",\n \"preflight.py\": \"6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd\",\n \"candidate-deployment.json\": \"722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e\",\n \"rollback-deployment.json\": \"39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121\",\n \"sealed-live-deployment.json\": \"d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362\",\n \"native-preflight.json\": \"eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262\",\n \"sealed-native-dependencies.json\": \"042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369\",\n \"sqlite_readonly.py\": \"9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509\"\n },\n \"owner_source_files\": {\n \"deploy/lifecycle/admission.candidate.json\": \"92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55\",\n \"deploy/lifecycle/service.candidate.json\": \"38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4\"\n }\n}\n" + }, + { + "item_id": "fresh-preflight-validation-json", + "media_type": "application/json", + "content": "{\n \"node_allocatable_cpu_m\": 4000,\n \"node_requested_cpu_m\": 3460,\n \"captured_at\": \"2026-10-11T01:39:14.234277+00:00\",\n \"native_workload_changed\": false,\n \"native_backup_restore_executed\": false,\n \"argo\": {\n \"uid\": \"499868f2-eabc-4df4-ae31-b89ce58d750d\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"path\": \"deploy/lifecycle\",\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"automated\": false,\n \"sync\": {\n \"comparedTo\": {\n \"destination\": {\n \"namespace\": \"informed-decision\",\n \"server\": \"https://kubernetes.default.svc\"\n },\n \"source\": {\n \"path\": \"deploy/lifecycle\",\n \"repoURL\": \"https://forgejo.coulomb.social/coulomb/informed-decision.git\",\n \"targetRevision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\"\n }\n },\n \"revision\": \"7db8485ffecdebfabd77a9daec085553c74bf0bf\",\n \"status\": \"OutOfSync\"\n },\n \"health\": {\n \"lastTransitionTime\": \"2026-10-10T23:14:52Z\",\n \"status\": \"Healthy\"\n }\n },\n \"native_dependencies_checked\": true,\n \"configmap_uid\": \"90113d2d-54d9-4e82-b1d3-90b49ebed2b5\",\n \"pvc_uid\": \"d80b25b1-141a-441b-b205-98fa2fd98b7c\",\n \"live_ready_replicas\": 1,\n \"admitted_uid\": \"a588e10a-90d2-4883-975e-6dd8b8feca92\",\n \"server_dry_run_passed\": true,\n \"admitted_spec_exactly_live_plus_image\": true,\n \"client_diff_exit\": 1,\n \"client_diff_sha256\": \"840769c7d2a9c1655c40a3259f833d1fc8f69950ceb3bedb707a955fed711566\",\n \"node_allocated_resources\": \"(Total limits may be over 100 percent, i.e., overcommitted.)\\n Resource Requests Limits\\n -------- -------- ------\\n cpu 3460m (86%) 36200m (905%)\\n memory 9472Mi (59%) 32898Mi (205%)\\n ephemeral-storage 0 (0%) 0 (0%)\\n hugepages-1Gi 0 (0%) 0 (0%)\\n hugepages-2Mi 0 (0%) 0 (0%)\",\n \"all_checks_pass\": true,\n \"sealed_preflight_inputs_sha256\": \"756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06\",\n \"fresh_execution_receipt\": true\n}\n" + } + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/revision-command.json b/docs/evidence/2026-10-11-purpose-image-release/revision-command.json new file mode 100644 index 0000000..9df6b66 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/revision-command.json @@ -0,0 +1,247 @@ +{ + "memo": { + "id": "infd-20261011-purpose-overlay-r1", + "version": 2, + "question": "Approve the exact existing-snapshot rescue of failed drill-copy using corrected frozen-snapshot reads, then conditionally finish the protected compatibility gates and Deployment-only purpose-image release, retaining the disclosed fixable MEDIUM finding?", + "requested_act": "approve", + "binding_level": "organizational", + "brief": "Original approved backup COMPLETE; copy UNCERTAIN beforelocalfile because staleSHM index. Main19537920bytes/hash8756 unchanged,WAL0. Version2 explicitclose +immutable frozen-only rescue, no sidecar delete/newdrillbackup/oldretry; distinctphase/newhashlinkedjournal. Remainingoffline/cutover/image763c gates ordered;0HIGH/CRITICAL,1fixableMEDIUM/T05Oct18. ALLphasesdeadlineOct12,freshfounderdecisionbeyond; installedpurpose synthetic/native_providerfalse. No version2actions.", + "binding": { + "principal": { + "id": "pending-human-session", + "kind": "person", + "display_name": "Founder review" + }, + "target": { + "kind": "environment", + "id": "realm:kubernetes/railiance01/informed-decision", + "label": "Informed Decision image-only purpose hardening on railiance01", + "environment": "production" + }, + "terms": "Exact attached same INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1 version2 ONLY: named drill-copy-rescue-r1 with newjournal preserving originalUNCERTAINcopy and exactoriginalbackup/mainhash19537920/WAL0/privateidentity; no SHMdelete or newdrillbackup. Absentlocalfile/volume/currentoldimage+source+UIDseals; corrected immutable frozen-only reads, live/offline remainWALaware. COMPLETErescueresult conditionallyallows exactisolatedofflineUID0CAP_CHOWNinitializer thenUID10001pre/admin/postproof+cleanup; distinctcutoverbackup/copy and fourGitpins/manualDeployment-only763c/prune=false. All phases incl recovery/verify beginbeforeOct12 23:59:59Z,newdecisionbeyond; rollbackprior7f5retainlatestDB,separateReadyoldimage/schema recoveryproof. Fresh rootauthenticated founderACCEPTversion2 eachphase; no signed/autonomousgrant. Explicit inheritedfixableMEDIUM/T05Oct18; installedchecks syntheticnative_providerfalse, actualPDPauthorityT04gate distinct. No credential/policy/wholeAppsync change." + }, + "step_kind": "approve", + "packet": [ + { + "item_id": "decision-packet-md", + "label": "decision-packet.md", + "hash": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024" + }, + { + "item_id": "proposal-json", + "label": "proposal.json", + "hash": "sha256:e4d8fa77ce97f9cc190e9cae8f86478dba5e89cc7a13bf993e3b8d47a3160b36" + }, + { + "item_id": "candidate-admission-json", + "label": "candidate-admission.json", + "hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55" + }, + { + "item_id": "rollback-admission-json", + "label": "rollback-admission.json", + "hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50" + }, + { + "item_id": "candidate-deployment-json", + "label": "candidate-deployment.json", + "hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e" + }, + { + "item_id": "rollback-deployment-json", + "label": "rollback-deployment.json", + "hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121" + }, + { + "item_id": "published-verification-json", + "label": "published-verification.json", + "hash": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd" + }, + { + "item_id": "registry-proof-json", + "label": "registry-proof.json", + "hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213" + }, + { + "item_id": "security-summary-json", + "label": "security-summary.json", + "hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44" + }, + { + "item_id": "execution-bundle-json", + "label": "execution-bundle.json", + "hash": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5" + }, + { + "item_id": "sqlite-readonly-py", + "label": "sqlite_readonly.py", + "hash": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509" + }, + { + "item_id": "sealed-native-dependencies-json", + "label": "sealed-native-dependencies.json", + "hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369" + }, + { + "item_id": "native-backup-restore-protocol-md", + "label": "native-backup-restore-protocol.md", + "hash": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5" + }, + { + "item_id": "inherited-vulnerability-follow-through-json", + "label": "inherited-vulnerability-follow-through.json", + "hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101" + }, + { + "item_id": "native-preflight-json", + "label": "native-preflight.json", + "hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262" + }, + { + "item_id": "sealed-live-deployment-json", + "label": "sealed-live-deployment.json", + "hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362" + }, + { + "item_id": "change-guard-py", + "label": "change_guard.py", + "hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be" + }, + { + "item_id": "preflight-py", + "label": "preflight.py", + "hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd" + }, + { + "item_id": "preflight-inputs-json", + "label": "preflight-inputs.json", + "hash": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b" + }, + { + "item_id": "fresh-preflight-validation-json", + "label": "fresh-preflight-validation.json", + "hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7" + } + ], + "highlights": [ + { + "id": "native-custody-rollout-and-known-medium", + "item_id": "decision-packet-md", + "note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.", + "required_ack": true, + "severity": "warning", + "locator": { + "kind": "section", + "heading": "Requested decision" + } + } + ], + "sealed": false, + "approval_id": null, + "approval_binding_digest": null + }, + "expected_version": 1, + "summary": "Same supervised trial: retain original approvedbackup and UNCERTAINcopy; correct explicitSQLiteclose/frozenimmutable reads and introduce exact named existing-snapshot rescue with separate hash-linked journal, fresh human review, unchanged image/scope.", + "documents": [ + { + "digest": "sha256:c79d505d9fd1c4897ea0709e22f3263bf92f50660336084aae0c83c65d6b9024", + "media_type": "text/markdown", + "content_base64": "IyBJbmZvcm1lZCBEZWNpc2lvbiB2ZXJzaW9uMiBleGlzdGluZy1zbmFwc2hvdCByZXNjdWUgYW5kIGltYWdlIHJlbGVhc2UKCkFwcHJvdmUgdGhlIGV4YWN0IHNvdXJjZS1yZWZpbmVkIHJlY292ZXJ5IG9mIHRoZSBmYWlsZWQgZHJpbGwtY29weSBhbmQgY29uZGl0aW9uYWwgcmVtYWluaW5nIGJhY2t1cC9kcmlsbC9EZXBsb3ltZW50LW9ubHkgaW1hZ2Ugcm9sbG91dC4gVGhpcyBpcyBtZW1vIHZlcnNpb24yIGluIHRoZSBzYW1lIHByb3Bvc2FsL3RyaWFsLCByZXF1aXJpbmcgTkVXIGZvdW5kZXIgYWNjZXB0YW5jZTsgb3JpZ2luYWwgdmVyc2lvbjEgYWNjZXB0YW5jZSBpcyByZXRhaW5lZCBhbmQgY2Fubm90IGF1dGhvcml6ZSBjaGFuZ2VkIGhlbHBlcmJ5dGVzLgoKT3JpZ2luYWwgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCB0aGUgcHJvdGVjdGVkIG5hdGl2ZSBkcmlsbC1iYWNrdXAsIHRoZW4gY29weSBmYWlsZWQgYmVmb3JlIGFueSBsb2NhbGZpbGUuIE1ldGFkYXRhLW9ubHkgdmVyaWZpY2F0aW9uIHByb3ZlcyB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMC9wcml2YXRlU0hNMzI3NjguIFRoZSBvcmlnaW5hbCByZWFkZXIgY291bGQgbGVhdmUgU0hNIGluZGV4aW5nIGJlY2F1c2UgaXRzIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgY2xvc2UuIFRoZSBjb3JyZWN0aW9uIGV4cGxpY2l0bHljbG9zZXMgYWxsIHJlYWRlcnMgYW5kIHVzZXMgaW1tdXRhYmxlIHJlYWRzIE9OTFkgZm9yIGEgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbm90IGxpdmUgb3Igd3JpdGFibGVjbG9uZS4gU0hNIHN0YXlzIHVuY2hhbmdlZDsgbm9uemVyb1dBTC9oYXNoL2lkZW50aXR5IGRyaWZ0IHN0b3BzIHJlc2N1ZS4KCkRpc3RpbmN0IGRyaWxsLWNvcHktcmVzY3VlLXIxL25ld2xpbmtlZGpvdXJuYWwgcHJlc2VydmVzIG9yaWdpbmFsIFVOQ0VSVEFJTmNvcHkgYW5kIGV4YWN0IGpvdXJuYWxoYXNoL2F0dGVtcHRzLiBObyBvbGRyZXRyeS9vdmVyd3JpdGUsIG5vIG5ld2RyaWxsYmFja3VwLiBSZXF1aXJlIG9yaWdpbmFsQ09NUExFVEViYWNrdXAvVU5DRVJUQUlOY29weSBvbmx5LCBhYnNlbnRsb2NhbGZpbGVzL3Jlc3RvcmV2b2x1bWUsIG9yaWdpbmFsbmF0aXZlUG9kVUlEL2N1cnJlbnRvbGRpbWFnZStzb3VyY2VwaW4gYW5kIGFsbENNL1BWQy9EZXBsb3ltZW50IHNlYWxzLiBDb3B5IHNuYXBzaG90Ynl0ZXMgb25seSBpbnRvIGEgbmV3cHJpdmF0ZTA2MDBmaWxlLiBSZW1haW5pbmdvcmRlcmVkcGhhc2VzIGV4cGxpY2l0bHkgY29uc3VtZSBDT01QTEVURXJlc2N1ZXJlc3VsdDsgb25lIGlzb2xhdGVkIFVJRDAvQ0FQX0NIT1dOLW9ubHkgTkVXdm9sdW1lIGluaXRpYWxpemVyIHRoZW4gVUlEMTAwMDEgcHJlLW9wZW4vYWRtaW4vcG9zdC1hZG1pbiBjaGVja3MgcHJvdmVzIHJlYWwtZGF0YSBjb21wYXRpYmlsaXR5IGJlZm9yZSBjdXRvdmVyLiBObyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50czsgbm8gc2VydmljZSBzdGFydHVwLiBBbnkgYXR0ZW1wdGVkIGZhaWx1cmUvYW1iaWd1aXR5IGlzIGR1cmFibGUgYW5kIGNhbm5vdHJldHJ5LgoKSW1hZ2U3NjNjIGZyb20gYWN0dWFsQ0kzZTRiY2IyNiByZW1haW5zIHVuY2hhbmdlZDhiYXNlIGxheWVycyBwbHVzcG9saWN5LnB5OyBsZWdhY3lzZXJpYWxpemF0aW9uIGRpZmZlcmVuY2VzIGRpc2Nsb3NlZC4gQWN0dWFsaW5zdGFsbGVkVUlEMTAwMDEvMTBwdXJwb3NldmFyaWFudHMgcGFzczsgbmF0aXZlX3Byb3ZpZGVyPWZhbHNlL3N5bnRoZXRpY3RyYW5zcG9ydCBpcyBub3QgYWN0dWFsUERQYXV0aG9yaXR5IHByb29mLCB3aGljaCByZW1haW5zIHNlcGFyYXRlVDA0Z2F0ZS4gQWN0dWFsZnVsbDQ0cGFja2FnZXNjYW4wSElHSC9DUklUSUNBTCwgT05FZml4YWJsZWluaGVyaXRlZE1FRElVTXpsaWJDVkUtMjAyNi04NTA5MSgxLjMuMi1yMOKGknIxKSwgaWRlbnRpY2FsYmFzZWZpbmRpbmcuIEV4cGxpY2l0dGVtcG9yYXJ5cGVybWlzc2lvbiBmb3IgdGhpcyBmaW5kaW5nIGlzIHJlcXVlc3RlZCBhZ2Fpbiwgd2l0aCBvd25lclQwNS9yaXNrcmVjb3JkZHVlT2N0MTg7IG5vIHplcm8tQ1ZFL1Jpc2tOZXh1c2dyYWRlY2xhaW0uIFJhd3NjYW4vU0JPTS9iYXNlIHNjYW4gc3RheSB1bmNoYW5nZWRoYXNoYm91bmQgdmlhIHB1Ymxpc2hlZHJlY2VpcHQ7IGV4YWN0aGVscGVyYW5kb3JpZ2luYWxjb3VudC1vbmx5cmVjZWlwdHMgZGlyZWN0bHlidW5kbGUtYm91bmQgd2l0aGluMjBkb2NzLgoKQWZ0ZXIgcmVzY3VlK29mZmxpbmVnYXRlcywgZGlzdGluY3RjdXRvdmVyYmFja3VwL2NvcHkgYW5kIG1hbnVhbEFyZ29EZXBsb3ltZW50LW9ubHkgaW1hZ2U3NjNjL3BydW5lPWZhbHNlIHJlbWFpbiBjb25kaXRpb25hbC4gRm91cmNvbW1pdHRlZEt1c3RvbWl6ZWJsb2JzL2N1cnJlbnRmaW5hbHNvdXJjZUhFQUQvaGVscGVycy9jYXNlaGFzaGVzIG1hdGNoOyBhdXRvbWF0ZWR7fSBvciBvdmVycmlkZXMgcmVmdXNlLiBDb25maWc2Yy9zY2hlbWE1L1BWQy9pZGVudGl0eS9wb2xpY2llcy9yZXBsaWNhMVJlY3JlYXRlIHN0YXlmaXhlZC4gUm9sbGJhY2tkb2Vzbm90bmVlZCBSZWFkeWNhbmRpZGF0ZSBvciBpdHNEQmV4ZWM7IG9sZGltYWdlUmVhZHkvc2NvcGVkb3BlcmF0aW9uL3NjaGVtYTVjdXJyZW50REIgaXMgYSBzZXBhcmF0ZXByb29mLiBQcmVzZXJ2ZSBsYXRlc3RsaXZlREIvYWxsbmV3Y29tbWl0cyBhbmQgYWxsdW5jZXJ0YWlub3V0Y29tZXM7IG5ldmVycmVzdG9yZW9sZGVyYmFja3VwIG92ZXJsYXRlcnJlY29yZHMuCgpBbGxwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZS9yZWNvdmVyeS92ZXJpZnkgbXVzdGJlZ2luIGJlZm9yZU9jdDEyIDIzOjU5OjU5WjsgZXhwaXJ5cmVxdWlyZXNuZXdkZWNpc2lvbiBhbmQgbWF5ZGVsYXlyZWNvdmVyeS4gTm8gYXV0b21hdGljZXhwaXJ5Y29udHJvbGxlci4gRnJlc2hyb290LWF1dGhlbnRpY2F0ZWQgbmF0aXZlZm91bmRlcmFjY2VwdGFuY2UgdmVyc2lvbjIgYmVmb3JlZWFjaHBoYXNlOyByZWNlaXB0cyBhcmUgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3RzaWduZWRncmFudC9hdXRvbm9teS4gRVVSMCByZWN1cnJpbmdpbmZyYSwgZXhpc3Rpbmdwcml2YXRlY29weS9zdG9yYWdlL2F0dGVuZGVkdGltZSB1bnByaWNlZDsgbm8gc2Vjb25kbmF0aXZlIGRyaWxsYmFja3VwLiBFeGFjdG9yaWdpbmFsYXBwcm92ZWRwYWNrZXQvZmFpbHVyZS90ZWNobmljYWxyZWZpbmVtZW50cyBwcmVzZXJ2ZWQgc2FtZXByb3Bvc2FsL3RyaWFsLiBObyB2ZXJzaW9uMm5hdGl2ZW9wZXJhdGlvbiB5ZXQuCg==" + }, + { + "digest": "sha256:e4d8fa77ce97f9cc190e9cae8f86478dba5e89cc7a13bf993e3b8d47a3160b36", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbF9pZCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgInRyaWFsX2lkIjogImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMSIsCiAgInN0YXRlIjogInByZXBhcmVkLXVuYXBwcm92ZWQiLAogICJ0YXJnZXQiOiAicmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbiIsCiAgImF1dGhvcml0eSI6ICJBRE1JTklTVEVSOyBhY3RpdmF0aW9uIEFQUFJPVkVEIG9ubHkgdXBvbiBleGFjdCBmb3VuZGVyIGRpc3Bvc2l0aW9uIiwKICAiY2FuZGlkYXRlX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYSIsCiAgInB1Ymxpc2hlZF9zb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInByaW9yX2ltYWdlIjogImZvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgInByaW9yX2FyZ29fcmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgIm5hdGl2ZV9vYmplY3QiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJhcHBzL3YxIiwKICAgICJraW5kIjogIkRlcGxveW1lbnQiLAogICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAidWlkIjogImE1ODhlMTBhLTkwZDItNDg4My05NzVlLTZkZDhiOGZlY2E5MiIKICB9LAogICJhcmdvX2FwcGxpY2F0aW9uX3VpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICJzb3VyY2VfZ2F0ZSI6ICJBbGwgZm91ciBleGFjdCBjb21taXR0ZWQgb3duZXIgS3VzdG9taXplIGlucHV0IGJsb2JzIGluIGV4ZWN1dGlvbi1wbGFuLmpzb24gYW5kIGNsZWFuIGN1cnJlbnQgb3duZXIgSEVBRCBtdXN0IG1hdGNoOyBzb3VyY2UgcHJlcGFyYXRpb24gaXMgbm90IG5hdGl2ZSBhcHByb3ZhbCIsCiAgInN5bmNfc2NvcGUiOiBbCiAgICAiYXBwczpEZXBsb3ltZW50OmluZm9ybWVkLWRlY2lzaW9uIgogIF0sCiAgInBydW5lIjogZmFsc2UsCiAgImF1dG9tYXRlZF9zeW5jIjogZmFsc2UsCiAgInJ1bnRpbWVfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAic2NoZW1hIjogNSwKICAicmVxdWVzdGVkX29wZXJhdGlvbnMiOiBbCiAgICAiUmVhZC1vbmx5IGltbXV0YWJsZSB2YWxpZGF0aW9uIG9mIGV4aXN0aW5nIGZyb3plbjE5NTM3OTIwYnl0ZSBuYXRpdmUgZHJpbGwgc25hcHNob3QsIFNIQTg3NTYuLi4sIHByaXZhdGVjdXN0b2R5L25vLXdyaXRlci96ZXJvV0FML3N0YWxlU0hNIHJldGFpbmVkIiwKICAgICJEaXN0aW5jdCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBiaW5hcnljb3B5IGludG8gYWJzZW50MDYwMHByb3RlY3RlZCBsb2NhbCBkZXN0aW5hdGlvbiwgbmV3IGhhc2gtbGlua2VkIHJlc2N1ZSBqb3VybmFsIHByZXNlcnZpbmcgb2xkIFVOQ0VSVEFJTiBjb3B5IiwKICAgICJFeGlzdGluZyBpc29sYXRlZCBvZmZsaW5lIHByZS1vcGVuL2FkbWluL3Bvc3Qtb3BlbiBjb21wYXRpYmlsaXR5IGRyaWxsIGFuZCBkaXNwb3NhYmxlLXZvbHVtZSBjbGVhbnVwIHVzaW5nIHJlc2N1ZWQgcmVzdWx0IiwKICAgICJEaXN0aW5jdCBjb25zaXN0ZW50IGN1dG92ZXIgc25hcHNob3QgcGx1cyBwcm90ZWN0ZWRjb3B5LCBmb2xsb3dlZCBvbmx5IGFmdGVyIGFsbGdhdGVzIGJ5IERlcGxveW1lbnQtb25seSBpbWFnZSByZWxlYXNlL3ZlcmlmeTsgc2FtZS1zY2hlbWEgcm9sbGJhY2svcmVjb3ZlcnkgcHJvb2YgaWYgbmVlZGVkIgogIF0sCiAgImV4ZWN1dGVfYnkiOiAiMjAyNi0xMC0xMlQyMzo1OTo1OVoiLAogICJ0ZW1wb3JhcnlfdnVsbmVyYWJpbGl0eV9yZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJrbm93bl9zY2FuX2ZpbmRpbmdzIjogIjBISUdIL0NSSVRJQ0FMLDFmaXhhYmxlIGluaGVyaXRlZE1FRElVTSB6bGliLCBhY3R1YWwgY3VycmVudGJhc2UrY2FuZGlkYXRlIGZpbmRpbmdzIGlkZW50aWNhbCIsCiAgInZ1bG5lcmFiaWxpdHlfcmVjb3JkIjogIklORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxIC8gSU5GRC1XUC0wMDA5LVQwNSIsCiAgImNvc3RfZXN0aW1hdGVfRVVSIjogMCwKICAiY29zdF9saW1pdHMiOiAiTm8gYWRkaXRpb25hbCByZWN1cnJpbmcgaW5mcmFzdHJ1Y3R1cmUgb3Igc2Vjb25kIGRyaWxsIGJhY2t1cC4gRXhpc3RpbmcgbmF0aXZlIHNuYXBzaG90MTk1Mzc5MjBieXRlcyByZXRhaW5lZDsgcHJvdGVjdGVkIGxvY2FsY29weS9vZmZsaW5lY2xvbmUgcGx1cyBkaXN0aW5jdCBjdXRvdmVyIHNuYXBzaG90cyBjb25zdW1lIGJvdW5kZWRleGlzdGluZ3N0b3JhZ2UuIEF0dGVuZGVkZW5naW5lZXJpbmcvcmVjb3ZlcnkgdGltZSB1bnByaWNlZDsgbm8gYXV0b3BpbG90IGdyYW50LiIsCiAgInJpc2tfZXN0aW1hdGVzIjogWwogICAgIkJyaWVmIFJlY3JlYXRlIHNlcnZpY2UgaW50ZXJydXB0aW9uOyBubyBjb25jdXJyZW50IG5ldyB3cml0ZXIvc3VyZ2UiLAogICAgIlByaXZhdGUgZXZpZGVuY2Ugc25hcHNob3QgY3VzdG9keSBhbmQgZGlzcG9zYWwgZXJyb3JzOyBubyBzbmFwc2hvdHMvdG9rZW5zIGluIHB1YmxpYyBldmlkZW5jZSIsCiAgICAiQ2FuZGlkYXRlIHB1cnBvc2UgcmVmdXNhbCBtYXkgZXhwb3NlIGNhbGxlcnMgcmVseWluZyBvbiBhZHZpc29yeSByZXN1bHRzIGFzIGJpbmRpbmciLAogICAgIkluaGVyaXRlZCBrbm93biBmaXhhYmxlIE1FRElVTSByZW1haW5zIHVudGlsIHNlcGFyYXRlbHkgYXBwcm92ZWQgb3duZXIgcmVtZWRpYXRpb24iLAogICAgIkV4aXN0aW5nIEFyZ28gT3V0T2ZTeW5jIGJhc2VsaW5lIGlzIHJldGFpbmVkOyBubyB3aG9sZS1hcHAgc3luYyBvciB1bnJlbGF0ZWQgcmVwYWlycyBwZXJtaXR0ZWQiLAogICAgIkFsbCBwaGFzZXMsIGluY2x1ZGluZyByZWNvdmVyeS92ZXJpZmljYXRpb24sIG11c3QgYmVnaW4gYmVmb3JlIE9jdDEyIGRlYWRsaW5lOyBpZiByZWNvdmVyeSB3aW5kb3cgaXMgZXhoYXVzdGVkIHN0b3AgYW5kIG9idGFpbiBhIGZyZXNoIGZvdW5kZXIgZGVjaXNpb24uIE5vIGF1dG9tYXRpYyBleHBpcnkgY29udHJvbGxlci4iCiAgXSwKICAicm9sbGJhY2siOiAiTWFudWFsIEFyZ28gc291cmNlIHBpbiBiYWNrIHRvN2RiODQ4NSBhbmQgc2NvcGVkIERlcGxveW1lbnQtb25seSBzeW5jIHRvN2Y1YyBpbWFnZTsgcmV0YWluIGN1cnJlbnQgc2NoZW1hNSBkYXRhYmFzZSBhbmQgYWxsIHBvc3QtY3V0b3ZlciBldmlkZW5jZSwgbmV2ZXIgcmVzdG9yZSBvbGRlciBzbmFwc2hvdCBvdmVyIGxpdmUgd3JpdGVzIiwKICAibmF0aXZlX2V4ZWN1dGVkIjogIk9yaWdpbmFsIGRyaWxsLWJhY2t1cCBleGVjdXRlZDsgb3JpZ2luYWwgZHJpbGwtY29weSBmYWlsZWQuIE5vIHZlcnNpb24yIGFjdGlvbiBleGVjdXRlZC4iLAogICJodW1hbl9hcHByb3ZhbCI6ICJWZXJzaW9uMSBhY2NlcHRlZCBvcmlnaW5hbHNvdXJjZTsgdmVyc2lvbjIgcmVxdWlyZXMgZnJlc2ggZXhhY3QgYWNjZXB0YW5jZS4iLAogICJyZWZpbmVtZW50X29mX21hbmlmZXN0IjogIjdjNjczOGIzOWVhOGU1NGU2MWM4ZWQ2MjVlOTRhZDBiMjc1NWU2NzJlMTU3NmVmY2RmODRhMWQ2NjVhYzMzMDAiLAogICJtYW5kYXRvcnlfcHJlX29wZW5fZ2F0ZSI6ICJzdGRsaWJTUUxpdGUgbW9kZT1yby9xdWVyeV9vbmx5OiBzY2hlbWE1K2ludGVncml0eStjb3VudCBiYXNlbGluZSBiZWZvcmUgQU5ZIFN0b3JlL2FkbWluIG9uIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5OyByZWZ1c2VvbGRzY2hlbWFzIHdpdGhvdXQgbWlncmF0aW9uIiwKICAib3B0aW1pemVkX2ludGVycHJldGVycyI6ICJsb2NhbCtyZW1vdGUgZXhwbGljaXRseXJlZnVzZWQgYmVmb3JlYXNzZXJ0IGdhdGVzIiwKICAibmF0aXZlX2RlcGVuZGVuY3lfZ2F0ZSI6ICJzZWFsZWQgYWN0dWFsQ00gVUlEL2ltbXV0YWJsZS9jYW5vbmljYWxkYXRhaGFzaCtQVkMgVUlEL2Z1bGxzcGVjL0JvdW5kL3ZvbHVtZU5hbWUsIG5vIHJhd0NNZGF0YSBvclNlY3JldCByZWFkcyIsCiAgImxpdmVfY291bnRzIjogIkZyb3plbiBzbmFwc2hvdC9jbG9uZSBleGFjdGNvdW50ZXIgZXF1YWxpdHk7IHBvc3RjdXRvdmVyL3JvbGxiYWNrIGxpdmVjb3VudGVyY2hhbmdlcyBtYXkgcmVmbGVjdCBsZWdpdGltYXRlIGNvbmN1cnJlbnRjb21taXRzL3N0YXRlIHRyYW5zaXRpb25zLCBsYXRlc3REQiBhbHdheXNyZXRhaW5lZCIsCiAgInNvdXJjZV9iYXNpcyI6IHsKICAgICJvcmlnaW5hbF9hcHByb3ZlZF9zb3VyY2UiOiAiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMCIsCiAgICAiZmluYWxfcmVjb3Zlcnlfc291cmNlIjogImV4YWN0IGZpbmFsIHJvb3QtYXBwbGllZCBvd25lciBIRUFEIHdpdGggYXBwcm92ZWQgZm91ciByZW5kZXIgYmxvYnMgbXVzdCBiZSBib3VuZCBieSBuZXcgZm91bmRlciByZWNlaXB0IgogIH0sCiAgImFwcHJvdmVkX293bmVyX3JlbmRlcl9ibG9iX3NoYTI1NiI6IHsKICAgICJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvbiI6ICI5MjM4MmE1NmIzNDljM2I4OTVlNTgwNmU5NzUwODI1MjdiYjk5ZDFhMDAxMTQwZTY5ZDg1N2U1YjAzOTFmYTU1IiwKICAgICJkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24iOiAiMzhiNzhiOWNiZWU1YWRlNzc1MGE1OGQ1MTU2Y2E0YzU3NzMzNTJlOTQ3YWNiMzA0ZWU3MTRiNTllNzQ5Y2ViNCIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwiOiAiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0NyIsCiAgICAiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uIjogIjliYWQ2ZGI1ZmJjMjE3OGQzMWIwNDEyMDAxNmE0MTgzMGMzNTUyZmJiOWUyNTE3YjcxOGY5YmJlODdjZjY0OWUiCiAgfSwKICAiZXhlY3V0aW9uX2J1bmRsZV9zaGEyNTYiOiAiNDljOWNiNzBmMzZmNmNlYjdiMGQyMjQwMGIyZWM5MjMyYTVlMWE4YTAwZDE3ZTkyYjkyZmUzNjdjOThlZmZiNSIsCiAgImV4ZWN1dGlvbl9wbGFuX3NoYTI1NiI6ICI5Y2U1NzI4YTU2MWU2ZDM4Zjg0OTcyMDFiYWEyYjg0MGQxMTQ0NGEwYWY4YWQ2MjM0ZGZjMzc0MjgxMTNmMjU4IiwKICAiZXhlY3V0aW9uX3BoYXNlcyI6IFsKICAgICJkcmlsbC1jb3B5LXJlc2N1ZS1yMSIsCiAgICAib2ZmbGluZS12ZXJpZnkiLAogICAgImNsZWFudXAtb2ZmbGluZSIsCiAgICAiY3V0b3Zlci1iYWNrdXAiLAogICAgImN1dG92ZXItY29weSIsCiAgICAicmVsZWFzZSIsCiAgICAidmVyaWZ5IiwKICAgICJyb2xsYmFjayIsCiAgICAicm9sbGJhY2stdmVyaWZ5IgogIF0sCiAgImRlYWRsaW5lX3NlbWFudGljcyI6ICJBbGwgcGhhc2VzIGluY2x1ZGluZyB2ZXJpZmljYXRpb24vcmVjb3ZlcnkgbXVzdCBiZWdpbiBiZWZvcmUgZXhlY3V0ZV9ieS4gTm8gZXh0ZW5zaW9uIG9yIGF1dG9tYXRpYyBlbWVyZ2VuY3kgZ3JhbnQ7IGJleW9uZCBkZWFkbGluZSBzdG9wIGFuZCBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBDb21wbGV0ZSB0aGUgYm91bmRlZCBkcmlsbCBhbmQgcm9sbG91dCBlYXJseSBlbm91Z2ggdG8gYWxsb3cgcmVjb3Zlcnkgd2l0aGluIHRoZSB3aW5kb3cuIiwKICAib2ZmbGluZV9pbml0aWFsaXplciI6ICJPbmUgaXNvbGF0ZWQgbG9jYWwgVUlEMDowL0NBUF9DSE9XTi1vbmx5IGluaXRpYWxpemVyIG9mIHRoZSBuZXdseSBjcmVhdGVkIG5vbmNlLWJvdW5kIGRpc3Bvc2FibGUgdm9sdW1lLCBleGFjdCBjYW5kaWRhdGUgaW1hZ2UsIG5ldHdvcmtub25lL3JlYWRvbmx5cm9vdC9uby1uZXdwcml2aWxlZ2VzL0NQVTEvMTI4TWk7IG5vIGhvc3QvbGl2ZVBWQy90b2tlbi9jb25maWcgbW91bnQuIFN1YnNlcXVlbnQgcHJlLW9wZW4vYWRtaW4vcG9zdC1vcGVuIGNoZWNrcyBVSUQxMDAwMToxMDAwMS4iLAogICJyb2xsYmFja19kaXNwYXRjaCI6ICJTZWFsZWQgRGVwbG95bWVudC9DTS9QVkMgYW5kIHNhbWUtc2NoZW1hIHNvdXJjZS9pbWFnZSBwYWlyIHBsdXMgYWRtaXNzaW9uIENBUzsgbm8gUmVhZHkgY2FuZGlkYXRlIG9yIFBvZC9kYXRhYmFzZSBleGVjIHByZXJlcXVpc2l0ZS4gcm9sbGJhY2stdmVyaWZ5IHNlcGFyYXRlbHkgcHJvdmVzIHJlY292ZXJlZCBvbGQgaW1hZ2UvUmVhZHkxL3Njb3BlZCBvcGVyYXRpb24gYW5kIHJlYWRvbmx5IGN1cnJlbnQgc2NoZW1hNS9pbnRlZ3JpdHkvY291bnRzLiIsCiAgInB1cnBvc2VfcHJvb2ZfbGltaXQiOiAiVGVuIGluc3RhbGxlZCBzeW50aGV0aWMtdHJhbnNwb3J0IGNoZWNrcyBvbiBhY3R1YWwgcGxhY2VtZW50OyBuYXRpdmVfcHJvdmlkZXI9ZmFsc2UuIE5vdCBhY3R1YWwgcHJvdmlkZXIvUERQIGF1dGhvcml0eSBwcm9vZiwgd2hpY2ggcmVtYWlucyBhIGRpc3RpbmN0IFQwNCBjb21wbGV0aW9uIGdhdGUuIiwKICAicmVmaW5lbWVudF9vZl9hbWVuZGVkX21hbmlmZXN0IjogImIxZTNlNjZiYzQwMjNkYzgwYzZlYTU5NTY0YzM1NTdjNzY1M2ZiM2MzMDdmNDZhMDQ5OTk3Yjc2MTk4YTkwMzMiLAogICJtZW1vX3ZlcnNpb24iOiAyLAogICJyZWNvdmVyeSI6IHsKICAgICJvcmlnaW5hbF9hbmNob3IiOiB7CiAgICAgICJvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiI6ICJkMTg3YjAyZDk4ZDZlOTc0MjlmZTIwYjRmYmUxZDMwOWE2YzZjNGI1NTIzMmI0YWUxM2FjMzk4NzMwMzlmMWMxIiwKICAgICAgInBoYXNlX21ldGFkYXRhIjogewogICAgICAgICJkcmlsbC1iYWNrdXAiOiB7CiAgICAgICAgICAic3RhdGUiOiAiQ09NUExFVEUiLAogICAgICAgICAgImF0dGVtcHRfaWQiOiAiZDYzMTgyYTctZTFhNS00ZThlLWE1ZjEtMmJmMzMzM2NmMTUzIiwKICAgICAgICAgICJzdGFydGVkX2F0IjogIjIwMjYtMTAtMTFUMDI6Mzg6NDUuMzEwNjUzKzAwOjAwIgogICAgICAgIH0sCiAgICAgICAgImRyaWxsLWNvcHkiOiB7CiAgICAgICAgICAic3RhdGUiOiAiVU5DRVJUQUlOIiwKICAgICAgICAgICJhdHRlbXB0X2lkIjogIjMyOWVmMTkwLTE2OTItNDI0Ni1iOTUzLWU2YTU5NjY0YWJjYyIsCiAgICAgICAgICAic3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAyOjM5OjUwLjE5ODc0MCswMDowMCIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJmcm96ZW5fYmFja3VwX3JlY2VpcHRfc2hhMjU2IjogIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGUiLAogICAgICAic25hcHNob3Rfc2hhMjU2IjogIjg3NTZjZjgyNWRmOWU3YjViNzRiYjRhMDEwNmE1MDI3ZjVjZmYyYzU5ZmY0NWQ3YjQ4ZWVkODUyMmE3ZDMzZjMiLAogICAgICAic25hcHNob3RfYnl0ZXMiOiAxOTUzNzkyMCwKICAgICAgIm9mZl9jbHVzdGVyX2ZpbGVfZXhpc3RzIjogZmFsc2UsCiAgICAgICJvbGRfdW5jZXJ0YWluX3JldHJ5X2F1dGhvcml6ZWQiOiBmYWxzZQogICAgfSwKICAgICJvcmlnaW5hbF9pZGVudGl0eSI6IHsKICAgICAgInByb3Bvc2FsIjogIklORkQtV1AtMDAwOS1UMDQvcHVycG9zZS1vdmVybGF5LXYxIiwKICAgICAgInNvdXJjZV9yZXZpc2lvbiI6ICJiYzY0OTRjZDFiMjkwNzgzZWYzYWVmMDc2M2JmMjhkMWRlYWJmNGIwIiwKICAgICAgIm1lbW9fc2hhMjU2IjogIjUwNmQzOTU2YmViN2M2MmFiMmJiZGZkYTc4M2MwNTkwNWQxODM0NTJhMWY2N2ExODE3ZjNmYjhjMmU1MjI5MzciLAogICAgICAicGxhbl9zaGEyNTYiOiAiZjVlNWZhOTA2ZmYxOWQzYTQ1ZDEwZGNkYjI4MTAzNzNhZTIxZjljZjQ0YzA0NzJmZjJiZDQ3ZDNiYzMzMjhkNiIKICAgIH0sCiAgICAibmV3X2pvdXJuYWwiOiAicmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24iLAogICAgIm5ld19waGFzZSI6ICJkcmlsbC1jb3B5LXJlc2N1ZS1yMSIsCiAgICAib2xkX3VuY2VydGFpbl9waGFzZV9vdmVyd3JpdGVfb3JfcmV0cnkiOiBmYWxzZSwKICAgICJuZXdfc25hcHNob3RfYmFja3VwIjogZmFsc2UsCiAgICAic25hcHNob3Rfb3Jfc2lkZWNhcl9tdXRhdGlvbiI6IGZhbHNlLAogICAgIm1hcHBpbmciOiAib2ZmbGluZS12ZXJpZnkgY29uc3VtZXMgQ09NUExFVEUgZHJpbGwtY29weS1yZXNjdWUtcjEgcmVzdWx0OyBhbGwgbGF0ZXIgcGhhc2VzIG9yZGVyZWQgb25seSBpbiBuZXcgaGFzaC1saW5rZWQgcmVjb3Zlcnkgam91cm5hbCIKICB9LAogICJvcmlnaW5hbF9uYXRpdmVfb3V0Y29tZSI6IHsKICAgICJkcmlsbC1iYWNrdXAiOiAiQ09NUExFVEUiLAogICAgImRyaWxsLWNvcHkiOiAiVU5DRVJUQUlOIGJlZm9yZSBsb2NhbGZpbGUgY3JlYXRpb24iLAogICAgIm5hdGl2ZV9pbWFnZSI6ICJ1bmNoYW5nZWQ3ZjU7IG5vIHJvbGxvdXQiLAogICAgIm9yaWdpbmFsX2pvdXJuYWxfYW5kX3NpZGVjYXJzIjogInJldGFpbmVkIHVuY2hhbmdlZCIKICB9LAogICJyZXNjdWVfbGltaXRzIjogIk5vIGxpdmVEQndyaXRlcyBkdXJpbmcgcmVzY3VlIGluc3BlY3Rpb24vY29weSwgbm8gc2lkZWNhciBkZWxldGlvbi9jaGVja3BvaW50LCBubyByZXRyeS9vdmVyd3JpdGUgb3JpZ2luYWwgVU5DRVJUQUlOIHBoYXNlLiBMYXRlciBleGlzdGluZyBhZG1pbiBvZmZsaW5laW5zcGVjdC9jdXRvdmVyYmFja3VwIGFuZCBpbWFnZSBhY3Rpb25zIG5lZWQgbmV3IGV4YWN0dmVyc2lvbjIgYWNjZXB0YW5jZSBhbmRvcmRlcmVkZ3VhcmRzLiIsCiAgInN1Ym1pc3Npb25fcm91dGUiOiAiUE9TVCAvbGlmZWN5Y2xlL21lbW9zL2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxL3JldmlzaW9ucyBDQVMgZXhwZWN0ZWRfdmVyc2lvbjE7IHNvdXJjZSBtdXN0IHJlbWFpbiB1bmJvdW5kOyBwdWJsaXNoL3JldmlldyBzb3VyY2V2ZXJzaW9uMiwgcmVzdWx0aW5nIGh1bWFuIHJldmlldyBvd252ZXJzaW9uMSIsCiAgIm9yaWdpbmFsX2V4ZWN1dGlvbl9oZWxwZXJfbWFuaWZlc3Rfc2hhMjU2IjogImYyZmFkNmMyNTFmYmI0NDIwZTA3YzEzMjk4MDJmNTIxYjUxM2JiZjY2ZTUxZjY0YzVkNjczZWYwNGYxNjI4NGMiLAogICJvcmlnaW5hbF9leGVjdXRpb25faGVscGVyX21hbmlmZXN0X2NvbnRleHQiOiAiUmV0YWluZWQgaGlzdG9yaWNhbCBmMmZhZDYgaGVscGVyIHJldmlldyBiZWZvcmUgdGhlIGZhaWxlZCBhcHByb3ZlZCBiYWNrdXAvY29weSB0cmlhbDsgY3VycmVudCByZXNjdWUgZXhlY3V0aW9uIGJ5dGVzIGFyZSBib3VuZCBieSBleGVjdXRpb25fYnVuZGxlX3NoYTI1NiBhbmQgZXhlY3V0aW9uX3BsYW5fc2hhMjU2LiBUaGlzIGhpc3RvcmljYWwgbWFuaWZlc3QgZG9lcyBub3QgZGVzY3JpYmUgY3VycmVudCB2ZXJzaW9uMiByZXNjdWUgZmlsZXMuIgp9Cg==" + }, + { + "digest": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICJwb2xpY3kiOiB7CiAgICAib3JpZ2luIjogImh0dHA6Ly9mbGV4LWF1dGgtaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicGFja2FnZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi5jb21wYWN0LXNpdHRpbmciLAogICAgInZlcnNpb24iOiAidjEzIiwKICAgICJwYWNrYWdlX2RpZ2VzdCI6ICJzaGEyNTY6MzFiZTU5ODVjMGMxZTZiMGMzYTAzOWVkNzMxMGQxZTk0ZGFmNTIzYTk0ZjZkOTI2ZTZlOGQ3NTlkMzcxMTg3MyIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLXNpdHRpbmciCiAgfSwKICAia2V5Y2FwZV9lZ3Jlc3NfaXBzIjogWwogICAgIjkyLjIwNS42Mi4yMzkiCiAgXSwKICAic3RvcmFnZV9jbGFzcyI6ICJsb2NhbC1wYXRoIiwKICAib3JkaW5hcnlfYXBwcm92YWxfaWRzIjogWwogICAgIjJjZTc2ZDdmLTAxYzMtNGI2My04NDc2LThkMTIzMDY3OTc2OSIsCiAgICAiYzJhZjRiY2YtMTViNC00MzA1LWFhYzEtYWNjN2U0ZGNiMDk5IiwKICAgICJkYzIyNjY2YS1kNWQ3LTQ2YmMtOTQ5MC1lYmU5ZmUwOWRjMzgiCiAgXSwKICAibGlmZWN5Y2xlX3BvbGljeSI6IHsKICAgICJwYWNrYWdlIjogImluZm9ybWVkLWRlY2lzaW9uLmxpZmVjeWNsZSIsCiAgICAidmVyc2lvbiI6ICJ2MiIsCiAgICAicGFja2FnZV9kaWdlc3QiOiAic2hhMjU2OmRhMDFlMDQ1ZmMxMDhhZGVjNmI0ODllNWQ1MWY3ZTU3MzY2NzkzMDE2YzVhNjQ3NzY5NjM3ODBhNmFhZTQ1N2MiLAogICAgIm9yaWdpbiI6ICJodHRwOi8vZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZS5mbGV4LWF1dGguc3ZjLmNsdXN0ZXIubG9jYWw6ODA4MCIsCiAgICAicG9kX25hbWUiOiAiZmxleC1hdXRoLWluZm9ybWVkLWRlY2lzaW9uLWxpZmVjeWNsZSIKICB9LAogICJsaWZlY3ljbGVfZGVsaXZlcnkiOiB0cnVlLAogICJpbnRha2VfYXR0cmlidXRlcyI6IHRydWUsCiAgImludGFrZV9kZWxpdmVyeSI6IHsKICAgICJodWJfb3JpZ2luIjogImh0dHA6Ly9zdGF0ZS1odWIuc3RhdGUtaHViLnN2Yy5jbHVzdGVyLmxvY2FsOjgwMDAiCiAgfSwKICAid29ya2xvYWRfYXBpIjogewogICAgInJlZ2lzdHJpZXNfY29uZmlnbWFwIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IiwKICAgICJwZWVycyI6IFsKICAgICAgewogICAgICAgICJuYW1lc3BhY2UiOiAic3RhdGUtaHViIiwKICAgICAgICAiYXBwIjogInN0YXRlLWh1YiIKICAgICAgfQogICAgXSwKICAgICJhcGlfZWdyZXNzIjogWwogICAgICB7CiAgICAgICAgImlwIjogIjEwLjQzLjAuMSIsCiAgICAgICAgInBvcnQiOiA0NDMKICAgICAgfSwKICAgICAgewogICAgICAgICJpcCI6ICI5Mi4yMDUuNjIuMjM5IiwKICAgICAgICAicG9ydCI6IDY0NDMKICAgICAgfQogICAgXSwKICAgICJpbnRha2UiOiB0cnVlLAogICAgImxpZmVjeWNsZSI6IHRydWUKICB9Cn0K" + }, + { + "digest": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiLAogICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOmFwcHMvRGVwbG95bWVudDppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbiIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInNlbGVjdG9yIjogewogICAgICAibWF0Y2hMYWJlbHMiOiB7CiAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgIH0KICAgIH0sCiAgICAic3RyYXRlZ3kiOiB7CiAgICAgICJ0eXBlIjogIlJlY3JlYXRlIgogICAgfSwKICAgICJ0ZW1wbGF0ZSI6IHsKICAgICAgIm1ldGFkYXRhIjogewogICAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICAgIH0sCiAgICAgICAgImxhYmVscyI6IHsKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9jb21wb25lbnQiOiAicmV2aWV3IiwKICAgICAgICAgICJhcHAua3ViZXJuZXRlcy5pby9uYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInNwZWMiOiB7CiAgICAgICAgImF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4iOiBmYWxzZSwKICAgICAgICAiY29udGFpbmVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImVudiI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0tFWUNBUEVfSVNTVUVSIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJodHRwczovL2tjLmNvdWxvbWIuc29jaWFsIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiSU5GRF9DT05UQUlORVJfQ09ORklHIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIvY29uZmlndXJhdGlvbi9ydW50aW1lLmpzb24iCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAiaW1hZ2UiOiAiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAgICAgICAgICAgImxpdmVuZXNzUHJvYmUiOiB7CiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgInBvcnRzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb250YWluZXJQb3J0IjogODA4MCwKICAgICAgICAgICAgICAgICJuYW1lIjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZWFkaW5lc3NQcm9iZSI6IHsKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicGVyaW9kU2Vjb25kcyI6IDEwLAogICAgICAgICAgICAgICJ0aW1lb3V0U2Vjb25kcyI6IDIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInJlc291cmNlcyI6IHsKICAgICAgICAgICAgICAibGltaXRzIjogewogICAgICAgICAgICAgICAgImNwdSI6ICI1MDBtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiMjU2TWkiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAicmVxdWVzdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjVtIiwKICAgICAgICAgICAgICAgICJtZW1vcnkiOiAiNjRNaSIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAgICAgImFsbG93UHJpdmlsZWdlRXNjYWxhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJjYXBhYmlsaXRpZXMiOiB7CiAgICAgICAgICAgICAgICAiZHJvcCI6IFsKICAgICAgICAgICAgICAgICAgIkFMTCIKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZWFkT25seVJvb3RGaWxlc3lzdGVtIjogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3RhcnR1cFByb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMTIsCiAgICAgICAgICAgICAgImh0dHBHZXQiOiB7CiAgICAgICAgICAgICAgICAicGF0aCI6ICIvaGVhbHRoeiIsCiAgICAgICAgICAgICAgICAicG9ydCI6ICJodHRwIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAidGltZW91dFNlY29uZHMiOiAyCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJzZWN1cml0eUNvbnRleHQiOiB7CiAgICAgICAgICAiZnNHcm91cCI6IDEwMDAxLAogICAgICAgICAgImZzR3JvdXBDaGFuZ2VQb2xpY3kiOiAiT25Sb290TWlzbWF0Y2giLAogICAgICAgICAgInJ1bkFzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJydW5Bc05vblJvb3QiOiB0cnVlLAogICAgICAgICAgInJ1bkFzVXNlciI6IDEwMDAxLAogICAgICAgICAgInNlY2NvbXBQcm9maWxlIjogewogICAgICAgICAgICAidHlwZSI6ICJSdW50aW1lRGVmYXVsdCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzZXJ2aWNlQWNjb3VudE5hbWUiOiAicmV2aWV3IiwKICAgICAgICAidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOiA0NSwKICAgICAgICAidm9sdW1lcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSIsCiAgICAgICAgICAgICJwZXJzaXN0ZW50Vm9sdW1lQ2xhaW0iOiB7CiAgICAgICAgICAgICAgImNsYWltTmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAicnVudGltZSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJlbXB0eURpciI6IHsKICAgICAgICAgICAgICAibWVkaXVtIjogIk1lbW9yeSIsCiAgICAgICAgICAgICAgInNpemVMaW1pdCI6ICIxNk1pIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ0bXAiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiY29uZmlnTWFwIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI5MiwKICAgICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAiY29uZmlndXJhdGlvbiIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImNhbGxlciIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiYXVkaWVuY2UiOiAiZmxleC1hdXRoIiwKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiAzNjAwLAogICAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXQogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICJzZWNyZXQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJpdGVtcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImtleSI6ICJ0b2tlbiIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogInRva2VuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tYXVkaXQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImt1YmVybmV0ZXMtYXBpIiwKICAgICAgICAgICAgInByb2plY3RlZCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgInNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJzZXJ2aWNlQWNjb3VudFRva2VuIjogewogICAgICAgICAgICAgICAgICAgICJleHBpcmF0aW9uU2Vjb25kcyI6IDYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2EuY3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAiY2EuY3J0IgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAia3ViZS1yb290LWNhLmNydCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24td29ya2xvYWQtcmVnaXN0cnkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogIndvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAic2l0dGluZy1yZXF1ZXN0ZXIiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAiY2xpZW50LXNlY3JldCIsCiAgICAgICAgICAgICAgICAgICJwYXRoIjogImNsaWVudC1zZWNyZXQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAib3B0aW9uYWwiOiBmYWxzZSwKICAgICAgICAgICAgICAic2VjcmV0TmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1zaXR0aW5nLXJlcXVlc3RlciIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfQogIH0KfQo=" + }, + { + "digest": "sha256:e59ab44b1aaf28140509593aae4ab9b97ab62cc8b589e3f1552bac78618896dd", + "media_type": "application/json", + "content_base64": "ewogICJwcm9wb3NhbCI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIsCiAgIm9ic2VydmVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjQ6MDEuOTg1MTI4KzAwOjAwIiwKICAibmF0aXZlX293bmVyX3B1YmxpY2F0aW9uX2pvYiI6IHsKICAgICJpZCI6IDExNDg0LAogICAgIm5hbWUiOiAicHVibGlzaC1jYW5kaWRhdGUiLAogICAgImhlYWRfYnJhbmNoIjogIm1haW4iLAogICAgImhlYWRfc2hhIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgInJ1bl9udW1iZXIiOiAzLAogICAgImV2ZW50IjogInB1c2giLAogICAgImRpc3BsYXlfdGl0bGUiOiAiUHJlcGFyZSByZWFkYWJsZSBvdmVybGF5IGNvbnRleHQgd2l0aCB0aGUgYWRtaXR0ZWQgbGVnYWN5IGJ1aWxkZXIiLAogICAgInN0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJ3b3JrZmxvd19pZCI6ICJwdXJwb3NlLW92ZXJsYXktaW1hZ2UueWFtbCIsCiAgICAidXJsIjogImh0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uL2FjdGlvbnMvcnVucy8zIiwKICAgICJjcmVhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjA6NTlaIiwKICAgICJ1cGRhdGVkX2F0IjogIjIwMjYtMTAtMTFUMDE6MjE6MDhaIiwKICAgICJydW5fc3RhcnRlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjIwOjU5WiIKICB9LAogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInBvbGljeV9zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgInJlZ2lzdHJ5X3Byb29mX3NoYTI1NiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAic291cmNlX3JlbmRlcl9jaGFuZ2Vfb25seSI6ICJEZXBsb3ltZW50L2luZm9ybWVkLWRlY2lzaW9uIHNwZWMudGVtcGxhdGUuc3BlYy5jb250YWluZXJzWzBdLmltYWdlIiwKICAicnVudGltZV9jb25maWdtYXBfdW5jaGFuZ2VkIjogImluZm9ybWVkLWRlY2lzaW9uLXJ1bnRpbWUtNmMyMjE4NzhkMDUxIiwKICAiaW5zdGFsbGVkX2ltYWdlX2V4ZWN1dGlvbiI6IHsKICAgICJpbW11dGFibGVfcmVnaXN0cnlfYXJ0aWZhY3RfcHVsbGVkX2Fub255bW91c2x5IjogdHJ1ZSwKICAgICJVSUQiOiAxMDAwMSwKICAgICJHSUQiOiAxMDAwMSwKICAgICJwb2xpY3lfZmlsZV9VSUQiOiAwLAogICAgInBvbGljeV9maWxlX21vZGUiOiAiMDY0NCIsCiAgICAicHVycG9zZV92YXJpYW50cyI6IDEwLAogICAgImJpbmRpbmdfZm9ybXNfYWxsb3dlZCI6IDIsCiAgICAiYWR2aXNvcnlfb3JfbWFsZm9ybWVkX3JlZnVzZWQiOiA4LAogICAgIm5ldHdvcmsiOiAibm9uZSIsCiAgICAicmVhZF9vbmx5IjogdHJ1ZSwKICAgICJzeW50aGV0aWNfdHJhbnNwb3J0IjogdHJ1ZSwKICAgICJuYXRpdmVfUERQX3Rlc3QiOiBmYWxzZQogIH0sCiAgInNjYW5fc3VtbWFyeV9zaGEyNTYiOiAiMGVlNTY0MDBkYzcwM2Y3Yzk5NjhjMmEwYTNlYTAzOTBkODM2MmY4ZDBiYmY4MDAyYTJiZDdmYTU4ZjE5Y2I0NCIsCiAgImhpc3RvcmljYWxfZmFpbGVkX3J1bnNfcmV0YWluZWQiOiBbCiAgICAiZjY2ZGU1MDUvdGFzazExNDgyL3J1bjEiLAogICAgImFjZWNhZDg4Ny90YXNrMTE0ODMvcnVuMiIKICBdLAogICJuYXRpdmVfaG9zdGluZ19jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJodW1hbl9hcHByb3ZhbCI6IGZhbHNlLAogICJldmlkZW5jZV9maWxlX3NoYTI1NiI6IHsKICAgICJpbWFnZS1tYW5pZmVzdC5qc29uIjogIjk3OGM1NzVkM2M3YmYwZGUzOWRiZTRlOTU2N2MzOWNkMzZmNzBiN2U1NWJjMTczNTdiZGIwM2ZiM2I5NmIwZmIiLAogICAgImltYWdlLWNvbmZpZy5qc29uIjogIjRhZDcyNDljNzVmZDlmYzAzOWNlYjE4Njc3MjQxOWUxY2JhNWZkOTc1OWM0MDQ1NTY0NTljODBhMmQyODVkMTAiLAogICAgImJhc2UtaW1hZ2UtY29uZmlnLmpzb24iOiAiYjcwNmM5MjA5ZTMyNGYzOWE4NmZmY2RhMmEzZTlkOTRjOTI2NDk3MzlhZDViMjFmZTQ2MTEwMDZlMzZmNmYwMCIsCiAgICAicmVnaXN0cnktcHJvb2YuanNvbiI6ICI1YWEyYzFmNzgwYzQ3ZjYyZmE5YjU5ZGE5NTQzZDgyYzA3YWZhMDJiMWQ5NDZlNjE0NGI4YTA0MmVmODZmMjEzIiwKICAgICJ0cml2eS1mdWxsLmpzb24iOiAiZjM4YThmN2U2YzQxOWVlZDkxNTRkNzc2MmY5MzJiOWRlYjY2ODBhNjIyMjQ3YjA4MTk2Yjc0NThiODkzNDM0ZSIsCiAgICAic2JvbS5jZHguanNvbiI6ICJhNDI1Mjk1MWUyMDI3NDcyYzI2ZDg2NzljYjU0M2UzMDk4MzE4MDgwOWQ2ZGQzYzdjOTRiODgzZDYyODAzZTVkIiwKICAgICJiYXNlLXRyaXZ5LWZ1bGwuanNvbiI6ICJkNDRjNTU1YWVjYmIxYTQ1MThmNDEyN2Q0ODAxNWVhNDU5MzI1YzkzZThiMDM3MTkxMGE1NWRlNDcyOTNjYTgwIiwKICAgICJjaGVja19pbnN0YWxsZWQucHkiOiAiYTM0YTUxYmU5YzlmMmIxNmEwNmE4ODE3M2I1YzZjNDkyYzk5NTdmZTAyMWNmNDEyYTg2YTE3Mzc3MzA2NDBhZCIsCiAgICAidmVyaWZ5X3JlZ2lzdHJ5LnB5IjogIjQxM2Y1NzVjMjFhMmJkMThhMzY5NmY4ZjJkOTM5ZWVhZGM1MmQ3NmYyODJjNDI4MTNmNzZiYjBlM2VlOGEyYTQiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAicmV2aWV3LXJlZmluZW1lbnQuanNvbiI6ICJlYTYyODQ1Y2VlNWVlNmY0ZjZjYjdmNWRjZDBhZjYwMWJhMjlhMjFjOGZmODBlZmJiYzAyYWQxNmUzNWJlYTc1IiwKICAgICJ0ZXN0X2NoYW5nZV9ndWFyZC5weSI6ICJkYTUzNTA0MzczNTdiYTMyOTIzNmNjMTM3NjEwYzAzODU2ZjM4ZjgzNmRkZjI4NTYwMjViYzEyMDExZmFkMDdmIiwKICAgICJ0ZXN0X3NxbGl0ZV9yZWFkb25seS5weSI6ICJjN2E5MWQwYzZhMzczZDczOGM4OGJiODE3ZDliZmIyZmY4YTE3OWJjNjFiOTMwNjNiODk2NzdiNTY2NTIwMzIzIiwKICAgICJ0ZXN0X3ByZWZsaWdodF9vcHRpbWl6YXRpb24ucHkiOiAiYTBjNGZhMThjNWQ2YzIxNDc2YTA2YzZkMDVmZTc2NTYyNTlkMjA0Mjk5MTM4ODUxNTk5ZTkyMTRkOTExMjA2ZCIsCiAgICAiaW5pdGlhbC1hcHByb3ZlZC1iYzY0OTRjZC9zcWxpdGVfcmVhZG9ubHkucHkiOiAiZWVmNTNkZDIzM2VlZTc0YzE3ZjIwODIzYmQ3ZjU3ODdjNjBjYWQ3OWFjNjQ4MDIxYzk0Nzk2NDNjNmNlOWUzOCIKICB9LAogICJ2ZXJzaW9uMl9zb3VyY2VfcG9pbnRlcl9yZWZpbmVtZW50IjogewogICAgIm9yaWdpbmFsX3JlY2VpcHRfc2hhMjU2IjogIjhhNjc2YzM4Zjg5ZjljYTc2MmI4ZWJlOTQ1YjVhY2I5MGQ0N2E0Y2IzNTA2OTI2ODdhYmI5ODViYmIyZDhhZTIiLAogICAgIm9yaWdpbmFsX3JlY2VpcHRfYXJjaGl2ZSI6ICJpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkL3B1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvbiIsCiAgICAicmVhc29uIjogIktlZXAgaGlzdG9yaWNhbCBvcmlnaW5hbCBwcmUtb3BlbiBjaGVja2VyIGhhc2ggYm91bmQgdG8gZXhhY3QgYXJjaGl2ZWQgb3JpZ2luYWwgYnl0ZXM7IGN1cnJlbnQgdmVyc2lvbjIgY2hlY2tlciBpcyBpbmRlcGVuZGVudGx5IGRpcmVjdC1wYWNrZXQvcGxhbiBib3VuZC4gQWN0dWFsIGltYWdlL3JlZ2lzdHJ5L3NjYW4vU0JPTSBwcm9vZiB1bmNoYW5nZWQ7IG5vIG5ldyBhcnRpZmFjdCB2ZXJpZmljYXRpb24gb3IgbmF0aXZlIHZlcnNpb24yIGFjdGlvbiBjbGFpbWVkLiIKICB9Cn0K" + }, + { + "digest": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZV9kaWdlc3QiOiAic2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgImJhc2VfaW1hZ2VfZGlnZXN0IjogInNoYTI1Njo3ZjVjNmNiMjljOWY3MGEwMjZiZmUzMGU3MjkzNDI3NGRkYzY5MjYxNjc2Y2Y2ZDQ3NmY4MWRkMzI4MTJkMTczIiwKICAiYmFzZV9sYXllcl9ieXRlc19pZGVudGljYWwiOiB0cnVlLAogICJsYXllcl9tZWRpYV90eXBlX2NvbnZlcnNpb24iOiAiT0NJIGd6aXAgdG8gRG9ja2VyIGd6aXAsIHNhbWUgZGlnZXN0IGFuZCBzaXplIiwKICAiYmFzZV9ydW50aW1lX2NvbmZpZ19zZW1hbnRpY3NfaWRlbnRpY2FsIjogdHJ1ZSwKICAibGVnYWN5X2J1aWxkZXJfY29uZmlnX2FkZGl0aW9ucyI6IHsKICAgICJIb3N0bmFtZSI6ICIiLAogICAgIkRvbWFpbm5hbWUiOiAiIiwKICAgICJBdHRhY2hTdGRpbiI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZG91dCI6IGZhbHNlLAogICAgIkF0dGFjaFN0ZGVyciI6IGZhbHNlLAogICAgIlR0eSI6IGZhbHNlLAogICAgIk9wZW5TdGRpbiI6IGZhbHNlLAogICAgIlN0ZGluT25jZSI6IGZhbHNlLAogICAgIkNtZCI6IG51bGwsCiAgICAiVm9sdW1lcyI6IG51bGwsCiAgICAiT25CdWlsZCI6IG51bGwsCiAgICAiSW1hZ2UiOiAic2hhMjU2OjkwZjE1NzRmOWVkYTM1ZmE2Y2I5NzI5NjFiZWIyN2E3Y2I5MDRjMzY1NjBlMzgxOTMwYjBlMTQwNjVjMjM4ODMiCiAgfSwKICAiYmFzZV9yb290ZnNfcHJlZml4X2lkZW50aWNhbCI6IHRydWUsCiAgIm92ZXJsYXlfcmVndWxhcl9maWxlcyI6IFsKICAgICJvcHQvdmVudi9saWIvcHl0aG9uMy4xMi9zaXRlLXBhY2thZ2VzL2luZm9ybWVkX2RlY2lzaW9uL3BvbGljeS5weSIKICBdLAogICJvdmVybGF5X2RpcmVjdG9yaWVzIjogWwogICAgIm9wdCIsCiAgICAib3B0L3ZlbnYiLAogICAgIm9wdC92ZW52L2xpYiIsCiAgICAib3B0L3ZlbnYvbGliL3B5dGhvbjMuMTIiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMiLAogICAgIm9wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24iCiAgXSwKICAicG9saWN5X3NoYTI1NiI6ICI5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyIiwKICAicG9saWN5X21vZGUiOiAiMDY0NCIsCiAgImJhc2VfdXNlciI6ICIxMDAwMToxMDAwMSIsCiAgInNvdXJjZV9zY29wZV9sYWJlbHMiOiB7CiAgICAib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnJldmlzaW9uIjogIjNlNGJjYjI2ZjhlZWFhOGM2NDM0NWM1NjU0NzdiNWFjOGNjYmIxNjgiLAogICAgIm9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5iYXNlLmRpZ2VzdCI6ICJzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MyIsCiAgICAic29jaWFsLmNvdWxvbWIuc291cmNlLnBvbGljeS5zaGEyNTYiOiAiOWQ3YzFiZTRjYjYxOTlkMTRlZjBhYWVhZDVmODU5NTFmNDViMGNjYmQ3YzgwMGE3ZmRlOTIyYTI1MzU2NmI2MiIsCiAgICAic29jaWFsLmNvdWxvbWIucmVsZWFzZS5zY29wZSI6ICJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MSIKICB9LAogICJyZWdpc3RyeV9yZWFkX3JvdXRlIjogImFub255bW91cyBwdWJsaWMgc2NvcGVkIGJlYXJlciBjaGFsbGVuZ2UsIG5vIHRva2VuIHJldGVudGlvbiIsCiAgImltYWdlX2V4ZWN1dGVkIjogZmFsc2UsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlCn0K" + }, + { + "digest": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44", + "media_type": "application/json", + "content_base64": "ewogICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2Ojc2M2MzNjQwMmM4YmU3Y2M0YzFiZDFhNjE2MjNkMWFmZjkxMTZkNTIyNDE4Nzc0MjViNDVhNzAxOGNjMDg4M2EiLAogICJzb3VyY2VfcmV2aXNpb24iOiAiM2U0YmNiMjZmOGVlYWE4YzY0MzQ1YzU2NTQ3N2I1YWM4Y2NiYjE2OCIsCiAgInNjYW5uZXIiOiAiYXF1YXNlYy90cml2eUBzaGEyNTY6NjJiMWU2NWU4ODY5YmM0YjRjNmFhNGZhMmIyMTU5NTI1NmM3YzJmNjAxOGE5ZDlhZDYxY2FmODcxODdjMTk2OSIsCiAgInZlcnNpb24iOiAiMC43NC4wIiwKICAiZGJfbWV0YWRhdGEiOiB7CiAgICAiVmVyc2lvbiI6IDIsCiAgICAiTmV4dFVwZGF0ZSI6ICIyMDI2LTEwLTExVDE4OjU5OjUwLjg4OTAxMDU3MloiLAogICAgIlVwZGF0ZWRBdCI6ICIyMDI2LTEwLTEwVDE4OjU5OjUwLjg4OTAxMDkyM1oiLAogICAgIkRvd25sb2FkZWRBdCI6ICIyMDI2LTEwLTEwVDIzOjMyOjMyLjM4MDAzMzEzMVoiCiAgfSwKICAic3VwcHJlc3Npb24iOiBmYWxzZSwKICAiaWdub3JlX3VuZml4ZWQiOiBmYWxzZSwKICAic2V2ZXJpdHlfZmlsdGVyIjogbnVsbCwKICAicGFja2FnZV9jb3VudCI6IDQ0LAogICJmaW5kaW5nc19ieV9zZXZlcml0eSI6IHsKICAgICJNRURJVU0iOiAxCiAgfSwKICAiZmluZGluZ3MiOiBbCiAgICB7CiAgICAgICJpZCI6ICJDVkUtMjAyNi04NTA5MSIsCiAgICAgICJwYWNrYWdlIjogInpsaWIiLAogICAgICAiaW5zdGFsbGVkIjogIjEuMy4yLXIwIiwKICAgICAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAgICAgInNldmVyaXR5IjogIk1FRElVTSIKICAgIH0KICBdLAogICJjb3ZlcmFnZV9saW1pdHMiOiBbCiAgICAiQWxwaW5lMy4yNCBhYnNlbnQgc2Nhbm5lciBFT0wgbGlzdDsgT1MgZGV0ZWN0b3IgcmFuIGFnYWluc3QgQWxwaW5lMy4yNCByZXBvc2l0b3J5IG9uMzhPUyBwYWNrYWdlcyIsCiAgICAiS25vd24gZmluZGluZ3MgYXNvZiBwaW5uZWREQiwgbm90IGNsYWltIGFic2VuY2Ugb2YgdW5rbm93biB2dWxuZXJhYmlsaXRpZXMiCiAgXSwKICAiaGlnaF9jcml0aWNhbCI6IDAsCiAgInNhbWVfc2Nhbm5lcl9hY3R1YWxfYmFzZV9zY2FuX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgImJhc2Vfc2Nhbl9maWxlIjogImJhc2UtdHJpdnktZnVsbC5qc29uIgp9Cg==" + }, + { + "digest": "sha256:49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5", + "media_type": "application/json", + "content_base64": "ewogICJraW5kIjogImluZm9ybWVkLWRlY2lzaW9uLnN1cGVydmlzZWQtZXhlY3V0aW9uLXNvdXJjZS1idW5kbGUiLAogICJ2ZXJzaW9uIjogMiwKICAicHJvcG9zYWxfaWQiOiAiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEiLAogICJmaWxlcyI6IHsKICAgICJSRUFETUUubWQiOiB7CiAgICAgICJzaGEyNTYiOiAiNTFiNTZjOGVjMmYzMGFkNjJmNmNkMDk3MzJjMGY3M2RkN2I1ZWJmMjA4MTMyMDIyM2M4NWJiY2JmMDBkMTVhOSIsCiAgICAgICJjb250ZW50IjogIiMgVmVyc2lvbjIgcHJvdGVjdGVkIGV4aXN0aW5nLXNuYXBzaG90IHJlc2N1ZSDigJQgcHJlcGFyZWQsIHVuYXBwcm92ZWRcblxuT3JpZ2luYWwgYXBwcm92ZWQgc291cmNlIGJjNjQ5NGNkIGNvbXBsZXRlZCBkcmlsbC1iYWNrdXAsIHRoZW4gZHJpbGwtY29weSBmYWlsZWQgYmVmb3JlIGNyZWF0aW5nIGEgbG9jYWwgc25hcHNob3QuIE9yaWdpbmFsIGpvdXJuYWwgZHJpbGwtY29weSByZW1haW5zIFVOQ0VSVEFJTi4gTWV0YWRhdGEtb25seSBjYXB0dXJlIHByb3ZlcyBleGFjdCB1bmNoYW5nZWQgbWFpbjE5NTM3OTIwYnl0ZXMvU0hBODc1Ni4uLiwgV0FMMCBhbmQgcHJpdmF0ZVNITTMyNzY4LiBTb3VyY2UgY2xvc2VzIFNRTGl0ZSBjb25uZWN0aW9ucyBleHBsaWNpdGx5OyBpbW11dGFibGUgcmVhZHMgYXJlIG9ubHkgZm9yIHRoZSBmcm96ZW4gbWFpbiBzbmFwc2hvdCB3aXRoIGV4YWN0IHByaW9yIGRpZ2VzdC9zaXplL3ByaXZhdGUgaWRlbnRpdHkgYW5kIG5vIFdBTCBmcmFtZXMuIExpdmUgc291cmNlIGFuZCBvZmZsaW5lIHByZS9wb3N0LWFkbWluIHJlYWRzIHJlbWFpbiBtb2RlPXJvL3F1ZXJ5X29ubHkgV0FMLWF3YXJlOyBpbW11dGFibGUgaXMgbmV2ZXIgYSBsaXZlIERCIG9yIHNjaGVtYS1taWdyYXRpb24gc2hvcnRjdXQuIFNpZGVjYXJzIHJlbWFpbiByZXRhaW5lZCwgbmV2ZXIgZGVsZXRlZC9jaGVja3BvaW50ZWQuXG5cbkZyZXNoIGZvdW5kZXIgYWNjZXB0YW5jZSBvZiB0aGUgZXhhY3QgbWVtbyB2ZXJzaW9uMiBpcyByZXF1aXJlZCBiZWZvcmUgYW55IHJlc2N1ZSBvciBjb250aW51YXRpb24uIE9sZCB2ZXJzaW9uMSBhY2NlcHRhbmNlIGNhbm5vdCBwYXNzIGF1dGhvcml0eSBjaGVja3MuIFJvb3QgbXVzdCBmcmVzaGx5IGF1dGhlbnRpY2F0ZSBhY3R1YWwgY29uZmlybWVkIHBlcnNvbi9wbGF0Zm9ybS1yb290IEFDQ0VQVCBhdCB0aGUgZml4ZWQgbmF0aXZlIG9yaWdpbiBiZWZvcmUgZWFjaCBwaGFzZTsgcHJvdGVjdGVkIHJlY2VpcHQgY2hlY2tpbmcgaXMgc3VwZXJ2aXNlZCBib29ra2VlcGluZywgbm90IGFuIGF1dGhlbnRpY2F0ZWQgc2lnbmVkL2F1dG9ub21vdXMgZ3JhbnQuIE5vIG5ldyBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4gaW4gdGhpcyBwcmVwYXJhdGlvbi5cblxuRml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnk7IHJvbGxiYWNrIOKGkiByb2xsYmFjay12ZXJpZnkgb25seSBhZnRlciByZWNvcmRlZCBuZXcgcmVsZWFzZSBhdHRlbXB0LiBOZXcgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24gYW5kIHJlc2N1ZS1leGVjdXRpb24tcjEubG9jayBjb2V4aXN0IHdpdGggdGhlIHVuY2hhbmdlZCBvcmlnaW5hbCBleGVjdXRpb24tam91cm5hbC5qc29uLiBUaGV5IGhhc2gtbGluayBpdHMgZXhhY3Qgb3JpZ2luYWwgYXBwcm92ZWQgaWRlbnRpdHksIENPTVBMRVRFIGJhY2t1cCBhbmQgVU5DRVJUQUlOIGNvcHkgYXR0ZW1wdCBJRHMvcmVzdWx0cy4gTm8gZXh0cmEgb3JpZ2luYWwgcGhhc2Ugb3IgcmVsZWFzZSBpcyBhbGxvd2VkOyBvcmlnaW5hbCBqb3VybmFsIGhhc2ggaXMgY2hlY2tlZCBiZWZvcmUgYW5kIGFmdGVyIGVhY2ggbmV3IHBoYXNlLiBObyBvbGQgZHJpbGwtY29weSByZXRyeS9vdmVyd3JpdGUgb3Igc3ludGhlc2l6ZWQgY29tcGxldGVkIHBoYXNlLlxuXG5CZWZvcmUgcmVzY3VlLCBvcmlnaW5hbCBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgbXVzdCBiZSBhYnNlbnQsIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50LCBhbmQgbG9jYWwgZW5naW5lIGJudC1sYXAwMDEvY3VycmVudCBuYXRpdmUgb2xkaW1hZ2U3ZjUvc291cmNlN2RiL3NlYWxlZERlcGxveW1lbnQrQ00vUFZDL29yaWdpbmFsUG9kVUlEIG11c3QgbWF0Y2guIFRoZSBvbGQgYmFja3VwIGFkbWluIGFscmVhZHkgZXhpdGVkIGFmdGVyIHVuaXF1ZWx5IGNyZWF0aW5nIHRoZSBwcml2YXRlIGZpeGVkIHNuYXBzaG90IHBhdGg7IHRoZSBvbmx5IGxhdGVyIG9yaWdpbmFsIGFjY2VzcyB3YXMgV0FMLWF3YXJlIHJlYWRvbmx5IGluc3BlY3Rpb24sIHdpdGggbm8gc25hcHNob3Qgd3JpdGVyLiBNYWluIGhhc2gsIHByaXZhdGUgaWRlbnRpdGllcyBhbmQgYWJzZW50L3plcm8gV0FMIGFyZSBjaGVja2VkIGJlZm9yZS9hZnRlciBpbW11dGFibGUgaW5zcGVjdGlvbiBhbmQgY29weS4gT3JpZ2luYWwgcHJpdmF0ZSBTSE0gaXMgaW5kZXhpbmcgYW5kIGlzIHJldGFpbmVkIHVuY2hhbmdlZC4gTm9uZW1wdHkgV0FMLCBjaGFuZ2VkIGhhc2gvbWV0YWRhdGEsIG1pc3NpbmcgZmFpbGVkIGpvdXJuYWwsIG1pc3Npbmcgb3JpZ2luIG9yIGFueSB1bnZlcmlmaWVkIG91dGNvbWUgc3RvcHMgcmVzY3VlLiBObyBuZXcgbmF0aXZlIGJhY2t1cCBpcyBtYWRlIGZvciB0aGUgZHJpbGwuIEJpbmFyeSBzbmFwc2hvdCBieXRlcyBmbG93IG9ubHkgaW50byBhIG5ldzA2MDAgbG9jYWxmaWxlLCBuZXZlciBjaGF0L2xvZy9wYWNrZXQuIFNhbWUgcmVzY3VlLXBoYXNlIHJldHJ5IGlzIHJlZnVzZWQgYWZ0ZXIgYW55IGF0dGVtcHRlZCBvdXRjb21lLlxuXG5PZmZsaW5lIHZlcmlmaWNhdGlvbiBleHBsaWNpdGx5IGNvbnN1bWVzIENPTVBMRVRFIGRyaWxsLWNvcHktcmVzY3VlLXIxIHJlc3VsdCwgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGV4YWN0IGlzb2xhdGVkIG5ldy12b2x1bWUgVUlEMC9DQVBfQ0hPV04gaW5pdGlhbGl6ZXIsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHJlYWRvbmx5L2FkbWluL3Bvc3QtYWRtaW4gY2hlY2tzIGFuZCByZXRhaW5lZCBvcmlnaW5hbCBTSEEsIHJlbWFpbnMgYm91bmRlZCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3QvQ1BVMS8xMjhNaSB3aXRoIG5vIGhvc3QvbmF0aXZlUFZDL3J1bnRpbWVjb25maWcvdG9rZW4gbW91bnRzLiBPbmx5IHRoZSBkaXNwb3NhYmxlIGNvcHkgdm9sdW1lIGNhbiBiZSByZW1vdmVkLiBDdXRvdmVyIHNuYXBzaG90IGlzIHRoZSBkaXN0aW5jdCBhbHJlYWR5LXNjb3BlZCBuZXcgY3V0b3Zlci5zcWxpdGU7IHJlc2N1ZSBuZXZlciBvdmVyd3JpdGVzIGRyaWxsLnNxbGl0ZSBvciBjcmVhdGVzIGFub3RoZXIgZHJpbGwgYmFja3VwLlxuXG5Gb3VyIGNvbW1pdHRlZCBvd25lciByZW5kZXIgR2l0IGJsb2JzIGFuZCBoZWxwZXIvY2FzZSBoYXNoZXMgbXVzdCBtYXRjaCBleGFjdCBmaW5hbCBzb3VyY2UgSEVBRC4gTWFudWFsQXBwbGljYXRpb24gcmVqZWN0cyBhbnkgYXV0b21hdGVkIGNvbmZpZ3VyYXRpb24gaW5jbHVkaW5nIHt9IG9yIHNvdXJjZSBvdmVycmlkZXMuIFNvdXJjZS1waW4gQXBwbGljYXRpb24ub3BlcmF0aW9uIHVzZXMgc2VydmVyIGRyeS1ydW4gYW5kIFVJRC9yZXNvdXJjZVZlcnNpb24vc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5L3BydW5lPWZhbHNlOyBubyB3aG9sZS1hcHAgc3luYy4gUm9sbGJhY2sgZGlzcGF0Y2ggaGFzIG5vIGZhaWxpbmctY2FuZGlkYXRlIFBvZC9EQiBkZXBlbmRlbmN5OyBzZXBhcmF0ZSByZWNvdmVyeSBwcm9vZiBjaGVja3Mgb2xkaW1hZ2UgUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9zY2hlbWE1IHJldGFpbmVkbGF0ZXN0REIuIEFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlY292ZXJ5L3ZlcmlmaWNhdGlvbiBtdXN0IGJlZ2luIGJ5MjAyNi0xMC0xMlQyMzo1OTo1OVo7IGFmdGVyIGV4cGlyeSBvYnRhaW4gYSBmcmVzaCBmb3VuZGVyIGRlY2lzaW9uLiBObyBleHBpcnkgY29udHJvbGxlciBvciBpbXBsaWNpdCBleHRlbnNpb24uXG5cbkltYWdlNzYzYy9wb2xpY3k5ZDdjIGFuZCBrbm93biBpbmhlcml0ZWQgZml4YWJsZSBNRURJVU0gcmVtYWluIHVuY2hhbmdlZDsgb3duZXIgVDA1IGR1ZU9jdDE4LiBUZW4gaW5zdGFsbGVkIGNoZWNrcyB1c2Ugc3ludGhldGljIHRyYW5zcG9ydC9uYXRpdmVfcHJvdmlkZXI9ZmFsc2UgYW5kIGRvIG5vdCBmdWxmaWxsIHNlcGFyYXRlIGFjdHVhbC1wcm92aWRlciBUMDQgZ2F0ZS4gUHJlc2VydmUgb3JpZ2luYWwgYWNjZXB0YW5jZS9iYWNrdXAvZmFpbHVyZS9oaXN0b3J5IGluIHRoaXMgc2FtZSB0cmlhbC4gVHdlbnR5LXNpeCBtb2NrZWQvc291cmNlIGV4ZWN1dG9yIHJlZ3Jlc3Npb25zIHBhc3M7IG5vIGFjdHVhbCBEQi9hZG1pbi9uYXRpdmUgY29tbWFuZCBkdXJpbmcgdGVzdHMvcHJlcGFyYXRpb24uXG5cbk5hdGl2ZSBwdWJsaWNhdGlvbiByb3V0ZTogUE9TVCBleGlzdGluZyBzb3VyY2UgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMgd2l0aCBleHBlY3RlZF92ZXJzaW9uMSBhbmQgZXhhY3QgbWVtbzIvZG9jdW1lbnRzL3N1bW1hcnksIHRoZW4gcHVibGljYXRpb25zL3Jldmlldy1yZXF1ZXN0cyB2ZXJzaW9uMi4gRnJlc2ggc291cmNlIHJlYWRiYWNrIG11c3QgcHJvdmUgY3VycmVudHZlcnNpb24xIGlzIHVuYm91bmQgYmVmb3JlIHJldmlzaW9uOyBib3VuZC9kaWZmZXJlbnQgc291cmNlIHN0b3BzLiBJbnRha2UvcmVnaXN0ZXIgcmVmdXNlIHZlcnNpb24yIGFzIGRlc2lnbmVkIGFuZCBhcmUgbm90IHVzZWQuIFJldmlldyBpbnRlZ3JhdGlvbiBjcmVhdGVzIGEgTkVXIHJldmlldy1JRCBhdCBpdHMgb3duIHZlcnNpb24xOyBmb3VuZGVyIGRpc3Bvc2l0aW9uIG1lbW9fdmVyc2lvbjEgYmVsb25ncyB0byB0aGF0IG5ldyByZXZpZXcuIFJvb3QgZnJlc2ggb3V0Y29tZXMgbXVzdCBiZSBxdWVyaWVkIGZvciBTT1VSQ0UgdmVyc2lvbjIsIGV4YWN0IG5ld3Jldmlld0lEL21lbW9TSEEgYW5kIGNvbmZpcm1lZCBuZXN0ZWQgcGVyc29uYXBwcm92YWwuIFJlY2VpcHQgb3V0Y29tZV9xdWVyeSBwaW5zIHRoYXQgc291cmNldmVyc2lvbjIgcm91dGU7IGl0IGRvZXMgbm90IGF1dGhlbnRpY2F0ZSBieSBpdHNlbGYuXG4iCiAgICB9LAogICAgImFjdHVhdG9yLnB5IjogewogICAgICAic2hhMjU2IjogIjg2YjY3ZDFhYmFkNmFmMmE4YzQ5NTI4ZmUxMjVhNWJhYjk0NDk3NWQzZTgwMTgyNmM1MTFlZTg4ODQ2NTcxYjIiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJPbmUgZml4ZWQgc3VwZXJ2aXNlZCBwaGFzZTsgbmV2ZXIgcnVuIHRoaXMgZHVyaW5nIHNvdXJjZSBwcmVwYXJhdGlvbi5cIlwiXCJcbmltcG9ydCBhcmdwYXJzZVxuaW1wb3J0IGhhc2hsaWJcbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHJlXG5pbXBvcnQgc2VsZWN0b3JzXG5pbXBvcnQgc3RhdFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0aW1lXG5cbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KCdvcHRpbWl6ZWQgaW50ZXJwcmV0ZXIgcmVmdXNlZCcpXG5cblBIQVNFUyA9ICgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCAnb2ZmbGluZS12ZXJpZnknLCAnY2xlYW51cC1vZmZsaW5lJyxcbiAgICAgICAgICAnY3V0b3Zlci1iYWNrdXAnLCAnY3V0b3Zlci1jb3B5JywgJ3JlbGVhc2UnLCAndmVyaWZ5JywgJ3JvbGxiYWNrJywgJ3JvbGxiYWNrLXZlcmlmeScpXG5cblxuZGVmIHJlcXVpcmUodmFsdWUsIHJlYXNvbik6XG4gICAgaWYgbm90IHZhbHVlOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKHJlYXNvbilcblxuXG5kZWYgc2hhKHBhdGgpOlxuICAgIGRpZ2VzdCA9IGhhc2hsaWIuc2hhMjU2KClcbiAgICB3aXRoIFBhdGgocGF0aCkub3BlbigncmInKSBhcyBzdHJlYW06XG4gICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6XG4gICAgICAgICAgICBkaWdlc3QudXBkYXRlKGJsb2NrKVxuICAgIHJldHVybiBkaWdlc3QuaGV4ZGlnZXN0KClcblxuXG5kZWYgcHJpdmF0ZShwYXRoLCBkaXJlY3Rvcnk9RmFsc2UpOlxuICAgIGluZm8gPSBQYXRoKHBhdGgpLmxzdGF0KClcbiAgICByZXF1aXJlKChzdGF0LlNfSVNESVIoaW5mby5zdF9tb2RlKSBpZiBkaXJlY3RvcnkgZWxzZSBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSlcbiAgICAgICAgICAgIGFuZCBpbmZvLnN0X3VpZCA9PSBvcy5nZXR1aWQoKSBhbmQgc3RhdC5TX0lNT0RFKGluZm8uc3RfbW9kZSkgPT0gKDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxuICAgICAgICAgICAgYW5kIChkaXJlY3Rvcnkgb3IgaW5mby5zdF9ubGluayA9PSAxKSwgJ3ByaXZhdGUgb3duZWQgY3VzdG9keSByZXF1aXJlZCcpXG5cblJPT1QgPSBQYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50XG5DQVNFID0gUk9PVC5wYXJlbnRcbk9XTkVSID0gUGF0aCgnL2hvbWUvd29yc2NoL2luZm9ybWVkLWRlY2lzaW9uJylcbkNVU1RPRElBTiA9IFBhdGgoJy9ob21lL3dvcnNjaC90aGUtY3VzdG9kaWFuJylcbkNVU1RPRFkgPSBDVVNUT0RJQU4gLyAnLnByaXZhdGUtYmFja3Vwcy8yMDI2MTAxMS1pbmZkLXB1cnBvc2UtcjEnXG5TT0NLRVQgPSAndW5peDovLy92YXIvcnVuL2RvY2tlci5zb2NrJ1xuSU1BR0UgPSAnZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhJ1xuVk9MVU1FID0gJ2luZmQtcHVycG9zZS1yMS1yZXN0b3JlLTIwMjYxMDExJ1xuTUFYX0JZVEVTID0gNTEyICogMTAyNCoqMlxuXG5cbmRlZiBydW4oYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTkwKTpcbiAgICByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndiwgaW5wdXQ9Ym9keSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIGpzb25fcmVzdWx0KHJlc3VsdCk6XG4gICAgdHJ5OlxuICAgICAgICB2YWx1ZSA9IGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcbiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6XG4gICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhZmUgcGhhc2UgcmVjZWlwdCB1bmF2YWlsYWJsZTsgb3V0Y29tZSB1bmNlcnRhaW4nKSBmcm9tIE5vbmVcbiAgICByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlID09IDAgYW5kIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIFRydWUsXG4gICAgICAgICAgICAncGhhc2UgZGlkIG5vdCB2ZXJpZnkgY29tcGxldGU7IHJhdyBvdXRwdXQgd2l0aGhlbGQ7IG5vIHJldHJ5JylcbiAgICBwZXJtaXR0ZWQgPSB7J3BoYXNlJywgJ2FsbF9jaGVja3NfcGFzcycsICdyYXdfb3V0cHV0X3dpdGhoZWxkJywgJ25hdGl2ZV9hcHByb3ZhbF92ZXJpZmllZF9ieV9yb290JyxcbiAgICAgICAgICAgICAgICAgJ25hdGl2ZV9hdXRoZW50aWNhdGVkX2dyYW50JywgJ3NvdXJjZV9yZWFkb25seV9iYXNlbGluZScsICdzbmFwc2hvdF9yZWFkb25seScsXG4gICAgICAgICAgICAgICAgICdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICduYXRpdmVfcGFyZW50X3ByaXZhdGUnLFxuICAgICAgICAgICAgICAgICAnbmF0aXZlX3VpZCcsICdwb2RfbmFtZScsICdwb2RfdWlkJywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnLFxuICAgICAgICAgICAgICAgICAnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzJywgJ29wZXJhdGlvbl9yZXF1ZXN0ZWQnLCAnc291cmNlX3JldmlzaW9uJyxcbiAgICAgICAgICAgICAgICAgJ3Jlc291cmNlcycsICdwcnVuZScsICdyb2xsb3V0X3ZlcmlmaWVkJywgJ2xhdGVzdF9saXZlX2RhdGFiYXNlX3JldGFpbmVkJyxcbiAgICAgICAgICAgICAgICAgJ2NsaWVudF9kaWZmX3NoYTI1NicsICduYXRpdmVfcm9sbG91dF92ZXJpZmllZCcsICdjdXJyZW50X3NjaGVtYTVfZGF0YWJhc2VfcmV0YWluZWQnLFxuICAgICAgICAgICAgICAgICAncHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJywgJ2luc3RhbGxlZF9wdXJwb3NlX2NoZWNrcycsICdwb2xpY3lfc2hhMjU2JyxcbiAgICAgICAgICAgICAgICAgJ3BvbGljeV9tb2RlJywgJ3BvbGljeV91aWQnLCAnaGVhbHRoX3N0YXR1c2VzJywgJ25hdGl2ZV9wcm92aWRlcl9wcm9iZScsICdyZWNvdmVyeV92ZXJpZmljYXRpb24nfVxuICAgIHJlcXVpcmUoc2V0KHZhbHVlKSA8PSBwZXJtaXR0ZWQsICd1bmV4cGVjdGVkIG91dHB1dCBmaWVsZHMgd2l0aGhlbGQnKVxuICAgIGZyb20gcmVjZWlwdF9zYWZldHkgaW1wb3J0IGNvdW50c1xuICAgIGZvciBuYW1lIGluICgnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lJywgJ3NuYXBzaG90X3JlYWRvbmx5JywgJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHMnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIGNvdW50cyh2YWx1ZVtuYW1lXSlcbiAgICBmb3IgbmFtZSBpbiAoJ3NuYXBzaG90X3NoYTI1NicsICdjbGllbnRfZGlmZl9zaGEyNTYnKTpcbiAgICAgICAgaWYgbmFtZSBpbiB2YWx1ZTpcbiAgICAgICAgICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtZjAtOV17NjR9JywgdmFsdWVbbmFtZV0pIGlzIG5vdCBOb25lLCAnaW52YWxpZCBvdXRwdXQgZGlnZXN0IHdpdGhoZWxkJylcbiAgICBpZiAnc25hcHNob3RfYnl0ZXMnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHR5cGUodmFsdWVbJ3NuYXBzaG90X2J5dGVzJ10pIGlzIGludCBhbmQgMCA8IHZhbHVlWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICAgICAnaW52YWxpZCBvdXRwdXQgc2l6ZSB3aXRoaGVsZCcpXG4gICAgaWYgJ3NuYXBzaG90X2ZpbGUnIGluIHZhbHVlOlxuICAgICAgICByZXF1aXJlKHZhbHVlWydzbmFwc2hvdF9maWxlJ10gaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSwgJ2ludmFsaWQgb3V0cHV0IGZpbGUgd2l0aGhlbGQnKVxuICAgIHJldHVybiB2YWx1ZVxuXG5cbmRlZiBkb2NrZXIoYXJndiwgYm9keT1Ob25lLCB0aW1lb3V0PTEyMCk6XG4gICAgcmV0dXJuIHJ1bihbJ2RvY2tlcicsICctLWNvbmZpZycsIHN0cihDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKSwgJy0taG9zdCcsIFNPQ0tFVF0gKyBhcmd2LFxuICAgICAgICAgICAgICAgYm9keT1ib2R5LCB0aW1lb3V0PXRpbWVvdXQpXG5cblxuZGVmIHJlbW90ZShwaGFzZSwgcmV2aXNpb24sIGFwcHJvdmVkLCBzbmFwc2hvdF9pZGVudGl0eT1Ob25lKTpcbiAgICAjIEZpeGVkIG1vZHVsZSBpbXBvcnRlZCBvbmx5IGFmdGVyIG1haW4gdmVyaWZpZXMgZXZlcnkgZXhlY3V0b3Igc291cmNlIGhhc2guXG4gICAgZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuICAgIHBheWxvYWQgPSB7J3NuYXBzaG90X2lkZW50aXR5Jzogc25hcHNob3RfaWRlbnRpdHksICdwaGFzZSc6IHBoYXNlLCAnc291cmNlX3JldmlzaW9uJzogcmV2aXNpb24sICdhcHByb3ZhbCc6IGFwcHJvdmVkLFxuICAgICAgICAgICAgICAgJ3NlYWxlZCc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLFxuICAgICAgICAgICAgICAgJ2RlcGVuZGVuY2llcyc6IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLW5hdGl2ZS1kZXBlbmRlbmNpZXMuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdjYW5kaWRhdGUnOiBqc29uLmxvYWRzKChDQVNFIC8gJ2NhbmRpZGF0ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICdyZWNlaXB0X3NhZmV0eSc6IChST09UIC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCksXG4gICAgICAgICAgICAgICAncHVycG9zZV9jaGVja3MnOiAoQ0FTRSAvICdjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICdyZWFkb25seSc6IChDQVNFIC8gJ3NxbGl0ZV9yZWFkb25seS5weScpLnJlYWRfdGV4dCgpfVxuICAgIHNjcmlwdCA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAnX19HVUFSRF9fJywgcmVwcigoQ0FTRSAvICdjaGFuZ2VfZ3VhcmQucHknKS5yZWFkX3RleHQoKSkpXG4gICAgcmV0dXJuIGpzb25fcmVzdWx0KHJ1bihbJ3NzaCcsICdyYWlsaWFuY2UwMScsICdweXRob24zIC0nXSwgc2NyaXB0LCB0aW1lb3V0PTIwMCkpXG5cblxuZGVmIGNvcHlfc25hcHNob3QocGhhc2UsIHJldmlzaW9uLCBhcHByb3ZlZCwgam91cm5hbCk6XG4gICAgcHJpb3IgPSAoam91cm5hbC5kYXRhWydpZGVudGl0eSddWydyZWNvdmVyeV9hbmNob3InXVsnYmFja3VwX3Jlc3VsdCddXG4gICAgICAgICAgICAgaWYgcGhhc2UgPT0gJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyBlbHNlIGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2N1dG92ZXItYmFja3VwJ11bJ3Jlc3VsdCddKVxuICAgIG1ldGFkYXRhID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIGZvciBrZXkgaW4gKCdzbmFwc2hvdF9zaGEyNTYnLCAnc25hcHNob3RfYnl0ZXMnLCAnc25hcHNob3RfZmlsZScsICdzbmFwc2hvdF9yZWFkb25seScpOlxuICAgICAgICByZXF1aXJlKG1ldGFkYXRhW2tleV0gPT0gcHJpb3Jba2V5XSwgJ2Nsb3NlZCBmcm96ZW4gc25hcHNob3QgY2hhbmdlZCcpXG4gICAgbmFtZSA9IG1ldGFkYXRhWydzbmFwc2hvdF9maWxlJ11cbiAgICByZXF1aXJlKG5hbWUgaW4gKCdkcmlsbC5zcWxpdGUnLCAnY3V0b3Zlci5zcWxpdGUnKSBhbmQgMCA8IG1ldGFkYXRhWydzbmFwc2hvdF9ieXRlcyddIDw9IE1BWF9CWVRFUyxcbiAgICAgICAgICAgICdmaXhlZCBib3VuZGVkIHNuYXBzaG90IHJlcXVpcmVkJylcbiAgICBwb2QgPSBtZXRhZGF0YVsncG9kX25hbWUnXVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInW2EtejAtOV0oWy1hLXowLTldKlthLXowLTldKT8nLCBwb2QpIGlzIG5vdCBOb25lLCAnZml4ZWQgb3duZXIgcG9kIG5hbWUgcmVxdWlyZWQnKVxuICAgIGxvY2FsID0gQ1VTVE9EWSAvIG5hbWVcbiAgICBmZCA9IG9zLm9wZW4obG9jYWwsIG9zLk9fV1JPTkxZIHwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1csIDBvNjAwKVxuICAgICMgQmluYXJ5IHNuYXBzaG90IHN0ZG91dCBnb2VzIG9ubHkgdG8gYSBwcml2YXRlIGZpbGUsIG5ldmVyIHRvb2wvY2hhdC9sb2cgb3V0cHV0LlxuICAgICMgU25hcHNob3Qgc2NoZW1hL2NvdW50IG1ldGFkYXRhIHdhcyB2YWxpZGF0ZWQgYmVmb3JlIG9wZW5pbmcgdGhpcyBkZXN0aW5hdGlvbi5cbiAgICB3aXRoIG9zLmZkb3BlbihmZCwgJ3diJykgYXMgZGVzdGluYXRpb246XG4gICAgICAgIGNvbW1hbmQgPSAoJ2t1YmVjdGwgZXhlYyAtbiBpbmZvcm1lZC1kZWNpc2lvbiAnICsgcG9kICtcbiAgICAgICAgICAgICAgICAgICAnIC1jIGluZm9ybWVkLWRlY2lzaW9uIC0tIGNhdCAvZGF0YS9wcml2YXRlL3B1cnBvc2Utb3ZlcmxheS1yMS8nICsgbmFtZSlcbiAgICAgICAgdHJhbnNmZXIgPSBzdWJwcm9jZXNzLlBvcGVuKFsnc3NoJywgJ3JhaWxpYW5jZTAxJywgY29tbWFuZF0sIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRlcnI9c3VicHJvY2Vzcy5ERVZOVUxMKVxuICAgICAgICBzZWxlY3RvciA9IHNlbGVjdG9ycy5EZWZhdWx0U2VsZWN0b3IoKVxuICAgICAgICBzZWxlY3Rvci5yZWdpc3Rlcih0cmFuc2Zlci5zdGRvdXQsIHNlbGVjdG9ycy5FVkVOVF9SRUFEKVxuICAgICAgICBkZWFkbGluZSA9IHRpbWUubW9ub3RvbmljKCkgKyAxNTBcbiAgICAgICAgcmVjZWl2ZWQgPSAwXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdoaWxlIFRydWU6XG4gICAgICAgICAgICAgICAgcmVtYWluaW5nID0gZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZW1haW5pbmcgPiAwIGFuZCBzZWxlY3Rvci5zZWxlY3QocmVtYWluaW5nKSwgJ3ByaXZhdGUgdHJhbnNmZXIgdGltZWQgb3V0JylcbiAgICAgICAgICAgICAgICBibG9jayA9IG9zLnJlYWQodHJhbnNmZXIuc3Rkb3V0LmZpbGVubygpLCAxMDI0KioyKVxuICAgICAgICAgICAgICAgIGlmIG5vdCBibG9jazpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICByZWNlaXZlZCArPSBsZW4oYmxvY2spXG4gICAgICAgICAgICAgICAgcmVxdWlyZShyZWNlaXZlZCA8PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXSBhbmQgcmVjZWl2ZWQgPD0gTUFYX0JZVEVTLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3ByaXZhdGUgY29weSBleGNlZWRzIGZyb3plbiBzbmFwc2hvdCBzaXplJylcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbi53cml0ZShibG9jaylcbiAgICAgICAgICAgIHRyYW5zZmVyLndhaXQodGltZW91dD1tYXgoMSwgZGVhZGxpbmUgLSB0aW1lLm1vbm90b25pYygpKSlcbiAgICAgICAgZmluYWxseTpcbiAgICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKClcbiAgICAgICAgICAgIHRyYW5zZmVyLnN0ZG91dC5jbG9zZSgpXG4gICAgICAgICAgICBpZiB0cmFuc2Zlci5wb2xsKCkgaXMgTm9uZTpcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci5raWxsKClcbiAgICAgICAgICAgICAgICB0cmFuc2Zlci53YWl0KClcbiAgICAgICAgZGVzdGluYXRpb24uZmx1c2goKVxuICAgICAgICBvcy5mc3luYyhkZXN0aW5hdGlvbi5maWxlbm8oKSlcbiAgICBwcml2YXRlKGxvY2FsKVxuICAgIHJlcXVpcmUodHJhbnNmZXIucmV0dXJuY29kZSA9PSAwIGFuZCBsb2NhbC5zdGF0KCkuc3Rfc2l6ZSA9PSBtZXRhZGF0YVsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIHNoYShsb2NhbCkgPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLCAncHJpdmF0ZSBjb3B5IGluY29tcGxldGUvdW5jZXJ0YWluOyByZXRhaW4sIG5vIHJldHJ5JylcbiAgICAjIFJlLXJlYWQgaWRlbnRpdHkvaGFzaCBhZnRlciB0cmFuc2Zlci4gVGhpcyBpcyB2ZXJpZmljYXRpb24sIG5vdCBhIHdyaXRlIHJldHJ5LlxuICAgIGFmdGVyID0gcmVtb3RlKHBoYXNlLCByZXZpc2lvbiwgYXBwcm92ZWQsIHNuYXBzaG90X2lkZW50aXR5PXByaW9yKVxuICAgIHJlcXVpcmUoYWZ0ZXJbJ3BvZF91aWQnXSA9PSBtZXRhZGF0YVsncG9kX3VpZCddIGFuZCBhZnRlclsnc25hcHNob3Rfc2hhMjU2J10gPT0gbWV0YWRhdGFbJ3NuYXBzaG90X3NoYTI1NiddLFxuICAgICAgICAgICAgJ3NvdXJjZSBpZGVudGl0eS9zbmFwc2hvdCBjaGFuZ2VkIGR1cmluZyB0cmFuc2ZlcicpXG4gICAgcmV0dXJuIHsqKm1ldGFkYXRhLCAnb2ZmX2NsdXN0ZXJfcHJpdmF0ZV9jb3B5X3ZlcmlmaWVkJzogVHJ1ZSwgJ3NuYXBzaG90X2NvbnRlbnRzX291dHB1dCc6IEZhbHNlfVxuXG5cbmRlZiBvZmZsaW5lX3ZlcmlmeShqb3VybmFsKTpcbiAgICBmcm9tIHJlY2VpcHRfc2FmZXR5IGltcG9ydCBjb3VudHNcbiAgICBzbmFwc2hvdCA9IENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJ1xuICAgIHByaXZhdGUoc25hcHNob3QpXG4gICAgcHJldmlvdXMgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydyZXN1bHQnXVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdwcm90ZWN0ZWQgc25hcHNob3QgYnl0ZXMgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgcmVxdWlyZShpZGVudGl0eS5yZXR1cm5jb2RlID09IDAgYW5kIGpzb24ubG9hZHMoaWRlbnRpdHkuc3Rkb3V0KSA9PSAnYm50LWxhcDAwMScsXG4gICAgICAgICAgICAnbG9jYWwgb2ZmbGluZSBEb2NrZXIgZW5naW5lIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICByZXF1aXJlKGxpc3RlZC5yZXR1cm5jb2RlID09IDAgYW5kIFZPTFVNRSBub3QgaW4gbGlzdGVkLnN0ZG91dC5zcGxpdGxpbmVzKCksXG4gICAgICAgICAgICAnZGlzcG9zYWJsZSB2b2x1bWUgYWJzZW5jZSBub3QgdmVyaWZpZWQnKVxuICAgIG5vbmNlID0gam91cm5hbC5kYXRhWydwaGFzZXMnXVsnb2ZmbGluZS12ZXJpZnknXVsnYXR0ZW1wdF9pZCddXG4gICAgbGFiZWxzID0geydpbmZvcm1lZC1kZWNpc2lvbi5jYXNlJzogJ2luZmQtcHVycG9zZS0yMDI2MTAxMS1yMScsXG4gICAgICAgICAgICAgICdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOiAnb2ZmbGluZS1yZXN0b3JlLW9ubHknLCAnaW5mb3JtZWQtZGVjaXNpb24uYXR0ZW1wdCc6IG5vbmNlfVxuICAgIGNyZWF0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnY3JlYXRlJywgJy0tZHJpdmVyJywgJ2xvY2FsJywgJy0tbGFiZWwnLCAnaW5mb3JtZWQtZGVjaXNpb24uY2FzZT1pbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQ9JyArIG5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICctLWxhYmVsJywgJ2luZm9ybWVkLWRlY2lzaW9uLnVzZT1vZmZsaW5lLXJlc3RvcmUtb25seScsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShjcmVhdGVkLnJldHVybmNvZGUgPT0gMCBhbmQgY3JlYXRlZC5zdGRvdXQuc3RyaXAoKSA9PSBWT0xVTUUsICd2b2x1bWUgY3JlYXRpb24gdW5jZXJ0YWluOyBubyByZXRyeScpXG4gICAgaW5zcGVjdGVkID0gZG9ja2VyKFsndm9sdW1lJywgJ2luc3BlY3QnLCBWT0xVTUVdKVxuICAgIHJlcXVpcmUoaW5zcGVjdGVkLnJldHVybmNvZGUgPT0gMCwgJ25ldyB2b2x1bWUgaWRlbnRpdHkgdW5hdmFpbGFibGUnKVxuICAgIHZvbHVtZSA9IGpzb24ubG9hZHMoaW5zcGVjdGVkLnN0ZG91dClcbiAgICByZXF1aXJlKGxlbih2b2x1bWUpID09IDEgYW5kIHZvbHVtZVswXVsnTmFtZSddID09IFZPTFVNRSBhbmQgdm9sdW1lWzBdLmdldCgnTGFiZWxzJykgPT0gbGFiZWxzXG4gICAgICAgICAgICBhbmQgdm9sdW1lWzBdLmdldCgnRHJpdmVyJykgPT0gJ2xvY2FsJyBhbmQgbm90IHZvbHVtZVswXS5nZXQoJ09wdGlvbnMnKVxuICAgICAgICAgICAgYW5kIHZvbHVtZVswXS5nZXQoJ1Njb3BlJykgPT0gJ2xvY2FsJywgJ25ldyBpc29sYXRlZCB2b2x1bWUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgaWRlbnRpdHkgPSB7a2V5OiB2b2x1bWVbMF1ba2V5XSBmb3Iga2V5IGluICgnTmFtZScsICdMYWJlbHMnLCAnRHJpdmVyJywgJ1Njb3BlJywgJ0NyZWF0ZWRBdCcpfVxuICAgIGpvdXJuYWwubm90ZSgnb2ZmbGluZS12ZXJpZnknLCAnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknLCBpZGVudGl0eSlcbiAgICAjIE9uZS10aW1lIFVJRDAvQ0FQX0NIT1dOIGluaXRpYWxpemF0aW9uIGlzIGlzb2xhdGVkIHRvIHRoZSBORVcgbmFtZWQgdm9sdW1lLlxuICAgICMgTm8gaG9zdC9saXZlIFBWQy9jb25maWcvdG9rZW4gbW91bnQgZXhpc3RzOyB0aGlzIGRldGFpbCBuZWVkcyBwYWNrZXQgcmV2aWV3LlxuICAgIGluaXRpYWxpemVyID0gXCJcIlwiaW1wb3J0IGhhc2hsaWIsb3Msc3RhdCxzeXNcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoJ29wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkJylcbmZvbGRlcj0nL3Jlc3RvcmUnO2V4cGVjdGVkPUVYUEVDVEVEXG5pZiBvcy5saXN0ZGlyKGZvbGRlcik6cmFpc2UgVmFsdWVFcnJvcignbmV3IGVtcHR5IHByaXZhdGUgdm9sdW1lIHJlcXVpcmVkJylcbm9zLmNobW9kKGZvbGRlciwwbzcwMClcbmZkPW9zLm9wZW4oZm9sZGVyKycvcmV2aWV3LnNxbGl0ZScsb3MuT19DUkVBVHxvcy5PX0VYQ0x8b3MuT19OT0ZPTExPV3xvcy5PX1dST05MWSwwbzYwMClcbmRpZ2VzdD1oYXNobGliLnNoYTI1NigpO3NpemU9MFxud2l0aCBvcy5mZG9wZW4oZmQsJ3diJykgYXMgdGFyZ2V0OlxuIHdoaWxlIFRydWU6XG4gIGJsb2NrPXN5cy5zdGRpbi5idWZmZXIucmVhZCgxMDI0KioyKVxuICBpZiBub3QgYmxvY2s6YnJlYWtcbiAgc2l6ZSs9bGVuKGJsb2NrKVxuICBpZiBzaXplPjUxMioxMDI0KioyOnJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgcmVzdG9yZSBzaXplIGV4Y2VlZHMgYm91bmQnKVxuICB0YXJnZXQud3JpdGUoYmxvY2spO2RpZ2VzdC51cGRhdGUoYmxvY2spXG4gdGFyZ2V0LmZsdXNoKCk7b3MuZnN5bmModGFyZ2V0LmZpbGVubygpKVxuaWYgZGlnZXN0LmhleGRpZ2VzdCgpIT1leHBlY3RlZDpyYWlzZSBWYWx1ZUVycm9yKCdwcml2YXRlIGNvcGllZCBzbmFwc2hvdCBkaWZmZXJzJylcbm9zLmNob3duKGZvbGRlcisnL3Jldmlldy5zcWxpdGUnLDEwMDAxLDEwMDAxKTtvcy5jaG93bihmb2xkZXIsMTAwMDEsMTAwMDEpXG5wcmludCgne1wiYWxsX2NoZWNrc19wYXNzXCI6dHJ1ZSxcInByaXZhdGVfY29weV92ZXJpZmllZFwiOnRydWV9JylcblwiXCJcIi5yZXBsYWNlKCdFWFBFQ1RFRCcsIHJlcHIocHJldmlvdXNbJ3NuYXBzaG90X3NoYTI1NiddKSlcbiAgICB3aXRoIHNuYXBzaG90Lm9wZW4oJ3JiJykgYXMgc291cmNlOlxuICAgICAgICBhcmd2ID0gWydkb2NrZXInLCAnLS1jb25maWcnLCBzdHIoQ1VTVE9EWSAvICdlbXB0eS1kb2NrZXItY29uZmlnJyksICctLWhvc3QnLCBTT0NLRVQsXG4gICAgICAgICAgICAgICAgJ3J1bicsICctLXJtJywgJy1pJywgJy0tbmV0d29yaycsICdub25lJywgJy0tcmVhZC1vbmx5JywgJy0tY3B1cycsICcxJywgJy0tbWVtb3J5JywgJzEyOG0nLFxuICAgICAgICAgICAgICAgICctLXVzZXInLCAnMDowJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tY2FwLWFkZCcsICdDSE9XTicsXG4gICAgICAgICAgICAgICAgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJywgJy0tbW91bnQnLCAndHlwZT12b2x1bWUsc3JjPScgKyBWT0xVTUUgKyAnLGRzdD0vcmVzdG9yZScsXG4gICAgICAgICAgICAgICAgJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy1jJywgaW5pdGlhbGl6ZXJdXG4gICAgICAgIGNvcGllZCA9IHN1YnByb2Nlc3MucnVuKGFyZ3YsIHN0ZGluPXNvdXJjZSwgdGV4dD1UcnVlLCBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PTE1MClcbiAgICBqc29uX3Jlc3VsdChjb3BpZWQpXG4gICAgb3B0aW9ucyA9IFsncnVuJywgJy0tcm0nLCAnLWknLCAnLS1uZXR3b3JrJywgJ25vbmUnLCAnLS1yZWFkLW9ubHknLCAnLS1jcHVzJywgJzEnLCAnLS1tZW1vcnknLCAnMTI4bScsXG4gICAgICAgICAgICAgICAnLS11c2VyJywgJzEwMDAxOjEwMDAxJywgJy0tY2FwLWRyb3AnLCAnQUxMJywgJy0tc2VjdXJpdHktb3B0JywgJ25vLW5ldy1wcml2aWxlZ2VzJyxcbiAgICAgICAgICAgICAgICctLW1vdW50JywgJ3R5cGU9dm9sdW1lLHNyYz0nICsgVk9MVU1FICsgJyxkc3Q9L3Jlc3RvcmUnXVxuICAgIHJlYWRvbmx5ID0gZG9ja2VyKG9wdGlvbnMgKyBbJy0tZW50cnlwb2ludCcsICdweXRob24nLCBJTUFHRSwgJy0nLCAnLS1kYicsICcvcmVzdG9yZS9yZXZpZXcuc3FsaXRlJ10sXG4gICAgICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShyZWFkb25seS5yZXR1cm5jb2RlID09IDAsICdvZmZsaW5lIHByZS1vcGVuIHNjaGVtYS9pbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkOyBuZXZlciBvcGVuIFN0b3JlJylcbiAgICBjaGVja2VkID0gY291bnRzKGpzb24ubG9hZHMocmVhZG9ubHkuc3Rkb3V0KSlcbiAgICByZXF1aXJlKGNoZWNrZWQgPT0gcHJldmlvdXNbJ3NuYXBzaG90X3JlYWRvbmx5J10sICdmcm96ZW4gc25hcHNob3QvY2xvbmUgcmVhZG9ubHkgY291bnRzIGRpZmZlcicpXG4gICAgYWRtaW4gPSBkb2NrZXIob3B0aW9ucyArIFsnLS1lbnRyeXBvaW50JywgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJywgSU1BR0UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaW5zcGVjdCcsICctLWRiJywgJy9yZXN0b3JlL3Jldmlldy5zcWxpdGUnXSlcbiAgICByZXF1aXJlKGFkbWluLnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgYWRtaW4gcmVzdWx0IHVuY2VydGFpbicpXG4gICAgYWRtaW5fY291bnRzID0ganNvbi5sb2FkcyhhZG1pbi5zdGRvdXQpXG4gICAgcmVxdWlyZShhZG1pbl9jb3VudHMgPT0ge2tleTogY2hlY2tlZFtrZXldIGZvciBrZXkgaW4gKCdzY2hlbWFfdmVyc2lvbicsICdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyl9LFxuICAgICAgICAgICAgJ29mZmxpbmUgYWRtaW4gY2hhbmdlZCBmcm96ZW4gc25hcHNob3QgY291bnRlcnMnKVxuICAgICMgQWRtaW4gU3RvcmUgY29uc3RydWN0aW9uIG11c3Qgbm90IHNpbGVudGx5IGFsdGVyIHNjaGVtYS9pbnRlZ3JpdHkvY291bnRlcnMuXG4gICAgcG9zdCA9IGRvY2tlcihvcHRpb25zICsgWyctLWVudHJ5cG9pbnQnLCAncHl0aG9uJywgSU1BR0UsICctJywgJy0tZGInLCAnL3Jlc3RvcmUvcmV2aWV3LnNxbGl0ZSddLFxuICAgICAgICAgICAgICAgICAgKENBU0UgLyAnc3FsaXRlX3JlYWRvbmx5LnB5JykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShwb3N0LnJldHVybmNvZGUgPT0gMCwgJ29mZmxpbmUgcG9zdC1hZG1pbiByZWFkb25seSBpbnRlZ3JpdHkgZ2F0ZSByZWZ1c2VkJylcbiAgICBwb3N0X2NoZWNrZWQgPSBjb3VudHMoanNvbi5sb2Fkcyhwb3N0LnN0ZG91dCkpXG4gICAgcmVxdWlyZShwb3N0X2NoZWNrZWQgPT0gY2hlY2tlZCA9PSBwcmV2aW91c1snc25hcHNob3RfcmVhZG9ubHknXSxcbiAgICAgICAgICAgICdvZmZsaW5lIGFkbWluIGFsdGVyZWQgZnJvemVuIHNuYXBzaG90IHByb29mJylcbiAgICBwcml2YXRlKHNuYXBzaG90KVxuICAgIHJlcXVpcmUoc2hhKHNuYXBzaG90KSA9PSBwcmV2aW91c1snc25hcHNob3Rfc2hhMjU2J10sICdvcmlnaW5hbCBwcm90ZWN0ZWQgc25hcHNob3QgY2hhbmdlZCBkdXJpbmcgZHJpbGwnKVxuICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdvZmZsaW5lX3ZvbHVtZSc6IFZPTFVNRSwgJ29mZmxpbmVfcmVhZG9ubHknOiBjaGVja2VkLFxuICAgICAgICAgICAgJ29mZmxpbmVfcG9zdF9hZG1pbl9yZWFkb25seSc6IHBvc3RfY2hlY2tlZCwgJ29yaWdpbmFsX3NuYXBzaG90X2hhc2hfdW5jaGFuZ2VkJzogVHJ1ZSxcbiAgICAgICAgICAgICdjcmVhdGVkX3ZvbHVtZV9pZGVudGl0eSc6IGlkZW50aXR5LFxuICAgICAgICAgICAgJ2FkbWluX2NvdW50cyc6IGFkbWluX2NvdW50cywgJ25ldHdvcmsnOiAnbm9uZScsICdydW50aW1lX3Rva2Vuc19vcl9jb25maWdfbW91bnRlZCc6IEZhbHNlLFxuICAgICAgICAgICAgJ3NlcnZpY2VfZW50cnlwb2ludF9zdGFydGVkJzogRmFsc2UsICdvcmlnaW5hbF9zbmFwc2hvdF9yZXRhaW5lZCc6IFRydWV9XG5cblxuZGVmIGNsZWFudXBfb2ZmbGluZShqb3VybmFsKTpcbiAgICBpbnNwZWN0ZWQgPSBkb2NrZXIoWyd2b2x1bWUnLCAnaW5zcGVjdCcsIFZPTFVNRV0pXG4gICAgcmVxdWlyZShpbnNwZWN0ZWQucmV0dXJuY29kZSA9PSAwLCAnb3duZWQgZGlzcG9zYWJsZSB2b2x1bWUgaWRlbnRpdHkgdW52ZXJpZmllZCcpXG4gICAgdmFsdWUgPSBqc29uLmxvYWRzKGluc3BlY3RlZC5zdGRvdXQpXG4gICAgZXhwZWN0ZWQgPSBqb3VybmFsLmRhdGFbJ3BoYXNlcyddWydvZmZsaW5lLXZlcmlmeSddWydyZXN1bHQnXVsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknXVxuICAgIHJlcXVpcmUobGVuKHZhbHVlKSA9PSAxIGFuZCB7a2V5OiB2YWx1ZVswXS5nZXQoa2V5KSBmb3Iga2V5IGluIGV4cGVjdGVkfSA9PSBleHBlY3RlZFxuICAgICAgICAgICAgYW5kIG5vdCB2YWx1ZVswXS5nZXQoJ09wdGlvbnMnKSwgJ3ZvbHVtZSBvd25lcnNoaXAvcmVjcmVhdGlvbiBjaGFuZ2VkJylcbiAgICByZW1vdmVkID0gZG9ja2VyKFsndm9sdW1lJywgJ3JtJywgVk9MVU1FXSlcbiAgICByZXF1aXJlKHJlbW92ZWQucmV0dXJuY29kZSA9PSAwIGFuZCByZW1vdmVkLnN0ZG91dC5zdHJpcCgpID09IFZPTFVNRVxuICAgICAgICAgICAgYW5kIGRvY2tlcihbJ3ZvbHVtZScsICdpbnNwZWN0JywgVk9MVU1FXSkucmV0dXJuY29kZSAhPSAwLFxuICAgICAgICAgICAgJ2NsZWFudXAgb3V0Y29tZSBhbWJpZ3VvdXM7IGRvIG5vdCByZXRyeScpXG4gICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZSwgJ29ubHlfZGlzcG9zYWJsZV9vZmZsaW5lX3ZvbHVtZV9yZW1vdmVkJzogVk9MVU1FLFxuICAgICAgICAgICAgJ25hdGl2ZV9hbmRfb2ZmY2x1c3Rlcl9vcmlnaW5hbF9zbmFwc2hvdHNfcmV0YWluZWQnOiBUcnVlfVxuXG5cbmRlZiBtYWluKCk6XG4gICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249X19kb2NfXylcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXBoYXNlJywgY2hvaWNlcz1QSEFTRVMsIHJlcXVpcmVkPVRydWUpXG4gICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1yb290LWF1dGhvcml0eS1yZWNlaXB0JywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKVxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tcm9vdC1uYXRpdmUtb3V0Y29tZScsIHR5cGU9UGF0aCwgcmVxdWlyZWQ9VHJ1ZSlcbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yZXZpc2lvbicsIHJlcXVpcmVkPVRydWUpXG4gICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKClcbiAgICByZXF1aXJlKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdCA9PSBQYXRoKCcvdG1wL3NlY3VyaXR5LWluZmQtcHVycG9zZS1yb290LWF1dGhvcml0eS5qc29uJylcbiAgICAgICAgICAgIGFuZCBhcmdzLnJvb3RfbmF0aXZlX291dGNvbWUgPT0gUGF0aCgnL3RtcC9zZWN1cml0eS1pbmZkLXB1cnBvc2UtbmF0aXZlLW91dGNvbWUtbGF0ZXN0Lmpzb24nKSxcbiAgICAgICAgICAgICdmaXhlZCBzdXBlcnZpc2VkIHJlY2VpcHQgcGF0aHMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUocmUuZnVsbG1hdGNoKHInWzAtOWEtZl17NDB9JywgYXJncy5zb3VyY2VfcmV2aXNpb24pIGlzIG5vdCBOb25lLCAnZXhhY3Qgc291cmNlIGNvbW1pdCByZXF1aXJlZCcpXG4gICAgIyBWZXJpZnkgYWxsIHByZXBhcmVkIGV4ZWN1dG9yL2lucHV0IGJ5dGVzIGJlZm9yZSByZWFkaW5nIGF1dGhvcml0eSBvciBkaXNwYXRjaGluZy5cbiAgICBwbGFuID0ganNvbi5sb2FkcygoUk9PVCAvICdleGVjdXRpb24tcGxhbi5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgcmVxdWlyZShzZXQocGxhblsnZXhlY3V0b3JfZmlsZXMnXSkgPT0geydhY3R1YXRvci5weScsICdhdXRob3JpdHlfam91cm5hbC5weScsICduYXRpdmVfcHJvZ3JhbS5weScsICdyZWNlaXB0X3NhZmV0eS5weSd9LFxuICAgICAgICAgICAgJ2ZpeGVkIGV4ZWN1dG9yIHNvdXJjZXMgcmVxdWlyZWQnKVxuICAgIHJlcXVpcmUoc2V0KHBsYW5bJ293bmVyX3NvdXJjZV9maWxlcyddKSA9PSB7J2RlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9zZXJ2aWNlLmNhbmRpZGF0ZS5qc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGVwbG95L2xpZmVjeWNsZS9rdXN0b21pemF0aW9uLnlhbWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZXBsb3kvbGlmZWN5Y2xlL3JlZ2lzdHJpZXMuY2FuZGlkYXRlLmpzb24nfSxcbiAgICAgICAgICAgICdmaXhlZCBvd25lciBpbWFnZSBzb3VyY2VzIHJlcXVpcmVkJylcbiAgICBmb3IgcmVsYXRpdmUsIGRpZ2VzdCBpbiBwbGFuWydleGVjdXRvcl9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHRhcmdldCA9IFJPT1QgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdleGVjdXRvciBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnY2FzZV9maWxlcyddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUobm90IFBhdGgocmVsYXRpdmUpLmlzX2Fic29sdXRlKCkgYW5kICcuLicgbm90IGluIFBhdGgocmVsYXRpdmUpLnBhcnRzLFxuICAgICAgICAgICAgICAgICdjYXNlIHNvdXJjZSBwYXRoIGVzY2FwZWQnKVxuICAgICAgICB0YXJnZXQgPSBDQVNFIC8gcmVsYXRpdmVcbiAgICAgICAgcmVxdWlyZShub3QgdGFyZ2V0LmlzX3N5bWxpbmsoKSBhbmQgc2hhKHRhcmdldCkgPT0gZGlnZXN0LCAnY2FzZSBzb3VyY2UgYnl0ZXMgY2hhbmdlZCcpXG4gICAgZm9yIHJlbGF0aXZlLCBkaWdlc3QgaW4gcGxhblsnb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKTpcbiAgICAgICAgdGFyZ2V0ID0gT1dORVIgLyByZWxhdGl2ZVxuICAgICAgICByZXF1aXJlKG5vdCB0YXJnZXQuaXNfc3ltbGluaygpIGFuZCBzaGEodGFyZ2V0KSA9PSBkaWdlc3QsICdvd25lciBpbWFnZS1vbmx5IHNvdXJjZSBjaGFuZ2VkJylcbiAgICAgICAgY29tbWl0dGVkID0gc3VicHJvY2Vzcy5ydW4oWydnaXQnLCAnLUMnLCBzdHIoT1dORVIpLCAnc2hvdycsIGFyZ3Muc291cmNlX3JldmlzaW9uICsgJzonICsgcmVsYXRpdmVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlKVxuICAgICAgICByZXF1aXJlKGNvbW1pdHRlZC5yZXR1cm5jb2RlID09IDAgYW5kIGhhc2hsaWIuc2hhMjU2KGNvbW1pdHRlZC5zdGRvdXQpLmhleGRpZ2VzdCgpID09IGRpZ2VzdCxcbiAgICAgICAgICAgICAgICAnY29tbWl0dGVkIG93bmVyIHJlbmRlciBzb3VyY2UgZGlmZmVycyBmcm9tIGFwcHJvdmVkIGlucHV0cycpXG4gICAgaGVhZCA9IHJ1bihbJ2dpdCcsICctQycsIHN0cihPV05FUiksICdyZXYtcGFyc2UnLCAnSEVBRCddKVxuICAgIHJlcXVpcmUoaGVhZC5yZXR1cm5jb2RlID09IDAgYW5kIGhlYWQuc3Rkb3V0LnN0cmlwKCkgPT0gYXJncy5zb3VyY2VfcmV2aXNpb24sICdvd25lciBzb3VyY2UgSEVBRCBkaWZmZXJzJylcbiAgICBmcm9tIGF1dGhvcml0eV9qb3VybmFsIGltcG9ydCBKb3VybmFsLCBhdXRob3JpdHksIG9yaWdpbmFsX2FuY2hvclxuICAgIHByaXZhdGUoYXJncy5yb290X2F1dGhvcml0eV9yZWNlaXB0KVxuICAgIHByaXZhdGUoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKVxuICAgIHJlY2VpcHQgPSBqc29uLmxvYWRzKGFyZ3Mucm9vdF9hdXRob3JpdHlfcmVjZWlwdC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKHJlY2VpcHQuZ2V0KCduYXRpdmVfb3V0Y29tZV9zaGEyNTYnKSA9PSBzaGEoYXJncy5yb290X25hdGl2ZV9vdXRjb21lKSwgJ25hdGl2ZSBvdXRjb21lIGJ5dGVzIGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocmVjZWlwdC5nZXQoJ2V4ZWN1dG9yX3BsYW5fc2hhMjU2JykgPT0gc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgJ3Jvb3QgdmVyaWZpZWQgZXhlY3V0b3IgcGxhbiBkaWZmZXJzJylcbiAgICBhcHByb3ZlZCA9IGF1dGhvcml0eShyZWNlaXB0LCBqc29uLmxvYWRzKGFyZ3Mucm9vdF9uYXRpdmVfb3V0Y29tZS5yZWFkX3RleHQoKSksIHNoYShDQVNFIC8gJ21lbW8uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcmdzLnBoYXNlKVxuICAgIHBhcmVudCA9IENVU1RPRFkucGFyZW50XG4gICAgcHJpdmF0ZShwYXJlbnQsIGRpcmVjdG9yeT1UcnVlKVxuICAgIGlnbm9yZWQgPSBydW4oWydnaXQnLCAnLUMnLCBzdHIoQ1VTVE9ESUFOKSwgJ2NoZWNrLWlnbm9yZScsICctLW5vLWluZGV4Jywgc3RyKENVU1RPRFkgLyAnZHJpbGwuc3FsaXRlJyldKVxuICAgIHJlcXVpcmUoaWdub3JlZC5yZXR1cm5jb2RlID09IDAsICdvZmZjbHVzdGVyIGN1c3RvZHkgaXMgbm90IGlnbm9yZWQnKVxuICAgIHJlcXVpcmUoQ1VTVE9EWS5leGlzdHMoKSwgJ29yaWdpbmFsIHByb3RlY3RlZCBjdXN0b2R5IG11c3QgYWxyZWFkeSBleGlzdCcpXG4gICAgcHJpdmF0ZShDVVNUT0RZLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICBjYXBhY2l0eSA9IG9zLnN0YXR2ZnMoQ1VTVE9EWSlcbiAgICByZXF1aXJlKGNhcGFjaXR5LmZfYmF2YWlsICogY2FwYWNpdHkuZl9mcnNpemUgPj0gMiAqIE1BWF9CWVRFUyArIDE2ICogMTAyNCoqMixcbiAgICAgICAgICAgICdpbmRlcGVuZGVudCBwcm90ZWN0ZWQgY3VzdG9keSBoZWFkcm9vbSBpbnN1ZmZpY2llbnQnKVxuICAgIG9zLm1ha2VkaXJzKENVU1RPRFkgLyAnZW1wdHktZG9ja2VyLWNvbmZpZycsIG1vZGU9MG83MDAsIGV4aXN0X29rPVRydWUpXG4gICAgcHJpdmF0ZShDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnLCBkaXJlY3Rvcnk9VHJ1ZSlcbiAgICByZXF1aXJlKG5vdCBsaXN0KChDVVNUT0RZIC8gJ2VtcHR5LWRvY2tlci1jb25maWcnKS5pdGVyZGlyKCkpLCAncHVibGljIERvY2tlciByZWFkIGNvbmZpZyBtdXN0IHN0YXkgZW1wdHknKVxuICAgIGFuY2hvciA9IG9yaWdpbmFsX2FuY2hvcihDVVNUT0RZLCBwbGFuWydyZWNvdmVyeSddWydvcmlnaW5hbF9hbmNob3InXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbi5sb2FkcygoQ0FTRSAvICdvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcbiAgICBpZiBhcmdzLnBoYXNlID09ICdkcmlsbC1jb3B5LXJlc2N1ZS1yMSc6XG4gICAgICAgIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXG4gICAgICAgICAgICAgICAgYW5kIG5vdCBvcy5wYXRoLmxleGlzdHMoQ1VTVE9EWSAvICdjdXRvdmVyLnNxbGl0ZScpLCAncmVzY3VlIGRlc3RpbmF0aW9uIG11c3QgYmUgYWJzZW50JylcbiAgICAgICAgaWRlbnRpdHkgPSBkb2NrZXIoWydpbmZvJywgJy0tZm9ybWF0JywgJ3t7anNvbiAuTmFtZX19J10pXG4gICAgICAgIHJlcXVpcmUoaWRlbnRpdHkucmV0dXJuY29kZSA9PSAwIGFuZCBqc29uLmxvYWRzKGlkZW50aXR5LnN0ZG91dCkgPT0gJ2JudC1sYXAwMDEnLFxuICAgICAgICAgICAgICAgICdsb2NhbCBlbmdpbmUgaWRlbnRpdHkgY2hhbmdlZCcpXG4gICAgICAgIGxpc3RlZCA9IGRvY2tlcihbJ3ZvbHVtZScsICdscycsICctLWZvcm1hdCcsICd7ey5OYW1lfX0nXSlcbiAgICAgICAgcmVxdWlyZShsaXN0ZWQucmV0dXJuY29kZSA9PSAwIGFuZCBWT0xVTUUgbm90IGluIGxpc3RlZC5zdGRvdXQuc3BsaXRsaW5lcygpLFxuICAgICAgICAgICAgICAgICdleGlzdGluZyByZXN0b3JlIHZvbHVtZSBmb3JiaWRzIHJlc2N1ZScpXG4gICAgam91cm5hbCA9IEpvdXJuYWwoQ1VTVE9EWSwgeydwcm9wb3NhbCc6IHBsYW5bJ3Byb3Bvc2FsX2lkJ10sICdzb3VyY2VfcmV2aXNpb24nOiBhcmdzLnNvdXJjZV9yZXZpc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWVtb19zaGEyNTYnOiBzaGEoQ0FTRSAvICdtZW1vLmpzb24nKSwgJ3BsYW5fc2hhMjU2Jzogc2hhKFJPT1QgLyAnZXhlY3V0aW9uLXBsYW4uanNvbicpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZWNvdmVyeV9hbmNob3InOiBhbmNob3J9KVxuICAgIHRyeTpcbiAgICAgICAgam91cm5hbC5zdGFydChhcmdzLnBoYXNlLCBhcHByb3ZlZCkgIyBmc3luY2VkIFJVTk5JTkcgYmVmb3JlIGFueSBwaGFzZSBlZmZlY3QuXG4gICAgICAgIGlmIGFyZ3MucGhhc2UgaW4gKCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsICdjdXRvdmVyLWNvcHknKTpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNvcHlfc25hcHNob3QoYXJncy5waGFzZSwgYXJncy5zb3VyY2VfcmV2aXNpb24sIGFwcHJvdmVkLCBqb3VybmFsKVxuICAgICAgICBlbGlmIGFyZ3MucGhhc2UgPT0gJ29mZmxpbmUtdmVyaWZ5JzpcbiAgICAgICAgICAgIHJlc3VsdCA9IG9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgIGVsaWYgYXJncy5waGFzZSA9PSAnY2xlYW51cC1vZmZsaW5lJzpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNsZWFudXBfb2ZmbGluZShqb3VybmFsKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgcmVzdWx0ID0gcmVtb3RlKGFyZ3MucGhhc2UsIGFyZ3Muc291cmNlX3JldmlzaW9uLCBhcHByb3ZlZClcbiAgICAgICAgcmVxdWlyZShvcmlnaW5hbF9hbmNob3IoQ1VTVE9EWSwgcGxhblsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzb24ubG9hZHMoKENBU0UgLyAnb3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtYmFja3VwLmpzb24nKS5yZWFkX3RleHQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYW5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10pID09IGFuY2hvcixcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkIGpvdXJuYWwgY2hhbmdlZCBkdXJpbmcgbmV3IHBoYXNlJylcbiAgICAgICAgam91cm5hbC5maW5pc2goYXJncy5waGFzZSwgcmVzdWx0KVxuICAgICAgICBwcmludChqc29uLmR1bXBzKHJlc3VsdCkpICMgT25seSBjb3VudC9oYXNoL2lkZW50aXR5IHJlY2VpcHRzLCBuZXZlciBzbmFwc2hvdCBieXRlcy5cbiAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICAgICAgc2FmZSA9IHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdwaGFzZSc6IGFyZ3MucGhhc2UsICdmYWlsdXJlX2NsYXNzJzogdHlwZShlcnJvcikuX19uYW1lX18sXG4gICAgICAgICAgICAgICAgJ2ZhaWx1cmUnOiAnZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeScsXG4gICAgICAgICAgICAgICAgJ3Jhd19vdXRwdXRfd2l0aGhlbGQnOiBUcnVlfVxuICAgICAgICBpZiBqb3VybmFsLmRhdGFbJ3BoYXNlcyddLmdldChhcmdzLnBoYXNlLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdSVU5OSU5HJzpcbiAgICAgICAgICAgIGpvdXJuYWwuZmluaXNoKGFyZ3MucGhhc2UsIHNhZmUpXG4gICAgICAgIHByaW50KGpzb24uZHVtcHMoc2FmZSkpXG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoMSkgZnJvbSBOb25lXG4gICAgZmluYWxseTpcbiAgICAgICAgam91cm5hbC5jbG9zZSgpXG5cblxuaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzpcbiAgICB0cnk6XG4gICAgICAgIG1haW4oKVxuICAgIGV4Y2VwdCBFeGNlcHRpb246XG4gICAgICAgIHJhaXNlIFN5c3RlbUV4aXQoJ3N1cGVydmlzZWQgZXhlY3V0aW9uIHJlZnVzZWQgYmVmb3JlIHBoYXNlOyByYXcgb3V0cHV0IHdpdGhoZWxkJykgZnJvbSBOb25lXG4iCiAgICB9LAogICAgImF1dGhvcml0eV9qb3VybmFsLnB5IjogewogICAgICAic2hhMjU2IjogIjA1MzU5NzVhZTYzMTIxOWY5MGZjZTdlNTJmOGI1NGU2MWU4YWZkNGVmNjhiYjc0NzM4NjM0NzhmMGY1MTlmNjgiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTdXBlcnZpc2VkIHJlY2VpcHQgYm9va2tlZXBpbmcsIG5vdCBhbiBhdXRoZW50aWNhdGVkIGFwcHJvdmFsIHByb3ZpZGVyLlwiXCJcIlxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgZmNudGxcbmltcG9ydCBoYXNobGliXG5pbXBvcnQganNvblxuaW1wb3J0IG9zXG5pbXBvcnQgcmVcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN0YXRcbmltcG9ydCB1dWlkXG5cbkZPVU5ERVIgPSB7J2tpbmQnOiAncGVyc29uJywgJ3N1Yic6ICd1aWQ9cGxhdGZvcm0tcm9vdCxvdT1wZW9wbGUsZGM9bmV0a2luZ2RvbSxkYz1sb2NhbCd9XG5NRU1PX0lEID0gJ2luZmQtMjAyNjEwMTEtcHVycG9zZS1vdmVybGF5LXIxJ1xuUFJPUE9TQUwgPSAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnXG5QSEFTRVMgPSAoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywgJ29mZmxpbmUtdmVyaWZ5JywgJ2NsZWFudXAtb2ZmbGluZScsXG4gICAgICAgICAgJ2N1dG92ZXItYmFja3VwJywgJ2N1dG92ZXItY29weScsICdyZWxlYXNlJywgJ3ZlcmlmeScsICdyb2xsYmFjaycsICdyb2xsYmFjay12ZXJpZnknKVxuXG5cbmRlZiByZXF1aXJlKHZhbHVlLCByZWFzb24pOlxuICAgIGlmIG5vdCB2YWx1ZTpcbiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcihyZWFzb24pXG5cblxuZGVmIHNoYShwYXRoKTpcbiAgICBkaWdlc3QgPSBoYXNobGliLnNoYTI1NigpXG4gICAgd2l0aCBQYXRoKHBhdGgpLm9wZW4oJ3JiJykgYXMgc3RyZWFtOlxuICAgICAgICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6IHN0cmVhbS5yZWFkKDEwMjQqKjIpLCBiJycpOlxuICAgICAgICAgICAgZGlnZXN0LnVwZGF0ZShibG9jaylcbiAgICByZXR1cm4gZGlnZXN0LmhleGRpZ2VzdCgpXG5cblxuZGVmIHByaXZhdGUocGF0aCwgZGlyZWN0b3J5PUZhbHNlKTpcbiAgICBpbmZvID0gUGF0aChwYXRoKS5sc3RhdCgpXG4gICAgcmVxdWlyZSgoc3RhdC5TX0lTRElSKGluZm8uc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKGluZm8uc3RfbW9kZSkpXG4gICAgICAgICAgICBhbmQgaW5mby5zdF91aWQgPT0gb3MuZ2V0dWlkKCkgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpID09ICgwbzcwMCBpZiBkaXJlY3RvcnkgZWxzZSAwbzYwMClcbiAgICAgICAgICAgIGFuZCAoZGlyZWN0b3J5IG9yIGluZm8uc3RfbmxpbmsgPT0gMSksICdwcml2YXRlIG93bmVkIGN1c3RvZHkgcmVxdWlyZWQnKVxuXG5cbmRlZiBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgbWVtb19zaGEsIHNvdXJjZV9yZXZpc2lvbiwgcGhhc2UsIG5vdz1Ob25lKTpcbiAgICBcIlwiXCJSb290IG11c3QgZnJlc2hseSB2ZXJpZnkgbmF0aXZlIG91dGNvbWUgYXQgZml4ZWQgT1JJR0lOIG91dHNpZGUgdGhpcyBoZWxwZXIuXG5cbiAgICBSZWNlaXB0IGZpbGVzL2ZsYWdzIGFyZSBub3Qgc2lnbmVkIGdyYW50cy4gVGhpcyBmdW5jdGlvbiBjaGVja3MgdGhlIGV4YWN0XG4gICAgc3VwZXJ2aXNlZCByZWNlaXB0IHJlbGF0aW9uOyBleGlzdGluZyBoYXJuZXNzL2ZvdW5kZXIgYXV0aG9yaXR5IHJlbWFpbnMgdGhlXG4gICAgYWN0dWFsIHBlcm1pc3Npb24gYm91bmRhcnkuIEl0IG5ldmVyIGF1dGhlbnRpY2F0ZXMgYSBjYWxsZXIgYXMgaHVtYW4uXG4gICAgXCJcIlwiXG4gICAgbm93ID0gbm93IG9yIGRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpXG4gICAgcmVxdWlyZShwaGFzZSBpbiBQSEFTRVMsICdmaXhlZCBwaGFzZSByZXF1aXJlZCcpXG4gICAgcmVxdWlyZShyZWNlaXB0LmdldCgncHJvcG9zYWxfaWQnKSA9PSBQUk9QT1NBTCBhbmQgcmVjZWlwdC5nZXQoJ21lbW9faWQnKSA9PSBNRU1PX0lEXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ21lbW9fdmVyc2lvbicpID09IDIgYW5kIHJlY2VpcHQuZ2V0KCdtZW1vX3NoYTI1NicpID09IG1lbW9fc2hhXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3NvdXJjZV9yZXZpc2lvbicpID09IHNvdXJjZV9yZXZpc2lvblxuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhY3RpdmF0aW9uJykgPT0gJ0FQUFJPVkVEJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCdhdXRob3JpdHlfbW9kZScpID09ICdBRE1JTklTVEVSJ1xuICAgICAgICAgICAgYW5kIHJlY2VpcHQuZ2V0KCd0YXJnZXQnKSA9PSAncmVhbG06a3ViZXJuZXRlcy9yYWlsaWFuY2UwMS9pbmZvcm1lZC1kZWNpc2lvbidcbiAgICAgICAgICAgIGFuZCByZWNlaXB0LmdldCgndmVyaWZpY2F0aW9uX21ldGhvZCcpID09ICdyb290LWZpeGVkLW9yaWdpbi1uYXRpdmUtcmVhZGJhY2snXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ3J1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudCcpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgcmVjZWlwdC5nZXQoJ291dGNvbWVfcXVlcnknKSA9PSAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgJ2V4YWN0IGV4dGVybmFsbHkgdmVyaWZpZWQgc3VwZXJ2aXNlZCByZWNlaXB0IHJlcXVpcmVkJylcbiAgICB2ZXJpZmllZCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQocmVjZWlwdFsndmVyaWZpZWRfYXQnXS5yZXBsYWNlKCdaJywgJyswMDowMCcpKVxuICAgIHJlcXVpcmUodmVyaWZpZWQudHppbmZvIGlzIG5vdCBOb25lIGFuZCAwIDw9IChub3cgLSB2ZXJpZmllZCkudG90YWxfc2Vjb25kcygpIDw9IDEyMCxcbiAgICAgICAgICAgICdmcmVzaCByb290IG5hdGl2ZSByZWFkYmFjayByZXF1aXJlZCBiZWZvcmUgZXZlcnkgcGhhc2UnKVxuICAgIGRlYWRsaW5lID0gZGF0ZXRpbWUuZGF0ZXRpbWUuZnJvbWlzb2Zvcm1hdCgnMjAyNi0xMC0xMlQyMzo1OTo1OSswMDowMCcpXG4gICAgcmVxdWlyZShub3cgPCBkZWFkbGluZSwgJ2FwcHJvdmVkIGV4ZWN1dGlvbiB3aW5kb3cgZXhwaXJlZCcpXG4gICAgcmVxdWlyZShvdXRjb21lLmdldCgnbWVtb19pZCcpID09IE1FTU9fSUQgYW5kIG91dGNvbWUuZ2V0KCdyZXZpZXcnLCB7fSkuZ2V0KCdzdGFsZScpIGlzIEZhbHNlXG4gICAgICAgICAgICBhbmQgb3V0Y29tZVsncmV2aWV3J10uZ2V0KCdpbnRha2Vfc3RhdGUnKSA9PSAncmVhZHknLCAnbmF0aXZlIHJldmlldyBpcyBub3QgcmVhZHkvY3VycmVudCcpXG4gICAgcmV2aWV3X2lkID0gb3V0Y29tZVsncmV2aWV3J11bJ21lbW9faWQnXVxuICAgIHJlcXVpcmUocmV2aWV3X2lkID09IHJlY2VpcHQuZ2V0KCdyZXZpZXdfbWVtb19pZCcpLCAnbmF0aXZlIHJldmlldyBpZGVudGl0eSBjaGFuZ2VkJylcbiAgICBhY2NlcHRlZCA9IFt4IGZvciB4IGluIG91dGNvbWUuZ2V0KCdkaXNwb3NpdGlvbnMnLCBbXSlcbiAgICAgICAgICAgICAgICBpZiB4LmdldCgnc3VibWlzc2lvbl9zdGF0ZScpID09ICdjb25maXJtZWQnXG4gICAgICAgICAgICAgICAgYW5kIHguZ2V0KCdkaXNwb3NpdGlvbicsIHt9KS5nZXQoJ3ZlcmInKSA9PSAnYWNjZXB0J1xuICAgICAgICAgICAgICAgIGFuZCB4WydkaXNwb3NpdGlvbiddLmdldCgnbWVtb192ZXJzaW9uJykgPT0gMV1cbiAgICByZXF1aXJlKGxlbihhY2NlcHRlZCkgPT0gMSwgJ29uZSBjb25maXJtZWQgZm91bmRlciBhY2NlcHRhbmNlIHJlcXVpcmVkJylcbiAgICBhY2NlcHRlZCA9IGFjY2VwdGVkWzBdWydkaXNwb3NpdGlvbiddXG4gICAgcmVxdWlyZShhY2NlcHRlZC5nZXQoJ2FjdG9yJykgPT0gRk9VTkRFUiBhbmQgYWNjZXB0ZWQuZ2V0KCdtZW1vX2lkJykgPT0gcmV2aWV3X2lkXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhcHByb3ZhbF9pZCcpID09IHJlY2VpcHQuZ2V0KCdhcHByb3ZhbF9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdpZCcpID09IHJlY2VpcHQuZ2V0KCdkaXNwb3NpdGlvbl9pZCcpXG4gICAgICAgICAgICBhbmQgYWNjZXB0ZWQuZ2V0KCdhdCcpID09IHJlY2VpcHQuZ2V0KCdhY2NlcHRlZF9hdCcpLCAnZXhhY3QgZm91bmRlciBkaXNwb3NpdGlvbiBtaXNtYXRjaCcpXG4gICAgcmVxdWlyZShyZS5mdWxsbWF0Y2gocidbYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2FwcHJvdmFsX2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHInZGlzcC1bYS1mMC05LV17MzZ9JywgYWNjZXB0ZWRbJ2lkJ10pIGlzIG5vdCBOb25lXG4gICAgICAgICAgICBhbmQgcmUuZnVsbG1hdGNoKHIncmV2aWV3LVthLWYwLTktXXszNn0nLCByZXZpZXdfaWQpIGlzIG5vdCBOb25lLFxuICAgICAgICAgICAgJ25hdGl2ZSBkaXNwb3NpdGlvbiBpZGVudGlmaWVycyBhcmUgbWFsZm9ybWVkJylcbiAgICBhY2NlcHRlZF9hdCA9IGRhdGV0aW1lLmRhdGV0aW1lLmZyb21pc29mb3JtYXQoYWNjZXB0ZWRbJ2F0J10ucmVwbGFjZSgnWicsICcrMDA6MDAnKSlcbiAgICByZXF1aXJlKGFjY2VwdGVkX2F0LnR6aW5mbyBpcyBub3QgTm9uZSBhbmQgYWNjZXB0ZWRfYXQgPD0gdmVyaWZpZWQsICdhY2NlcHRhbmNlIHRpbWUgbm90IGJvdW5kZWQnKVxuICAgIHJldHVybiB7a2V5OiByZWNlaXB0W2tleV0gZm9yIGtleSBpbiAoJ2FwcHJvdmFsX2lkJywgJ2Rpc3Bvc2l0aW9uX2lkJywgJ2FjY2VwdGVkX2F0JywgJ3ZlcmlmaWVkX2F0Jyl9XG5cblxuZGVmIG9yaWdpbmFsX2FuY2hvcihwYXJlbnQsIGV4cGVjdGVkLCBiYWNrdXBfcmVzdWx0LCBvcmlnaW5hbF9pZGVudGl0eSk6XG4gICAgXCJcIlwiUmVhZCBvbmx5IHNhbml0aXplZCBvcmlnaW5hbCBqb3VybmFsOyBuZXZlciByZXdyaXRlL3N5bnRoZXNpemUgaXRzIHBoYXNlcy5cIlwiXCJcbiAgICBwYXRoID0gUGF0aChwYXJlbnQpIC8gJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nXG4gICAgcHJpdmF0ZShwYXRoKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBieXRlcyBjaGFuZ2VkJylcbiAgICBvcmlnaW5hbCA9IGpzb24ubG9hZHMocGF0aC5yZWFkX3RleHQoKSlcbiAgICByZXF1aXJlKG9yaWdpbmFsLmdldCgnaWRlbnRpdHknKSA9PSBvcmlnaW5hbF9pZGVudGl0eSwgJ29yaWdpbmFsIGFwcHJvdmVkIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHBoYXNlcyA9IG9yaWdpbmFsLmdldCgncGhhc2VzJywge30pXG4gICAgcmVxdWlyZShzZXQocGhhc2VzKSA9PSB7J2RyaWxsLWJhY2t1cCcsICdkcmlsbC1jb3B5J30sICd1bmV4cGVjdGVkIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0JylcbiAgICBmb3IgbmFtZSwgZmllbGRzIGluIGV4cGVjdGVkWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgIHJlcXVpcmUoYWxsKHBoYXNlc1tuYW1lXS5nZXQoa2V5KSA9PSB2YWx1ZSBmb3Iga2V5LHZhbHVlIGluIGZpZWxkcy5pdGVtcygpKSxcbiAgICAgICAgICAgICAgICAnb3JpZ2luYWwgZmFpbGVkL2NvbXBsZXRlZCBhdHRlbXB0IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUocGhhc2VzWydkcmlsbC1iYWNrdXAnXS5nZXQoJ3Jlc3VsdCcpID09IGJhY2t1cF9yZXN1bHRcbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZVxuICAgICAgICAgICAgYW5kIHBoYXNlc1snZHJpbGwtY29weSddLmdldCgncmVzdWx0Jywge30pLmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgRmFsc2UsXG4gICAgICAgICAgICAnb3JpZ2luYWwgYmFja3VwL2NvcHkgb3V0Y29tZSBjaGFuZ2VkJylcbiAgICByZXF1aXJlKGJhY2t1cF9yZXN1bHQuZ2V0KCdzbmFwc2hvdF9zaGEyNTYnKSA9PSBleHBlY3RlZFsnc25hcHNob3Rfc2hhMjU2J11cbiAgICAgICAgICAgIGFuZCBiYWNrdXBfcmVzdWx0LmdldCgnc25hcHNob3RfYnl0ZXMnKSA9PSBleHBlY3RlZFsnc25hcHNob3RfYnl0ZXMnXVxuICAgICAgICAgICAgYW5kIGJhY2t1cF9yZXN1bHQuZ2V0KCdwb2RfdWlkJykgPT0gJ2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNycsXG4gICAgICAgICAgICAnb3JpZ2luYWwgZnJvemVuIHNuYXBzaG90IGlkZW50aXR5IGNoYW5nZWQnKVxuICAgIHJlcXVpcmUoc2hhKHBhdGgpID09IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLCAnb3JpZ2luYWwgam91cm5hbCBjaGFuZ2VkIGR1cmluZyByZWFkJylcbiAgICByZXR1cm4geydvcmlnaW5hbF9qb3VybmFsX3NoYTI1Nic6IGV4cGVjdGVkWydvcmlnaW5hbF9qb3VybmFsX3NoYTI1NiddLFxuICAgICAgICAgICAgJ29yaWdpbmFsX2NvcHlfYXR0ZW1wdF9pZCc6IHBoYXNlc1snZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnb3JpZ2luYWxfYmFja3VwX2F0dGVtcHRfaWQnOiBwaGFzZXNbJ2RyaWxsLWJhY2t1cCddWydhdHRlbXB0X2lkJ10sXG4gICAgICAgICAgICAnYmFja3VwX3Jlc3VsdCc6IGJhY2t1cF9yZXN1bHQsICdvbGRfdW5jZXJ0YWluX3BoYXNlX3JldGFpbmVkJzogVHJ1ZX1cblxuXG5jbGFzcyBKb3VybmFsOlxuICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXJlbnQsIGlkZW50aXR5KTpcbiAgICAgICAgc2VsZi5wYXJlbnQgPSBQYXRoKHBhcmVudClcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCwgZGlyZWN0b3J5PVRydWUpXG4gICAgICAgIHNlbGYucGF0aCA9IHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tam91cm5hbC1yMS5qc29uJ1xuICAgICAgICBzZWxmLmxvY2sgPSBvcy5vcGVuKHNlbGYucGFyZW50IC8gJ3Jlc2N1ZS1leGVjdXRpb24tcjEubG9jaycsIG9zLk9fQ1JFQVQgfCBvcy5PX05PRk9MTE9XIHwgb3MuT19SRFdSLCAwbzYwMClcbiAgICAgICAgZmNudGwuZmxvY2soc2VsZi5sb2NrLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQilcbiAgICAgICAgcHJpdmF0ZShzZWxmLnBhcmVudCAvICdyZXNjdWUtZXhlY3V0aW9uLXIxLmxvY2snKVxuICAgICAgICBpZiBzZWxmLnBhdGguZXhpc3RzKCk6XG4gICAgICAgICAgICBwcml2YXRlKHNlbGYucGF0aClcbiAgICAgICAgICAgIHNlbGYuZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5wYXRoLnJlYWRfdGV4dCgpKVxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ2lkZW50aXR5J10gPT0gaWRlbnRpdHksICdqb3VybmFsIGNhc2Uvc291cmNlIGlkZW50aXR5IGNoYW5nZWQnKVxuICAgICAgICBlbHNlOlxuICAgICAgICAgICAgc2VsZi5kYXRhID0geydpZGVudGl0eSc6IGlkZW50aXR5LCAncGhhc2VzJzoge319XG4gICAgICAgICAgICBzZWxmLnNhdmUoKVxuXG4gICAgZGVmIHNhdmUoc2VsZik6XG4gICAgICAgIHRlbXBvcmFyeSA9IHNlbGYucGFyZW50IC8gJ2V4ZWN1dGlvbi1qb3VybmFsLm5ldydcbiAgICAgICAgZmQgPSBvcy5vcGVuKHRlbXBvcmFyeSwgb3MuT19DUkVBVCB8IG9zLk9fRVhDTCB8IG9zLk9fTk9GT0xMT1cgfCBvcy5PX1dST05MWSwgMG82MDApXG4gICAgICAgIHRyeTpcbiAgICAgICAgICAgIHdpdGggb3MuZmRvcGVuKGZkLCAndycpIGFzIHN0cmVhbTpcbiAgICAgICAgICAgICAgICBqc29uLmR1bXAoc2VsZi5kYXRhLCBzdHJlYW0sIGluZGVudD0yKVxuICAgICAgICAgICAgICAgIHN0cmVhbS53cml0ZSgnXFxuJylcbiAgICAgICAgICAgICAgICBzdHJlYW0uZmx1c2goKVxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKHN0cmVhbS5maWxlbm8oKSlcbiAgICAgICAgICAgIG9zLnJlcGxhY2UodGVtcG9yYXJ5LCBzZWxmLnBhdGgpXG4gICAgICAgICAgICBkaXJlY3RvcnkgPSBvcy5vcGVuKHNlbGYucGFyZW50LCBvcy5PX0RJUkVDVE9SWSB8IG9zLk9fUkRPTkxZKVxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIG9zLmZzeW5jKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIGZpbmFsbHk6XG4gICAgICAgICAgICAgICAgb3MuY2xvc2UoZGlyZWN0b3J5KVxuICAgICAgICBleGNlcHQgQmFzZUV4Y2VwdGlvbjpcbiAgICAgICAgICAgICMgUmV0YWluIGV2aWRlbmNlIHJhdGhlciB0aGFuIG92ZXJ3cml0aW5nIGFuIHVuY2VydGFpbiBkdXJhYmxlIGludGVudC5cbiAgICAgICAgICAgIHJhaXNlXG5cbiAgICBkZWYgc3RhcnQoc2VsZiwgcGhhc2UsIGFwcHJvdmFsKTpcbiAgICAgICAgcmVxdWlyZShwaGFzZSBub3QgaW4gc2VsZi5kYXRhWydwaGFzZXMnXSwgJ2FscmVhZHkgYXR0ZW1wdGVkIHBoYXNlOyBubyByZXRyeScpXG4gICAgICAgIHJlcXVpcmUocGhhc2UgaW4gUEhBU0VTLCAnZml4ZWQgcmVzY3VlIG9yIHJlbWFpbmluZyBwaGFzZSByZXF1aXJlZCcpXG4gICAgICAgIHByZWRlY2Vzc29ycyA9IGRpY3QoemlwKFBIQVNFU1sxOjddLCBQSEFTRVNbOjZdKSlcbiAgICAgICAgcHJlZGVjZXNzb3JzWydyb2xsYmFjay12ZXJpZnknXSA9ICdyb2xsYmFjaydcbiAgICAgICAgaWYgcGhhc2UgaW4gcHJlZGVjZXNzb3JzOlxuICAgICAgICAgICAgcmVxdWlyZShzZWxmLmRhdGFbJ3BoYXNlcyddLmdldChwcmVkZWNlc3NvcnNbcGhhc2VdLCB7fSkuZ2V0KCdzdGF0ZScpID09ICdDT01QTEVURScsXG4gICAgICAgICAgICAgICAgICAgICdwcmVjZWRpbmcgcGhhc2UgaXMgbm90IHZlcmlmaWVkIGNvbXBsZXRlJylcbiAgICAgICAgaWYgcGhhc2UgPT0gJ3JvbGxiYWNrJzpcbiAgICAgICAgICAgIHJlcXVpcmUoJ3JlbGVhc2UnIGluIHNlbGYuZGF0YVsncGhhc2VzJ10sICdyb2xsYmFjayByZXF1aXJlcyBhIHJlY29yZGVkIHJlbGVhc2UgYXR0ZW1wdCcpXG4gICAgICAgIHNlbGYuZGF0YVsncGhhc2VzJ11bcGhhc2VdID0geydzdGF0ZSc6ICdSVU5OSU5HJywgJ2FwcHJvdmFsJzogYXBwcm92YWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhdHRlbXB0X2lkJzogc3RyKHV1aWQudXVpZDQoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzdGFydGVkX2F0JzogZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0YykuaXNvZm9ybWF0KCl9XG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgbm90ZShzZWxmLCBwaGFzZSwga2V5LCB2YWx1ZSk6XG4gICAgICAgIHJlcXVpcmUoc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1bJ3N0YXRlJ10gPT0gJ1JVTk5JTkcnLCAncGhhc2UgaW50ZW50IG1pc3NpbmcnKVxuICAgICAgICBzZWxmLmRhdGFbJ3BoYXNlcyddW3BoYXNlXVtrZXldID0gdmFsdWVcbiAgICAgICAgc2VsZi5zYXZlKClcblxuICAgIGRlZiBmaW5pc2goc2VsZiwgcGhhc2UsIHJlc3VsdCk6XG4gICAgICAgIGVudHJ5ID0gc2VsZi5kYXRhWydwaGFzZXMnXVtwaGFzZV1cbiAgICAgICAgcmVxdWlyZShlbnRyeVsnc3RhdGUnXSA9PSAnUlVOTklORycsICdwaGFzZSBpbnRlbnQgbWlzc2luZycpXG4gICAgICAgIGVudHJ5WydyZXN1bHQnXSA9IHJlc3VsdFxuICAgICAgICBlbnRyeVsnc3RhdGUnXSA9ICdDT01QTEVURScgaWYgcmVzdWx0LmdldCgnYWxsX2NoZWNrc19wYXNzJykgaXMgVHJ1ZSBlbHNlICdVTkNFUlRBSU4nXG4gICAgICAgIHNlbGYuc2F2ZSgpXG5cbiAgICBkZWYgY2xvc2Uoc2VsZik6XG4gICAgICAgIG9zLmNsb3NlKHNlbGYubG9jaylcbiIKICAgIH0sCiAgICAiZXhlY3V0aW9uLXBsYW4uanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICI5Y2U1NzI4YTU2MWU2ZDM4Zjg0OTcyMDFiYWEyYjg0MGQxMTQ0NGEwYWY4YWQ2MjM0ZGZjMzc0MjgxMTNmMjU4IiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcImtpbmRcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi5zdXBlcnZpc2VkLW1lY2hhbmljYWwtcmVsZWFzZS1wbGFuXCIsXG4gIFwidmVyc2lvblwiOiAyLFxuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcInN0YXRlXCI6IFwicHJlcGFyZWQtdW5hcHByb3ZlZFwiLFxuICBcImV4ZWN1dG9yX2ZpbGVzXCI6IHtcbiAgICBcImFjdHVhdG9yLnB5XCI6IFwiODZiNjdkMWFiYWQ2YWYyYThjNDk1MjhmZTEyNWE1YmFiOTQ0OTc1ZDNlODAxODI2YzUxMWVlODg4NDY1NzFiMlwiLFxuICAgIFwiYXV0aG9yaXR5X2pvdXJuYWwucHlcIjogXCIwNTM1OTc1YWU2MzEyMTlmOTBmY2U3ZTUyZjhiNTRlNjFlOGFmZDRlZjY4YmI3NDczODYzNDc4ZjBmNTE5ZjY4XCIsXG4gICAgXCJuYXRpdmVfcHJvZ3JhbS5weVwiOiBcIjc4OGRjOTlmN2VkZmJmZDU0MmEzYmIwOGZjMzFmNjBjYWY0ZjhmZDVkNjU0YTZhOTFiNDVlMTk3ZWNmZjlmOTFcIixcbiAgICBcInJlY2VpcHRfc2FmZXR5LnB5XCI6IFwiNWM1NDM3M2YyZGM0YjA2NDAwODIyNWMxODZlZmIxZDVhZmRlZWMzNmQxNTM1MGJkYTBhMTJkZWQ5NzYwMmQxYlwiXG4gIH0sXG4gIFwiY2FzZV9maWxlc1wiOiB7XG4gICAgXCJjaGFuZ2VfZ3VhcmQucHlcIjogXCJmMzQ4ZTQ0OWM0OWY0ZDllNDlhZjllODJlMDE3NjRlNzE5NzgzN2ZkM2RmOWQ3NTZmNTg5MWQ5YjhkOWIzOGJlXCIsXG4gICAgXCJzcWxpdGVfcmVhZG9ubHkucHlcIjogXCI5MDkzYzY0ZjdmMGUzOWIyNDlkYTlmZWZkZjVhYWY0ZTQyNThiYzMxZTdhMjdmZDg4ODQ3OWNlMzI5YTIwNTA5XCIsXG4gICAgXCJwcmVmbGlnaHQtaW5wdXRzLmpzb25cIjogXCIwM2JiNGI0MmZlMWFhNTFiODQ2ZTk1N2E5ZTIzOTI2ZmFlNzJmMDJhMmNiNWUyOTczNjgwNDdmYjI1YzE3ZTliXCIsXG4gICAgXCJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb25cIjogXCJkMThkMjcwNjNkMDZmNTM1YWU4ODRlYTAxZjk2NzQ3ZmUzMDE2ODU1MThhYjk0YjFjYmEwNzJhMWUxNTE5MzYyXCIsXG4gICAgXCJzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uXCI6IFwiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OVwiLFxuICAgIFwiY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvblwiOiBcIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGVcIixcbiAgICBcInJvbGxiYWNrLWRlcGxveW1lbnQuanNvblwiOiBcIjM5YjNmNDNiYjg0ZWY0OTIxY2MzYTFmYmNkYzQ0NDYxMDc0MWVkODgwOTE0OWQ4ZjhmMTdlZDgwNWYyNjIxMjFcIixcbiAgICBcImNoZWNrX2luc3RhbGxlZC5weVwiOiBcImEzNGE1MWJlOWM5ZjJiMTZhMDZhODgxNzNiNWM2YzQ5MmM5OTU3ZmUwMjFjZjQxMmE4NmExNzM3NzMwNjQwYWRcIixcbiAgICBcInB1Ymxpc2hlZC12ZXJpZmljYXRpb24uanNvblwiOiBcImU1OWFiNDRiMWFhZjI4MTQwNTA5NTkzYWFlNGFiOWI5N2FiNjJjYzhiNTg5ZTNmMTU1MmJhYzc4NjE4ODk2ZGRcIixcbiAgICBcInNlY3VyaXR5LXN1bW1hcnkuanNvblwiOiBcIjBlZTU2NDAwZGM3MDNmN2M5OTY4YzJhMGEzZWEwMzkwZDgzNjJmOGQwYmJmODAwMmEyYmQ3ZmE1OGYxOWNiNDRcIixcbiAgICBcIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWJhY2t1cC5qc29uXCI6IFwiMDI1ZGRkZjFlOTM5MzZmMzFlOThiOWZiZmE4NGFhMmJkYWFhMzM1NzNmOWQzYjBlMzJkOTQ3ZmQyODZiMTcwZVwiLFxuICAgIFwib3JpZ2luYWwtYXBwcm92ZWQtZHJpbGwtY29weS1mYWlsdXJlLmpzb25cIjogXCJmYjc4ZmIyZThjM2Q0MTY0OTBjZjBmNTU5YjJmNWJkMDE5NDA2YTQ5MGY4ZjVmYTZmNTkzMjQyMWYwYjFhYzU2XCIsXG4gICAgXCJvcmlnaW5hbC1qb3VybmFsLXNhbml0aXplZC1hbmNob3IuanNvblwiOiBcIjk4OGZjYTYxYWQ4ZWI5ZDQzZDkzMzkwYTgzNTMyM2Y5NTIxOTZiYmNlOGNjMGJkZTUxYzQyYTE3ZDQxMWY0NTRcIlxuICB9LFxuICBcIm93bmVyX3NvdXJjZV9maWxlc1wiOiB7XG4gICAgXCJkZXBsb3kvbGlmZWN5Y2xlL2FkbWlzc2lvbi5jYW5kaWRhdGUuanNvblwiOiBcIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTVcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvblwiOiBcIjM4Yjc4YjljYmVlNWFkZTc3NTBhNThkNTE1NmNhNGM1NzczMzUyZTk0N2FjYjMwNGVlNzE0YjU5ZTc0OWNlYjRcIixcbiAgICBcImRlcGxveS9saWZlY3ljbGUva3VzdG9taXphdGlvbi55YW1sXCI6IFwiMWJiY2U4MWJjNjc1ODQzNDM1NDE1N2Y4NjAxNTM0MzIwYzVkMDI5MDU4NzkwOGZkMTVhNmQyNWUzZmE1N2Y0N1wiLFxuICAgIFwiZGVwbG95L2xpZmVjeWNsZS9yZWdpc3RyaWVzLmNhbmRpZGF0ZS5qc29uXCI6IFwiOWJhZDZkYjVmYmMyMTc4ZDMxYjA0MTIwMDE2YTQxODMwYzM1NTJmYmI5ZTI1MTdiNzE4ZjliYmU4N2NmNjQ5ZVwiXG4gIH0sXG4gIFwiY2FuZGlkYXRlX2ltYWdlXCI6IFwiZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uQHNoYTI1Njo3NjNjMzY0MDJjOGJlN2NjNGMxYmQxYTYxNjIzZDFhZmY5MTE2ZDUyMjQxODc3NDI1YjQ1YTcwMThjYzA4ODNhXCIsXG4gIFwicHJpb3JfaW1hZ2VcIjogXCJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcIixcbiAgXCJzb3VyY2VfcmV2aXNpb25cIjogXCJtdXN0LWJlLWV4YWN0LWZpbmFsLW93bmVyLUhFQUQtd2l0aC1hcHByb3ZlZC1mb3VyLUdpdC1ibG9ic1wiLFxuICBcInBoYXNlc1wiOiBbXG4gICAgXCJkcmlsbC1jb3B5LXJlc2N1ZS1yMVwiLFxuICAgIFwib2ZmbGluZS12ZXJpZnlcIixcbiAgICBcImNsZWFudXAtb2ZmbGluZVwiLFxuICAgIFwiY3V0b3Zlci1iYWNrdXBcIixcbiAgICBcImN1dG92ZXItY29weVwiLFxuICAgIFwicmVsZWFzZVwiLFxuICAgIFwidmVyaWZ5XCIsXG4gICAgXCJyb2xsYmFja1wiLFxuICAgIFwicm9sbGJhY2stdmVyaWZ5XCJcbiAgXSxcbiAgXCJhdXRob3JpemF0aW9uXCI6IFwiZnJlc2ggZXh0ZXJuYWxseSBhdXRoZW50aWNhdGVkIHJvb3QgZml4ZWQtb3JpZ2luIG5hdGl2ZSByZWFkYmFjayBiZWZvcmUgZWFjaCBwaGFzZTsgZXhhY3QgY29uZmlybWVkIHBsYXRmb3JtLXJvb3QgZGlzcG9zaXRpb24gYW5kIGN1cnJlbnQgcGFja2V0IFNIQS9zb3VyY2UgY29tbWl0OyByZWNlaXB0IGJvb2trZWVwaW5nIGlzIG5vdCBhbiBhdXRvbm9tb3VzIHNpZ25lZCBncmFudFwiLFxuICBcImV4ZWN1dGVfYnlcIjogXCIyMDI2LTEwLTEyVDIzOjU5OjU5WlwiLFxuICBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZSxcbiAgXCJuYXRpdmVfZGF0YV9vcl93b3JrbG9hZF9hY3Rpb25fZXhlY3V0ZWRcIjogZmFsc2UsXG4gIFwiZGVhZGxpbmVfc2VtYW50aWNzXCI6IFwiQWxsIHBoYXNlcyBpbmNsdWRpbmcgdmVyaWZpY2F0aW9uL3JlY292ZXJ5IG11c3QgYmVnaW4gYmVmb3JlIGV4ZWN1dGVfYnkuIE5vIGV4dGVuc2lvbiBvciBhdXRvbWF0aWMgZW1lcmdlbmN5IGdyYW50OyBiZXlvbmQgZGVhZGxpbmUgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbi4gQ29tcGxldGUgdGhlIGJvdW5kZWQgZHJpbGwgYW5kIHJvbGxvdXQgZWFybHkgZW5vdWdoIHRvIGFsbG93IHJlY292ZXJ5IHdpdGhpbiB0aGUgd2luZG93LlwiLFxuICBcInJlY292ZXJ5XCI6IHtcbiAgICBcIm9yaWdpbmFsX2FuY2hvclwiOiB7XG4gICAgICBcIm9yaWdpbmFsX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICAgICAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgICAgIFwiZHJpbGwtYmFja3VwXCI6IHtcbiAgICAgICAgICBcInN0YXRlXCI6IFwiQ09NUExFVEVcIixcbiAgICAgICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgICAgICBcInN0YXJ0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM4OjQ1LjMxMDY1MyswMDowMFwiXG4gICAgICAgIH0sXG4gICAgICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICAgICAgXCJzdGF0ZVwiOiBcIlVOQ0VSVEFJTlwiLFxuICAgICAgICAgIFwiYXR0ZW1wdF9pZFwiOiBcIjMyOWVmMTkwLTE2OTItNDI0Ni1iOTUzLWU2YTU5NjY0YWJjY1wiLFxuICAgICAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgICAgIFwic25hcHNob3Rfc2hhMjU2XCI6IFwiODc1NmNmODI1ZGY5ZTdiNWI3NGJiNGEwMTA2YTUwMjdmNWNmZjJjNTlmZjQ1ZDdiNDhlZWQ4NTIyYTdkMzNmM1wiLFxuICAgICAgXCJzbmFwc2hvdF9ieXRlc1wiOiAxOTUzNzkyMCxcbiAgICAgIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gICAgICBcIm9sZF91bmNlcnRhaW5fcmV0cnlfYXV0aG9yaXplZFwiOiBmYWxzZVxuICAgIH0sXG4gICAgXCJvcmlnaW5hbF9pZGVudGl0eVwiOiB7XG4gICAgICBcInByb3Bvc2FsXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgICAgIFwic291cmNlX3JldmlzaW9uXCI6IFwiYmM2NDk0Y2QxYjI5MDc4M2VmM2FlZjA3NjNiZjI4ZDFkZWFiZjRiMFwiLFxuICAgICAgXCJtZW1vX3NoYTI1NlwiOiBcIjUwNmQzOTU2YmViN2M2MmFiMmJiZGZkYTc4M2MwNTkwNWQxODM0NTJhMWY2N2ExODE3ZjNmYjhjMmU1MjI5MzdcIixcbiAgICAgIFwicGxhbl9zaGEyNTZcIjogXCJmNWU1ZmE5MDZmZjE5ZDNhNDVkMTBkY2RiMjgxMDM3M2FlMjFmOWNmNDRjMDQ3MmZmMmJkNDdkM2JjMzMyOGQ2XCJcbiAgICB9LFxuICAgIFwibmV3X2pvdXJuYWxcIjogXCJyZXNjdWUtZXhlY3V0aW9uLWpvdXJuYWwtcjEuanNvblwiLFxuICAgIFwibmV3X3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgICBcIm9sZF91bmNlcnRhaW5fcGhhc2Vfb3ZlcndyaXRlX29yX3JldHJ5XCI6IGZhbHNlLFxuICAgIFwibmV3X3NuYXBzaG90X2JhY2t1cFwiOiBmYWxzZSxcbiAgICBcInNuYXBzaG90X29yX3NpZGVjYXJfbXV0YXRpb25cIjogZmFsc2UsXG4gICAgXCJtYXBwaW5nXCI6IFwib2ZmbGluZS12ZXJpZnkgY29uc3VtZXMgQ09NUExFVEUgZHJpbGwtY29weS1yZXNjdWUtcjEgcmVzdWx0OyBhbGwgbGF0ZXIgcGhhc2VzIG9yZGVyZWQgb25seSBpbiBuZXcgaGFzaC1saW5rZWQgcmVjb3Zlcnkgam91cm5hbFwiXG4gIH0sXG4gIFwic291cmNlX21lbW9fdmVyc2lvblwiOiAyLFxuICBcIm5hdGl2ZV9yZXZpZXdfbWVtb192ZXJzaW9uXCI6IDFcbn1cbiIKICAgIH0sCiAgICAibmF0aXZlX3Byb2dyYW0ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiNzg4ZGM5OWY3ZWRmYmZkNTQyYTNiYjA4ZmMzMWY2MGNhZjRmOGZkNWQ2NTRhNmE5MWI0NWUxOTdlY2ZmOWY5MSIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIkZpeGVkIHZlcnNpb24yIHJlY292ZXJ5IHJlbW90ZSBzb3VyY2U7IHJlcXVpcmVzIGZyZXNoIGV4YWN0IGFjY2VwdGFuY2UuXCJcIlwiXG5QUk9HUkFNID0gJ1xcbmltcG9ydCBjb3B5LGRhdGV0aW1lLGhhc2hsaWIsanNvbixvcyxyZSxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxucGF5bG9hZD1qc29uLmxvYWRzKF9fUEFZTE9BRF9fKVxcbmV4ZWMoX19HVUFSRF9fKVxcbnBoYXNlPXBheWxvYWRbXFwncGhhc2VcXCddXFxuaWYgcGhhc2Ugbm90IGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2tcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpyYWlzZSBWYWx1ZUVycm9yKFxcJ2ZpeGVkIG5hdGl2ZSBwaGFzZSByZXF1aXJlZFxcJylcXG5kZWFkbGluZT1kYXRldGltZS5kYXRldGltZS5mcm9taXNvZm9ybWF0KFxcJzIwMjYtMTAtMTJUMjM6NTk6NTkrMDA6MDBcXCcpXFxuZGVmIHJlcXVpcmUodmFsdWUscmVhc29uKTpcXG4gaWYgbm90IHZhbHVlOnJhaXNlIFZhbHVlRXJyb3IocmVhc29uKVxcbnJlcXVpcmUoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KGRhdGV0aW1lLnRpbWV6b25lLnV0Yyk8ZGVhZGxpbmUsXFwnZXhlY3V0aW9uIHdpbmRvdyBleHBpcmVkXFwnKVxcbmVudj17Kipvcy5lbnZpcm9uLFxcJ0tVQkVDT05GSUdcXCc6XFwnL2V0Yy9yYW5jaGVyL2szcy9rM3MueWFtbFxcJ31cXG5kZWYgcnVuKGFyZ3YsYm9keT1Ob25lLHRpbWVvdXQ9OTApOlxcbiByZXR1cm4gc3VicHJvY2Vzcy5ydW4oYXJndixpbnB1dD1ib2R5LHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlLHRpbWVvdXQ9dGltZW91dCxlbnY9ZW52KVxcbmRlZiByZWFkKGtpbmQsbmFtZSxuYW1lc3BhY2UpOlxcbiByZXN1bHQ9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxraW5kLG5hbWUsXFwnLW5cXCcsbmFtZXNwYWNlLFxcJy1vXFwnLFxcJ2pzb25cXCddKVxcbiByZXF1aXJlKHJlc3VsdC5yZXR1cm5jb2RlPT0wLFxcJ2ZpeGVkIG1ldGFkYXRhIHJlYWQgcmVmdXNlZFxcJylcXG4gcmV0dXJuIGpzb24ubG9hZHMocmVzdWx0LnN0ZG91dClcXG5zZWFsZWQ9cGF5bG9hZFtcXCdzZWFsZWRcXCddOyBkZXBlbmRlbmNpZXM9cGF5bG9hZFtcXCdkZXBlbmRlbmNpZXNcXCddXFxubGl2ZT1yZWFkKFxcJ2RlcGxveW1lbnRcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY209cmVhZChcXCdjb25maWdtYXBcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxucHZjPXJlYWQoXFwncHZjXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uLWRhdGFcXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcpXFxuY2hlY2tfZGVwZW5kZW5jaWVzKGNtLHB2YyxkZXBlbmRlbmNpZXMpXFxuYXBwPXJlYWQoXFwnYXBwbGljYXRpb25cXCcsXFwnaW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnYXJnb2NkXFwnKVxcbnJlcXVpcmUoYXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddPT1cXCc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGRcXCcsXFwnQXBwbGljYXRpb24gVUlEIGNoYW5nZWRcXCcpXFxucmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdyZXBvVVJMXFwnXT09XFwnaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0XFwnXFxuIGFuZCBhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCdwYXRoXFwnXT09XFwnZGVwbG95L2xpZmVjeWNsZVxcJ1xcbiBhbmQgYXBwW1xcJ3NwZWNcXCddW1xcJ2Rlc3RpbmF0aW9uXFwnXT09e1xcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCdzZXJ2ZXJcXCc6XFwnaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjXFwnfVxcbiBhbmQgYXBwW1xcJ3NwZWNcXCddLmdldChcXCdzeW5jUG9saWN5XFwnLHt9KS5nZXQoXFwnYXV0b21hdGVkXFwnKSBpcyBOb25lXFxuIGFuZCBzZXQoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ10pPT17XFwncmVwb1VSTFxcJyxcXCdwYXRoXFwnLFxcJ3RhcmdldFJldmlzaW9uXFwnfSBhbmQgbm90IGFwcFtcXCdzcGVjXFwnXS5nZXQoXFwnc291cmNlc1xcJyksXFwnQXBwbGljYXRpb24gb3duZXIvc2NvcGUgY2hhbmdlZFxcJylcXG5leHBlY3RlZD1jb3B5LmRlZXBjb3B5KHNlYWxlZClcXG5pZiBwaGFzZT09XFwndmVyaWZ5XFwnOmV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOlxcbiBpbWFnZT1saXZlW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ11cXG4gcmVxdWlyZShpbWFnZSBpbiAoQkFTRSxDQU5ESURBVEUpLFxcJ3JvbGxiYWNrIGltYWdlIGlzIG91dHNpZGUgc2FtZS1zY2hlbWEgcGFpclxcJylcXG4gZXhwZWN0ZWRbXFwnc3BlY1xcJ11bXFwndGVtcGxhdGVcXCddW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddWzBdW1xcJ2ltYWdlXFwnXT1pbWFnZVxcbmNoZWNrX2N1cnJlbnQobGl2ZSxleHBlY3RlZClcXG5pZiBwaGFzZSE9XFwncm9sbGJhY2tcXCc6XFxuIHJlcXVpcmUobGl2ZS5nZXQoXFwnc3RhdHVzXFwnLHt9KS5nZXQoXFwncmVhZHlSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ3VwZGF0ZWRSZXBsaWNhc1xcJyk9PTFcXG4gIGFuZCBsaXZlW1xcJ3N0YXR1c1xcJ10uZ2V0KFxcJ29ic2VydmVkR2VuZXJhdGlvblxcJyk9PWxpdmVbXFwnbWV0YWRhdGFcXCddW1xcJ2dlbmVyYXRpb25cXCddLFxcJ3NlcnZpY2Ugbm90IFJlYWR5MVxcJylcXG50YXJnZXQ9cGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddIGlmIHBoYXNlPT1cXCd2ZXJpZnlcXCcgZWxzZSBcXCc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmXFwnXFxuaWYgcGhhc2U9PVxcJ3JvbGxiYWNrXFwnOnJlcXVpcmUoYXBwW1xcJ3NwZWNcXCddW1xcJ3NvdXJjZVxcJ11bXFwndGFyZ2V0UmV2aXNpb25cXCddIGluICh0YXJnZXQscGF5bG9hZFtcXCdzb3VyY2VfcmV2aXNpb25cXCddKSxcXCdyb2xsYmFjayBzb3VyY2UgaXMgb3V0c2lkZSBwYWlyXFwnKVxcbmVsc2U6cmVxdWlyZShhcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ109PXRhcmdldCxcXCd1bmV4cGVjdGVkIHNvdXJjZSBwaW5cXCcpXFxucmVzdWx0PXtcXCdwaGFzZVxcJzpwaGFzZSxcXCdhbGxfY2hlY2tzX3Bhc3NcXCc6RmFsc2UsXFwncmF3X291dHB1dF93aXRoaGVsZFxcJzpUcnVlLFxcbiBcXCduYXRpdmVfYXBwcm92YWxfdmVyaWZpZWRfYnlfcm9vdFxcJzpwYXlsb2FkW1xcJ2FwcHJvdmFsXFwnXSxcXCduYXRpdmVfYXV0aGVudGljYXRlZF9ncmFudFxcJzpGYWxzZX1cXG50cnk6XFxuIGlmIHBoYXNlIGluIChcXCdjdXRvdmVyLWJhY2t1cFxcJyxcXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyxcXCdjdXRvdmVyLWNvcHlcXCcsXFwncmVsZWFzZVxcJyxcXCd2ZXJpZnlcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gIHBvZGxpc3Q9cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2dldFxcJyxcXCdwb2RzXFwnLFxcJy1uXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy1sXFwnLFxcJ2FwcC5rdWJlcm5ldGVzLmlvL25hbWU9aW5mb3JtZWQtZGVjaXNpb25cXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pXFxuICByZXF1aXJlKHBvZGxpc3QucmV0dXJuY29kZT09MCxcXCdwb2QgbWV0YWRhdGEgcXVlcnkgcmVmdXNlZFxcJylcXG4gIHBvZHM9W3AgZm9yIHAgaW4ganNvbi5sb2Fkcyhwb2RsaXN0LnN0ZG91dClbXFwnaXRlbXNcXCddIGlmIG5vdCBwW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnZGVsZXRpb25UaW1lc3RhbXBcXCcpXVxcbiAgcmVxdWlyZShsZW4ocG9kcyk9PTEsXFwnZXhhY3Qgc2luZ2xlIGxpdmUgb3duZXIgcG9kIHJlcXVpcmVkXFwnKTtwb2Q9cG9kc1swXVxcbiAgcmVxdWlyZShwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwncGhhc2VcXCcpPT1cXCdSdW5uaW5nXFwnIGFuZCBsZW4ocG9kW1xcJ3NwZWNcXCddW1xcJ2NvbnRhaW5lcnNcXCddKT09MVxcbiAgIGFuZCBwb2RbXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddPT1leHBlY3RlZFtcXCdzcGVjXFwnXVtcXCd0ZW1wbGF0ZVxcJ11bXFwnc3BlY1xcJ11bXFwnY29udGFpbmVyc1xcJ11bMF1bXFwnaW1hZ2VcXCddXFxuICAgYW5kIGxlbihwb2RbXFwnc3RhdHVzXFwnXS5nZXQoXFwnY29udGFpbmVyU3RhdHVzZXNcXCcsW10pKT09MVxcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ25hbWVcXCcpPT1cXCdpbmZvcm1lZC1kZWNpc2lvblxcJ1xcbiAgIGFuZCBwb2RbXFwnc3RhdHVzXFwnXVtcXCdjb250YWluZXJTdGF0dXNlc1xcJ11bMF0uZ2V0KFxcJ3JlYWR5XFwnKSBpcyBUcnVlLFxcJ293bmVyIHBvZCByZWFkaW5lc3MvaW1hZ2UgY2hhbmdlZFxcJylcXG4gIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJzpyZXF1aXJlKHBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09XFwnZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XFwnLFxcJ29yaWdpbmFsIGJhY2t1cCBQb2QgaWRlbnRpdHkgY2hhbmdlZFxcJylcXG4gIHRlbXBsYXRlPWV4cGVjdGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVxcbiAgY29udHJvbGxlZD1zZXQodGVtcGxhdGUpfHtcXCdpbml0Q29udGFpbmVyc1xcJyxcXCdob3N0TmV0d29ya1xcJyxcXCdob3N0UElEXFwnLFxcJ2hvc3RJUENcXCcsXFwncnVudGltZUNsYXNzTmFtZVxcJyxcXCdzaGFyZVByb2Nlc3NOYW1lc3BhY2VcXCd9XFxuICByZXF1aXJlKGFsbChwb2RbXFwnc3BlY1xcJ10uZ2V0KGtleSk9PXRlbXBsYXRlLmdldChrZXkpIGZvciBrZXkgaW4gY29udHJvbGxlZCksXFwnYWN0dWFsIG93bmVyIFBvZCBjb25maWd1cmF0aW9uIGRyaWZ0ZWRcXCcpXFxuICBvd25lcnM9cG9kW1xcJ21ldGFkYXRhXFwnXS5nZXQoXFwnb3duZXJSZWZlcmVuY2VzXFwnLFtdKTtyZXF1aXJlKGxlbihvd25lcnMpPT0xIGFuZCBvd25lcnNbMF1bXFwna2luZFxcJ109PVxcJ1JlcGxpY2FTZXRcXCcsXFwncG9kIG93bmVyIGNoYWluIGNoYW5nZWRcXCcpXFxuICBycz1yZWFkKFxcJ3JlcGxpY2FzZXRcXCcsb3duZXJzWzBdW1xcJ25hbWVcXCddLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnKVxcbiAgcmVxdWlyZShyc1tcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXT09b3duZXJzWzBdW1xcJ3VpZFxcJ10gYW5kIGFueShvLmdldChcXCd1aWRcXCcpPT1zZWFsZWRbXFwnbWV0YWRhdGFcXCddW1xcJ3VpZFxcJ11cXG4gICBhbmQgby5nZXQoXFwna2luZFxcJyk9PVxcJ0RlcGxveW1lbnRcXCcgZm9yIG8gaW4gcnNbXFwnbWV0YWRhdGFcXCddLmdldChcXCdvd25lclJlZmVyZW5jZXNcXCcsW10pKSxcXCdSZXBsaWNhU2V0IG93bmVyc2hpcCBjaGFuZ2VkXFwnKVxcbiAgaW5uZXI9clwiXCJcIlxcbmltcG9ydCBoYXNobGliLGpzb24sb3Msc3RhdCxzdWJwcm9jZXNzLHN5c1xcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoXFwnb3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWRcXCcpXFxuZXhlYyhfX1JFQURPTkxZX18pXFxuZXhlYyhfX1NBRkVUWV9fKVxcbmFjdGlvbj1fX0FDVElPTl9fO2RiPVxcJy9kYXRhL3ByaXZhdGUvcmV2aWV3LnNxbGl0ZVxcJztmb2xkZXI9XFwnL2RhdGEvcHJpdmF0ZS9wdXJwb3NlLW92ZXJsYXktcjFcXCdcXG5kZWYgcmVxdWlyZSh2LHIpOlxcbiBpZiBub3QgdjpyYWlzZSBWYWx1ZUVycm9yKHIpXFxucmVxdWlyZShvcy5nZXR1aWQoKT09MTAwMDEgYW5kIG9zLmdldGdpZCgpPT0xMDAwMSxcXCduYXRpdmUgb3duZXIgVUlEL0dJRCByZXF1aXJlZFxcJylcXG5kZWYgcHJpdmF0ZShwLGRpcmVjdG9yeT1GYWxzZSk6XFxuIHM9b3MubHN0YXQocCk7cmVxdWlyZSgoc3RhdC5TX0lTRElSKHMuc3RfbW9kZSkgaWYgZGlyZWN0b3J5IGVsc2Ugc3RhdC5TX0lTUkVHKHMuc3RfbW9kZSkpXFxuICBhbmQgcy5zdF91aWQ9PTEwMDAxIGFuZCBzdGF0LlNfSU1PREUocy5zdF9tb2RlKT09KDBvNzAwIGlmIGRpcmVjdG9yeSBlbHNlIDBvNjAwKVxcbiAgYW5kIChkaXJlY3Rvcnkgb3Igcy5zdF9ubGluaz09MSksXFwncHJpdmF0ZSBuYXRpdmUgY3VzdG9keSByZXF1aXJlZFxcJylcXG5wcml2YXRlKFxcJy9kYXRhL3ByaXZhdGVcXCcsVHJ1ZSk7cHJpdmF0ZShkYilcXG5iYXNlbGluZT1jb3VudHMoaW5zcGVjdF9yZWFkb25seShkYikpICMgTVVTVCBwcmVjZWRlIGFueSBTdG9yZS9hZG1pbiBvcGVuLlxcbmlmIGFjdGlvbiBpbiAoXFwnY3V0b3Zlci1iYWNrdXBcXCcpOlxcbiBzaXplPW9zLnN0YXQoZGIpLnN0X3NpemVcXG4gaWYgb3MucGF0aC5leGlzdHMoZGIrXFwnLXdhbFxcJyk6c2l6ZSs9b3Muc3RhdChkYitcXCctd2FsXFwnKS5zdF9zaXplXFxuIHY9b3Muc3RhdHZmcyhcXCcvZGF0YS9wcml2YXRlXFwnKTtmcmVlPXYuZl9iYXZhaWwqdi5mX2Zyc2l6ZVxcbiByZXF1aXJlKHNpemU+MCBhbmQgc2l6ZTw9NTEyKjEwMjQqKjIgYW5kIGZyZWU+PXNpemUqKDIgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSAxKSsxNioxMDI0KioyLFxcJ2JvdW5kZWQgbmF0aXZlIHNuYXBzaG90IGNhcGFjaXR5IHJlcXVpcmVkXFwnKVxcbiBpZiBhY3Rpb249PVxcJ2RyaWxsLWJhY2t1cFxcJzpcXG4gIHJlcXVpcmUobm90IG9zLnBhdGgubGV4aXN0cyhmb2xkZXIpLFxcJ25hdGl2ZSBjYXNlIGRpcmVjdG9yeSBtdXN0IGJlIHVuaXF1ZVxcJylcXG4gIG9zLm1rZGlyKGZvbGRlciwwbzcwMCk7b3MuY2htb2QoZm9sZGVyLDBvNzAwKVxcbiBwcml2YXRlKGZvbGRlcixUcnVlKVxcbiBmaWxlbmFtZT1cXCdkcmlsbC5zcWxpdGVcXCcgaWYgYWN0aW9uPT1cXCdkcmlsbC1iYWNrdXBcXCcgZWxzZSBcXCdjdXRvdmVyLnNxbGl0ZVxcJztvdXRwdXQ9Zm9sZGVyK1xcJy9cXCcrZmlsZW5hbWVcXG4gcmVxdWlyZShub3Qgb3MucGF0aC5sZXhpc3RzKG91dHB1dCksXFwnc25hcHNob3Qgb3V0cHV0IG11c3QgYmUgdW5pcXVlXFwnKVxcbiBhZG1pbj1zdWJwcm9jZXNzLnJ1bihbXFwnaW5mb3JtZWQtZGVjaXNpb24tYWRtaW5cXCcsXFwnYmFja3VwXFwnLFxcJy0tZGJcXCcsZGIsXFwnLS1vdXRwdXRcXCcsb3V0cHV0XSxjYXB0dXJlX291dHB1dD1UcnVlLHRleHQ9VHJ1ZSx0aW1lb3V0PTEyMClcXG4gcmVxdWlyZShhZG1pbi5yZXR1cm5jb2RlPT0wIGFuZCBqc29uLmxvYWRzKGFkbWluLnN0ZG91dCk9PXtcXCdzdGF0dXNcXCc6XFwnYmFja2VkX3VwXFwnLFxcJ2NvbnNpc3RlbnRfc25hcHNob3RcXCc6VHJ1ZX0sXFwnYmFja3VwIGNvbXBsZXRpb24gbm90IHZlcmlmaWVkOyBkbyBub3QgcmV0cnlcXCcpXFxuIHByaXZhdGUob3V0cHV0KVxcbiBmb3Igc3VmZml4IGluIChcXCctd2FsXFwnLCk6XFxuICByZXF1aXJlKG5vdCBvcy5wYXRoLmV4aXN0cyhvdXRwdXQrc3VmZml4KSBvciBvcy5zdGF0KG91dHB1dCtzdWZmaXgpLnN0X3NpemU9PTAsXFwnc25hcHNob3QgaGFzIFdBTCBmcmFtZXM7IGltbXV0YWJsZSByZWFkIHJlZnVzZWRcXCcpXFxuIGRpZ2VzdD1oYXNobGliLnNoYTI1NigpXFxuIHdpdGggb3BlbihvdXRwdXQsXFwncmJcXCcpIGFzIHN0cmVhbTpcXG4gIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTpzdHJlYW0ucmVhZCgxMDI0KioyKSxiXFwnXFwnKTpkaWdlc3QudXBkYXRlKGJsb2NrKVxcbiBmcm96ZW5fZGlnZXN0PWRpZ2VzdC5oZXhkaWdlc3QoKVxcbiBzbmFwc2hvdD1jb3VudHMoaW5zcGVjdF9jbG9zZWRfc25hcHNob3Qob3V0cHV0LGZyb3plbl9kaWdlc3QpKVxcbiBzaXplPW9zLnN0YXQob3V0cHV0KS5zdF9zaXplO3JlcXVpcmUoMDxzaXplPD01MTIqMTAyNCoqMixcXCdzbmFwc2hvdCBvdXRzaWRlIGJvdW5kZWQgY29weSBzaXplXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXFwnOmJhc2VsaW5lLFxcJ3NuYXBzaG90X3JlYWRvbmx5XFwnOnNuYXBzaG90LFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfYnl0ZXNcXCc6c2l6ZSxcXCdzbmFwc2hvdF9maWxlXFwnOmZpbGVuYW1lLFxcJ25hdGl2ZV9wYXJlbnRfcHJpdmF0ZVxcJzpUcnVlLFxcJ25hdGl2ZV91aWRcXCc6b3MuZ2V0dWlkKCl9KSlcXG5lbGlmIGFjdGlvbiBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2stdmVyaWZ5XFwnKTpcXG4gcHJvb2Y9e1xcJ2FsbF9jaGVja3NfcGFzc1xcJzpUcnVlLFxcJ2xpdmVfcmVhZG9ubHlfc2NoZW1hX2ludGVncml0eV9jb3VudHNcXCc6YmFzZWxpbmUsXFwnbGl2ZV9jb3VudHNfbWF5X2luY2x1ZGVfY29uY3VycmVudF9jb21taXRzXFwnOlRydWV9XFxuIGlmIGFjdGlvbj09XFwndmVyaWZ5XFwnOlxcbiAgaW1wb3J0IHVybGxpYi5yZXF1ZXN0XFxuICBtb2R1bGU9XFwnL29wdC92ZW52L2xpYi9weXRob24zLjEyL3NpdGUtcGFja2FnZXMvaW5mb3JtZWRfZGVjaXNpb24vcG9saWN5LnB5XFwnO2luZm89b3MubHN0YXQobW9kdWxlKVxcbiAgcmVxdWlyZShzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBhbmQgaW5mby5zdF91aWQ9PTAgYW5kIHN0YXQuU19JTU9ERShpbmZvLnN0X21vZGUpPT0wbzY0NCxcXCdpbnN0YWxsZWQgcG9saWN5IG1ldGFkYXRhIGRpZmZlcnNcXCcpXFxuICB3aXRoIG9wZW4obW9kdWxlLFxcJ3JiXFwnKSBhcyBzb3VyY2U6bW9kdWxlX2RpZ2VzdD1oYXNobGliLnNoYTI1Nihzb3VyY2UucmVhZCgpKS5oZXhkaWdlc3QoKVxcbiAgcmVxdWlyZShtb2R1bGVfZGlnZXN0PT1cXCc5ZDdjMWJlNGNiNjE5OWQxNGVmMGFhZWFkNWY4NTk1MWY0NWIwY2NiZDdjODAwYTdmZGU5MjJhMjUzNTY2YjYyXFwnLFxcJ2luc3RhbGxlZCBzb3VyY2UgbW9kdWxlIGRpZmZlcnNcXCcpXFxuICBwdXJwb3NlPXN1YnByb2Nlc3MucnVuKFtzeXMuZXhlY3V0YWJsZSxcXCctXFwnXSxpbnB1dD1fX1BVUlBPU0VfXyx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSx0aW1lb3V0PTMwKVxcbiAgcmVxdWlyZShwdXJwb3NlLnJldHVybmNvZGU9PTAsXFwnaW5zdGFsbGVkIG5hdGl2ZS1wbGFjZW1lbnQgcHVycG9zZSBjaGVja3MgZmFpbGVkXFwnKVxcbiAgdGVzdGVkPWpzb24ubG9hZHMocHVycG9zZS5zdGRvdXQpXFxuICByZXF1aXJlKHRlc3RlZD09e1xcJ2luc3RhbGxlZF9pbWFnZV9wdXJwb3NlX3ZhcmlhbnRzXFwnOjEwLFxcJ2JpbmRpbmdfZm9ybXNfYWxsb3dlZFxcJzoyLFxcJ2Fkdmlzb3J5X29yX21hbGZvcm1lZF9yZWZ1c2VkXFwnOjgsXFwnc3ludGhldGljX29ubHlcXCc6VHJ1ZSxcXCduYXRpdmVfcHJvdmlkZXJcXCc6RmFsc2V9LFxcJ3B1cnBvc2UgcmVzdWx0IGRpZmZlcnNcXCcpXFxuICBjbGFzcyBOb1JlZGlyZWN0KHVybGxpYi5yZXF1ZXN0LkhUVFBSZWRpcmVjdEhhbmRsZXIpOlxcbiAgIGRlZiByZWRpcmVjdF9yZXF1ZXN0KHNlbGYsKmFyZ3MsKiprd2FyZ3MpOnJhaXNlIFZhbHVlRXJyb3IoXFwnaGVhbHRoIHJlZGlyZWN0IHJlZnVzZWRcXCcpXFxuICBvcGVuZXI9dXJsbGliLnJlcXVlc3QuYnVpbGRfb3BlbmVyKE5vUmVkaXJlY3QoKSk7c3RhdHVzZXM9e31cXG4gIGZvciByb3V0ZSBpbiAoXFwnL2hlYWx0aHpcXCcsXFwnL3JlYWR5elxcJyk6XFxuICAgd2l0aCBvcGVuZXIub3BlbihcXCdodHRwOi8vMTI3LjAuMC4xOjgwODBcXCcrcm91dGUsdGltZW91dD0xMCkgYXMgcmVzcG9uc2U6XFxuICAgIHJlcXVpcmUocmVzcG9uc2Uuc3RhdHVzPT0yMDAgYW5kIGxlbihyZXNwb25zZS5yZWFkKDgxOTMpKTw9ODE5MixcXCdib3VuZGVkIGhlYWx0aCBjaGVjayByZWZ1c2VkXFwnKTtzdGF0dXNlc1tyb3V0ZV09MjAwXFxuICBwcm9vZi51cGRhdGUoaW5zdGFsbGVkX3B1cnBvc2VfY2hlY2tzPXRlc3RlZCxwb2xpY3lfc2hhMjU2PW1vZHVsZV9kaWdlc3QscG9saWN5X21vZGU9XFwnMDY0NFxcJyxwb2xpY3lfdWlkPTAsaGVhbHRoX3N0YXR1c2VzPXN0YXR1c2VzLG5hdGl2ZV9wcm92aWRlcl9wcm9iZT1GYWxzZSlcXG4gcHJpbnQoanNvbi5kdW1wcyhwcm9vZikpXFxuZWxpZiBhY3Rpb24gaW4gKFxcJ2RyaWxsLWNvcHlcXCcsXFwnY3V0b3Zlci1jb3B5XFwnKTpcXG4gcHJpdmF0ZShmb2xkZXIsVHJ1ZSk7ZmlsZW5hbWU9XFwnZHJpbGwuc3FsaXRlXFwnIGlmIGFjdGlvbj09XFwnZHJpbGwtY29weVxcJyBlbHNlIFxcJ2N1dG92ZXIuc3FsaXRlXFwnO291dHB1dD1mb2xkZXIrXFwnL1xcJytmaWxlbmFtZTtwcml2YXRlKG91dHB1dClcXG4gaWRlbnRpdHk9X19TTkFQU0hPVF9fO3JlcXVpcmUoaXNpbnN0YW5jZShpZGVudGl0eSxkaWN0KSBhbmQgaWRlbnRpdHkuZ2V0KFxcJ3NuYXBzaG90X2ZpbGVcXCcpPT1maWxlbmFtZSxcXCdyZWNvcmRlZCBvcmlnaW5hbCBmcm96ZW4gc25hcHNob3QgaWRlbnRpdHkgcmVxdWlyZWRcXCcpXFxuIHNuYXBzaG90PWNvdW50cyhpbnNwZWN0X2Nsb3NlZF9zbmFwc2hvdChvdXRwdXQsaWRlbnRpdHlbXFwnc25hcHNob3Rfc2hhMjU2XFwnXSkpO3NpemU9b3Muc3RhdChvdXRwdXQpLnN0X3NpemU7cmVxdWlyZShzaXplPT1pZGVudGl0eVtcXCdzbmFwc2hvdF9ieXRlc1xcJ10gYW5kIDA8c2l6ZTw9NTEyKjEwMjQqKjIsXFwnc25hcHNob3Qgc2l6ZSBvdXRzaWRlIGZyb3plbiBib3VuZFxcJylcXG4gcmVxdWlyZShzbmFwc2hvdD09aWRlbnRpdHlbXFwnc25hcHNob3RfcmVhZG9ubHlcXCddLFxcJ2Zyb3plbiBzbmFwc2hvdCBwcm9vZiBkaWZmZXJzXFwnKVxcbiBkaWdlc3Q9aGFzaGxpYi5zaGEyNTYoKVxcbiB3aXRoIG9wZW4ob3V0cHV0LFxcJ3JiXFwnKSBhcyBzdHJlYW06XFxuICBmb3IgYmxvY2sgaW4gaXRlcihsYW1iZGE6c3RyZWFtLnJlYWQoMTAyNCoqMiksYlxcJ1xcJyk6ZGlnZXN0LnVwZGF0ZShibG9jaylcXG4gcHJpbnQoanNvbi5kdW1wcyh7XFwnYWxsX2NoZWNrc19wYXNzXFwnOlRydWUsXFwnc25hcHNob3RfZmlsZVxcJzpmaWxlbmFtZSxcXCdzbmFwc2hvdF9ieXRlc1xcJzpzaXplLFxcJ3NuYXBzaG90X3NoYTI1NlxcJzpkaWdlc3QuaGV4ZGlnZXN0KCksXFwnc25hcHNob3RfcmVhZG9ubHlcXCc6c25hcHNob3R9KSlcXG5lbHNlOnJhaXNlIFZhbHVlRXJyb3IoXFwnZml4ZWQgbmF0aXZlIGJhY2t1cC92ZXJpZnkgcGhhc2UgcmVxdWlyZWRcXCcpXFxuXCJcIlwiXFxuICAjIFN0cmlwIHRoZSBDTEkgYnJhbmNoOiBleGVjIG9ubHkgdGhlIHZlcmlmaWVkIHN0ZGxpYiBmdW5jdGlvbiwgbmV2ZXIgU3RvcmUuXFxuICByZWFkb25seT1wYXlsb2FkW1xcJ3JlYWRvbmx5XFwnXS5zcGxpdChcImlmIF9fbmFtZV9fID09IFxcJ19fbWFpbl9fXFwnOlwiLDEpWzBdXFxuICBpbm5lcj1pbm5lci5yZXBsYWNlKFxcJ19fUkVBRE9OTFlfX1xcJyxyZXByKHJlYWRvbmx5KSkucmVwbGFjZShcXCdfX1NBRkVUWV9fXFwnLHJlcHIocGF5bG9hZFtcXCdyZWNlaXB0X3NhZmV0eVxcJ10pKS5yZXBsYWNlKFxcJ19fQUNUSU9OX19cXCcscmVwcihcXCdkcmlsbC1jb3B5XFwnIGlmIHBoYXNlPT1cXCdkcmlsbC1jb3B5LXJlc2N1ZS1yMVxcJyBlbHNlIHBoYXNlKSkucmVwbGFjZShcXCdfX1BVUlBPU0VfX1xcJyxyZXByKHBheWxvYWRbXFwncHVycG9zZV9jaGVja3NcXCddKSkucmVwbGFjZShcXCdfX1NOQVBTSE9UX19cXCcscmVwcihwYXlsb2FkLmdldChcXCdzbmFwc2hvdF9pZGVudGl0eVxcJykpKVxcbiAgcD1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnZXhlY1xcJyxcXCctaVxcJyxcXCctblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxwb2RbXFwnbWV0YWRhdGFcXCddW1xcJ25hbWVcXCddLFxcJy1jXFwnLFxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJy0tXFwnLFxcJ3B5dGhvblxcJyxcXCctXFwnXSxpbm5lciwxNTApXFxuICByZXF1aXJlKHAucmV0dXJuY29kZT09MCxcXCduYXRpdmUgcGhhc2Ugb3V0Y29tZSB1bnZlcmlmaWVkOyByYXcgb3V0cHV0IHdpdGhoZWxkLCBkbyBub3QgcmV0cnlcXCcpXFxuICBvdXRjb21lPWpzb24ubG9hZHMocC5zdGRvdXQpO3JlcXVpcmUob3V0Y29tZS5nZXQoXFwnYWxsX2NoZWNrc19wYXNzXFwnKSBpcyBUcnVlLFxcJ25hdGl2ZSBwaGFzZSBnYXRlIHJlZnVzZWRcXCcpXFxuICByZXN1bHQudXBkYXRlKG91dGNvbWUscG9kX25hbWU9cG9kW1xcJ21ldGFkYXRhXFwnXVtcXCduYW1lXFwnXSxwb2RfdWlkPXBvZFtcXCdtZXRhZGF0YVxcJ11bXFwndWlkXFwnXSlcXG4gaWYgcGhhc2UgaW4gKFxcJ3JlbGVhc2VcXCcsXFwncm9sbGJhY2tcXCcpOlxcbiAgbm9kZV9yZWFkPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdnZXRcXCcsXFwnbm9kZXNcXCcsXFwnLW9cXCcsXFwnanNvblxcJ10pO3JlcXVpcmUobm9kZV9yZWFkLnJldHVybmNvZGU9PTAsXFwnbm9kZSBtZXRhZGF0YSB1bmF2YWlsYWJsZVxcJylcXG4gIG5vZGVzPWpzb24ubG9hZHMobm9kZV9yZWFkLnN0ZG91dClbXFwnaXRlbXNcXCddO3JlcXVpcmUobGVuKG5vZGVzKT09MSxcXCdvbmUgdGFyZ2V0IG5vZGUgcmVxdWlyZWRcXCcpO25vZGU9bm9kZXNbMF1cXG4gIHJlcXVpcmUoYW55KGEuZ2V0KFxcJ2FkZHJlc3NcXCcpPT1cXCc5Mi4yMDUuNjIuMjM5XFwnIGZvciBhIGluIG5vZGVbXFwnc3RhdHVzXFwnXVtcXCdhZGRyZXNzZXNcXCddKSxcXCd0YXJnZXQgbm9kZSBhZGRyZXNzIGNoYW5nZWRcXCcpXFxuICBjb25kaXRpb25zPXtjW1xcJ3R5cGVcXCddOmNbXFwnc3RhdHVzXFwnXSBmb3IgYyBpbiBub2RlW1xcJ3N0YXR1c1xcJ11bXFwnY29uZGl0aW9uc1xcJ119XFxuICByZXF1aXJlKGNvbmRpdGlvbnMuZ2V0KFxcJ1JlYWR5XFwnKT09XFwnVHJ1ZVxcJyBhbmQgYWxsKGNvbmRpdGlvbnMuZ2V0KGspPT1cXCdGYWxzZVxcJyBmb3IgayBpbiAoXFwnTWVtb3J5UHJlc3N1cmVcXCcsXFwnRGlza1ByZXNzdXJlXFwnLFxcJ1BJRFByZXNzdXJlXFwnKSksXFwnbm9kZSB1bmhlYWx0aHkgb3IgcHJlc3N1cmVkXFwnKVxcbiAgZGVzY3JpcHRpb249cnVuKFtcXCdrdWJlY3RsXFwnLFxcJ2Rlc2NyaWJlXFwnLFxcJ25vZGVcXCcsbm9kZVtcXCdtZXRhZGF0YVxcJ11bXFwnbmFtZVxcJ11dKTtyZXF1aXJlKGRlc2NyaXB0aW9uLnJldHVybmNvZGU9PTAsXFwnaGVhZHJvb20gY2FwdHVyZSB1bmF2YWlsYWJsZVxcJylcXG4gIHRhYmxlPWRlc2NyaXB0aW9uLnN0ZG91dC5zcGxpdChcXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOlxcJywxKVsxXTtyZXF1ZXN0ZWQ9aW50KHJlLnNlYXJjaChyXFwnY3B1XFxcXHMrKFxcXFxkKyltXFwnLHRhYmxlKS5ncm91cCgxKSk7YWxsb2M9bm9kZVtcXCdzdGF0dXNcXCddW1xcJ2FsbG9jYXRhYmxlXFwnXVtcXCdjcHVcXCddO2NhcGFjaXR5PWludChhbGxvY1s6LTFdKSBpZiBhbGxvYy5lbmRzd2l0aChcXCdtXFwnKSBlbHNlIGludChhbGxvYykqMTAwMFxcbiAgcmVxdWlyZShyZXF1ZXN0ZWQ8PWNhcGFjaXR5LFxcJ1JlY3JlYXRlIHJlcXVlc3RlZCBDUFUgZXhjZWVkcyBjYXBhY2l0eVxcJylcXG4gIHJlcXVpcmUobm90IGFwcC5nZXQoXFwnb3BlcmF0aW9uXFwnKSBhbmQgYXBwLmdldChcXCdzdGF0dXNcXCcse30pLmdldChcXCdvcGVyYXRpb25TdGF0ZVxcJyx7fSkuZ2V0KFxcJ3BoYXNlXFwnKSBub3QgaW4gKFxcJ1J1bm5pbmdcXCcsXFwnVGVybWluYXRpbmdcXCcpLFxcJ2V4aXN0aW5nIEFyZ28gb3BlcmF0aW9uIG11c3QgYmUgc2V0dGxlZFxcJylcXG4gIGRlc3RpbmF0aW9uPXBheWxvYWRbXFwnc291cmNlX3JldmlzaW9uXFwnXSBpZiBwaGFzZT09XFwncmVsZWFzZVxcJyBlbHNlIFxcJzdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmZcXCdcXG4gIGJvZHk9Y29weS5kZWVwY29weShwYXlsb2FkW1xcJ2NhbmRpZGF0ZVxcJ10gaWYgcGhhc2U9PVxcJ3JlbGVhc2VcXCcgZWxzZSBwYXlsb2FkW1xcJ3JvbGxiYWNrXFwnXSlcXG4gIGRyeT1ydW4oW1xcJ2t1YmVjdGxcXCcsXFwnYXBwbHlcXCcsXFwnLS1kcnktcnVuPXNlcnZlclxcJyxcXCctZlxcJyxcXCctXFwnLFxcJy1vXFwnLFxcJ2pzb25cXCddLGpzb24uZHVtcHMoYm9keSkpXFxuICByZXF1aXJlKGRyeS5yZXR1cm5jb2RlPT0wLFxcJ2ZyZXNoIG93bmVyIHNlcnZlciBhZG1pc3Npb24gcmVmdXNlZFxcJylcXG4gIGFkbWl0dGVkPWpzb24ubG9hZHMoZHJ5LnN0ZG91dCk7d2FudGVkPWNvcHkuZGVlcGNvcHkoc2VhbGVkKVxcbiAgd2FudGVkW1xcJ3NwZWNcXCddW1xcJ3RlbXBsYXRlXFwnXVtcXCdzcGVjXFwnXVtcXCdjb250YWluZXJzXFwnXVswXVtcXCdpbWFnZVxcJ109Q0FORElEQVRFIGlmIHBoYXNlPT1cXCdyZWxlYXNlXFwnIGVsc2UgQkFTRVxcbiAgcmVxdWlyZShwcm9qZWN0aW9uKGFkbWl0dGVkKT09d2FudGVkLFxcJ2RyeS1ydW4gY2hhbmdlZCBhbnl0aGluZyBiZXlvbmQgZXhhY3QgaW1hZ2VcXCcpXFxuICBkaWZmPXJ1bihbXFwna3ViZWN0bFxcJyxcXCdkaWZmXFwnLFxcJy1mXFwnLFxcJy1cXCddLGpzb24uZHVtcHMoYm9keSkpO3JlcXVpcmUoZGlmZi5yZXR1cm5jb2RlIGluICgwLDEpLFxcJ2NsaWVudCBkaWZmIHVuYXZhaWxhYmxlXFwnKVxcbiAgb3BlcmF0aW9uPXtcXCdpbml0aWF0ZWRCeVxcJzp7XFwndXNlcm5hbWVcXCc6XFwnY3VzdG9kaWFuLWNvZGV4XFwnfSxcXCdzeW5jXFwnOntcXCdyZXZpc2lvblxcJzpkZXN0aW5hdGlvbixcXCdwcnVuZVxcJzpGYWxzZSxcXG4gICBcXCdyZXNvdXJjZXNcXCc6W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dfX1cXG4gIHBhdGNoPVt7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS91aWRcXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCd1aWRcXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9tZXRhZGF0YS9yZXNvdXJjZVZlcnNpb25cXCcsXFwndmFsdWVcXCc6YXBwW1xcJ21ldGFkYXRhXFwnXVtcXCdyZXNvdXJjZVZlcnNpb25cXCddfSxcXG4gICB7XFwnb3BcXCc6XFwndGVzdFxcJyxcXCdwYXRoXFwnOlxcJy9zcGVjL3NvdXJjZS90YXJnZXRSZXZpc2lvblxcJyxcXCd2YWx1ZVxcJzphcHBbXFwnc3BlY1xcJ11bXFwnc291cmNlXFwnXVtcXCd0YXJnZXRSZXZpc2lvblxcJ119LFxcbiAgIHtcXCdvcFxcJzpcXCdyZXBsYWNlXFwnLFxcJ3BhdGhcXCc6XFwnL3NwZWMvc291cmNlL3RhcmdldFJldmlzaW9uXFwnLFxcJ3ZhbHVlXFwnOmRlc3RpbmF0aW9ufSxcXG4gICB7XFwnb3BcXCc6XFwnYWRkXFwnLFxcJ3BhdGhcXCc6XFwnL29wZXJhdGlvblxcJyxcXCd2YWx1ZVxcJzpvcGVyYXRpb259XVxcbiAgYXJndj1bXFwna3ViZWN0bFxcJyxcXCdwYXRjaFxcJyxcXCdhcHBsaWNhdGlvblxcJyxcXCdpbmZvcm1lZC1kZWNpc2lvblxcJyxcXCctblxcJyxcXCdhcmdvY2RcXCcsXFwnLS10eXBlPWpzb25cXCcsXFwnLS1wYXRjaC1maWxlPS9kZXYvc3RkaW5cXCcsXFwnLW9cXCcsXFwnbmFtZVxcJ11cXG4gIHBhdGNoZHJ5PXJ1bihhcmd2K1tcXCctLWRyeS1ydW49c2VydmVyXFwnXSxqc29uLmR1bXBzKHBhdGNoKSk7cmVxdWlyZShwYXRjaGRyeS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIG9wZXJhdGlvbiBkcnktcnVuIHJlZnVzZWRcXCcpXFxuICBjaGFuZ2U9cnVuKGFyZ3YsanNvbi5kdW1wcyhwYXRjaCkpXFxuICByZXF1aXJlKGNoYW5nZS5yZXR1cm5jb2RlPT0wLFxcJ0FwcGxpY2F0aW9uIHBhdGNoIG91dGNvbWUgYW1iaWd1b3VzOyBkbyBub3QgcmV0cnlcXCcpXFxuICByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1UcnVlLG9wZXJhdGlvbl9yZXF1ZXN0ZWQ9VHJ1ZSxzb3VyY2VfcmV2aXNpb249ZGVzdGluYXRpb24sXFxuICAgcmVzb3VyY2VzPW9wZXJhdGlvbltcXCdzeW5jXFwnXVtcXCdyZXNvdXJjZXNcXCddLHBydW5lPUZhbHNlLHJvbGxvdXRfdmVyaWZpZWQ9RmFsc2UsXFxuICAgbGF0ZXN0X2xpdmVfZGF0YWJhc2VfcmV0YWluZWQ9VHJ1ZSxjbGllbnRfZGlmZl9zaGEyNTY9aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpKVxcbiBpZiBwaGFzZSBpbiAoXFwndmVyaWZ5XFwnLFxcJ3JvbGxiYWNrLXZlcmlmeVxcJyk6XFxuICBvcD1hcHAuZ2V0KFxcJ3N0YXR1c1xcJyx7fSkuZ2V0KFxcJ29wZXJhdGlvblN0YXRlXFwnLHt9KTtzeW5jPW9wLmdldChcXCdvcGVyYXRpb25cXCcse30pLmdldChcXCdzeW5jXFwnLHt9KVxcbiAgcmVxdWlyZShvcC5nZXQoXFwncGhhc2VcXCcpPT1cXCdTdWNjZWVkZWRcXCcgYW5kIHN5bmMuZ2V0KFxcJ3JldmlzaW9uXFwnKT09dGFyZ2V0IGFuZCBzeW5jLmdldChcXCdwcnVuZVxcJykgaXMgRmFsc2VcXG4gICBhbmQgc3luYy5nZXQoXFwncmVzb3VyY2VzXFwnKT09W3tcXCdncm91cFxcJzpcXCdhcHBzXFwnLFxcJ2tpbmRcXCc6XFwnRGVwbG95bWVudFxcJyxcXCduYW1lXFwnOlxcJ2luZm9ybWVkLWRlY2lzaW9uXFwnLFxcJ25hbWVzcGFjZVxcJzpcXCdpbmZvcm1lZC1kZWNpc2lvblxcJ31dLFxcJ2V4YWN0IG5hdGl2ZSBBcmdvIG9wZXJhdGlvbiBjb21wbGV0aW9uIHVudmVyaWZpZWRcXCcpXFxuICByZXF1aXJlKGxpdmVbXFwnc3RhdHVzXFwnXS5nZXQoXFwnb2JzZXJ2ZWRHZW5lcmF0aW9uXFwnKT09bGl2ZVtcXCdtZXRhZGF0YVxcJ11bXFwnZ2VuZXJhdGlvblxcJ10sXFwnY29udHJvbGxlciBnZW5lcmF0aW9uIG5vdCBzZXR0bGVkXFwnKVxcbiAgcmVzdWx0LnVwZGF0ZShuYXRpdmVfcm9sbG91dF92ZXJpZmllZD1UcnVlLGN1cnJlbnRfc2NoZW1hNV9kYXRhYmFzZV9yZXRhaW5lZD1UcnVlLHJlY292ZXJ5X3ZlcmlmaWNhdGlvbj1waGFzZT09XFwncm9sbGJhY2stdmVyaWZ5XFwnKVxcbmV4Y2VwdCBCYXNlRXhjZXB0aW9uIGFzIGVycm9yOlxcbiByZXN1bHQudXBkYXRlKGFsbF9jaGVja3NfcGFzcz1GYWxzZSxmYWlsdXJlX2NsYXNzPXR5cGUoZXJyb3IpLl9fbmFtZV9fLFxcbiAgZmFpbHVyZT1cXCdmaXhlZCBwaGFzZSBvdXRjb21lIHJlZnVzZWQgb3IgYW1iaWd1b3VzOyByYXcgb3V0cHV0IHdpdGhoZWxkOyBubyByZXRyeVxcJylcXG5wcmludChqc29uLmR1bXBzKHJlc3VsdCkpO3N5cy5leGl0KDAgaWYgcmVzdWx0LmdldChcXCdhbGxfY2hlY2tzX3Bhc3NcXCcpIGlzIFRydWUgZWxzZSAxKVxcbidcbiIKICAgIH0sCiAgICAicGFja2V0LXJlZmluZW1lbnQuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIzMWI3MThhNDllZDQ3NTg2NWVkZWExYjJmNmQ3NDlhNTBhM2U2NmY1NmRiYzRmYTliNWZmMTE1OGFjYWVmNTYzIiwKICAgICAgImNvbnRlbnQiOiAie1xuICBcInByb3Bvc2FsX2lkXCI6IFwiSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjFcIixcbiAgXCJ0cmlhbF9pZFwiOiBcImluZmQtcHVycG9zZS0yMDI2MTAxMS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm9yaWdpbmFsX2FwcHJvdmVkX3NvdXJjZVwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIixcbiAgXCJvcmlnaW5hbF9wYWNrZXRfYXJjaGl2ZVwiOiBcImluaXRpYWwtYXBwcm92ZWQtYmM2NDk0Y2RcIixcbiAgXCJvcmlnaW5hbF9hcHByb3ZlZF9zdWJtaXNzaW9uX2RpZ2VzdFwiOiBcInNoYTI1NjpmZDc4ZDQ4NjE3NDY3MGUxMmVmYjJmODEyYmFjMDJlNjhmMjk0ZTc3OTFiOTMwMmQwZDQ1OGMwNTMyNDBmNWE5XCIsXG4gIFwib3JpZ2luYWxfZmFpbGVkX2pvdXJuYWxfc2hhMjU2XCI6IFwiZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMVwiLFxuICBcIm9yaWdpbmFsX29sZF91bmNlcnRhaW5fcmV0cnlcIjogZmFsc2UsXG4gIFwicmVzY3VlX3BoYXNlXCI6IFwiZHJpbGwtY29weS1yZXNjdWUtcjFcIixcbiAgXCJyZWZpbmVtZW50c1wiOiBbXG4gICAgXCJleHBsaWNpdGNsb3NlIGxpdmUgV0FMLWF3YXJlIGluc3BlY3RvclwiLFxuICAgIFwiaW1tdXRhYmxlIGZpeGVkIGhhc2gtYm91bmQgZnJvemVuIHNuYXBzaG90IGFsbG93aW5nIHJldGFpbmVkIHN0YWxlU0hNIG9ubHkgd2l0aCB6ZXJvV0FMXCIsXG4gICAgXCJuZXcgc2VwYXJhdGVseSBsaW5rZWQgam91cm5hbCBhbmQgZGlzdGluY3QgbmFtZWQgcmVzY3VlLWNvcHkgYXR0ZW1wdFwiLFxuICAgIFwicmVtYWluaW5nIHBoYXNlIGlucHV0IGV4cGxpY2l0bHkgcmVzY3VlZCByZXN1bHRcIlxuICBdLFxuICBcIm5ld19uYXRpdmVfYWN0aW9uc1wiOiBmYWxzZSxcbiAgXCJuZXdfZm91bmRlcl9hcHByb3ZhbFwiOiBmYWxzZVxufVxuIgogICAgfSwKICAgICJyZWNlaXB0X3NhZmV0eS5weSI6IHsKICAgICAgInNoYTI1NiI6ICI1YzU0MzczZjJkYzRiMDY0MDA4MjI1YzE4NmVmYjFkNWFmZGVlYzM2ZDE1MzUwYmRhMGExMmRlZDk3NjAyZDFiIiwKICAgICAgImNvbnRlbnQiOiAiXCJcIlwiT25seSBzdHJ1Y3R1cmFsIGNvdW50L2hhc2ggcmVjZWlwdHMgY2FuIGxlYXZlIHRoZSBwcml2YXRlIGV4ZWN1dGlvbiBwaGFzZS5cIlwiXCJcbmRlZiBjb3VudHModmFsdWUpOlxuICAgIGlmIChzZXQodmFsdWUpICE9IHsnc2NoZW1hX3ZlcnNpb24nLCAnbGlmZWN5Y2xlJywgJ291dGJveCcsICdzdWJtaXNzaW9ucycsICdpbnRlZ3JpdHknLFxuICAgICAgICAgICAgICAgICAgICAgICAncmVhZF9vbmx5X3ByZV9vcGVuJywgJ3N0b3JlX2NvbnN0cnVjdGVkJ31cbiAgICAgICAgICAgIG9yIHZhbHVlWydzY2hlbWFfdmVyc2lvbiddICE9IDUgb3IgdmFsdWVbJ2ludGVncml0eSddICE9ICdvaydcbiAgICAgICAgICAgIG9yIHZhbHVlWydyZWFkX29ubHlfcHJlX29wZW4nXSBpcyBub3QgVHJ1ZSBvciB2YWx1ZVsnc3RvcmVfY29uc3RydWN0ZWQnXSBpcyBub3QgRmFsc2VcbiAgICAgICAgICAgIG9yIHNldCh2YWx1ZVsnbGlmZWN5Y2xlJ10pICE9IHsncmVjb3JkcycsICdldmVudHMnLCAncGVuZGluZyd9XG4gICAgICAgICAgICBvciBub3Qgc2V0KHZhbHVlWydvdXRib3gnXSkgPD0geydwZW5kaW5nJywgJ2RlbGl2ZXJlZCcsICdibG9ja2VkJ31cbiAgICAgICAgICAgIG9yIG5vdCBzZXQodmFsdWVbJ3N1Ym1pc3Npb25zJ10pIDw9IHsncHJlcGFyZWQnLCAnaW5fZmxpZ2h0JywgJ2NvbmZpcm1lZCcsICd1bnJlc29sdmVkJ30pOlxuICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdjb3VudC1vbmx5IHJlY2VpcHQgc2hhcGUvc3RhdGUgcmVmdXNlZDsgdmFsdWVzIHdpdGhoZWxkJylcbiAgICBmb3IgZ3JvdXAgaW4gKCdsaWZlY3ljbGUnLCAnb3V0Ym94JywgJ3N1Ym1pc3Npb25zJyk6XG4gICAgICAgIGlmIGFueSh0eXBlKG51bWJlcikgaXMgbm90IGludCBvciBudW1iZXIgPCAwIG9yIG51bWJlciA+IDEwKioxMlxuICAgICAgICAgICAgICAgZm9yIG51bWJlciBpbiB2YWx1ZVtncm91cF0udmFsdWVzKCkpOlxuICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignY291bnQtb25seSByZWNlaXB0IHZhbHVlcyByZWZ1c2VkJylcbiAgICByZXR1cm4gdmFsdWVcbiIKICAgIH0sCiAgICAicm9vdC1hdXRob3JpdHktcmVjZWlwdC10ZW1wbGF0ZS5qc29uIjogewogICAgICAic2hhMjU2IjogImRiMjhkMDNlM2M0NmI0ZGU1MmRjNDA0YzkxMjA1NDQ4M2Y0YTJhYWE2YzRmNDc2Yjc4OTJjYWIyYTVmNDA4ZDQiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwicHJvcG9zYWxfaWRcIjogXCJJTkZELVdQLTAwMDktVDA0L3B1cnBvc2Utb3ZlcmxheS12MVwiLFxuICBcIm1lbW9faWRcIjogXCJpbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMVwiLFxuICBcIm1lbW9fdmVyc2lvblwiOiAyLFxuICBcIm1lbW9fc2hhMjU2XCI6IG51bGwsXG4gIFwic291cmNlX3JldmlzaW9uXCI6IG51bGwsXG4gIFwiYWN0aXZhdGlvblwiOiBcIlBFTkRJTkdcIixcbiAgXCJhdXRob3JpdHlfbW9kZVwiOiBcIkFETUlOSVNURVJcIixcbiAgXCJ0YXJnZXRcIjogXCJyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uXCIsXG4gIFwidmVyaWZpY2F0aW9uX21ldGhvZFwiOiBcInJvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFja1wiLFxuICBcInJ1bnRpbWVfYXV0aGVudGljYXRlZF9ncmFudFwiOiBmYWxzZSxcbiAgXCJ2ZXJpZmllZF9hdFwiOiBudWxsLFxuICBcImFjY2VwdGVkX2F0XCI6IG51bGwsXG4gIFwicmV2aWV3X21lbW9faWRcIjogbnVsbCxcbiAgXCJhcHByb3ZhbF9pZFwiOiBudWxsLFxuICBcImRpc3Bvc2l0aW9uX2lkXCI6IG51bGwsXG4gIFwibmF0aXZlX291dGNvbWVfc2hhMjU2XCI6IG51bGwsXG4gIFwiZXhlY3V0b3JfcGxhbl9zaGEyNTZcIjogXCI0ZDU1MzBlNzQxOGY2MzhiMTBjY2ZmMGUwZDlhMDcyN2FkYzY0YTdmM2E0NTkwN2Y2ZGViNTczOWFkMmFkYzg1XCIsXG4gIFwib3V0Y29tZV9xdWVyeVwiOiBcIi9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0yXCIsXG4gIFwicmV2aWV3X21lbW9fdmVyc2lvblwiOiAxXG59XG4iCiAgICB9LAogICAgInRlc3RfZXhlY3V0aW9uLnB5IjogewogICAgICAic2hhMjU2IjogImIyNTA0NDEyODI1MTM4NjJlZWI5OTBiMThkMDFiYjFlYWZlNzg3YjkzNGQ2NzBhNzVhMmJmYWE5ZjVjZmI4OWMiLAogICAgICAiY29udGVudCI6ICJcIlwiXCJTeW50aGV0aWMgY3VzdG9keS90cmFuc3BvcnQgdGVzdHMuIE5vIG5hdGl2ZSBkYXRhLCBEb2NrZXIgb3IgY2x1c3RlciBhY3Rpb24uXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaW9cbmltcG9ydCBqc29uXG5pbXBvcnQgb3NcbmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aFxuaW1wb3J0IHN1YnByb2Nlc3NcbmltcG9ydCBzeXNcbmltcG9ydCB0ZW1wZmlsZVxuaW1wb3J0IHVuaXR0ZXN0XG5mcm9tIHVuaXR0ZXN0Lm1vY2sgaW1wb3J0IHBhdGNoXG5mcm9tIGNvbnRleHRsaWIgaW1wb3J0IHJlZGlyZWN0X3N0ZG91dFxuXG5pbXBvcnQgYWN0dWF0b3JcbmZyb20gYXV0aG9yaXR5X2pvdXJuYWwgaW1wb3J0IEpvdXJuYWwsIGF1dGhvcml0eVxuZnJvbSBuYXRpdmVfcHJvZ3JhbSBpbXBvcnQgUFJPR1JBTVxuZnJvbSByZWNlaXB0X3NhZmV0eSBpbXBvcnQgY291bnRzXG5cbkNBU0UgPSBQYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24vZG9jcy9ldmlkZW5jZS8yMDI2LTEwLTExLXB1cnBvc2UtaW1hZ2UtcmVsZWFzZScpXG5OT1cgPSBkYXRldGltZS5kYXRldGltZSgyMDI2LCAxMCwgMTEsIDIsIDAsIHR6aW5mbz1kYXRldGltZS50aW1lem9uZS51dGMpXG5SRVZJU0lPTiA9ICdlJyAqIDQwXG5DT1VOVCA9IHsnc2NoZW1hX3ZlcnNpb24nOiA1LCAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlLFxuICAgICAgICAgJ2xpZmVjeWNsZSc6IHsncmVjb3Jkcyc6IDMsICdldmVudHMnOiA4LCAncGVuZGluZyc6IDF9LFxuICAgICAgICAgJ291dGJveCc6IHsncGVuZGluZyc6IDIsICdkZWxpdmVyZWQnOiAxMH0sICdzdWJtaXNzaW9ucyc6IHsnY29uZmlybWVkJzogMSwgJ3VucmVzb2x2ZWQnOiAxfX1cblxuXG5kZWYgYWNjZXB0ZWQoKTpcbiAgICBhcHByb3ZhbCA9ICcxMTExMTExMS0xMTExLTQxMTEtODExMS0xMTExMTExMTExMTEnXG4gICAgcmV2aWV3ID0gJ3Jldmlldy0yMjIyMjIyMi0yMjIyLTQyMjItODIyMi0yMjIyMjIyMjIyMjInXG4gICAgZGlzcG9zaXRpb24gPSAnZGlzcC0zMzMzMzMzMy0zMzMzLTQzMzMtODMzMy0zMzMzMzMzMzMzMzMnXG4gICAgcmVjZWlwdCA9IHsncHJvcG9zYWxfaWQnOiAnSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEnLFxuICAgICAgICAgICAgICAgJ21lbW9faWQnOiAnaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEnLCAnbWVtb192ZXJzaW9uJzogMixcbiAgICAgICAgICAgICAgICdtZW1vX3NoYTI1Nic6ICdhJyAqIDY0LCAnc291cmNlX3JldmlzaW9uJzogUkVWSVNJT04sICdhY3RpdmF0aW9uJzogJ0FQUFJPVkVEJyxcbiAgICAgICAgICAgICAgICdhdXRob3JpdHlfbW9kZSc6ICdBRE1JTklTVEVSJywgJ3RhcmdldCc6ICdyZWFsbTprdWJlcm5ldGVzL3JhaWxpYW5jZTAxL2luZm9ybWVkLWRlY2lzaW9uJyxcbiAgICAgICAgICAgICAgICd2ZXJpZmljYXRpb25fbWV0aG9kJzogJ3Jvb3QtZml4ZWQtb3JpZ2luLW5hdGl2ZS1yZWFkYmFjaycsICdydW50aW1lX2F1dGhlbnRpY2F0ZWRfZ3JhbnQnOiBGYWxzZSwgJ291dGNvbWVfcXVlcnknOiAnL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9vdXRjb21lcz92ZXJzaW9uPTInLFxuICAgICAgICAgICAgICAgJ3ZlcmlmaWVkX2F0JzogJzIwMjYtMTAtMTFUMDI6MDA6MDBaJywgJ2FjY2VwdGVkX2F0JzogJzIwMjYtMTAtMTFUMDE6NTk6MDBaJyxcbiAgICAgICAgICAgICAgICdyZXZpZXdfbWVtb19pZCc6IHJldmlldywgJ2FwcHJvdmFsX2lkJzogYXBwcm92YWwsICdkaXNwb3NpdGlvbl9pZCc6IGRpc3Bvc2l0aW9ufVxuICAgIG91dGNvbWUgPSB7J21lbW9faWQnOiByZWNlaXB0WydtZW1vX2lkJ10sICdyZXZpZXcnOiB7J21lbW9faWQnOiByZXZpZXcsICdzdGFsZSc6IEZhbHNlLCAnaW50YWtlX3N0YXRlJzogJ3JlYWR5J30sXG4gICAgICAgICAgICAgICAnZGlzcG9zaXRpb25zJzogW3snYXBwcm92YWxfaWQnOiBOb25lLCAnc3VibWlzc2lvbl9zdGF0ZSc6ICdjb25maXJtZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Rpc3Bvc2l0aW9uJzogeyd2ZXJiJzogJ2FjY2VwdCcsICdtZW1vX3ZlcnNpb24nOiAxLCAnbWVtb19pZCc6IHJldmlldyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXBwcm92YWxfaWQnOiBhcHByb3ZhbCwgJ2lkJzogZGlzcG9zaXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FjdG9yJzogeydraW5kJzogJ3BlcnNvbicsICdzdWInOiAndWlkPXBsYXRmb3JtLXJvb3Qsb3U9cGVvcGxlLGRjPW5ldGtpbmdkb20sZGM9bG9jYWwnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXQnOiByZWNlaXB0WydhY2NlcHRlZF9hdCddfX1dfVxuICAgIHJldHVybiByZWNlaXB0LCBvdXRjb21lXG5cblxuY2xhc3MgQXV0aG9yaXR5QW5kQ3VzdG9keSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIHRlc3RfZXhhY3RfbmVzdGVkX2ZvdW5kZXJfcmVjZWlwdF9ub3RfdG9wX2xldmVsX2FwcHJvdmFsKHNlbGYpOlxuICAgICAgICByZWNlaXB0LCBvdXRjb21lID0gYWNjZXB0ZWQoKVxuICAgICAgICByZXN1bHQgPSBhdXRob3JpdHkocmVjZWlwdCwgb3V0Y29tZSwgJ2EnICogNjQsIFJFVklTSU9OLCAnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBOT1cpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WydhcHByb3ZhbF9pZCddLCByZWNlaXB0WydhcHByb3ZhbF9pZCddKVxuXG4gICAgZGVmIHRlc3RfcGVuZGluZ19zdGFsZV93cm9uZ19hY3Rvcl92ZXJzaW9uX2FuZF9iaW5kaW5nX3JlZnVzZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSByLCBvOiByLnVwZGF0ZShhY3RpdmF0aW9uPSdQRU5ESU5HJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUobWVtb19zaGEyNTY9J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZShzb3VyY2VfcmV2aXNpb249J2NoYW5nZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiByLnVwZGF0ZSh0YXJnZXQ9J290aGVyJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpZWRfYXQ9JzIwMjYtMTAtMTFUMDE6MDA6MDBaJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUodmVyaWZpY2F0aW9uX21ldGhvZD0nY2FsbGVyLWFzc2VydGVkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogci51cGRhdGUocnVudGltZV9hdXRoZW50aWNhdGVkX2dyYW50PVRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ3JldmlldyddLnVwZGF0ZShzdGFsZT1UcnVlKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydyZXZpZXcnXS51cGRhdGUoaW50YWtlX3N0YXRlPSdwZW5kaW5nJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ11bMF0udXBkYXRlKHN1Ym1pc3Npb25fc3RhdGU9J3VucmVzb2x2ZWQnKSxcbiAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSByLCBvOiBvWydkaXNwb3NpdGlvbnMnXVswXVsnZGlzcG9zaXRpb24nXS51cGRhdGUobWVtb192ZXJzaW9uPTMpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHIsIG86IG9bJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddLnVwZGF0ZShhY3Rvcj17J2tpbmQnOiAnYWdlbnQnLCAnc3ViJzogJ3BsYXRmb3JtLXJvb3QnfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgciwgbzogb1snZGlzcG9zaXRpb25zJ10uYXBwZW5kKGNvcHkuZGVlcGNvcHkob1snZGlzcG9zaXRpb25zJ11bMF0pKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICAgICAgICAgIG11dGF0ZShyLCBvKVxuICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyZWxlYXNlJywgTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwaXJlZF93aW5kb3dfYW5kX3Vua25vd25fcGhhc2VfcmVmdXNlKHNlbGYpOlxuICAgICAgICByLCBvID0gYWNjZXB0ZWQoKVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgYXV0aG9yaXR5KHIsIG8sICdhJyAqIDY0LCBSRVZJU0lPTiwgJ2FyYml0cmFyeScsIE5PVylcbiAgICAgICAgbGF0ZSA9IGRhdGV0aW1lLmRhdGV0aW1lKDIwMjYsIDEwLCAxMywgdHppbmZvPWRhdGV0aW1lLnRpbWV6b25lLnV0YylcbiAgICAgICAgclsndmVyaWZpZWRfYXQnXSA9IGxhdGUuaXNvZm9ybWF0KClcbiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgIGF1dGhvcml0eShyLCBvLCAnYScgKiA2NCwgUkVWSVNJT04sICdyb2xsYmFjaycsIGxhdGUpXG5cbiAgICBkZWYgdGVzdF9kdXJhYmxlX2ludGVudF9wcmVjZWRlc19kaXNwYXRjaF9hbmRfbmV2ZXJfcmV0cmllcyhzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQgPSBQYXRoKGRpcmVjdG9yeSlcbiAgICAgICAgICAgIG9zLmNobW9kKHBhcmVudCwgMG83MDApXG4gICAgICAgICAgICBqb3VybmFsID0gSm91cm5hbChwYXJlbnQsIHsnY2FzZSc6ICdmaXh0dXJlJ30pXG4gICAgICAgICAgICBqb3VybmFsLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIHsnYXBwcm92YWxfaWQnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChqc29uLmxvYWRzKGpvdXJuYWwucGF0aC5yZWFkX3RleHQoKSlbJ3BoYXNlcyddWydkcmlsbC1jb3B5LXJlc2N1ZS1yMSddWydzdGF0ZSddLCAnUlVOTklORycpXG4gICAgICAgICAgICBqb3VybmFsLmNsb3NlKCkgICMgc2ltdWxhdGVkIGNyYXNoIGJlZm9yZSByZXN1bHRcbiAgICAgICAgICAgIHJlY292ZXJlZCA9IEpvdXJuYWwocGFyZW50LCB7J2Nhc2UnOiAnZml4dHVyZSd9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICByZWNvdmVyZWQuc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIHJlY292ZXJlZC5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCB7fSlcbiAgICAgICAgICAgIHJlY292ZXJlZC5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9waGFzZV9vcmRlcl9hbmRfdW5jZXJ0YWluX3JlbGVhc2VfYWxsb3dzX29ubHlfZGlzdGluY3RfcmVjb3Zlcnkoc2VsZik6XG4gICAgICAgIHdpdGggdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZGlyZWN0b3J5OlxuICAgICAgICAgICAgb3MuY2htb2QoZGlyZWN0b3J5LCAwbzcwMClcbiAgICAgICAgICAgIGogPSBKb3VybmFsKGRpcmVjdG9yeSwgeydjYXNlJzogJ2ZpeHR1cmUnfSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgai5zdGFydCgncmVsZWFzZScsIHt9KVxuICAgICAgICAgICAgZm9yIHBoYXNlIGluIGFjdHVhdG9yLlBIQVNFU1s6NV06XG4gICAgICAgICAgICAgICAgai5zdGFydChwaGFzZSwge30pXG4gICAgICAgICAgICAgICAgai5maW5pc2gocGhhc2UsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICBqLmZpbmlzaCgncmVsZWFzZScsIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2V9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBqLnN0YXJ0KCdyZWxlYXNlJywge30pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGouc3RhcnQoJ3ZlcmlmeScsIHt9KVxuICAgICAgICAgICAgai5zdGFydCgncm9sbGJhY2snLCB7fSlcbiAgICAgICAgICAgIGouZmluaXNoKCdyb2xsYmFjaycsIHsnYWxsX2NoZWNrc19wYXNzJzogVHJ1ZX0pXG4gICAgICAgICAgICBqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X3NlY3JldF9vcl91bmtub3duX2NoaWxkX291dHB1dF9pc193aXRoaGVsZChzZWxmKTpcbiAgICAgICAgZm9yIGJvZHkgaW4gKCdub3QtanNvbicsICd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwidG9rZW5cIjpcInByaXZhdGUtdmFsdWVcIn0nLFxuICAgICAgICAgICAgICAgICAgICAgJ3tcImFsbF9jaGVja3NfcGFzc1wiOnRydWUsXCJzbmFwc2hvdF9yZWFkb25seVwiOntcInNjaGVtYV92ZXJzaW9uXCI6NX19Jyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgICAgIGFjdHVhdG9yLmpzb25fcmVzdWx0KHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwgMCwgYm9keSwgJycpKVxuICAgICAgICB3cm9uZyA9IGNvcHkuZGVlcGNvcHkoQ09VTlQpXG4gICAgICAgIHdyb25nWydvdXRib3gnXSA9IHsncHJpdmF0ZS1yb3ctdmFsdWUnOiAxfVxuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOlxuICAgICAgICAgICAgY291bnRzKHdyb25nKVxuICAgICAgICBjb3VudHMoQ09VTlQpICAjIGJsb2NrZWQvdW5yZXNvbHZlZCBjb3VudHMgYXJlIG5vdCByZXF1aXJlZCB0byBiZSB6ZXJvLlxuXG4gICAgZGVmIHRlc3RfYmluYXJ5X2NvcHlfaXNfYm91bmRlZF9wcml2YXRlX2FuZF9uZXZlcl9lY2hvZWQoc2VsZik6XG4gICAgICAgIGJsb2IgPSBiJ3N5bnRoZXRpYyBwcml2YXRlIGZpeHR1cmUgYnl0ZXMnXG4gICAgICAgIGRpZ2VzdCA9IF9faW1wb3J0X18oJ2hhc2hsaWInKS5zaGEyNTYoYmxvYikuaGV4ZGlnZXN0KClcbiAgICAgICAgbWV0YWRhdGEgPSB7J2FsbF9jaGVja3NfcGFzcyc6IFRydWUsICdzbmFwc2hvdF9maWxlJzogJ2RyaWxsLnNxbGl0ZScsICdzbmFwc2hvdF9ieXRlcyc6IGxlbihibG9iKSxcbiAgICAgICAgICAgICAgICAgICAgJ3NuYXBzaG90X3NoYTI1Nic6IGRpZ2VzdCwgJ3NuYXBzaG90X3JlYWRvbmx5JzogQ09VTlQsXG4gICAgICAgICAgICAgICAgICAgICdwb2RfbmFtZSc6ICdmaXh0dXJlLXBvZCcsICdwb2RfdWlkJzogJ2ZpeHR1cmUtdWlkJ31cbiAgICAgICAgam91cm5hbCA9IHR5cGUoJ0ZpeHR1cmVKb3VybmFsJywgKCksIHsnZGF0YSc6IHsnaWRlbnRpdHknOiB7J3JlY292ZXJ5X2FuY2hvcic6IHsnYmFja3VwX3Jlc3VsdCc6IG1ldGFkYXRhfX19fSkoKVxuICAgICAgICByZWFsX3BvcGVuID0gc3VicHJvY2Vzcy5Qb3BlblxuICAgICAgICBmb3IgZXh0cmEgaW4gKGInJywgYidvdmVyc2l6ZWQnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGV4dHJhPWV4dHJhKSwgdGVtcGZpbGUuVGVtcG9yYXJ5RGlyZWN0b3J5KCkgYXMgZm9sZGVyOlxuICAgICAgICAgICAgICAgIG9zLmNobW9kKGZvbGRlciwgMG83MDApXG4gICAgICAgICAgICAgICAgb3V0cHV0ID0gaW8uU3RyaW5nSU8oKVxuXG4gICAgICAgICAgICAgICAgZGVmIGNoaWxkKCphcmdzLCAqKmt3YXJncyk6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFsX3BvcGVuKFtzeXMuZXhlY3V0YWJsZSwgJy1jJywgJ2ltcG9ydCBzeXM7c3lzLnN0ZG91dC5idWZmZXIud3JpdGUoJyArIHJlcHIoYmxvYiArIGV4dHJhKSArICcpJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwpXG5cbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwgJ0NVU1RPRFknLCBQYXRoKGZvbGRlcikpLCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdyZW1vdGUnLCByZXR1cm5fdmFsdWU9bWV0YWRhdGEpLCBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2goJ3N1YnByb2Nlc3MuUG9wZW4nLCBzaWRlX2VmZmVjdD1jaGlsZCksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgICAgICAgICBpZiBleHRyYTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWF0b3IuY29weV9zbmFwc2hvdCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLCBSRVZJU0lPTiwge30sIGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBhY3R1YXRvci5jb3B5X3NuYXBzaG90KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsIFJFVklTSU9OLCB7fSwgam91cm5hbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXN1bHRbJ29mZl9jbHVzdGVyX3ByaXZhdGVfY29weV92ZXJpZmllZCddKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoUGF0aChmb2xkZXIpIC8gJ2RyaWxsLnNxbGl0ZScpLnJlYWRfYnl0ZXMoKSwgYmxvYilcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG91dHB1dC5nZXR2YWx1ZSgpLCAnJylcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKChQYXRoKGZvbGRlcikgLyAnZHJpbGwuc3FsaXRlJykuc3RhdCgpLnN0X21vZGUgJiAwbzc3NywgMG82MDApXG5cbiAgICBkZWYgdGVzdF9yZWNyZWF0ZWRfb2ZmbGluZV92b2x1bWVfY2Fubm90X2JlX2RlbGV0ZWQoc2VsZik6XG4gICAgICAgIGlkZW50aXR5ID0geydOYW1lJzogYWN0dWF0b3IuVk9MVU1FLCAnTGFiZWxzJzogeydub25jZSc6ICdvbGQnfSwgJ0NyZWF0ZWRBdCc6ICdvbGQnfVxuICAgICAgICBqb3VybmFsID0gdHlwZSgnRml4dHVyZUpvdXJuYWwnLCAoKSwgeydkYXRhJzogeydwaGFzZXMnOiB7XG4gICAgICAgICAgICAnb2ZmbGluZS12ZXJpZnknOiB7J3Jlc3VsdCc6IHsnY3JlYXRlZF92b2x1bWVfaWRlbnRpdHknOiBpZGVudGl0eX19fX19KSgpXG4gICAgICAgIGluc3BlY3RlZCA9IFt7KippZGVudGl0eSwgJ0NyZWF0ZWRBdCc6ICdyZWNyZWF0ZWQnfV1cbiAgICAgICAgd2l0aCBwYXRjaC5vYmplY3QoYWN0dWF0b3IsICdkb2NrZXInLCByZXR1cm5fdmFsdWU9c3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKFtdLCAwLCBqc29uLmR1bXBzKGluc3BlY3RlZCksICcnKSkgYXMgbW9ja2VkOlxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpcbiAgICAgICAgICAgICAgICBhY3R1YXRvci5jbGVhbnVwX29mZmxpbmUoam91cm5hbClcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobW9ja2VkLmNhbGxfY291bnQsIDEpXG5cbiAgICBkZWYgdGVzdF9vZmZsaW5lX3Bvc3RfYWRtaW5faW50ZWdyaXR5X2FuZF9vcmlnaW5hbF9oYXNoX2FyZV9yZWNoZWNrZWQoc2VsZik6XG4gICAgICAgIGZvciBkZWZlY3QgaW4gKCdub25lJywgJ3Bvc3QtaW50ZWdyaXR5JywgJ29yaWdpbmFsLWhhc2gnKTpcbiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGRlZmVjdD1kZWZlY3QpLCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgZm9sZGVyPVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChmb2xkZXIsMG83MDApXG4gICAgICAgICAgICAgICAgc25hcHNob3Q9Zm9sZGVyLydkcmlsbC5zcWxpdGUnO3NuYXBzaG90LndyaXRlX2J5dGVzKGIncHJpdmF0ZSBzeW50aGV0aWMgc25hcHNob3QnKTtvcy5jaG1vZChzbmFwc2hvdCwwbzYwMClcbiAgICAgICAgICAgICAgICBkaWdlc3Q9YWN0dWF0b3Iuc2hhKHNuYXBzaG90KVxuICAgICAgICAgICAgICAgIHByaW9yPXsnc25hcHNob3Rfc2hhMjU2JzpkaWdlc3QsJ3NuYXBzaG90X3JlYWRvbmx5JzpDT1VOVH1cbiAgICAgICAgICAgICAgICBqb3VybmFsPXR5cGUoJ0ZpeHR1cmVKb3VybmFsJywoKSx7J2RhdGEnOnsncGhhc2VzJzp7J2RyaWxsLWNvcHktcmVzY3VlLXIxJzp7J3Jlc3VsdCc6cHJpb3J9LCdvZmZsaW5lLXZlcmlmeSc6eydhdHRlbXB0X2lkJzonbm9uY2UnfX19LCdub3RlJzpsYW1iZGEgKmFyZ3M6Tm9uZX0pKClcbiAgICAgICAgICAgICAgICByZWFkcz1bXVxuICAgICAgICAgICAgICAgIHZvbHVtZT17J05hbWUnOmFjdHVhdG9yLlZPTFVNRSwnTGFiZWxzJzp7J2luZm9ybWVkLWRlY2lzaW9uLmNhc2UnOidpbmZkLXB1cnBvc2UtMjAyNjEwMTEtcjEnLCdpbmZvcm1lZC1kZWNpc2lvbi51c2UnOidvZmZsaW5lLXJlc3RvcmUtb25seScsJ2luZm9ybWVkLWRlY2lzaW9uLmF0dGVtcHQnOidub25jZSd9LCdEcml2ZXInOidsb2NhbCcsJ1Njb3BlJzonbG9jYWwnLCdDcmVhdGVkQXQnOidmaXh0dXJlJywnT3B0aW9ucyc6Tm9uZX1cbiAgICAgICAgICAgICAgICBkZWYgZG9ja2VyKGFyZ3YsIGJvZHk9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgICAgICAgICBpZiBhcmd2WzBdPT0naW5mbyc6Ym9keT1qc29uLmR1bXBzKCdibnQtbGFwMDAxJylcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdscyddOmJvZHk9JydcbiAgICAgICAgICAgICAgICAgICAgZWxpZiBhcmd2WzoyXT09Wyd2b2x1bWUnLCdjcmVhdGUnXTpib2R5PWFjdHVhdG9yLlZPTFVNRVxuICAgICAgICAgICAgICAgICAgICBlbGlmIGFyZ3ZbOjJdPT1bJ3ZvbHVtZScsJ2luc3BlY3QnXTpib2R5PWpzb24uZHVtcHMoW3ZvbHVtZV0pXG4gICAgICAgICAgICAgICAgICAgIGVsaWYgJ2luZm9ybWVkLWRlY2lzaW9uLWFkbWluJyBpbiBhcmd2OlxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keT1qc29uLmR1bXBzKHtrZXk6Q09VTlRba2V5XSBmb3Iga2V5IGluICgnc2NoZW1hX3ZlcnNpb24nLCdsaWZlY3ljbGUnLCdvdXRib3gnLCdzdWJtaXNzaW9ucycpfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J29yaWdpbmFsLWhhc2gnOnNuYXBzaG90LndyaXRlX2J5dGVzKGInY2hhbmdlZCBzeW50aGV0aWMgb3JpZ2luYWwnKVxuICAgICAgICAgICAgICAgICAgICBlbGlmICctLWVudHJ5cG9pbnQnIGluIGFyZ3YgYW5kICdweXRob24nIGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkcy5hcHBlbmQoYXJndik7cHJvb2Y9Y29weS5kZWVwY29weShDT1VOVClcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihyZWFkcyk9PTIgYW5kIGRlZmVjdD09J3Bvc3QtaW50ZWdyaXR5Jzpwcm9vZlsnaW50ZWdyaXR5J109J2NvcnJ1cHQnXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5PWpzb24uZHVtcHMocHJvb2YpXG4gICAgICAgICAgICAgICAgICAgIGVsc2U6cmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgb2ZmbGluZSBjb21tYW5kJylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LDAsYm9keSwnJylcbiAgICAgICAgICAgICAgICB3aXRoIHBhdGNoLm9iamVjdChhY3R1YXRvciwnQ1VTVE9EWScsZm9sZGVyKSxwYXRjaC5vYmplY3QoYWN0dWF0b3IsJ0NBU0UnLENBU0UpLHBhdGNoLm9iamVjdChhY3R1YXRvciwnZG9ja2VyJyxzaWRlX2VmZmVjdD1kb2NrZXIpLHBhdGNoKCdzdWJwcm9jZXNzLnJ1bicscmV0dXJuX3ZhbHVlPXN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2VzcyhbXSwwLCd7XCJhbGxfY2hlY2tzX3Bhc3NcIjp0cnVlLFwicHJpdmF0ZV9jb3B5X3ZlcmlmaWVkXCI6dHJ1ZX0nLCcnKSk6XG4gICAgICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J25vbmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0PWFjdHVhdG9yLm9mZmxpbmVfdmVyaWZ5KGpvdXJuYWwpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlc3VsdFsnb2ZmbGluZV9wb3N0X2FkbWluX3JlYWRvbmx5J10sQ09VTlQpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydFRydWUocmVzdWx0WydvcmlnaW5hbF9zbmFwc2hvdF9oYXNoX3VuY2hhbmdlZCddKVxuICAgICAgICAgICAgICAgICAgICBlbHNlOlxuICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTphY3R1YXRvci5vZmZsaW5lX3ZlcmlmeShqb3VybmFsKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlYWRzKSwyKVxuXG5cbmNsYXNzIEZpeGVkTmF0aXZlUHJvZ3JhbSh1bml0dGVzdC5UZXN0Q2FzZSk6XG4gICAgZGVmIGZpeHR1cmUoc2VsZik6XG4gICAgICAgIHNlYWxlZCA9IGpzb24ubG9hZHMoKENBU0UgLyAnc2VhbGVkLWxpdmUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpXG4gICAgICAgIGxpdmUgPSBjb3B5LmRlZXBjb3B5KHNlYWxlZClcbiAgICAgICAgbGl2ZVsnbWV0YWRhdGEnXS51cGRhdGUoZ2VuZXJhdGlvbj00MilcbiAgICAgICAgbGl2ZVsnc3RhdHVzJ10gPSB7J3JlYWR5UmVwbGljYXMnOiAxLCAndXBkYXRlZFJlcGxpY2FzJzogMSwgJ29ic2VydmVkR2VuZXJhdGlvbic6IDQyfVxuICAgICAgICBkZXBlbmRlbmNpZXMgPSBqc29uLmxvYWRzKChDQVNFIC8gJ3NlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY20gPSBjb3B5LmRlZXBjb3B5KGRlcGVuZGVuY2llc1snY29uZmlnbWFwJ10pXG4gICAgICAgIGNtLnBvcCgnY2Fub25pY2FsX2RhdGFfc2hhMjU2JylcbiAgICAgICAgc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UgLyAnY2FuZGlkYXRlLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKVxuICAgICAgICBzb3VyY2Vfc2VydmljZSA9IGpzb24ubG9hZHMoKENBU0UucGFyZW50c1syXSAvICdkZXBsb3kvbGlmZWN5Y2xlL3NlcnZpY2UuY2FuZGlkYXRlLmpzb24nKS5yZWFkX3RleHQoKSlcbiAgICAgICAgY21bJ2RhdGEnXSA9IG5leHQoeCBmb3IgeCBpbiBzb3VyY2Vfc2VydmljZVsnaXRlbXMnXSBpZiB4WydraW5kJ10gPT0gJ0NvbmZpZ01hcCcpWydkYXRhJ11cbiAgICAgICAgcHZjID0gY29weS5kZWVwY29weShkZXBlbmRlbmNpZXNbJ3B2YyddKVxuICAgICAgICBwdmNbJ3N0YXR1cyddID0geydwaGFzZSc6ICdCb3VuZCd9XG4gICAgICAgIGFwcCA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICc0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQnLCAncmVzb3VyY2VWZXJzaW9uJzogJzE3J30sXG4gICAgICAgICAgICAgICAnc3BlYyc6IHsnc291cmNlJzogeydyZXBvVVJMJzogJ2h0dHBzOi8vZm9yZ2Vqby5jb3Vsb21iLnNvY2lhbC9jb3Vsb21iL2luZm9ybWVkLWRlY2lzaW9uLmdpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwYXRoJzogJ2RlcGxveS9saWZlY3ljbGUnLCAndGFyZ2V0UmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZid9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2Rlc3RpbmF0aW9uJzogeyduYW1lc3BhY2UnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnc2VydmVyJzogJ2h0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yyd9fX1cbiAgICAgICAgb2JqZWN0cyA9IHsnZGVwbG95bWVudCc6IGxpdmUsICdjb25maWdtYXAnOiBjbSwgJ3B2Yyc6IHB2YywgJ2FwcGxpY2F0aW9uJzogYXBwfVxuICAgICAgICBwYXlsb2FkID0geydwaGFzZSc6ICdyZWxlYXNlJywgJ3NvdXJjZV9yZXZpc2lvbic6IFJFVklTSU9OLCAnYXBwcm92YWwnOiB7fSwgJ3NlYWxlZCc6IHNlYWxlZCxcbiAgICAgICAgICAgICAgICAgICAnZGVwZW5kZW5jaWVzJzogZGVwZW5kZW5jaWVzLCAnY2FuZGlkYXRlJzogc2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAncm9sbGJhY2snOiBqc29uLmxvYWRzKChDQVNFIC8gJ3JvbGxiYWNrLWRlcGxveW1lbnQuanNvbicpLnJlYWRfdGV4dCgpKSxcbiAgICAgICAgICAgICAgICAgICAncmVhZG9ubHknOiAoQ0FTRSAvICdzcWxpdGVfcmVhZG9ubHkucHknKS5yZWFkX3RleHQoKSwncHVycG9zZV9jaGVja3MnOihDQVNFLydjaGVja19pbnN0YWxsZWQucHknKS5yZWFkX3RleHQoKSxcbiAgICAgICAgICAgICAgICAgICAncmVjZWlwdF9zYWZldHknOiAoUGF0aChfX2ZpbGVfXykucGFyZW50IC8gJ3JlY2VpcHRfc2FmZXR5LnB5JykucmVhZF90ZXh0KCl9XG4gICAgICAgIHJldHVybiBvYmplY3RzLCBwYXlsb2FkXG5cbiAgICBkZWYgZXhlY3V0ZV9mYWtlKHNlbGYsIG9iamVjdHMsIHBheWxvYWQsIGFtYmlndW91cz1GYWxzZSwgc2NoZW1hX3JlZnVzZWQ9RmFsc2UpOlxuICAgICAgICB3cml0ZXMgPSBbXVxuICAgICAgICBjYWxscyA9IFtdXG5cbiAgICAgICAgZGVmIGZha2UoYXJndiwgaW5wdXQ9Tm9uZSwgKiprd2FyZ3MpOlxuICAgICAgICAgICAgY2FsbHMuYXBwZW5kKGFyZ3YpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZ2V0J106XG4gICAgICAgICAgICAgICAga2luZCA9IGFyZ3ZbMl1cbiAgICAgICAgICAgICAgICBpZiBraW5kIGluIG9iamVjdHM6XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSBvYmplY3RzW2tpbmRdXG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdwb2RzJzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnaXRlbXMnOiBbeydtZXRhZGF0YSc6IHsnbmFtZSc6ICdmaXh0dXJlLXBvZCcsICd1aWQnOiAncG9kLXVpZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnb3duZXJSZWZlcmVuY2VzJzogW3sna2luZCc6ICdSZXBsaWNhU2V0JywgJ25hbWUnOiAnZml4dHVyZS1ycycsICd1aWQnOiAncnMtdWlkJ31dfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwZWMnOiBvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3RhdHVzJzogeydwaGFzZSc6ICdSdW5uaW5nJywgJ2NvbnRhaW5lclN0YXR1c2VzJzogW3snbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywncmVhZHknOiBUcnVlfV19fV19XG4gICAgICAgICAgICAgICAgZWxpZiBraW5kID09ICdyZXBsaWNhc2V0JzpcbiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHsnbWV0YWRhdGEnOiB7J3VpZCc6ICdycy11aWQnLCAnb3duZXJSZWZlcmVuY2VzJzogW1xuICAgICAgICAgICAgICAgICAgICAgICAgeydraW5kJzogJ0RlcGxveW1lbnQnLCAndWlkJzogcGF5bG9hZFsnc2VhbGVkJ11bJ21ldGFkYXRhJ11bJ3VpZCddfV19fVxuICAgICAgICAgICAgICAgIGVsaWYga2luZCA9PSAnbm9kZXMnOlxuICAgICAgICAgICAgICAgICAgICBib2R5ID0geydpdGVtcyc6IFt7J21ldGFkYXRhJzogeyduYW1lJzogJ2ZpeHR1cmUtbm9kZSd9LCAnc3RhdHVzJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FkZHJlc3Nlcyc6IFt7J2FkZHJlc3MnOiAnOTIuMjA1LjYyLjIzOSd9XSwgJ2FsbG9jYXRhYmxlJzogeydjcHUnOiAnNCd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbmRpdGlvbnMnOiBbeyd0eXBlJzoga2V5LCAnc3RhdHVzJzogJ1RydWUnIGlmIGtleSA9PSAnUmVhZHknIGVsc2UgJ0ZhbHNlJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBrZXkgaW4gKCdSZWFkeScsICdNZW1vcnlQcmVzc3VyZScsICdEaXNrUHJlc3N1cmUnLCAnUElEUHJlc3N1cmUnKV19fV19XG4gICAgICAgICAgICAgICAgZWxzZTpcbiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoJ3VuZXhwZWN0ZWQgZml4ZWQgbWV0YWRhdGEgcm91dGUnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhib2R5KSwgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddOlxuICAgICAgICAgICAgICAgIGlmIHNjaGVtYV9yZWZ1c2VkOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VicHJvY2Vzcy5Db21wbGV0ZWRQcm9jZXNzKGFyZ3YsIDEsICcnLCAnd2l0aGhlbGQnKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyh7XG4gICAgICAgICAgICAgICAgICAgICdhbGxfY2hlY2tzX3Bhc3MnOiBUcnVlLCAnbGl2ZV9yZWFkb25seV9zY2hlbWFfaW50ZWdyaXR5X2NvdW50cyc6IENPVU5UfSksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2FwcGx5J106XG4gICAgICAgICAgICAgICAgYWRtaXR0ZWQgPSBjb3B5LmRlZXBjb3B5KHBheWxvYWRbJ3NlYWxlZCddKVxuICAgICAgICAgICAgICAgIGFkbWl0dGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gKGFjdHVhdG9yLklNQUdFIGlmIHBheWxvYWRbJ3BoYXNlJ109PSdyZWxlYXNlJyBlbHNlIHBheWxvYWRbJ3NlYWxlZCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddKVxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMCwganNvbi5kdW1wcyhhZG1pdHRlZCksICcnKVxuICAgICAgICAgICAgaWYgYXJndls6Ml0gPT0gWydrdWJlY3RsJywgJ2Rlc2NyaWJlJ106XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnQWxsb2NhdGVkIHJlc291cmNlczpcXG4gY3B1IDM0NjBtICg4NiUpXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZGlmZiddOlxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJy1pbWFnZTogYmFzZVxcbitpbWFnZTogY2FuZGlkYXRlXFxuJywgJycpXG4gICAgICAgICAgICBpZiBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXTpcbiAgICAgICAgICAgICAgICBpZiAnLS1kcnktcnVuPXNlcnZlcicgbm90IGluIGFyZ3Y6XG4gICAgICAgICAgICAgICAgICAgIHdyaXRlcy5hcHBlbmQoanNvbi5sb2FkcyhpbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIGlmIGFtYmlndW91czpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJwcm9jZXNzLkNvbXBsZXRlZFByb2Nlc3MoYXJndiwgMSwgJycsICd3aXRoaGVsZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1YnByb2Nlc3MuQ29tcGxldGVkUHJvY2Vzcyhhcmd2LCAwLCAnYXBwbGljYXRpb24uYXJnb3Byb2ouaW8vaW5mb3JtZWQtZGVjaXNpb25cXG4nLCAnJylcbiAgICAgICAgICAgIHJhaXNlIEFzc2VydGlvbkVycm9yKCd1bmV4cGVjdGVkIGNvbW1hbmQnKVxuXG4gICAgICAgIHNvdXJjZSA9IFBST0dSQU0ucmVwbGFjZSgnX19QQVlMT0FEX18nLCByZXByKGpzb24uZHVtcHMocGF5bG9hZCkpKS5yZXBsYWNlKFxuICAgICAgICAgICAgJ19fR1VBUkRfXycsIHJlcHIoKENBU0UgLyAnY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpKVxuICAgICAgICBvdXRwdXQgPSBpby5TdHJpbmdJTygpXG4gICAgICAgIHdpdGggcGF0Y2goJ3N1YnByb2Nlc3MucnVuJywgc2lkZV9lZmZlY3Q9ZmFrZSksIHJlZGlyZWN0X3N0ZG91dChvdXRwdXQpOlxuICAgICAgICAgICAgdHJ5OlxuICAgICAgICAgICAgICAgIGV4ZWMoY29tcGlsZShzb3VyY2UsICdmaXhlZC1uYXRpdmUtZml4dHVyZScsICdleGVjJyksIHsnX19uYW1lX18nOiAnX19maXh0dXJlX18nfSlcbiAgICAgICAgICAgIGV4Y2VwdCAoVmFsdWVFcnJvciwgU3lzdGVtRXhpdCk6XG4gICAgICAgICAgICAgICAgcGFzc1xuICAgICAgICByZWNlaXB0ID0ganNvbi5sb2FkcyhvdXRwdXQuZ2V0dmFsdWUoKSkgaWYgb3V0cHV0LmdldHZhbHVlKCkgZWxzZSB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlfVxuICAgICAgICByZXR1cm4gcmVjZWlwdCwgd3JpdGVzLCBjYWxsc1xuXG4gICAgZGVmIHRlc3Rfb25seV9leGlzdGluZ19hcHBsaWNhdGlvbl9vcGVyYXRpb25fYW5kX2RlcGxveW1lbnRfYXJlX3JlcXVlc3RlZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBvcGVyYXRpb24gPSB3cml0ZXNbMF1bLTFdWyd2YWx1ZSddXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2Uob3BlcmF0aW9uWydzeW5jJ11bJ3BydW5lJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwob3BlcmF0aW9uWydzeW5jJ11bJ3Jlc291cmNlcyddLCBbXG4gICAgICAgICAgICB7J2dyb3VwJzogJ2FwcHMnLCAna2luZCc6ICdEZXBsb3ltZW50JywgJ25hbWUnOiAnaW5mb3JtZWQtZGVjaXNpb24nLCAnbmFtZXNwYWNlJzogJ2luZm9ybWVkLWRlY2lzaW9uJ31dKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KCctLWRyeS1ydW49c2VydmVyJyBpbiBhcmd2IGFuZCBhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAncGF0Y2gnXSBmb3IgYXJndiBpbiBjYWxscykpXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzWzBdWzBdWydwYXRoJ10sICcvbWV0YWRhdGEvdWlkJylcblxuICAgIGRlZiB0ZXN0X3NvdXJjZV9vdmVycmlkZXNfYXV0b21hdGlvbl9hbmRfY3VzdG9keV9kcmlmdF9zdG9wX2JlZm9yZV93cml0ZShzZWxmKTpcbiAgICAgICAgbXV0YXRpb25zID0gW2xhbWJkYSBvOiBvWydhcHBsaWNhdGlvbiddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2FwcGxpY2F0aW9uJ11bJ3NwZWMnXS51cGRhdGUoc3luY1BvbGljeT17J2F1dG9tYXRlZCc6IHt9fSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXS51cGRhdGUoa3VzdG9taXplPXsnaW1hZ2VzJzogWydvdGhlciddfSksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snYXBwbGljYXRpb24nXVsnc3BlYyddLnVwZGF0ZShzb3VyY2VzPVt7fV0pLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ2NvbmZpZ21hcCddWydtZXRhZGF0YSddLnVwZGF0ZSh1aWQ9J3JlY3JlYXRlZCcpLFxuICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIG86IG9bJ3B2YyddWydzcGVjJ10udXBkYXRlKHZvbHVtZU5hbWU9J3JlcGxhY2VkJyksXG4gICAgICAgICAgICAgICAgICAgICBsYW1iZGEgbzogb1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wKV1cbiAgICAgICAgZm9yIG11dGF0ZSBpbiBtdXRhdGlvbnM6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChtdXRhdGU9bXV0YXRlKTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgICAgICAgICBtdXRhdGUob2JqZWN0cylcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKVxuICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuICAgIGRlZiB0ZXN0X3ByZW9wZW5fc2NoZW1hX3JlZnVzYWxfcHJldmVudHNfaW1hZ2Vfb3BlcmF0aW9uKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcmVjZWlwdCwgd3JpdGVzLCBjYWxscyA9IHNlbGYuZXhlY3V0ZV9mYWtlKG9iamVjdHMsIHBheWxvYWQsIHNjaGVtYV9yZWZ1c2VkPVRydWUpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwod3JpdGVzLCBbXSlcblxuXG4gICAgZGVmIHRlc3Rfcm9sbGJhY2tfdW5yZWFkeV9jYW5kaWRhdGVfbmV2ZXJfcmVhZHNfcG9kX29yX2RhdGFiYXNlKHNlbGYpOlxuICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKClcbiAgICAgICAgcGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzdGF0dXMnXS51cGRhdGUocmVhZHlSZXBsaWNhcz0wLCB1cGRhdGVkUmVwbGljYXM9MClcbiAgICAgICAgb2JqZWN0c1snZGVwbG95bWVudCddWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddWzBdWydpbWFnZSddID0gYWN0dWF0b3IuSU1BR0VcbiAgICAgICAgb2JqZWN0c1snYXBwbGljYXRpb24nXVsnc3BlYyddWydzb3VyY2UnXVsndGFyZ2V0UmV2aXNpb24nXSA9IFJFVklTSU9OXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBzY2hlbWFfcmVmdXNlZD1UcnVlKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsncm9sbG91dF92ZXJpZmllZCddKVxuICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih3cml0ZXMpLCAxKVxuICAgICAgICBzZWxmLmFzc2VydEZhbHNlKGFueShhcmd2WzoyXSA9PSBbJ2t1YmVjdGwnLCAnZXhlYyddIG9yIGFyZ3ZbOjNdID09IFsna3ViZWN0bCcsICdnZXQnLCAncG9kcyddIGZvciBhcmd2IGluIGNhbGxzKSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXNbMF1bLTFdWyd2YWx1ZSddWydzeW5jJ11bJ3JldmlzaW9uJ10sICc3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmJylcblxuICAgIGRlZiB0ZXN0X3JvbGxiYWNrX3N0aWxsX3JlZnVzZXNfY3VzdG9keV9vcl9ub25wYWlyX2ltYWdlX2RyaWZ0KHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnY20nLCAncHZjJywgJ2ltYWdlJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KTpcbiAgICAgICAgICAgICAgICBvYmplY3RzLCBwYXlsb2FkID0gc2VsZi5maXh0dXJlKCk7cGF5bG9hZFsncGhhc2UnXSA9ICdyb2xsYmFjaydcbiAgICAgICAgICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgICAgICAgICAgaWYgZGVmZWN0ID09ICdjbSc6b2JqZWN0c1snY29uZmlnbWFwJ11bJ21ldGFkYXRhJ11bJ3VpZCddID0gJ3JlY3JlYXRlZCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdCA9PSAncHZjJzpvYmplY3RzWydwdmMnXVsnc3BlYyddWyd2b2x1bWVOYW1lJ10gPSAncmVwbGFjZWQnXG4gICAgICAgICAgICAgICAgZWxzZTpvYmplY3RzWydkZXBsb3ltZW50J11bJ3NwZWMnXVsndGVtcGxhdGUnXVsnc3BlYyddWydjb250YWluZXJzJ11bMF1bJ2ltYWdlJ10gPSAnZm9yZWlnbi1pbWFnZSdcbiAgICAgICAgICAgICAgICByZWNlaXB0LCB3cml0ZXMsIGNhbGxzID0gc2VsZi5leGVjdXRlX2Zha2Uob2JqZWN0cywgcGF5bG9hZClcbiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKHJlY2VpcHRbJ2FsbF9jaGVja3NfcGFzcyddKTtzZWxmLmFzc2VydEVxdWFsKHdyaXRlcywgW10pXG5cbiAgICBkZWYgdGVzdF9yZWNvdmVyeV92ZXJpZmljYXRpb25faXNfc2VwYXJhdGVfcmVhZHlfb2xkX2ltYWdlX3NjaGVtYV9wcm9vZihzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpO3BheWxvYWRbJ3BoYXNlJ10gPSAncm9sbGJhY2stdmVyaWZ5J1xuICAgICAgICBvYmplY3RzWydhcHBsaWNhdGlvbiddWydzdGF0dXMnXSA9IHsnb3BlcmF0aW9uU3RhdGUnOiB7J3BoYXNlJzogJ1N1Y2NlZWRlZCcsICdvcGVyYXRpb24nOiB7J3N5bmMnOiB7XG4gICAgICAgICAgICAncmV2aXNpb24nOiAnN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZicsICdwcnVuZSc6IEZhbHNlLFxuICAgICAgICAgICAgJ3Jlc291cmNlcyc6IFt7J2dyb3VwJzonYXBwcycsJ2tpbmQnOidEZXBsb3ltZW50JywnbmFtZSc6J2luZm9ybWVkLWRlY2lzaW9uJywnbmFtZXNwYWNlJzonaW5mb3JtZWQtZGVjaXNpb24nfV19fX19XG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pO3NlbGYuYXNzZXJ0VHJ1ZShyZWNlaXB0WydyZWNvdmVyeV92ZXJpZmljYXRpb24nXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh3cml0ZXMsIFtdKVxuICAgICAgICBzZWxmLmFzc2VydFRydWUoYW55KGFyZ3ZbOjJdPT1bJ2t1YmVjdGwnLCdleGVjJ10gZm9yIGFyZ3YgaW4gY2FsbHMpKVxuICAgICAgICBvYmplY3RzWydkZXBsb3ltZW50J11bJ3N0YXR1cyddWydyZWFkeVJlcGxpY2FzJ10gPSAwXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLHBheWxvYWQpXG4gICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UocmVjZWlwdFsnYWxsX2NoZWNrc19wYXNzJ10pXG5cbiAgICBkZWYgdGVzdF9hbWJpZ3VvdXNfcGF0Y2hfaXNfbmV2ZXJfcmV0cmllZChzZWxmKTpcbiAgICAgICAgb2JqZWN0cywgcGF5bG9hZCA9IHNlbGYuZml4dHVyZSgpXG4gICAgICAgIHJlY2VpcHQsIHdyaXRlcywgY2FsbHMgPSBzZWxmLmV4ZWN1dGVfZmFrZShvYmplY3RzLCBwYXlsb2FkLCBhbWJpZ3VvdXM9VHJ1ZSlcbiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShyZWNlaXB0WydhbGxfY2hlY2tzX3Bhc3MnXSlcbiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4od3JpdGVzKSwgMSlcblxuXG5pZiBfX25hbWVfXyA9PSAnX19tYWluX18nOlxuICAgIHVuaXR0ZXN0Lm1haW4oKVxuIgogICAgfSwKICAgICJ0ZXN0X3Jlc2N1ZV9leGVjdXRpb24ucHkiOiB7CiAgICAgICJzaGEyNTYiOiAiOGVjYmIwMjYwYTg3YTdhMTJiZDVjNGM5Njc4ZmIyYTlkNDNhNGVhNzMyMjEyOTczNGJjMjFmOGVlMzgzY2Q3MCIsCiAgICAgICJjb250ZW50IjogIlwiXCJcIlN5bnRoZXRpYyByZWNvdmVyeSBndWFyZHM7IG5vIGFjdHVhbCBwcml2YXRlIGpvdXJuYWwvREIvbmF0aXZlIGNvbW1hbmQuXCJcIlwiXG5pbXBvcnQgY29weVxuaW1wb3J0IGRhdGV0aW1lXG5pbXBvcnQgaGFzaGxpYlxuaW1wb3J0IGpzb25cbmltcG9ydCBvc1xuZnJvbSBwYXRobGliIGltcG9ydCBQYXRoXG5pbXBvcnQgdGVtcGZpbGVcbmltcG9ydCB1bml0dGVzdFxuZnJvbSBhdXRob3JpdHlfam91cm5hbCBpbXBvcnQgSm91cm5hbCwgYXV0aG9yaXR5LCBvcmlnaW5hbF9hbmNob3JcbmZyb20gdGVzdF9leGVjdXRpb24gaW1wb3J0IGFjY2VwdGVkLCBOT1csIFJFVklTSU9OXG5cblJPT1Q9UGF0aChfX2ZpbGVfXykucGFyZW50XG5QTEFOPWpzb24ubG9hZHMoKFJPT1QvJ2V4ZWN1dGlvbi1wbGFuLmpzb24nKS5yZWFkX3RleHQoKSlcbkNBU0U9Uk9PVC5wYXJlbnRcbkJBQ0tVUD1qc29uLmxvYWRzKChDQVNFLydvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbicpLnJlYWRfdGV4dCgpKVxuXG5jbGFzcyBSZXNjdWVHdWFyZHModW5pdHRlc3QuVGVzdENhc2UpOlxuICAgIGRlZiBvcmlnaW5hbChzZWxmLHBhcmVudCk6XG4gICAgICAgIG9yaWdpbmFsPXsnaWRlbnRpdHknOlBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2lkZW50aXR5J10sJ3BoYXNlcyc6e319XG4gICAgICAgIGZvciBuYW1lLG1ldGFkYXRhIGluIFBMQU5bJ3JlY292ZXJ5J11bJ29yaWdpbmFsX2FuY2hvciddWydwaGFzZV9tZXRhZGF0YSddLml0ZW1zKCk6XG4gICAgICAgICAgICBvcmlnaW5hbFsncGhhc2VzJ11bbmFtZV09eyoqbWV0YWRhdGEsJ3Jlc3VsdCc6QkFDS1VQIGlmIG5hbWU9PSdkcmlsbC1iYWNrdXAnIGVsc2UgeydhbGxfY2hlY2tzX3Bhc3MnOkZhbHNlfX1cbiAgICAgICAgcD1wYXJlbnQvJ2V4ZWN1dGlvbi1qb3VybmFsLmpzb24nO3Aud3JpdGVfdGV4dChqc29uLmR1bXBzKG9yaWdpbmFsKSk7b3MuY2htb2QocCwwbzYwMClcbiAgICAgICAgYW5jaG9yPWNvcHkuZGVlcGNvcHkoUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfYW5jaG9yJ10pO2FuY2hvclsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgcmV0dXJuIHAsb3JpZ2luYWwsYW5jaG9yXG5cbiAgICBkZWYgdGVzdF9leGFjdF9vcmlnaW5hbF9mYWlsZWRfam91cm5hbF9pc19saW5rZWRfd2l0aG91dF9tdXRhdGlvbihzZWxmKTpcbiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICBwYXJlbnQ9UGF0aChkaXJlY3RvcnkpO29zLmNobW9kKHBhcmVudCwwbzcwMCk7cCxvcmlnaW5hbCxleHBlY3RlZD1zZWxmLm9yaWdpbmFsKHBhcmVudCk7YmVmb3JlPXAucmVhZF9ieXRlcygpXG4gICAgICAgICAgICBhbmNob3I9b3JpZ2luYWxfYW5jaG9yKHBhcmVudCxleHBlY3RlZCxCQUNLVVAsb3JpZ2luYWxbJ2lkZW50aXR5J10pXG4gICAgICAgICAgICBqPUpvdXJuYWwocGFyZW50LHsnZml4dHVyZSc6VHJ1ZSwncmVjb3ZlcnlfYW5jaG9yJzphbmNob3J9KTtqLnN0YXJ0KCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScse30pXG4gICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHAucmVhZF9ieXRlcygpLGJlZm9yZSk7c2VsZi5hc3NlcnRFcXVhbChqLnBhdGgubmFtZSwncmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24nKVxuICAgICAgICAgICAgai5maW5pc2goJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7J2FsbF9jaGVja3NfcGFzcyc6VHJ1ZX0pO2ouc3RhcnQoJ29mZmxpbmUtdmVyaWZ5Jyx7fSlcbiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocC5yZWFkX2J5dGVzKCksYmVmb3JlKTtqLmNsb3NlKClcblxuICAgIGRlZiB0ZXN0X29yaWdpbmFsX21pc3NpbmdfdW5jZXJ0YWluX3JlY3JlYXRlZF9hdHRlbXB0X29yX3JvbGxvdXRfcmVmdXNlKHNlbGYpOlxuICAgICAgICBmb3IgZGVmZWN0IGluICgnbWlzc2luZycsJ2NvbXBsZXRlJywnYXR0ZW1wdCcsJ3JvbGxvdXQnLCdoYXNoJyk6XG4gICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChkZWZlY3Q9ZGVmZWN0KSx0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyBkaXJlY3Rvcnk6XG4gICAgICAgICAgICAgICAgcGFyZW50PVBhdGgoZGlyZWN0b3J5KTtvcy5jaG1vZChwYXJlbnQsMG83MDApO3AsbyxlPXNlbGYub3JpZ2luYWwocGFyZW50KVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdD09J21pc3NpbmcnOm9bJ3BoYXNlcyddLnBvcCgnZHJpbGwtY29weScpXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdjb21wbGV0ZSc6b1sncGhhc2VzJ11bJ2RyaWxsLWNvcHknXVsnc3RhdGUnXT0nQ09NUExFVEUnXG4gICAgICAgICAgICAgICAgZWxpZiBkZWZlY3Q9PSdhdHRlbXB0JzpvWydwaGFzZXMnXVsnZHJpbGwtY29weSddWydhdHRlbXB0X2lkJ109J2RpZmZlcmVudCdcbiAgICAgICAgICAgICAgICBlbGlmIGRlZmVjdD09J3JvbGxvdXQnOm9bJ3BoYXNlcyddWydyZWxlYXNlJ109eydzdGF0ZSc6J1JVTk5JTkcnfVxuICAgICAgICAgICAgICAgIGlmIGRlZmVjdCE9J2hhc2gnOlxuICAgICAgICAgICAgICAgICAgICBwLndyaXRlX3RleHQoanNvbi5kdW1wcyhvKSk7ZVsnb3JpZ2luYWxfam91cm5hbF9zaGEyNTYnXT1oYXNobGliLnNoYTI1NihwLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KClcbiAgICAgICAgICAgICAgICBlbHNlOmVbJ29yaWdpbmFsX2pvdXJuYWxfc2hhMjU2J109JzAnKjY0XG4gICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcygoVmFsdWVFcnJvcixLZXlFcnJvcikpOm9yaWdpbmFsX2FuY2hvcihwYXJlbnQsZSxCQUNLVVAsUExBTlsncmVjb3ZlcnknXVsnb3JpZ2luYWxfaWRlbnRpdHknXSlcblxuICAgIGRlZiB0ZXN0X3Jlc2N1ZV9yZXBsYXlfcmVmdXNlZF9hbmRfb2xkX3BoYXNlX25ldmVyX2FkbWl0dGVkKHNlbGYpOlxuICAgICAgICB3aXRoIHRlbXBmaWxlLlRlbXBvcmFyeURpcmVjdG9yeSgpIGFzIGRpcmVjdG9yeTpcbiAgICAgICAgICAgIG9zLmNobW9kKGRpcmVjdG9yeSwwbzcwMCk7aj1Kb3VybmFsKGRpcmVjdG9yeSx7J2ZpeHR1cmUnOlRydWV9KVxuICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yKTpqLnN0YXJ0KCdkcmlsbC1jb3B5Jyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnZHJpbGwtYmFja3VwJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5zdGFydCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHt9KTtqLmZpbmlzaCgnZHJpbGwtY29weS1yZXNjdWUtcjEnLHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZX0pXG4gICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmouc3RhcnQoJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyx7fSlcbiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6ai5zdGFydCgnb2ZmbGluZS12ZXJpZnknLHt9KVxuICAgICAgICAgICAgai5jbG9zZSgpXG5cbiAgICBkZWYgdGVzdF9uZXdfYXV0aG9yaXR5X3JlcXVpcmVzX3ZlcnNpb24yX29sZF9hcHByb3ZhbF9yZWZ1c2VzKHNlbGYpOlxuICAgICAgICByZWNlaXB0LG91dGNvbWU9YWNjZXB0ZWQoKTtyZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0yO291dGNvbWVbJ2Rpc3Bvc2l0aW9ucyddWzBdWydkaXNwb3NpdGlvbiddWydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIGF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuICAgICAgICByZWNlaXB0WydtZW1vX3ZlcnNpb24nXT0xXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHktcmVzY3VlLXIxJyxOT1cpXG4gICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvcik6YXV0aG9yaXR5KHJlY2VpcHQsb3V0Y29tZSwnYScqNjQsUkVWSVNJT04sJ2RyaWxsLWNvcHknLE5PVylcbiAgICAgICAgcmVjZWlwdFsnbWVtb192ZXJzaW9uJ109MjtyZWNlaXB0WydvdXRjb21lX3F1ZXJ5J109Jy9saWZlY3ljbGUvbWVtb3MvaW5mZC0yMDI2MTAxMS1wdXJwb3NlLW92ZXJsYXktcjEvb3V0Y29tZXM/dmVyc2lvbj0xJ1xuICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IpOmF1dGhvcml0eShyZWNlaXB0LG91dGNvbWUsJ2EnKjY0LFJFVklTSU9OLCdkcmlsbC1jb3B5LXJlc2N1ZS1yMScsTk9XKVxuXG4gICAgZGVmIHRlc3RfZXhwbGljaXRfb2ZmbGluZV9pbnB1dF9tYXBwaW5nX2FuZF9hYnNlbmNlX2d1YXJkcyhzZWxmKTpcbiAgICAgICAgc291cmNlPShST09ULydhY3R1YXRvci5weScpLnJlYWRfdGV4dCgpXG4gICAgICAgIHNlbGYuYXNzZXJ0SW4oXCJwcmV2aW91cyA9IGpvdXJuYWwuZGF0YVsncGhhc2VzJ11bJ2RyaWxsLWNvcHktcmVzY3VlLXIxJ11bJ3Jlc3VsdCddXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwibm90IG9zLnBhdGgubGV4aXN0cyhDVVNUT0RZIC8gJ2RyaWxsLnNxbGl0ZScpXCIsc291cmNlKVxuICAgICAgICBzZWxmLmFzc2VydEluKFwiVk9MVU1FIG5vdCBpbiBsaXN0ZWQuc3Rkb3V0LnNwbGl0bGluZXMoKVwiLHNvdXJjZSlcbiAgICAgICAgc2VsZi5hc3NlcnROb3RJbihcIm9zLm1rZGlyKENVU1RPRFlcIixzb3VyY2UpXG4gICAgICAgIGltcG9ydCBhc3RcbiAgICAgICAgcHJvZ3JhbT1hc3QubGl0ZXJhbF9ldmFsKG5leHQobi52YWx1ZSBmb3IgbiBpbiBhc3QucGFyc2UoKFJPT1QvJ25hdGl2ZV9wcm9ncmFtLnB5JykucmVhZF90ZXh0KCkpLmJvZHkgaWYgaXNpbnN0YW5jZShuLGFzdC5Bc3NpZ24pKSlcbiAgICAgICAgY29tcGlsZShwcm9ncmFtLCduYXRpdmUtcmVzY3VlLWZpeHR1cmUnLCdleGVjJylcbiAgICAgICAgc2VsZi5hc3NlcnRJbihcInBoYXNlPT0nZHJpbGwtY29weS1yZXNjdWUtcjEnOnJlcXVpcmUocG9kWydtZXRhZGF0YSddWyd1aWQnXT09J2U4NTYxYWUwLTRiMDktNDQ1NS05MjRkLTY0YzI3YjYyNWZjNydcIixwcm9ncmFtKVxuXG5pZiBfX25hbWVfXz09J19fbWFpbl9fJzp1bml0dGVzdC5tYWluKClcbiIKICAgIH0sCiAgICAidmFsaWRhdGlvbi5qc29uIjogewogICAgICAic2hhMjU2IjogIjZmMzM3OWY2Mzk2OGU5YTAyOTRhYmE3YjViNTdlYTQ2NjJhZGRhNmIxZmExYjM3ZWZmMTFjMmY3MmE1ODkzMWYiLAogICAgICAiY29udGVudCI6ICJ7XG4gIFwic3RhdGVcIjogXCJwcmVwYXJlZC11bmFwcHJvdmVkLXZlcnNpb24yXCIsXG4gIFwiZXhlY3V0b3JfdGVzdHNcIjogMjEsXG4gIFwic25hcHNob3RfbW9ja190ZXN0c1wiOiA1LFxuICBcIm5hdGl2ZV9hY3Rpb25zXCI6IGZhbHNlLFxuICBcImRhdGFiYXNlX2FkbWluX2NvbW1hbmRzX2luX3ByZXBhcmF0aW9uXCI6IGZhbHNlLFxuICBcIm9sZF9qb3VybmFsX21vZGlmaWVkXCI6IGZhbHNlLFxuICBcIm9sZF9mYWlsZWRfcGhhc2VfcmV0cmllZFwiOiBmYWxzZSxcbiAgXCJvd25lcl9oZWFkX3VuY2hhbmdlZFwiOiBcImJjNjQ5NGNkMWIyOTA3ODNlZjNhZWYwNzYzYmYyOGQxZGVhYmY0YjBcIlxufVxuIgogICAgfQogIH0sCiAgIm5hdGl2ZV9leGVjdXRpb24iOiBmYWxzZSwKICAiY2FzZV9ldmlkZW5jZSI6IHsKICAgICJvcmlnaW5hbC1hcHByb3ZlZC1kcmlsbC1iYWNrdXAuanNvbiI6IHsKICAgICAgInNoYTI1NiI6ICIwMjVkZGRmMWU5MzkzNmYzMWU5OGI5ZmJmYTg0YWEyYmRhYWEzMzU3M2Y5ZDNiMGUzMmQ5NDdmZDI4NmIxNzBlIiwKICAgICAgImNvbnRlbnQiOiAie1wicGhhc2VcIjogXCJkcmlsbC1iYWNrdXBcIiwgXCJhbGxfY2hlY2tzX3Bhc3NcIjogdHJ1ZSwgXCJyYXdfb3V0cHV0X3dpdGhoZWxkXCI6IHRydWUsIFwibmF0aXZlX2FwcHJvdmFsX3ZlcmlmaWVkX2J5X3Jvb3RcIjoge1wiYXBwcm92YWxfaWRcIjogXCJlYzkyODA2YS05YWE2LTQ5NGYtYTc2Yi0wMzg1ZjM5YmE2MDlcIiwgXCJkaXNwb3NpdGlvbl9pZFwiOiBcImRpc3AtMDk2ODM3M2QtMjk0ZC00MmJmLTg5NzktMzZhN2M1ZGQzOGNmXCIsIFwiYWNjZXB0ZWRfYXRcIjogXCIyMDI2LTEwLTExVDAyOjM0OjIwWlwiLCBcInZlcmlmaWVkX2F0XCI6IFwiMjAyNi0xMC0xMVQwMjozODo0MS43Nzc5NDkrMDA6MDBcIn0sIFwibmF0aXZlX2F1dGhlbnRpY2F0ZWRfZ3JhbnRcIjogZmFsc2UsIFwic291cmNlX3JlYWRvbmx5X2Jhc2VsaW5lXCI6IHtcInNjaGVtYV92ZXJzaW9uXCI6IDUsIFwibGlmZWN5Y2xlXCI6IHtcInJlY29yZHNcIjogMTUsIFwiZXZlbnRzXCI6IDUwLCBcInBlbmRpbmdcIjogMH0sIFwib3V0Ym94XCI6IHtcImRlbGl2ZXJlZFwiOiAzMjB9LCBcInN1Ym1pc3Npb25zXCI6IHtcImNvbmZpcm1lZFwiOiA0MX0sIFwiaW50ZWdyaXR5XCI6IFwib2tcIiwgXCJyZWFkX29ubHlfcHJlX29wZW5cIjogdHJ1ZSwgXCJzdG9yZV9jb25zdHJ1Y3RlZFwiOiBmYWxzZX0sIFwic25hcHNob3RfcmVhZG9ubHlcIjoge1wic2NoZW1hX3ZlcnNpb25cIjogNSwgXCJsaWZlY3ljbGVcIjoge1wicmVjb3Jkc1wiOiAxNSwgXCJldmVudHNcIjogNTAsIFwicGVuZGluZ1wiOiAwfSwgXCJvdXRib3hcIjoge1wiZGVsaXZlcmVkXCI6IDMyMH0sIFwic3VibWlzc2lvbnNcIjoge1wiY29uZmlybWVkXCI6IDQxfSwgXCJpbnRlZ3JpdHlcIjogXCJva1wiLCBcInJlYWRfb25seV9wcmVfb3BlblwiOiB0cnVlLCBcInN0b3JlX2NvbnN0cnVjdGVkXCI6IGZhbHNlfSwgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsIFwic25hcHNob3RfZmlsZVwiOiBcImRyaWxsLnNxbGl0ZVwiLCBcIm5hdGl2ZV9wYXJlbnRfcHJpdmF0ZVwiOiB0cnVlLCBcIm5hdGl2ZV91aWRcIjogMTAwMDEsIFwicG9kX25hbWVcIjogXCJpbmZvcm1lZC1kZWNpc2lvbi1mNTU3NTU2ZGYtbXdwejdcIiwgXCJwb2RfdWlkXCI6IFwiZTg1NjFhZTAtNGIwOS00NDU1LTkyNGQtNjRjMjdiNjI1ZmM3XCJ9XG4iCiAgICB9LAogICAgIm9yaWdpbmFsLWFwcHJvdmVkLWRyaWxsLWNvcHktZmFpbHVyZS5qc29uIjogewogICAgICAic2hhMjU2IjogImZiNzhmYjJlOGMzZDQxNjQ5MGNmMGY1NTliMmY1YmQwMTk0MDZhNDkwZjhmNWZhNmY1OTMyNDIxZjBiMWFjNTYiLAogICAgICAiY29udGVudCI6ICJ7XCJhbGxfY2hlY2tzX3Bhc3NcIjogZmFsc2UsIFwicGhhc2VcIjogXCJkcmlsbC1jb3B5XCIsIFwiZmFpbHVyZV9jbGFzc1wiOiBcIlZhbHVlRXJyb3JcIiwgXCJmYWlsdXJlXCI6IFwiZml4ZWQgcGhhc2Ugb3V0Y29tZSB1bmNlcnRhaW47IG9yaWdpbmFsIGV2aWRlbmNlIHJldGFpbmVkOyBubyByZXRyeVwiLCBcInJhd19vdXRwdXRfd2l0aGhlbGRcIjogdHJ1ZX1cbiIKICAgIH0sCiAgICAib3JpZ2luYWwtam91cm5hbC1zYW5pdGl6ZWQtYW5jaG9yLmpzb24iOiB7CiAgICAgICJzaGEyNTYiOiAiOTg4ZmNhNjFhZDhlYjlkNDNkOTMzOTBhODM1MzIzZjk1MjE5NmJiY2U4Y2MwYmRlNTFjNDJhMTdkNDExZjQ1NCIsCiAgICAgICJjb250ZW50IjogIntcbiAgXCJvcmlnaW5hbF9qb3VybmFsX3NoYTI1NlwiOiBcImQxODdiMDJkOThkNmU5NzQyOWZlMjBiNGZiZTFkMzA5YTZjNmM0YjU1MjMyYjRhZTEzYWMzOTg3MzAzOWYxYzFcIixcbiAgXCJwaGFzZV9tZXRhZGF0YVwiOiB7XG4gICAgXCJkcmlsbC1iYWNrdXBcIjoge1xuICAgICAgXCJzdGF0ZVwiOiBcIkNPTVBMRVRFXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCJkNjMxODJhNy1lMWE1LTRlOGUtYTVmMS0yYmYzMzMzY2YxNTNcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzg6NDUuMzEwNjUzKzAwOjAwXCJcbiAgICB9LFxuICAgIFwiZHJpbGwtY29weVwiOiB7XG4gICAgICBcInN0YXRlXCI6IFwiVU5DRVJUQUlOXCIsXG4gICAgICBcImF0dGVtcHRfaWRcIjogXCIzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2NcIixcbiAgICAgIFwic3RhcnRlZF9hdFwiOiBcIjIwMjYtMTAtMTFUMDI6Mzk6NTAuMTk4NzQwKzAwOjAwXCJcbiAgICB9XG4gIH0sXG4gIFwiZnJvemVuX2JhY2t1cF9yZWNlaXB0X3NoYTI1NlwiOiBcIjAyNWRkZGYxZTkzOTM2ZjMxZTk4YjlmYmZhODRhYTJiZGFhYTMzNTczZjlkM2IwZTMyZDk0N2ZkMjg2YjE3MGVcIixcbiAgXCJzbmFwc2hvdF9zaGEyNTZcIjogXCI4NzU2Y2Y4MjVkZjllN2I1Yjc0YmI0YTAxMDZhNTAyN2Y1Y2ZmMmM1OWZmNDVkN2I0OGVlZDg1MjJhN2QzM2YzXCIsXG4gIFwic25hcHNob3RfYnl0ZXNcIjogMTk1Mzc5MjAsXG4gIFwib2ZmX2NsdXN0ZXJfZmlsZV9leGlzdHNcIjogZmFsc2UsXG4gIFwib2xkX3VuY2VydGFpbl9yZXRyeV9hdXRob3JpemVkXCI6IGZhbHNlXG59XG4iCiAgICB9CiAgfQp9Cg==" + }, + { + "digest": "sha256:9093c64f7f0e39b249da9fefdf5aaf4e4258bc31e7a27fd888479ce329a20509", + "media_type": "text/plain", + "content_base64": "IiIiUHJlLW9wZW4gc2NoZW1hL2ludGVncml0eS9jb3VudCBwcm9vZjsgc3RkbGliIG9ubHksIG5ldmVyIGNvbnN0cnVjdHMgU3RvcmUuIiIiCmltcG9ydCBhcmdwYXJzZQpmcm9tIGNvbnRleHRsaWIgaW1wb3J0IGNsb3NpbmcKaW1wb3J0IGhhc2hsaWIKaW1wb3J0IG9zCmltcG9ydCByZQppbXBvcnQgc3RhdAppbXBvcnQganNvbgpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaW1wb3J0IHNxbGl0ZTMKCgpkZWYgaW5zcGVjdF9yZWFkb25seShwYXRoLCAqLCBfY2xvc2VkX3NuYXBzaG90PUZhbHNlKToKICAgIHBhdGggPSBQYXRoKHBhdGgpCiAgICBpZiBub3QgcGF0aC5pc19maWxlKCkgb3IgcGF0aC5pc19zeW1saW5rKCk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZXhpc3Rpbmcgbm9uc3ltbGluayBwcml2YXRlIGRhdGFiYXNlIHJlcXVpcmVkJykKICAgIHVyaSA9IHBhdGgucmVzb2x2ZSgpLmFzX3VyaSgpICsgJz9tb2RlPXJvJyArICgnJmltbXV0YWJsZT0xJyBpZiBfY2xvc2VkX3NuYXBzaG90IGVsc2UgJycpCiAgICAjIHNxbGl0ZTMuQ29ubmVjdGlvbiBjb250ZXh0IG1hbmFnZW1lbnQgZW5kcyB0cmFuc2FjdGlvbnM7IGl0IGRvZXMgbm90IGNsb3NlLgogICAgd2l0aCBjbG9zaW5nKHNxbGl0ZTMuY29ubmVjdCh1cmksIHVyaT1UcnVlLCB0aW1lb3V0PTUpKSBhcyBkYjoKICAgICAgICBkYi5leGVjdXRlKCdQUkFHTUEgcXVlcnlfb25seT1PTicpCiAgICAgICAgZGIuZXhlY3V0ZSgnQkVHSU4nKQogICAgICAgIHZlcnNpb24gPSBkYi5leGVjdXRlKCdQUkFHTUEgdXNlcl92ZXJzaW9uJykuZmV0Y2hvbmUoKVswXQogICAgICAgIGlmIHZlcnNpb24gIT0gNToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncHJlLW9wZW4gZGF0YWJhc2UgaXMgbm90IHNjaGVtYTU7IHJlZnVzZSBtaWdyYXRpb24nKQogICAgICAgIGlmIGRiLmV4ZWN1dGUoJ1BSQUdNQSBpbnRlZ3JpdHlfY2hlY2snKS5mZXRjaGFsbCgpICE9IFsoJ29rJywpXToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigncmVhZC1vbmx5IGludGVncml0eSBjaGVjayByZWZ1c2VkJykKICAgICAgICBsaWZlY3ljbGUgPSB7bmFtZTogZGIuZXhlY3V0ZSgnU0VMRUNUIENPVU5UKCopIEZST00gJyArIHRhYmxlKS5mZXRjaG9uZSgpWzBdCiAgICAgICAgICAgICAgICAgICAgIGZvciBuYW1lLCB0YWJsZSBpbiAoKCdyZWNvcmRzJywgJ2xpZmVjeWNsZV9yZWNvcmRzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCdldmVudHMnLCAnbGlmZWN5Y2xlX2V2ZW50cycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgncGVuZGluZycsICdsaWZlY3ljbGVfcGVuZGluZycpKX0KICAgICAgICByZXN1bHQgPSB7J3NjaGVtYV92ZXJzaW9uJzogdmVyc2lvbiwgJ2xpZmVjeWNsZSc6IGxpZmVjeWNsZSwKICAgICAgICAgICAgICAgICAgJ291dGJveCc6IGRpY3QoZGIuZXhlY3V0ZSgnU0VMRUNUIHN0YXRlLENPVU5UKCopIEZST00gb3V0Ym94IEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnc3VibWlzc2lvbnMnOiBkaWN0KGRiLmV4ZWN1dGUoJ1NFTEVDVCBzdGF0ZSxDT1VOVCgqKSBGUk9NIHN1Ym1pc3Npb25zIEdST1VQIEJZIHN0YXRlJykpLAogICAgICAgICAgICAgICAgICAnaW50ZWdyaXR5JzogJ29rJywgJ3JlYWRfb25seV9wcmVfb3Blbic6IFRydWUsICdzdG9yZV9jb25zdHJ1Y3RlZCc6IEZhbHNlfQogICAgICAgIGRiLnJvbGxiYWNrKCkKICAgIHJldHVybiByZXN1bHQKCgpkZWYgaW5zcGVjdF9jbG9zZWRfc25hcHNob3QocGF0aCwgZXhwZWN0ZWRfc2hhMjU2KToKICAgICIiIk9ubHkgYSBwcml2YXRlbHkgcmV0YWluZWQsIGZyb3plbiBtYWluLWZpbGUgc25hcHNob3Qgd2l0aCBubyBXQUwgZnJhbWVzLgoKICAgIENhbGxlciBtdXN0IGVzdGFibGlzaCBleGNsdXNpdmUgc25hcHNob3QgY3JlYXRpb24vYWRtaW4gZXhpdC9ubyB3cml0ZXIsIGFuZAogICAgc3VwcGx5IHRoZSByZWNvcmRlZCBmcm96ZW4gbWFpbiBkaWdlc3QuIE5ldmVyIHVzZSBmb3IgdGhlIGxpdmUgZGF0YWJhc2UuCiAgICBJbW11dGFibGUgU1FMaXRlIHJlYWRzIGlnbm9yZSBzdGFsZSBTSE0gYW5kIG5ldmVyIGNyZWF0ZS9jaGFuZ2Ugc2lkZWNhcnMuCiAgICBFeGlzdGluZyBzaWRlY2FycyByZW1haW4gY3VzdG9keSBldmlkZW5jZTsgbm90aGluZyBpcyBkZWxldGVkL2NoZWNrcG9pbnRlZC4KICAgICIiIgogICAgcGF0aCA9IFBhdGgocGF0aCkKICAgIGlmIHJlLmZ1bGxtYXRjaChyJ1swLTlhLWZdezY0fScsIGV4cGVjdGVkX3NoYTI1NikgaXMgTm9uZToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdleGFjdCBmcm96ZW4gc25hcHNob3QgZGlnZXN0IHJlcXVpcmVkJykKICAgIGRlZiBtZXRhZGF0YSh0YXJnZXQpOgogICAgICAgIGluZm8gPSB0YXJnZXQubHN0YXQoKQogICAgICAgIGlmIG5vdCBzdGF0LlNfSVNSRUcoaW5mby5zdF9tb2RlKSBvciBzdGF0LlNfSU1PREUoaW5mby5zdF9tb2RlKSAhPSAwbzYwMCBvciBpbmZvLnN0X25saW5rICE9IDE6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3ByaXZhdGUgc2luZ2xlLWxpbmsgc25hcHNob3QgY3VzdG9keSByZXF1aXJlZCcpCiAgICAgICAgcmV0dXJuIGluZm8KICAgIG1haW4gPSBtZXRhZGF0YShwYXRoKQogICAgaWYgbm90IDAgPCBtYWluLnN0X3NpemUgPD0gNTEyICogMTAyNCoqMjoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdib3VuZGVkIGZyb3plbiBzbmFwc2hvdCByZXF1aXJlZCcpCiAgICBkZWYgc2lkZWNhcnMoKToKICAgICAgICBpZGVudGl0aWVzID0ge30KICAgICAgICBmb3Igc3VmZml4IGluICgnLXdhbCcsICctc2htJyk6CiAgICAgICAgICAgIHRhcmdldCA9IFBhdGgoc3RyKHBhdGgpICsgc3VmZml4KQogICAgICAgICAgICBpZiBvcy5wYXRoLmxleGlzdHModGFyZ2V0KToKICAgICAgICAgICAgICAgIGluZm8gPSBtZXRhZGF0YSh0YXJnZXQpCiAgICAgICAgICAgICAgICBpZiBpbmZvLnN0X3VpZCAhPSBtYWluLnN0X3VpZCBvciBpbmZvLnN0X2dpZCAhPSBtYWluLnN0X2dpZDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBzaWRlY2FyIGN1c3RvZHkgY2hhbmdlZCcpCiAgICAgICAgICAgICAgICBpZiBzdWZmaXggPT0gJy13YWwnIGFuZCBpbmZvLnN0X3NpemUgIT0gMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzbmFwc2hvdCBoYXMgV0FMIGZyYW1lczsgaW1tdXRhYmxlIHJlYWQgcmVmdXNlZCcpCiAgICAgICAgICAgICAgICBpZGVudGl0aWVzW3N1ZmZpeF0gPSAoaW5mby5zdF9kZXYsIGluZm8uc3RfaW5vLCBpbmZvLnN0X3NpemUsIGluZm8uc3RfbXRpbWVfbnMpCiAgICAgICAgcmV0dXJuIGlkZW50aXRpZXMKICAgIGJlZm9yZV9zaWRlY2FycyA9IHNpZGVjYXJzKCkKICAgIGRlZiBkaWdlc3QoKToKICAgICAgICB2YWx1ZSA9IGhhc2hsaWIuc2hhMjU2KCkKICAgICAgICB3aXRoIHBhdGgub3BlbigncmInKSBhcyBzdHJlYW06CiAgICAgICAgICAgIGZvciBibG9jayBpbiBpdGVyKGxhbWJkYTogc3RyZWFtLnJlYWQoMTAyNCoqMiksIGInJyk6CiAgICAgICAgICAgICAgICB2YWx1ZS51cGRhdGUoYmxvY2spCiAgICAgICAgcmV0dXJuIHZhbHVlLmhleGRpZ2VzdCgpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTY6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIG1haW4tZmlsZSBkaWdlc3QgY2hhbmdlZCBiZWZvcmUgaW5zcGVjdGlvbicpCiAgICBwcm9vZiA9IGluc3BlY3RfcmVhZG9ubHkocGF0aCwgX2Nsb3NlZF9zbmFwc2hvdD1UcnVlKQogICAgYWZ0ZXIgPSBtZXRhZGF0YShwYXRoKQogICAgaWYgKGFmdGVyLnN0X2RldiwgYWZ0ZXIuc3RfaW5vLCBhZnRlci5zdF91aWQsIGFmdGVyLnN0X2dpZCwgYWZ0ZXIuc3Rfc2l6ZSkgIT0gKG1haW4uc3RfZGV2LCBtYWluLnN0X2lubywgbWFpbi5zdF91aWQsIG1haW4uc3RfZ2lkLCBtYWluLnN0X3NpemUpOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ2Zyb3plbiBtYWluLWZpbGUgaWRlbnRpdHkgY2hhbmdlZCcpCiAgICBpZiBkaWdlc3QoKSAhPSBleHBlY3RlZF9zaGEyNTYgb3Igc2lkZWNhcnMoKSAhPSBiZWZvcmVfc2lkZWNhcnM6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignZnJvemVuIHNuYXBzaG90IGNoYW5nZWQgZHVyaW5nIGluc3BlY3Rpb24nKQogICAgcmV0dXJuIHByb29mCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHBhcnNlciA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKGRlc2NyaXB0aW9uPV9fZG9jX18pCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWRiJywgdHlwZT1QYXRoLCByZXF1aXJlZD1UcnVlKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKICAgIHRyeToKICAgICAgICBwcmludChqc29uLmR1bXBzKGluc3BlY3RfcmVhZG9ubHkoYXJncy5kYiksIHNvcnRfa2V5cz1UcnVlKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmFpc2UgU3lzdGVtRXhpdCgncmVhZC1vbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50IGdhdGUgcmVmdXNlZDsgbm8gU3RvcmUvYWRtaW4gb3BlbicpIGZyb20gTm9uZQo=" + }, + { + "digest": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369", + "media_type": "application/json", + "content_base64": "ewogICJjb25maWdtYXAiOiB7CiAgICAiYXBpVmVyc2lvbiI6ICJ2MSIsCiAgICAiaW1tdXRhYmxlIjogdHJ1ZSwKICAgICJraW5kIjogIkNvbmZpZ01hcCIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgICAiYXJnb2NkLmFyZ29wcm9qLmlvL3RyYWNraW5nLWlkIjogImluZm9ybWVkLWRlY2lzaW9uOi9Db25maWdNYXA6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiLAogICAgICAgICJpbmZvcm1lZC1kZWNpc2lvbi5jb3Vsb21iLnNvY2lhbC9hZG1pc3Npb24iOiAiYXBwcm92ZWQ7IElORkQtV1AtMDAwNyBjdXRvdmVyIgogICAgICB9LAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MSIsCiAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAidWlkIjogIjkwMTEzZDJkLTU0ZDktNGU4Mi1iMWQzLTkwYjQ5ZWJlZDJiNSIKICAgIH0sCiAgICAiY2Fub25pY2FsX2RhdGFfc2hhMjU2IjogIjhlYzQ2MmQxMjM0NzU0OGY1MDZlZWViZjFlM2M3Y2M0NzY0ODAxOWM4YTc4MzgwNGQwOWJjYzc5YjBmMjJhZjYiCiAgfSwKICAicHZjIjogewogICAgImFwaVZlcnNpb24iOiAidjEiLAogICAgImtpbmQiOiAiUGVyc2lzdGVudFZvbHVtZUNsYWltIiwKICAgICJtZXRhZGF0YSI6IHsKICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICJhcmdvY2QuYXJnb3Byb2ouaW8vdHJhY2tpbmctaWQiOiAiaW5mb3JtZWQtZGVjaXNpb246L1BlcnNpc3RlbnRWb2x1bWVDbGFpbTppbmZvcm1lZC1kZWNpc2lvbi9pbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIsCiAgICAgICAgInB2Lmt1YmVybmV0ZXMuaW8vYmluZC1jb21wbGV0ZWQiOiAieWVzIiwKICAgICAgICAicHYua3ViZXJuZXRlcy5pby9ib3VuZC1ieS1jb250cm9sbGVyIjogInllcyIsCiAgICAgICAgInZvbHVtZS5iZXRhLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiLAogICAgICAgICJ2b2x1bWUua3ViZXJuZXRlcy5pby9zZWxlY3RlZC1ub2RlIjogIjIzOS42Mi4yMDUuOTIuaG9zdC5zZWN1cmVzZXJ2ZXIubmV0IiwKICAgICAgICAidm9sdW1lLmt1YmVybmV0ZXMuaW8vc3RvcmFnZS1wcm92aXNpb25lciI6ICJyYW5jaGVyLmlvL2xvY2FsLXBhdGgiCiAgICAgIH0sCiAgICAgICJmaW5hbGl6ZXJzIjogWwogICAgICAgICJrdWJlcm5ldGVzLmlvL3B2Yy1wcm90ZWN0aW9uIgogICAgICBdLAogICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbi1kYXRhIiwKICAgICAgIm5hbWVzcGFjZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICJ1aWQiOiAiZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfSwKICAgICJzcGVjIjogewogICAgICAiYWNjZXNzTW9kZXMiOiBbCiAgICAgICAgIlJlYWRXcml0ZU9uY2UiCiAgICAgIF0sCiAgICAgICJyZXNvdXJjZXMiOiB7CiAgICAgICAgInJlcXVlc3RzIjogewogICAgICAgICAgInN0b3JhZ2UiOiAiMUdpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInN0b3JhZ2VDbGFzc05hbWUiOiAibG9jYWwtcGF0aCIsCiAgICAgICJ2b2x1bWVNb2RlIjogIkZpbGVzeXN0ZW0iLAogICAgICAidm9sdW1lTmFtZSI6ICJwdmMtZDgwYjI1YjEtMTQxYS00NDFiLWIyMDUtOThmYTJmZDk4YjdjIgogICAgfQogIH0sCiAgInB2Y19waGFzZSI6ICJCb3VuZCIKfQo=" + }, + { + "digest": "sha256:54aa31c7709c5178d1aa0dda5ef22340fc2c1ede7635c8273c53e7954885f8e5", + "media_type": "text/markdown", + "content_base64": "IyBWZXJzaW9uMiBwcm90ZWN0ZWQgZXhpc3Rpbmctc25hcHNob3QgcmVzY3VlIGFuZCBjb25kaXRpb25hbCBjb250aW51YXRpb24KClNhbWUgcHJvcG9zYWwgSU5GRC1XUC0wMDA5LVQwNC9wdXJwb3NlLW92ZXJsYXktdjEsIHRyaWFsIGluZmQtcHVycG9zZS0yMDI2MTAxMS1yMS4gT3JpZ2luYWwgdmVyc2lvbjEgZm91bmRlciBhY2NlcHRhbmNlIGFwcHJvdmVkIHNvdXJjZSBiYzY0OTRjZDFiMjkwNzgzZWYzYWVmMDc2M2JmMjhkMWRlYWJmNGIwLiBEcmlsbC1iYWNrdXAgY29tcGxldGVkOyBkcmlsbC1jb3B5IGZhaWxlZCBWYWx1ZUVycm9yIGJlZm9yZSBhbnkgbG9jYWxmaWxlLiBObyBpbWFnZSByb2xsb3V0IG9jY3VycmVkLiBUaGlzIGV4YWN0IGNoYW5nZWQgc291cmNlL3BsYW4vaGVscGVyIHJlcXVpcmVzIE5FVyBmb3VuZGVyIGFjY2VwdGFuY2Ugb2YgbWVtbyB2ZXJzaW9uMiBiZWZvcmUgcmVzY3VlL2NvbnRpbnVhdGlvbjsgcHJpb3IgYXBwcm92YWwgYW5kIHRlY2huaWNhbCByZXZpZXcgZG8gbm90IGFwcHJvdmUgaXQuCgojIyBGYWlsdXJlIGFuZCBuYXJyb3dseSBzZWxlY3RlZCByZXNjdWUKCk9yaWdpbmFsIHNuYXBzaG90IG1haW4xOTUzNzkyMGJ5dGVzIFNIQTg3NTZjZjgyNWRmOWU3YjViNzRiYjRhMDEwNmE1MDI3ZjVjZmYyYzU5ZmY0NWQ3YjQ4ZWVkODUyMmE3ZDMzZjMgaXMgdW5jaGFuZ2VkLiBSb290J3MgbWV0YWRhdGEtb25seSB2ZXJpZmljYXRpb24gc2hvd3MgV0FMMGJ5dGVzLCBTSE0zMjc2OGJ5dGVzLCBwcml2YXRlVUlEMTAwMDEvbW9kZTA2MDAvbmxpbmsxLCBhbmQgbm8gbG9jYWwgc25hcHNob3QuIFRoZSBvbGQgU1FMaXRlIGNvbm5lY3Rpb24gY29udGV4dCBtYW5hZ2VyIGRpZCBub3QgZXhwbGljaXRseSBjbG9zZTsgaXRzIFdBTCByZWFkZXIgY2FuIGNyZWF0ZSBTSE0gaW5kZXhpbmcsIGFuZCB0aGUgbmV4dCBjb3B5IHJlamVjdGVkIHRoYXQgbm9uemVybyBpbmRleC4gUGxhdGZvcm0gaW5kZXBlbmRlbnRseSByZXByb2R1Y2VkIHRoaXMgb24gc3ludGhldGljIGRhdGEuIE5vIG5hdGl2ZSBEQiB3YXMgb3BlbmVkIHRvIGRpYWdub3NlIHRoZSBzaWRlY2FyIG1ldGFkYXRhLCBhbmQgbm8gbmF0aXZlIHNpZGVjYXIgaXMgZGVsZXRlZC9jaGVja3BvaW50ZWQuCgpSZXVzZSB0aGlzIGV4YWN0IGluZGVwZW5kZW50bHkgaGFzaC1ib3VuZCBmcm96ZW4gbWFpbiBzbmFwc2hvdCByYXRoZXIgdGhhbiBtYWtlIGFub3RoZXIgZHJpbGwgYmFja3VwLiBUaGUgYmFja3VwYWRtaW4gZXhpdGVkIGFmdGVyIGNyZWF0aW5nIHRoZSB1bmlxdWVseSBvd25lZCBwcml2YXRlIHNuYXBzaG90LiBPcmlnaW5hbCBzdWJzZXF1ZW50IHNuYXBzaG90IGFjY2VzcyB3YXMgcmVhZG9ubHk7IGFjdHVhbCBzZXJ2aWNlIERCIGlzIHRoZSBkaXN0aW5jdCAvZGF0YS9wcml2YXRlL3Jldmlldy5zcWxpdGUuIE9yaWdpbmFsIGpvdXJuYWwgaGFzIG9ubHkgQ09NUExFVEUgZHJpbGwtYmFja3VwIGQ2MzE4MmE3LWUxYTUtNGU4ZS1hNWYxLTJiZjMzMzNjZjE1MyBhbmQgVU5DRVJUQUlOIGRyaWxsLWNvcHkzMjllZjE5MC0xNjkyLTQyNDYtYjk1My1lNmE1OTY2NGFiY2MuIEl0cyBleGFjdCBTSEEgZDE4N2IwMmQ5OGQ2ZTk3NDI5ZmUyMGI0ZmJlMWQzMDlhNmM2YzRiNTUyMzJiNGFlMTNhYzM5ODczMDM5ZjFjMSwgb3JpZ2luYWwgc291cmNlL21lbW8vcGxhbiBpZGVudGl0eSBhbmQgb3V0Y29tZXMgYXJlIHZlcmlmaWVkIGJlZm9yZS9hZnRlciBldmVyeSBuZXcgcGhhc2UuIE5vIG90aGVyIG9yaWdpbmFsIGFjdGlvbiBvciByb2xsb3V0IGlzIGFsbG93ZWQuCgpUaGUgZXhwbGljaXRseSBuYW1lZCBkcmlsbC1jb3B5LXJlc2N1ZS1yMSBjcmVhdGVzIGEgc2VwYXJhdGUgcmVzY3VlLWV4ZWN1dGlvbi1qb3VybmFsLXIxLmpzb24vbG9jayBpbiBleGlzdGluZyBwcm90ZWN0ZWQgaWdub3JlZCBjdXN0b2R5OyBpdCBoYXNoLWxpbmtzIG9yaWdpbmFsIGF0dGVtcHRzIGFuZCBiYWNrdXByZXN1bHQgYW5kIG5ldmVyIHJld3JpdGVzL3N5bnRoZXNpemVzIHRoZSBvbGQgZmFpbGVkIHBoYXNlLiBBbnkgYXR0ZW1wdGVkIHJlc2N1ZSByZXN1bHQsIGNyYXNoIG9yIGFtYmlndW91cyBvdXRwdXQgaXMgZHVyYWJsZSBhbmQgc2FtZS1waGFzZSByZXRyeSBpcyByZWZ1c2VkLiBCZWZvcmUgcmVzY3VlOiBsb2NhbCBkcmlsbC5zcWxpdGUvY3V0b3Zlci5zcWxpdGUgYW5kIGV4aXN0aW5nIHJlc3RvcmUgdm9sdW1lIG11c3QgYmUgYWJzZW50OyBuYXRpdmUgb3JpZ2luYWxQb2RVSUQvY3VycmVudG9sZGltYWdlN2Y1L0FyZ283ZGIvc2VhbGVkRGVwbG95bWVudC9DTS9QVkMgbWF0Y2guIFRoZSBmaXhlZCBpbW11dGFibGUgc25hcHNob3QgcmVhZGVyIGNoZWNrcyByZWNvcmRlZCBkaWdlc3QvcHJpdmF0ZSBpZGVudGl0eS9ubyBXQUxmcmFtZXMgYmVmb3JlIGFuZCBhZnRlciBzY2hlbWE1L2ludGVncml0eS9jb3VudCB2YWxpZGF0aW9uLCByZXRhaW5pbmcgdW5jaGFuZ2VkIFNITS4gTm9uemVybyBXQUwgb3IgYW55IGlkZW50aXR5L2hhc2ggZHJpZnQgc3RvcHMgcmVzY3VlLiBTbmFwc2hvdCBiaW5hcnlzdGRvdXQgZmxvd3Mgb25seSB0byBhIG5ldzA2MDBwcml2YXRlIGZpbGUsIHdpdGggYm91bmRlZCBzaXplL2hhc2ggYW5kIHJlcGVhdCBzb3VyY2UgcHJvb2YuIEl0IG5ldmVyIHJlYWNoZXMgY2hhdC9sb2cvR2l0L1N0YXRlSHViLgoKIyMgTGl2ZS1XQUwgYW5kIGRhdGEgY29tcGF0aWJpbGl0eSBib3VuZGFyaWVzCgpMaXZlIHNvdXJjZSBhbmQgd3JpdGFibGUgb2ZmbGluZSBwcmUvcG9zdC1hZG1pbiByZWFkcyBNVVNUIHN0YXkgbW9kZT1yby9xdWVyeV9vbmx5IGFuZCBleHBsaWNpdGx5IGNsb3NlIFNRTGl0ZSBjb25uZWN0aW9ucy4gaW1tdXRhYmxlPTEgaWdub3JlcyBXQUwgYW5kIHdvdWxkIGxvc2UgY29tbWl0dGVkIGxpdmUgcm93czsgaXQgaXMgcmVzdHJpY3RlZCB0byB0aGUgcHJvdmVuIGZyb3plbiBjbG9zZWQtbWFpbiBzbmFwc2hvdCwgbmV2ZXIgdGhlIGxpdmVEQiBvciB3cml0YWJsZWNsb25lLiBCZWZvcmUgQU5ZIG5hdGl2ZSBzb3VyY2Ugb3IgcmVzdG9yZWRjb3B5IFN0b3JlL2FkbWluIG9wZW4sIHJlcXVpcmUgc3RkbGliIHJlYWRvbmx5IHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50czsgcmVmdXNlIG9sZHNjaGVtYXMgYmVmb3JlIGF1dG9tYXRpYyBtaWdyYXRpb24uIEZyb3plbiBzbmFwc2hvdC9jbG9uZSBjb3VudCBlcXVhbGl0eSBpcyBleGFjdDsgY3VycmVudGxpdmUgY291bnRlciBjaGFuZ2VzIG1heSByZWZsZWN0IGNvbmN1cnJlbnQgbGVnaXRpbWF0ZSBjb21taXRzIGFuZCBhcmUgcmV0YWluZWQuCgpPbmx5IGFmdGVyIENPTVBMRVRFIG5hbWVkIHJlc2N1ZSBkb2VzIG9mZmxpbmUtdmVyaWZ5IGNvbnN1bWUgaXRzIHJlc3VsdCB2aWEgZXhwbGljaXQgbWFwcGluZywgbm90IHRoZSBvbGQgVU5DRVJUQUlOIGRyaWxsLWNvcHkuIEV4aXN0aW5nIGlzb2xhdGVkIGRpc3Bvc2FibGV2b2x1bWUgaW5mZC1wdXJwb3NlLXIxLXJlc3RvcmUtMjAyNjEwMTEgbXVzdCBiZSBhYnNlbnQvbmV3IG5vbmNlLWJvdW5kLiBPbmUgZXhhY3Q3NjNjIFVJRDAvQ0FQX0NIT1dOLW9ubHkgaW5pdGlhbGl6ZXIgcmVjZWl2ZXMgc25hcHNob3RzdGRpbiBpbnRvIHRoYXQgTkVXdm9sdW1lLCBuZXR3b3Jrbm9uZS9yZWFkb25seXJvb3Qvbm8tbmV3cHJpdmlsZWdlcy9DUFUxLzEyOE1pLCBubyBob3N0L25hdGl2ZVBWQy9ydW50aW1lY29uZmlnL3Rva2VuIG1vdW50cy4gSXQgc2V0cyBmb2xkZXIwNzAwL2ZpbGUwNjAwVUlEMTAwMDEsIGZvbGxvd2VkIGJ5IFVJRDEwMDAxIHByZS1vcGVuIHJlYWRvbmx5LCAtLWVudHJ5cG9pbnQgaW5mb3JtZWQtZGVjaXNpb24tYWRtaW4gaW5zcGVjdCAtLWRiIC9yZXN0b3JlL3Jldmlldy5zcWxpdGUgYW5kIHBvc3QtYWRtaW4gcmVhZG9ubHkgZnVsbHByb29mOyBvcmlnaW5hbCBwcm90ZWN0ZWQgU0hBIG11c3QgcmVtYWluIHVuY2hhbmdlZC4gTm8gc2VydmljZWVudHJ5cG9pbnQgc3RhcnRzLiBDbGVhbnVwIG9ubHkgdGhpcyBkaXNwb3NhYmxlIHZvbHVtZSwgcmV0YWluaW5nIG9yaWdpbmFsIG5hdGl2ZS9vZmZjbHVzdGVyIHNuYXBzaG90cy9zaWRlY2Fycy4KCiMjIENvbmRpdGlvbmFsIHJlbWFpbmluZyBwaGFzZXMgYW5kIHJlbGVhc2UvcmVjb3ZlcnkKCk5ld2pvdXJuYWwgZml4ZWQgb3JkZXI6IGRyaWxsLWNvcHktcmVzY3VlLXIxIOKGkiBvZmZsaW5lLXZlcmlmeSDihpIgY2xlYW51cC1vZmZsaW5lIOKGkiBjdXRvdmVyLWJhY2t1cCDihpIgY3V0b3Zlci1jb3B5IOKGkiByZWxlYXNlIOKGkiB2ZXJpZnkuIGN1dG92ZXItYmFja3VwIHVzZXMgZGlzdGluY3QgbmV3Y3V0b3Zlci5zcWxpdGUgaW4gb3JpZ2luYWxwcml2YXRlY2FzZSBkaXJlY3RvcnksIGFmdGVyIHJlYWRvbmx5IGxpdmUgc2NoZW1hNS9jYXBhY2l0eSBnYXRlcywgU1FMaXRlYmFja3VwQVBJL2FkbWluIGNvbXBsZXRpb24sIGNsb3NlZC1tYWluIGltbXV0YWJsZSBwcm9vZjsgZG8gbm90IG92ZXJ3cml0ZSBvcmlnaW5hbHMgb3IgcmV0cnlmYWlsZWRwYXRocy4gVmVyc2lvbjIgYWNjZXB0YW5jZSBjb25kaXRpb25hbGx5IGFwcHJvdmVzIHRoZXNlIGV4YWN0IHVuY2hhbmdlZCByZW1haW5pbmcgb3BlcmF0aW9ucyBvbmx5IGFmdGVyIHJlc2N1ZStkcmlsbGdhdGVzLiBBbGwgZm91ciBjb21taXR0ZWQgS3VzdG9taXplIEdpdCBibG9icy9jdXJyZW50SEVBRCwgZXhhY3QgaGVscGVyL2Nhc2UgaGFzaGVzLCBDTS9QVkMvRGVwbG95bWVudCBzZWFscyBhbmQgbWFudWFsQXBwbGljYXRpb24obm8gYXV0b21hdGVke30gb3Igc291cmNlb3ZlcnJpZGUpIG11c3QgbWF0Y2guCgpSZWxlYXNlIHJldGFpbnMgZXhpc3RpbmcgcmVwbGljYTEvUmVjcmVhdGUvY29uZmlnNmMvc2NoZW1hNS9QVkMvY3JlZGVudGlhbHMvcG9saWNpZXM6IHNvdXJjZXBpbiBBcHBsaWNhdGlvbi5vcGVyYXRpb24gc2VydmVyZHJ5cnVuL1VJRCtyZXNvdXJjZVZlcnNpb24rc291cmNlIENBUywgRGVwbG95bWVudC1vbmx5IGltYWdlNzYzYywgcHJ1bmU9ZmFsc2UuIE5vIHdob2xlLWFwcCBzeW5jL2Fkb3B0aW9uLiBWZXJpZnkgcmVxdWlyZXMgc3VjY2VlZGVkIGV4YWN0c2NvcGUvY29udHJvbGxlcmdlbmVyYXRpb24vUmVhZHkxLCBpbnN0YWxsZWRwb2xpY3loYXNoL21vZGVVSUQvMTBzeW50aGV0aWNwdXJwb3NldmFyaWFudHMrYm91bmRlZGhlYWx0aCwgc2FtZSBjdXJyZW50bGl2ZURCIHNjaGVtYTUvaW50ZWdyaXR5L2NvdW50cy4gVGhvc2UgaW5zdGFsbGVkY2hlY2tzIHJlcG9ydCBuYXRpdmVfcHJvdmlkZXI9ZmFsc2U7IGFjdHVhbHByb3ZpZGVyL1BEUGF1dGhvcml0eSBldmlkZW5jZSByZW1haW5zIGEgc2VwYXJhdGUgVDA0Z2F0ZS4KClJvbGxiYWNrIGFmdGVyIHJlY29yZGVkIG5ld3JlbGVhc2UgYXR0ZW1wdCBwaW5zIHByaW9yN2RiLzdmNSBhbmQgcmV0YWlucyBsYXRlc3RzY2hlbWE1REIsIHdpdGhvdXQgcmVxdWlyaW5nIFJlYWR5IGZhaWxpbmdjYW5kaWRhdGUgb3IgY2FuZGlkYXRlREJleGVjLiBTZXBhcmF0ZSByb2xsYmFjay12ZXJpZnkgcHJvdmVzIG9sZGltYWdlUmVhZHkxL3Njb3BlZG9wZXJhdGlvbi9yZWFkb25seXNjaGVtYTUgY3VycmVudERCIGludGVncml0eS4gTmV2ZXIgcmVzdG9yZSBhbiBvbGRlciBzbmFwc2hvdCBvdmVyIHBvc3RjdXRvdmVycmVjb3Jkcy4gQW55IGRhdGEgcmVjb3ZlcnkgYmV5b25kIHRoaXMgc2FtZS1zY2hlbWEgaW1hZ2Ugcm9sbGJhY2sgbmVlZHMgYW5vdGhlciBkZWNpc2lvbi4KCkFsbCBwaGFzZXMgaW5jbHVkaW5nIHJlc2N1ZSwgdmVyaWZpY2F0aW9uIGFuZCByZWNvdmVyeSBtdXN0IGJlZ2luIGJlZm9yZTIwMjYtMTAtMTJUMjM6NTk6NTlaLiBTdGFydCBlYXJseSBlbm91Z2g7IGlmIGV4cGlyZWQgc3RvcCBhbmQgb2J0YWluIGEgZnJlc2ggZm91bmRlciBkZWNpc2lvbiwgd2hpY2ggbWF5IGRlbGF5IHJlY292ZXJ5LiBObyBhdXRvbWF0aWMgdGltZXIvY29udHJvbGxlci9leHRlbnNpb24uIFJvb3QgZnJlc2hseSBhdXRoZW50aWNhdGVzIGV4YWN0IGNvbmZpcm1lZCBwbGF0Zm9ybS1yb290IHBlcnNvbiBBQ0NFUFQgbWVtbyB2ZXJzaW9uMiBhdCBmaXhlZG5hdGl2ZW9yaWdpbiBiZWZvcmUgZXZlcnkgcGhhc2U7IHByb3RlY3RlZHJlY2VpcHRyZWxhdGlvbi9mcmVzaG5lc3MxMjBzZWMgaXMgc3VwZXJ2aXNlZGJvb2trZWVwaW5nLCBub3QgYSBzaWduZWQvYXV0b25vbW91cyBncmFudC4KCkltYWdlNzYzYy9wb2xpY3k5ZDdjL2Jhc2U3ZjUgYW5kIGFjdHVhbHVuZmlsdGVyZWRzY2FuMEhJR0gvQ1JJVElDQUwvMWZpeGFibGVNRURJVU16bGliIHJlbWFpbiB1bmNoYW5nZWQsIG93bmVyIElORkQtUklTSy0yMDI2MTAxMS1aTElCLTg1MDkxL1QwNSBkdWVPY3QxOC4gVGhlIGV4YWN0YnVuZGxlIGRpcmVjdGx5IGJpbmRzIGhlbHBlci9wbGFuL3Rlc3RzIHBsdXMgb3JpZ2luYWwgY291bnQtb25seWJhY2t1cC9mYWlsdXJlL2FuY2hvci4gRXhpc3RpbmdwdWJsaXNoZWRyZWNlaXB0IHN0aWxsIGJpbmRzIHVuY2hhbmdlZCByYXdzY2FuL1NCT00vYmFzZSBzY2FuOyBubyBzdXBwcmVzc2lvbi4gUHJlc2VydmUgb3JpZ2luYWxhcHByb3ZlZDIwZG9jcGFja2V0L2hlbHBlcnMvaGlzdG9yeSBpbiBpbml0aWFsLWFwcHJvdmVkLWJjNjQ5NGNkLiBObyB2ZXJzaW9uMiBuYXRpdmUgb3BlcmF0aW9uIGhhcyBydW4uIEVVUjAgcmVjdXJyaW5naW5mcmFzdHJ1Y3R1cmU7IHByaXZhdGUgYm91bmRlZHN0b3JhZ2UvYXR0ZW5kZWR0aW1lIHVucHJpY2VkLCBubyBuZXdkcmlsbGJhY2t1cCBvciBhdXRvbm9teWdyYW50LgoKTmF0aXZlIHNvdXJjZSBwdWJsaWNhdGlvbiB1c2VzIGV4YWN0IHJldmlzaW9uLWNvbW1hbmQuanNvbiB2aWEgL2xpZmVjeWNsZS9tZW1vcy9pbmZkLTIwMjYxMDExLXB1cnBvc2Utb3ZlcmxheS1yMS9yZXZpc2lvbnMsIGV4cGVjdGVkX3ZlcnNpb24xLCBvbmx5IGFmdGVyIGZyZXNoIHVuYm91bmQtc291cmNlIHJlYWRiYWNrLiBObyB2ZXJzaW9uMiBpbnRha2UvcmVnaXN0ZXIuIFB1Ymxpc2gvcmV2aWV3IHNvdXJjZXZlcnNpb24yOyBuZXcgaHVtYW4gcmV2aWV3LUlEIGlzIG93bnZlcnNpb24xLCBzbyBpdHMgY29uZmlybWVkIG5lc3RlZCBkaXNwb3NpdGlvbiBtZW1vX3ZlcnNpb24xIGlzIGNvcnJlY3QuIFJvb3QgYWN0dWFsIG91dGNvbWVzIHF1ZXJ5IG11c3QgbmFtZSBTT1VSQ0UgdmVyc2lvbjIgYW5kIGV4YWN0IG5ld3Jldmlld0lEOyBvcmlnaW5hbCByZXZpZXcvYXBwcm92YWwgY2Fubm90IGJlIHJldXNlZC4K" + }, + { + "digest": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101", + "media_type": "application/json", + "content_base64": "ewogICJpZCI6ICJJTkZELVJJU0stMjAyNjEwMTEtWkxJQi04NTA5MSIsCiAgImtpbmQiOiAib3duZXItdnVsbmVyYWJpbGl0eS1mb2xsb3ctdGhyb3VnaCIsCiAgIm93bmVyIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAidGFzayI6ICJJTkZELVdQLTAwMDktVDA1IiwKICAic3RhdHVzIjogIm9wZW4iLAogICJjcmVhdGVkIjogIjIwMjYtMTAtMTEiLAogICJyZXZpZXdfZHVlIjogIjIwMjYtMTAtMTgiLAogICJmaW5kaW5nIjogIkNWRS0yMDI2LTg1MDkxIiwKICAic2Nhbm5lcl9zZXZlcml0eSI6ICJNRURJVU0iLAogICJlc3RhdGVfcmlza19ncmFkZSI6IG51bGwsCiAgImFmZmVjdGVkX3BhY2thZ2UiOiAiemxpYiIsCiAgImluc3RhbGxlZCI6ICIxLjMuMi1yMCIsCiAgImZpeGVkIjogIjEuMy4yLXIxIiwKICAiYWN0dWFsX2N1cnJlbnRfYmFzZV9hbmRfY2FuZGlkYXRlX2ZpbmRpbmdzX2lkZW50aWNhbCI6IHRydWUsCiAgInNvdXJjZV9ldmlkZW5jZSI6ICJzZWN1cml0eS1zdW1tYXJ5Lmpzb24sIHRyaXZ5LWZ1bGwuanNvbiwgYmFzZS10cml2eS1mdWxsLmpzb24iLAogICJodW1hbl90ZW1wb3JhcnlfZGlzcG9zaXRpb24iOiAicGVuZGluZyIsCiAgImZvbGxvd190aHJvdWdoIjogIlByZXBhcmUgYSBzZXBhcmF0ZWx5IHNvdXJjZS1ib3VuZCBvZmZpY2lhbC1iYXNlL2RlcGVuZGVuY3kgcmVmcmVzaCB0aHJvdWdoIG5vcm1hbCBvd25lciBDSSwgdmVyaWZ5IGZ1bGwgc2NhbiBhbmQgcnVudGltZSBjb21wYXRpYmlsaXR5LCBvYnRhaW4gZGlzdGluY3QgbmF0aXZlIHJlbGVhc2UgYXBwcm92YWwgYmVmb3JlIHVwZGF0aW5nIHRoaXMgd29ya2xvYWQiLAogICJtYW51YWxfcmV2aWV3X2V4cGlyeSI6ICJEdWUgZGF0ZSByZXF1aXJlcyBvd25lciByZXZpZXcvZXNjYWxhdGlvbiBpZiB1bnJlc29sdmVkOyBubyBhdXRvbWF0aWMgcm9sbGJhY2svY29udHJvbGxlciBpcyBpbnN0YWxsZWQiLAogICJjbG9zZV9jb25kaXRpb24iOiAiVmVyaWZpZWQgaW5zdGFsbGVkIG5hdGl2ZSBmaXhlZCBwYWNrYWdlIGFuZCBmdWxsIHVuZmlsdGVyZWQgcmVzY2FuOyBwcmVzZXJ2ZSBvcmlnaW5hbCBkZXRlY3Rpb24gYW5kIGFueSBodW1hbiBkaXNwb3NpdGlvbiIKfQo=" + }, + { + "digest": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262", + "media_type": "application/json", + "content_base64": "ewogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjI1OjM4Ljc5MzU1NSswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibGl2ZV9yZWFkeV9yZXBsaWNhcyI6IDEsCiAgImFkbWl0dGVkX3VpZCI6ICJhNTg4ZTEwYS05MGQyLTQ4ODMtOTc1ZS02ZGQ4YjhmZWNhOTIiLAogICJzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWQiOiB0cnVlLAogICJhZG1pdHRlZF9zcGVjX2V4YWN0bHlfbGl2ZV9wbHVzX2ltYWdlIjogdHJ1ZSwKICAiY2xpZW50X2RpZmZfZXhpdCI6IDEsCiAgImNsaWVudF9kaWZmX3NoYTI1NiI6ICJhNGJjMDI0YThjZWM2NThmODM1Mjg1ZWQ1MTk2NGUyZTA4NGVkYmFmMTAzZDQ1YTQ4Yjg5YzA5NTBiY2QzZTdkIiwKICAibm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzIjogIihUb3RhbCBsaW1pdHMgbWF5IGJlIG92ZXIgMTAwIHBlcmNlbnQsIGkuZS4sIG92ZXJjb21taXR0ZWQuKVxuICBSZXNvdXJjZSAgICAgICAgICAgUmVxdWVzdHMgICAgICBMaW1pdHNcbiAgLS0tLS0tLS0gICAgICAgICAgIC0tLS0tLS0tICAgICAgLS0tLS0tXG4gIGNwdSAgICAgICAgICAgICAgICAzNDYwbSAoODYlKSAgIDM2MjAwbSAoOTA1JSlcbiAgbWVtb3J5ICAgICAgICAgICAgIDk0NzJNaSAoNTklKSAgMzI4OThNaSAoMjA1JSlcbiAgZXBoZW1lcmFsLXN0b3JhZ2UgIDAgKDAlKSAgICAgICAgMCAoMCUpXG4gIGh1Z2VwYWdlcy0xR2kgICAgICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMk1pICAgICAgMCAoMCUpICAgICAgICAwICgwJSkiLAogICJhbGxfY2hlY2tzX3Bhc3MiOiB0cnVlCn0K" + }, + { + "digest": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362", + "media_type": "application/json", + "content_base64": "ewogICJhcGlWZXJzaW9uIjogImFwcHMvdjEiLAogICJraW5kIjogIkRlcGxveW1lbnQiLAogICJtZXRhZGF0YSI6IHsKICAgICJhbm5vdGF0aW9ucyI6IHsKICAgICAgImFyZ29jZC5hcmdvcHJvai5pby90cmFja2luZy1pZCI6ICJpbmZvcm1lZC1kZWNpc2lvbjphcHBzL0RlcGxveW1lbnQ6aW5mb3JtZWQtZGVjaXNpb24vaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAiaW5mb3JtZWQtZGVjaXNpb24uY291bG9tYi5zb2NpYWwvYWRtaXNzaW9uIjogImFwcHJvdmVkOyBJTkZELVdQLTAwMDcgY3V0b3ZlciIKICAgIH0sCiAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICJ1aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIgogIH0sCiAgInNwZWMiOiB7CiAgICAicHJvZ3Jlc3NEZWFkbGluZVNlY29uZHMiOiA2MDAsCiAgICAicmVwbGljYXMiOiAxLAogICAgInJldmlzaW9uSGlzdG9yeUxpbWl0IjogMTAsCiAgICAic2VsZWN0b3IiOiB7CiAgICAgICJtYXRjaExhYmVscyI6IHsKICAgICAgICAiYXBwLmt1YmVybmV0ZXMuaW8vbmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIKICAgICAgfQogICAgfSwKICAgICJzdHJhdGVneSI6IHsKICAgICAgInR5cGUiOiAiUmVjcmVhdGUiCiAgICB9LAogICAgInRlbXBsYXRlIjogewogICAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImFubm90YXRpb25zIjogewogICAgICAgICAgImluZm9ybWVkLWRlY2lzaW9uLmNvdWxvbWIuc29jaWFsL2FkbWlzc2lvbiI6ICJhcHByb3ZlZDsgSU5GRC1XUC0wMDA3IGN1dG92ZXIiCiAgICAgICAgfSwKICAgICAgICAibGFiZWxzIjogewogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ICJyZXZpZXciLAogICAgICAgICAgImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24iCiAgICAgICAgfQogICAgICB9LAogICAgICAic3BlYyI6IHsKICAgICAgICAiYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbiI6IGZhbHNlLAogICAgICAgICJjb250YWluZXJzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiZW52IjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIklORkRfS0VZQ0FQRV9JU1NVRVIiLAogICAgICAgICAgICAgICAgInZhbHVlIjogImh0dHBzOi8va2MuY291bG9tYi5zb2NpYWwiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJJTkZEX0NPTlRBSU5FUl9DT05GSUciLAogICAgICAgICAgICAgICAgInZhbHVlIjogIi9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvbiIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJpbWFnZSI6ICJmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzMiLAogICAgICAgICAgICAiaW1hZ2VQdWxsUG9saWN5IjogIklmTm90UHJlc2VudCIsCiAgICAgICAgICAgICJsaXZlbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJpbmZvcm1lZC1kZWNpc2lvbiIsCiAgICAgICAgICAgICJwb3J0cyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODAsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJodHRwIiwKICAgICAgICAgICAgICAgICJwcm90b2NvbCI6ICJUQ1AiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29udGFpbmVyUG9ydCI6IDgwODEsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZCIsCiAgICAgICAgICAgICAgICAicHJvdG9jb2wiOiAiVENQIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlYWRpbmVzc1Byb2JlIjogewogICAgICAgICAgICAgICJmYWlsdXJlVGhyZXNob2xkIjogMywKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVzb3VyY2VzIjogewogICAgICAgICAgICAgICJsaW1pdHMiOiB7CiAgICAgICAgICAgICAgICAiY3B1IjogIjUwMG0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICIyNTZNaSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJyZXF1ZXN0cyI6IHsKICAgICAgICAgICAgICAgICJjcHUiOiAiNW0iLAogICAgICAgICAgICAgICAgIm1lbW9yeSI6ICI2NE1pIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInNlY3VyaXR5Q29udGV4dCI6IHsKICAgICAgICAgICAgICAiYWxsb3dQcml2aWxlZ2VFc2NhbGF0aW9uIjogZmFsc2UsCiAgICAgICAgICAgICAgImNhcGFiaWxpdGllcyI6IHsKICAgICAgICAgICAgICAgICJkcm9wIjogWwogICAgICAgICAgICAgICAgICAiQUxMIgogICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInJlYWRPbmx5Um9vdEZpbGVzeXN0ZW0iOiB0cnVlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJzdGFydHVwUHJvYmUiOiB7CiAgICAgICAgICAgICAgImZhaWx1cmVUaHJlc2hvbGQiOiAxMiwKICAgICAgICAgICAgICAiaHR0cEdldCI6IHsKICAgICAgICAgICAgICAgICJwYXRoIjogIi9oZWFsdGh6IiwKICAgICAgICAgICAgICAgICJwb3J0IjogImh0dHAiLAogICAgICAgICAgICAgICAgInNjaGVtZSI6ICJIVFRQIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgInBlcmlvZFNlY29uZHMiOiAxMCwKICAgICAgICAgICAgICAic3VjY2Vzc1RocmVzaG9sZCI6IDEsCiAgICAgICAgICAgICAgInRpbWVvdXRTZWNvbmRzIjogMgogICAgICAgICAgICB9LAogICAgICAgICAgICAidGVybWluYXRpb25NZXNzYWdlUGF0aCI6ICIvZGV2L3Rlcm1pbmF0aW9uLWxvZyIsCiAgICAgICAgICAgICJ0ZXJtaW5hdGlvbk1lc3NhZ2VQb2xpY3kiOiAiRmlsZSIsCiAgICAgICAgICAgICJ2b2x1bWVNb3VudHMiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvZGF0YSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkYXRhIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvcnVuL2luZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi90bXAiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIm1vdW50UGF0aCI6ICIvY29uZmlndXJhdGlvbiIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9wb2xpY3kiLAogICAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsbGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJtb3VudFBhdGgiOiAiL3Zhci9ydW4vc2VjcmV0cy9pbmZvcm1lZC1kZWNpc2lvbi9hdWRpdCIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJhdWRpdCIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24va3ViZXJuZXRlcyIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi93b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIsCiAgICAgICAgICAgICAgICAicmVhZE9ubHkiOiB0cnVlCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibW91bnRQYXRoIjogIi92YXIvcnVuL3NlY3JldHMvaW5mb3JtZWQtZGVjaXNpb24vcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgICAgICJyZWFkT25seSI6IHRydWUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJkbnNQb2xpY3kiOiAiQ2x1c3RlckZpcnN0IiwKICAgICAgICAicmVzdGFydFBvbGljeSI6ICJBbHdheXMiLAogICAgICAgICJzY2hlZHVsZXJOYW1lIjogImRlZmF1bHQtc2NoZWR1bGVyIiwKICAgICAgICAic2VjdXJpdHlDb250ZXh0IjogewogICAgICAgICAgImZzR3JvdXAiOiAxMDAwMSwKICAgICAgICAgICJmc0dyb3VwQ2hhbmdlUG9saWN5IjogIk9uUm9vdE1pc21hdGNoIiwKICAgICAgICAgICJydW5Bc0dyb3VwIjogMTAwMDEsCiAgICAgICAgICAicnVuQXNOb25Sb290IjogdHJ1ZSwKICAgICAgICAgICJydW5Bc1VzZXIiOiAxMDAwMSwKICAgICAgICAgICJzZWNjb21wUHJvZmlsZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiUnVudGltZURlZmF1bHQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic2VydmljZUFjY291bnQiOiAicmV2aWV3IiwKICAgICAgICAic2VydmljZUFjY291bnROYW1lIjogInJldmlldyIsCiAgICAgICAgInRlcm1pbmF0aW9uR3JhY2VQZXJpb2RTZWNvbmRzIjogNDUsCiAgICAgICAgInZvbHVtZXMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogImRhdGEiLAogICAgICAgICAgICAicGVyc2lzdGVudFZvbHVtZUNsYWltIjogewogICAgICAgICAgICAgICJjbGFpbU5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tZGF0YSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImVtcHR5RGlyIjogewogICAgICAgICAgICAgICJtZWRpdW0iOiAiTWVtb3J5IiwKICAgICAgICAgICAgICAic2l6ZUxpbWl0IjogIjE2TWkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogInJ1bnRpbWUiCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiZW1wdHlEaXIiOiB7CiAgICAgICAgICAgICAgIm1lZGl1bSI6ICJNZW1vcnkiLAogICAgICAgICAgICAgICJzaXplTGltaXQiOiAiMTZNaSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm5hbWUiOiAidG1wIgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImNvbmZpZ01hcCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyOTIsCiAgICAgICAgICAgICAgIm5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJuYW1lIjogImNvbmZpZ3VyYXRpb24iCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJjYWxsZXIiLAogICAgICAgICAgICAicHJvamVjdGVkIjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAic291cmNlcyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgInNlcnZpY2VBY2NvdW50VG9rZW4iOiB7CiAgICAgICAgICAgICAgICAgICAgImF1ZGllbmNlIjogImZsZXgtYXV0aCIsCiAgICAgICAgICAgICAgICAgICAgImV4cGlyYXRpb25TZWNvbmRzIjogMzYwMCwKICAgICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0KICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAiYXVkaXQiLAogICAgICAgICAgICAic2VjcmV0IjogewogICAgICAgICAgICAgICJkZWZhdWx0TW9kZSI6IDI4OCwKICAgICAgICAgICAgICAiaXRlbXMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJrZXkiOiAidG9rZW4iLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJ0b2tlbiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJzZWNyZXROYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLWF1ZGl0IgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAibmFtZSI6ICJrdWJlcm5ldGVzLWFwaSIsCiAgICAgICAgICAgICJwcm9qZWN0ZWQiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjg4LAogICAgICAgICAgICAgICJzb3VyY2VzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAic2VydmljZUFjY291bnRUb2tlbiI6IHsKICAgICAgICAgICAgICAgICAgICAiZXhwaXJhdGlvblNlY29uZHMiOiA2MDAsCiAgICAgICAgICAgICAgICAgICAgInBhdGgiOiAidG9rZW4iCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAia2V5IjogImNhLmNydCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJwYXRoIjogImNhLmNydCIKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICJuYW1lIjogImt1YmUtcm9vdC1jYS5jcnQiCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJjb25maWdNYXAiOiB7CiAgICAgICAgICAgICAgImRlZmF1bHRNb2RlIjogMjkyLAogICAgICAgICAgICAgICJuYW1lIjogImluZm9ybWVkLWRlY2lzaW9uLXdvcmtsb2FkLXJlZ2lzdHJ5IgogICAgICAgICAgICB9LAogICAgICAgICAgICAibmFtZSI6ICJ3b3JrbG9hZC1yZWdpc3RyeSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJuYW1lIjogInNpdHRpbmctcmVxdWVzdGVyIiwKICAgICAgICAgICAgInNlY3JldCI6IHsKICAgICAgICAgICAgICAiZGVmYXVsdE1vZGUiOiAyODgsCiAgICAgICAgICAgICAgIml0ZW1zIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAia2V5IjogImNsaWVudC1zZWNyZXQiLAogICAgICAgICAgICAgICAgICAicGF0aCI6ICJjbGllbnQtc2VjcmV0IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm9wdGlvbmFsIjogZmFsc2UsCiAgICAgICAgICAgICAgInNlY3JldE5hbWUiOiAiaW5mb3JtZWQtZGVjaXNpb24tc2l0dGluZy1yZXF1ZXN0ZXIiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0KICAgIH0KICB9Cn0K" + }, + { + "digest": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IGV4YWN0IERlcGxveW1lbnQgYW5kIGFkbWlzc2lvbiBib3VuZGFyaWVzOyBubyBtdXRhdGlvbiBhdXRob3JpdHkuIiIiCmltcG9ydCBjb3B5CmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCgpCQVNFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6N2Y1YzZjYjI5YzlmNzBhMDI2YmZlMzBlNzI5MzQyNzRkZGM2OTI2MTY3NmNmNmQ0NzZmODFkZDMyODEyZDE3MycKQ0FORElEQVRFID0gJ2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbkBzaGEyNTY6NzYzYzM2NDAyYzhiZTdjYzRjMWJkMWE2MTYyM2QxYWZmOTExNmQ1MjI0MTg3NzQyNWI0NWE3MDE4Y2MwODgzYScKCgpkZWYgZGVwZW5kZW5jeV9wcm9qZWN0aW9uKGNvbmZpZ21hcCwgcHZjKToKICAgIGlmIChjb25maWdtYXAuZ2V0KCdraW5kJykgIT0gJ0NvbmZpZ01hcCcgb3IgY29uZmlnbWFwLmdldCgnaW1tdXRhYmxlJykgaXMgbm90IFRydWUKICAgICAgICAgICAgb3IgY29uZmlnbWFwWydtZXRhZGF0YSddWyduYW1lc3BhY2UnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24nCiAgICAgICAgICAgIG9yIGNvbmZpZ21hcFsnbWV0YWRhdGEnXVsnbmFtZSddICE9ICdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MScKICAgICAgICAgICAgb3Igc2V0KGNvbmZpZ21hcC5nZXQoJ2RhdGEnLCB7fSkpICE9IHsncnVudGltZS5qc29uJ30KICAgICAgICAgICAgb3IgY29uZmlnbWFwLmdldCgnYmluYXJ5RGF0YScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGltbXV0YWJsZSBydW50aW1lIGNvbmZpZyBpZGVudGl0eScpCiAgICBpZiAocHZjLmdldCgna2luZCcpICE9ICdQZXJzaXN0ZW50Vm9sdW1lQ2xhaW0nCiAgICAgICAgICAgIG9yIHB2Y1snbWV0YWRhdGEnXVsnbmFtZXNwYWNlJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJwogICAgICAgICAgICBvciBwdmNbJ21ldGFkYXRhJ11bJ25hbWUnXSAhPSAnaW5mb3JtZWQtZGVjaXNpb24tZGF0YScKICAgICAgICAgICAgb3IgcHZjLmdldCgnc3RhdHVzJywge30pLmdldCgncGhhc2UnKSAhPSAnQm91bmQnCiAgICAgICAgICAgIG9yIG5vdCBwdmMuZ2V0KCdzcGVjJywge30pLmdldCgndm9sdW1lTmFtZScpKToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCd1bmV4cGVjdGVkIGJvdW5kIFBWQyBjdXN0b2R5JykKICAgIGNvbmZpZyA9IHByb2plY3Rpb24oY29uZmlnbWFwKQogICAgY29uZmlnLnBvcCgnZGF0YScpCiAgICBjb25maWdbJ2Nhbm9uaWNhbF9kYXRhX3NoYTI1NiddID0gaGFzaGxpYi5zaGEyNTYoanNvbi5kdW1wcygKICAgICAgICBjb25maWdtYXBbJ2RhdGEnXSwgc29ydF9rZXlzPVRydWUsIHNlcGFyYXRvcnM9KCcsJywgJzonKSkuZW5jb2RlKCkpLmhleGRpZ2VzdCgpCiAgICByZXR1cm4geydjb25maWdtYXAnOiBjb25maWcsICdwdmMnOiBwcm9qZWN0aW9uKHB2YyksICdwdmNfcGhhc2UnOiAnQm91bmQnfQoKCmRlZiBjaGVja19kZXBlbmRlbmNpZXMoY29uZmlnbWFwLCBwdmMsIHNlYWxlZCk6CiAgICBpZiBkZXBlbmRlbmN5X3Byb2plY3Rpb24oY29uZmlnbWFwLCBwdmMpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdydW50aW1lIGNvbmZpZyBvciBQVkMgaWRlbnRpdHkvY3VzdG9keSBjaGFuZ2VkJykKCgpkZWYgcHJvamVjdGlvbih2YWx1ZSk6CiAgICB2YWx1ZSA9IGNvcHkuZGVlcGNvcHkodmFsdWUpCiAgICB2YWx1ZS5wb3AoJ3N0YXR1cycsIE5vbmUpCiAgICBmb3Iga2V5IGluICgncmVzb3VyY2VWZXJzaW9uJywgJ2dlbmVyYXRpb24nLCAnY3JlYXRpb25UaW1lc3RhbXAnLCAnbWFuYWdlZEZpZWxkcycpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLnBvcChrZXksIE5vbmUpCiAgICBmb3Iga2V5IGluICgna3ViZWN0bC5rdWJlcm5ldGVzLmlvL2xhc3QtYXBwbGllZC1jb25maWd1cmF0aW9uJywgJ2RlcGxveW1lbnQua3ViZXJuZXRlcy5pby9yZXZpc2lvbicpOgogICAgICAgIHZhbHVlWydtZXRhZGF0YSddLmdldCgnYW5ub3RhdGlvbnMnLCB7fSkucG9wKGtleSwgTm9uZSkKICAgIHJldHVybiB2YWx1ZQoKCmRlZiBjaGVja19jdXJyZW50KGN1cnJlbnQsIHNlYWxlZCk6CiAgICBpZiBwcm9qZWN0aW9uKGN1cnJlbnQpICE9IHNlYWxlZDoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdzZWFsZWQgbGl2ZSBVSUQgb3IgY29uZmlndXJhdGlvbiBjaGFuZ2VkJykKCgpkZWYgY2hlY2tfYWRtaXR0ZWQoYWRtaXR0ZWQsIHNlYWxlZCk6CiAgICBleHBlY3RlZCA9IGNvcHkuZGVlcGNvcHkoc2VhbGVkKQogICAgY29udGFpbmVycyA9IGV4cGVjdGVkWydzcGVjJ11bJ3RlbXBsYXRlJ11bJ3NwZWMnXVsnY29udGFpbmVycyddCiAgICBpZiBsZW4oY29udGFpbmVycykgIT0gMSBvciBjb250YWluZXJzWzBdWyduYW1lJ10gIT0gJ2luZm9ybWVkLWRlY2lzaW9uJyBvciBjb250YWluZXJzWzBdWydpbWFnZSddICE9IEJBU0U6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigndW5leHBlY3RlZCBiYXNlbGluZSBjb250YWluZXIgaWRlbnRpdHknKQogICAgY29udGFpbmVyc1swXVsnaW1hZ2UnXSA9IENBTkRJREFURQogICAgaWYgcHJvamVjdGlvbihhZG1pdHRlZCkgIT0gZXhwZWN0ZWQ6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcignYWRtaXNzaW9uIGNoYW5nZWQgY29uZmlndXJhdGlvbiBiZXlvbmQgdGhlIHNvbGUgaW1hZ2UgcGluJykKCgpkZWYgdHJhbnNwb3J0X3Jlc3VsdChleGl0X2NvZGUsIG91dHB1dCk6CiAgICBpbXBvcnQganNvbgogICAgdHJ5OgogICAgICAgIHZhbHVlID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICBleGNlcHQgKFZhbHVlRXJyb3IsIFR5cGVFcnJvcik6CiAgICAgICAgcmV0dXJuIHsnYWxsX2NoZWNrc19wYXNzJzogRmFsc2UsICdyZWFzb24nOiAnaW52YWxpZCB0cmFuc3BvcnQgcmVzdWx0J30KICAgIGlmIGV4aXRfY29kZSAhPSAwIG9yIG5vdCBpc2luc3RhbmNlKHZhbHVlLCBkaWN0KSBvciB2YWx1ZS5nZXQoJ2FsbF9jaGVja3NfcGFzcycpIGlzIG5vdCBUcnVlOgogICAgICAgIHJldHVybiB7J2FsbF9jaGVja3NfcGFzcyc6IEZhbHNlLCAncmVhc29uJzogJ3JlYWQtb25seSBwcmVmbGlnaHQgcmVmdXNlZCd9CiAgICByZXR1cm4gdmFsdWUK" + }, + { + "digest": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd", + "media_type": "text/plain", + "content_base64": "IiIiUmVhZC1vbmx5IHJlZnJlc2g7IGV4YWN0IG9yaWdpbmFsIGNhcHR1cmUgcmVtYWlucyBpbW11dGFibGU7IG5ldmVyIGV4ZWN1dGUgY3V0b3Zlci4iIiIKaW1wb3J0IGFyZ3BhcnNlLGhhc2hsaWIsanNvbixzdWJwcm9jZXNzLHN5cwpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKaWYgc3lzLmZsYWdzLm9wdGltaXplOgogcmFpc2UgU3lzdGVtRXhpdCgib3B0aW1pemVkIGludGVycHJldGVyIHJlZnVzZWQgYmVmb3JlIHNvdXJjZS90cmFuc3BvcnQgZXhlY3V0aW9uIikKUk9PVD1QYXRoKF9fZmlsZV9fKS5yZXNvbHZlKCkucGFyZW50CnA9YXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKTtwLmFkZF9hcmd1bWVudCgnLS1yZWNlaXB0LW91dHB1dCcsdHlwZT1QYXRoLHJlcXVpcmVkPVRydWUpO3AuYWRkX2FyZ3VtZW50KCctLXNvdXJjZS1yb290Jyx0eXBlPVBhdGgsZGVmYXVsdD1QYXRoKCcvaG9tZS93b3JzY2gvaW5mb3JtZWQtZGVjaXNpb24nKSk7YT1wLnBhcnNlX2FyZ3MoKQpvdXQ9YS5yZWNlaXB0X291dHB1dC5yZXNvbHZlKCkKaWYgbm90IGEucmVjZWlwdF9vdXRwdXQuaXNfYWJzb2x1dGUoKSBvciBvdXQ9PVJPT1Qgb3IgUk9PVCBpbiBvdXQucGFyZW50cyBvciBvdXQ9PWEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIG9yIGEuc291cmNlX3Jvb3QucmVzb2x2ZSgpIGluIG91dC5wYXJlbnRzIG9yIG91dC5leGlzdHMoKToKIHJhaXNlIFN5c3RlbUV4aXQoJ3VuaXF1ZSBleGVjdXRpb24gcmVjZWlwdCBtdXN0IGJlIG91dHNpZGUgdGhlIHNlYWxlZCBwYWNrZXQnKQppbnB1dHM9anNvbi5sb2FkcygoUk9PVC8ncHJlZmxpZ2h0LWlucHV0cy5qc29uJykucmVhZF90ZXh0KCkpCmZvciByZWxhdGl2ZSxkaWdlc3QgaW4gaW5wdXRzWydwYWNrZXRfZmlsZXMnXS5pdGVtcygpOgogcGF0aD1ST09UL3JlbGF0aXZlCiBpZiBwYXRoLmlzX3N5bWxpbmsoKSBvciBoYXNobGliLnNoYTI1NihwYXRoLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCkhPWRpZ2VzdDpyYWlzZSBTeXN0ZW1FeGl0KCdzZWFsZWQgaGVscGVyL2lucHV0IGJ5dGVzIGNoYW5nZWQnKQpmb3IgcmVsYXRpdmUsZGlnZXN0IGluIGlucHV0c1snb3duZXJfc291cmNlX2ZpbGVzJ10uaXRlbXMoKToKIHBhdGg9YS5zb3VyY2Vfcm9vdC9yZWxhdGl2ZQogaWYgcGF0aC5pc19zeW1saW5rKCkgb3IgaGFzaGxpYi5zaGEyNTYocGF0aC5yZWFkX2J5dGVzKCkpLmhleGRpZ2VzdCgpIT1kaWdlc3Q6cmFpc2UgU3lzdGVtRXhpdCgnb3duZXIgc291cmNlIGJ5dGVzIGNoYW5nZWQnKQpmcm9tIGNoYW5nZV9ndWFyZCBpbXBvcnQgdHJhbnNwb3J0X3Jlc3VsdApwcm9ncmFtPSdpbXBvcnQgc3VicHJvY2Vzcyxqc29uLGhhc2hsaWIsZGF0ZXRpbWUsc3lzLGNvcHkscmVcbmlmIHN5cy5mbGFncy5vcHRpbWl6ZTpyYWlzZSBSdW50aW1lRXJyb3IoIm9wdGltaXplZCBpbnRlcnByZXRlciByZWZ1c2VkIilcbmNhbmRpZGF0ZT1qc29uLmxvYWRzKENBTkRJREFURV9MSVRFUkFMKVxuc2VhbGVkX2RlcGVuZGVuY2llcz1qc29uLmxvYWRzKERFUEVOREVOQ0lFU19MSVRFUkFMKVxuc2VhbGVkX2Jhc2VsaW5lPWpzb24ubG9hZHMoU0VBTEVEX0xJVEVSQUwpXG5leGVjKEdVQVJEX0xJVEVSQUwpXG5kZWYgcnVuKGFyZ3MsZGF0YT1Ob25lKTpcbiBwPXN1YnByb2Nlc3MucnVuKGFyZ3MsaW5wdXQ9ZGF0YSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSlcbiBpZiBwLnJldHVybmNvZGU6IHJhaXNlIFZhbHVlRXJyb3IoXCdyZWFkLW9ubHkgY29tbWFuZCBmYWlsZWQ6IFwnK2FyZ3NbMV0rXCcgXCcrYXJnc1syXSlcbiByZXR1cm4gcC5zdGRvdXRcbmxpdmU9anNvbi5sb2FkcyhydW4oW1wna3ViZWN0bFwnLFwnZ2V0XCcsXCdkZXBsb3ltZW50XCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2luZm9ybWVkLWRlY2lzaW9uXCcsXCctb1wnLFwnanNvblwnXSkpXG5jbT1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2NvbmZpZ21hcFwnLFwnaW5mb3JtZWQtZGVjaXNpb24tcnVudGltZS02YzIyMTg3OGQwNTFcJyxcJy1uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW9cJyxcJ2pzb25cJ10pKVxucHZjPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwncHZjXCcsXCdpbmZvcm1lZC1kZWNpc2lvbi1kYXRhXCcsXCctblwnLFwnaW5mb3JtZWQtZGVjaXNpb25cJyxcJy1vXCcsXCdqc29uXCddKSlcbmNoZWNrX2RlcGVuZGVuY2llcyhjbSxwdmMsc2VhbGVkX2RlcGVuZGVuY2llcylcbmNoZWNrX2N1cnJlbnQobGl2ZSxzZWFsZWRfYmFzZWxpbmUpXG5zcGVjPWxpdmVbXCdzcGVjXCddOyBjcz1zcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wnY29udGFpbmVyc1wnXTthc3NlcnQgbGVuKGNzKT09MSBhbmQgY3NbMF1bXCduYW1lXCddPT1cJ2luZm9ybWVkLWRlY2lzaW9uXCdcbmV4cGVjdGVkX2Vudj17XCdJTkZEX0tFWUNBUEVfSVNTVUVSXCc6XCdodHRwczovL2tjLmNvdWxvbWIuc29jaWFsXCcsXCdJTkZEX0NPTlRBSU5FUl9DT05GSUdcJzpcJy9jb25maWd1cmF0aW9uL3J1bnRpbWUuanNvblwnfVxuYXNzZXJ0IGNzWzBdLmdldChcJ2VudlwnKT09W3tcJ25hbWVcJzpcJ0lORkRfS0VZQ0FQRV9JU1NVRVJcJyxcJ3ZhbHVlXCc6ZXhwZWN0ZWRfZW52W1wnSU5GRF9LRVlDQVBFX0lTU1VFUlwnXX0se1wnbmFtZVwnOlwnSU5GRF9DT05UQUlORVJfQ09ORklHXCcsXCd2YWx1ZVwnOmV4cGVjdGVkX2VudltcJ0lORkRfQ09OVEFJTkVSX0NPTkZJR1wnXX1dXG5hc3NlcnQgY3NbMF1bXCdpbWFnZVwnXT09XCdmb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb25Ac2hhMjU2OjdmNWM2Y2IyOWM5ZjcwYTAyNmJmZTMwZTcyOTM0Mjc0ZGRjNjkyNjE2NzZjZjZkNDc2ZjgxZGQzMjgxMmQxNzNcJ1xuYXNzZXJ0IHNwZWNbXCdyZXBsaWNhc1wnXT09MSBhbmQgc3BlY1tcJ3N0cmF0ZWd5XCddPT17XCd0eXBlXCc6XCdSZWNyZWF0ZVwnfVxuYXNzZXJ0IG5leHQodiBmb3IgdiBpbiBzcGVjW1wndGVtcGxhdGVcJ11bXCdzcGVjXCddW1wndm9sdW1lc1wnXSBpZiB2W1wnbmFtZVwnXT09XCdjb25maWd1cmF0aW9uXCcpW1wnY29uZmlnTWFwXCddW1wnbmFtZVwnXT09XCdpbmZvcm1lZC1kZWNpc2lvbi1ydW50aW1lLTZjMjIxODc4ZDA1MVwnXG5hc3NlcnQgbGl2ZVtcJ3N0YXR1c1wnXS5nZXQoXCdyZWFkeVJlcGxpY2FzXCcpPT0xIGFuZCBsaXZlW1wnc3RhdHVzXCddLmdldChcJ3VwZGF0ZWRSZXBsaWNhc1wnKT09MVxuc2VhbGVkPXtcJ2FwaVZlcnNpb25cJzpsaXZlW1wnYXBpVmVyc2lvblwnXSxcJ2tpbmRcJzpsaXZlW1wna2luZFwnXSxcJ21ldGFkYXRhXCc6e2s6Y29weS5kZWVwY29weSh2KSBmb3Igayx2IGluIGxpdmVbXCdtZXRhZGF0YVwnXS5pdGVtcygpIGlmIGsgbm90IGluIChcJ3Jlc291cmNlVmVyc2lvblwnLFwnZ2VuZXJhdGlvblwnLFwnY3JlYXRpb25UaW1lc3RhbXBcJyxcJ21hbmFnZWRGaWVsZHNcJyl9LFwnc3BlY1wnOmNvcHkuZGVlcGNvcHkoc3BlYyl9XG5mb3Iga2V5IGluIChcJ2t1YmVjdGwua3ViZXJuZXRlcy5pby9sYXN0LWFwcGxpZWQtY29uZmlndXJhdGlvblwnLFwnZGVwbG95bWVudC5rdWJlcm5ldGVzLmlvL3JldmlzaW9uXCcpOnNlYWxlZFtcJ21ldGFkYXRhXCddLmdldChcJ2Fubm90YXRpb25zXCcse30pLnBvcChrZXksTm9uZSlcbmFkbWl0dGVkPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2FwcGx5XCcsXCctLWRyeS1ydW49c2VydmVyXCcsXCctZlwnLFwnLVwnLFwnLW9cJyxcJ2pzb25cJ10sanNvbi5kdW1wcyhjYW5kaWRhdGUpKSlcbmNoZWNrX2FkbWl0dGVkKGFkbWl0dGVkLHNlYWxlZF9iYXNlbGluZSlcbmFwcD1qc29uLmxvYWRzKHJ1bihbXCdrdWJlY3RsXCcsXCdnZXRcJyxcJ2FwcGxpY2F0aW9uXCcsXCdpbmZvcm1lZC1kZWNpc2lvblwnLFwnLW5cJyxcJ2FyZ29jZFwnLFwnLW9cJyxcJ2pzb25cJ10pKVxuYXNzZXJ0IGFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCdwYXRoXCddPT1cJ2RlcGxveS9saWZlY3ljbGVcJyBhbmQgbm90IGFwcFtcJ3NwZWNcJ10uZ2V0KFwnc3luY1BvbGljeVwnLHt9KS5nZXQoXCdhdXRvbWF0ZWRcJylcbmFyZ289e1wndWlkXCc6YXBwW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdyZXBvVVJMXCc6YXBwW1wnc3BlY1wnXVtcJ3NvdXJjZVwnXVtcJ3JlcG9VUkxcJ10sXCd0YXJnZXRSZXZpc2lvblwnOmFwcFtcJ3NwZWNcJ11bXCdzb3VyY2VcJ11bXCd0YXJnZXRSZXZpc2lvblwnXSxcJ3BhdGhcJzphcHBbXCdzcGVjXCddW1wnc291cmNlXCddW1wncGF0aFwnXSxcJ2Rlc3RpbmF0aW9uXCc6YXBwW1wnc3BlY1wnXVtcJ2Rlc3RpbmF0aW9uXCddLFwnYXV0b21hdGVkXCc6RmFsc2UsXCdzeW5jXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdzeW5jXCcpLFwnaGVhbHRoXCc6YXBwLmdldChcJ3N0YXR1c1wnLHt9KS5nZXQoXCdoZWFsdGhcJyl9XG5leHBlY3RlZF9hcmdvPWpzb24ubG9hZHMoQVJHT19MSVRFUkFMKVxuZm9yIGtleSBpbiAoXCd1aWRcJyxcJ3JlcG9VUkxcJyxcJ3RhcmdldFJldmlzaW9uXCcsXCdwYXRoXCcsXCdkZXN0aW5hdGlvblwnLFwnYXV0b21hdGVkXCcpOlxuIGFzc2VydCBhcmdvW2tleV09PWV4cGVjdGVkX2FyZ29ba2V5XVxuYXNzZXJ0IGFyZ29bXCdoZWFsdGhcJ11bXCdzdGF0dXNcJ109PVwnSGVhbHRoeVwnXG5kaWZmPXN1YnByb2Nlc3MucnVuKFtcJ2t1YmVjdGxcJyxcJ2RpZmZcJyxcJy1mXCcsXCctXCddLGlucHV0PWpzb24uZHVtcHMoY2FuZGlkYXRlKSx0ZXh0PVRydWUsY2FwdHVyZV9vdXRwdXQ9VHJ1ZSk7YXNzZXJ0IGRpZmYucmV0dXJuY29kZSBpbiAoMCwxKVxuIyBEaWZmIGNhbiBjb250YWluIG9ubHkgbm9uc2VjcmV0IERlcGxveW1lbnQgcmVmZXJlbmNlczsgcHJlc2VydmUgZGlnZXN0IHJhdGhlciB0aGFuIHJhdyBzdGRvdXQuXG5ub2RlPXJ1bihbXCdrdWJlY3RsXCcsXCdkZXNjcmliZVwnLFwnbm9kZVwnXSk7YWxsb2NhdGVkPXJlLnNlYXJjaChyXCdBbGxvY2F0ZWQgcmVzb3VyY2VzOi4qP0NQVSBSZXF1ZXN0c3xBbGxvY2F0ZWQgcmVzb3VyY2VzOlwnLG5vZGUscmUuUylcbnNlY3Rpb249bm9kZS5zcGxpdChcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcpWzFdLnNwbGl0KFwnRXZlbnRzOlwnKVswXSBpZiBcJ0FsbG9jYXRlZCByZXNvdXJjZXM6XCcgaW4gbm9kZSBlbHNlIFwnXCdcbm5vZGVzPWpzb24ubG9hZHMocnVuKFtcJ2t1YmVjdGxcJyxcJ2dldFwnLFwnbm9kZXNcJyxcJy1vXCcsXCdqc29uXCddKSlbXCdpdGVtc1wnXTthc3NlcnQgbGVuKG5vZGVzKT09MVxuYWxsb2M9bm9kZXNbMF1bXCdzdGF0dXNcJ11bXCdhbGxvY2F0YWJsZVwnXTtjcHU9YWxsb2NbXCdjcHVcJ107Y3B1X209aW50KGNwdVs6LTFdKSBpZiBjcHUuZW5kc3dpdGgoXCdtXCcpIGVsc2UgaW50KGNwdSkqMTAwMFxucmVxdWVzdGVkPWludChyZS5zZWFyY2goclwnY3B1XFxzKyhcXGQrKW1cJyxzZWN0aW9uKS5ncm91cCgxKSk7YXNzZXJ0IHJlcXVlc3RlZDw9Y3B1X21cbnJlY2VpcHQ9e1wnbm9kZV9hbGxvY2F0YWJsZV9jcHVfbVwnOmNwdV9tLFwnbm9kZV9yZXF1ZXN0ZWRfY3B1X21cJzpyZXF1ZXN0ZWQsXCdjYXB0dXJlZF9hdFwnOmRhdGV0aW1lLmRhdGV0aW1lLm5vdyhkYXRldGltZS50aW1lem9uZS51dGMpLmlzb2Zvcm1hdCgpLFwnbmF0aXZlX3dvcmtsb2FkX2NoYW5nZWRcJzpGYWxzZSxcJ25hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZFwnOkZhbHNlLFwnYXJnb1wnOmFyZ28sXCduYXRpdmVfZGVwZW5kZW5jaWVzX2NoZWNrZWRcJzpUcnVlLFwnY29uZmlnbWFwX3VpZFwnOmNtW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdwdmNfdWlkXCc6cHZjW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdsaXZlX3JlYWR5X3JlcGxpY2FzXCc6MSxcJ2FkbWl0dGVkX3VpZFwnOmFkbWl0dGVkW1wnbWV0YWRhdGFcJ11bXCd1aWRcJ10sXCdzZXJ2ZXJfZHJ5X3J1bl9wYXNzZWRcJzpUcnVlLFwnYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZVwnOlRydWUsXCdjbGllbnRfZGlmZl9leGl0XCc6ZGlmZi5yZXR1cm5jb2RlLFwnY2xpZW50X2RpZmZfc2hhMjU2XCc6aGFzaGxpYi5zaGEyNTYoZGlmZi5zdGRvdXQuZW5jb2RlKCkpLmhleGRpZ2VzdCgpLFwnbm9kZV9hbGxvY2F0ZWRfcmVzb3VyY2VzXCc6c2VjdGlvbi5zdHJpcCgpLFwnYWxsX2NoZWNrc19wYXNzXCc6VHJ1ZX1cbnByaW50KGpzb24uZHVtcHMocmVjZWlwdCkpXG4nCmZvciBtYXJrZXIsdmFsdWUgaW4gWygnREVQRU5ERU5DSUVTX0xJVEVSQUwnLChST09ULydzZWFsZWQtbmF0aXZlLWRlcGVuZGVuY2llcy5qc29uJykucmVhZF90ZXh0KCkpLCgnQ0FORElEQVRFX0xJVEVSQUwnLChST09ULydjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uJykucmVhZF90ZXh0KCkpLCgnU0VBTEVEX0xJVEVSQUwnLChST09ULydzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24nKS5yZWFkX3RleHQoKSksKCdHVUFSRF9MSVRFUkFMJywoUk9PVC8nY2hhbmdlX2d1YXJkLnB5JykucmVhZF90ZXh0KCkpLCgnQVJHT19MSVRFUkFMJyxqc29uLmR1bXBzKGpzb24ubG9hZHMoKFJPT1QvJ25hdGl2ZS1wcmVmbGlnaHQuanNvbicpLnJlYWRfdGV4dCgpKVsnYXJnbyddKSldOgogcHJvZ3JhbT1wcm9ncmFtLnJlcGxhY2UobWFya2VyLHJlcHIodmFsdWUpKQpwcm9ncmFtPSdpbXBvcnQgdHJhY2ViYWNrLGpzb25cbnRyeTpcbicrJycuam9pbignICAgICcrbGluZSsnXG4nIGZvciBsaW5lIGluIHByb2dyYW0uc3BsaXRsaW5lcygpKSsiZXhjZXB0IEV4Y2VwdGlvbiBhcyBlcnJvcjpcbiAgICBwcmludChqc29uLmR1bXBzKHsnYWxsX2NoZWNrc19wYXNzJzpGYWxzZSwnZXhjZXB0aW9uX3R5cGUnOnR5cGUoZXJyb3IpLl9fbmFtZV9fLCdleGNlcHRpb25fbGluZSc6dHJhY2ViYWNrLmV4dHJhY3RfdGIoZXJyb3IuX190cmFjZWJhY2tfXylbLTFdLmxpbmVub30pKVxuIgpyPXN1YnByb2Nlc3MucnVuKFsnc3NoJywncmFpbGlhbmNlMDEnLCdweXRob24zIC0nXSxpbnB1dD1wcm9ncmFtLHRleHQ9VHJ1ZSxjYXB0dXJlX291dHB1dD1UcnVlKQpyZXN1bHQ9dHJhbnNwb3J0X3Jlc3VsdChyLnJldHVybmNvZGUsci5zdGRvdXQpO3Jlc3VsdFsnc2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2J109aGFzaGxpYi5zaGEyNTYoKFJPT1QvJ3ByZWZsaWdodC1pbnB1dHMuanNvbicpLnJlYWRfYnl0ZXMoKSkuaGV4ZGlnZXN0KCk7cmVzdWx0WydmcmVzaF9leGVjdXRpb25fcmVjZWlwdCddPVRydWUKb3V0LndyaXRlX3RleHQoanNvbi5kdW1wcyhyZXN1bHQsaW5kZW50PTIpKydcbicpO3ByaW50KGpzb24uZHVtcHMocmVzdWx0LGluZGVudD0yKSk7c3lzLmV4aXQoMCBpZiByZXN1bHQuZ2V0KCdhbGxfY2hlY2tzX3Bhc3MnKSBpcyBUcnVlIGVsc2UgMSkK" + }, + { + "digest": "sha256:03bb4b42fe1aa51b846e957a9e23926fae72f02a2cb5e297368047fb25c17e9b", + "media_type": "application/json", + "content_base64": "ewogICJwYWNrZXRfZmlsZXMiOiB7CiAgICAiY2hhbmdlX2d1YXJkLnB5IjogImYzNDhlNDQ5YzQ5ZjRkOWU0OWFmOWU4MmUwMTc2NGU3MTk3ODM3ZmQzZGY5ZDc1NmY1ODkxZDliOGQ5YjM4YmUiLAogICAgInByZWZsaWdodC5weSI6ICI2YjRjNjVmNzA4MjM4YzlhOWQxN2ZkMDY1ODc2YzdhMDBlMWYxNzQ1OTI2Zjk5MGExZGQ1ZTY2NzI5ODM0MGNkIiwKICAgICJjYW5kaWRhdGUtZGVwbG95bWVudC5qc29uIjogIjcyMmE4ZTJkYzUyYmVjMjE3YmY5NjBlMjNiMmZkZGZjN2FjMjdkMzQzYWM4NzQzNzkwZTMxODNkYjgxYTZhMGUiLAogICAgInJvbGxiYWNrLWRlcGxveW1lbnQuanNvbiI6ICIzOWIzZjQzYmI4NGVmNDkyMWNjM2ExZmJjZGM0NDQ2MTA3NDFlZDg4MDkxNDlkOGY4ZjE3ZWQ4MDVmMjYyMTIxIiwKICAgICJzZWFsZWQtbGl2ZS1kZXBsb3ltZW50Lmpzb24iOiAiZDE4ZDI3MDYzZDA2ZjUzNWFlODg0ZWEwMWY5Njc0N2ZlMzAxNjg1NTE4YWI5NGIxY2JhMDcyYTFlMTUxOTM2MiIsCiAgICAibmF0aXZlLXByZWZsaWdodC5qc29uIjogImViNWY0MWFlZmI5NzY2NmJiMGMxMjc5NjE3ZTk1YTdjMDUwMTdhNjA5NDE1NjI0ZGFlZTcyNGM0OGI5MGQyNjIiLAogICAgInNlYWxlZC1uYXRpdmUtZGVwZW5kZW5jaWVzLmpzb24iOiAiMDQyMzI3YTAzNmVkMjU0Y2Y5NWRiZWIwYzA1NmFjMjViMDNhNmE4NDRiOTVhMzMyYzk5MmRmMjk0MzY5MTM2OSIsCiAgICAic3FsaXRlX3JlYWRvbmx5LnB5IjogIjkwOTNjNjRmN2YwZTM5YjI0OWRhOWZlZmRmNWFhZjRlNDI1OGJjMzFlN2EyN2ZkODg4NDc5Y2UzMjlhMjA1MDkiCiAgfSwKICAib3duZXJfc291cmNlX2ZpbGVzIjogewogICAgImRlcGxveS9saWZlY3ljbGUvYWRtaXNzaW9uLmNhbmRpZGF0ZS5qc29uIjogIjkyMzgyYTU2YjM0OWMzYjg5NWU1ODA2ZTk3NTA4MjUyN2JiOTlkMWEwMDExNDBlNjlkODU3ZTViMDM5MWZhNTUiLAogICAgImRlcGxveS9saWZlY3ljbGUvc2VydmljZS5jYW5kaWRhdGUuanNvbiI6ICIzOGI3OGI5Y2JlZTVhZGU3NzUwYTU4ZDUxNTZjYTRjNTc3MzM1MmU5NDdhY2IzMDRlZTcxNGI1OWU3NDljZWI0IgogIH0KfQo=" + }, + { + "digest": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7", + "media_type": "application/json", + "content_base64": "ewogICJub2RlX2FsbG9jYXRhYmxlX2NwdV9tIjogNDAwMCwKICAibm9kZV9yZXF1ZXN0ZWRfY3B1X20iOiAzNDYwLAogICJjYXB0dXJlZF9hdCI6ICIyMDI2LTEwLTExVDAxOjM5OjE0LjIzNDI3NyswMDowMCIsCiAgIm5hdGl2ZV93b3JrbG9hZF9jaGFuZ2VkIjogZmFsc2UsCiAgIm5hdGl2ZV9iYWNrdXBfcmVzdG9yZV9leGVjdXRlZCI6IGZhbHNlLAogICJhcmdvIjogewogICAgInVpZCI6ICI0OTk4NjhmMi1lYWJjLTRkZjQtYWUzMS1iODljZTU4ZDc1MGQiLAogICAgInJlcG9VUkwiOiAiaHR0cHM6Ly9mb3JnZWpvLmNvdWxvbWIuc29jaWFsL2NvdWxvbWIvaW5mb3JtZWQtZGVjaXNpb24uZ2l0IiwKICAgICJ0YXJnZXRSZXZpc2lvbiI6ICI3ZGI4NDg1ZmZlY2RlYmZhYmQ3N2E5ZGFlYzA4NTU1M2M3NGJmMGJmIiwKICAgICJwYXRoIjogImRlcGxveS9saWZlY3ljbGUiLAogICAgImRlc3RpbmF0aW9uIjogewogICAgICAibmFtZXNwYWNlIjogImluZm9ybWVkLWRlY2lzaW9uIiwKICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICB9LAogICAgImF1dG9tYXRlZCI6IGZhbHNlLAogICAgInN5bmMiOiB7CiAgICAgICJjb21wYXJlZFRvIjogewogICAgICAgICJkZXN0aW5hdGlvbiI6IHsKICAgICAgICAgICJuYW1lc3BhY2UiOiAiaW5mb3JtZWQtZGVjaXNpb24iLAogICAgICAgICAgInNlcnZlciI6ICJodHRwczovL2t1YmVybmV0ZXMuZGVmYXVsdC5zdmMiCiAgICAgICAgfSwKICAgICAgICAic291cmNlIjogewogICAgICAgICAgInBhdGgiOiAiZGVwbG95L2xpZmVjeWNsZSIsCiAgICAgICAgICAicmVwb1VSTCI6ICJodHRwczovL2Zvcmdlam8uY291bG9tYi5zb2NpYWwvY291bG9tYi9pbmZvcm1lZC1kZWNpc2lvbi5naXQiLAogICAgICAgICAgInRhcmdldFJldmlzaW9uIjogIjdkYjg0ODVmZmVjZGViZmFiZDc3YTlkYWVjMDg1NTUzYzc0YmYwYmYiCiAgICAgICAgfQogICAgICB9LAogICAgICAicmV2aXNpb24iOiAiN2RiODQ4NWZmZWNkZWJmYWJkNzdhOWRhZWMwODU1NTNjNzRiZjBiZiIsCiAgICAgICJzdGF0dXMiOiAiT3V0T2ZTeW5jIgogICAgfSwKICAgICJoZWFsdGgiOiB7CiAgICAgICJsYXN0VHJhbnNpdGlvblRpbWUiOiAiMjAyNi0xMC0xMFQyMzoxNDo1MloiLAogICAgICAic3RhdHVzIjogIkhlYWx0aHkiCiAgICB9CiAgfSwKICAibmF0aXZlX2RlcGVuZGVuY2llc19jaGVja2VkIjogdHJ1ZSwKICAiY29uZmlnbWFwX3VpZCI6ICI5MDExM2QyZC01NGQ5LTRlODItYjFkMy05MGI0OWViZWQyYjUiLAogICJwdmNfdWlkIjogImQ4MGIyNWIxLTE0MWEtNDQxYi1iMjA1LTk4ZmEyZmQ5OGI3YyIsCiAgImxpdmVfcmVhZHlfcmVwbGljYXMiOiAxLAogICJhZG1pdHRlZF91aWQiOiAiYTU4OGUxMGEtOTBkMi00ODgzLTk3NWUtNmRkOGI4ZmVjYTkyIiwKICAic2VydmVyX2RyeV9ydW5fcGFzc2VkIjogdHJ1ZSwKICAiYWRtaXR0ZWRfc3BlY19leGFjdGx5X2xpdmVfcGx1c19pbWFnZSI6IHRydWUsCiAgImNsaWVudF9kaWZmX2V4aXQiOiAxLAogICJjbGllbnRfZGlmZl9zaGEyNTYiOiAiODQwNzY5YzdkMmE5YzE2NTVjNDBhMzI1OWY4MzNkMWZjOGY2OTk1MGNlYjNiZWRiNzA3YTk1NWZlZDcxMTU2NiIsCiAgIm5vZGVfYWxsb2NhdGVkX3Jlc291cmNlcyI6ICIoVG90YWwgbGltaXRzIG1heSBiZSBvdmVyIDEwMCBwZXJjZW50LCBpLmUuLCBvdmVyY29tbWl0dGVkLilcbiAgUmVzb3VyY2UgICAgICAgICAgIFJlcXVlc3RzICAgICAgTGltaXRzXG4gIC0tLS0tLS0tICAgICAgICAgICAtLS0tLS0tLSAgICAgIC0tLS0tLVxuICBjcHUgICAgICAgICAgICAgICAgMzQ2MG0gKDg2JSkgICAzNjIwMG0gKDkwNSUpXG4gIG1lbW9yeSAgICAgICAgICAgICA5NDcyTWkgKDU5JSkgIDMyODk4TWkgKDIwNSUpXG4gIGVwaGVtZXJhbC1zdG9yYWdlICAwICgwJSkgICAgICAgIDAgKDAlKVxuICBodWdlcGFnZXMtMUdpICAgICAgMCAoMCUpICAgICAgICAwICgwJSlcbiAgaHVnZXBhZ2VzLTJNaSAgICAgIDAgKDAlKSAgICAgICAgMCAoMCUpIiwKICAiYWxsX2NoZWNrc19wYXNzIjogdHJ1ZSwKICAic2VhbGVkX3ByZWZsaWdodF9pbnB1dHNfc2hhMjU2IjogIjc1NmU3MmRhOWVjMzY1NzIyNDI0MjFiZWE4YjZkMjI4NTM5NGUzMzRmOTkxZGI1ZTkwZTliNDA5NTYzYjVmMDYiLAogICJmcmVzaF9leGVjdXRpb25fcmVjZWlwdCI6IHRydWUKfQo=" + } + ] +} diff --git a/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py b/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py index 833721b..64274bd 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py +++ b/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py @@ -1,15 +1,22 @@ """Pre-open schema/integrity/count proof; stdlib only, never constructs Store.""" import argparse +from contextlib import closing +import hashlib +import os +import re +import stat import json from pathlib import Path import sqlite3 -def inspect_readonly(path): +def inspect_readonly(path, *, _closed_snapshot=False): path = Path(path) if not path.is_file() or path.is_symlink(): raise ValueError('existing nonsymlink private database required') - with sqlite3.connect(path.resolve().as_uri() + '?mode=ro', uri=True, timeout=5) as db: + uri = path.resolve().as_uri() + '?mode=ro' + ('&immutable=1' if _closed_snapshot else '') + # sqlite3.Connection context management ends transactions; it does not close. + with closing(sqlite3.connect(uri, uri=True, timeout=5)) as db: db.execute('PRAGMA query_only=ON') db.execute('BEGIN') version = db.execute('PRAGMA user_version').fetchone()[0] @@ -29,6 +36,55 @@ def inspect_readonly(path): return result +def inspect_closed_snapshot(path, expected_sha256): + """Only a privately retained, frozen main-file snapshot with no WAL frames. + + Caller must establish exclusive snapshot creation/admin exit/no writer, and + supply the recorded frozen main digest. Never use for the live database. + Immutable SQLite reads ignore stale SHM and never create/change sidecars. + Existing sidecars remain custody evidence; nothing is deleted/checkpointed. + """ + path = Path(path) + if re.fullmatch(r'[0-9a-f]{64}', expected_sha256) is None: + raise ValueError('exact frozen snapshot digest required') + def metadata(target): + info = target.lstat() + if not stat.S_ISREG(info.st_mode) or stat.S_IMODE(info.st_mode) != 0o600 or info.st_nlink != 1: + raise ValueError('private single-link snapshot custody required') + return info + main = metadata(path) + if not 0 < main.st_size <= 512 * 1024**2: + raise ValueError('bounded frozen snapshot required') + def sidecars(): + identities = {} + for suffix in ('-wal', '-shm'): + target = Path(str(path) + suffix) + if os.path.lexists(target): + info = metadata(target) + if info.st_uid != main.st_uid or info.st_gid != main.st_gid: + raise ValueError('snapshot sidecar custody changed') + if suffix == '-wal' and info.st_size != 0: + raise ValueError('snapshot has WAL frames; immutable read refused') + identities[suffix] = (info.st_dev, info.st_ino, info.st_size, info.st_mtime_ns) + return identities + before_sidecars = sidecars() + def digest(): + value = hashlib.sha256() + with path.open('rb') as stream: + for block in iter(lambda: stream.read(1024**2), b''): + value.update(block) + return value.hexdigest() + if digest() != expected_sha256: + raise ValueError('frozen main-file digest changed before inspection') + proof = inspect_readonly(path, _closed_snapshot=True) + after = metadata(path) + if (after.st_dev, after.st_ino, after.st_uid, after.st_gid, after.st_size) != (main.st_dev, main.st_ino, main.st_uid, main.st_gid, main.st_size): + raise ValueError('frozen main-file identity changed') + if digest() != expected_sha256 or sidecars() != before_sidecars: + raise ValueError('frozen snapshot changed during inspection') + return proof + + if __name__ == '__main__': parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--db', type=Path, required=True) diff --git a/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py b/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py new file mode 100644 index 0000000..913ef29 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-image-release/test_snapshot_readonly_repair.py @@ -0,0 +1,97 @@ +"""Mocked SQLite regression fixtures; no actual SQLite/admin/native command.""" +import hashlib +import os +from pathlib import Path +import tempfile +import unittest +from unittest.mock import patch +import sqlite_readonly as checker + + +class Cursor: + def __init__(self, one=None, rows=None):self.one=one;self.rows=rows + def fetchone(self):return self.one + def fetchall(self):return self.rows + def __iter__(self):return iter(self.rows or []) + + +class Connection: + def __init__(self, version=5):self.version=version;self.closed=False;self.queries=[] + def execute(self, sql): + self.queries.append(sql) + if sql=='PRAGMA user_version':return Cursor(one=(self.version,)) + if sql=='PRAGMA integrity_check':return Cursor(rows=[('ok',)]) + if 'GROUP BY' in sql:return Cursor(rows=[('confirmed',1)] if 'submissions' in sql else [('delivered',1)]) + return Cursor(one=(1,)) + def rollback(self):pass + def close(self):self.closed=True + + +class SnapshotRepair(unittest.TestCase): + def file(self, root, name='snapshot.sqlite', data=b'frozen synthetic main'): + p=Path(root)/name;p.write_bytes(data);os.chmod(p,0o600);return p + + def test_live_reader_remains_wal_aware_and_explicitly_closes(self): + for schema in (5,4): + with self.subTest(schema=schema),tempfile.TemporaryDirectory() as root: + p=self.file(root);connection=Connection(schema) + with patch.object(checker.sqlite3,'connect',return_value=connection) as connect: + if schema==5:checker.inspect_readonly(p) + else: + with self.assertRaises(ValueError):checker.inspect_readonly(p) + self.assertTrue(connection.closed) + self.assertTrue(connect.call_args.args[0].endswith('?mode=ro')) + self.assertNotIn('immutable',connect.call_args.args[0]) + self.assertIn('PRAGMA query_only=ON',connection.queries) + + def test_zero_wal_stale_shm_retained_immutable_main_proof_no_mutation(self): + with tempfile.TemporaryDirectory() as root: + p=self.file(root);wal=self.file(root,p.name+'-wal',b'');shm=self.file(root,p.name+'-shm',b'x'*32768) + before={q:(q.read_bytes(),q.stat().st_mtime_ns) for q in (p,wal,shm)};connection=Connection() + with patch.object(checker.sqlite3,'connect',return_value=connection) as connect: + result=checker.inspect_closed_snapshot(p,hashlib.sha256(p.read_bytes()).hexdigest()) + self.assertEqual(result['schema_version'],5);self.assertTrue(connection.closed) + self.assertTrue(connect.call_args.args[0].endswith('?mode=ro&immutable=1')) + for q,(data,mtime) in before.items():self.assertEqual((q.read_bytes(),q.stat().st_mtime_ns),(data,mtime)) + + def test_nonempty_wal_changed_digest_and_symlink_refuse_before_sqlite(self): + for defect in ('wal','digest','symlink'): + with self.subTest(defect=defect),tempfile.TemporaryDirectory() as root: + p=self.file(root);digest=hashlib.sha256(p.read_bytes()).hexdigest() + if defect=='wal':self.file(root,p.name+'-wal',b'frame') + elif defect=='digest':digest='0'*64 + else: + alias=Path(root)/'alias.sqlite';alias.symlink_to(p);p=alias + with patch.object(checker.sqlite3,'connect') as connect: + with self.assertRaises(ValueError):checker.inspect_closed_snapshot(p,digest) + connect.assert_not_called() + + def test_main_or_sidecar_change_during_inspection_refuses(self): + for defect in ('main','wal','shm'): + with self.subTest(defect=defect),tempfile.TemporaryDirectory() as root: + p=self.file(root);digest=hashlib.sha256(p.read_bytes()).hexdigest() + if defect=='shm':self.file(root,p.name+'-shm',b'x'*32768) + connection=Connection();original=connection.execute + def changed(sql): + result=original(sql) + if sql=='PRAGMA integrity_check': + if defect=='main':p.write_bytes(b'changed main') + elif defect=='wal':self.file(root,p.name+'-wal',b'frame') + else:Path(str(p)+'-shm').write_bytes(b'changed') + return result + connection.execute=changed + with patch.object(checker.sqlite3,'connect',return_value=connection): + with self.assertRaises(ValueError):checker.inspect_closed_snapshot(p,digest) + self.assertTrue(connection.closed) + + def test_inner_native_paths_use_immutable_only_for_snapshot_output(self): + import ast + p=Path(__file__).parent/'execution/native_program.py';tree=ast.parse(p.read_text());source=ast.literal_eval(next(n.value for n in tree.body if isinstance(n,ast.Assign))) + self.assertIn('baseline=counts(inspect_readonly(db))',source) + self.assertEqual(source.count('inspect_closed_snapshot(output,'),2) + self.assertNotIn('inspect_closed_snapshot(db',source) + self.assertIn("identity['snapshot_sha256']",source) + self.assertIn("size==identity['snapshot_bytes']",source) + + +if __name__=='__main__':unittest.main() diff --git a/docs/evidence/2026-10-11-purpose-image-release/validation.json b/docs/evidence/2026-10-11-purpose-image-release/validation.json index 957926b..123166c 100644 --- a/docs/evidence/2026-10-11-purpose-image-release/validation.json +++ b/docs/evidence/2026-10-11-purpose-image-release/validation.json @@ -1,57 +1,26 @@ { - "intake_valid_offline": true, - "typed_memo_valid": true, - "lifecycle_documents_valid": 20, - "packet_actual_file_bytes_verified": true, - "submission_digest": "sha256:fd78d486174670e12efb2f812bac02e68f294e7791b9302d0d458c053240f5a9", - "offline_constructed_grant": "state-hub/decision-record/net-kingdom-admins", - "deployed_submitter_admission_verified": false, - "human_approval": false, - "live_submitted": false, - "native_backup_restore_executed": false, - "native_workload_changed": false, - "packet_bytes_total": 171910, - "guard_tests": 11, - "guard_drift_negative_assertions": 28, - "transport_negative_cases": 6, - "fresh_readonly_preflight_all_checks_pass": true, - "fresh_readonly_capture": "2026-10-11T01:39:14Z", - "original_capture_bytes_preserved": true, - "pre_open_old_unknown_schema_negative_cases": 6, - "optimized_interpreter_negative_cases": 2, - "native_dependencies_checked": true, - "native_pre_open_schema_checked": false, - "original36path_snapshot_preserved": true, - "refinement_same_proposal_trial": true, - "register_json_bytes": 238209, - "mechanical_helper_tests": 16, - "mechanical_review_manifest_sha256": "80fd16e0f5841b83a012ce195b28ebf5b0dad37c87d1efa5d8cbfd219a780824", - "helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c", - "execution_bundle_sha256": "27d6d6d3133c963da1dde92d498d636617387c16e850a17c598148abc35c775d", - "combined_source_negative_cases": [ - { - "case": "document-content-changed", - "refused": true - }, - { - "case": "helper-hash-changed", - "refused": true - }, - { - "case": "duplicate-document-identity", - "refused": true - }, - { - "case": "typed-source-bytes-changed", - "refused": true - }, - { - "case": "typed-duplicate-digest", - "refused": true - } + "version2_intake_refuses_as_required": true, + "submission_route": "POST /lifecycle/memos/infd-20261011-purpose-overlay-r1/revisions", + "expected_source_version": 1, + "source_must_be_unbound": true, + "typed_memo_documents_valid": 20, + "memo_version": 2, + "revision_command_digest": "sha256:ccbeca292dd4ffcd0ed8a4669c82a93f9b773a30186966d3f146d5db8e5e6b8a", + "packet_bytes_total": 173469, + "revision_json_bytes": 240451, + "negative_packet_cases_refused": [ + "helpercontentchanged", + "digestchanged", + "duplicatedigest" ], - "original78path_snapshot_preserved": true, - "actual_provider_probe": false, - "source_hash_negative_refusals_before_authority_or_dispatch": 4, - "source_boundary_receipt_sha256": "877f93485c1a6817bdfde257051f202d33e14f0ee54e03e597043c8924723337" + "executor_tests": 21, + "snapshot_mock_tests": 5, + "original_native_backup_completed": true, + "original_copy_uncertain_retained": true, + "original_approval_is_version1_only": true, + "new_version2_human_approval": false, + "version2_native_actions": false, + "live_submitted_version2": false, + "original_actual_image_source_and_scan_unchanged": true, + "same_proposal_trial": true } diff --git a/docs/evidence/2026-10-11-purpose-provider-probe/README.md b/docs/evidence/2026-10-11-purpose-provider-probe/README.md new file mode 100644 index 0000000..5f68ab0 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-provider-probe/README.md @@ -0,0 +1,77 @@ +# Provider-derived lifecycle denial mechanism probe — SOURCE ONLY + +Work item INFD-WP-ADHOC-2026-10-11-T06. This newly prepared probe has not been +run against the estate and changes neither the posted frozen112/helper bundle +nor its decision memo. Ten synthetic source tests pass; they access no actual +provider, runtime configuration, caller token, native DB or data. + +## Truthful contract and scope + +Actual Access Engine examples/informed-decision-lifecycle/policy.md atv2 supports +collection listing as lifecycle.search, not lifecycle.list. It admits only +net-kingdom-admins KeyCape AAL2 humans or separately TokenReview-authenticated +system:serviceaccount:state-hub:state-hub. The actual Informed Decision consumer +ServiceAccount is review; its independent PDP caller uses the existing projected +flex-auth token. This probe submits its own truthful subject +system:serviceaccount:informed-decision:review, type service, tenant platform, +empty attributes. It claims no authentication_audience, workload_uid, human +assurance, roles, groups or imported tenant provenance. It does not impersonate +StateHub or a human to turn an expected denial into allowance. + +The request is fixed lifecycle.search of the decision collection, with no content +query/DB retrieval, record mutation or approval/act effect. Only one POST/v1/check +is sent; that provider may retain ordinary decision telemetry, so the probe is +not globally side-effect free. Installed PolicyClient must accept a canonical, +properly bound/pinned genuine DENY; ALLOW, caller refusal, unavailability, malformed +binding/purpose, wrong pin or identity are failure, not completed proof. This +establishes provider-derived denial/binding consumption and transformation +refusals. It cannot establish an authorized native lifecycle request, real human +MFA, provider-emitted advisory behavior, complete emission or T04 completion. + +## Source and custody gates for future execution + +Root must freshly verify the existing native Pod/deployment/SA chain at namespace +informed-decision, expected serviceAccountName review, admitted UID/template, +immutable candidate763c and runtimeConfigMap6c/policyv2 pins. The script refuses +UID/GID other than10001, optimized interpreter, wrong installed module9d7 hash/ +root ownership/mode0644, wrong private runtime config ownership/mode0600/size, +or any lifecycle config/pin/token-path drift. It reads only the existing private +/run/informed-decision/private/runtime.json and fixed projected policy caller +file INSIDE the Pod. Root must never export/decode/print that credential, read +Secret objects or substitute browser/requester custody. + +The actual response remains solely in Pod memory. Ten deep-copied local transport +fixtures alter only binding.purpose to readback, enforcement, unknown, null, +false, zero, list, object, true or whitespace. They require invalid_decision and +no retained decision_json. All original other fields remain unchanged; the +captured response itself remains unchanged. No second provider request is sent, +and these transformed copies are explicitly labelled fixtures. A test result +must never imply the real provider actually emitted an advisory decision. + +No Store, Runtime, admin, dispatcher, lifecycle service or delivery worker is +constructed. The probe creates no SQLite record, queries no native DB, starts +no listener and changes no runtime image/config/credentials. Child exceptions, +provider bodies, request identity details, headers/config/token bytes and paths +are withheld; only a closed fixed boolean/count/version/effect metadata receipt +may reach the coordinator. Failure prints one fixed refusal and exits1. + +## Authority assessment + +The posted packet at owner commitbc6494 is unaccepted. Its frozen helper and +20 documents distinguish actual-provider acceptance as a later T04 gate, but +this additional exact source and its one native provider call are not part of +that hash-bound execution bundle. Do not treat owner technical review, public +source publication, a PENDING template or generic installed verification as +approval to execute this new probe. Root must retain a separately scoped exact +founder go naming probe digest, Pod/SA/caller/readonly action, telemetry effect, +expected denial/ten transformed fixtures and receipt limits before execution. +If executing after an earlier packet acceptance, record this as separate exact +verification authorization; never mutate accepted memo bytes or backfill it. +The owner can prepare this reversible source without that future live authority. + +A successful real invocation gives a bounded provider-derived denial mechanism +receipt only. T04 still needs actual authorized native lifecycle/binding +preservation through an already authenticated admitted caller or real human, +with existing subject/assurance evidence. If that evidence/route is unavailable, +report the gate, preserve truthful denial and do not invent claims or score it +closed. This preparation creates no new grant, credential route or native allow. diff --git a/docs/evidence/2026-10-11-purpose-provider-probe/probe.py b/docs/evidence/2026-10-11-purpose-provider-probe/probe.py new file mode 100644 index 0000000..036ca82 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-provider-probe/probe.py @@ -0,0 +1,145 @@ +"""Unexecuted exact readonly provider-derived denial mechanism probe. + +Run only inside the existing admitted Pod after exact separate founder go. +Never constructs Store/Runtime/admin or starts delivery/approval/lifecycle effects. +""" +import copy +import hashlib +import json +import os +from pathlib import Path +import stat +import sys +import uuid + +from informed_decision.http_transport import JSONTransport +from informed_decision.policy import PolicyClient + +POLICY_SHA = "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62" +CONFIG = Path("/run/informed-decision/private/runtime.json") +PIN = {"origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080", + "package": "informed-decision.lifecycle", "version": "v2", + "package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c", + "caller_token_file": "/var/run/secrets/informed-decision/policy/token"} +BAD_PURPOSES = ("readback", "enforcement", "unknown", None, False, 0, [], {}, True, " ") + + +def require(value): + if not value: + raise ValueError("provider mechanism proof refused") + + +def request(): + # This truthful service is NOT the separately authenticated StateHub lifecycle + # principal. Empty attributes claim no human/group/role/assurance/provenance. + command = json.dumps({"query": "", "limit": 1}, sort_keys=True, separators=(",", ":")) + return {"id": str(uuid.uuid4()), "tenant": "tenant:platform", + "subject": {"id": "system:serviceaccount:informed-decision:review", + "type": "service", "tenant": "tenant:platform", "attributes": {}}, + "action": "lifecycle.search", + "resource": {"id": "decisions", "type": "decision-collection", + "system": "informed-decision", "tenant": "tenant:platform"}, + "context": {"contract": "informed-decision.lifecycle.v1", "memo_version": None, + "record": {"registered": False}, + "command_digest": "sha256:" + hashlib.sha256(command.encode()).hexdigest()}, + "policy_version": "v2"} + + +class Capture: + def __init__(self, real): + self.real, self.calls, self.captured = real, 0, None + + def request(self, method, url, *, headers=None, body=None): + require(self.calls == 0 and method == "POST" and url == PIN["origin"] + "/v1/check") + self.calls += 1 + status, data = self.real.request(method, url, headers=headers, body=body) + require(status == 200 and isinstance(data, dict)) + self.captured = copy.deepcopy(data) # Pod memory only; no raw evidence export. + return status, data + + +class TransformedCopy: + def __init__(self, captured, purpose): + self.captured, self.purpose, self.calls = captured, purpose, 0 + + def request(self, method, url, *, headers=None, body=None): + # No network/provider call here. This is labelled transformed fixture data. + self.calls += 1 + value = copy.deepcopy(self.captured) + value["binding"]["purpose"] = self.purpose + return 200, value + + +def prove(token_provider, transport): + capture = Capture(transport) + args = {key: PIN[key] for key in ("package", "version", "package_digest")} + client = PolicyClient(PIN["origin"], token_provider, transport=capture, + allow_internal_http=True, **args) + req = request() + baseline = client.check(req) + # Expected genuine DENY: this consumer service is not the initial audience. + # Unavailable/auth failure/malformed response/allow are not successful proof. + require(capture.calls == 1 and baseline.outcome == "policy_denied" + and baseline.decision_json is not None and capture.captured is not None) + require(capture.captured["effect"] == "deny" + and type(capture.captured["binding"].get("purpose", "")) is str + and capture.captured["binding"].get("purpose", "") == "") + before = copy.deepcopy(capture.captured) + refused = 0 + for purpose in BAD_PURPOSES: + fixture = TransformedCopy(capture.captured, purpose) + # No credential needed for these isolated transport copies. PolicyClient + # requires a nonempty caller string; this value never leaves this function. + isolated = PolicyClient(PIN["origin"], lambda: "transformed-fixture-only", + transport=fixture, allow_internal_http=True, **args) + observed = isolated.check(req) + require(fixture.calls == 1 and observed.outcome == "invalid_decision" + and observed.decision_json is None) + refused += 1 + require(capture.captured == before and capture.calls == 1 and refused == 10) + return {"kind": "informed-decision.provider-derived-denial-mechanism-proof", + "all_checks_pass": True, "actual_provider_calls": 1, + "actual_provider_effect": "deny", "canonical_binding_validated": True, + "package": PIN["package"], "version": PIN["version"], + "request_action": "lifecycle.search", "truthful_service_subject": True, + "human_or_statehub_impersonation": False, "provider_allow_proven": False, + "transformed_noncanonical_purposes_refused": refused, + "transformed_fixture_copies_only": True, + "provider_emitted_advisory_proven": False, + "database_or_act_effect": False, "credential_or_raw_response_output": False, + "full_T04_native_lifecycle_acceptance": False} + + +def main(): + require(not sys.flags.optimize and os.getuid() == 10001 and os.getgid() == 10001) + import informed_decision.policy as installed + module = Path(installed.__file__) + info = module.lstat() + require(stat.S_ISREG(info.st_mode) and info.st_uid == 0 + and stat.S_IMODE(info.st_mode) == 0o644 + and hashlib.sha256(module.read_bytes()).hexdigest() == POLICY_SHA) + info = CONFIG.lstat() + require(stat.S_ISREG(info.st_mode) and info.st_uid == 10001 and info.st_nlink == 1 + and stat.S_IMODE(info.st_mode) == 0o600 and 0 < info.st_size <= 16384) + config = json.loads(CONFIG.read_text()) + require(config.get("schema") == "informed-decision.review-runtime.v1" + and config.get("lifecycle_policy") == PIN) + def token(): + # Reopen existing projected caller custody inside Pod only. Never print, + # export/decode/cache it or use a human/requester credential instead. + with Path(PIN["caller_token_file"]).open("rb") as stream: + raw = stream.read(32769) + require(0 < len(raw) <= 32768) + return raw.decode("ascii").strip() + receipt = prove(token, JSONTransport(allow_internal_http=True)) + print(json.dumps(receipt, sort_keys=True)) + + +if __name__ == "__main__": + try: + main() + except BaseException: + # Fixed failure only. Raw exception, transport/header/config/body/token + # are never surfaced. No fallback identity, effect retry or DB write. + print('{"kind":"informed-decision.provider-derived-denial-mechanism-proof","all_checks_pass":false,"raw_output_withheld":true}') + raise SystemExit(1) from None diff --git a/docs/evidence/2026-10-11-purpose-provider-probe/test_probe.py b/docs/evidence/2026-10-11-purpose-provider-probe/test_probe.py new file mode 100644 index 0000000..36c7298 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-provider-probe/test_probe.py @@ -0,0 +1,59 @@ +"""Synthetic source negatives only; never calls real provider or credentials.""" +import copy +import json +import pytest +import probe +from test_policy_client import envelope + + +class Fixture: + def __init__(self, defect=None): + self.calls = 0 + self.defect = defect + def request(self, method, url, *, headers=None, body=None): + self.calls += 1 + req = json.loads(body) + data = envelope(req) + data["effect"] = "deny" + data["matched_policy_version"] = "v2" + data["provenance"].update(policy_package=probe.PIN["package"], policy_version="v2", + policy_package_digest=probe.PIN["package_digest"]) + if self.defect == "allow": data["effect"] = "allow" + elif self.defect == "wrong-pin": data["provenance"]["policy_package_digest"] = "sha256:" + "0" * 64 + elif self.defect == "advisory": data["binding"]["purpose"] = "readback" + elif self.defect == "wrong-subject": data["binding"]["subject"]["id"] = "someone-else" + elif self.defect == "bad-purpose": data["binding"]["purpose"] = False + return (403 if self.defect == "auth-refusal" else 503 if self.defect == "unavailable" else 200), data + + +def test_truthful_service_uses_supported_collection_search_with_no_imported_claims(): + request = probe.request() + assert request["subject"]["id"] == "system:serviceaccount:informed-decision:review" + assert request["subject"]["type"] == "service" + assert request["subject"]["attributes"] == {} + assert request["action"] == "lifecycle.search" + assert request["resource"]["type"] == "decision-collection" + + +def test_one_captured_denial_and_ten_in_memory_copies_have_closed_metadata(): + transport = Fixture() + receipt = probe.prove(lambda: "synthetic-secret-sentinel", transport) + assert transport.calls == 1 + assert receipt["transformed_noncanonical_purposes_refused"] == 10 + assert receipt["actual_provider_effect"] == "deny" + assert receipt["provider_allow_proven"] is False + assert receipt["provider_emitted_advisory_proven"] is False + assert receipt["full_T04_native_lifecycle_acceptance"] is False + assert "synthetic-secret-sentinel" not in json.dumps(receipt) + + +@pytest.mark.parametrize("defect", ["allow", "wrong-pin", "advisory", "wrong-subject", "bad-purpose", "auth-refusal", "unavailable"]) +def test_unknown_or_incorrect_baseline_refuses_without_additional_network(defect): + transport = Fixture(defect) + with pytest.raises(ValueError): + probe.prove(lambda: "synthetic-secret-sentinel", transport) + assert transport.calls == 1 + + +def test_request_identity_changes_between_probes(): + assert probe.request()["id"] != probe.request()["id"] diff --git a/docs/evidence/2026-10-11-purpose-provider-probe/validation.json b/docs/evidence/2026-10-11-purpose-provider-probe/validation.json new file mode 100644 index 0000000..6cda6b4 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-provider-probe/validation.json @@ -0,0 +1,17 @@ +{ + "work_item": "INFD-WP-ADHOC-2026-10-11-T06", + "status": "source-prepared-unexecuted", + "source_tests": 10, + "result": "passed", + "elapsed_seconds": 0.18, + "synthetic_transport_only": true, + "actual_provider_calls": 0, + "native_runtime_or_token_read": false, + "native_database_or_act_effect": false, + "new_helper_in_frozen112_bundle": false, + "separate_exact_founder_go_required_before_native_probe": true, + "expected_actual_provider_outcome": "canonical bound deny for truthful consumer service", + "actual_native_allow_proven": false, + "full_T04_native_acceptance": false, + "probe_sha256": "3f91b6a17f3e2c7047020c504d5426aab0cbcb8fc6326f8a29d9046227eeab1f" +} diff --git a/docs/evidence/2026-10-11-purpose-rescue-product-review/final-validation.json b/docs/evidence/2026-10-11-purpose-rescue-product-review/final-validation.json new file mode 100644 index 0000000..8a8a19b --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-rescue-product-review/final-validation.json @@ -0,0 +1,23 @@ +{ + "work_item": "INFD-WP-ADHOC-2026-10-11-T07", + "initial_reviewed_manifest_sha256": "0867e27a6754dddff3eedbb333ab4ca4faa98ee31d383ebe940b8e054c6cabf7", + "amended_manifest_sha256": "d05d6e3b15df9acf1d7aef0ba2ec82a5a00d979ab1f324e981025cffe2cc753d", + "paths": 134, + "all_hashes_verified": true, + "only_proposal_semantic_change": "current old-helper label renamed original with historical context", + "helper_bundle_unchanged": true, + "plan_unchanged": true, + "strict_typed_source_version": 2, + "source_CAS_expected_version": 1, + "native_human_review_own_version": 1, + "documents": 20, + "packet_bytes": 173469, + "revision_bytes": 240451, + "scope_mutations_refused": 8, + "packet_mutations_refused": 3, + "prior_mock_tests_repeated": false, + "original_complete_backup_uncertain_copy_retained": true, + "native_commands_or_DB_opens": false, + "version2_acceptance_or_execution": false, + "decision": "approved-source-only" +} diff --git a/docs/evidence/2026-10-11-purpose-rescue-product-review/initial66-scope-fixture.json b/docs/evidence/2026-10-11-purpose-rescue-product-review/initial66-scope-fixture.json new file mode 100644 index 0000000..530e730 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-rescue-product-review/initial66-scope-fixture.json @@ -0,0 +1,130 @@ +{ + "initial_reviewed_manifest_sha256": "0867e27a6754dddff3eedbb333ab4ca4faa98ee31d383ebe940b8e054c6cabf7", + "proposal": { + "memo_version": 2, + "execution_phases": [ + "drill-copy-rescue-r1", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "recovery": { + "original_anchor": { + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false + }, + "original_identity": { + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "memo_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937", + "plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + "new_journal": "rescue-execution-journal-r1.json", + "new_phase": "drill-copy-rescue-r1", + "old_uncertain_phase_overwrite_or_retry": false, + "new_snapshot_backup": false, + "snapshot_or_sidecar_mutation": false, + "mapping": "offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal" + }, + "sync_scope": [ + "apps:Deployment:informed-decision" + ], + "prune": false, + "automated_sync": false, + "schema": 5, + "runtime_configmap": "informed-decision-runtime-6c221878d051", + "approved_owner_render_blob_sha256": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "execute_by": "2026-10-12T23:59:59Z", + "execution_helper_manifest_sha256": "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c" + }, + "plan": { + "source_memo_version": 2, + "native_review_memo_version": 1, + "phases": [ + "drill-copy-rescue-r1", + "offline-verify", + "cleanup-offline", + "cutover-backup", + "cutover-copy", + "release", + "verify", + "rollback", + "rollback-verify" + ], + "recovery": { + "original_anchor": { + "original_journal_sha256": "d187b02d98d6e97429fe20b4fbe1d309a6c6c4b55232b4ae13ac39873039f1c1", + "phase_metadata": { + "drill-backup": { + "state": "COMPLETE", + "attempt_id": "d63182a7-e1a5-4e8e-a5f1-2bf3333cf153", + "started_at": "2026-10-11T02:38:45.310653+00:00" + }, + "drill-copy": { + "state": "UNCERTAIN", + "attempt_id": "329ef190-1692-4246-b953-e6a59664abcc", + "started_at": "2026-10-11T02:39:50.198740+00:00" + } + }, + "frozen_backup_receipt_sha256": "025dddf1e93936f31e98b9fbfa84aa2bdaaa33573f9d3b0e32d947fd286b170e", + "snapshot_sha256": "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3", + "snapshot_bytes": 19537920, + "off_cluster_file_exists": false, + "old_uncertain_retry_authorized": false + }, + "original_identity": { + "proposal": "INFD-WP-0009-T04/purpose-overlay-v1", + "source_revision": "bc6494cd1b290783ef3aef0763bf28d1deabf4b0", + "memo_sha256": "506d3956beb7c62ab2bbdfda783c05905d183452a1f67a1817f3fb8c2e522937", + "plan_sha256": "f5e5fa906ff19d3a45d10dcdb2810373ae21f9cf44c0472ff2bd47d3bc3328d6" + }, + "new_journal": "rescue-execution-journal-r1.json", + "new_phase": "drill-copy-rescue-r1", + "old_uncertain_phase_overwrite_or_retry": false, + "new_snapshot_backup": false, + "snapshot_or_sidecar_mutation": false, + "mapping": "offline-verify consumes COMPLETE drill-copy-rescue-r1 result; all later phases ordered only in new hash-linked recovery journal" + }, + "owner_source_files": { + "deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55", + "deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4", + "deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47", + "deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e" + }, + "execute_by": "2026-10-12T23:59:59Z" + }, + "revision": { + "memo": { + "version": 2, + "approval_id": null, + "approval_binding_digest": null + }, + "expected_version": 1 + } +} diff --git a/docs/evidence/2026-10-11-purpose-rescue-product-review/scope_guard.py b/docs/evidence/2026-10-11-purpose-rescue-product-review/scope_guard.py new file mode 100644 index 0000000..886be09 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-rescue-product-review/scope_guard.py @@ -0,0 +1,39 @@ +"""Product review guard of proposed recovery metadata; no native or DB access.""" +PHASES = ["drill-copy-rescue-r1", "offline-verify", "cleanup-offline", "cutover-backup", + "cutover-copy", "release", "verify", "rollback", "rollback-verify"] +RENDER = {"deploy/lifecycle/admission.candidate.json", "deploy/lifecycle/service.candidate.json", + "deploy/lifecycle/kustomization.yaml", "deploy/lifecycle/registries.candidate.json"} + + +def check_scope(proposal, plan, revision): + def require(value): + if not value: raise ValueError("product recovery scope refused") + require(proposal["memo_version"] == plan["source_memo_version"] == revision["memo"]["version"] == 2) + require(type(revision["expected_version"]) is int and revision["expected_version"] == 1) + require(plan["native_review_memo_version"] == 1 and revision["memo"]["approval_id"] is None + and revision["memo"]["approval_binding_digest"] is None) + require(proposal["execution_phases"] == plan["phases"] == PHASES) + require(proposal["recovery"] == plan["recovery"]) + recovery = plan["recovery"] + require(recovery["new_journal"] == "rescue-execution-journal-r1.json" + and recovery["new_phase"] == "drill-copy-rescue-r1" + and recovery["old_uncertain_phase_overwrite_or_retry"] is False + and recovery["new_snapshot_backup"] is False + and recovery["snapshot_or_sidecar_mutation"] is False) + anchor = recovery["original_anchor"] + require(anchor["old_uncertain_retry_authorized"] is False + and anchor["snapshot_sha256"] == "8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3" + and anchor["snapshot_bytes"] == 19537920) + require(anchor["phase_metadata"]["drill-backup"]["state"] == "COMPLETE" + and anchor["phase_metadata"]["drill-copy"]["state"] == "UNCERTAIN") + require(proposal["sync_scope"] == ["apps:Deployment:informed-decision"] + and proposal["prune"] is False and proposal["automated_sync"] is False + and proposal["schema"] == 5 and proposal["runtime_configmap"] == "informed-decision-runtime-6c221878d051") + require(set(plan["owner_source_files"]) == RENDER + and proposal["approved_owner_render_blob_sha256"] == plan["owner_source_files"]) + require(proposal["execute_by"] == plan["execute_by"] == "2026-10-12T23:59:59Z") + # The old helper manifest is historical provenance, not the current v2 freeze. + require("execution_helper_manifest_sha256" not in proposal + and proposal["original_execution_helper_manifest_sha256"] == + "f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c") + return True diff --git a/docs/evidence/2026-10-11-purpose-rescue-product-review/test_scope_guard.py b/docs/evidence/2026-10-11-purpose-rescue-product-review/test_scope_guard.py new file mode 100644 index 0000000..1d3b503 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-rescue-product-review/test_scope_guard.py @@ -0,0 +1,37 @@ +import copy,json +from pathlib import Path +import pytest +from scope_guard import check_scope +ROOT=Path(__file__).parent + + +def data(normalize=True): + fixture=json.loads((ROOT/"initial66-scope-fixture.json").read_text()) + proposal,plan,revision=(fixture[name] for name in ("proposal","plan","revision")) + # Normalized fixture only; owner packet bytes are not edited by this reviewer. + if normalize: + proposal["original_execution_helper_manifest_sha256"]=proposal.pop("execution_helper_manifest_sha256") + return proposal,plan,revision + + +def test_actual_initial66_packet_refuses_stale_current_helper_provenance(): + with pytest.raises(ValueError):check_scope(*data(False)) + + +def test_other_scope_gates_pass_in_explicit_normalized_fixture(): + assert check_scope(*data()) + + +@pytest.mark.parametrize("fault",["old-retry","new-drill-backup","sidecar-write","whole-app-sync", + "old-CAS","review-v2","render-drift","expiry-drift"]) +def test_semantic_scope_changes_refuse(fault): + p,plan,r=data() + if fault=="old-retry":plan["recovery"]["old_uncertain_phase_overwrite_or_retry"]=True + elif fault=="new-drill-backup":plan["recovery"]["new_snapshot_backup"]=True + elif fault=="sidecar-write":plan["recovery"]["snapshot_or_sidecar_mutation"]=True + elif fault=="whole-app-sync":p["sync_scope"]=["*"] + elif fault=="old-CAS":r["expected_version"]=2 + elif fault=="review-v2":plan["native_review_memo_version"]=2 + elif fault=="render-drift":plan["owner_source_files"]["deploy/lifecycle/kustomization.yaml"]="0"*64 + elif fault=="expiry-drift":plan["execute_by"]="2026-10-13T23:59:59Z" + with pytest.raises(ValueError):check_scope(p,plan,r) diff --git a/docs/evidence/2026-10-11-purpose-rescue-product-review/validation.json b/docs/evidence/2026-10-11-purpose-rescue-product-review/validation.json new file mode 100644 index 0000000..61d2c73 --- /dev/null +++ b/docs/evidence/2026-10-11-purpose-rescue-product-review/validation.json @@ -0,0 +1,16 @@ +{ + "work_item": "INFD-WP-ADHOC-2026-10-11-T07", + "reviewed_manifest_sha256": "0867e27a6754dddff3eedbb333ab4ca4faa98ee31d383ebe940b8e054c6cabf7", + "paths": 66, + "all_file_hashes_pass": true, + "independent_existing_source_mock_tests": 26, + "independent_existing_subtests": 41, + "product_scope_tests": 10, + "product_mutation_negative_cases": 8, + "actual_initial_packet_stale_helper_label_refused": true, + "fixture_normalization_only": true, + "review_decision": "changes_requested", + "native_commands_or_database_opens": false, + "version2_acceptance": false, + "version2_execution": false +} diff --git a/docs/reviews/2026-10-11-purpose-rescue-product-owner-final-ack.md b/docs/reviews/2026-10-11-purpose-rescue-product-owner-final-ack.md new file mode 100644 index 0000000..e70e269 --- /dev/null +++ b/docs/reviews/2026-10-11-purpose-rescue-product-owner-final-ack.md @@ -0,0 +1,67 @@ +# Exact amended rescue packet product-owner confirmation + +```yaml +reviewer: informed-decision-owner (agent informed-decision, codex) +decision: approved +work_item: INFD-WP-ADHOC-2026-10-11-T07 +scope: exact amended rescue source packet technical agreement only +comment: >- + INTENT.md Purpose/What informed-decision Owns and Design Principles9-10 require + preserved evidence, exact provenance and human binding. Same T07 trial now + confirms amended134-path manifest SHA256 + d05d6e3b15df9acf1d7aef0ba2ec82a5a00d979ab1f324e981025cffe2cc753d after the + single historical helper-label correction. Initial66 changes-requested review + remains preserved, not rewritten as prior success. This is source agreement, + not founder acceptance, new phase authority or native execution. +``` + +All134 staged file hashes verify. Actual original-to-amended proposal diff is +only removal of execution_helper_manifest_sha256 and addition of +original_execution_helper_manifest_sha256 plus explicit historical context. +The oldf2fad manifest now clearly identifies historical helper review before +version2 rescue. Dependent memo/revision/doc hashes are correctly refreshed. +Initial66 source is immutable in initial-rescue-0867e27a; initial product review +and frozen guard fixture retain the original finding. Code and current bundle +49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5 and plan +9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258 are unchanged. +No execution scope or original backup/failure outcome changed with this correction. + +Exact amended memo SHA256: +`391330d062ede170a546415886d18b4895ba24d313a0dd50dcc1591c1aa3c2fa`. +Revision command digest: +`sha256:ccbeca292dd4ffcd0ed8a4669c82a93f9b773a30186966d3f146d5db8e5e6b8a`. +Strict typed decode validates source memo version2, unbound state and twenty +hash-bound documents; packet173469bytes/compact revision240451bytes independently +counted. Existing source must remain unbound1 for revisions CAS1. Human review +is a newly created distinct review memo with its own version1 and requires new +confirmed founder acceptance through outcomes?version=2. Old version1 acceptance +is historical authority for old source only, never new helper bytes. + +The corrected actual packet passes product scope guard without fixture normalization. +Eight independent semantic mutations refuse: old phase retry, new drill backup, +sidecar mutation, whole-app sync, wrong source CAS, review-own-version2, render +drift and expiry drift. Three typed packet mutations refuse: changed content, +changed digest and duplicate digest. Prior26 mocked tests/41 subtests remain +applicable because code is unchanged; they were not needlessly repeated. +These are source-only checks with no native command or DB open. + +Original COMPLETE drill-backup and UNCERTAIN drill-copy stay immutable. Distinct +new rescue phase/journal use exact original snapshot/journal hashes and absent +local outputs; no original phase retry, overwrite, deletion or second drill backup. +Immutable inspection is limited to proven frozen closed-main snapshots with +zero/absent WAL, private custody, no writer and unchanged retained sidecars. +Live/writable-clone readers remain WAL-aware and explicitly close. Rescued local +copy feeds ordered offline pre/admin/post verification, cleanup, distinct cutover +backup/copy and only then conditional Deployment-only image release/verification. +Failed-candidate rollback remains independent of its readiness/DB execution, +with separate old-image Ready/scoped operation/current schema5 proof. Latest DB, +all new/uncertain evidence and all original sidecars remain retained. + +Image763c/config6c/schema5/PVC/identity/policy/audience/four render pins and all-phase +start expiry remain fixed. Source plan/case/executor hashes bind the new exact +source; fresh independently authenticated root founder disposition remains required +before every phase. Installed ten synthetic purpose forms/native_provider=false +remain separate from actual provider/authorized lifecycle acceptance. Inherited +fixable MEDIUM/T05 follow-through remains visible, not accepted by agent review. +T04 stays progress. No version2 native action or new founder disposition occurred. +The initial product correction is satisfied only by this exact amended freeze. diff --git a/docs/reviews/2026-10-11-purpose-rescue-product-owner-review.md b/docs/reviews/2026-10-11-purpose-rescue-product-owner-review.md new file mode 100644 index 0000000..dd38f16 --- /dev/null +++ b/docs/reviews/2026-10-11-purpose-rescue-product-owner-review.md @@ -0,0 +1,75 @@ +# Informed Decision existing-snapshot rescue product-owner review + +```yaml +reviewer: informed-decision-owner (agent informed-decision, codex) +decision: changes_requested +work_item: INFD-WP-ADHOC-2026-10-11-T07 +scope: exact version2 rescue source and packet only +comment: >- + INTENT.md Purpose/What informed-decision Owns require preserved decision evidence; + Design Principles9-10 reserve identity/human binding. Reviewed exact66-path + manifest0867e27a6754dddff3eedbb333ab4ca4faa98ee31d383ebe940b8e054c6cabf7 under + INFD-WP-ADHOC-2026-10-11-T07. Source recovery boundaries agree, but the changed + packet must label its old helper manifest as historical before exact final + packet source acknowledgement and new human acceptance. +``` + +Required correction: proposal.json still labels f2fad6c251fbb4420e07c1329802f521b513bbf66e51f64c5d673ef04f16284c +as execution_helper_manifest_sha256. That digest identifies the unchanged +historical23-path helper, not this changed version2 rescue source. Rename the +field original_execution_helper_manifest_sha256 or explicitly mark it historical; +refreeze proposal/document/memo/revision/bundle hashes consistently. Current +bundle49c9cb70f36f6ceb7b0d22400b2ec9232a5e1a8a00d17e92b92fe367c98effb5 and +plan9ce5728a561e6d38f8497201baa2b840d11444a0af8ad6234dfc37428113f258 are +otherwise bound. A stale current-source label weakens the exact human review +provenance even when execution separately checks the correct plan bytes. + +All66 staged hashes verify. Independently rerun26 existing mocked/source tests +and41 subtests pass;10 new source scope tests include the real initial label +refusal, an explicitly normalized fixture and eight negative scope mutations +(old retry, new drill backup, sidecar write, whole-app sync, incorrect source CAS, +review-own-version2, render drift and expiry drift). The fixture normalization is +not an owner packet edit. No native command or DB open occurred; checker tests +mock SQLite connections and do not establish real native snapshot compatibility. + +Original protected drill-backup is COMPLETE; original drill-copy is UNCERTAIN +before local file creation. Recorded main snapshot19537920bytes/SHA8756cf825df9e7b5b74bb4a0106a5027f5cff2c59ff45d7b48eed8522a7d33f3, +zero WAL and private stale SHM remain retained. New rescue journal/lock/phase +hash-link the original identity, outcomes and attempt IDs without rewriting or +retrying the failed original phase. Absent local destinations and restore volume, +exact old-image/source/Pod/Deployment/CM/PVC custody and frozen snapshot hashes +bound rescue. Failure remains durable and same-phase retry is refused. + +The corrected SQLite reader explicitly closes connections. Immutable reads are +only for previously created closed-main snapshots with proven no writer, +absent/zero WAL, exact frozen digest/private identity and unchanged sidecars before/ +after inspection. No sidecar deletion or checkpoint occurs. Live source and +writable offline clone remain WAL-aware mode=ro/query_only; immutable mode cannot +hide live WAL frames, substitute for schema5 or bypass admin migration guards. +Frozen snapshot/clone equality differs from legitimate concurrent live commits. + +Offline checks consume only COMPLETE drill-copy-rescue-r1 result. Confined new +volume UID0/CAP_CHOWN initialization and UID10001 pre-open/admin/post-open proof, +original snapshot retention, distinct cutover-backup/copy and conditional manual +Argo Deployment-only image release/verification remain ordered in the new journal. +Rollback dispatch remains independent of failed candidate readiness/DB execution; +rollback-verify separately proves oldimage Ready/scoped succeeded operation/current +retained schema5/integrity/counts. No older snapshot overwrites newer evidence. +All phase starts including recovery are bounded byOct12 23:59:59Z; recovery-delay +risk after expiry remains explicit. Four renderer inputs and source/hash gates, +image763c/config6c/schema5/PVC/identity/policy/audience scope remain unchanged. + +Actual lifecycle code requires new unbound source version2 through revisions CAS1; +register(version2) correctly fails. Version-specific review preparation creates a +new review memo with its own version1. Root must authenticate outcomes?version=2 +and the new confirmed human acceptance before every phase; an old version1 +acceptance cannot authorize changed helper bytes. Bookkeeping is not authenticated +human identity or autonomous permission. Historical source/acceptance/backup/failure +are retained in the same trial, never backfilled or counted as another success. + +Full scan/base/SBOM provenance and known inherited fixable MEDIUM/T05 follow-through +remain visible. Installed ten synthetic purpose forms keep native_provider=false; +actual-provider/authorized lifecycle acceptance remains a separate T04 gate. +No new acceptance/submission or version2 native action occurred. This entry +records only informed-decision-owner judgement; it authorizes no live action, +credential use, human disposition, risk acceptance or T04 closure. diff --git a/workplans/ADHOC-2026-10-11.md b/workplans/ADHOC-2026-10-11.md index 5974053..436838f 100644 --- a/workplans/ADHOC-2026-10-11.md +++ b/workplans/ADHOC-2026-10-11.md @@ -150,3 +150,65 @@ Exact combined packet acknowledgement remains a separate review gate. Review: docs/reviews/2026-10-11-purpose-actuator-product-owner-review.md. No native reads/backups/export/restore/release, credentials, human disposition, founder approval or phase authority was exercised by this review. + +## Prepare separately gated provider-derived denial mechanism probe + +```task +id: INFD-WP-ADHOC-2026-10-11-T06 +status: done +priority: medium +``` + +Prepared source-only readonly lifecycle.search provider-derived mechanism probe +with truthful informed-decision/review SERVICE and no human/StateHub attributes. +Actual lifecyclev2 permits only StateHub workload or admitted AAL2 humans, so a +canonical real DENY is required; no claims are invented to obtain ALLOW. +One actual provider response will remain in Pod memory; ten transformed +noncanonical purpose copies test installed consumer refusal without further +provider calls, DB/admin or act effects. This is a denial/binding mechanism +proof candidate, not actual authorized lifecycle or full T04 acceptance. + +Source: docs/evidence/2026-10-11-purpose-provider-probe/. +Ten synthetic source tests pass; no actual provider, credential, runtime config, +DB, native data or live action was accessed. Posted frozen112 packet/helper +remain unchanged. Exact separate founder go for this newly prepared probe and +its target must precede any execution; current memo has no acceptance and this +new helper is not hash-bound in that submitted packet. T04 remains progress. + +## Review exact existing-snapshot rescue version2 preparation + +```task +id: INFD-WP-ADHOC-2026-10-11-T07 +status: done +priority: medium +``` + +Reviewed exact66-path rescue manifest0867e27a6754dddff3eedbb333ab4ca4faa98ee31d383ebe940b8e054c6cabf7 +under the same informed-decision-owner role. Actual original backupCOMPLETE/copy +UNCERTAIN are retained; new rescue journal/phase and sourceversion2/newreviewown1 +require fresh founder acceptance. Immutable reads are bounded to proven frozen +closed snapshots; live/offline writable-clone reads remain WAL-aware/explicitclose. +Independent existing26 mocked tests plus41 subtests pass, and10 new product scope +guards pass (including eight refusal mutations and a frozen initial packet check). +No native command, DB open, credentials or rescue operation occurred. + +Initial review decision changes_requested: proposal.json misleadingly names old +f2fad helper manifest as execution_helper_manifest_sha256 after helper bytes changed; +label it original/historical and refreeze all dependent packet hashes. Correct +current bundle/plan digests already exist. The normalized test fixture is not an +owner edit or approval. Initial review/failure must remain after correction; +exact amended confirmation is still required before newhuman submission/execution. + +Review: docs/reviews/2026-10-11-purpose-rescue-product-owner-review.md. +Evidence/checks: docs/evidence/2026-10-11-purpose-rescue-product-review/. +T04 remains progress; original version1 approval is not newversion2 authority. + +**Amended source confirmation, same T07 trial:** exact134-path manifest +`d05d6e3b15df9acf1d7aef0ba2ec82a5a00d979ab1f324e981025cffe2cc753d` +corrects only the historical helper provenance label and dependent packet hashes; +original66 source and initial changes-requested review remain retained. Current +helper code/bundle49c9/plan9ce5 are unchanged. Strict typed sourceversion2/CAS1 +and20documents validate:173469packetbytes/240451revisionbytes. Eight scope +mutations and three packet mutations independently refuse. Final technical +source acknowledgement approved; no new human acceptance or native rescue. +Confirmation: docs/reviews/2026-10-11-purpose-rescue-product-owner-final-ack.md.