Skip to content

feat(contracts): versioned schema validation + contract tests for webhooks#82

Closed
adm01-debug wants to merge 1 commit into
mainfrom
claude/webhook-contract-tests-swzNU
Closed

feat(contracts): versioned schema validation + contract tests for webhooks#82
adm01-debug wants to merge 1 commit into
mainfrom
claude/webhook-contract-tests-swzNU

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 22, 2026

Summary

Establishes a contract-testing framework for the ~80 Supabase Edge Functions and applies it end-to-end to the 3 webhook endpoints (product-webhook, webhook-inbound, webhook-dispatcher) with full v1/v2 path-based versioning.

This PR delivers Tier 0 (foundation) and Tier 1 (webhooks) from the rollout plan in docs/CONTRACT_TESTING.md. Tiers T2-T4 will follow in subsequent PRs using npm run generate:contract-stub.

Foundation (_shared/)

File What
version-dispatch.ts Path-based version resolver (/v1, /v2); defaults to v1. Correctly distinguishes the Supabase mount prefix /functions/v1 from the contract version suffix by taking the last /vN segment.
error-response.ts Dual error builders. V1 preserves the legacy {error, details} 400 shape byte-for-byte (n8n compat, with snapshot regression guard). V2 introduces RFC-7807-inspired {code, message, fields[]} at 422 with Content-Type: application/problem+json.
zod-validate.ts Adds parseBodyVersioned() alongside the unchanged parseBodyWithSchema(). Dispatches v1/v2 by path.

Webhooks (Tier 1)

Endpoint V1 (back-compat) V2 (new)
product-webhook Existing n8n shape preserved Required idempotency_key, required metadata.source, .strict(), response adds errors_by_sku
webhook-inbound First Zod schema (lenient passthrough, accepts existing publishers) Required request_id (UUID), required payload, .strict()
webhook-dispatcher Existing inline schema extracted to schemas.ts Required correlation_id (UUID), optional dispatch_options.{parallel, timeout_ms}, .strict(), response adds correlation_id

Each handler is now exported (export const handler) so unit tests can invoke it without binding a port. Deno.serve(handler) runs only when import.meta.main is true (production entry).

Test layers

  1. Deno unit tests (78 cases, all passing) — cover happy path, missing fields, wrong types, empty values, invalid enums/UUIDs, unknown keys (v2 strict), CORS preflight, auth failures, and version-aware response shape (X-Contract-Version-Served header). Sanitizers disabled per test via a small t() wrapper because supabase-js starts internal keep-alive timers.
  2. Node runner scripts/contract-testing.mjs (31 scenarios, all passing in simulate mode) — auto-discovers contract.json manifests and runs a v1/v2 matrix. Modes:
    • --simulate (default, no network, CI-safe)
    • --live (POST against deployment, verifies status + response shape)
    • --baseline (records SHA-256 of v1 responses to scripts/__contracts__/v1-baseline.json)
  3. Coverage gate scripts/check-contract-coverage.mjs — reports schema/test/manifest coverage per tier; fails CI on the webhook tier (T1), warn-only on the rest until T2-T4 land. Exceptions live in scripts/contract-exceptions.json (21 functions, mostly crons + diagnostics).
  4. Stub generator scripts/generate-contract-stub.mjs — scaffolds schemas.ts, index.test.ts and contract.json for a new function with npm run generate:contract-stub <name> [--v2].

NPM scripts added

test:contracts              # simulate mode (default)
test:contracts:live         # POST against deployed Supabase
test:contracts:baseline     # record v1 response hashes
test:contracts:verbose      # per-scenario log
test:contracts:deno         # all Deno unit tests for foundation + webhooks
check:contract-coverage     # report + gate (webhook tier)
check:contract-coverage:strict   # gate public tier too
generate:contract-stub      # scaffold new function contract

V1 anti-regression

  • error-response.test.ts includes a snapshot test pinning the {error, details} shape at HTTP 400 / application/json.
  • scripts/__contracts__/v1-baseline.json will accumulate SHA-256 of v1 responses per scenario (populated by --baseline mode). PRs altering v1 must add a breaking-v1 label.
  • The original parseBodyWithSchema helper is unchanged; the ~40 functions using it are not impacted.

Coverage report at HEAD

Tier WEBHOOK   3/3   ✅ all covered
Tier PUBLIC    0/9   (3 exempt, 6 warn-only — for T2)
Tier CRON     13/13  ✅ all exempt (cron jobs have no body)
Tier JWT       1/56  (5 exempt, 50 warn-only — for T4)

Hard fails: 0. Webhook tier is fully covered.

Test plan

  • npm run check:contract-coverage — passes, 0 hard fails
  • npm run test:contracts — 31/31 scenarios pass in simulate mode
  • deno test --allow-env --allow-net --allow-read supabase/functions/_shared/*.test.ts supabase/functions/{product-webhook,webhook-inbound,webhook-dispatcher}/index.test.ts78/78 pass
  • After deploy to staging: npm run test:contracts:live against staging — verify real 400/422 responses
  • After deploy to staging: npm run test:contracts:baseline and commit the resulting baseline JSON
  • Smoke n8n: send a real product webhook payload to confirm v1 byte-for-byte compatibility

Follow-up PRs

  • T2 — 13 public (verify_jwt=false) functions get v1 schemas + tests (use generate:contract-stub)
  • T3 — 12 crons (most are exempt — config in contract-exceptions.json)
  • T4 — ~52 JWT-protected functions, split by domain (ai, crm, mcp, secrets, etc.)

See docs/CONTRACT_TESTING.md for the full pattern and roadmap.

https://claude.ai/code/session_01TZcZo79a7Wwr4rUVtwyfB3


Generated by Claude Code


Summary by cubic

Adds path-based v1/v2 schema validation and a contract-testing framework for our webhooks, keeping v1 behavior stable while enabling stricter v2 contracts. This sets the foundation for rolling the pattern across all Edge Functions.

  • New Features

    • Framework: path-based version resolver (defaults to v1) and unified errors (v1 400 {error,details}; v2 422 application/problem+json with {code,message,fields[]}) via parseBodyVersioned().
    • Webhooks: versioned schemas applied to product-webhook, webhook-inbound, and webhook-dispatcher.
    • Testing + tooling: Deno unit tests, contract runner (--simulate|--live|--baseline), coverage gate for webhook tier, stub generator, and docs in docs/CONTRACT_TESTING.md.
    • Scripts: added test:contracts*, check:contract-coverage*, and generate:contract-stub in package.json.
  • Migration

    • No changes required for v1 clients; existing URLs keep working.
    • To adopt v2, call /functions/v1/<endpoint>/v2 and update payloads:
      • product-webhook: add idempotency_key and metadata.source; unknown keys rejected.
      • webhook-inbound: add request_id (UUID); strict envelope.
      • webhook-dispatcher: add correlation_id (UUID); optional dispatch_options.{parallel,timeout_ms}; response echoes correlation_id.
    • Post-deploy (optional): run npm run test:contracts:live and then npm run test:contracts:baseline to capture v1 baselines.

Written for commit 66783e3. Summary will update on new commits. Review in cubic

…test runner

Establishes a contract-testing framework for Supabase Edge Functions and
applies it to the 3 webhook endpoints (product-webhook, webhook-inbound,
webhook-dispatcher) with full v1/v2 versioning.

Foundation:
- _shared/version-dispatch.ts: path-based version resolver (/v1, /v2);
  defaults to v1 for back-compat. Distinguishes the Supabase mount prefix
  /functions/v1 from the contract version suffix.
- _shared/error-response.ts: dual error builders. V1 preserves the legacy
  {error, details} 400 shape byte-for-byte (n8n compat). V2 introduces
  RFC-7807-inspired {code, message, fields[]} at 422 with
  Content-Type: application/problem+json. Includes a snapshot regression
  guard test for V1.
- _shared/zod-validate.ts: adds parseBodyVersioned() alongside the unchanged
  parseBodyWithSchema(); dispatches v1/v2 by path.

Webhooks (T1):
- product-webhook: extracted handler; v1 keeps n8n shape; v2 adds required
  idempotency_key + metadata.source + strict() + errors_by_sku in response.
- webhook-inbound: introduces Zod validation (first time); v1 is lenient
  (passthrough); v2 requires request_id (uuid) + strict envelope.
- webhook-dispatcher: extracted schema to schemas.ts; v1 matches old inline
  BodySchema; v2 adds required correlation_id + dispatch_options (parallel,
  timeout_ms).

All 3 expose 'export const handler' so unit tests can invoke without binding
a port; Deno.serve runs only when import.meta.main is true (prod entry).

Test layers:
- Deno unit tests (78 cases) cover happy path, missing fields, wrong types,
  empty values, invalid enums/UUIDs, unknown keys (strict), CORS preflight,
  auth failure, and version-aware response shape. Sanitizers disabled per
  test via a small t() wrapper because supabase-js starts internal timers.
- Node runner scripts/contract-testing.mjs auto-discovers contract.json
  manifests and runs a 31-scenario v1/v2 matrix. Modes: --simulate (default,
  no network, CI-safe), --live (POST against deployment), --baseline
  (records v1 response hashes).
- scripts/check-contract-coverage.mjs reports schema/test/manifest coverage
  per tier and gates CI on the webhook tier. Exceptions live in
  scripts/contract-exceptions.json (21 functions, mostly crons + diagnostics).
- scripts/generate-contract-stub.mjs scaffolds schemas.ts, index.test.ts and
  contract.json for new functions — used by T2-T4 PRs.

npm scripts: test:contracts[:live|:baseline|:verbose|:deno],
check:contract-coverage[:strict], generate:contract-stub.

Docs: docs/CONTRACT_TESTING.md explains the pattern and the rollout plan
(T0 helpers + T1 webhooks land here; T2 13 public functions, T3 12 crons,
T4 ~52 JWT functions follow in subsequent PRs).

V1 anti-regression:
- error-response.test.ts pins the {error, details} shape with status 400
  and Content-Type application/json.
- scripts/__contracts__/v1-baseline.json records SHA-256 of v1 responses
  per scenario; PRs that change v1 must add label 'breaking-v1'.

https://claude.ai/code/session_01TZcZo79a7Wwr4rUVtwyfB3
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 22, 2026 2:49am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ebad9f69-e0f3-46a6-b244-aab961ad3a83

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/webhook-contract-tests-swzNU

Comment @coderabbitai help to get the list of available commands and usage tips.

@supabase
Copy link
Copy Markdown

supabase Bot commented May 22, 2026

Updates to Preview Branch (claude/webhook-contract-tests-swzNU) ↗︎

Deployments Status Updated
Database Fri, 22 May 2026 02:49:36 UTC
Services Fri, 22 May 2026 02:49:36 UTC
APIs Fri, 22 May 2026 02:49:36 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Fri, 22 May 2026 02:49:42 UTC
Migrations Fri, 22 May 2026 02:49:54 UTC
Seeding ⏸️ Fri, 22 May 2026 02:49:30 UTC
Edge Functions ⏸️ Fri, 22 May 2026 02:49:30 UTC

❌ Branch Error • Fri, 22 May 2026 02:49:55 UTC

ERROR: syntax error at or near "LS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tIEdJRlRTIFNUT1JFIC0gUkxTIENPTSBPUkdBTklaQVRJT05TIChNVUxUSS1URU5BTlQpCi0tIEFwbGljYSBSb3cgTGV2ZWwgU2VjdXJpdHkgYmFzZWFkbyBlbSBPcmdhbml6YXRpb25zCi0tIERhdGE6IDAzLzAxLzIwMjUKLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tIEd1YXJkOiB0aGlzIGVudGlyZSBtaWdyYXRpb24gaXMgd3JhcHBlZCBpbiBhIERPIGJsb2NrIHNvIGl0Ci0tIGV4aXRzIGNsZWFubHkgd2hlbiBwdWJsaWMub3JnYW5pemF0aW9ucyBkb2Vzbid0IGV4aXN0IHlldC4KLS0gT24gYSBmcmVzaCBTdXBhYmFzZSBQcmV2aWV3IEJyYW5jaCB0aGF0IHJlcGxheXMgYWxsIG1pZ3JhdGlvbnMKLS0gZnJvbSBzY3JhdGNoLCBvcmdhbml6YXRpb25zIGlzIGNyZWF0ZWQgbGF0ZXIgaW4gdGhlIHNlcXVlbmNlLgotLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCkRPICRvdXRlciQKQkVHSU4KICBJRiBOT1QgRVhJU1RTICgKICAgIFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcwogICAgV0hFUkUgdGFibGVfc2NoZW1hID0gJ3B1YmxpYycgQU5EIHRhYmxlX25hbWUgPSAnb3JnYW5pemF0aW9ucycKICApIFRIRU4KICAgIFJBSVNFIE5PVElDRSAnTWlncmF0aW9uIDIwMjUwMTAzXzAyX3Jsc19vcmdhbml6YXRpb25zIHNraXBwZWQ6IHB1YmxpYy5vcmdhbml6YXRpb25zIGRvZXMgbm90IGV4aXN0IHlldC4nOwogICAgUkVUVVJOOwogIEVORCBJRjsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTogQURJQ0lPTkFSIG9yZ2FuaXphdGlvbl9pZCBOQVMgVEFCRUxBUyBQUklOQ0lQQUlTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5jYXRlZ29yaWVzCiAgICBBREQgQ09MVU1OIElGIE5PVCBFWElTVFMgb3JnYW5pemF0aW9uX2lkIFVVSUQgUkVGRVJFTkNFUyBwdWJsaWMub3JnYW5pemF0aW9ucyhpZCkgT04gREVMRVRFIENBU0NBREU7CiAgQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgaWR4X2NhdGVnb3JpZXNfb3JnIE9OIHB1YmxpYy5jYXRlZ29yaWVzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5zdXBwbGllcnMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfc3VwcGxpZXJzX29yZyBPTiBwdWJsaWMuc3VwcGxpZXJzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5wcm9kdWN0cwogICAgQUREIENPTFVNTiBJRiBOT1QgRVhJU1RTIG9yZ2FuaXphdGlvbl9pZCBVVUlEIFJFRkVSRU5DRVMgcHVibGljLm9yZ2FuaXphdGlvbnMoaWQpIE9OIERFTEVURSBDQVNDQURFOwogIENSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTIGlkeF9wcm9kdWN0c19vcmcgT04gcHVibGljLnByb2R1Y3RzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5xdW90ZXMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfcXVvdGVzX29yZyBPTiBwdWJsaWMucXVvdGVzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5vcmRlcnMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfb3JkZXJzX29yZyBPTiBwdWJsaWMub3JkZXJzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5iaXRyaXhfY2xpZW50cwogICAgQUREIENPTFVNTiBJRiBOT1QgRVhJU1RTIG9yZ2FuaXphdGlvbl9pZCBVVUlEIFJFRkVSRU5DRVMgcHVibGljLm9yZ2FuaXphdGlvbnMoaWQpIE9OIERFTEVURSBDQVNDQURFOwogIENSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTIGlkeF9iaXRyaXhfY2xpZW50c19vcmcgT04gcHVibGljLmJpdHJpeF9jbGllbnRzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzCiAgICBBREQgQ09MVU1OIElGIE5PVCBFWElTVFMgb3JnYW5pemF0aW9uX2lkIFVVSUQgUkVGRVJFTkNFUyBwdWJsaWMub3JnYW5pemF0aW9ucyhpZCkgT04gREVMRVRFIENBU0NBREU7CiAgQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgaWR4X21vY2t1cF9qb2JzX29yZyBPTiBwdWJsaWMubW9ja3VwX2dlbmVyYXRpb25fam9icyhvcmdhbml6YXRpb25faWQpOwoKICBBTFRFUiBUQUJMRSBwdWJsaWMuY29sbGVjdGlvbnMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfY29sbGVjdGlvbnNfb3JnIE9OIHB1YmxpYy5jb2xsZWN0aW9ucyhvcmdhbml6YXRpb25faWQpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAyOiBGVU7Dh8ODTyBIRUxQRVIgLSBWZXJpZmljYXIgc2UgdXNlciBwZXJ0ZW5jZSDDoCBvcmcKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgQ1JFQVRFIE9SIFJFUExBQ0UgRlVOQ1RJT04gcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdfaWQgVVVJRCkKICBSRVRVUk5TIEJPT0xFQU4gQVMgJGZuJAogIEJFR0lOCiAgICBSRVRVUk4gRVhJU1RTICgKICAgICAgU0VMRUNUIDEKICAgICAgRlJPTSBwdWJsaWMudXNlcl9vcmdhbml6YXRpb25zCiAgICAgIFdIRVJFIG9yZ2FuaXphdGlvbl9pZCA9IG9yZ19pZAogICAgICAgIEFORCB1c2VyX2lkID0gYXV0aC51aWQoKQogICAgKTsKICBFTkQ7CiAgJGZuJCBMQU5HVUFHRSBwbHBnc3FsIFNFQ1VSSVRZIERFRklORVIgU1RBQkxFOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAzOiBBUExJQ0FSIFJMUyBFTSBUT0RBUyBBUyBUQUJFTEFTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5jYXRlZ29yaWVzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLnN1cHBsaWVycyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5wcm9kdWN0cyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5wcm9kdWN0X3ZhcmlhbnRzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLnF1b3RlcyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5xdW90ZV9pdGVtcyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5vcmRlcnMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBBTFRFUiBUQUJMRSBwdWJsaWMub3JkZXJfaXRlbXMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBJRiBFWElTVFMgKFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBXSEVSRSB0YWJsZV9zY2hlbWE9J3B1YmxpYycgQU5EIHRhYmxlX25hbWU9J3BheW1lbnRzJykgVEhFTgogICAgQUxURVIgVEFCTEUgcHVibGljLnBheW1lbnRzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgRU5EIElGOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5iaXRyaXhfY2xpZW50cyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLmdlbmVyYXRlZF9tb2NrdXBzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLmNvbGxlY3Rpb25zIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLmNvbGxlY3Rpb25fcHJvZHVjdHMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBBTFRFUiBUQUJMRSBwdWJsaWMucGVyc29uYWxpemF0aW9uX3RlY2huaXF1ZXMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBBTFRFUiBUQUJMRSBwdWJsaWMubm90aWZpY2F0aW9ucyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5mZWF0dXJlX2ZsYWdzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLnN5c3RlbV9zZXR0aW5ncyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSA0OiBQT0xJQ0lFUyAtIENBVEVHT1JJRVMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X2NhdGVnb3JpZXMiIE9OIHB1YmxpYy5jYXRlZ29yaWVzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfY2F0ZWdvcmllcyIKICAgIE9OIHB1YmxpYy5jYXRlZ29yaWVzIEZPUiBTRUxFQ1QgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy51c2VyX2lzX29yZ19tZW1iZXIob3JnYW5pemF0aW9uX2lkKSk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX2FkbWluc19jcmVhdGVfY2F0ZWdvcmllcyIgT04gcHVibGljLmNhdGVnb3JpZXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19jcmVhdGVfY2F0ZWdvcmllcyIKICAgIE9OIHB1YmxpYy5jYXRlZ29yaWVzIEZPUiBJTlNFUlQgVE8gYXV0aGVudGljYXRlZAogICAgV0lUSCBDSEVDSyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX3VwZGF0ZV9jYXRlZ29yaWVzIiBPTiBwdWJsaWMuY2F0ZWdvcmllczsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX3VwZGF0ZV9jYXRlZ29yaWVzIgogICAgT04gcHVibGljLmNhdGVnb3JpZXMgRk9SIFVQREFURSBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgV0lUSCBDSEVDSyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX2RlbGV0ZV9jYXRlZ29yaWVzIiBPTiBwdWJsaWMuY2F0ZWdvcmllczsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX2RlbGV0ZV9jYXRlZ29yaWVzIgogICAgT04gcHVibGljLmNhdGVnb3JpZXMgRk9SIERFTEVURSBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgNTogUE9MSUNJRVMgLSBTVVBQTElFUlMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X3N1cHBsaWVycyIgT04gcHVibGljLnN1cHBsaWVyczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X3N1cHBsaWVycyIKICAgIE9OIHB1YmxpYy5zdXBwbGllcnMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX21hbmFnZV9zdXBwbGllcnMiIE9OIHB1YmxpYy5zdXBwbGllcnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19tYW5hZ2Vfc3VwcGxpZXJzIgogICAgT04gcHVibGljLnN1cHBsaWVycyBGT1IgQUxMIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMuaXNfb3JnX293bmVyX29yX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpCiAgICBXSVRIIENIRUNLIChwdWJsaWMuaXNfb3JnX293bmVyX29yX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSA2OiBQT0xJQ0lFUyAtIFBST0RVQ1RTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfdmlld19wcm9kdWN0cyIgT04gcHVibGljLnByb2R1Y3RzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfcHJvZHVjdHMiCiAgICBPTiBwdWJsaWMucHJvZHVjdHMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX21hbmFnZV9wcm9kdWN0cyIgT04gcHVibGljLnByb2R1Y3RzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19hZG1pbnNfbWFuYWdlX3Byb2R1Y3RzIgogICAgT04gcHVibGljLnByb2R1Y3RzIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSkKICAgIFdJVEggQ0hFQ0sgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDc6IFBPTElDSUVTIC0gUFJPRFVDVF9WQVJJQU5UUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfdmFyaWFudHMiIE9OIHB1YmxpYy5wcm9kdWN0X3ZhcmlhbnRzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfdmFyaWFudHMiCiAgICBPTiBwdWJsaWMucHJvZHVjdF92YXJpYW50cyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5wcm9kdWN0cwogICAgICAgIFdIRVJFIGlkID0gcHJvZHVjdF92YXJpYW50cy5wcm9kdWN0X2lkCiAgICAgICAgICBBTkQgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX2FkbWluc19tYW5hZ2VfdmFyaWFudHMiIE9OIHB1YmxpYy5wcm9kdWN0X3ZhcmlhbnRzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19hZG1pbnNfbWFuYWdlX3ZhcmlhbnRzIgogICAgT04gcHVibGljLnByb2R1Y3RfdmFyaWFudHMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAoCiAgICAgIEVYSVNUUyAoCiAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMucHJvZHVjdHMKICAgICAgICBXSEVSRSBpZCA9IHByb2R1Y3RfdmFyaWFudHMucHJvZHVjdF9pZAogICAgICAgICAgQU5EIHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKQogICAgICApCiAgICApCiAgICBXSVRIIENIRUNLICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5wcm9kdWN0cwogICAgICAgIFdIRVJFIGlkID0gcHJvZHVjdF92YXJpYW50cy5wcm9kdWN0X2lkCiAgICAgICAgICBBTkQgcHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDg6IFBPTElDSUVTIC0gUVVPVEVTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfdmlld19xdW90ZXMiIE9OIHB1YmxpYy5xdW90ZXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19xdW90ZXMiCiAgICBPTiBwdWJsaWMucXVvdGVzIEZPUiBTRUxFQ1QgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy51c2VyX2lzX29yZ19tZW1iZXIob3JnYW5pemF0aW9uX2lkKSk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfY3JlYXRlX3F1b3RlcyIgT04gcHVibGljLnF1b3RlczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc19jcmVhdGVfcXVvdGVzIgogICAgT04gcHVibGljLnF1b3RlcyBGT1IgSU5TRVJUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFdJVEggQ0hFQ0sgKHB1YmxpYy51c2VyX2lzX29yZ19tZW1iZXIob3JnYW5pemF0aW9uX2lkKSk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfdXBkYXRlX293bl9xdW90ZXMiIE9OIHB1YmxpYy5xdW90ZXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdXBkYXRlX293bl9xdW90ZXMiCiAgICBPTiBwdWJsaWMucXVvdGVzIEZPUiBVUERBVEUgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgQU5EIChjcmVhdGVkX2J5ID0gYXV0aC51aWQoKSBPUiBwdWJsaWMuaXNfb3JnX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpCiAgICApOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19hZG1pbnNfZGVsZXRlX3F1b3RlcyIgT04gcHVibGljLnF1b3RlczsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX2RlbGV0ZV9xdW90ZXMiCiAgICBPTiBwdWJsaWMucXVvdGVzIEZPUiBERUxFVEUgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDk6IFBPTElDSUVTIC0gUVVPVEVfSVRFTVMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X3F1b3RlX2l0ZW1zIiBPTiBwdWJsaWMucXVvdGVfaXRlbXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19xdW90ZV9pdGVtcyIKICAgIE9OIHB1YmxpYy5xdW90ZV9pdGVtcyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5xdW90ZXMKICAgICAgICBXSEVSRSBpZCA9IHF1b3RlX2l0ZW1zLnF1b3RlX2lkCiAgICAgICAgICBBTkQgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfbWFuYWdlX3F1b3RlX2l0ZW1zIiBPTiBwdWJsaWMucXVvdGVfaXRlbXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfbWFuYWdlX3F1b3RlX2l0ZW1zIgogICAgT04gcHVibGljLnF1b3RlX2l0ZW1zIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLnF1b3RlcwogICAgICAgIFdIRVJFIGlkID0gcXVvdGVfaXRlbXMucXVvdGVfaWQKICAgICAgICAgIEFORCAoY3JlYXRlZF9ieSA9IGF1dGgudWlkKCkgT1IgcHVibGljLmlzX29yZ19hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgICApCiAgICApCiAgICBXSVRIIENIRUNLICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5xdW90ZXMKICAgICAgICBXSEVSRSBpZCA9IHF1b3RlX2l0ZW1zLnF1b3RlX2lkCiAgICAgICAgICBBTkQgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDEwOiBQT0xJQ0lFUyAtIE9SREVSUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfb3JkZXJzIiBPTiBwdWJsaWMub3JkZXJzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfb3JkZXJzIgogICAgT04gcHVibGljLm9yZGVycyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX2NyZWF0ZV9vcmRlcnMiIE9OIHB1YmxpYy5vcmRlcnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfY3JlYXRlX29yZGVycyIKICAgIE9OIHB1YmxpYy5vcmRlcnMgRk9SIElOU0VSVCBUTyBhdXRoZW50aWNhdGVkCiAgICBXSVRIIENIRUNLIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3VwZGF0ZV9vd25fb3JkZXJzIiBPTiBwdWJsaWMub3JkZXJzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3VwZGF0ZV9vd25fb3JkZXJzIgogICAgT04gcHVibGljLm9yZGVycyBGT1IgVVBEQVRFIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgIEFORCAoY3JlYXRlZF9ieSA9IGF1dGgudWlkKCkgT1IgcHVibGljLmlzX29yZ19hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX2RlbGV0ZV9vcmRlcnMiIE9OIHB1YmxpYy5vcmRlcnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19kZWxldGVfb3JkZXJzIgogICAgT04gcHVibGljLm9yZGVycyBGT1IgREVMRVRFIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMuaXNfb3JnX293bmVyX29yX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxMTogUE9MSUNJRVMgLSBPUkRFUl9JVEVNUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfb3JkZXJfaXRlbXMiIE9OIHB1YmxpYy5vcmRlcl9pdGVtczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X29yZGVyX2l0ZW1zIgogICAgT04gcHVibGljLm9yZGVyX2l0ZW1zIEZPUiBTRUxFQ1QgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLm9yZGVycwogICAgICAgIFdIRVJFIGlkID0gb3JkZXJfaXRlbXMub3JkZXJfaWQKICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgKQogICAgKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc19tYW5hZ2Vfb3JkZXJfaXRlbXMiIE9OIHB1YmxpYy5vcmRlcl9pdGVtczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc19tYW5hZ2Vfb3JkZXJfaXRlbXMiCiAgICBPTiBwdWJsaWMub3JkZXJfaXRlbXMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAoCiAgICAgIEVYSVNUUyAoCiAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMub3JkZXJzCiAgICAgICAgV0hFUkUgaWQgPSBvcmRlcl9pdGVtcy5vcmRlcl9pZAogICAgICAgICAgQU5EIChjcmVhdGVkX2J5ID0gYXV0aC51aWQoKSBPUiBwdWJsaWMuaXNfb3JnX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpCiAgICAgICkKICAgICkKICAgIFdJVEggQ0hFQ0sgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLm9yZGVycwogICAgICAgIFdIRVJFIGlkID0gb3JkZXJfaXRlbXMub3JkZXJfaWQKICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgKQogICAgKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTI6IFBPTElDSUVTIC0gUEFZTUVOVFMgKGd1YXJkZWQ6IHRhYmxlIG1heSBub3QgZXhpc3QgeWV0KQogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBJRiBFWElTVFMgKFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBXSEVSRSB0YWJsZV9zY2hlbWE9J3B1YmxpYycgQU5EIHRhYmxlX25hbWU9J3BheW1lbnRzJykgVEhFTgogICAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X3BheW1lbnRzIiBPTiBwdWJsaWMucGF5bWVudHM7CiAgICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X3BheW1lbnRzIgogICAgICBPTiBwdWJsaWMucGF5bWVudHMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICAgIFVTSU5HICgKICAgICAgICBFWElTVFMgKAogICAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMub3JkZXJzCiAgICAgICAgICBXSEVSRSBpZCA9IHBheW1lbnRzLm9yZGVyX2lkCiAgICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgICApCiAgICAgICk7CgogICAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX21hbmFnZV9wYXltZW50cyIgT04gcHVibGljLnBheW1lbnRzOwogICAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19tYW5hZ2VfcGF5bWVudHMiCiAgICAgIE9OIHB1YmxpYy5wYXltZW50cyBGT1IgQUxMIFRPIGF1dGhlbnRpY2F0ZWQKICAgICAgVVNJTkcgKAogICAgICAgIEVYSVNUUyAoCiAgICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5vcmRlcnMKICAgICAgICAgIFdIRVJFIGlkID0gcGF5bWVudHMub3JkZXJfaWQKICAgICAgICAgICAgQU5EIHB1YmxpYy5pc19vcmdfYWRtaW4ob3JnYW5pemF0aW9uX2lkKQogICAgICAgICkKICAgICAgKQogICAgICBXSVRIIENIRUNLICgKICAgICAgICBFWElTVFMgKAogICAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMub3JkZXJzCiAgICAgICAgICBXSEVSRSBpZCA9IHBheW1lbnRzLm9yZGVyX2lkCiAgICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgICApCiAgICAgICk7CiAgRU5EIElGOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxMzogUE9MSUNJRVMgLSBCSVRSSVhfQ0xJRU5UUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfY2xpZW50cyIgT04gcHVibGljLmJpdHJpeF9jbGllbnRzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfY2xpZW50cyIKICAgIE9OIHB1YmxpYy5iaXRyaXhfY2xpZW50cyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19hZG1pbnNfbWFuYWdlX2NsaWVudHMiIE9OIHB1YmxpYy5iaXRyaXhfY2xpZW50czsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX21hbmFnZV9jbGllbnRzIgogICAgT04gcHVibGljLmJpdHJpeF9jbGllbnRzIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSkKICAgIFdJVEggQ0hFQ0sgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDE0OiBQT0xJQ0lFUyAtIE1PQ0tVUFMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X21vY2t1cF9qb2JzIiBPTiBwdWJsaWMubW9ja3VwX2dlbmVyYXRpb25fam9iczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X21vY2t1cF9qb2JzIgogICAgT04gcHVibGljLm1vY2t1cF9nZW5lcmF0aW9uX2pvYnMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc19jcmVhdGVfbW9ja3VwX2pvYnMiIE9OIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX2NyZWF0ZV9tb2NrdXBfam9icyIKICAgIE9OIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzIEZPUiBJTlNFUlQgVE8gYXV0aGVudGljYXRlZAogICAgV0lUSCBDSEVDSyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X2dlbmVyYXRlZF9tb2NrdXBzIiBPTiBwdWJsaWMuZ2VuZXJhdGVkX21vY2t1cHM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19nZW5lcmF0ZWRfbW9ja3VwcyIKICAgIE9OIHB1YmxpYy5nZW5lcmF0ZWRfbW9ja3VwcyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzCiAgICAgICAgV0hFUkUgaWQgPSBnZW5lcmF0ZWRfbW9ja3Vwcy5qb2JfaWQKICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgKQogICAgKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTU6IFBPTElDSUVTIC0gQ09MTEVDVElPTlMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X2NvbGxlY3Rpb25zIiBPTiBwdWJsaWMuY29sbGVjdGlvbnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19jb2xsZWN0aW9ucyIKICAgIE9OIHB1YmxpYy5jb2xsZWN0aW9ucyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19hZG1pbnNfbWFuYWdlX2NvbGxlY3Rpb25zIiBPTiBwdWJsaWMuY29sbGVjdGlvbnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19tYW5hZ2VfY29sbGVjdGlvbnMiCiAgICBPTiBwdWJsaWMuY29sbGVjdGlvbnMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgV0lUSCBDSEVDSyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTY6IFBPTElDSUVTIC0gUEVSU09OQUxJWkFUSU9OX1RFQ0hOSVFVRVMgKEdMT0JBTCkKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJhbnlvbmVfdmlld190ZWNobmlxdWVzIiBPTiBwdWJsaWMucGVyc29uYWxpemF0aW9uX3RlY2huaXF1ZXM7CiAgQ1JFQVRFIFBPTElDWSAiYW55b25lX3ZpZXdfdGVjaG5pcXVlcyIKICAgIE9OIHB1YmxpYy5wZXJzb25hbGl6YXRpb25fdGVjaG5pcXVlcyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChpc19hY3RpdmUgPSB0cnVlKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJhZG1pbnNfbWFuYWdlX3RlY2huaXF1ZXMiIE9OIHB1YmxpYy5wZXJzb25hbGl6YXRpb25fdGVjaG5pcXVlczsKICBDUkVBVEUgUE9MSUNZICJhZG1pbnNfbWFuYWdlX3RlY2huaXF1ZXMiCiAgICBPTiBwdWJsaWMucGVyc29uYWxpemF0aW9uX3RlY2huaXF1ZXMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAoCiAgICAgIEVYSVNUUyAoCiAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMudXNlcl9vcmdhbml6YXRpb25zCiAgICAgICAgV0hFUkUgdXNlcl9pZCA9IGF1dGgudWlkKCkKICAgICAgICAgIEFORCByb2xlIElOICgnb3duZXInLCAnYWRtaW4nKQogICAgICApCiAgICApOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxNzogUE9MSUNJRVMgLSBOT1RJRklDQVRJT05TIChVU0VSLVNDT1BFRCkKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJ1c2Vyc192aWV3X293bl9ub3RpZmljYXRpb25zIiBPTiBwdWJsaWMubm90aWZpY2F0aW9uczsKICBDUkVBVEUgUE9MSUNZICJ1c2Vyc192aWV3X293bl9ub3RpZmljYXRpb25zIgogICAgT04gcHVibGljLm5vdGlmaWNhdGlvbnMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAodXNlcl9pZCA9IGF1dGgudWlkKCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgInVzZXJzX3VwZGF0ZV9vd25fbm90aWZpY2F0aW9ucyIgT04gcHVibGljLm5vdGlmaWNhdGlvbnM7CiAgQ1JFQVRFIFBPTElDWSAidXNlcnNfdXBkYXRlX293bl9ub3RpZmljYXRpb25zIgogICAgT04gcHVibGljLm5vdGlmaWNhdGlvbnMgRk9SIFVQREFURSBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAodXNlcl9pZCA9IGF1dGgudWlkKCkpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxODogUE9MSUNJRVMgLSBTWVNURU0gVEFCTEVTIChBRE1JTiBPTkxZKQogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgImFkbWluc192aWV3X2ZlYXR1cmVfZmxhZ3MiIE9OIHB1YmxpYy5mZWF0dXJlX2ZsYWdzOwogIENSRUFURSBQT0xJQ1kgImFkbWluc192aWV3X2ZlYXR1cmVfZmxhZ3MiCiAgICBPTiBwdWJsaWMuZmVhdHVyZV9mbGFncyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy51c2VyX29yZ2FuaXphdGlvbnMKICAgICAgICBXSEVSRSB1c2VyX2lkID0gYXV0aC51aWQoKQogICAgICAgICAgQU5EIHJvbGUgSU4gKCdvd25lcicsICdhZG1pbicpCiAgICAgICkKICAgICk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAiYWRtaW5zX21hbmFnZV9zeXN0ZW1fc2V0dGluZ3MiIE9OIHB1YmxpYy5zeXN0ZW1fc2V0dGluZ3M7CiAgQ1JFQVRFIFBPTElDWSAiYWRtaW5zX21hbmFnZV9zeXN0ZW1fc2V0dGluZ3MiCiAgICBPTiBwdWJsaWMuc3lzdGVtX3NldHRpbmdzIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLnVzZXJfb3JnYW5pemF0aW9ucwogICAgICAgIFdIRVJFIHVzZXJfaWQgPSBhdXRoLnVpZCgpCiAgICAgICAgICBBTkQgcm9sZSBJTiAoJ293bmVyJywgJ2FkbWluJykKICAgICAgKQogICAgKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTk6IEdSQU5UUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBHUkFOVCBTRUxFQ1QgT04gcHVibGljLmNhdGVnb3JpZXMgVE8gYXV0aGVudGljYXRlZDsKICBHUkFOVCBTRUxFQ1QgT04gcHVibGljLnN1cHBsaWVycyBUTyBhdXRoZW50aWNhdGVkOwogIEdSQU5UIFNFTEVDVCBPTiBwdWJsaWMucHJvZHVjdHMgVE8gYXV0aGVudGljYXRlZDsKICBHUkFOVCBTRUxFQ1QgT04gcHVibGljLnF1b3RlcyBUTyBhdXRoZW50aWNhdGVkOwogIEdSQU5UIFNFTEVDVCBPTiBwdWJsaWMub3JkZXJzIFRPIGF1dGhlbnRpY2F0ZWQ7CiAgSUYgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgV0hFUkUgdGFibGVfc2NoZW1hPSdwdWJsaWMnIEFORCB0YWJsZV9uYW1lPSdwYXltZW50cycpIFRIRU4KICAgIEdSQU5UIFNFTEVDVCBPTiBwdWJsaWMucGF5bWVudHMgVE8gYXV0aGVudGljYXRlZDsKICBFTkQgSUY7CgogIFJBSVNFIE5PVElDRSAnTWlncmF0aW9uIDIwMjUwMTAzXzAyX3Jsc19vcmdhbml6YXRpb25zIGFwcGxpZWQgc3VjY2Vzc2Z1bGx5Lic7CkVORCAkb3V0ZXIkOwo" (SQLSTATE 42601)
At statement: 0
LS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tIEdJRlRTIFNUT1JFIC0gUkxTIENPTSBPUkdBTklaQVRJT05TIChNVUxUSS1URU5BTlQpCi0tIEFwbGljYSBSb3cgTGV2ZWwgU2VjdXJpdHkgYmFzZWFkbyBlbSBPcmdhbml6YXRpb25zCi0tIERhdGE6IDAzLzAxLzIwMjUKLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tIEd1YXJkOiB0aGlzIGVudGlyZSBtaWdyYXRpb24gaXMgd3JhcHBlZCBpbiBhIERPIGJsb2NrIHNvIGl0Ci0tIGV4aXRzIGNsZWFubHkgd2hlbiBwdWJsaWMub3JnYW5pemF0aW9ucyBkb2Vzbid0IGV4aXN0IHlldC4KLS0gT24gYSBmcmVzaCBTdXBhYmFzZSBQcmV2aWV3IEJyYW5jaCB0aGF0IHJlcGxheXMgYWxsIG1pZ3JhdGlvbnMKLS0gZnJvbSBzY3JhdGNoLCBvcmdhbml6YXRpb25zIGlzIGNyZWF0ZWQgbGF0ZXIgaW4gdGhlIHNlcXVlbmNlLgotLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCkRPICRvdXRlciQKQkVHSU4KICBJRiBOT1QgRVhJU1RTICgKICAgIFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcwogICAgV0hFUkUgdGFibGVfc2NoZW1hID0gJ3B1YmxpYycgQU5EIHRhYmxlX25hbWUgPSAnb3JnYW5pemF0aW9ucycKICApIFRIRU4KICAgIFJBSVNFIE5PVElDRSAnTWlncmF0aW9uIDIwMjUwMTAzXzAyX3Jsc19vcmdhbml6YXRpb25zIHNraXBwZWQ6IHB1YmxpYy5vcmdhbml6YXRpb25zIGRvZXMgbm90IGV4aXN0IHlldC4nOwogICAgUkVUVVJOOwogIEVORCBJRjsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTogQURJQ0lPTkFSIG9yZ2FuaXphdGlvbl9pZCBOQVMgVEFCRUxBUyBQUklOQ0lQQUlTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5jYXRlZ29yaWVzCiAgICBBREQgQ09MVU1OIElGIE5PVCBFWElTVFMgb3JnYW5pemF0aW9uX2lkIFVVSUQgUkVGRVJFTkNFUyBwdWJsaWMub3JnYW5pemF0aW9ucyhpZCkgT04gREVMRVRFIENBU0NBREU7CiAgQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgaWR4X2NhdGVnb3JpZXNfb3JnIE9OIHB1YmxpYy5jYXRlZ29yaWVzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5zdXBwbGllcnMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfc3VwcGxpZXJzX29yZyBPTiBwdWJsaWMuc3VwcGxpZXJzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5wcm9kdWN0cwogICAgQUREIENPTFVNTiBJRiBOT1QgRVhJU1RTIG9yZ2FuaXphdGlvbl9pZCBVVUlEIFJFRkVSRU5DRVMgcHVibGljLm9yZ2FuaXphdGlvbnMoaWQpIE9OIERFTEVURSBDQVNDQURFOwogIENSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTIGlkeF9wcm9kdWN0c19vcmcgT04gcHVibGljLnByb2R1Y3RzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5xdW90ZXMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfcXVvdGVzX29yZyBPTiBwdWJsaWMucXVvdGVzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5vcmRlcnMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfb3JkZXJzX29yZyBPTiBwdWJsaWMub3JkZXJzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5iaXRyaXhfY2xpZW50cwogICAgQUREIENPTFVNTiBJRiBOT1QgRVhJU1RTIG9yZ2FuaXphdGlvbl9pZCBVVUlEIFJFRkVSRU5DRVMgcHVibGljLm9yZ2FuaXphdGlvbnMoaWQpIE9OIERFTEVURSBDQVNDQURFOwogIENSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTIGlkeF9iaXRyaXhfY2xpZW50c19vcmcgT04gcHVibGljLmJpdHJpeF9jbGllbnRzKG9yZ2FuaXphdGlvbl9pZCk7CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzCiAgICBBREQgQ09MVU1OIElGIE5PVCBFWElTVFMgb3JnYW5pemF0aW9uX2lkIFVVSUQgUkVGRVJFTkNFUyBwdWJsaWMub3JnYW5pemF0aW9ucyhpZCkgT04gREVMRVRFIENBU0NBREU7CiAgQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgaWR4X21vY2t1cF9qb2JzX29yZyBPTiBwdWJsaWMubW9ja3VwX2dlbmVyYXRpb25fam9icyhvcmdhbml6YXRpb25faWQpOwoKICBBTFRFUiBUQUJMRSBwdWJsaWMuY29sbGVjdGlvbnMKICAgIEFERCBDT0xVTU4gSUYgTk9UIEVYSVNUUyBvcmdhbml6YXRpb25faWQgVVVJRCBSRUZFUkVOQ0VTIHB1YmxpYy5vcmdhbml6YXRpb25zKGlkKSBPTiBERUxFVEUgQ0FTQ0FERTsKICBDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfY29sbGVjdGlvbnNfb3JnIE9OIHB1YmxpYy5jb2xsZWN0aW9ucyhvcmdhbml6YXRpb25faWQpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAyOiBGVU7Dh8ODTyBIRUxQRVIgLSBWZXJpZmljYXIgc2UgdXNlciBwZXJ0ZW5jZSDDoCBvcmcKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgQ1JFQVRFIE9SIFJFUExBQ0UgRlVOQ1RJT04gcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdfaWQgVVVJRCkKICBSRVRVUk5TIEJPT0xFQU4gQVMgJGZuJAogIEJFR0lOCiAgICBSRVRVUk4gRVhJU1RTICgKICAgICAgU0VMRUNUIDEKICAgICAgRlJPTSBwdWJsaWMudXNlcl9vcmdhbml6YXRpb25zCiAgICAgIFdIRVJFIG9yZ2FuaXphdGlvbl9pZCA9IG9yZ19pZAogICAgICAgIEFORCB1c2VyX2lkID0gYXV0aC51aWQoKQogICAgKTsKICBFTkQ7CiAgJGZuJCBMQU5HVUFHRSBwbHBnc3FsIFNFQ1VSSVRZIERFRklORVIgU1RBQkxFOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAzOiBBUExJQ0FSIFJMUyBFTSBUT0RBUyBBUyBUQUJFTEFTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIEFMVEVSIFRBQkxFIHB1YmxpYy5jYXRlZ29yaWVzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLnN1cHBsaWVycyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5wcm9kdWN0cyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5wcm9kdWN0X3ZhcmlhbnRzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLnF1b3RlcyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5xdW90ZV9pdGVtcyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5vcmRlcnMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBBTFRFUiBUQUJMRSBwdWJsaWMub3JkZXJfaXRlbXMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBJRiBFWElTVFMgKFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBXSEVSRSB0YWJsZV9zY2hlbWE9J3B1YmxpYycgQU5EIHRhYmxlX25hbWU9J3BheW1lbnRzJykgVEhFTgogICAgQUxURVIgVEFCTEUgcHVibGljLnBheW1lbnRzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgRU5EIElGOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5iaXRyaXhfY2xpZW50cyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLmdlbmVyYXRlZF9tb2NrdXBzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLmNvbGxlY3Rpb25zIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLmNvbGxlY3Rpb25fcHJvZHVjdHMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBBTFRFUiBUQUJMRSBwdWJsaWMucGVyc29uYWxpemF0aW9uX3RlY2huaXF1ZXMgRU5BQkxFIFJPVyBMRVZFTCBTRUNVUklUWTsKICBBTFRFUiBUQUJMRSBwdWJsaWMubm90aWZpY2F0aW9ucyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwogIEFMVEVSIFRBQkxFIHB1YmxpYy5mZWF0dXJlX2ZsYWdzIEVOQUJMRSBST1cgTEVWRUwgU0VDVVJJVFk7CiAgQUxURVIgVEFCTEUgcHVibGljLnN5c3RlbV9zZXR0aW5ncyBFTkFCTEUgUk9XIExFVkVMIFNFQ1VSSVRZOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSA0OiBQT0xJQ0lFUyAtIENBVEVHT1JJRVMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X2NhdGVnb3JpZXMiIE9OIHB1YmxpYy5jYXRlZ29yaWVzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfY2F0ZWdvcmllcyIKICAgIE9OIHB1YmxpYy5jYXRlZ29yaWVzIEZPUiBTRUxFQ1QgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy51c2VyX2lzX29yZ19tZW1iZXIob3JnYW5pemF0aW9uX2lkKSk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX2FkbWluc19jcmVhdGVfY2F0ZWdvcmllcyIgT04gcHVibGljLmNhdGVnb3JpZXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19jcmVhdGVfY2F0ZWdvcmllcyIKICAgIE9OIHB1YmxpYy5jYXRlZ29yaWVzIEZPUiBJTlNFUlQgVE8gYXV0aGVudGljYXRlZAogICAgV0lUSCBDSEVDSyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX3VwZGF0ZV9jYXRlZ29yaWVzIiBPTiBwdWJsaWMuY2F0ZWdvcmllczsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX3VwZGF0ZV9jYXRlZ29yaWVzIgogICAgT04gcHVibGljLmNhdGVnb3JpZXMgRk9SIFVQREFURSBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgV0lUSCBDSEVDSyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX2RlbGV0ZV9jYXRlZ29yaWVzIiBPTiBwdWJsaWMuY2F0ZWdvcmllczsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX2RlbGV0ZV9jYXRlZ29yaWVzIgogICAgT04gcHVibGljLmNhdGVnb3JpZXMgRk9SIERFTEVURSBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgNTogUE9MSUNJRVMgLSBTVVBQTElFUlMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X3N1cHBsaWVycyIgT04gcHVibGljLnN1cHBsaWVyczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X3N1cHBsaWVycyIKICAgIE9OIHB1YmxpYy5zdXBwbGllcnMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX21hbmFnZV9zdXBwbGllcnMiIE9OIHB1YmxpYy5zdXBwbGllcnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19tYW5hZ2Vfc3VwcGxpZXJzIgogICAgT04gcHVibGljLnN1cHBsaWVycyBGT1IgQUxMIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMuaXNfb3JnX293bmVyX29yX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpCiAgICBXSVRIIENIRUNLIChwdWJsaWMuaXNfb3JnX293bmVyX29yX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSA2OiBQT0xJQ0lFUyAtIFBST0RVQ1RTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfdmlld19wcm9kdWN0cyIgT04gcHVibGljLnByb2R1Y3RzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfcHJvZHVjdHMiCiAgICBPTiBwdWJsaWMucHJvZHVjdHMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX21hbmFnZV9wcm9kdWN0cyIgT04gcHVibGljLnByb2R1Y3RzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19hZG1pbnNfbWFuYWdlX3Byb2R1Y3RzIgogICAgT04gcHVibGljLnByb2R1Y3RzIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSkKICAgIFdJVEggQ0hFQ0sgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDc6IFBPTElDSUVTIC0gUFJPRFVDVF9WQVJJQU5UUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfdmFyaWFudHMiIE9OIHB1YmxpYy5wcm9kdWN0X3ZhcmlhbnRzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfdmFyaWFudHMiCiAgICBPTiBwdWJsaWMucHJvZHVjdF92YXJpYW50cyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5wcm9kdWN0cwogICAgICAgIFdIRVJFIGlkID0gcHJvZHVjdF92YXJpYW50cy5wcm9kdWN0X2lkCiAgICAgICAgICBBTkQgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX2FkbWluc19tYW5hZ2VfdmFyaWFudHMiIE9OIHB1YmxpYy5wcm9kdWN0X3ZhcmlhbnRzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19hZG1pbnNfbWFuYWdlX3ZhcmlhbnRzIgogICAgT04gcHVibGljLnByb2R1Y3RfdmFyaWFudHMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAoCiAgICAgIEVYSVNUUyAoCiAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMucHJvZHVjdHMKICAgICAgICBXSEVSRSBpZCA9IHByb2R1Y3RfdmFyaWFudHMucHJvZHVjdF9pZAogICAgICAgICAgQU5EIHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKQogICAgICApCiAgICApCiAgICBXSVRIIENIRUNLICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5wcm9kdWN0cwogICAgICAgIFdIRVJFIGlkID0gcHJvZHVjdF92YXJpYW50cy5wcm9kdWN0X2lkCiAgICAgICAgICBBTkQgcHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDg6IFBPTElDSUVTIC0gUVVPVEVTCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfdmlld19xdW90ZXMiIE9OIHB1YmxpYy5xdW90ZXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19xdW90ZXMiCiAgICBPTiBwdWJsaWMucXVvdGVzIEZPUiBTRUxFQ1QgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy51c2VyX2lzX29yZ19tZW1iZXIob3JnYW5pemF0aW9uX2lkKSk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfY3JlYXRlX3F1b3RlcyIgT04gcHVibGljLnF1b3RlczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc19jcmVhdGVfcXVvdGVzIgogICAgT04gcHVibGljLnF1b3RlcyBGT1IgSU5TRVJUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFdJVEggQ0hFQ0sgKHB1YmxpYy51c2VyX2lzX29yZ19tZW1iZXIob3JnYW5pemF0aW9uX2lkKSk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfdXBkYXRlX293bl9xdW90ZXMiIE9OIHB1YmxpYy5xdW90ZXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdXBkYXRlX293bl9xdW90ZXMiCiAgICBPTiBwdWJsaWMucXVvdGVzIEZPUiBVUERBVEUgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgQU5EIChjcmVhdGVkX2J5ID0gYXV0aC51aWQoKSBPUiBwdWJsaWMuaXNfb3JnX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpCiAgICApOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19hZG1pbnNfZGVsZXRlX3F1b3RlcyIgT04gcHVibGljLnF1b3RlczsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX2RlbGV0ZV9xdW90ZXMiCiAgICBPTiBwdWJsaWMucXVvdGVzIEZPUiBERUxFVEUgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDk6IFBPTElDSUVTIC0gUVVPVEVfSVRFTVMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X3F1b3RlX2l0ZW1zIiBPTiBwdWJsaWMucXVvdGVfaXRlbXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19xdW90ZV9pdGVtcyIKICAgIE9OIHB1YmxpYy5xdW90ZV9pdGVtcyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5xdW90ZXMKICAgICAgICBXSEVSRSBpZCA9IHF1b3RlX2l0ZW1zLnF1b3RlX2lkCiAgICAgICAgICBBTkQgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAib3JnX21lbWJlcnNfbWFuYWdlX3F1b3RlX2l0ZW1zIiBPTiBwdWJsaWMucXVvdGVfaXRlbXM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfbWFuYWdlX3F1b3RlX2l0ZW1zIgogICAgT04gcHVibGljLnF1b3RlX2l0ZW1zIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLnF1b3RlcwogICAgICAgIFdIRVJFIGlkID0gcXVvdGVfaXRlbXMucXVvdGVfaWQKICAgICAgICAgIEFORCAoY3JlYXRlZF9ieSA9IGF1dGgudWlkKCkgT1IgcHVibGljLmlzX29yZ19hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgICApCiAgICApCiAgICBXSVRIIENIRUNLICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5xdW90ZXMKICAgICAgICBXSEVSRSBpZCA9IHF1b3RlX2l0ZW1zLnF1b3RlX2lkCiAgICAgICAgICBBTkQgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgICkKICAgICk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDEwOiBQT0xJQ0lFUyAtIE9SREVSUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfb3JkZXJzIiBPTiBwdWJsaWMub3JkZXJzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfb3JkZXJzIgogICAgT04gcHVibGljLm9yZGVycyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX2NyZWF0ZV9vcmRlcnMiIE9OIHB1YmxpYy5vcmRlcnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfY3JlYXRlX29yZGVycyIKICAgIE9OIHB1YmxpYy5vcmRlcnMgRk9SIElOU0VSVCBUTyBhdXRoZW50aWNhdGVkCiAgICBXSVRIIENIRUNLIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3VwZGF0ZV9vd25fb3JkZXJzIiBPTiBwdWJsaWMub3JkZXJzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3VwZGF0ZV9vd25fb3JkZXJzIgogICAgT04gcHVibGljLm9yZGVycyBGT1IgVVBEQVRFIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgcHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpCiAgICAgIEFORCAoY3JlYXRlZF9ieSA9IGF1dGgudWlkKCkgT1IgcHVibGljLmlzX29yZ19hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX2RlbGV0ZV9vcmRlcnMiIE9OIHB1YmxpYy5vcmRlcnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19kZWxldGVfb3JkZXJzIgogICAgT04gcHVibGljLm9yZGVycyBGT1IgREVMRVRFIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMuaXNfb3JnX293bmVyX29yX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxMTogUE9MSUNJRVMgLSBPUkRFUl9JVEVNUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfb3JkZXJfaXRlbXMiIE9OIHB1YmxpYy5vcmRlcl9pdGVtczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X29yZGVyX2l0ZW1zIgogICAgT04gcHVibGljLm9yZGVyX2l0ZW1zIEZPUiBTRUxFQ1QgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLm9yZGVycwogICAgICAgIFdIRVJFIGlkID0gb3JkZXJfaXRlbXMub3JkZXJfaWQKICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgKQogICAgKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc19tYW5hZ2Vfb3JkZXJfaXRlbXMiIE9OIHB1YmxpYy5vcmRlcl9pdGVtczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc19tYW5hZ2Vfb3JkZXJfaXRlbXMiCiAgICBPTiBwdWJsaWMub3JkZXJfaXRlbXMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAoCiAgICAgIEVYSVNUUyAoCiAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMub3JkZXJzCiAgICAgICAgV0hFUkUgaWQgPSBvcmRlcl9pdGVtcy5vcmRlcl9pZAogICAgICAgICAgQU5EIChjcmVhdGVkX2J5ID0gYXV0aC51aWQoKSBPUiBwdWJsaWMuaXNfb3JnX2FkbWluKG9yZ2FuaXphdGlvbl9pZCkpCiAgICAgICkKICAgICkKICAgIFdJVEggQ0hFQ0sgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLm9yZGVycwogICAgICAgIFdIRVJFIGlkID0gb3JkZXJfaXRlbXMub3JkZXJfaWQKICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgKQogICAgKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTI6IFBPTElDSUVTIC0gUEFZTUVOVFMgKGd1YXJkZWQ6IHRhYmxlIG1heSBub3QgZXhpc3QgeWV0KQogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBJRiBFWElTVFMgKFNFTEVDVCAxIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyBXSEVSRSB0YWJsZV9zY2hlbWE9J3B1YmxpYycgQU5EIHRhYmxlX25hbWU9J3BheW1lbnRzJykgVEhFTgogICAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X3BheW1lbnRzIiBPTiBwdWJsaWMucGF5bWVudHM7CiAgICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X3BheW1lbnRzIgogICAgICBPTiBwdWJsaWMucGF5bWVudHMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICAgIFVTSU5HICgKICAgICAgICBFWElTVFMgKAogICAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMub3JkZXJzCiAgICAgICAgICBXSEVSRSBpZCA9IHBheW1lbnRzLm9yZGVyX2lkCiAgICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgICApCiAgICAgICk7CgogICAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfYWRtaW5zX21hbmFnZV9wYXltZW50cyIgT04gcHVibGljLnBheW1lbnRzOwogICAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19tYW5hZ2VfcGF5bWVudHMiCiAgICAgIE9OIHB1YmxpYy5wYXltZW50cyBGT1IgQUxMIFRPIGF1dGhlbnRpY2F0ZWQKICAgICAgVVNJTkcgKAogICAgICAgIEVYSVNUUyAoCiAgICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5vcmRlcnMKICAgICAgICAgIFdIRVJFIGlkID0gcGF5bWVudHMub3JkZXJfaWQKICAgICAgICAgICAgQU5EIHB1YmxpYy5pc19vcmdfYWRtaW4ob3JnYW5pemF0aW9uX2lkKQogICAgICAgICkKICAgICAgKQogICAgICBXSVRIIENIRUNLICgKICAgICAgICBFWElTVFMgKAogICAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMub3JkZXJzCiAgICAgICAgICBXSEVSRSBpZCA9IHBheW1lbnRzLm9yZGVyX2lkCiAgICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgICApCiAgICAgICk7CiAgRU5EIElGOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxMzogUE9MSUNJRVMgLSBCSVRSSVhfQ0xJRU5UUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19tZW1iZXJzX3ZpZXdfY2xpZW50cyIgT04gcHVibGljLmJpdHJpeF9jbGllbnRzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX3ZpZXdfY2xpZW50cyIKICAgIE9OIHB1YmxpYy5iaXRyaXhfY2xpZW50cyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19hZG1pbnNfbWFuYWdlX2NsaWVudHMiIE9OIHB1YmxpYy5iaXRyaXhfY2xpZW50czsKICBDUkVBVEUgUE9MSUNZICJvcmdfYWRtaW5zX21hbmFnZV9jbGllbnRzIgogICAgT04gcHVibGljLmJpdHJpeF9jbGllbnRzIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSkKICAgIFdJVEggQ0hFQ0sgKHB1YmxpYy5pc19vcmdfb3duZXJfb3JfYWRtaW4ob3JnYW5pemF0aW9uX2lkKSk7CgogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIC0tIFBBUlRFIDE0OiBQT0xJQ0lFUyAtIE1PQ0tVUFMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X21vY2t1cF9qb2JzIiBPTiBwdWJsaWMubW9ja3VwX2dlbmVyYXRpb25fam9iczsKICBDUkVBVEUgUE9MSUNZICJvcmdfbWVtYmVyc192aWV3X21vY2t1cF9qb2JzIgogICAgT04gcHVibGljLm1vY2t1cF9nZW5lcmF0aW9uX2pvYnMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc19jcmVhdGVfbW9ja3VwX2pvYnMiIE9OIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzOwogIENSRUFURSBQT0xJQ1kgIm9yZ19tZW1iZXJzX2NyZWF0ZV9tb2NrdXBfam9icyIKICAgIE9OIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzIEZPUiBJTlNFUlQgVE8gYXV0aGVudGljYXRlZAogICAgV0lUSCBDSEVDSyAocHVibGljLnVzZXJfaXNfb3JnX21lbWJlcihvcmdhbml6YXRpb25faWQpKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X2dlbmVyYXRlZF9tb2NrdXBzIiBPTiBwdWJsaWMuZ2VuZXJhdGVkX21vY2t1cHM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19nZW5lcmF0ZWRfbW9ja3VwcyIKICAgIE9OIHB1YmxpYy5nZW5lcmF0ZWRfbW9ja3VwcyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy5tb2NrdXBfZ2VuZXJhdGlvbl9qb2JzCiAgICAgICAgV0hFUkUgaWQgPSBnZW5lcmF0ZWRfbW9ja3Vwcy5qb2JfaWQKICAgICAgICAgIEFORCBwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkKICAgICAgKQogICAgKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTU6IFBPTElDSUVTIC0gQ09MTEVDVElPTlMKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJvcmdfbWVtYmVyc192aWV3X2NvbGxlY3Rpb25zIiBPTiBwdWJsaWMuY29sbGVjdGlvbnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX21lbWJlcnNfdmlld19jb2xsZWN0aW9ucyIKICAgIE9OIHB1YmxpYy5jb2xsZWN0aW9ucyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChwdWJsaWMudXNlcl9pc19vcmdfbWVtYmVyKG9yZ2FuaXphdGlvbl9pZCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgIm9yZ19hZG1pbnNfbWFuYWdlX2NvbGxlY3Rpb25zIiBPTiBwdWJsaWMuY29sbGVjdGlvbnM7CiAgQ1JFQVRFIFBPTElDWSAib3JnX2FkbWluc19tYW5hZ2VfY29sbGVjdGlvbnMiCiAgICBPTiBwdWJsaWMuY29sbGVjdGlvbnMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKQogICAgV0lUSCBDSEVDSyAocHVibGljLmlzX29yZ19vd25lcl9vcl9hZG1pbihvcmdhbml6YXRpb25faWQpKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTY6IFBPTElDSUVTIC0gUEVSU09OQUxJWkFUSU9OX1RFQ0hOSVFVRVMgKEdMT0JBTCkKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJhbnlvbmVfdmlld190ZWNobmlxdWVzIiBPTiBwdWJsaWMucGVyc29uYWxpemF0aW9uX3RlY2huaXF1ZXM7CiAgQ1JFQVRFIFBPTElDWSAiYW55b25lX3ZpZXdfdGVjaG5pcXVlcyIKICAgIE9OIHB1YmxpYy5wZXJzb25hbGl6YXRpb25fdGVjaG5pcXVlcyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HIChpc19hY3RpdmUgPSB0cnVlKTsKCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJhZG1pbnNfbWFuYWdlX3RlY2huaXF1ZXMiIE9OIHB1YmxpYy5wZXJzb25hbGl6YXRpb25fdGVjaG5pcXVlczsKICBDUkVBVEUgUE9MSUNZICJhZG1pbnNfbWFuYWdlX3RlY2huaXF1ZXMiCiAgICBPTiBwdWJsaWMucGVyc29uYWxpemF0aW9uX3RlY2huaXF1ZXMgRk9SIEFMTCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAoCiAgICAgIEVYSVNUUyAoCiAgICAgICAgU0VMRUNUIDEgRlJPTSBwdWJsaWMudXNlcl9vcmdhbml6YXRpb25zCiAgICAgICAgV0hFUkUgdXNlcl9pZCA9IGF1dGgudWlkKCkKICAgICAgICAgIEFORCByb2xlIElOICgnb3duZXInLCAnYWRtaW4nKQogICAgICApCiAgICApOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxNzogUE9MSUNJRVMgLSBOT1RJRklDQVRJT05TIChVU0VSLVNDT1BFRCkKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgRFJPUCBQT0xJQ1kgSUYgRVhJU1RTICJ1c2Vyc192aWV3X293bl9ub3RpZmljYXRpb25zIiBPTiBwdWJsaWMubm90aWZpY2F0aW9uczsKICBDUkVBVEUgUE9MSUNZICJ1c2Vyc192aWV3X293bl9ub3RpZmljYXRpb25zIgogICAgT04gcHVibGljLm5vdGlmaWNhdGlvbnMgRk9SIFNFTEVDVCBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAodXNlcl9pZCA9IGF1dGgudWlkKCkpOwoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgInVzZXJzX3VwZGF0ZV9vd25fbm90aWZpY2F0aW9ucyIgT04gcHVibGljLm5vdGlmaWNhdGlvbnM7CiAgQ1JFQVRFIFBPTElDWSAidXNlcnNfdXBkYXRlX293bl9ub3RpZmljYXRpb25zIgogICAgT04gcHVibGljLm5vdGlmaWNhdGlvbnMgRk9SIFVQREFURSBUTyBhdXRoZW50aWNhdGVkCiAgICBVU0lORyAodXNlcl9pZCA9IGF1dGgudWlkKCkpOwoKICAtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAtLSBQQVJURSAxODogUE9MSUNJRVMgLSBTWVNURU0gVEFCTEVTIChBRE1JTiBPTkxZKQogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBEUk9QIFBPTElDWSBJRiBFWElTVFMgImFkbWluc192aWV3X2ZlYXR1cmVfZmxhZ3MiIE9OIHB1YmxpYy5mZWF0dXJlX2ZsYWdzOwogIENSRUFURSBQT0xJQ1kgImFkbWluc192aWV3X2ZlYXR1cmVfZmxhZ3MiCiAgICBPTiBwdWJsaWMuZmVhdHVyZV9mbGFncyBGT1IgU0VMRUNUIFRPIGF1dGhlbnRpY2F0ZWQKICAgIFVTSU5HICgKICAgICAgRVhJU1RTICgKICAgICAgICBTRUxFQ1QgMSBGUk9NIHB1YmxpYy51c2VyX29yZ2FuaXphdGlvbnMKICAgICAgICBXSEVSRSB1c2VyX2lkID0gYXV0aC51aWQoKQogICAgICAgICAgQU5EIHJvbGUgSU4gKCdvd25lcicsICdhZG1pbicpCiAgICAgICkKICAgICk7CgogIERST1AgUE9MSUNZIElGIEVYSVNUUyAiYWRtaW5zX21hbmFnZV9zeXN0ZW1fc2V0dGluZ3MiIE9OIHB1YmxpYy5zeXN0ZW1fc2V0dGluZ3M7CiAgQ1JFQVRFIFBPTElDWSAiYWRtaW5zX21hbmFnZV9zeXN0ZW1fc2V0dGluZ3MiCiAgICBPTiBwdWJsaWMuc3lzdGVtX3NldHRpbmdzIEZPUiBBTEwgVE8gYXV0aGVudGljYXRlZAogICAgVVNJTkcgKAogICAgICBFWElTVFMgKAogICAgICAgIFNFTEVDVCAxIEZST00gcHVibGljLnVzZXJfb3JnYW5pemF0aW9ucwogICAgICAgIFdIRVJFIHVzZXJfaWQgPSBhdXRoLnVpZCgpCiAgICAgICAgICBBTkQgcm9sZSBJTiAoJ293bmVyJywgJ2FkbWluJykKICAgICAgKQogICAgKTsKCiAgLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgLS0gUEFSVEUgMTk6IEdSQU5UUwogIC0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICBHUkFOVCBTRUxFQ1QgT04gcHVibGljLmNhdGVnb3JpZXMgVE8gYXV0aGVudGljYXRlZDsKICBHUkFOVCBTRUxFQ1QgT04gcHVibGljLnN1cHBsaWVycyBUTyBhdXRoZW50aWNhdGVkOwogIEdSQU5UIFNFTEVDVCBPTiBwdWJsaWMucHJvZHVjdHMgVE8gYXV0aGVudGljYXRlZDsKICBHUkFOVCBTRUxFQ1QgT04gcHVibGljLnF1b3RlcyBUTyBhdXRoZW50aWNhdGVkOwogIEdSQU5UIFNFTEVDVCBPTiBwdWJsaWMub3JkZXJzIFRPIGF1dGhlbnRpY2F0ZWQ7CiAgSUYgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgV0hFUkUgdGFibGVfc2NoZW1hPSdwdWJsaWMnIEFORCB0YWJsZV9uYW1lPSdwYXltZW50cycpIFRIRU4KICAgIEdSQU5UIFNFTEVDVCBPTiBwdWJsaWMucGF5bWVudHMgVE8gYXV0aGVudGljYXRlZDsKICBFTkQgSUY7CgogIFJBSVNFIE5PVElDRSAnTWlncmF0aW9uIDIwMjUwMTAzXzAyX3Jsc19vcmdhbml6YXRpb25zIGFwcGxpZWQgc3VjY2Vzc2Z1bGx5Lic7CkVORCAkb3V0ZXIkOwo=
^

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

@adm01-debug
Copy link
Copy Markdown
Owner Author

Fechando como duplicata. PR #45 já entregou a infraestrutura equivalente (caminhos _shared/contracts/, envelope 422, v1/v2) e foi mergeado em main em 73b8a82. Próxima onda de migração para mais 13 endpoints está em #69.

@adm01-debug adm01-debug deleted the claude/webhook-contract-tests-swzNU branch May 24, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants