@pipeline-builder/pipeline-data 4.1.24 → 4.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/lib/api/alert-destinations.d.ts +17 -0
  2. package/lib/api/alert-destinations.js +36 -0
  3. package/lib/api/reporting/analytics-queries.d.ts +274 -0
  4. package/lib/api/reporting/analytics-queries.js +598 -0
  5. package/lib/api/reporting/daily-rollup.d.ts +41 -0
  6. package/lib/api/reporting/daily-rollup.js +173 -0
  7. package/lib/api/reporting/deploy-rollup.d.ts +78 -0
  8. package/lib/api/reporting/deploy-rollup.js +203 -0
  9. package/lib/api/reporting/dora-scoring.d.ts +14 -0
  10. package/lib/api/reporting/dora-scoring.js +25 -1
  11. package/lib/api/reporting/dora.js +30 -6
  12. package/lib/api/reporting/failure-classifier.d.ts +54 -0
  13. package/lib/api/reporting/failure-classifier.js +179 -0
  14. package/lib/api/reporting/ingest.d.ts +2 -2
  15. package/lib/api/reporting/ingest.js +129 -4
  16. package/lib/api/reporting/last-deploy.d.ts +31 -0
  17. package/lib/api/reporting/last-deploy.js +93 -0
  18. package/lib/api/reporting/needs-attention.d.ts +93 -0
  19. package/lib/api/reporting/needs-attention.js +152 -0
  20. package/lib/api/reporting/plugin-exposure.d.ts +129 -0
  21. package/lib/api/reporting/plugin-exposure.js +312 -0
  22. package/lib/api/reporting/retention-sweep.js +9 -1
  23. package/lib/api/reporting/sql-helpers.d.ts +35 -2
  24. package/lib/api/reporting/sql-helpers.js +39 -1
  25. package/lib/api/reporting/stakeholder/compose.d.ts +115 -0
  26. package/lib/api/reporting/stakeholder/compose.js +234 -0
  27. package/lib/api/reporting/stakeholder/index.d.ts +14 -0
  28. package/lib/api/reporting/stakeholder/index.js +17 -0
  29. package/lib/api/reporting/stakeholder/period.d.ts +102 -0
  30. package/lib/api/reporting/stakeholder/period.js +273 -0
  31. package/lib/api/reporting/stakeholder/report-html.d.ts +93 -0
  32. package/lib/api/reporting/stakeholder/report-html.js +208 -0
  33. package/lib/api/reporting/stakeholder/sections.d.ts +117 -0
  34. package/lib/api/reporting/stakeholder/sections.js +249 -0
  35. package/lib/api/reporting/stakeholder/store.d.ts +450 -0
  36. package/lib/api/reporting/stakeholder/store.js +981 -0
  37. package/lib/api/reporting/stakeholder/templates.d.ts +21 -0
  38. package/lib/api/reporting/stakeholder/templates.js +104 -0
  39. package/lib/api/reporting/types.d.ts +73 -0
  40. package/lib/api/reporting/types.js +1 -1
  41. package/lib/api/reporting-service.d.ts +94 -5
  42. package/lib/api/reporting-service.js +169 -10
  43. package/lib/api/soft-delete-sweep.d.ts +11 -2
  44. package/lib/api/soft-delete-sweep.js +17 -6
  45. package/lib/database/drizzle-schema.d.ts +2263 -385
  46. package/lib/database/drizzle-schema.js +18 -7
  47. package/lib/database/index.d.ts +1 -1
  48. package/lib/database/index.js +4 -2
  49. package/lib/database/schema/compliance.d.ts +0 -682
  50. package/lib/database/schema/compliance.js +6 -66
  51. package/lib/database/schema/ecosystem.d.ts +20 -157
  52. package/lib/database/schema/ecosystem.js +23 -16
  53. package/lib/database/schema/pipeline.d.ts +200 -0
  54. package/lib/database/schema/pipeline.js +100 -1
  55. package/lib/database/schema/plugin.d.ts +20 -1
  56. package/lib/database/schema/plugin.js +13 -1
  57. package/lib/database/schema/reporting-analytics.d.ts +1212 -0
  58. package/lib/database/schema/reporting-analytics.js +250 -0
  59. package/lib/database/schema/reporting-stakeholder.d.ts +1405 -0
  60. package/lib/database/schema/reporting-stakeholder.js +251 -0
  61. package/lib/index.d.ts +10 -1
  62. package/lib/index.js +15 -1
  63. package/lib/testing/exports.json +67 -4
  64. package/package.json +4 -3
@@ -0,0 +1,179 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * The rules, most specific first.
5
+ *
6
+ * Read this as the taxonomy itself. Each entry answers "what would somebody DO
7
+ * about this", which is why e.g. `permissions` and `authentication` are separate:
8
+ * one is a policy change, the other is a credential.
9
+ */
10
+ const RULES = [
11
+ // Credentials and policy first: their messages often also contain words that
12
+ // would otherwise match `external_service` or `configuration`.
13
+ {
14
+ category: 'permissions',
15
+ patterns: [
16
+ /accessdenied/, /access denied/, /not authorized to perform/, /forbidden/,
17
+ /explicit deny/, /assumerole.*denied/, /iam.*permission/, /insufficient privileges/,
18
+ ],
19
+ },
20
+ {
21
+ category: 'authentication',
22
+ patterns: [
23
+ /unauthorized/, /401/, /authentication failed/, /invalid credentials/,
24
+ /expired token/, /token.*expired/, /no basic auth/, /bad credentials/,
25
+ /could not be authenticated/,
26
+ ],
27
+ },
28
+ {
29
+ category: 'source_checkout',
30
+ patterns: [
31
+ /could not resolve host: github/, /repository not found/, /fatal: could not read/,
32
+ /git clone.*failed/, /reference is not a tree/, /unable to access.*\.git/,
33
+ /source.*checkout.*failed/, /codecommit.*not found/,
34
+ ],
35
+ },
36
+ {
37
+ category: 'dependency',
38
+ patterns: [
39
+ /npm err!.*(?:e404|etarget|eresolve)/, /could not resolve dependency/,
40
+ /no matching version found/, /unable to resolve dependency tree/,
41
+ /could not find a version that satisfies/, /pip.*could not find/,
42
+ /go: .*: unknown revision/, /maven.*could not resolve dependencies/,
43
+ /bundler.*could not find/, /cargo.*failed to select a version/,
44
+ /peer dep/, /lockfile.*out of sync/,
45
+ ],
46
+ },
47
+ {
48
+ category: 'unit_test',
49
+ patterns: [/tests? failed/, /assertion(?:error)? failed/, /\d+ (?:tests?|specs?) failed/, /jest.*fail/, /pytest.*failed/],
50
+ action: /test|spec|jest|pytest|junit/i,
51
+ },
52
+ {
53
+ category: 'integration_test',
54
+ patterns: [/tests? failed/, /assertion(?:error)? failed/, /connection refused/],
55
+ action: /integration|e2e|smoke|acceptance|contract/i,
56
+ },
57
+ {
58
+ category: 'security_scan',
59
+ patterns: [
60
+ /vulnerabilit/, /cve-\d{4}/, /grype/, /trivy/, /sast/, /dependency check failed/,
61
+ /secret detected/, /license violation/, /policy violation.*scan/,
62
+ ],
63
+ },
64
+ {
65
+ category: 'timeout',
66
+ patterns: [
67
+ /timed? ?out/, /etimedout/, /deadline exceeded/, /exceeded the.*timeout/,
68
+ /build.*exceeded.*minutes/, /context deadline/,
69
+ ],
70
+ },
71
+ {
72
+ category: 'resource_exhaustion',
73
+ patterns: [
74
+ /out of memory/, /oomkilled/, /cannot allocate memory/, /no space left on device/,
75
+ /disk quota exceeded/, /enospc/, /too many open files/, /killed.*signal 9/,
76
+ /javascript heap out of memory/,
77
+ ],
78
+ },
79
+ {
80
+ category: 'deployment',
81
+ patterns: [
82
+ /cloudformation.*rollback/, /stack.*rollback_complete/, /create_failed/, /update_rollback/,
83
+ /cdk deploy.*failed/, /ecs.*deployment.*failed/, /deployment.*circuit breaker/,
84
+ /health check.*failed.*target group/,
85
+ ],
86
+ },
87
+ {
88
+ category: 'infrastructure',
89
+ patterns: [
90
+ /throttl/, /rate exceeded/, /limitexceeded/, /servicequotaexceeded/,
91
+ /capacity/, /insufficientinstancecapacity/, /host.*unreachable/,
92
+ /internal service error/, /5\d\d.*aws/,
93
+ ],
94
+ },
95
+ {
96
+ category: 'external_service',
97
+ patterns: [
98
+ /could not resolve host/, /enotfound/, /econnrefused/, /econnreset/,
99
+ /getaddrinfo/, /socket hang up/, /bad gateway/, /502|503|504/,
100
+ /upstream.*unavailable/, /registry.*unreachable/,
101
+ ],
102
+ },
103
+ {
104
+ category: 'configuration',
105
+ patterns: [
106
+ /is not defined/, /no such file or directory/, /enoent/, /invalid.*configuration/,
107
+ /missing required.*(?:variable|parameter|input)/,
108
+ // Both orders: "yaml parse error" and "error parsing YAML".
109
+ /yaml.*(?:parse|parsing|syntax)/, /(?:parse|parsing|syntax).*yaml/,
110
+ /unexpected token.*json/, /buildspec/, /command not found/,
111
+ ],
112
+ },
113
+ {
114
+ category: 'build',
115
+ patterns: [
116
+ /compilation (?:failed|error)/, /error ts\d+/, /syntax error/, /cannot find module/,
117
+ /undefined reference/, /build failed/, /webpack.*error/, /tsc.*error/,
118
+ /docker build.*failed/, /failed to solve/,
119
+ ],
120
+ },
121
+ ];
122
+ /**
123
+ * The category for a failed action.
124
+ *
125
+ * `null` for anything that is not a failure — the caller stores nothing rather
126
+ * than labelling a success, so a category's presence always means "this broke".
127
+ */
128
+ export function classifyFailure(input) {
129
+ const failed = /^(FAILED|FAILURE|ERROR|TIMED_OUT)$/i.test(input.status);
130
+ if (!failed)
131
+ return null;
132
+ const text = (input.errorMessage ?? '').toLowerCase();
133
+ const where = `${input.actionName ?? ''} ${input.stageName ?? ''}`;
134
+ for (const rule of RULES) {
135
+ if (rule.action && !rule.action.test(where))
136
+ continue;
137
+ if (rule.patterns.some((p) => p.test(text)))
138
+ return rule.category;
139
+ }
140
+ // Nothing matched. `other` rather than a guess, and counted, so the share of
141
+ // `other` measures how good the rules are and names the gap to close.
142
+ return 'other';
143
+ }
144
+ /**
145
+ * A human label for a category, for the report and the UI.
146
+ *
147
+ * Phrased as what broke rather than as an enum: a manager reading
148
+ * "Dependency resolution" understands it, and `integration_test` does not.
149
+ */
150
+ export const FAILURE_CATEGORY_LABELS = {
151
+ source_checkout: 'Source checkout',
152
+ dependency: 'Dependency resolution',
153
+ build: 'Build / compile',
154
+ unit_test: 'Unit tests',
155
+ integration_test: 'Integration tests',
156
+ security_scan: 'Security scan',
157
+ infrastructure: 'Cloud infrastructure',
158
+ deployment: 'Deployment',
159
+ authentication: 'Authentication',
160
+ permissions: 'Permissions',
161
+ configuration: 'Configuration',
162
+ timeout: 'Timeout',
163
+ resource_exhaustion: 'Out of resources',
164
+ external_service: 'External service',
165
+ other: 'Unclassified',
166
+ };
167
+ /**
168
+ * Whether a category is something the TEAM can act on, as opposed to something
169
+ * that happened to them.
170
+ *
171
+ * Used by the failure-analysis section to separate the two, because a week whose
172
+ * failures were all cloud throttling is a different conversation from one whose
173
+ * failures were all broken tests — and presenting them in one ranked list invites
174
+ * exactly the wrong conclusion.
175
+ */
176
+ export function isTeamActionable(category) {
177
+ return !['infrastructure', 'external_service'].includes(category);
178
+ }
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpbHVyZS1jbGFzc2lmaWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvZmFpbHVyZS1jbGFzc2lmaWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUEwQ3RDOzs7Ozs7R0FNRztBQUNILE1BQU0sS0FBSyxHQUFXO0lBQ3BCLDZFQUE2RTtJQUM3RSwrREFBK0Q7SUFDL0Q7UUFDRSxRQUFRLEVBQUUsYUFBYTtRQUN2QixRQUFRLEVBQUU7WUFDUixjQUFjLEVBQUUsZUFBZSxFQUFFLDJCQUEyQixFQUFFLFdBQVc7WUFDekUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLHlCQUF5QjtTQUNwRjtLQUNGO0lBQ0Q7UUFDRSxRQUFRLEVBQUUsZ0JBQWdCO1FBQzFCLFFBQVEsRUFBRTtZQUNSLGNBQWMsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCO1lBQ3JFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsaUJBQWlCO1lBQ3JFLDRCQUE0QjtTQUM3QjtLQUNGO0lBQ0Q7UUFDRSxRQUFRLEVBQUUsaUJBQWlCO1FBQzNCLFFBQVEsRUFBRTtZQUNSLGdDQUFnQyxFQUFFLHNCQUFzQixFQUFFLHVCQUF1QjtZQUNqRixtQkFBbUIsRUFBRSx5QkFBeUIsRUFBRSx5QkFBeUI7WUFDekUsMEJBQTBCLEVBQUUsdUJBQXVCO1NBQ3BEO0tBQ0Y7SUFDRDtRQUNFLFFBQVEsRUFBRSxZQUFZO1FBQ3RCLFFBQVEsRUFBRTtZQUNSLHFDQUFxQyxFQUFFLDhCQUE4QjtZQUNyRSwyQkFBMkIsRUFBRSxtQ0FBbUM7WUFDaEUseUNBQXlDLEVBQUUscUJBQXFCO1lBQ2hFLDBCQUEwQixFQUFFLHVDQUF1QztZQUNuRSx5QkFBeUIsRUFBRSxtQ0FBbUM7WUFDOUQsVUFBVSxFQUFFLHVCQUF1QjtTQUNwQztLQUNGO0lBQ0Q7UUFDRSxRQUFRLEVB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bGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBXaGF0IEtJTkQgb2YgdGhpbmcgYnJva2UuXG4gKlxuICogXCIzNCBmYWlsdXJlcyB0aGlzIHdlZWtcIiBpcyBub3QgYWN0aW9uYWJsZS4gXCIxOCBvZiB0aGVtIHdlcmUgZGVwZW5kZW5jeVxuICogcmVzb2x1dGlvbiwgYW5kIHRoZXkgYXJlIGFsbCBpbiBvbmUgcGlwZWxpbmVcIiBpcy4gVGhhdCBpcyB0aGUgd2hvbGUgcmVhc29uIHRoaXNcbiAqIGV4aXN0cyDigJQgYW5kIGl0IGlzIGFsc28gd2h5IHRoZSBjbGFzc2lmaWNhdGlvbiBoYXBwZW5zIGF0IElOR0VTVCByYXRoZXIgdGhhbiBhdFxuICogcmVhZCB0aW1lOiBlcnJvciB0ZXh0IGlzIHNjcnViYmVkIG9mIEFXUyBpZGVudGlmaWVycyBhdCB0aGUgcGVyc2lzdGVuY2UgYm91bmRhcnlcbiAqIGFuZCBldmVudHVhbGx5IHN3ZXB0IGJ5IHJldGVudGlvbiwgc28gYSBjYXRlZ29yeSBkZXJpdmVkIGxhdGVyIHdvdWxkIGhhdmVcbiAqIG5vdGhpbmcgbGVmdCB0byByZWFkLlxuICpcbiAqIFRIRSBSVUxFUyBBUkUgREFUQS4gQSBjYXRlZ29yeSBpcyBhIHByb3ZpZGVyL2FjdGlvbiBtYXRjaCBwbHVzIGFuIG9yZGVyZWQgbGlzdFxuICogb2YgcGF0dGVybnMgb3ZlciB0aGUgZXJyb3IgdGV4dCwgaW4gb25lIHRhYmxlIGJlbG93LCBzbyB0aGUgdGF4b25vbXkgY2FuIGdyb3dcbiAqIGZyb20gcmVhbCBtaXNzZXMgd2l0aG91dCB0b3VjaGluZyB0aGUgY2xhc3NpZmllci4gQW55dGhpbmcgdW5tYXRjaGVkIGxhbmRzIGluXG4gKiBgb3RoZXJgIGFuZCBpcyBjb3VudGVkLCBzbyB0aGUgc2l6ZSBvZiBgb3RoZXJgIGlzIHRoZSBtZWFzdXJlIG9mIGhvdyBnb29kIHRoZVxuICogcnVsZXMgYXJlLlxuICpcbiAqIFRIRSBDQVRFR09SSUVTIE9WRVJMQVAgVEhFIFBMVUdJTi1CVUlMRCBUQVhPTk9NWSBPTiBQVVJQT1NFLiBBIGRlcGVuZGVuY3lcbiAqIGZhaWx1cmUgaXMgYSBkZXBlbmRlbmN5IGZhaWx1cmUgd2hldGhlciBpdCBoYXBwZW5lZCBidWlsZGluZyBhIHBsdWdpbiBvciBydW5uaW5nXG4gKiBvbmU7IHR3byB2b2NhYnVsYXJpZXMgZm9yIHRoZSBzYW1lIHRoaW5nIHdvdWxkIG1ha2UgdGhlIHJlcG9ydCBhbmQgdGhlIGJ1aWxkXG4gKiBxdWV1ZSBkaXNhZ3JlZSBhYm91dCB0aGUgc2FtZSBpbmNpZGVudC5cbiAqXG4gKiBXSEFUIFRIRSBBSSBFVkVSIFNFRVMgaXMgdGhlIGNhdGVnb3J5LCBuZXZlciB0aGUgcmF3IGVycm9yLiBFcnJvciB0ZXh0IGZyb20gYVxuICogY3VzdG9tZXIncyBidWlsZCBpcyB0aGUgbGFzdCB0aGluZyB0aGF0IHNob3VsZCByZWFjaCBhIG1vZGVsLlxuICovXG5cbmltcG9ydCB0eXBlIHsgRmFpbHVyZUNhdGVnb3J5IH0gZnJvbSAnLi4vLi4vZGF0YWJhc2Uvc2NoZW1hL3JlcG9ydGluZy1hbmFseXRpY3MuanMnO1xuXG4vKiogT25lIGNsYXNzaWZpY2F0aW9uIHJ1bGU6IHRoZSBjYXRlZ29yeSwgYW5kIGhvdyB0byByZWNvZ25pc2UgaXQuICovXG5pbnRlcmZhY2UgUnVsZSB7XG4gIGNhdGVnb3J5OiBGYWlsdXJlQ2F0ZWdvcnk7XG4gIC8qKlxuICAgKiBPcmRlcmVkIHBhdHRlcm5zIG92ZXIgdGhlIGxvd2VyY2FzZWQgZXJyb3IgdGV4dC4gRmlyc3QgcnVsZSB3aXRoIGFueSBtYXRjaFxuICAgKiB3aW5zLCBzbyB0aGUgdGFibGUncyBPUkRFUiBpcyBwYXJ0IG9mIGl0cyBtZWFuaW5nOiB0aGUgc3BlY2lmaWMgY2FzZXMgY29tZVxuICAgKiBiZWZvcmUgdGhlIGdlbmVyYWwgb25lcy5cbiAgICovXG4gIHBhdHRlcm5zOiBSZWdFeHBbXTtcbiAgLyoqIFdoZW4gc2V0LCB0aGUgcnVsZSBvbmx5IGFwcGxpZXMgdG8gYW4gYWN0aW9uL3N0YWdlIG5hbWUgbWF0Y2hpbmcgdGhpcy4gKi9cbiAgYWN0aW9uPzogUmVnRXhwO1xufVxuXG4vKipcbiAqIFRoZSBydWxlcywgbW9zdCBzcGVjaWZpYyBmaXJzdC5cbiAqXG4gKiBSZWFkIHRoaXMgYXMgdGhlIHRheG9ub215IGl0c2VsZi4gRWFjaCBlbnRyeSBhbnN3ZXJzIFwid2hhdCB3b3VsZCBzb21lYm9keSBET1xuICogYWJvdXQgdGhpc1wiLCB3aGljaCBpcyB3aHkgZS5nLiBgcGVybWlzc2lvbnNgIGFuZCBgYXV0aGVudGljYXRpb25gIGFyZSBzZXBhcmF0ZTpcbiAqIG9uZSBpcyBhIHBvbGljeSBjaGFuZ2UsIHRoZSBvdGhlciBpcyBhIGNyZWRlbnRpYWwuXG4gKi9cbmNvbnN0IFJVTEVTOiBSdWxlW10gPSBbXG4gIC8vIENyZWRlbnRpYWxzIGFuZCBwb2xpY3kgZmlyc3Q6IHRoZWlyIG1lc3NhZ2VzIG9mdGVuIGFsc28gY29udGFpbiB3b3JkcyB0aGF0XG4gIC8vIHdvdWxkIG90aGVyd2lzZSBtYXRjaCBgZXh0ZXJuYWxfc2VydmljZWAgb3IgYGNvbmZpZ3VyYXRpb25gLlxuICB7XG4gICAgY2F0ZWdvcnk6ICdwZXJtaXNzaW9ucycsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9hY2Nlc3NkZW5pZWQvLCAvYWNjZXNzIGRlbmllZC8sIC9ub3QgYXV0aG9yaXplZCB0byBwZXJmb3JtLywgL2ZvcmJpZGRlbi8sXG4gICAgICAvZXhwbGljaXQgZGVueS8sIC9hc3N1bWVyb2xlLipkZW5pZWQvLCAvaWFtLipwZXJtaXNzaW9uLywgL2luc3VmZmljaWVudCBwcml2aWxlZ2VzLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdhdXRoZW50aWNhdGlvbicsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC91bmF1dGhvcml6ZWQvLCAvNDAxLywgL2F1dGhlbnRpY2F0aW9uIGZhaWxlZC8sIC9pbnZhbGlkIGNyZWRlbnRpYWxzLyxcbiAgICAgIC9leHBpcmVkIHRva2VuLywgL3Rva2VuLipleHBpcmVkLywgL25vIGJhc2ljIGF1dGgvLCAvYmFkIGNyZWRlbnRpYWxzLyxcbiAgICAgIC9jb3VsZCBub3QgYmUgYXV0aGVudGljYXRlZC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnc291cmNlX2NoZWNrb3V0JyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL2NvdWxkIG5vdCByZXNvbHZlIGhvc3Q6IGdpdGh1Yi8sIC9yZXBvc2l0b3J5IG5vdCBmb3VuZC8sIC9mYXRhbDogY291bGQgbm90IHJlYWQvLFxuICAgICAgL2dpdCBjbG9uZS4qZmFpbGVkLywgL3JlZmVyZW5jZSBpcyBub3QgYSB0cmVlLywgL3VuYWJsZSB0byBhY2Nlc3MuKlxcLmdpdC8sXG4gICAgICAvc291cmNlLipjaGVja291dC4qZmFpbGVkLywgL2NvZGVjb21taXQuKm5vdCBmb3VuZC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnZGVwZW5kZW5jeScsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9ucG0gZXJyIS4qKD86ZTQwNHxldGFyZ2V0fGVyZXNvbHZlKS8sIC9jb3VsZCBub3QgcmVzb2x2ZSBkZXBlbmRlbmN5LyxcbiAgICAgIC9ubyBtYXRjaGluZyB2ZXJzaW9uIGZvdW5kLywgL3VuYWJsZSB0byByZXNvbHZlIGRlcGVuZGVuY3kgdHJlZS8sXG4gICAgICAvY291bGQgbm90IGZpbmQgYSB2ZXJzaW9uIHRoYXQgc2F0aXNmaWVzLywgL3BpcC4qY291bGQgbm90IGZpbmQvLFxuICAgICAgL2dvOiAuKjogdW5rbm93biByZXZpc2lvbi8sIC9tYXZlbi4qY291bGQgbm90IHJlc29sdmUgZGVwZW5kZW5jaWVzLyxcbiAgICAgIC9idW5kbGVyLipjb3VsZCBub3QgZmluZC8sIC9jYXJnby4qZmFpbGVkIHRvIHNlbGVjdCBhIHZlcnNpb24vLFxuICAgICAgL3BlZXIgZGVwLywgL2xvY2tmaWxlLipvdXQgb2Ygc3luYy8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAndW5pdF90ZXN0JyxcbiAgICBwYXR0ZXJuczogWy90ZXN0cz8gZmFpbGVkLywgL2Fzc2VydGlvbig/OmVycm9yKT8gZmFpbGVkLywgL1xcZCsgKD86dGVzdHM/fHNwZWNzPykgZmFpbGVkLywgL2plc3QuKmZhaWwvLCAvcHl0ZXN0LipmYWlsZWQvXSxcbiAgICBhY3Rpb246IC90ZXN0fHNwZWN8amVzdHxweXRlc3R8anVuaXQvaSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnaW50ZWdyYXRpb25fdGVzdCcsXG4gICAgcGF0dGVybnM6IFsvdGVzdHM/IGZhaWxlZC8sIC9hc3NlcnRpb24oPzplcnJvcik/IGZhaWxlZC8sIC9jb25uZWN0aW9uIHJlZnVzZWQvXSxcbiAgICBhY3Rpb246IC9pbnRlZ3JhdGlvbnxlMmV8c21va2V8YWNjZXB0YW5jZXxjb250cmFjdC9pLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdzZWN1cml0eV9zY2FuJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL3Z1bG5lcmFiaWxpdC8sIC9jdmUtXFxkezR9LywgL2dyeXBlLywgL3RyaXZ5LywgL3Nhc3QvLCAvZGVwZW5kZW5jeSBjaGVjayBmYWlsZWQvLFxuICAgICAgL3NlY3JldCBkZXRlY3RlZC8sIC9saWNlbnNlIHZpb2xhdGlvbi8sIC9wb2xpY3kgdmlvbGF0aW9uLipzY2FuLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICd0aW1lb3V0JyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL3RpbWVkPyA/b3V0LywgL2V0aW1lZG91dC8sIC9kZWFkbGluZSBleGNlZWRlZC8sIC9leGNlZWRlZCB0aGUuKnRpbWVvdXQvLFxuICAgICAgL2J1aWxkLipleGNlZWRlZC4qbWludXRlcy8sIC9jb250ZXh0IGRlYWRsaW5lLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdyZXNvdXJjZV9leGhhdXN0aW9uJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL291dCBvZiBtZW1vcnkvLCAvb29ta2lsbGVkLywgL2Nhbm5vdCBhbGxvY2F0ZSBtZW1vcnkvLCAvbm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UvLFxuICAgICAgL2Rpc2sgcXVvdGEgZXhjZWVkZWQvLCAvZW5vc3BjLywgL3RvbyBtYW55IG9wZW4gZmlsZXMvLCAva2lsbGVkLipzaWduYWwgOS8sXG4gICAgICAvamF2YXNjcmlwdCBoZWFwIG91dCBvZiBtZW1vcnkvLFxuICAgIF0sXG4gIH0sXG4gIHtcbiAgICBjYXRlZ29yeTogJ2RlcGxveW1lbnQnLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvY2xvdWRmb3JtYXRpb24uKnJvbGxiYWNrLywgL3N0YWNrLipyb2xsYmFja19jb21wbGV0ZS8sIC9jcmVhdGVfZmFpbGVkLywgL3VwZGF0ZV9yb2xsYmFjay8sXG4gICAgICAvY2RrIGRlcGxveS4qZmFpbGVkLywgL2Vjcy4qZGVwbG95bWVudC4qZmFpbGVkLywgL2RlcGxveW1lbnQuKmNpcmN1aXQgYnJlYWtlci8sXG4gICAgICAvaGVhbHRoIGNoZWNrLipmYWlsZWQuKnRhcmdldCBncm91cC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnaW5mcmFzdHJ1Y3R1cmUnLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvdGhyb3R0bC8sIC9yYXRlIGV4Y2VlZGVkLywgL2xpbWl0ZXhjZWVkZWQvLCAvc2VydmljZXF1b3RhZXhjZWVkZWQvLFxuICAgICAgL2NhcGFjaXR5LywgL2luc3VmZmljaWVudGluc3RhbmNlY2FwYWNpdHkvLCAvaG9zdC4qdW5yZWFjaGFibGUvLFxuICAgICAgL2ludGVybmFsIHNlcnZpY2UgZXJyb3IvLCAvNVxcZFxcZC4qYXdzLyxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgY2F0ZWdvcnk6ICdleHRlcm5hbF9zZXJ2aWNlJyxcbiAgICBwYXR0ZXJuczogW1xuICAgICAgL2NvdWxkIG5vdCByZXNvbHZlIGhvc3QvLCAvZW5vdGZvdW5kLywgL2Vjb25ucmVmdXNlZC8sIC9lY29ubnJlc2V0LyxcbiAgICAgIC9nZXRhZGRyaW5mby8sIC9zb2NrZXQgaGFuZyB1cC8sIC9iYWQgZ2F0ZXdheS8sIC81MDJ8NTAzfDUwNC8sXG4gICAgICAvdXBzdHJlYW0uKnVuYXZhaWxhYmxlLywgL3JlZ2lzdHJ5Lip1bnJlYWNoYWJsZS8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgcGF0dGVybnM6IFtcbiAgICAgIC9pcyBub3QgZGVmaW5lZC8sIC9ubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5LywgL2Vub2VudC8sIC9pbnZhbGlkLipjb25maWd1cmF0aW9uLyxcbiAgICAgIC9taXNzaW5nIHJlcXVpcmVkLiooPzp2YXJpYWJsZXxwYXJhbWV0ZXJ8aW5wdXQpLyxcbiAgICAgIC8vIEJvdGggb3JkZXJzOiBcInlhbWwgcGFyc2UgZXJyb3JcIiBhbmQgXCJlcnJvciBwYXJzaW5nIFlBTUxcIi5cbiAgICAgIC95YW1sLiooPzpwYXJzZXxwYXJzaW5nfHN5bnRheCkvLCAvKD86cGFyc2V8cGFyc2luZ3xzeW50YXgpLip5YW1sLyxcbiAgICAgIC91bmV4cGVjdGVkIHRva2VuLipqc29uLywgL2J1aWxkc3BlYy8sIC9jb21tYW5kIG5vdCBmb3VuZC8sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGNhdGVnb3J5OiAnYnVpbGQnLFxuICAgIHBhdHRlcm5zOiBbXG4gICAgICAvY29tcGlsYXRpb24gKD86ZmFpbGVkfGVycm9yKS8sIC9lcnJvciB0c1xcZCsvLCAvc3ludGF4IGVycm9yLywgL2Nhbm5vdCBmaW5kIG1vZHVsZS8sXG4gICAgICAvdW5kZWZpbmVkIHJlZmVyZW5jZS8sIC9idWlsZCBmYWlsZWQvLCAvd2VicGFjay4qZXJyb3IvLCAvdHNjLiplcnJvci8sXG4gICAgICAvZG9ja2VyIGJ1aWxkLipmYWlsZWQvLCAvZmFpbGVkIHRvIHNvbHZlLyxcbiAgICBdLFxuICB9LFxuXTtcblxuLyoqXG4gKiBUaGUgY2F0ZWdvcnkgZm9yIGEgZmFpbGVkIGFjdGlvbi5cbiAqXG4gKiBgbnVsbGAgZm9yIGFueXRoaW5nIHRoYXQgaXMgbm90IGEgZmFpbHVyZSDigJQgdGhlIGNhbGxlciBzdG9yZXMgbm90aGluZyByYXRoZXJcbiAqIHRoYW4gbGFiZWxsaW5nIGEgc3VjY2Vzcywgc28gYSBjYXRlZ29yeSdzIHByZXNlbmNlIGFsd2F5cyBtZWFucyBcInRoaXMgYnJva2VcIi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYXNzaWZ5RmFpbHVyZShpbnB1dDoge1xuICBzdGF0dXM6IHN0cmluZztcbiAgZXJyb3JNZXNzYWdlPzogc3RyaW5nIHwgbnVsbDtcbiAgYWN0aW9uTmFtZT86IHN0cmluZyB8IG51bGw7XG4gIHN0YWdlTmFtZT86IHN0cmluZyB8IG51bGw7XG59KTogRmFpbHVyZUNhdGVnb3J5IHwgbnVsbCB7XG4gIGNvbnN0IGZhaWxlZCA9IC9eKEZBSUxFRHxGQUlMVVJFfEVSUk9SfFRJTUVEX09VVCkkL2kudGVzdChpbnB1dC5zdGF0dXMpO1xuICBpZiAoIWZhaWxlZCkgcmV0dXJuIG51bGw7XG5cbiAgY29uc3QgdGV4dCA9IChpbnB1dC5lcnJvck1lc3NhZ2UgPz8gJycpLnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IHdoZXJlID0gYCR7aW5wdXQuYWN0aW9uTmFtZSA/PyAnJ30gJHtpbnB1dC5zdGFnZU5hbWUgPz8gJyd9YDtcblxuICBmb3IgKGNvbnN0IHJ1bGUgb2YgUlVMRVMpIHtcbiAgICBpZiAocnVsZS5hY3Rpb24gJiYgIXJ1bGUuYWN0aW9uLnRlc3Qod2hlcmUpKSBjb250aW51ZTtcbiAgICBpZiAocnVsZS5wYXR0ZXJucy5zb21lKChwKSA9PiBwLnRlc3QodGV4dCkpKSByZXR1cm4gcnVsZS5jYXRlZ29yeTtcbiAgfVxuXG4gIC8vIE5vdGhpbmcgbWF0Y2hlZC4gYG90aGVyYCByYXRoZXIgdGhhbiBhIGd1ZXNzLCBhbmQgY291bnRlZCwgc28gdGhlIHNoYXJlIG9mXG4gIC8vIGBvdGhlcmAgbWVhc3VyZXMgaG93IGdvb2QgdGhlIHJ1bGVzIGFyZSBhbmQgbmFtZXMgdGhlIGdhcCB0byBjbG9zZS5cbiAgcmV0dXJuICdvdGhlcic7XG59XG5cbi8qKlxuICogQSBodW1hbiBsYWJlbCBmb3IgYSBjYXRlZ29yeSwgZm9yIHRoZSByZXBvcnQgYW5kIHRoZSBVSS5cbiAqXG4gKiBQaHJhc2VkIGFzIHdoYXQgYnJva2UgcmF0aGVyIHRoYW4gYXMgYW4gZW51bTogYSBtYW5hZ2VyIHJlYWRpbmdcbiAqIFwiRGVwZW5kZW5jeSByZXNvbHV0aW9uXCIgdW5kZXJzdGFuZHMgaXQsIGFuZCBgaW50ZWdyYXRpb25fdGVzdGAgZG9lcyBub3QuXG4gKi9cbmV4cG9ydCBjb25zdCBGQUlMVVJFX0NBVEVHT1JZX0xBQkVMUzogUmVjb3JkPEZhaWx1cmVDYXRlZ29yeSwgc3RyaW5nPiA9IHtcbiAgc291cmNlX2NoZWNrb3V0OiAnU291cmNlIGNoZWNrb3V0JyxcbiAgZGVwZW5kZW5jeTogJ0RlcGVuZGVuY3kgcmVzb2x1dGlvbicsXG4gIGJ1aWxkOiAnQnVpbGQgLyBjb21waWxlJyxcbiAgdW5pdF90ZXN0OiAnVW5pdCB0ZXN0cycsXG4gIGludGVncmF0aW9uX3Rlc3Q6ICdJbnRlZ3JhdGlvbiB0ZXN0cycsXG4gIHNlY3VyaXR5X3NjYW46ICdTZWN1cml0eSBzY2FuJyxcbiAgaW5mcmFzdHJ1Y3R1cmU6ICdDbG91ZCBpbmZyYXN0cnVjdHVyZScsXG4gIGRlcGxveW1lbnQ6ICdEZXBsb3ltZW50JyxcbiAgYXV0aGVudGljYXRpb246ICdBdXRoZW50aWNhdGlvbicsXG4gIHBlcm1pc3Npb25zOiAnUGVybWlzc2lvbnMnLFxuICBjb25maWd1cmF0aW9uOiAnQ29uZmlndXJhdGlvbicsXG4gIHRpbWVvdXQ6ICdUaW1lb3V0JyxcbiAgcmVzb3VyY2VfZXhoYXVzdGlvbjogJ091dCBvZiByZXNvdXJjZXMnLFxuICBleHRlcm5hbF9zZXJ2aWNlOiAnRXh0ZXJuYWwgc2VydmljZScsXG4gIG90aGVyOiAnVW5jbGFzc2lmaWVkJyxcbn07XG5cbi8qKlxuICogV2hldGhlciBhIGNhdGVnb3J5IGlzIHNvbWV0aGluZyB0aGUgVEVBTSBjYW4gYWN0IG9uLCBhcyBvcHBvc2VkIHRvIHNvbWV0aGluZ1xuICogdGhhdCBoYXBwZW5lZCB0byB0aGVtLlxuICpcbiAqIFVzZWQgYnkgdGhlIGZhaWx1cmUtYW5hbHlzaXMgc2VjdGlvbiB0byBzZXBhcmF0ZSB0aGUgdHdvLCBiZWNhdXNlIGEgd2VlayB3aG9zZVxuICogZmFpbHVyZXMgd2VyZSBhbGwgY2xvdWQgdGhyb3R0bGluZyBpcyBhIGRpZmZlcmVudCBjb252ZXJzYXRpb24gZnJvbSBvbmUgd2hvc2VcbiAqIGZhaWx1cmVzIHdlcmUgYWxsIGJyb2tlbiB0ZXN0cyDigJQgYW5kIHByZXNlbnRpbmcgdGhlbSBpbiBvbmUgcmFua2VkIGxpc3QgaW52aXRlc1xuICogZXhhY3RseSB0aGUgd3JvbmcgY29uY2x1c2lvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVGVhbUFjdGlvbmFibGUoY2F0ZWdvcnk6IEZhaWx1cmVDYXRlZ29yeSk6IGJvb2xlYW4ge1xuICByZXR1cm4gIVsnaW5mcmFzdHJ1Y3R1cmUnLCAnZXh0ZXJuYWxfc2VydmljZSddLmluY2x1ZGVzKGNhdGVnb3J5KTtcbn1cbiJdfQ==
@@ -1,4 +1,4 @@
1
- import type { IngestEvent, IngestMetric, IngestResult } from './types.js';
1
+ import type { IngestCaller, IngestEvent, IngestMetric, IngestResult } from './types.js';
2
2
  /**
3
3
  * Resolve incoming events against the pipeline registry, batch-insert the
4
4
  * matched ones, and invalidate reporting caches for affected orgs.
@@ -8,4 +8,4 @@ import type { IngestEvent, IngestMetric, IngestResult } from './types.js';
8
8
  *
9
9
  * Returns counts + a sample of unregistered pipeline ids for observability.
10
10
  */
11
- export declare function ingestEvents(events: IngestEvent[], onMetric?: (m: IngestMetric) => void): Promise<IngestResult>;
11
+ export declare function ingestEvents(events: IngestEvent[], onMetric?: (m: IngestMetric) => void, caller?: IngestCaller): Promise<IngestResult>;
@@ -10,6 +10,8 @@
10
10
  import { createLogger, errorMessage, scrubAwsIdentifiers } from '@pipeline-builder/api-core';
11
11
  import { inArray } from 'drizzle-orm';
12
12
  import { invalidateOrgReports } from './caches.js';
13
+ import { upsertDeployments } from './deploy-rollup.js';
14
+ import { classifyFailure } from './failure-classifier.js';
13
15
  import { scrubOptional } from './sql-helpers.js';
14
16
  import { schema } from '../../database/drizzle-schema.js';
15
17
  import { withTenantTx } from '../../database/tenancy.js';
@@ -47,6 +49,50 @@ async function loadStepPlugins(tx, attributable) {
47
49
  .where(inArray(schema.pipelineStepManifest.pipelineId, pipelineIds));
48
50
  return new Map(rows.map((m) => [stepKey(m.pipelineId, m.stageName, m.actionName), m]));
49
51
  }
52
+ /**
53
+ * Allowance for clock skew between an AWS event's source clock and ours. A real
54
+ * CodePipeline event can carry a timestamp a little ahead of our `now`; without
55
+ * some tolerance the validation below would drop healthy events during normal
56
+ * NTP drift, which is far worse than admitting a few seconds of skew.
57
+ */
58
+ const CLOCK_SKEW_TOLERANCE_MS = 5 * 60 * 1000;
59
+ /**
60
+ * Why this event's timestamps are impossible, or null when they are usable.
61
+ *
62
+ * Checked at INGEST — the durable boundary — rather than clamped when the metrics
63
+ * are computed. A negative duration or a future deploy used to be clamped to 0
64
+ * downstream, which reported a broken clock as an instant deploy and quietly
65
+ * moved deployment frequency, change-failure rate and lead time for the org.
66
+ *
67
+ * NOT checked here: commit time vs deploy completion. `commit_timestamp` rides the
68
+ * PIPELINE/source event while the deploy's `completed_at` is on a separate STAGE
69
+ * row, joined by `execution_id` only when DORA is queried — so no single event
70
+ * carries both, and that ordering can only be guarded where the two meet.
71
+ */
72
+ function invalidEventTimes(event, nowMs) {
73
+ const ceiling = nowMs + CLOCK_SKEW_TOLERANCE_MS;
74
+ const parsed = [];
75
+ for (const field of ['startedAt', 'completedAt', 'commitTimestamp']) {
76
+ const raw = event[field];
77
+ if (raw === undefined || raw === null)
78
+ continue;
79
+ const ms = Date.parse(String(raw));
80
+ if (!Number.isFinite(ms))
81
+ return `${field} is not a parseable timestamp`;
82
+ if (ms > ceiling)
83
+ return `${field} is in the future`;
84
+ parsed.push([field, ms]);
85
+ }
86
+ const started = parsed.find(([f]) => f === 'startedAt')?.[1];
87
+ const completed = parsed.find(([f]) => f === 'completedAt')?.[1];
88
+ if (started !== undefined && completed !== undefined && completed < started) {
89
+ return 'completedAt is before startedAt';
90
+ }
91
+ if (event.durationMs !== undefined && event.durationMs !== null && event.durationMs < 0) {
92
+ return 'durationMs is negative';
93
+ }
94
+ return null;
95
+ }
50
96
  /**
51
97
  * The persisted row for one ingested event. This is the DURABLE persistence
52
98
  * boundary: every user/AWS-derived free-form string is scrubbed here, and
@@ -87,6 +133,16 @@ function toEventRow(event, registry, plugin) {
87
133
  pluginPublisherId: plugin?.pluginPublisherId ?? null,
88
134
  pluginName: plugin?.pluginName ?? null,
89
135
  pluginVersion: plugin?.pluginVersion ?? null,
136
+ // WHAT KIND of thing broke, classified here rather than at read time: the
137
+ // error text is scrubbed above and eventually swept by retention, so a
138
+ // category derived later would have nothing left to read. NULL for anything
139
+ // that is not a failure, so its presence always means "this broke".
140
+ failureCategory: classifyFailure({
141
+ status: event.status,
142
+ errorMessage: scrubOptional(event.errorMessage),
143
+ actionName: scrubOptional(event.actionName),
144
+ stageName: scrubOptional(event.stageName),
145
+ }),
90
146
  detail: event.detail !== undefined ? scrubAwsIdentifiers(event.detail) : undefined,
91
147
  };
92
148
  }
@@ -118,7 +174,19 @@ function emitStageMetrics(rows, onMetric) {
118
174
  *
119
175
  * Returns counts + a sample of unregistered pipeline ids for observability.
120
176
  */
121
- export async function ingestEvents(events, onMetric) {
177
+ export async function ingestEvents(events, onMetric, caller) {
178
+ // TENANCY. An event's org comes from the pipeline REGISTRY, not the token, so
179
+ // the scope check alone let any `reporting:ingest` holder post events for
180
+ // another org's pipeline id and have them attributed there. `caller` carries
181
+ // the org ids this token may write for; anything else is dropped below.
182
+ //
183
+ // `caller` is optional only so in-process callers that already run
184
+ // cross-tenant (tests, backfills) keep working — an ABSENT caller means "no
185
+ // restriction", and the route always supplies one. A caller with an EMPTY
186
+ // allow-list and no crossTenant flag therefore drops everything, which is the
187
+ // right answer when the route could not establish who is writing.
188
+ const unrestricted = caller === undefined || caller.crossTenant === true;
189
+ const allowed = new Set(caller?.allowedOrgIds ?? []);
122
190
  // Multi-org batch insert: the caller resolves to multiple orgs via the
123
191
  // pipeline-registry lookup below, so the route layer MUST establish a
124
192
  // `runWithTenantContext({ isSuperAdmin: true }, ...)` scope before calling
@@ -129,7 +197,7 @@ export async function ingestEvents(events, onMetric) {
129
197
  // Caches are invalidated AFTER the tx resolves: doing it inside held the pg
130
198
  // locks open across unrelated cache round-trips. The TTL is 2-5 min, so a
131
199
  // fire-and-forget post-commit invalidation is an acceptable trade.
132
- const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, insertedRows } = await withTenantTx(async (tx) => {
200
+ const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, droppedForeignOrg, droppedInvalidTime, insertedRows } = await withTenantTx(async (tx) => {
133
201
  // Batch-resolve all unique pipeline ids in one query
134
202
  const uniqueIds = [...new Set(events.map(e => e.pipelineId))];
135
203
  const registryRows = await tx
@@ -144,7 +212,14 @@ export async function ingestEvents(events, onMetric) {
144
212
  // Build insert batch (skip events whose pipeline isn't registered)
145
213
  const rows = [];
146
214
  let skippedLocal = 0;
215
+ let foreignLocal = 0;
216
+ let invalidTimeLocal = 0;
217
+ const invalidTimeReasons = new Set();
218
+ const foreignOrgIds = new Set();
147
219
  const unregisteredLocal = [];
220
+ // One `now` for the whole batch: per-event clocks would let an event pass or
221
+ // fail depending on where it sat in the loop.
222
+ const nowMs = Date.now();
148
223
  for (const event of events) {
149
224
  const registry = idMap.get(event.pipelineId);
150
225
  if (!registry) {
@@ -152,6 +227,22 @@ export async function ingestEvents(events, onMetric) {
152
227
  unregisteredLocal.push(event.pipelineId);
153
228
  continue;
154
229
  }
230
+ // The pipeline resolves to an org this caller may not write for. Counted
231
+ // separately from `skipped` (an unregistered id is a producer running
232
+ // ahead of registration; this is a tenancy refusal) and never inserted.
233
+ if (!unrestricted && !allowed.has(registry.orgId)) {
234
+ foreignLocal++;
235
+ foreignOrgIds.add(registry.orgId);
236
+ continue;
237
+ }
238
+ // Impossible timestamps are refused at the boundary, so no downstream
239
+ // metric has to clamp a negative gap and call it zero.
240
+ const badTime = invalidEventTimes(event, nowMs);
241
+ if (badTime) {
242
+ invalidTimeLocal++;
243
+ invalidTimeReasons.add(badTime);
244
+ continue;
245
+ }
155
246
  const stageName = scrubOptional(event.stageName);
156
247
  const actionName = scrubOptional(event.actionName);
157
248
  const step = isAttributable(event) && stageName && actionName
@@ -176,18 +267,52 @@ export async function ingestEvents(events, onMetric) {
176
267
  status: schema.pipelineEvent.status,
177
268
  stageName: schema.pipelineEvent.stageName,
178
269
  environment: schema.pipelineEvent.environment,
270
+ // For the per-deploy rollup below: everything `dora_deployments` needs,
271
+ // taken from the rows that ACTUALLY landed so a re-delivery cannot
272
+ // produce a second deploy.
273
+ executionId: schema.pipelineEvent.executionId,
274
+ commitSha: schema.pipelineEvent.commitSha,
275
+ commitTimestamp: schema.pipelineEvent.commitTimestamp,
276
+ commitCount: schema.pipelineEvent.commitCount,
277
+ completedAt: schema.pipelineEvent.completedAt,
278
+ startedAt: schema.pipelineEvent.startedAt,
279
+ createdAt: schema.pipelineEvent.createdAt,
280
+ detail: schema.pipelineEvent.detail,
179
281
  })
180
282
  : [];
283
+ // Log inside the tx scope while the org set is in hand. WARN, not error:
284
+ // a misrouted producer is the common cause, but the same line is the only
285
+ // signal of an injection attempt, so it names the orgs it refused.
286
+ if (foreignLocal > 0) {
287
+ logger.warn('Dropped ingest events for orgs the caller may not write for', {
288
+ dropped: foreignLocal,
289
+ foreignOrgIds: [...foreignOrgIds],
290
+ allowedOrgIds: [...allowed],
291
+ });
292
+ }
293
+ if (invalidTimeLocal > 0) {
294
+ logger.warn('Dropped ingest events with impossible timestamps', {
295
+ dropped: invalidTimeLocal,
296
+ reasons: [...invalidTimeReasons],
297
+ });
298
+ }
181
299
  return {
182
300
  inserted: landed.length,
183
301
  skipped: skippedLocal,
184
302
  unregisteredPipelineIds: unregisteredLocal,
185
303
  affectedOrgs: [...new Set(landed.map(r => r.orgId))],
304
+ droppedForeignOrg: foreignLocal,
305
+ droppedInvalidTime: invalidTimeLocal,
186
306
  insertedRows: landed,
187
307
  };
188
308
  });
189
309
  if (onMetric)
190
310
  emitStageMetrics(insertedRows, onMetric);
311
+ // Per-deploy rollup. AFTER the events commit and outside their transaction: the
312
+ // events are the durable record and `dora_deployments` is derived from them, so
313
+ // a rollup failure must not roll back an ingest that succeeded. Rebuildable
314
+ // either way. `upsertDeployments` never throws for that reason.
315
+ await upsertDeployments(insertedRows);
191
316
  // Surface the silent skip: an unregistered pipeline id usually means the
192
317
  // pipeline hasn't called POST /pipelines/registry yet (or its
193
318
  // pb.pipeline-id tag is missing/unreadable by the Lambda). Logging it
@@ -205,6 +330,6 @@ export async function ingestEvents(events, onMetric) {
205
330
  logger.warn('Reporting cache invalidation failed', { orgId: org, error: errorMessage(err) });
206
331
  })));
207
332
  }
208
- return { inserted, skipped, unregisteredPipelineIds, affectedOrgs };
333
+ return { inserted, skipped, unregisteredPipelineIds, affectedOrgs, droppedForeignOrg, droppedInvalidTime };
209
334
  }
210
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvaW5nZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUd6RCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQWNoRCxxRUFBcUU7QUFDckUsU0FBUyxjQUFjLENBQUMsQ0FBYztJQUNwQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUM7V0FDdkQsQ0FBQyxDQUFDLENBQUMsV0FBVyxLQUFLLGNBQWMsSUFBSSxDQUFDLENBQUMsV0FBVyxLQUFLLFdBQVcsQ0FBQztXQUNuRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztBQUN2QyxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsVUFBa0IsRUFBRSxTQUFpQixFQUFFLFVBQWtCO0lBQ3hFLE9BQU8sR0FBRyxVQUFVLFNBQVMsU0FBUyxTQUFTLFVBQVUsRUFBRSxDQUFDO0FBQzlELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsS0FBSyxVQUFVLGVBQWUsQ0FBQyxF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QUFDLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUV2RCx5RUFBeUU7SUFDekUsOERBQThEO0lBQzlELHNFQUFzRTtJQUN0RSxxRUFBcUU7SUFDckUsSUFBSSx1QkFBdUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDdkMsTUFBTSxDQUFDLElBQUksQ0FBQyw0REFBNEQsRUFBRTtZQUN4RSxLQUFLLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtZQUNyQyxNQUFNLEVBQUUsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDNUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSxzREFBc0Q7SUFDdEQsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzVCLEtBQUssT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDeEMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDL0YsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFlBQVksRUFBRSxDQUFDO0FBQ3RFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBFdmVudCBpbmdlc3Q6IHRoZSBXUklURSBoYWxmIG9mIHJlcG9ydGluZy4gUmVzb2x2ZXMgaW5jb21pbmcgcGlwZWxpbmUgZXZlbnRzXG4gKiBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgc2NydWJzIGV2ZXJ5IGZyZWUtZm9ybSBzdHJpbmcsIGJhdGNoLWluc2VydHNcbiAqIHRoZSBtYXRjaGVkIHJvd3MgaWRlbXBvdGVudGx5LCBhbmQgaW52YWxpZGF0ZXMgdGhlIGFmZmVjdGVkIG9yZ3MnIHJlcG9ydFxuICogY2FjaGVzLiBTZXBhcmF0ZSBmcm9tIHRoZSByZXBvcnQgcXVlcmllcyBiZWNhdXNlIHRoaXMgaXMgcmVwb3J0aW5nJ3Mgb25seVxuICogZHVyYWJsZSBwZXJzaXN0ZW5jZSBib3VuZGFyeSDigJQgZXZlcnl0aGluZyBlbHNlIGluIHRoZSBzZXJ2aWNlIG9ubHkgcmVhZHMuXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBlcnJvck1lc3NhZ2UsIHNjcnViQXdzSWRlbnRpZmllcnMgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBpbkFycmF5IH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgaW52YWxpZGF0ZU9yZ1JlcG9ydHMgfSBmcm9tICcuL2NhY2hlcy5qcyc7XG5pbXBvcnQgeyBzY3J1Yk9wdGlvbmFsIH0gZnJvbSAnLi9zcWwtaGVscGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7IEluZ2VzdEV2ZW50LCBJbmdlc3RNZXRyaWMsIEluZ2VzdFJlc3VsdCB9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEuanMnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4IH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5pbXBvcnQgdHlwZSB7IENydWRUeCB9IGZyb20gJy4uL2NydWQtc2VydmljZS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLWluZ2VzdCcpO1xuXG50eXBlIFBpcGVsaW5lRXZlbnRJbnNlcnQgPSB0eXBlb2Ygc2NoZW1hLnBpcGVsaW5lRXZlbnQuJGluZmVySW5zZXJ0O1xuXG5cbi8qKiBUaGUgcGx1Z2luIGEgcGlwZWxpbmUgc3RlcCBydW5zLCBmcm9tIHRoZSBzdGVwIG1hbmlmZXN0IGl0cyBsYXN0IGRlcGxveSByZWdpc3RlcmVkLiAqL1xuaW50ZXJmYWNlIFN0ZXBQbHVnaW4ge1xuICBvcmdJZDogc3RyaW5nO1xuICBwbHVnaW5QdWJsaXNoZXI6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpblB1Ymxpc2hlcklkOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5OYW1lOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5WZXJzaW9uOiBzdHJpbmcgfCBudWxsO1xufVxuXG4vKiogQW4gYWN0aW9uL2J1aWxkIGV2ZW50IHRoYXQgY2FuIGJlIGF0dHJpYnV0ZWQgdG8gYSBwbHVnaW4gc3RlcC4gKi9cbmZ1bmN0aW9uIGlzQXR0cmlidXRhYmxlKGU6IEluZ2VzdEV2ZW50KTogYm9vbGVhbiB7XG4gIHJldHVybiAoZS5ldmVudFR5cGUgPT09ICdBQ1RJT04nIHx8IGUuZXZlbnRUeXBlID09PSAnQlVJTEQnKVxuICAgICYmIChlLmV2ZW50U291cmNlID09PSAnY29kZXBpcGVsaW5lJyB8fCBlLmV2ZW50U291cmNlID09PSAnY29kZWJ1aWxkJylcbiAgICAmJiAhIWUuc3RhZ2VOYW1lICYmICEhZS5hY3Rpb25OYW1lO1xufVxuXG5mdW5jdGlvbiBzdGVwS2V5KHBpcGVsaW5lSWQ6IHN0cmluZywgc3RhZ2VOYW1lOiBzdHJpbmcsIGFjdGlvbk5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtwaXBlbGluZUlkfVxcdTAwMDAke3N0YWdlTmFtZX1cXHUwMDAwJHthY3Rpb25OYW1lfWA7XG59XG5cbi8qKlxuICogUGx1Z2luIGF0dHJpYnV0aW9uOiB0aGUgc3RlcCBtYW5pZmVzdHMgb2YgZXZlcnkgcGlwZWxpbmUgd2l0aCBhbiBhdHRyaWJ1dGFibGVcbiAqIGV2ZW50LCBpbiBPTkUgcmVhZCBwZXIgYmF0Y2gsIGtleWVkIGZvciBhbiBpbi1tZW1vcnkgam9pbi4gTmFtZXMgYXJlIGNvbXBhcmVkXG4gKiBwb3N0LXNjcnViIG9uIGJvdGggc2lkZXMgKHRoZSBtYW5pZmVzdCBzdG9yZXMgdGhlbSBzY3J1YmJlZCB0aGUgc2FtZSB3YXkpLlxuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkU3RlcFBsdWdpbnModHg6IENydWRUeCwgYXR0cmlidXRhYmxlOiBJbmdlc3RFdmVudFtdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBTdGVwUGx1Z2luPj4ge1xuICBjb25zdCBwaXBlbGluZUlkcyA9IFsuLi5uZXcgU2V0KGF0dHJpYnV0YWJsZS5tYXAoKGUpID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgaWYgKHBpcGVsaW5lSWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG5ldyBNYXAoKTtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHR4XG4gICAgLnNlbGVjdCh7XG4gICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3Qub3JnSWQsXG4gICAgICBzdGFnZU5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5zdGFnZU5hbWUsXG4gICAgICBhY3Rpb25OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QuYWN0aW9uTmFtZSxcbiAgICAgIHBsdWdpblB1Ymxpc2hlcjogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblB1Ymxpc2hlcixcbiAgICAgIHBsdWdpblB1Ymxpc2hlcklkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luUHVibGlzaGVySWQsXG4gICAgICBwbHVnaW5OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luTmFtZSxcbiAgICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5WZXJzaW9uLFxuICAgIH0pXG4gICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0KVxuICAgIC53aGVyZShpbkFycmF5KHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5waXBlbGluZUlkLCBwaXBlbGluZUlkcykpO1xuICByZXR1cm4gbmV3IE1hcChyb3dzLm1hcCgobSkgPT4gW3N0ZXBLZXkobS5waXBlbGluZUlkLCBtLnN0YWdlTmFtZSwgbS5hY3Rpb25OYW1lKSwgbV0pKTtcbn1cblxuLyoqXG4gKiBUaGUgcGVyc2lzdGVkIHJvdyBmb3Igb25lIGluZ2VzdGVkIGV2ZW50LiBUaGlzIGlzIHRoZSBEVVJBQkxFIHBlcnNpc3RlbmNlXG4gKiBib3VuZGFyeTogZXZlcnkgdXNlci9BV1MtZGVyaXZlZCBmcmVlLWZvcm0gc3RyaW5nIGlzIHNjcnViYmVkIGhlcmUsIGFuZFxuICogdGVuYW5jeSBjb21lcyBmcm9tIHRoZSBwaXBlbGluZSByZWdpc3RyeSwgbmV2ZXIgdGhlIGNhbGxlcidzIGNsYWltZWQgb3JnLlxuICovXG5mdW5jdGlvbiB0b0V2ZW50Um93KGV2ZW50OiBJbmdlc3RFdmVudCwgcmVnaXN0cnk6IHsgcGlwZWxpbmVJZDogc3RyaW5nOyBvcmdJZDogc3RyaW5nIH0sIHBsdWdpbjogU3RlcFBsdWdpbiB8IHVuZGVmaW5lZCk6IFBpcGVsaW5lRXZlbnRJbnNlcnQge1xuICByZXR1cm4ge1xuICAgIC8vIHJlZ2lzdHJ5LnBpcGVsaW5lSWQgPT09IGV2ZW50LnBpcGVsaW5lSWQ7IHRoZSByZWdpc3RyeSdzIGlzIGFsd2F5cyBhIHJvd1xuICAgIC8vIHRoYXQgZXhpc3RzIChGSykgYW5kIGl0cyBvcmdJZCBpcyB0aGUgdHJ1c3RlZCB0ZW5hbnQuXG4gICAgcGlwZWxpbmVJZDogcmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICBvcmdJZDogcmVnaXN0cnkub3JnSWQsXG4gICAgZXZlbnRTb3VyY2U6IGV2ZW50LmV2ZW50U291cmNlLFxuICAgIGV2ZW50VHlwZTogZXZlbnQuZXZlbnRUeXBlLFxuICAgIHN0YXR1czogZXZlbnQuc3RhdHVzLFxuICAgIC8vIEFuIEFXUy1BU1NJR05FRCBVVUlELCBub3QgZnJlZS1mb3JtIHRleHQ6IGl0IGNhbid0IGNhcnJ5IGFuIGFjY291bnQgaWQsXG4gICAgLy8gYW5kIHNjcnViYmluZyBhIDEyLWRpZ2l0IHJ1biBpbnNpZGUgaXQgd291bGQgY29ycnVwdCB0aGUgY29ycmVsYXRpb24ga2V5LlxuICAgIGV4ZWN1dGlvbklkOiBldmVudC5leGVjdXRpb25JZCxcbiAgICAvLyBVU0VSLUFVVEhPUkVEIHBpcGVsaW5lLXN0cnVjdHVyZSBuYW1lcyDigJQgc2FtZSB1bnRydXN0ZWQgb3JpZ2luIGFzXG4gICAgLy8gZXJyb3JNZXNzYWdlLCBzbyBzY3J1YmJlZCAoYSBzdGFnZSBuYW1lZCB3aXRoIGFuIEFSTiBtdXN0IG5vdCBwZXJzaXN0KS5cbiAgICBzdGFnZU5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuc3RhZ2VOYW1lKSxcbiAgICBhY3Rpb25OYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpLFxuICAgIC8vIEhBUkQgQ09OU1RSQUlOVDogYW4gQVdTIGFjY291bnQgaWQgbXVzdCBORVZFUiBiZSBwZXJzaXN0ZWQuIEZhaWx1cmUgZGV0YWlsXG4gICAgLy8gYW5kIG1lc3NhZ2VzIHJvdXRpbmVseSBjYXJyeSBBUk5zIGFuZCBiYXJlIDEyLWRpZ2l0IGFjY291bnQgaWRzLlxuICAgIGVycm9yTWVzc2FnZTogc2NydWJPcHRpb25hbChldmVudC5lcnJvck1lc3NhZ2UpLFxuICAgIHN0YXJ0ZWRBdDogZXZlbnQuc3RhcnRlZEF0ID8gbmV3IERhdGUoZXZlbnQuc3RhcnRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICBjb21wbGV0ZWRBdDogZXZlbnQuY29tcGxldGVkQXQgPyBuZXcgRGF0ZShldmVudC5jb21wbGV0ZWRBdCkgOiB1bmRlZmluZWQsXG4gICAgZHVyYXRpb25NczogZXZlbnQuZHVyYXRpb25NcyxcbiAgICAvLyBEZXBsb3kgYXR0cmlidXRpb24g4oCUIHNjcnViYmVkIGxpa2UgdGhlIG90aGVyIGZyZWUtZm9ybSBzdHJpbmdzLlxuICAgIGNvbW1pdFNoYTogc2NydWJPcHRpb25hbChldmVudC5jb21taXRTaGEpLFxuICAgIGNvbW1pdFJlZjogc2NydWJPcHRpb25hbChldmVudC5jb21taXRSZWYpLFxuICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVudmlyb25tZW50KSxcbiAgICAvLyBNZWFzdXJlZCBsZWFkIHRpbWU6IHRoZSBvbGRlc3QgdW5zaGlwcGVkIGNvbW1pdCdzIHRpbWUgKyB0aGUgY291bnQuIEFuXG4gICAgLy8gU0NNLWRlcml2ZWQgaW5zdGFudCBhbmQgYSBwbGFpbiBpbnRlZ2VyIOKAlCBub3RoaW5nIHRvIHNjcnViLlxuICAgIGNvbW1pdFRpbWVzdGFtcDogZXZlbnQuY29tbWl0VGltZXN0YW1wID8gbmV3IERhdGUoZXZlbnQuY29tbWl0VGltZXN0YW1wKSA6IHVuZGVmaW5lZCxcbiAgICBjb21taXRDb3VudDogZXZlbnQuY29tbWl0Q291bnQsXG4gICAgLy8gTlVMTCBmb3Igbm9uLXBsdWdpbiBhY3Rpb25zIGFuZCBmb3IgcGlwZWxpbmVzIGRlcGxveWVkIHdpdGhvdXQgYSBtYW5pZmVzdC5cbiAgICBwbHVnaW5QdWJsaXNoZXI6IHBsdWdpbj8ucGx1Z2luUHVibGlzaGVyID8/IG51bGwsXG4gICAgcGx1Z2luUHVibGlzaGVySWQ6IHBsdWdpbj8ucGx1Z2luUHVibGlzaGVySWQgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBwbHVnaW4/LnBsdWdpbk5hbWUgPz8gbnVsbCxcbiAgICBwbHVnaW5WZXJzaW9uOiBwbHVnaW4/LnBsdWdpblZlcnNpb24gPz8gbnVsbCxcbiAgICBkZXRhaWw6IGV2ZW50LmRldGFpbCAhPT0gdW5kZWZpbmVkID8gc2NydWJBd3NJZGVudGlmaWVycyhldmVudC5kZXRhaWwpIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIEZhbiB0ZXJtaW5hbCBTVEFHRSBvdXRjb21lcyBpbnRvIHRoZSByb3V0ZSdzIG1ldHJpYyBob29rIChwaXBlbGluZS1kYXRhIGNhbid0XG4gKiBpbXBvcnQgYXBpLXNlcnZlcidzIHJlZ2lzdHJ5KSBhZnRlciB0aGUgaW5zZXJ0IGNvbW1pdHMuIERyaXZlbiBvZmYgdGhlXG4gKiBJTlNFUlRFRCByb3dzLCBzbyBhIHJlLWRlbGl2ZXJlZCBldmVudCB0aGUgZGVkdXAgaW5kZXggc3dhbGxvd2VkIGlzIG5ldmVyXG4gKiBjb3VudGVkIHR3aWNlLiBBIG5vbi1udWxsIGVudmlyb25tZW50IG1hcmtzIGEgZGVwbG95LlxuICovXG5mdW5jdGlvbiBlbWl0U3RhZ2VNZXRyaWNzKFxuICByb3dzOiBSZWFkb25seUFycmF5PHsgb3JnSWQ6IHN0cmluZzsgcGlwZWxpbmVJZDogc3RyaW5nIHwgbnVsbDsgZXZlbnRUeXBlOiBzdHJpbmc7IHN0YXR1czogc3RyaW5nOyBzdGFnZU5hbWU6IHN0cmluZyB8IG51bGw7IGVudmlyb25tZW50OiBzdHJpbmcgfCBudWxsIH0+LFxuICBvbk1ldHJpYzogKG06IEluZ2VzdE1ldHJpYykgPT4gdm9pZCxcbik6IHZvaWQge1xuICBmb3IgKGNvbnN0IHIgb2Ygcm93cykge1xuICAgIGlmIChyLmV2ZW50VHlwZSAhPT0gJ1NUQUdFJyB8fCAoci5zdGF0dXMgIT09ICdTVUNDRUVERUQnICYmIHIuc3RhdHVzICE9PSAnRkFJTEVEJykgfHwgIXIucGlwZWxpbmVJZCkgY29udGludWU7XG4gICAgb25NZXRyaWMoe1xuICAgICAgcGlwZWxpbmVJZDogci5waXBlbGluZUlkLFxuICAgICAgb3JnSWQ6IHIub3JnSWQsXG4gICAgICBzdGFnZTogci5zdGFnZU5hbWUgPz8gJycsXG4gICAgICBlbnZpcm9ubWVudDogci5lbnZpcm9ubWVudCA/PyBudWxsLFxuICAgICAgcmVzdWx0OiByLnN0YXR1cyA9PT0gJ1NVQ0NFRURFRCcgPyAnc3VjY2VlZGVkJyA6ICdmYWlsZWQnLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZSBpbmNvbWluZyBldmVudHMgYWdhaW5zdCB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIGJhdGNoLWluc2VydCB0aGVcbiAqIG1hdGNoZWQgb25lcywgYW5kIGludmFsaWRhdGUgcmVwb3J0aW5nIGNhY2hlcyBmb3IgYWZmZWN0ZWQgb3Jncy5cbiAqIEV2ZW50cyBmb3IgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gKiB3aXRoIHNhbXBsZSBpZHMgc28gYW4gb3BlcmF0b3IgY2FuIHNlZSB3aGVuIEV2ZW50QnJpZGdlIGlzIGRlbGl2ZXJpbmdcbiAqIGV2ZW50cyBmb3IgcGlwZWxpbmVzIHRoYXQgaGF2ZW4ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCkuXG4gKlxuICogUmV0dXJucyBjb3VudHMgKyBhIHNhbXBsZSBvZiB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgaWRzIGZvciBvYnNlcnZhYmlsaXR5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5nZXN0RXZlbnRzKGV2ZW50czogSW5nZXN0RXZlbnRbXSwgb25NZXRyaWM/OiAobTogSW5nZXN0TWV0cmljKSA9PiB2b2lkKTogUHJvbWlzZTxJbmdlc3RSZXN1bHQ+IHtcbiAgLy8gTXVsdGktb3JnIGJhdGNoIGluc2VydDogdGhlIGNhbGxlciByZXNvbHZlcyB0byBtdWx0aXBsZSBvcmdzIHZpYSB0aGVcbiAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAvLyBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgLi4uKWAgc2NvcGUgYmVmb3JlIGNhbGxpbmdcbiAgLy8gdGhpcyBmdW5jdGlvbi4gVW5kZXIgRk9SQ0UnZCBSTFMsIGEgc2luZ2xlIHR4IHdpdGggYGFwcC5vcmdfaWQgPSA8b25lXG4gIC8vIG9yZz5gIGNvdWxkIG9ubHkgd3JpdGUgZXZlbnRzIGZvciB0aGF0IG9yZzsgYnlwYXNzIHZpYSBzeXNhZG1pbiBpc1xuICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgLy8gYXBpL3JlcG9ydGluZy9zcmMvcm91dGVzL2V2ZW50LWluZ2VzdC50cyBmb3IgdGhlIHdyYXBwZXIuXG4gIC8vIENhY2hlcyBhcmUgaW52YWxpZGF0ZWQgQUZURVIgdGhlIHR4IHJlc29sdmVzOiBkb2luZyBpdCBpbnNpZGUgaGVsZCB0aGUgcGdcbiAgLy8gbG9ja3Mgb3BlbiBhY3Jvc3MgdW5yZWxhdGVkIGNhY2hlIHJvdW5kLXRyaXBzLiBUaGUgVFRMIGlzIDItNSBtaW4sIHNvIGFcbiAgLy8gZmlyZS1hbmQtZm9yZ2V0IHBvc3QtY29tbWl0IGludmFsaWRhdGlvbiBpcyBhbiBhY2NlcHRhYmxlIHRyYWRlLlxuICBjb25zdCB7IGluc2VydGVkLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcywgYWZmZWN0ZWRPcmdzLCBpbnNlcnRlZFJvd3MgfSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgIGNvbnN0IHVuaXF1ZUlkcyA9IFsuLi5uZXcgU2V0KGV2ZW50cy5tYXAoZSA9PiBlLnBpcGVsaW5lSWQpKV07XG4gICAgY29uc3QgcmVnaXN0cnlSb3dzID0gYXdhaXQgdHhcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkub3JnSWQsXG4gICAgICB9KVxuICAgICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkpXG4gICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLCB1bmlxdWVJZHMpKTtcblxuICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcbiAgICBjb25zdCBzdGVwUGx1Z2lucyA9IGF3YWl0IGxvYWRTdGVwUGx1Z2lucyh0eCwgZXZlbnRzLmZpbHRlcigoZSkgPT4gaXNBdHRyaWJ1dGFibGUoZSkgJiYgaWRNYXAuaGFzKGUucGlwZWxpbmVJZCkpKTtcblxuICAgIC8vIEJ1aWxkIGluc2VydCBiYXRjaCAoc2tpcCBldmVudHMgd2hvc2UgcGlwZWxpbmUgaXNuJ3QgcmVnaXN0ZXJlZClcbiAgICBjb25zdCByb3dzOiBQaXBlbGluZUV2ZW50SW5zZXJ0W10gPSBbXTtcbiAgICBsZXQgc2tpcHBlZExvY2FsID0gMDtcbiAgICBjb25zdCB1bnJlZ2lzdGVyZWRMb2NhbDogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IGlkTWFwLmdldChldmVudC5waXBlbGluZUlkKTtcbiAgICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgICAgc2tpcHBlZExvY2FsKys7XG4gICAgICAgIHVucmVnaXN0ZXJlZExvY2FsLnB1c2goZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhZ2VOYW1lID0gc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpO1xuICAgICAgY29uc3QgYWN0aW9uTmFtZSA9IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSk7XG4gICAgICBjb25zdCBzdGVwID0gaXNBdHRyaWJ1dGFibGUoZXZlbnQpICYmIHN0YWdlTmFtZSAmJiBhY3Rpb25OYW1lXG4gICAgICAgID8gc3RlcFBsdWdpbnMuZ2V0KHN0ZXBLZXkocmVnaXN0cnkucGlwZWxpbmVJZCwgc3RhZ2VOYW1lLCBhY3Rpb25OYW1lKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAvLyBTYW1lLW9yZyBndWFyZDogYSBtYW5pZmVzdCByb3cgaXMgb25seSBldmVyIHdyaXR0ZW4gYnkgdGhlIG9yZyB0aGF0XG4gICAgICAvLyBvd25zIHRoZSBwaXBlbGluZSwgYnV0IHRoZSBpbmdlc3QgcnVucyBjcm9zcy10ZW5hbnQsIHNvIGRvbid0IGxlYW4gb24gaXQuXG4gICAgICByb3dzLnB1c2godG9FdmVudFJvdyhldmVudCwgcmVnaXN0cnksIHN0ZXAgJiYgc3RlcC5vcmdJZCA9PT0gcmVnaXN0cnkub3JnSWQgPyBzdGVwIDogdW5kZWZpbmVkKSk7XG4gICAgfVxuXG4gICAgLy8gU1FTIGlzIGF0LWxlYXN0LW9uY2UsIHNvIEV2ZW50QnJpZGdlIGNhbiBkZWxpdmVyIHRoZSBzYW1lIHN0YXRlLWNoYW5nZVxuICAgIC8vIHR3aWNlLiBgb25Db25mbGljdERvTm90aGluZ2AgKyB0aGUgcGFydGlhbCB1bmlxdWUgaW5kZXggb25cbiAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAvLyBtYWtlcyByZS1kZWxpdmVyeSBpZGVtcG90ZW50LiBgcmV0dXJuaW5nYCBnaXZlcyB0aGUgUkVBTCBpbnNlcnRlZCBzZXQgc29cbiAgICAvLyBjb3VudHMsIG1ldHJpY3MgYW5kIGNhY2hlIGludmFsaWRhdGlvbiBhbGwgaWdub3JlIGR1cGxpY2F0ZXMuXG4gICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICA/IGF3YWl0IHR4Lmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpXG4gICAgICAgIC5vbkNvbmZsaWN0RG9Ob3RoaW5nKClcbiAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkLFxuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnBpcGVsaW5lSWQsXG4gICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgc3RhdHVzOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGF0dXMsXG4gICAgICAgICAgc3RhZ2VOYW1lOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGFnZU5hbWUsXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmVudmlyb25tZW50LFxuICAgICAgICB9KVxuICAgICAgOiBbXTtcblxuICAgIHJldHVybiB7XG4gICAgICBpbnNlcnRlZDogbGFuZGVkLmxlbmd0aCxcbiAgICAgIHNraXBwZWQ6IHNraXBwZWRMb2NhbCxcbiAgICAgIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzOiB1bnJlZ2lzdGVyZWRMb2NhbCxcbiAgICAgIGFmZmVjdGVkT3JnczogWy4uLm5ldyBTZXQobGFuZGVkLm1hcChyID0+IHIub3JnSWQpKV0sXG4gICAgICBpbnNlcnRlZFJvd3M6IGxhbmRlZCxcbiAgICB9O1xuICB9KTtcblxuICBpZiAob25NZXRyaWMpIGVtaXRTdGFnZU1ldHJpY3MoaW5zZXJ0ZWRSb3dzLCBvbk1ldHJpYyk7XG5cbiAgLy8gU3VyZmFjZSB0aGUgc2lsZW50IHNraXA6IGFuIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZCB1c3VhbGx5IG1lYW5zIHRoZVxuICAvLyBwaXBlbGluZSBoYXNuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQgKG9yIGl0c1xuICAvLyBwYi5waXBlbGluZS1pZCB0YWcgaXMgbWlzc2luZy91bnJlYWRhYmxlIGJ5IHRoZSBMYW1iZGEpLiBMb2dnaW5nIGl0XG4gIC8vIG1ha2VzIGEgYnJva2VuIGpvaW4gdmlzaWJsZSBpbnN0ZWFkIG9mIGxvb2tpbmcgbGlrZSBcIm5vIGFjdGl2aXR5XCIuXG4gIGlmICh1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5sZW5ndGggPiAwKSB7XG4gICAgbG9nZ2VyLndhcm4oJ1BpcGVsaW5lIGV2ZW50cyBza2lwcGVkOiBwaXBlbGluZSBpZCBub3QgZm91bmQgaW4gcmVnaXN0cnknLCB7XG4gICAgICBjb3VudDogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoLFxuICAgICAgc2FtcGxlOiB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5zbGljZSgwLCAzKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFBvc3QtY29tbWl0IGNhY2hlIGludmFsaWRhdGlvbi4gRmlyZS1hbmQtZm9yZ2V0IHdpdGggbG9nZ2luZyDigJQgVFRMIGlzXG4gIC8vIHNob3J0IGVub3VnaCB0aGF0IGEgbWlzc2VkIGludmFsaWRhdGlvbiBzZWxmLWhlYWxzLlxuICBpZiAoYWZmZWN0ZWRPcmdzLmxlbmd0aCA+IDApIHtcbiAgICB2b2lkIFByb21pc2UuYWxsKGFmZmVjdGVkT3Jncy5tYXAoKG9yZykgPT5cbiAgICAgIGludmFsaWRhdGVPcmdSZXBvcnRzKG9yZykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkOiBvcmcsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICAgIH0pLFxuICAgICkpO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLCBhZmZlY3RlZE9yZ3MgfTtcbn1cbiJdfQ==
335
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvaW5nZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNuRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWpELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFjaEQscUVBQXFFO0FBQ3JFLFNBQVMsY0FBYyxDQUFDLENBQWM7SUFDcEMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLEtBQUssUUFBUSxJQUFJLENBQUMsQ0FBQyxTQUFTLEtBQUssT0FBTyxDQUFDO1dBQ3ZELENBQUMsQ0FBQyxDQUFDLFdBQVcsS0FBSyxjQUFjLElBQUksQ0FBQyxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUM7V0FDbkUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7QUFDdkMsQ0FBQztBQUVELFNBQVMsT0FBTyxDQUFDLFVBQWtCLEVBQUUsU0FBaUIsRUFBRSxVQUFrQjtJQUN4RSxPQUFPLEdBQUcsVUFBVSxTQUFTLFNBQVMsU0FBUyxVQUFVLEVBQUUsQ0FBQztBQUM5RCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILEtBQUssVUFBVSxlQUFlLENBQUMsRUFBVSxFQUFFLFlBQTJCO0lBQ3BFLE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLElBQUksV0FBVyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQy9DLE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRTtTQUNsQixNQUFNLENBQUM7UUFDTixVQUFVLEVBQUUsTUFBTSxDQUFDLG9CQUFvQixDQUFDLFVBQVU7UUFDbEQsS0FBSyxFQUFFLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLO1FBQ3hDLFNBQVMsRUFBRSxNQUFNLENBQUMsb0JBQW9CLENBQUMsU0FBUztRQUNoRCxVQUFVLEVBQUUsTUFBTSxDQUFDLG9CQUFvQixDQUFDLFVBQVU7UUFDbEQsZUFBZSxFQUFFLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlO1FBQzVELGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxpQkFBaUI7UUFDaEUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVO1FBQ2xELGFBQWEsRUFBRSxNQUFNLENBQUMsb0JBQW9CLENBQUMsYUFBYTtLQUN6RCxDQUFDO1NBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQztTQUNqQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztJQUN2RSxPQUFPLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFOUM7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxLQUFrQixFQUFFLEtBQWE7SUFDMUQsTUFBTSxPQUFPLEdBQUcsS0FBSyxHQUFHLHVCQUF1QixDQUFDO0lBQ2hELE1BQU0sTUFBTSxHQUE0QixFQUFFLENBQUM7SUFDM0MsS0FBSyxNQUFNLEtBQUssSUFBSSxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsaUJBQWlCLENBQVUsRUFBRSxDQUFDO1FBQzdFLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLElBQUk7WUFBRSxTQUFTO1FBQ2hELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQUUsT0FBTyxHQUFHLEtBQUssK0JBQStCLENBQUM7UUFDekUsSUFBSSxFQUFFLEdBQUcsT0FBTztZQUFFLE9BQU8sR0FBRyxLQUFLLG1CQUFtQixDQUFDO1FBQ3JELE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQ0QsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqRSxJQUFJLE9BQU8sS0FBSyxTQUFTLElBQUksU0FBUyxLQUFLLFNBQVMsSUFBSSxTQUFTLEdBQUcsT0FBTyxFQUFFLENBQUM7UUFDNUUsT0FBTyxpQ0FBaUMsQ0FBQztJQUMzQyxDQUFDO0lBQ0QsSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLElBQUksSUFBSSxLQUFLLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3hGLE9BQU8sd0JBQXdCLENBQUM7SUFDbEMsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLFVBQVUsQ0FBQyxLQUFrQixFQUFFLFFBQStDLEVBQUUsTUFBOEI7SUFDckgsT0FBTztRQUNMLDJFQUEyRTtRQUMzRSx3REFBd0Q7UUFDeEQsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVO1FBQy9CLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSztRQUNyQixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVc7UUFDOUIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1FBQzFCLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtRQUNwQiwwRUFBMEU7UUFDMUUsNEVBQTRFO1FBQzVFLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztRQUM5QixvRUFBb0U7UUFDcEUsMEVBQTBFO1FBQzFFLFNBQVMsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUN6QyxVQUFVLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDM0MsNkVBQTZFO1FBQzdFLG1FQUFtRTtRQUNuRSxZQUFZLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7UUFDL0MsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztRQUNsRSxXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ3hFLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtRQUM1QixrRUFBa0U7UUFDbEUsU0FBUyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ3pDLFNBQVMsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUN6QyxXQUFXLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUM7UUFDN0MseUVBQXlFO1FBQ3pFLDhEQUE4RDtRQUM5RCxlQUFlLEVBQUUsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ3BGLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztRQUM5Qiw2RUFBNkU7UUFDN0UsZUFBZSxFQUFFLE1BQU0sRUFBRSxlQUFlLElBQUksSUFBSTtRQUNoRCxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLElBQUksSUFBSTtRQUNwRCxVQUFVLEVBQUUsTUFBTSxFQUFFLFVBQVUsSUFBSSxJQUFJO1FBQ3RDLGFBQWEsRUFBRSxNQUFNLEVBQUUsYUFBYSxJQUFJLElBQUk7UUFDNUMsMEVBQTBFO1FBQzFFLHVFQUF1RTtRQUN2RSw0RUFBNEU7UUFDNUUsb0VBQW9FO1FBQ3BFLGVBQWUsRUFBRSxlQUFlLENBQUM7WUFDL0IsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO1lBQ3BCLFlBQVksRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztZQUMvQyxVQUFVLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7WUFDM0MsU0FBUyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1NBQzFDLENBQUM7UUFDRixNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztLQUNuRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FDdkIsSUFBMEosRUFDMUosUUFBbUM7SUFFbkMsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsQ0FBQyxTQUFTLEtBQUssT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxXQUFXLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVO1lBQUUsU0FBUztRQUM5RyxRQUFRLENBQUM7WUFDUCxVQUFVLEVBQUUsQ0FBQyxDQUFDLFVBQVU7WUFDeEIsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLO1lBQ2QsS0FBSyxFQUFFLENBQUMsQ0FBQyxTQUFTLElBQUksRUFBRTtZQUN4QixXQUFXLEVBQUUsQ0FBQyxDQUFDLFdBQVcsSUFBSSxJQUFJO1lBQ2xDLE1BQU0sRUFBRSxDQUFDLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxRQUFRO1NBQzFELENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FDaEMsTUFBcUIsRUFDckIsUUFBb0MsRUFDcEMsTUFBcUI7SUFFckIsOEVBQThFO0lBQzlFLDBFQUEwRTtJQUMxRSw2RUFBNkU7SUFDN0Usd0VBQXdFO0lBQ3hFLEVBQUU7SUFDRixtRUFBbUU7SUFDbkUsNEVBQTRFO0lBQzVFLDBFQUEwRTtJQUMxRSw4RUFBOEU7SUFDOUUsa0VBQWtFO0lBQ2xFLE1BQU0sWUFBWSxHQUFHLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUM7SUFDekUsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxFQUFFLGFBQWEsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNyRCx1RUFBdUU7SUFDdkUsc0VBQXNFO0lBQ3RFLDJFQUEyRTtJQUMzRSx3RUFBd0U7SUFDeEUscUVBQXFFO0lBQ3JFLHFFQUFxRTtJQUNyRSw0REFBNEQ7SUFDNUQsNEVBQTRFO0lBQzVFLDBFQUEwRTtJQUMxRSxtRUFBbUU7SUFDbkUsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxHQUFHLE1BQU0sWUFBWSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRTtRQUN4SixxREFBcUQ7UUFDckQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlELE1BQU0sWUFBWSxHQUFHLE1BQU0sRUFBRTthQUMxQixNQUFNLENBQUM7WUFDTixVQUFVLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFVBQVU7WUFDOUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLO1NBQ3JDLENBQUM7YUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDO2FBQzdCLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBRWpFLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sV0FBVyxHQUFHLE1BQU0sZUFBZSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWxILG1FQUFtRTtRQUNuRSxNQUFNLElBQUksR0FBMEIsRUFBRSxDQUFDO1FBQ3ZDLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztRQUNyQixJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDckIsSUFBSSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFDekIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQzdDLE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDeEMsTUFBTSxpQkFBaUIsR0FBYSxFQUFFLENBQUM7UUFDdkMsNkVBQTZFO1FBQzdFLDhDQUE4QztRQUM5QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFekIsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUMzQixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2QsWUFBWSxFQUFFLENBQUM7Z0JBQ2YsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDekMsU0FBUztZQUNYLENBQUM7WUFDRCx5RUFBeUU7WUFDekUsc0VBQXNFO1lBQ3RFLHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDbEQsWUFBWSxFQUFFLENBQUM7Z0JBQ2YsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xDLFNBQVM7WUFDWCxDQUFDO1lBQ0Qsc0VBQXNFO1lBQ3RFLHVEQUF1RDtZQUN2RCxNQUFNLE9BQU8sR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDaEQsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDWixnQkFBZ0IsRUFBRSxDQUFDO2dCQUNuQixrQkFBa0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ2hDLFNBQVM7WUFDWCxDQUFDO1lBQ0QsTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqRCxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ25ELE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsSUFBSSxTQUFTLElBQUksVUFBVTtnQkFDM0QsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUN0RSxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2Qsc0VBQXNFO1lBQ3RFLDRFQUE0RTtZQUM1RSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNuRyxDQUFDO1FBRUQseUVBQXlFO1FBQ3pFLDZEQUE2RDtRQUM3RCwyRUFBMkU7UUFDM0UsMkVBQTJFO1FBQzNFLGdFQUFnRTtRQUNoRSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUM7WUFDNUIsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztpQkFDakQsbUJBQW1CLEVBQUU7aUJBQ3JCLFNBQVMsQ0FBQztnQkFDVCxLQUFLLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLO2dCQUNqQyxVQUFVLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxVQUFVO2dCQUMzQyxTQUFTLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTO2dCQUN6QyxNQUFNLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNO2dCQUNuQyxTQUFTLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTO2dCQUN6QyxXQUFXLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXO2dCQUM3Qyx3RUFBd0U7Z0JBQ3hFLG1FQUFtRTtnQkFDbkUsMkJBQTJCO2dCQUMzQixXQUFXLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXO2dCQUM3QyxTQUFTLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTO2dCQUN6QyxlQUFlLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxlQUFlO2dCQUNyRCxXQUFXLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXO2dCQUM3QyxXQUFXLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXO2dCQUM3QyxTQUFTLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTO2dCQUN6QyxTQUFTLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTO2dCQUN6QyxNQUFNLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNO2FBQ3BDLENBQUM7WUFDSixDQUFDLENBQUMsRUFBRSxDQUFDO1FBRVAseUVBQXlFO1FBQ3pFLDBFQUEwRTtRQUMxRSxtRUFBbUU7UUFDbkUsSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckIsTUFBTSxDQUFDLElBQUksQ0FBQyw2REFBNkQsRUFBRTtnQkFDekUsT0FBTyxFQUFFLFlBQVk7Z0JBQ3JCLGFBQWEsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDO2dCQUNqQyxhQUFhLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQzthQUM1QixDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxnQkFBZ0IsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6QixNQUFNLENBQUMsSUFBSSxDQUFDLGtEQUFrRCxFQUFFO2dCQUM5RCxPQUFPLEVBQUUsZ0JBQWdCO2dCQUN6QixPQUFPLEVBQUUsQ0FBQyxHQUFHLGtCQUFrQixDQUFDO2FBQ2pDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPO1lBQ0wsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNO1lBQ3ZCLE9BQU8sRUFBRSxZQUFZO1lBQ3JCLHVCQUF1QixFQUFFLGlCQUFpQjtZQUMxQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNwRCxpQkFBaUIsRUFBRSxZQUFZO1lBQy9CLGtCQUFrQixFQUFFLGdCQUFnQjtZQUNwQyxZQUFZLEVBQUUsTUFBTTtTQUNyQixDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLFFBQVE7UUFBRSxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFdkQsZ0ZBQWdGO0lBQ2hGLGdGQUFnRjtJQUNoRiw0RUFBNEU7SUFDNUUsZ0VBQWdFO0lBQ2hFLE1BQU0saUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFFdEMseUVBQXlFO0lBQ3pFLDhEQUE4RDtJQUM5RCxzRUFBc0U7SUFDdEUscUVBQXFFO0lBQ3JFLElBQUksdUJBQXVCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNERBQTRELEVBQUU7WUFDeEUsS0FBSyxFQUFFLHVCQUF1QixDQUFDLE1BQU07WUFDckMsTUFBTSxFQUFFLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzVDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCx3RUFBd0U7SUFDeEUsc0RBQXNEO0lBQ3RELElBQUksWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM1QixLQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQ3hDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3RDLE1BQU0sQ0FBQyxJQUFJLENBQUMscUNBQXFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQy9GLENBQUMsQ0FBQyxDQUNILENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQztBQUM3RyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogRXZlbnQgaW5nZXN0OiB0aGUgV1JJVEUgaGFsZiBvZiByZXBvcnRpbmcuIFJlc29sdmVzIGluY29taW5nIHBpcGVsaW5lIGV2ZW50c1xuICogYWdhaW5zdCB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIHNjcnVicyBldmVyeSBmcmVlLWZvcm0gc3RyaW5nLCBiYXRjaC1pbnNlcnRzXG4gKiB0aGUgbWF0Y2hlZCByb3dzIGlkZW1wb3RlbnRseSwgYW5kIGludmFsaWRhdGVzIHRoZSBhZmZlY3RlZCBvcmdzJyByZXBvcnRcbiAqIGNhY2hlcy4gU2VwYXJhdGUgZnJvbSB0aGUgcmVwb3J0IHF1ZXJpZXMgYmVjYXVzZSB0aGlzIGlzIHJlcG9ydGluZydzIG9ubHlcbiAqIGR1cmFibGUgcGVyc2lzdGVuY2UgYm91bmRhcnkg4oCUIGV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgc2VydmljZSBvbmx5IHJlYWRzLlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBzY3J1YkF3c0lkZW50aWZpZXJzIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgaW5BcnJheSB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGludmFsaWRhdGVPcmdSZXBvcnRzIH0gZnJvbSAnLi9jYWNoZXMuanMnO1xuaW1wb3J0IHsgdXBzZXJ0RGVwbG95bWVudHMgfSBmcm9tICcuL2RlcGxveS1yb2xsdXAuanMnO1xuaW1wb3J0IHsgY2xhc3NpZnlGYWlsdXJlIH0gZnJvbSAnLi9mYWlsdXJlLWNsYXNzaWZpZXIuanMnO1xuaW1wb3J0IHsgc2NydWJPcHRpb25hbCB9IGZyb20gJy4vc3FsLWhlbHBlcnMuanMnO1xuaW1wb3J0IHR5cGUgeyBJbmdlc3RDYWxsZXIsIEluZ2VzdEV2ZW50LCBJbmdlc3RNZXRyaWMsIEluZ2VzdFJlc3VsdCB9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEuanMnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4IH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5pbXBvcnQgdHlwZSB7IENydWRUeCB9IGZyb20gJy4uL2NydWQtc2VydmljZS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLWluZ2VzdCcpO1xuXG50eXBlIFBpcGVsaW5lRXZlbnRJbnNlcnQgPSB0eXBlb2Ygc2NoZW1hLnBpcGVsaW5lRXZlbnQuJGluZmVySW5zZXJ0O1xuXG5cbi8qKiBUaGUgcGx1Z2luIGEgcGlwZWxpbmUgc3RlcCBydW5zLCBmcm9tIHRoZSBzdGVwIG1hbmlmZXN0IGl0cyBsYXN0IGRlcGxveSByZWdpc3RlcmVkLiAqL1xuaW50ZXJmYWNlIFN0ZXBQbHVnaW4ge1xuICBvcmdJZDogc3RyaW5nO1xuICBwbHVnaW5QdWJsaXNoZXI6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpblB1Ymxpc2hlcklkOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5OYW1lOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5WZXJzaW9uOiBzdHJpbmcgfCBudWxsO1xufVxuXG4vKiogQW4gYWN0aW9uL2J1aWxkIGV2ZW50IHRoYXQgY2FuIGJlIGF0dHJpYnV0ZWQgdG8gYSBwbHVnaW4gc3RlcC4gKi9cbmZ1bmN0aW9uIGlzQXR0cmlidXRhYmxlKGU6IEluZ2VzdEV2ZW50KTogYm9vbGVhbiB7XG4gIHJldHVybiAoZS5ldmVudFR5cGUgPT09ICdBQ1RJT04nIHx8IGUuZXZlbnRUeXBlID09PSAnQlVJTEQnKVxuICAgICYmIChlLmV2ZW50U291cmNlID09PSAnY29kZXBpcGVsaW5lJyB8fCBlLmV2ZW50U291cmNlID09PSAnY29kZWJ1aWxkJylcbiAgICAmJiAhIWUuc3RhZ2VOYW1lICYmICEhZS5hY3Rpb25OYW1lO1xufVxuXG5mdW5jdGlvbiBzdGVwS2V5KHBpcGVsaW5lSWQ6IHN0cmluZywgc3RhZ2VOYW1lOiBzdHJpbmcsIGFjdGlvbk5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtwaXBlbGluZUlkfVxcdTAwMDAke3N0YWdlTmFtZX1cXHUwMDAwJHthY3Rpb25OYW1lfWA7XG59XG5cbi8qKlxuICogUGx1Z2luIGF0dHJpYnV0aW9uOiB0aGUgc3RlcCBtYW5pZmVzdHMgb2YgZXZlcnkgcGlwZWxpbmUgd2l0aCBhbiBhdHRyaWJ1dGFibGVcbiAqIGV2ZW50LCBpbiBPTkUgcmVhZCBwZXIgYmF0Y2gsIGtleWVkIGZvciBhbiBpbi1tZW1vcnkgam9pbi4gTmFtZXMgYXJlIGNvbXBhcmVkXG4gKiBwb3N0LXNjcnViIG9uIGJvdGggc2lkZXMgKHRoZSBtYW5pZmVzdCBzdG9yZXMgdGhlbSBzY3J1YmJlZCB0aGUgc2FtZSB3YXkpLlxuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkU3RlcFBsdWdpbnModHg6IENydWRUeCwgYXR0cmlidXRhYmxlOiBJbmdlc3RFdmVudFtdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBTdGVwUGx1Z2luPj4ge1xuICBjb25zdCBwaXBlbGluZUlkcyA9IFsuLi5uZXcgU2V0KGF0dHJpYnV0YWJsZS5tYXAoKGUpID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgaWYgKHBpcGVsaW5lSWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG5ldyBNYXAoKTtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHR4XG4gICAgLnNlbGVjdCh7XG4gICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3Qub3JnSWQsXG4gICAgICBzdGFnZU5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5zdGFnZU5hbWUsXG4gICAgICBhY3Rpb25OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QuYWN0aW9uTmFtZSxcbiAgICAgIHBsdWdpblB1Ymxpc2hlcjogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblB1Ymxpc2hlcixcbiAgICAgIHBsdWdpblB1Ymxpc2hlcklkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luUHVibGlzaGVySWQsXG4gICAgICBwbHVnaW5OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luTmFtZSxcbiAgICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5WZXJzaW9uLFxuICAgIH0pXG4gICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0KVxuICAgIC53aGVyZShpbkFycmF5KHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5waXBlbGluZUlkLCBwaXBlbGluZUlkcykpO1xuICByZXR1cm4gbmV3IE1hcChyb3dzLm1hcCgobSkgPT4gW3N0ZXBLZXkobS5waXBlbGluZUlkLCBtLnN0YWdlTmFtZSwgbS5hY3Rpb25OYW1lKSwgbV0pKTtcbn1cblxuLyoqXG4gKiBBbGxvd2FuY2UgZm9yIGNsb2NrIHNrZXcgYmV0d2VlbiBhbiBBV1MgZXZlbnQncyBzb3VyY2UgY2xvY2sgYW5kIG91cnMuIEEgcmVhbFxuICogQ29kZVBpcGVsaW5lIGV2ZW50IGNhbiBjYXJyeSBhIHRpbWVzdGFtcCBhIGxpdHRsZSBhaGVhZCBvZiBvdXIgYG5vd2A7IHdpdGhvdXRcbiAqIHNvbWUgdG9sZXJhbmNlIHRoZSB2YWxpZGF0aW9uIGJlbG93IHdvdWxkIGRyb3AgaGVhbHRoeSBldmVudHMgZHVyaW5nIG5vcm1hbFxuICogTlRQIGRyaWZ0LCB3aGljaCBpcyBmYXIgd29yc2UgdGhhbiBhZG1pdHRpbmcgYSBmZXcgc2Vjb25kcyBvZiBza2V3LlxuICovXG5jb25zdCBDTE9DS19TS0VXX1RPTEVSQU5DRV9NUyA9IDUgKiA2MCAqIDEwMDA7XG5cbi8qKlxuICogV2h5IHRoaXMgZXZlbnQncyB0aW1lc3RhbXBzIGFyZSBpbXBvc3NpYmxlLCBvciBudWxsIHdoZW4gdGhleSBhcmUgdXNhYmxlLlxuICpcbiAqIENoZWNrZWQgYXQgSU5HRVNUIOKAlCB0aGUgZHVyYWJsZSBib3VuZGFyeSDigJQgcmF0aGVyIHRoYW4gY2xhbXBlZCB3aGVuIHRoZSBtZXRyaWNzXG4gKiBhcmUgY29tcHV0ZWQuIEEgbmVnYXRpdmUgZHVyYXRpb24gb3IgYSBmdXR1cmUgZGVwbG95IHVzZWQgdG8gYmUgY2xhbXBlZCB0byAwXG4gKiBkb3duc3RyZWFtLCB3aGljaCByZXBvcnRlZCBhIGJyb2tlbiBjbG9jayBhcyBhbiBpbnN0YW50IGRlcGxveSBhbmQgcXVpZXRseVxuICogbW92ZWQgZGVwbG95bWVudCBmcmVxdWVuY3ksIGNoYW5nZS1mYWlsdXJlIHJhdGUgYW5kIGxlYWQgdGltZSBmb3IgdGhlIG9yZy5cbiAqXG4gKiBOT1QgY2hlY2tlZCBoZXJlOiBjb21taXQgdGltZSB2cyBkZXBsb3kgY29tcGxldGlvbi4gYGNvbW1pdF90aW1lc3RhbXBgIHJpZGVzIHRoZVxuICogUElQRUxJTkUvc291cmNlIGV2ZW50IHdoaWxlIHRoZSBkZXBsb3kncyBgY29tcGxldGVkX2F0YCBpcyBvbiBhIHNlcGFyYXRlIFNUQUdFXG4gKiByb3csIGpvaW5lZCBieSBgZXhlY3V0aW9uX2lkYCBvbmx5IHdoZW4gRE9SQSBpcyBxdWVyaWVkIOKAlCBzbyBubyBzaW5nbGUgZXZlbnRcbiAqIGNhcnJpZXMgYm90aCwgYW5kIHRoYXQgb3JkZXJpbmcgY2FuIG9ubHkgYmUgZ3VhcmRlZCB3aGVyZSB0aGUgdHdvIG1lZXQuXG4gKi9cbmZ1bmN0aW9uIGludmFsaWRFdmVudFRpbWVzKGV2ZW50OiBJbmdlc3RFdmVudCwgbm93TXM6IG51bWJlcik6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBjZWlsaW5nID0gbm93TXMgKyBDTE9DS19TS0VXX1RPTEVSQU5DRV9NUztcbiAgY29uc3QgcGFyc2VkOiBBcnJheTxbc3RyaW5nLCBudW1iZXJdPiA9IFtdO1xuICBmb3IgKGNvbnN0IGZpZWxkIG9mIFsnc3RhcnRlZEF0JywgJ2NvbXBsZXRlZEF0JywgJ2NvbW1pdFRpbWVzdGFtcCddIGFzIGNvbnN0KSB7XG4gICAgY29uc3QgcmF3ID0gZXZlbnRbZmllbGRdO1xuICAgIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09IG51bGwpIGNvbnRpbnVlO1xuICAgIGNvbnN0IG1zID0gRGF0ZS5wYXJzZShTdHJpbmcocmF3KSk7XG4gICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobXMpKSByZXR1cm4gYCR7ZmllbGR9IGlzIG5vdCBhIHBhcnNlYWJsZSB0aW1lc3RhbXBgO1xuICAgIGlmIChtcyA+IGNlaWxpbmcpIHJldHVybiBgJHtmaWVsZH0gaXMgaW4gdGhlIGZ1dHVyZWA7XG4gICAgcGFyc2VkLnB1c2goW2ZpZWxkLCBtc10pO1xuICB9XG4gIGNvbnN0IHN0YXJ0ZWQgPSBwYXJzZWQuZmluZCgoW2ZdKSA9PiBmID09PSAnc3RhcnRlZEF0Jyk/LlsxXTtcbiAgY29uc3QgY29tcGxldGVkID0gcGFyc2VkLmZpbmQoKFtmXSkgPT4gZiA9PT0gJ2NvbXBsZXRlZEF0Jyk/LlsxXTtcbiAgaWYgKHN0YXJ0ZWQgIT09IHVuZGVmaW5lZCAmJiBjb21wbGV0ZWQgIT09IHVuZGVmaW5lZCAmJiBjb21wbGV0ZWQgPCBzdGFydGVkKSB7XG4gICAgcmV0dXJuICdjb21wbGV0ZWRBdCBpcyBiZWZvcmUgc3RhcnRlZEF0JztcbiAgfVxuICBpZiAoZXZlbnQuZHVyYXRpb25NcyAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmR1cmF0aW9uTXMgIT09IG51bGwgJiYgZXZlbnQuZHVyYXRpb25NcyA8IDApIHtcbiAgICByZXR1cm4gJ2R1cmF0aW9uTXMgaXMgbmVnYXRpdmUnO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFRoZSBwZXJzaXN0ZWQgcm93IGZvciBvbmUgaW5nZXN0ZWQgZXZlbnQuIFRoaXMgaXMgdGhlIERVUkFCTEUgcGVyc2lzdGVuY2VcbiAqIGJvdW5kYXJ5OiBldmVyeSB1c2VyL0FXUy1kZXJpdmVkIGZyZWUtZm9ybSBzdHJpbmcgaXMgc2NydWJiZWQgaGVyZSwgYW5kXG4gKiB0ZW5hbmN5IGNvbWVzIGZyb20gdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBuZXZlciB0aGUgY2FsbGVyJ3MgY2xhaW1lZCBvcmcuXG4gKi9cbmZ1bmN0aW9uIHRvRXZlbnRSb3coZXZlbnQ6IEluZ2VzdEV2ZW50LCByZWdpc3RyeTogeyBwaXBlbGluZUlkOiBzdHJpbmc7IG9yZ0lkOiBzdHJpbmcgfSwgcGx1Z2luOiBTdGVwUGx1Z2luIHwgdW5kZWZpbmVkKTogUGlwZWxpbmVFdmVudEluc2VydCB7XG4gIHJldHVybiB7XG4gICAgLy8gcmVnaXN0cnkucGlwZWxpbmVJZCA9PT0gZXZlbnQucGlwZWxpbmVJZDsgdGhlIHJlZ2lzdHJ5J3MgaXMgYWx3YXlzIGEgcm93XG4gICAgLy8gdGhhdCBleGlzdHMgKEZLKSBhbmQgaXRzIG9yZ0lkIGlzIHRoZSB0cnVzdGVkIHRlbmFudC5cbiAgICBwaXBlbGluZUlkOiByZWdpc3RyeS5waXBlbGluZUlkLFxuICAgIG9yZ0lkOiByZWdpc3RyeS5vcmdJZCxcbiAgICBldmVudFNvdXJjZTogZXZlbnQuZXZlbnRTb3VyY2UsXG4gICAgZXZlbnRUeXBlOiBldmVudC5ldmVudFR5cGUsXG4gICAgc3RhdHVzOiBldmVudC5zdGF0dXMsXG4gICAgLy8gQW4gQVdTLUFTU0lHTkVEIFVVSUQsIG5vdCBmcmVlLWZvcm0gdGV4dDogaXQgY2FuJ3QgY2FycnkgYW4gYWNjb3VudCBpZCxcbiAgICAvLyBhbmQgc2NydWJiaW5nIGEgMTItZGlnaXQgcnVuIGluc2lkZSBpdCB3b3VsZCBjb3JydXB0IHRoZSBjb3JyZWxhdGlvbiBrZXkuXG4gICAgZXhlY3V0aW9uSWQ6IGV2ZW50LmV4ZWN1dGlvbklkLFxuICAgIC8vIFVTRVItQVVUSE9SRUQgcGlwZWxpbmUtc3RydWN0dXJlIG5hbWVzIOKAlCBzYW1lIHVudHJ1c3RlZCBvcmlnaW4gYXNcbiAgICAvLyBlcnJvck1lc3NhZ2UsIHNvIHNjcnViYmVkIChhIHN0YWdlIG5hbWVkIHdpdGggYW4gQVJOIG11c3Qgbm90IHBlcnNpc3QpLlxuICAgIHN0YWdlTmFtZTogc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpLFxuICAgIGFjdGlvbk5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSksXG4gICAgLy8gSEFSRCBDT05TVFJBSU5UOiBhbiBBV1MgYWNjb3VudCBpZCBtdXN0IE5FVkVSIGJlIHBlcnNpc3RlZC4gRmFpbHVyZSBkZXRhaWxcbiAgICAvLyBhbmQgbWVzc2FnZXMgcm91dGluZWx5IGNhcnJ5IEFSTnMgYW5kIGJhcmUgMTItZGlnaXQgYWNjb3VudCBpZHMuXG4gICAgZXJyb3JNZXNzYWdlOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVycm9yTWVzc2FnZSksXG4gICAgc3RhcnRlZEF0OiBldmVudC5zdGFydGVkQXQgPyBuZXcgRGF0ZShldmVudC5zdGFydGVkQXQpIDogdW5kZWZpbmVkLFxuICAgIGNvbXBsZXRlZEF0OiBldmVudC5jb21wbGV0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LmNvbXBsZXRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICBkdXJhdGlvbk1zOiBldmVudC5kdXJhdGlvbk1zLFxuICAgIC8vIERlcGxveSBhdHRyaWJ1dGlvbiDigJQgc2NydWJiZWQgbGlrZSB0aGUgb3RoZXIgZnJlZS1mb3JtIHN0cmluZ3MuXG4gICAgY29tbWl0U2hhOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFNoYSksXG4gICAgY29tbWl0UmVmOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFJlZiksXG4gICAgZW52aXJvbm1lbnQ6IHNjcnViT3B0aW9uYWwoZXZlbnQuZW52aXJvbm1lbnQpLFxuICAgIC8vIE1lYXN1cmVkIGxlYWQgdGltZTogdGhlIG9sZGVzdCB1bnNoaXBwZWQgY29tbWl0J3MgdGltZSArIHRoZSBjb3VudC4gQW5cbiAgICAvLyBTQ00tZGVyaXZlZCBpbnN0YW50IGFuZCBhIHBsYWluIGludGVnZXIg4oCUIG5vdGhpbmcgdG8gc2NydWIuXG4gICAgY29tbWl0VGltZXN0YW1wOiBldmVudC5jb21taXRUaW1lc3RhbXAgPyBuZXcgRGF0ZShldmVudC5jb21taXRUaW1lc3RhbXApIDogdW5kZWZpbmVkLFxuICAgIGNvbW1pdENvdW50OiBldmVudC5jb21taXRDb3VudCxcbiAgICAvLyBOVUxMIGZvciBub24tcGx1Z2luIGFjdGlvbnMgYW5kIGZvciBwaXBlbGluZXMgZGVwbG95ZWQgd2l0aG91dCBhIG1hbmlmZXN0LlxuICAgIHBsdWdpblB1Ymxpc2hlcjogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5QdWJsaXNoZXJJZDogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXJJZCA/PyBudWxsLFxuICAgIHBsdWdpbk5hbWU6IHBsdWdpbj8ucGx1Z2luTmFtZSA/PyBudWxsLFxuICAgIHBsdWdpblZlcnNpb246IHBsdWdpbj8ucGx1Z2luVmVyc2lvbiA/PyBudWxsLFxuICAgIC8vIFdIQVQgS0lORCBvZiB0aGluZyBicm9rZSwgY2xhc3NpZmllZCBoZXJlIHJhdGhlciB0aGFuIGF0IHJlYWQgdGltZTogdGhlXG4gICAgLy8gZXJyb3IgdGV4dCBpcyBzY3J1YmJlZCBhYm92ZSBhbmQgZXZlbnR1YWxseSBzd2VwdCBieSByZXRlbnRpb24sIHNvIGFcbiAgICAvLyBjYXRlZ29yeSBkZXJpdmVkIGxhdGVyIHdvdWxkIGhhdmUgbm90aGluZyBsZWZ0IHRvIHJlYWQuIE5VTEwgZm9yIGFueXRoaW5nXG4gICAgLy8gdGhhdCBpcyBub3QgYSBmYWlsdXJlLCBzbyBpdHMgcHJlc2VuY2UgYWx3YXlzIG1lYW5zIFwidGhpcyBicm9rZVwiLlxuICAgIGZhaWx1cmVDYXRlZ29yeTogY2xhc3NpZnlGYWlsdXJlKHtcbiAgICAgIHN0YXR1czogZXZlbnQuc3RhdHVzLFxuICAgICAgZXJyb3JNZXNzYWdlOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVycm9yTWVzc2FnZSksXG4gICAgICBhY3Rpb25OYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpLFxuICAgICAgc3RhZ2VOYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LnN0YWdlTmFtZSksXG4gICAgfSksXG4gICAgZGV0YWlsOiBldmVudC5kZXRhaWwgIT09IHVuZGVmaW5lZCA/IHNjcnViQXdzSWRlbnRpZmllcnMoZXZlbnQuZGV0YWlsKSA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBGYW4gdGVybWluYWwgU1RBR0Ugb3V0Y29tZXMgaW50byB0aGUgcm91dGUncyBtZXRyaWMgaG9vayAocGlwZWxpbmUtZGF0YSBjYW4ndFxuICogaW1wb3J0IGFwaS1zZXJ2ZXIncyByZWdpc3RyeSkgYWZ0ZXIgdGhlIGluc2VydCBjb21taXRzLiBEcml2ZW4gb2ZmIHRoZVxuICogSU5TRVJURUQgcm93cywgc28gYSByZS1kZWxpdmVyZWQgZXZlbnQgdGhlIGRlZHVwIGluZGV4IHN3YWxsb3dlZCBpcyBuZXZlclxuICogY291bnRlZCB0d2ljZS4gQSBub24tbnVsbCBlbnZpcm9ubWVudCBtYXJrcyBhIGRlcGxveS5cbiAqL1xuZnVuY3Rpb24gZW1pdFN0YWdlTWV0cmljcyhcbiAgcm93czogUmVhZG9ubHlBcnJheTx7IG9yZ0lkOiBzdHJpbmc7IHBpcGVsaW5lSWQ6IHN0cmluZyB8IG51bGw7IGV2ZW50VHlwZTogc3RyaW5nOyBzdGF0dXM6IHN0cmluZzsgc3RhZ2VOYW1lOiBzdHJpbmcgfCBudWxsOyBlbnZpcm9ubWVudDogc3RyaW5nIHwgbnVsbCB9PixcbiAgb25NZXRyaWM6IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQsXG4pOiB2b2lkIHtcbiAgZm9yIChjb25zdCByIG9mIHJvd3MpIHtcbiAgICBpZiAoci5ldmVudFR5cGUgIT09ICdTVEFHRScgfHwgKHIuc3RhdHVzICE9PSAnU1VDQ0VFREVEJyAmJiByLnN0YXR1cyAhPT0gJ0ZBSUxFRCcpIHx8ICFyLnBpcGVsaW5lSWQpIGNvbnRpbnVlO1xuICAgIG9uTWV0cmljKHtcbiAgICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiByLm9yZ0lkLFxuICAgICAgc3RhZ2U6IHIuc3RhZ2VOYW1lID8/ICcnLFxuICAgICAgZW52aXJvbm1lbnQ6IHIuZW52aXJvbm1lbnQgPz8gbnVsbCxcbiAgICAgIHJlc3VsdDogci5zdGF0dXMgPT09ICdTVUNDRUVERUQnID8gJ3N1Y2NlZWRlZCcgOiAnZmFpbGVkJyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmUgaW5jb21pbmcgZXZlbnRzIGFnYWluc3QgdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBiYXRjaC1pbnNlcnQgdGhlXG4gKiBtYXRjaGVkIG9uZXMsIGFuZCBpbnZhbGlkYXRlIHJlcG9ydGluZyBjYWNoZXMgZm9yIGFmZmVjdGVkIG9yZ3MuXG4gKiBFdmVudHMgZm9yIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZHMgYXJlIGRyb3BwZWQgKGFuZCBsb2dnZWQgYXQgV0FSTlxuICogd2l0aCBzYW1wbGUgaWRzIHNvIGFuIG9wZXJhdG9yIGNhbiBzZWUgd2hlbiBFdmVudEJyaWRnZSBpcyBkZWxpdmVyaW5nXG4gKiBldmVudHMgZm9yIHBpcGVsaW5lcyB0aGF0IGhhdmVuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQpLlxuICpcbiAqIFJldHVybnMgY291bnRzICsgYSBzYW1wbGUgb2YgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBmb3Igb2JzZXJ2YWJpbGl0eS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluZ2VzdEV2ZW50cyhcbiAgZXZlbnRzOiBJbmdlc3RFdmVudFtdLFxuICBvbk1ldHJpYz86IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQsXG4gIGNhbGxlcj86IEluZ2VzdENhbGxlcixcbik6IFByb21pc2U8SW5nZXN0UmVzdWx0PiB7XG4gIC8vIFRFTkFOQ1kuIEFuIGV2ZW50J3Mgb3JnIGNvbWVzIGZyb20gdGhlIHBpcGVsaW5lIFJFR0lTVFJZLCBub3QgdGhlIHRva2VuLCBzb1xuICAvLyB0aGUgc2NvcGUgY2hlY2sgYWxvbmUgbGV0IGFueSBgcmVwb3J0aW5nOmluZ2VzdGAgaG9sZGVyIHBvc3QgZXZlbnRzIGZvclxuICAvLyBhbm90aGVyIG9yZydzIHBpcGVsaW5lIGlkIGFuZCBoYXZlIHRoZW0gYXR0cmlidXRlZCB0aGVyZS4gYGNhbGxlcmAgY2Fycmllc1xuICAvLyB0aGUgb3JnIGlkcyB0aGlzIHRva2VuIG1heSB3cml0ZSBmb3I7IGFueXRoaW5nIGVsc2UgaXMgZHJvcHBlZCBiZWxvdy5cbiAgLy9cbiAgLy8gYGNhbGxlcmAgaXMgb3B0aW9uYWwgb25seSBzbyBpbi1wcm9jZXNzIGNhbGxlcnMgdGhhdCBhbHJlYWR5IHJ1blxuICAvLyBjcm9zcy10ZW5hbnQgKHRlc3RzLCBiYWNrZmlsbHMpIGtlZXAgd29ya2luZyDigJQgYW4gQUJTRU5UIGNhbGxlciBtZWFucyBcIm5vXG4gIC8vIHJlc3RyaWN0aW9uXCIsIGFuZCB0aGUgcm91dGUgYWx3YXlzIHN1cHBsaWVzIG9uZS4gQSBjYWxsZXIgd2l0aCBhbiBFTVBUWVxuICAvLyBhbGxvdy1saXN0IGFuZCBubyBjcm9zc1RlbmFudCBmbGFnIHRoZXJlZm9yZSBkcm9wcyBldmVyeXRoaW5nLCB3aGljaCBpcyB0aGVcbiAgLy8gcmlnaHQgYW5zd2VyIHdoZW4gdGhlIHJvdXRlIGNvdWxkIG5vdCBlc3RhYmxpc2ggd2hvIGlzIHdyaXRpbmcuXG4gIGNvbnN0IHVucmVzdHJpY3RlZCA9IGNhbGxlciA9PT0gdW5kZWZpbmVkIHx8IGNhbGxlci5jcm9zc1RlbmFudCA9PT0gdHJ1ZTtcbiAgY29uc3QgYWxsb3dlZCA9IG5ldyBTZXQoY2FsbGVyPy5hbGxvd2VkT3JnSWRzID8/IFtdKTtcbiAgLy8gTXVsdGktb3JnIGJhdGNoIGluc2VydDogdGhlIGNhbGxlciByZXNvbHZlcyB0byBtdWx0aXBsZSBvcmdzIHZpYSB0aGVcbiAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAvLyBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgLi4uKWAgc2NvcGUgYmVmb3JlIGNhbGxpbmdcbiAgLy8gdGhpcyBmdW5jdGlvbi4gVW5kZXIgRk9SQ0UnZCBSTFMsIGEgc2luZ2xlIHR4IHdpdGggYGFwcC5vcmdfaWQgPSA8b25lXG4gIC8vIG9yZz5gIGNvdWxkIG9ubHkgd3JpdGUgZXZlbnRzIGZvciB0aGF0IG9yZzsgYnlwYXNzIHZpYSBzeXNhZG1pbiBpc1xuICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgLy8gYXBpL3JlcG9ydGluZy9zcmMvcm91dGVzL2V2ZW50LWluZ2VzdC50cyBmb3IgdGhlIHdyYXBwZXIuXG4gIC8vIENhY2hlcyBhcmUgaW52YWxpZGF0ZWQgQUZURVIgdGhlIHR4IHJlc29sdmVzOiBkb2luZyBpdCBpbnNpZGUgaGVsZCB0aGUgcGdcbiAgLy8gbG9ja3Mgb3BlbiBhY3Jvc3MgdW5yZWxhdGVkIGNhY2hlIHJvdW5kLXRyaXBzLiBUaGUgVFRMIGlzIDItNSBtaW4sIHNvIGFcbiAgLy8gZmlyZS1hbmQtZm9yZ2V0IHBvc3QtY29tbWl0IGludmFsaWRhdGlvbiBpcyBhbiBhY2NlcHRhYmxlIHRyYWRlLlxuICBjb25zdCB7IGluc2VydGVkLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcywgYWZmZWN0ZWRPcmdzLCBkcm9wcGVkRm9yZWlnbk9yZywgZHJvcHBlZEludmFsaWRUaW1lLCBpbnNlcnRlZFJvd3MgfSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgIGNvbnN0IHVuaXF1ZUlkcyA9IFsuLi5uZXcgU2V0KGV2ZW50cy5tYXAoZSA9PiBlLnBpcGVsaW5lSWQpKV07XG4gICAgY29uc3QgcmVnaXN0cnlSb3dzID0gYXdhaXQgdHhcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkub3JnSWQsXG4gICAgICB9KVxuICAgICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkpXG4gICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLCB1bmlxdWVJZHMpKTtcblxuICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcbiAgICBjb25zdCBzdGVwUGx1Z2lucyA9IGF3YWl0IGxvYWRTdGVwUGx1Z2lucyh0eCwgZXZlbnRzLmZpbHRlcigoZSkgPT4gaXNBdHRyaWJ1dGFibGUoZSkgJiYgaWRNYXAuaGFzKGUucGlwZWxpbmVJZCkpKTtcblxuICAgIC8vIEJ1aWxkIGluc2VydCBiYXRjaCAoc2tpcCBldmVudHMgd2hvc2UgcGlwZWxpbmUgaXNuJ3QgcmVnaXN0ZXJlZClcbiAgICBjb25zdCByb3dzOiBQaXBlbGluZUV2ZW50SW5zZXJ0W10gPSBbXTtcbiAgICBsZXQgc2tpcHBlZExvY2FsID0gMDtcbiAgICBsZXQgZm9yZWlnbkxvY2FsID0gMDtcbiAgICBsZXQgaW52YWxpZFRpbWVMb2NhbCA9IDA7XG4gICAgY29uc3QgaW52YWxpZFRpbWVSZWFzb25zID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgZm9yZWlnbk9yZ0lkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHVucmVnaXN0ZXJlZExvY2FsOiBzdHJpbmdbXSA9IFtdO1xuICAgIC8vIE9uZSBgbm93YCBmb3IgdGhlIHdob2xlIGJhdGNoOiBwZXItZXZlbnQgY2xvY2tzIHdvdWxkIGxldCBhbiBldmVudCBwYXNzIG9yXG4gICAgLy8gZmFpbCBkZXBlbmRpbmcgb24gd2hlcmUgaXQgc2F0IGluIHRoZSBsb29wLlxuICAgIGNvbnN0IG5vd01zID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IGlkTWFwLmdldChldmVudC5waXBlbGluZUlkKTtcbiAgICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgICAgc2tpcHBlZExvY2FsKys7XG4gICAgICAgIHVucmVnaXN0ZXJlZExvY2FsLnB1c2goZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gVGhlIHBpcGVsaW5lIHJlc29sdmVzIHRvIGFuIG9yZyB0aGlzIGNhbGxlciBtYXkgbm90IHdyaXRlIGZvci4gQ291bnRlZFxuICAgICAgLy8gc2VwYXJhdGVseSBmcm9tIGBza2lwcGVkYCAoYW4gdW5yZWdpc3RlcmVkIGlkIGlzIGEgcHJvZHVjZXIgcnVubmluZ1xuICAgICAgLy8gYWhlYWQgb2YgcmVnaXN0cmF0aW9uOyB0aGlzIGlzIGEgdGVuYW5jeSByZWZ1c2FsKSBhbmQgbmV2ZXIgaW5zZXJ0ZWQuXG4gICAgICBpZiAoIXVucmVzdHJpY3RlZCAmJiAhYWxsb3dlZC5oYXMocmVnaXN0cnkub3JnSWQpKSB7XG4gICAgICAgIGZvcmVpZ25Mb2NhbCsrO1xuICAgICAgICBmb3JlaWduT3JnSWRzLmFkZChyZWdpc3RyeS5vcmdJZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gSW1wb3NzaWJsZSB0aW1lc3RhbXBzIGFyZSByZWZ1c2VkIGF0IHRoZSBib3VuZGFyeSwgc28gbm8gZG93bnN0cmVhbVxuICAgICAgLy8gbWV0cmljIGhhcyB0byBjbGFtcCBhIG5lZ2F0aXZlIGdhcCBhbmQgY2FsbCBpdCB6ZXJvLlxuICAgICAgY29uc3QgYmFkVGltZSA9IGludmFsaWRFdmVudFRpbWVzKGV2ZW50LCBub3dNcyk7XG4gICAgICBpZiAoYmFkVGltZSkge1xuICAgICAgICBpbnZhbGlkVGltZUxvY2FsKys7XG4gICAgICAgIGludmFsaWRUaW1lUmVhc29ucy5hZGQoYmFkVGltZSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhZ2VOYW1lID0gc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpO1xuICAgICAgY29uc3QgYWN0aW9uTmFtZSA9IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSk7XG4gICAgICBjb25zdCBzdGVwID0gaXNBdHRyaWJ1dGFibGUoZXZlbnQpICYmIHN0YWdlTmFtZSAmJiBhY3Rpb25OYW1lXG4gICAgICAgID8gc3RlcFBsdWdpbnMuZ2V0KHN0ZXBLZXkocmVnaXN0cnkucGlwZWxpbmVJZCwgc3RhZ2VOYW1lLCBhY3Rpb25OYW1lKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAvLyBTYW1lLW9yZyBndWFyZDogYSBtYW5pZmVzdCByb3cgaXMgb25seSBldmVyIHdyaXR0ZW4gYnkgdGhlIG9yZyB0aGF0XG4gICAgICAvLyBvd25zIHRoZSBwaXBlbGluZSwgYnV0IHRoZSBpbmdlc3QgcnVucyBjcm9zcy10ZW5hbnQsIHNvIGRvbid0IGxlYW4gb24gaXQuXG4gICAgICByb3dzLnB1c2godG9FdmVudFJvdyhldmVudCwgcmVnaXN0cnksIHN0ZXAgJiYgc3RlcC5vcmdJZCA9PT0gcmVnaXN0cnkub3JnSWQgPyBzdGVwIDogdW5kZWZpbmVkKSk7XG4gICAgfVxuXG4gICAgLy8gU1FTIGlzIGF0LWxlYXN0LW9uY2UsIHNvIEV2ZW50QnJpZGdlIGNhbiBkZWxpdmVyIHRoZSBzYW1lIHN0YXRlLWNoYW5nZVxuICAgIC8vIHR3aWNlLiBgb25Db25mbGljdERvTm90aGluZ2AgKyB0aGUgcGFydGlhbCB1bmlxdWUgaW5kZXggb25cbiAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAvLyBtYWtlcyByZS1kZWxpdmVyeSBpZGVtcG90ZW50LiBgcmV0dXJuaW5nYCBnaXZlcyB0aGUgUkVBTCBpbnNlcnRlZCBzZXQgc29cbiAgICAvLyBjb3VudHMsIG1ldHJpY3MgYW5kIGNhY2hlIGludmFsaWRhdGlvbiBhbGwgaWdub3JlIGR1cGxpY2F0ZXMuXG4gICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICA/IGF3YWl0IHR4Lmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpXG4gICAgICAgIC5vbkNvbmZsaWN0RG9Ob3RoaW5nKClcbiAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkLFxuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnBpcGVsaW5lSWQsXG4gICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgc3RhdHVzOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGF0dXMsXG4gICAgICAgICAgc3RhZ2VOYW1lOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGFnZU5hbWUsXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmVudmlyb25tZW50LFxuICAgICAgICAgIC8vIEZvciB0aGUgcGVyLWRlcGxveSByb2xsdXAgYmVsb3c6IGV2ZXJ5dGhpbmcgYGRvcmFfZGVwbG95bWVudHNgIG5lZWRzLFxuICAgICAgICAgIC8vIHRha2VuIGZyb20gdGhlIHJvd3MgdGhhdCBBQ1RVQUxMWSBsYW5kZWQgc28gYSByZS1kZWxpdmVyeSBjYW5ub3RcbiAgICAgICAgICAvLyBwcm9kdWNlIGEgc2Vjb25kIGRlcGxveS5cbiAgICAgICAgICBleGVjdXRpb25JZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuZXhlY3V0aW9uSWQsXG4gICAgICAgICAgY29tbWl0U2hhOiBzY2hlbWEucGlwZWxpbmVFdmVudC5jb21taXRTaGEsXG4gICAgICAgICAgY29tbWl0VGltZXN0YW1wOiBzY2hlbWEucGlwZWxpbmVFdmVudC5jb21taXRUaW1lc3RhbXAsXG4gICAgICAgICAgY29tbWl0Q291bnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmNvbW1pdENvdW50LFxuICAgICAgICAgIGNvbXBsZXRlZEF0OiBzY2hlbWEucGlwZWxpbmVFdmVudC5jb21wbGV0ZWRBdCxcbiAgICAgICAgICBzdGFydGVkQXQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnN0YXJ0ZWRBdCxcbiAgICAgICAgICBjcmVhdGVkQXQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmNyZWF0ZWRBdCxcbiAgICAgICAgICBkZXRhaWw6IHNjaGVtYS5waXBlbGluZUV2ZW50LmRldGFpbCxcbiAgICAgICAgfSlcbiAgICAgIDogW107XG5cbiAgICAvLyBMb2cgaW5zaWRlIHRoZSB0eCBzY29wZSB3aGlsZSB0aGUgb3JnIHNldCBpcyBpbiBoYW5kLiBXQVJOLCBub3QgZXJyb3I6XG4gICAgLy8gYSBtaXNyb3V0ZWQgcHJvZHVjZXIgaXMgdGhlIGNvbW1vbiBjYXVzZSwgYnV0IHRoZSBzYW1lIGxpbmUgaXMgdGhlIG9ubHlcbiAgICAvLyBzaWduYWwgb2YgYW4gaW5qZWN0aW9uIGF0dGVtcHQsIHNvIGl0IG5hbWVzIHRoZSBvcmdzIGl0IHJlZnVzZWQuXG4gICAgaWYgKGZvcmVpZ25Mb2NhbCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdEcm9wcGVkIGluZ2VzdCBldmVudHMgZm9yIG9yZ3MgdGhlIGNhbGxlciBtYXkgbm90IHdyaXRlIGZvcicsIHtcbiAgICAgICAgZHJvcHBlZDogZm9yZWlnbkxvY2FsLFxuICAgICAgICBmb3JlaWduT3JnSWRzOiBbLi4uZm9yZWlnbk9yZ0lkc10sXG4gICAgICAgIGFsbG93ZWRPcmdJZHM6IFsuLi5hbGxvd2VkXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChpbnZhbGlkVGltZUxvY2FsID4gMCkge1xuICAgICAgbG9nZ2VyLndhcm4oJ0Ryb3BwZWQgaW5nZXN0IGV2ZW50cyB3aXRoIGltcG9zc2libGUgdGltZXN0YW1wcycsIHtcbiAgICAgICAgZHJvcHBlZDogaW52YWxpZFRpbWVMb2NhbCxcbiAgICAgICAgcmVhc29uczogWy4uLmludmFsaWRUaW1lUmVhc29uc10sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5zZXJ0ZWQ6IGxhbmRlZC5sZW5ndGgsXG4gICAgICBza2lwcGVkOiBza2lwcGVkTG9jYWwsXG4gICAgICB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkczogdW5yZWdpc3RlcmVkTG9jYWwsXG4gICAgICBhZmZlY3RlZE9yZ3M6IFsuLi5uZXcgU2V0KGxhbmRlZC5tYXAociA9PiByLm9yZ0lkKSldLFxuICAgICAgZHJvcHBlZEZvcmVpZ25Pcmc6IGZvcmVpZ25Mb2NhbCxcbiAgICAgIGRyb3BwZWRJbnZhbGlkVGltZTogaW52YWxpZFRpbWVMb2NhbCxcbiAgICAgIGluc2VydGVkUm93czogbGFuZGVkLFxuICAgIH07XG4gIH0pO1xuXG4gIGlmIChvbk1ldHJpYykgZW1pdFN0YWdlTWV0cmljcyhpbnNlcnRlZFJvd3MsIG9uTWV0cmljKTtcblxuICAvLyBQZXItZGVwbG95IHJvbGx1cC4gQUZURVIgdGhlIGV2ZW50cyBjb21taXQgYW5kIG91dHNpZGUgdGhlaXIgdHJhbnNhY3Rpb246IHRoZVxuICAvLyBldmVudHMgYXJlIHRoZSBkdXJhYmxlIHJlY29yZCBhbmQgYGRvcmFfZGVwbG95bWVudHNgIGlzIGRlcml2ZWQgZnJvbSB0aGVtLCBzb1xuICAvLyBhIHJvbGx1cCBmYWlsdXJlIG11c3Qgbm90IHJvbGwgYmFjayBhbiBpbmdlc3QgdGhhdCBzdWNjZWVkZWQuIFJlYnVpbGRhYmxlXG4gIC8vIGVpdGhlciB3YXkuIGB1cHNlcnREZXBsb3ltZW50c2AgbmV2ZXIgdGhyb3dzIGZvciB0aGF0IHJlYXNvbi5cbiAgYXdhaXQgdXBzZXJ0RGVwbG95bWVudHMoaW5zZXJ0ZWRSb3dzKTtcblxuICAvLyBTdXJmYWNlIHRoZSBzaWxlbnQgc2tpcDogYW4gdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkIHVzdWFsbHkgbWVhbnMgdGhlXG4gIC8vIHBpcGVsaW5lIGhhc24ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCAob3IgaXRzXG4gIC8vIHBiLnBpcGVsaW5lLWlkIHRhZyBpcyBtaXNzaW5nL3VucmVhZGFibGUgYnkgdGhlIExhbWJkYSkuIExvZ2dpbmcgaXRcbiAgLy8gbWFrZXMgYSBicm9rZW4gam9pbiB2aXNpYmxlIGluc3RlYWQgb2YgbG9va2luZyBsaWtlIFwibm8gYWN0aXZpdHlcIi5cbiAgaWYgKHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCA+IDApIHtcbiAgICBsb2dnZXIud2FybignUGlwZWxpbmUgZXZlbnRzIHNraXBwZWQ6IHBpcGVsaW5lIGlkIG5vdCBmb3VuZCBpbiByZWdpc3RyeScsIHtcbiAgICAgIGNvdW50OiB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5sZW5ndGgsXG4gICAgICBzYW1wbGU6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLnNsaWNlKDAsIDMpLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gUG9zdC1jb21taXQgY2FjaGUgaW52YWxpZGF0aW9uLiBGaXJlLWFuZC1mb3JnZXQgd2l0aCBsb2dnaW5nIOKAlCBUVEwgaXNcbiAgLy8gc2hvcnQgZW5vdWdoIHRoYXQgYSBtaXNzZWQgaW52YWxpZGF0aW9uIHNlbGYtaGVhbHMuXG4gIGlmIChhZmZlY3RlZE9yZ3MubGVuZ3RoID4gMCkge1xuICAgIHZvaWQgUHJvbWlzZS5hbGwoYWZmZWN0ZWRPcmdzLm1hcCgob3JnKSA9PlxuICAgICAgaW52YWxpZGF0ZU9yZ1JlcG9ydHMob3JnKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQ6IG9yZywgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgfSksXG4gICAgKSk7XG4gIH1cblxuICByZXR1cm4geyBpbnNlcnRlZCwgc2tpcHBlZCwgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMsIGFmZmVjdGVkT3JncywgZHJvcHBlZEZvcmVpZ25PcmcsIGRyb3BwZWRJbnZhbGlkVGltZSB9O1xufVxuIl19
@@ -0,0 +1,31 @@
1
+ import type { IngestCaller } from './types.js';
2
+ /** The bound, or nulls when this pipeline has no recorded deploy carrying a commit. */
3
+ export interface LastDeployedCommit {
4
+ /** Commit sha of the most recent successful deploy to the environment. */
5
+ commitSha: string | null;
6
+ /** When that deploy completed, ISO text — for the caller's own logging. */
7
+ deployedAt: string | null;
8
+ }
9
+ /**
10
+ * The commit sha of the most recent SUCCEEDED deploy-stage execution for this
11
+ * pipeline — narrowed to one `environment` when given.
12
+ *
13
+ * Two steps, because the two facts live on different rows: `environment` is
14
+ * stamped on the deploy STAGE event, while `commit_sha` rides the source
15
+ * ACTION/PIPELINE event of the same execution. They are joined by `execution_id`,
16
+ * exactly as the DORA lead-time query does it.
17
+ *
18
+ * `environment` is OPTIONAL because of who asks. The events Lambda resolves a
19
+ * commit while handling the SOURCE event, and a source stage carries no
20
+ * environment — the execution has not reached a deploy stage yet, so at that
21
+ * moment the environment is genuinely unknown. Omitting it answers "what did this
22
+ * pipeline last ship anywhere", which is the right lower bound for an SCM range;
23
+ * passing it answers per-environment, for callers that know.
24
+ *
25
+ * TENANCY. `caller` is enforced the same way as {@link ingestEvents}: the org
26
+ * comes from the pipeline REGISTRY, never from the caller, and a pipeline outside
27
+ * the caller's allow-list returns nothing. Without this the endpoint would hand
28
+ * any `reporting:ingest` holder another tenant's commit history — the same hole
29
+ * the ingest tenancy check closes on the write side.
30
+ */
31
+ export declare function getLastDeployedCommit(pipelineId: string, environment?: string, caller?: IngestCaller): Promise<LastDeployedCommit>;