sonamu 0.7.3 → 0.7.5

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 (133) hide show
  1. package/dist/api/config.d.ts +1 -4
  2. package/dist/api/config.d.ts.map +1 -1
  3. package/dist/api/config.js +1 -1
  4. package/dist/api/sonamu.d.ts +2 -0
  5. package/dist/api/sonamu.d.ts.map +1 -1
  6. package/dist/api/sonamu.js +19 -47
  7. package/dist/bin/cli.js +6 -6
  8. package/dist/database/base-model.d.ts +1 -1
  9. package/dist/database/base-model.d.ts.map +1 -1
  10. package/dist/database/base-model.js +15 -4
  11. package/dist/database/code-generator.d.ts.map +1 -1
  12. package/dist/database/code-generator.js +3 -3
  13. package/dist/database/db.d.ts.map +1 -1
  14. package/dist/database/db.js +1 -1
  15. package/dist/database/puri-wrapper.d.ts +11 -11
  16. package/dist/database/puri-wrapper.d.ts.map +1 -1
  17. package/dist/database/puri-wrapper.js +7 -11
  18. package/dist/database/puri.d.ts +36 -17
  19. package/dist/database/puri.d.ts.map +1 -1
  20. package/dist/database/puri.js +54 -7
  21. package/dist/database/puri.types.d.ts +54 -17
  22. package/dist/database/puri.types.d.ts.map +1 -1
  23. package/dist/database/puri.types.js +2 -4
  24. package/dist/database/puri.types.test-d.js +129 -0
  25. package/dist/database/upsert-builder.d.ts +16 -10
  26. package/dist/database/upsert-builder.d.ts.map +1 -1
  27. package/dist/database/upsert-builder.js +10 -19
  28. package/dist/entity/entity-manager.d.ts +113 -22
  29. package/dist/entity/entity-manager.d.ts.map +1 -1
  30. package/dist/entity/entity-manager.js +1 -1
  31. package/dist/entity/entity.d.ts +34 -0
  32. package/dist/entity/entity.d.ts.map +1 -1
  33. package/dist/entity/entity.js +110 -37
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +8 -2
  37. package/dist/migration/code-generation.d.ts.map +1 -1
  38. package/dist/migration/code-generation.js +341 -149
  39. package/dist/migration/migration-set.d.ts.map +1 -1
  40. package/dist/migration/migration-set.js +21 -5
  41. package/dist/migration/migrator.d.ts.map +1 -1
  42. package/dist/migration/migrator.js +7 -1
  43. package/dist/migration/postgresql-schema-reader.d.ts +11 -1
  44. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  45. package/dist/migration/postgresql-schema-reader.js +111 -10
  46. package/dist/syncer/syncer.d.ts.map +1 -1
  47. package/dist/syncer/syncer.js +5 -4
  48. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  49. package/dist/template/implementations/generated.template.js +12 -2
  50. package/dist/template/implementations/generated_sso.template.d.ts +3 -3
  51. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  52. package/dist/template/implementations/generated_sso.template.js +50 -2
  53. package/dist/template/implementations/model.template.js +6 -6
  54. package/dist/template/implementations/model_test.template.js +4 -4
  55. package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
  56. package/dist/template/implementations/view_enums_select.template.js +2 -2
  57. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  58. package/dist/template/implementations/view_form.template.js +12 -9
  59. package/dist/template/implementations/view_id_async_select.template.js +4 -4
  60. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  61. package/dist/template/implementations/view_list.template.js +12 -9
  62. package/dist/template/implementations/view_search_input.template.js +2 -2
  63. package/dist/template/template.js +2 -2
  64. package/dist/template/zod-converter.d.ts.map +1 -1
  65. package/dist/template/zod-converter.js +17 -2
  66. package/dist/testing/fixture-manager.d.ts +2 -1
  67. package/dist/testing/fixture-manager.d.ts.map +1 -1
  68. package/dist/testing/fixture-manager.js +29 -29
  69. package/dist/types/types.d.ts +593 -68
  70. package/dist/types/types.d.ts.map +1 -1
  71. package/dist/types/types.js +113 -9
  72. package/dist/vector/chunking.d.ts +25 -0
  73. package/dist/vector/chunking.d.ts.map +1 -0
  74. package/dist/vector/chunking.js +97 -0
  75. package/dist/vector/config.d.ts +12 -0
  76. package/dist/vector/config.d.ts.map +1 -0
  77. package/dist/vector/config.js +83 -0
  78. package/dist/vector/embedding.d.ts +42 -0
  79. package/dist/vector/embedding.d.ts.map +1 -0
  80. package/dist/vector/embedding.js +147 -0
  81. package/dist/vector/types.d.ts +105 -0
  82. package/dist/vector/types.d.ts.map +1 -0
  83. package/dist/vector/types.js +5 -0
  84. package/dist/vector/vector-search.d.ts +47 -0
  85. package/dist/vector/vector-search.d.ts.map +1 -0
  86. package/dist/vector/vector-search.js +176 -0
  87. package/package.json +11 -11
  88. package/src/api/config.ts +0 -4
  89. package/src/api/sonamu.ts +21 -36
  90. package/src/bin/cli.ts +5 -5
  91. package/src/database/base-model.ts +20 -11
  92. package/src/database/code-generator.ts +6 -2
  93. package/src/database/db.ts +1 -0
  94. package/src/database/puri-wrapper.ts +22 -16
  95. package/src/database/puri.ts +150 -27
  96. package/src/database/puri.types.test-d.ts +457 -0
  97. package/src/database/puri.types.ts +231 -33
  98. package/src/database/upsert-builder.ts +43 -34
  99. package/src/entity/entity-manager.ts +2 -2
  100. package/src/entity/entity.ts +134 -44
  101. package/src/index.ts +6 -0
  102. package/src/migration/code-generation.ts +377 -174
  103. package/src/migration/migration-set.ts +22 -3
  104. package/src/migration/migrator.ts +6 -0
  105. package/src/migration/postgresql-schema-reader.ts +121 -21
  106. package/src/syncer/syncer.ts +4 -3
  107. package/src/template/implementations/generated.template.ts +51 -9
  108. package/src/template/implementations/generated_sso.template.ts +71 -2
  109. package/src/template/implementations/model.template.ts +5 -5
  110. package/src/template/implementations/model_test.template.ts +3 -3
  111. package/src/template/implementations/view_enums_dropdown.template.ts +1 -1
  112. package/src/template/implementations/view_enums_select.template.ts +1 -1
  113. package/src/template/implementations/view_form.template.ts +11 -8
  114. package/src/template/implementations/view_id_async_select.template.ts +3 -3
  115. package/src/template/implementations/view_list.template.ts +11 -8
  116. package/src/template/implementations/view_search_input.template.ts +1 -1
  117. package/src/template/template.ts +1 -1
  118. package/src/template/zod-converter.ts +20 -0
  119. package/src/testing/fixture-manager.ts +31 -30
  120. package/src/types/types.ts +226 -48
  121. package/src/vector/chunking.ts +115 -0
  122. package/src/vector/config.ts +68 -0
  123. package/src/vector/embedding.ts +193 -0
  124. package/src/vector/types.ts +122 -0
  125. package/src/vector/vector-search.ts +261 -0
  126. package/dist/template/implementations/view_enums_buttonset.template.d.ts +0 -17
  127. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +0 -1
  128. package/dist/template/implementations/view_enums_buttonset.template.js +0 -31
  129. package/dist/template/implementations/view_list_columns.template.d.ts +0 -17
  130. package/dist/template/implementations/view_list_columns.template.d.ts.map +0 -1
  131. package/dist/template/implementations/view_list_columns.template.js +0 -49
  132. package/src/template/implementations/view_enums_buttonset.template.ts +0 -34
  133. package/src/template/implementations/view_list_columns.template.ts +0 -53
@@ -1,27 +1,24 @@
1
1
  import equal from "fast-deep-equal";
2
- import { alphabetical, diff, fork, omit } from "radashi";
2
+ import { alphabetical, diff, omit } from "radashi";
3
3
  import { Naite } from "../index.js";
4
4
  import { formatCode } from "../utils/formatter.js";
5
5
  import { differenceWith, intersectionBy } from "../utils/utils.js";
6
6
  /**
7
7
  * 테이블 생성하는 케이스 - 컬럼/인덱스 생성
8
8
  */ async function generateCreateCode_ColumnAndIndexes(table, columns, indexes) {
9
- // fulltext index 분리
10
- const [ngramIndexes, standardIndexes] = fork(indexes, (i)=>i.type === "fulltext" && i.parser === "ngram");
9
+ const columnDefs = genColumnDefinitions(table, columns);
11
10
  // 컬럼, 인덱스 처리
12
11
  const lines = [
13
12
  'import { Knex } from "knex";',
14
13
  "",
15
14
  "export async function up(knex: Knex): Promise<void> {",
16
15
  `await knex.schema.createTable("${table}", (table) => {`,
17
- "// columns",
18
- ...genColumnDefinitions(columns),
19
- "",
20
- "// indexes",
21
- ...standardIndexes.map((index)=>genIndexDefinition(index, table)),
16
+ ...columnDefs.builder,
22
17
  "});",
23
- // ngram은 knex.raw 처리하므로 createTable 밖에서 실행
24
- ...ngramIndexes.map((index)=>genIndexDefinition(index, table)),
18
+ // raw 구문 (Generated Column 등)
19
+ ...columnDefs.raw,
20
+ // index는 knex.raw로 처리하므로 createTable 밖에서 실행
21
+ ...indexes.map((index)=>genIndexDefinition(index, table)),
25
22
  "}",
26
23
  "",
27
24
  "export async function down(knex: Knex): Promise<void> {",
@@ -37,56 +34,113 @@ import { differenceWith, intersectionBy } from "../utils/utils.js";
37
34
  }
38
35
  /**
39
36
  * MigrationColumn[] 읽어서 컬럼 정의하는 구문 생성
40
- */ function genColumnDefinitions(columns) {
41
- return columns.map((column)=>{
42
- const chains = [];
43
- if (column.name === "id") {
44
- return `table.increments().primary();`;
37
+ * @returns builder: table builder 메서드, raw: knex.raw() 구문
38
+ */ function genColumnDefinitions(table, columns) {
39
+ const result = {
40
+ builder: [],
41
+ raw: []
42
+ };
43
+ for (const column of columns){
44
+ // Generated Column은 raw로 처리
45
+ if (column.generated) {
46
+ result.raw.push(genGeneratedColumnDefinition(table, column));
47
+ continue;
45
48
  }
46
- // 배열 타입 처리
47
- if (column.type.endsWith("[]")) {
48
- const elementType = column.type.slice(0, -2); // "integer[]" -> "integer"
49
- const pgType = getPgArrayType(column, elementType);
50
- chains.push(`specificType('${column.name}', '${pgType}')`);
51
- } else if (column.type === "numberOrNumeric") {
52
- // number
53
- if (column.numberType === "real") {
54
- chains.push(`float('${column.name}')`);
55
- } else if (column.numberType === "double precision") {
56
- chains.push(`double('${column.name}')`);
57
- } else if ((column.numberType ?? "numeric") === "numeric") {
58
- chains.push(`decimal('${column.name}', ${column.precision}, ${column.scale})`);
59
- }
60
- } else if (column.type === "string") {
61
- // string
62
- if (column.length !== undefined) {
63
- chains.push(`string('${column.name}', ${column.length})`);
64
- } else {
65
- chains.push(`text('${column.name}')`);
66
- }
67
- } else if (column.type === "date") {
68
- // date
69
- chains.push(`timestamp('${column.name}', { useTz: true })`);
70
- } else if (column.type === "json") {
71
- // json
72
- chains.push(`jsonb('${column.name}')`);
49
+ // 일반 컬럼은 builder로 처리
50
+ result.builder.push(genNormalColumnDefinition(column));
51
+ }
52
+ return result;
53
+ }
54
+ /**
55
+ * Generated Column 정의 생성 (ALTER TABLE ADD COLUMN 사용)
56
+ */ function genGeneratedColumnDefinition(table, column) {
57
+ if (!column.generated) {
58
+ throw new Error("Generated column definition required");
59
+ }
60
+ const pgType = getPgTypeForColumn(column);
61
+ const storageType = column.generated.type === "VIRTUAL" ? " VIRTUAL" : " STORED";
62
+ const nullableClause = column.nullable ? "" : " NOT NULL";
63
+ return `await knex.raw(\`ALTER TABLE "${table}" ADD COLUMN "${column.name}" ${pgType} GENERATED ALWAYS AS (${column.generated.expression})${storageType}${nullableClause}\`);`;
64
+ }
65
+ /**
66
+ * 일반 컬럼 정의 생성 (table.xxx() 체인)
67
+ */ function genNormalColumnDefinition(column) {
68
+ const chains = [];
69
+ if (column.name === "id") {
70
+ return `table.increments().primary();`;
71
+ }
72
+ // 배열 타입 처리
73
+ if (column.type.endsWith("[]")) {
74
+ const elementType = column.type.slice(0, -2); // "integer[]" -> "integer"
75
+ const pgType = getPgArrayType(column, elementType);
76
+ chains.push(`specificType('${column.name}', '${pgType}')`);
77
+ } else if (column.type === "vector") {
78
+ // Knex는 vector 타입을 직접 지원하지 않으므로 specificType 사용
79
+ chains.push(`specificType('${column.name}', 'vector(${column.dimensions})')`);
80
+ } else if (column.type === "numberOrNumeric") {
81
+ // number
82
+ if (column.numberType === "real") {
83
+ chains.push(`float('${column.name}')`);
84
+ } else if (column.numberType === "double precision") {
85
+ chains.push(`double('${column.name}')`);
86
+ } else if ((column.numberType ?? "numeric") === "numeric") {
87
+ chains.push(`decimal('${column.name}', ${column.precision}, ${column.scale})`);
88
+ }
89
+ } else if (column.type === "string") {
90
+ // string
91
+ if (column.length !== undefined) {
92
+ chains.push(`string('${column.name}', ${column.length})`);
73
93
  } else {
74
- // type, length
75
- let extraType;
76
- chains.push(`${column.type}('${column.name}'${column.length ? `, ${column.length}` : ""}${extraType ? `, '${extraType}'` : ""})`);
94
+ chains.push(`text('${column.name}')`);
77
95
  }
78
- // nullable
79
- chains.push(column.nullable ? "nullable()" : "notNullable()");
80
- // defaultTo
81
- if (column.defaultTo !== undefined) {
82
- if (typeof column.defaultTo === "string" && column.defaultTo.startsWith(`"`)) {
83
- chains.push(`defaultTo(${column.defaultTo})`);
84
- } else {
85
- chains.push(`defaultTo(knex.raw('${column.defaultTo}'))`);
86
- }
96
+ } else if (column.type === "date") {
97
+ // date
98
+ chains.push(`timestamp('${column.name}', { useTz: true })`);
99
+ } else if (column.type === "json") {
100
+ // json
101
+ chains.push(`jsonb('${column.name}')`);
102
+ } else {
103
+ // type, length
104
+ let extraType;
105
+ chains.push(`${column.type}('${column.name}'${column.length ? `, ${column.length}` : ""}${extraType ? `, '${extraType}'` : ""})`);
106
+ }
107
+ // nullable
108
+ chains.push(column.nullable ? "nullable()" : "notNullable()");
109
+ // defaultTo
110
+ if (column.defaultTo !== undefined) {
111
+ if (typeof column.defaultTo === "string" && column.defaultTo.startsWith(`"`)) {
112
+ chains.push(`defaultTo(${column.defaultTo})`);
113
+ } else {
114
+ chains.push(`defaultTo(knex.raw('${column.defaultTo}'))`);
87
115
  }
88
- return `table.${chains.join(".")};`;
89
- });
116
+ }
117
+ return `table.${chains.join(".")};`;
118
+ }
119
+ /**
120
+ * MigrationColumn의 타입을 PostgreSQL 타입 문자열로 변환
121
+ */ function getPgTypeForColumn(column) {
122
+ if (column.type.endsWith("[]")) {
123
+ const elementType = column.type.slice(0, -2);
124
+ return getPgArrayType(column, elementType);
125
+ }
126
+ switch(column.type){
127
+ case "string":
128
+ return column.length !== undefined ? `varchar(${column.length})` : "text";
129
+ case "bigInteger":
130
+ return "bigint";
131
+ case "numberOrNumeric":
132
+ if (column.numberType === "real") return "real";
133
+ if (column.numberType === "double precision") return "double precision";
134
+ return `numeric(${column.precision}, ${column.scale})`;
135
+ case "date":
136
+ return "timestamptz";
137
+ case "json":
138
+ return "jsonb";
139
+ case "vector":
140
+ return `vector(${column.dimensions})`;
141
+ default:
142
+ return column.type;
143
+ }
90
144
  }
91
145
  function getPgArrayType(column, elementType) {
92
146
  if (elementType === "numberOrNumeric") {
@@ -103,22 +157,56 @@ function getPgArrayType(column, elementType) {
103
157
  if (elementType === "boolean") return "boolean[]";
104
158
  if (elementType === "uuid") return "uuid[]";
105
159
  if (elementType === "enum") return "text[]";
160
+ if (elementType === "vector") return `vector(${column.dimensions})[]`;
106
161
  throw new Error(`Unknown array element type: ${elementType}`);
107
162
  }
108
163
  /**
109
164
  * 개별 인덱스 정의 생성
110
165
  */ function genIndexDefinition(index, table) {
166
+ if (index.type === "hnsw" || index.type === "ivfflat") {
167
+ return genVectorIndexDefinition(index, table);
168
+ }
111
169
  const methodMap = {
112
- index: "index",
113
- fulltext: "index",
114
- unique: "unique"
170
+ index: "INDEX",
171
+ fulltext: "INDEX",
172
+ unique: "UNIQUE INDEX"
115
173
  };
116
- if (index.type === "fulltext" && index.parser === "ngram") {
117
- return `await knex.raw(\`ALTER TABLE ${table} ADD FULLTEXT INDEX ${index.name} (${index.columns.join(", ")}) WITH PARSER ngram\`);`;
118
- }
119
- return `table.${methodMap[index.type]}([${index.columns.map((col)=>`'${col}'`).join(",")}], '${index.name}'${index.type === "fulltext" ? ", 'FULLTEXT'" : ""}
174
+ const nullsNotDistinctClause = index.nullsNotDistinct === undefined ? "" : ` NULLS ${index.nullsNotDistinct ? "NOT DISTINCT" : "DISTINCT"}`;
175
+ return `await knex.raw(
176
+ \`CREATE ${methodMap[index.type]} ${index.name} ON ${table} (${index.columns.map((col)=>{
177
+ const sortOrderClause = col.sortOrder === undefined ? "" : ` ${col.sortOrder}`;
178
+ const nullsFirstClause = col.nullsFirst === undefined ? "" : ` NULLS ${col.nullsFirst ? "FIRST" : "LAST"}`;
179
+ return `${col.name}${sortOrderClause}${nullsFirstClause}`;
180
+ }).join(", ")})${nullsNotDistinctClause};\`
120
181
  );`;
121
182
  }
183
+ /**
184
+ * @description
185
+ * - HNSW (Hierarchical Navigable Small World): 느린 빌드, 빠른 검색 속도, 높은 메모리 및 정확도
186
+ * - IVFFlat (Inverted File with Flat Compression): 빠른 빌드, 중간 검색 속도, 낮은 메모리
187
+ *
188
+ * @example
189
+ * // HNSW 인덱스 (권장 - 빠른 검색, 높은 정확도)
190
+ * CREATE INDEX idx_embedding ON items USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
191
+ *
192
+ * // IVFFlat 인덱스 (대용량 데이터, 비용 중요 시)
193
+ * CREATE INDEX idx_embedding ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
194
+ */ function genVectorIndexDefinition(index, table) {
195
+ const column = index.columns[0];
196
+ const vectorOps = column.vectorOps ?? "vector_cosine_ops";
197
+ // HNSW (Hierarchical Navigable Small World) - 권장: 빠른 검색, 높은 정확도
198
+ if (index.type === "hnsw") {
199
+ const m = index.m ?? 16;
200
+ const efConstruction = index.efConstruction ?? 64;
201
+ return `await knex.raw(\`CREATE INDEX ${index.name} ON ${table} USING hnsw (${column.name} ${vectorOps}) WITH (m = ${m}, ef_construction = ${efConstruction})\`);`;
202
+ }
203
+ // IVFFlat (Inverted File with Flat Compression) - 대용량, 비용 중요 시
204
+ if (index.type === "ivfflat") {
205
+ const lists = index.lists ?? 100;
206
+ return `await knex.raw(\`CREATE INDEX ${index.name} ON ${table} USING ivfflat (${column.name} ${vectorOps}) WITH (lists = ${lists})\`);`;
207
+ }
208
+ throw new Error(`Unknown raw SQL index type: ${index.type}`);
209
+ }
122
210
  /**
123
211
  * 테이블 생성하는 케이스 - FK 생성
124
212
  */ async function generateCreateCode_Foreign(table, foreigns) {
@@ -192,12 +280,11 @@ function getPgArrayType(column, elementType) {
192
280
  const alterColumnLinesTo = getAlterColumnLinesTo(alterColumnsTo, entityColumns, table, dbForeigns);
193
281
  // 인덱스의 add, drop 여부 확인
194
282
  const alterIndexesTo = getAlterIndexesTo(entityIndexes, dbIndexes);
195
- // fulltext index 분리
196
- const [ngramIndexes, standardIndexes] = fork(alterIndexesTo.add, (i)=>i.type === "fulltext" && i.parser === "ngram");
197
283
  // 인덱스가 삭제되는 경우, 컬럼과 같이 삭제된 케이스에는 drop에서 제외해야함!
198
- const indexNeedsToDrop = alterIndexesTo.drop.filter((index)=>index.columns.every((colName)=>alterColumnsTo.drop.map((col)=>col.name).includes(colName)) === false);
284
+ const indexNeedsToDrop = alterIndexesTo.drop.filter((index)=>index.columns.every(({ name })=>alterColumnsTo.drop.map((col)=>col.name).includes(name)) === false);
199
285
  // 빈 코드 생성 방지
200
- if (alterColumnLinesTo.add.up.length === 0 && alterColumnLinesTo.drop.up.length === 0 && alterColumnLinesTo.alter.up.length === 0 && standardIndexes.length === 0 && indexNeedsToDrop.length === 0) {
286
+ const hasUpChanges = alterColumnLinesTo.add.up.builder.length > 0 || alterColumnLinesTo.add.up.raw.length > 0 || alterColumnLinesTo.drop.up.builder.length > 0 || alterColumnLinesTo.alter.up.builder.length > 0 || alterIndexesTo.add.length > 0 || indexNeedsToDrop.length > 0;
287
+ if (!hasUpChanges) {
201
288
  Naite.t("migrator:generateAlterCode_ColumnAndIndexes:emptyCodeGenerationError", {
202
289
  entityColumns,
203
290
  dbColumns,
@@ -212,39 +299,52 @@ function getPgArrayType(column, elementType) {
212
299
  "alterColumnsTo.alter.length": alterColumnsTo.alter.length,
213
300
  "alterIndexesTo.add.length": alterIndexesTo.add.length,
214
301
  "alterIndexesTo.drop.length": alterIndexesTo.drop.length,
215
- "standardIndexes.length": standardIndexes.length,
216
302
  "indexNeedsToDrop.length": indexNeedsToDrop.length
217
303
  });
218
304
  // Naite.t("migrator:generateAlterCode_ColumnAndIndexes:alterColumnsTo", alterColumnsTo);
219
305
  // TODO: 인덱스명 변경된 경우 처리
306
+ // table builder 메서드로 실행할 코드 (drop → add → alter 순서)
307
+ const upBuilderLines = [
308
+ ...alterColumnLinesTo.drop.up.builder.length > 0 ? alterColumnLinesTo.drop.up.builder : [],
309
+ ...alterColumnLinesTo.add.up.builder.length > 0 ? alterColumnLinesTo.add.up.builder : [],
310
+ ...alterColumnLinesTo.alter.up.builder.length > 0 ? alterColumnLinesTo.alter.up.builder : [],
311
+ ...indexNeedsToDrop.map(genIndexDropDefinition)
312
+ ];
313
+ // knex.raw()로 실행할 코드
314
+ const upRawLines = [
315
+ ...alterColumnLinesTo.add.up.raw.length > 0 ? alterColumnLinesTo.add.up.raw : [],
316
+ ...alterIndexesTo.add.map((index)=>genIndexDefinition(index, table))
317
+ ];
318
+ // down은 up의 역순 (add.down = drop rollback, drop.down = add rollback)
319
+ const downBuilderLines = [
320
+ ...alterColumnLinesTo.add.down.builder.length > 0 ? alterColumnLinesTo.add.down.builder : [],
321
+ ...alterColumnLinesTo.alter.down.builder.length > 0 ? alterColumnLinesTo.alter.down.builder : [],
322
+ ...alterColumnLinesTo.drop.down.builder.length > 0 ? alterColumnLinesTo.drop.down.builder : [],
323
+ ...alterIndexesTo.add.filter((index)=>index.columns.every((indexCol)=>alterColumnsTo.add.map((col)=>col.name).includes(indexCol.name)) === false).map(genIndexDropDefinition)
324
+ ];
325
+ const downRawLines = [
326
+ ...alterColumnLinesTo.drop.down.raw.length > 0 ? alterColumnLinesTo.drop.down.raw : [],
327
+ ...indexNeedsToDrop.map((index)=>genIndexDefinition(index, table))
328
+ ];
220
329
  const lines = [
221
330
  'import { Knex } from "knex";',
222
331
  "",
223
332
  "export async function up(knex: Knex): Promise<void> {",
224
- `await knex.schema.alterTable("${table}", (table) => {`,
225
- // 1. add column
226
- ...alterColumnsTo.add.length > 0 ? alterColumnLinesTo.add.up : [],
227
- // 2. drop column
228
- ...alterColumnsTo.drop.length > 0 ? alterColumnLinesTo.drop.up : [],
229
- // 3. alter column
230
- ...alterColumnsTo.alter.length > 0 ? alterColumnLinesTo.alter.up : [],
231
- // 4. add index
232
- ...standardIndexes.map((index)=>genIndexDefinition(index, table)),
233
- // 5. drop index
234
- ...indexNeedsToDrop.map(genIndexDropDefinition),
235
- "});",
236
- // ngram은 knex.raw로 처리하므로 alterTable 밖에서 실행
237
- ...ngramIndexes.map((index)=>genIndexDefinition(index, table)),
333
+ ...upBuilderLines.length > 0 ? [
334
+ `await knex.schema.alterTable("${table}", (table) => {`,
335
+ ...upBuilderLines,
336
+ "});"
337
+ ] : [],
338
+ ...upRawLines,
238
339
  "}",
239
340
  "",
240
341
  "export async function down(knex: Knex): Promise<void> {",
241
- `return knex.schema.alterTable("${table}", (table) => {`,
242
- ...alterColumnsTo.add.length > 0 ? alterColumnLinesTo.add.down : [],
243
- ...alterColumnsTo.drop.length > 0 ? alterColumnLinesTo.drop.down : [],
244
- ...alterColumnsTo.alter.length > 0 ? alterColumnLinesTo.alter.down : [],
245
- ...alterIndexesTo.add.filter((index)=>index.columns.every((colName)=>alterColumnsTo.add.map((col)=>col.name).includes(colName)) === false).map(genIndexDropDefinition),
246
- ...indexNeedsToDrop.map((index)=>genIndexDefinition(index, table)),
247
- "});",
342
+ ...downBuilderLines.length > 0 ? [
343
+ `await knex.schema.alterTable("${table}", (table) => {`,
344
+ ...downBuilderLines,
345
+ "});"
346
+ ] : [],
347
+ ...downRawLines,
248
348
  "}"
249
349
  ];
250
350
  const formatted = formatCode(lines.join("\n"), "typescript", `src/migration/${table}.ts`);
@@ -272,6 +372,20 @@ function getPgArrayType(column, elementType) {
272
372
  }
273
373
  ];
274
374
  }
375
+ /**
376
+ * 컬럼 비교를 위해 Generated Column의 expression을 제외한 객체를 생성
377
+ */ function normalizeColumnForComparison(col) {
378
+ if (col.generated) {
379
+ return {
380
+ ...col,
381
+ generated: {
382
+ type: col.generated.type,
383
+ expression: ""
384
+ }
385
+ };
386
+ }
387
+ return col;
388
+ }
275
389
  /**
276
390
  * 각 컬럼 이름 기준으로 add, drop, alter 여부 확인
277
391
  */ function getAlterColumnsTo(entityColumns, dbColumns) {
@@ -282,8 +396,14 @@ function getPgArrayType(column, elementType) {
282
396
  };
283
397
  // 컬럼명 기준 비교
284
398
  const extraColumns = {
285
- db: diff(dbColumns, entityColumns, (col)=>col.name),
286
- entity: diff(entityColumns, dbColumns, (col)=>col.name)
399
+ db: diff(dbColumns, entityColumns, (col)=>[
400
+ col.name,
401
+ col.generated?.type
402
+ ].join("///")),
403
+ entity: diff(entityColumns, dbColumns, (col)=>[
404
+ col.name,
405
+ col.generated?.type
406
+ ].join("///"))
287
407
  };
288
408
  if (extraColumns.entity.length > 0) {
289
409
  columnsTo.add = columnsTo.add.concat(extraColumns.entity);
@@ -291,10 +411,16 @@ function getPgArrayType(column, elementType) {
291
411
  if (extraColumns.db.length > 0) {
292
412
  columnsTo.drop = columnsTo.drop.concat(extraColumns.db);
293
413
  }
294
- // 동일 컬럼명의 세부 필드 비교
414
+ // 동일 컬럼명의 세부 필드 비교 (Generated Column expression 제외)
295
415
  const sameDbColumns = intersectionBy(dbColumns, entityColumns, (col)=>col.name);
296
416
  const sameMdColumns = intersectionBy(entityColumns, dbColumns, (col)=>col.name);
297
- columnsTo.alter = differenceWith(sameDbColumns, sameMdColumns, (a, b)=>equal(a, b));
417
+ columnsTo.alter = differenceWith(sameDbColumns, sameMdColumns, (a, b)=>equal({
418
+ ...a,
419
+ generated: undefined
420
+ }, {
421
+ ...b,
422
+ generated: undefined
423
+ }));
298
424
  return columnsTo;
299
425
  }
300
426
  /**
@@ -302,27 +428,54 @@ function getPgArrayType(column, elementType) {
302
428
  */ function getAlterColumnLinesTo(columnsTo, entityColumns, table, dbForeigns) {
303
429
  const linesTo = {
304
430
  add: {
305
- up: [],
306
- down: []
431
+ up: {
432
+ builder: [],
433
+ raw: []
434
+ },
435
+ down: {
436
+ builder: [],
437
+ raw: []
438
+ }
307
439
  },
308
440
  drop: {
309
- up: [],
310
- down: []
441
+ up: {
442
+ builder: [],
443
+ raw: []
444
+ },
445
+ down: {
446
+ builder: [],
447
+ raw: []
448
+ }
311
449
  },
312
450
  alter: {
313
- up: [],
314
- down: []
451
+ up: {
452
+ builder: [],
453
+ raw: []
454
+ },
455
+ down: {
456
+ builder: [],
457
+ raw: []
458
+ }
315
459
  }
316
460
  };
317
- linesTo.add = {
318
- up: [
461
+ // add columns
462
+ const addColumnDefs = genColumnDefinitions(table, columnsTo.add);
463
+ linesTo.add.up = {
464
+ builder: addColumnDefs.builder.length > 0 ? [
319
465
  "// add",
320
- ...genColumnDefinitions(columnsTo.add)
321
- ],
322
- down: [
466
+ ...addColumnDefs.builder
467
+ ] : [],
468
+ raw: addColumnDefs.raw.length > 0 ? [
469
+ "// add (generated)",
470
+ ...addColumnDefs.raw
471
+ ] : []
472
+ };
473
+ linesTo.add.down = {
474
+ builder: columnsTo.add.length > 0 ? [
323
475
  "// rollback - add",
324
476
  `table.dropColumns(${columnsTo.add.map((col)=>`'${col.name}'`).join(", ")})`
325
- ]
477
+ ] : [],
478
+ raw: []
326
479
  };
327
480
  // drop할 컬럼에 걸린 FK 찾기
328
481
  const dropColumnNames = columnsTo.drop.map((col)=>col.name);
@@ -332,56 +485,78 @@ function getPgArrayType(column, elementType) {
332
485
  return `table.dropForeign([${columnsStringQuote}])`;
333
486
  });
334
487
  const restoreFkLines = genForeignDefinitions(table, fkToDropBeforeColumn).up;
488
+ // drop의 rollback시에는 generated column도 복원해야 함
489
+ const dropColumnDefs = genColumnDefinitions(table, columnsTo.drop);
335
490
  linesTo.drop = {
336
- up: [
337
- ...dropFkLines.length > 0 ? [
338
- "// drop foreign keys on columns to be dropped",
339
- ...dropFkLines
340
- ] : [],
341
- "// drop columns",
342
- `table.dropColumns(${columnsTo.drop.map((col)=>`'${col.name}'`).join(", ")})`
343
- ],
344
- down: [
345
- "// rollback - drop columns",
346
- ...genColumnDefinitions(columnsTo.drop),
347
- ...restoreFkLines.length > 0 ? [
348
- "// restore foreign keys",
349
- ...restoreFkLines
491
+ up: {
492
+ builder: [
493
+ ...dropFkLines.length > 0 ? [
494
+ "// drop foreign keys on columns to be dropped",
495
+ ...dropFkLines
496
+ ] : [],
497
+ ...columnsTo.drop.length > 0 ? [
498
+ "// drop columns",
499
+ `table.dropColumns(${columnsTo.drop.map((col)=>`'${col.name}'`).join(", ")})`
500
+ ] : []
501
+ ],
502
+ raw: []
503
+ },
504
+ down: {
505
+ builder: [
506
+ ...dropColumnDefs.builder.length > 0 ? [
507
+ "// rollback - drop columns",
508
+ ...dropColumnDefs.builder
509
+ ] : [],
510
+ ...restoreFkLines.length > 0 ? [
511
+ "// restore foreign keys",
512
+ ...restoreFkLines
513
+ ] : []
514
+ ],
515
+ raw: dropColumnDefs.raw.length > 0 ? [
516
+ "// rollback - drop columns (generated)",
517
+ ...dropColumnDefs.raw
350
518
  ] : []
351
- ]
519
+ }
352
520
  };
521
+ // alter columns (Generated Column은 ALTER 불가하므로 drop 후 재생성)
353
522
  linesTo.alter = columnsTo.alter.reduce((r, dbColumn)=>{
354
523
  const entityColumn = entityColumns.find((col)=>col.name === dbColumn.name);
355
524
  if (entityColumn === undefined) {
356
525
  return r;
357
526
  }
358
527
  // 컬럼 변경사항
359
- const columnDiffUp = diff(genColumnDefinitions([
528
+ const columnDiffUp = diff(genColumnDefinitions(table, [
360
529
  entityColumn
361
- ]), genColumnDefinitions([
530
+ ]).builder, genColumnDefinitions(table, [
362
531
  dbColumn
363
- ]));
364
- const columnDiffDown = diff(genColumnDefinitions([
532
+ ]).builder);
533
+ const columnDiffDown = diff(genColumnDefinitions(table, [
365
534
  dbColumn
366
- ]), genColumnDefinitions([
535
+ ]).builder, genColumnDefinitions(table, [
367
536
  entityColumn
368
- ]));
537
+ ]).builder);
369
538
  if (columnDiffUp.length > 0) {
370
- r.up = [
371
- ...r.up,
539
+ r.up.builder = [
540
+ ...r.up.builder,
372
541
  "// alter column",
373
542
  ...columnDiffUp.map((l)=>`${l.replace(";", "")}.alter();`)
374
543
  ];
375
- r.down = [
376
- ...r.down,
544
+ r.down.builder = [
545
+ ...r.down.builder,
377
546
  "// rollback - alter column",
378
547
  ...columnDiffDown.map((l)=>`${l.replace(";", "")}.alter();`)
379
548
  ];
380
549
  }
381
550
  return r;
382
551
  }, {
383
- up: [],
384
- down: []
552
+ up: {
553
+ builder: [],
554
+ raw: []
555
+ },
556
+ down: {
557
+ builder: [],
558
+ raw: []
559
+ }
385
560
  });
386
561
  return linesTo;
387
562
  }
@@ -393,15 +568,22 @@ function getPgArrayType(column, elementType) {
393
568
  add: [],
394
569
  drop: []
395
570
  };
571
+ // 인덱스 고유 식별자 생성 (name을 제외한 모든 필드를 문자열로 변환하여 조합)
572
+ const identity = (index)=>{
573
+ const keys = Object.keys(index).filter((key)=>key !== "name").sort();
574
+ return keys.map((key)=>{
575
+ if (key === "name") {
576
+ return undefined;
577
+ }
578
+ if (key === "columns") {
579
+ return index[key].flatMap(identity);
580
+ }
581
+ return `${key}=${index[key]}`;
582
+ }).join("//");
583
+ };
396
584
  const extraIndexes = {
397
- db: diff(dbIndexes, entityIndexes, (col)=>[
398
- col.type,
399
- col.columns.join("-")
400
- ].join("//")),
401
- entity: diff(entityIndexes, dbIndexes, (col)=>[
402
- col.type,
403
- col.columns.join("-")
404
- ].join("//"))
585
+ db: diff(dbIndexes, entityIndexes.map(setMigrationIndexDefaults), identity),
586
+ entity: diff(entityIndexes.map(setMigrationIndexDefaults), dbIndexes, identity)
405
587
  };
406
588
  if (extraIndexes.entity.length > 0) {
407
589
  indexesTo.add = indexesTo.add.concat(extraIndexes.entity);
@@ -414,12 +596,21 @@ function getPgArrayType(column, elementType) {
414
596
  /**
415
597
  * 인덱스 삭제 정의 생성
416
598
  */ function genIndexDropDefinition(index) {
417
- const methodMap = {
418
- index: "Index",
419
- fulltext: "Index",
420
- unique: "Unique"
599
+ return `table.dropIndex([${index.columns.map((column)=>`'${column.name}'`).join(",")}], '${index.name}')`;
600
+ }
601
+ /**
602
+ * DB 조회 결과와 비교하기 위한 인덱스 기본값 설정
603
+ */ function setMigrationIndexDefaults(index) {
604
+ return {
605
+ ...index,
606
+ columns: index.columns.map((col)=>({
607
+ ...col,
608
+ sortOrder: col.sortOrder ?? "ASC",
609
+ // sortOrder에 따라 nullsFirst의 default 값 설정
610
+ nullsFirst: col.nullsFirst ?? col.sortOrder === "DESC"
611
+ })),
612
+ nullsNotDistinct: index.nullsNotDistinct ?? false
421
613
  };
422
- return `table.drop${methodMap[index.type]}([${index.columns.map((columnName)=>`'${columnName}'`).join(",")}], '${index.name}')`;
423
614
  }
424
615
  /**
425
616
  * 테이블 변경 케이스 - Foreign Key 변경
@@ -566,7 +757,8 @@ function getPgArrayType(column, elementType) {
566
757
  (col) => col.name === "price_krw"
567
758
  );
568
759
  console.debug({ entityColumn, dbColumn });
569
- */ const entityIndexes = alphabetical(entitySet.indexes, (a)=>[
760
+ */ // ?
761
+ const entityIndexes = alphabetical(entitySet.indexes, (a)=>[
570
762
  a.type,
571
763
  ...a.columns
572
764
  ].join("-"));
@@ -595,10 +787,10 @@ function getPgArrayType(column, elementType) {
595
787
  const droppingColumns = diff(dbColumns, entityColumns, (col)=>col.name);
596
788
  const alterCodes = [];
597
789
  // 1. columnsAndIndexes 처리
598
- const isEqualColumns = equal(entityColumns, dbColumns);
790
+ const isEqualColumns = equal(entityColumns.map(normalizeColumnForComparison), dbColumns.map(normalizeColumnForComparison));
599
791
  const isEqualIndexes = equal(entityIndexes.map((index)=>omit(index, [
600
792
  "parser"
601
- ])), dbIndexes);
793
+ ])).map(setMigrationIndexDefaults), dbIndexes);
602
794
  if (!isEqualColumns || !isEqualIndexes) {
603
795
  alterCodes.push(await generateAlterCode_ColumnAndIndexes(entitySet.table, entityColumns, entityIndexes, dbColumns, dbIndexes, dbSet.foreigns));
604
796
  }
@@ -612,4 +804,4 @@ function getPgArrayType(column, elementType) {
612
804
  return alterCodes.filter((alterCode)=>alterCode !== null).flat();
613
805
  }
614
806
 
615
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb24vY29kZS1nZW5lcmF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBlcXVhbCBmcm9tIFwiZmFzdC1kZWVwLWVxdWFsXCI7XG5pbXBvcnQgeyBhbHBoYWJldGljYWwsIGRpZmYsIGZvcmssIG9taXQgfSBmcm9tIFwicmFkYXNoaVwiO1xuaW1wb3J0IHsgTmFpdGUgfSBmcm9tIFwiLi5cIjtcbmltcG9ydCB0eXBlIHtcbiAgR2VuTWlncmF0aW9uQ29kZSxcbiAgTWlncmF0aW9uQ29sdW1uLFxuICBNaWdyYXRpb25Gb3JlaWduLFxuICBNaWdyYXRpb25JbmRleCxcbiAgTWlncmF0aW9uU2V0LFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBkaWZmZXJlbmNlV2l0aCwgaW50ZXJzZWN0aW9uQnkgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcblxuLyoqXG4gKiDthYzsnbTruJQg7IOd7ISx7ZWY64qUIOy8gOydtOyKpCAtIOy7rOufvC/snbjrjbHsiqQg7IOd7ISxXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ3JlYXRlQ29kZV9Db2x1bW5BbmRJbmRleGVzKFxuICB0YWJsZTogc3RyaW5nLFxuICBjb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgaW5kZXhlczogTWlncmF0aW9uSW5kZXhbXSxcbik6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZT4ge1xuICAvLyBmdWxsdGV4dCBpbmRleCDrtoTrpqxcbiAgY29uc3QgW25ncmFtSW5kZXhlcywgc3RhbmRhcmRJbmRleGVzXSA9IGZvcmsoXG4gICAgaW5kZXhlcyxcbiAgICAoaSkgPT4gaS50eXBlID09PSBcImZ1bGx0ZXh0XCIgJiYgaS5wYXJzZXIgPT09IFwibmdyYW1cIixcbiAgKTtcblxuICAvLyDsu6zrn7wsIOyduOuNseyKpCDsspjrpqxcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW1xuICAgICdpbXBvcnQgeyBLbmV4IH0gZnJvbSBcImtuZXhcIjsnLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gdXAoa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGBhd2FpdCBrbmV4LnNjaGVtYS5jcmVhdGVUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgXCIvLyBjb2x1bW5zXCIsXG4gICAgLi4uZ2VuQ29sdW1uRGVmaW5pdGlvbnMoY29sdW1ucyksXG4gICAgXCJcIixcbiAgICBcIi8vIGluZGV4ZXNcIixcbiAgICAuLi5zdGFuZGFyZEluZGV4ZXMubWFwKChpbmRleCkgPT4gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4LCB0YWJsZSkpLFxuICAgIFwifSk7XCIsXG4gICAgLy8gbmdyYW3snYAga25leC5yYXfroZwg7LKY66as7ZWY66+A66GcIGNyZWF0ZVRhYmxlIOuwluyXkOyEnCDsi6TtlolcbiAgICAuLi5uZ3JhbUluZGV4ZXMubWFwKChpbmRleCkgPT4gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4LCB0YWJsZSkpLFxuICAgIFwifVwiLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gZG93bihrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYCByZXR1cm4ga25leC5zY2hlbWEuZHJvcFRhYmxlKFwiJHt0YWJsZX1cIik7YCxcbiAgICBcIn1cIixcbiAgXTtcbiAgcmV0dXJuIHtcbiAgICB0YWJsZSxcbiAgICB0eXBlOiBcIm5vcm1hbFwiLFxuICAgIHRpdGxlOiBgY3JlYXRlX18ke3RhYmxlfWAsXG4gICAgZm9ybWF0dGVkOiBmb3JtYXRDb2RlKGxpbmVzLmpvaW4oXCJcXG5cIiksIFwidHlwZXNjcmlwdFwiLCBgc3JjL21pZ3JhdGlvbi8ke3RhYmxlfS50c2ApLFxuICB9O1xufVxuXG4vKipcbiAqIE1pZ3JhdGlvbkNvbHVtbltdIOydveyWtOyEnCDsu6zrn7wg7KCV7J2Y7ZWY64qUIOq1rOusuCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuQ29sdW1uRGVmaW5pdGlvbnMoY29sdW1uczogTWlncmF0aW9uQ29sdW1uW10pOiBzdHJpbmdbXSB7XG4gIHJldHVybiBjb2x1bW5zLm1hcCgoY29sdW1uKSA9PiB7XG4gICAgY29uc3QgY2hhaW5zOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChjb2x1bW4ubmFtZSA9PT0gXCJpZFwiKSB7XG4gICAgICByZXR1cm4gYHRhYmxlLmluY3JlbWVudHMoKS5wcmltYXJ5KCk7YDtcbiAgICB9XG5cbiAgICAvLyDrsLDsl7Qg7YOA7J6FIOyymOumrFxuICAgIGlmIChjb2x1bW4udHlwZS5lbmRzV2l0aChcIltdXCIpKSB7XG4gICAgICBjb25zdCBlbGVtZW50VHlwZSA9IGNvbHVtbi50eXBlLnNsaWNlKDAsIC0yKTsgLy8gXCJpbnRlZ2VyW11cIiAtPiBcImludGVnZXJcIlxuICAgICAgY29uc3QgcGdUeXBlID0gZ2V0UGdBcnJheVR5cGUoY29sdW1uLCBlbGVtZW50VHlwZSk7XG4gICAgICBjaGFpbnMucHVzaChgc3BlY2lmaWNUeXBlKCcke2NvbHVtbi5uYW1lfScsICcke3BnVHlwZX0nKWApO1xuICAgIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwibnVtYmVyT3JOdW1lcmljXCIpIHtcbiAgICAgIC8vIG51bWJlclxuICAgICAgaWYgKGNvbHVtbi5udW1iZXJUeXBlID09PSBcInJlYWxcIikge1xuICAgICAgICBjaGFpbnMucHVzaChgZmxvYXQoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgICAgIH0gZWxzZSBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSB7XG4gICAgICAgIGNoYWlucy5wdXNoKGBkb3VibGUoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgICAgIH0gZWxzZSBpZiAoKGNvbHVtbi5udW1iZXJUeXBlID8/IFwibnVtZXJpY1wiKSA9PT0gXCJudW1lcmljXCIpIHtcbiAgICAgICAgY2hhaW5zLnB1c2goYGRlY2ltYWwoJyR7Y29sdW1uLm5hbWV9JywgJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KWApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIC8vIHN0cmluZ1xuICAgICAgaWYgKGNvbHVtbi5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjaGFpbnMucHVzaChgc3RyaW5nKCcke2NvbHVtbi5uYW1lfScsICR7Y29sdW1uLmxlbmd0aH0pYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGFpbnMucHVzaChgdGV4dCgnJHtjb2x1bW4ubmFtZX0nKWApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwiZGF0ZVwiKSB7XG4gICAgICAvLyBkYXRlXG4gICAgICBjaGFpbnMucHVzaChgdGltZXN0YW1wKCcke2NvbHVtbi5uYW1lfScsIHsgdXNlVHo6IHRydWUgfSlgKTtcbiAgICB9IGVsc2UgaWYgKGNvbHVtbi50eXBlID09PSBcImpzb25cIikge1xuICAgICAgLy8ganNvblxuICAgICAgY2hhaW5zLnB1c2goYGpzb25iKCcke2NvbHVtbi5uYW1lfScpYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHR5cGUsIGxlbmd0aFxuICAgICAgbGV0IGV4dHJhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgY2hhaW5zLnB1c2goXG4gICAgICAgIGAke2NvbHVtbi50eXBlfSgnJHtjb2x1bW4ubmFtZX0nJHtcbiAgICAgICAgICBjb2x1bW4ubGVuZ3RoID8gYCwgJHtjb2x1bW4ubGVuZ3RofWAgOiBcIlwiXG4gICAgICAgIH0ke2V4dHJhVHlwZSA/IGAsICcke2V4dHJhVHlwZX0nYCA6IFwiXCJ9KWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIG51bGxhYmxlXG4gICAgY2hhaW5zLnB1c2goY29sdW1uLm51bGxhYmxlID8gXCJudWxsYWJsZSgpXCIgOiBcIm5vdE51bGxhYmxlKClcIik7XG5cbiAgICAvLyBkZWZhdWx0VG9cbiAgICBpZiAoY29sdW1uLmRlZmF1bHRUbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGNvbHVtbi5kZWZhdWx0VG8gPT09IFwic3RyaW5nXCIgJiYgY29sdW1uLmRlZmF1bHRUby5zdGFydHNXaXRoKGBcImApKSB7XG4gICAgICAgIGNoYWlucy5wdXNoKGBkZWZhdWx0VG8oJHtjb2x1bW4uZGVmYXVsdFRvfSlgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYWlucy5wdXNoKGBkZWZhdWx0VG8oa25leC5yYXcoJyR7Y29sdW1uLmRlZmF1bHRUb30nKSlgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYHRhYmxlLiR7Y2hhaW5zLmpvaW4oXCIuXCIpfTtgO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0UGdBcnJheVR5cGUoY29sdW1uOiBNaWdyYXRpb25Db2x1bW4sIGVsZW1lbnRUeXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwibnVtYmVyT3JOdW1lcmljXCIpIHtcbiAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwicmVhbFwiKSByZXR1cm4gXCJyZWFsW11cIjtcbiAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSByZXR1cm4gXCJkb3VibGUgcHJlY2lzaW9uW11cIjtcbiAgICByZXR1cm4gYG51bWVyaWMoJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KVtdYDtcbiAgfVxuICBpZiAoZWxlbWVudFR5cGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gY29sdW1uLmxlbmd0aCA/IGB2YXJjaGFyKCR7Y29sdW1uLmxlbmd0aH0pW11gIDogXCJ0ZXh0W11cIjtcbiAgfVxuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiZGF0ZVwiKSByZXR1cm4gXCJ0aW1lc3RhbXB0eltdXCI7XG4gIGlmIChlbGVtZW50VHlwZSA9PT0gXCJpbnRlZ2VyXCIpIHJldHVybiBcImludGVnZXJbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiYmlnSW50ZWdlclwiKSByZXR1cm4gXCJiaWdpbnRbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiYm9vbGVhblwiKSByZXR1cm4gXCJib29sZWFuW11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcInV1aWRcIikgcmV0dXJuIFwidXVpZFtdXCI7XG4gIGlmIChlbGVtZW50VHlwZSA9PT0gXCJlbnVtXCIpIHJldHVybiBcInRleHRbXVwiO1xuXG4gIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBhcnJheSBlbGVtZW50IHR5cGU6ICR7ZWxlbWVudFR5cGV9YCk7XG59XG5cbi8qKlxuICog6rCc67OEIOyduOuNseyKpCDsoJXsnZgg7IOd7ISxXG4gKi9cbmZ1bmN0aW9uIGdlbkluZGV4RGVmaW5pdGlvbihpbmRleDogTWlncmF0aW9uSW5kZXgsIHRhYmxlOiBzdHJpbmcpIHtcbiAgY29uc3QgbWV0aG9kTWFwID0ge1xuICAgIGluZGV4OiBcImluZGV4XCIsXG4gICAgZnVsbHRleHQ6IFwiaW5kZXhcIixcbiAgICB1bmlxdWU6IFwidW5pcXVlXCIsXG4gIH07XG5cbiAgaWYgKGluZGV4LnR5cGUgPT09IFwiZnVsbHRleHRcIiAmJiBpbmRleC5wYXJzZXIgPT09IFwibmdyYW1cIikge1xuICAgIHJldHVybiBgYXdhaXQga25leC5yYXcoXFxgQUxURVIgVEFCTEUgJHt0YWJsZX0gQUREIEZVTExURVhUIElOREVYICR7aW5kZXgubmFtZX0gKCR7aW5kZXguY29sdW1ucy5qb2luKFxuICAgICAgXCIsIFwiLFxuICAgICl9KSBXSVRIIFBBUlNFUiBuZ3JhbVxcYCk7YDtcbiAgfVxuXG4gIHJldHVybiBgdGFibGUuJHttZXRob2RNYXBbaW5kZXgudHlwZV19KFske2luZGV4LmNvbHVtbnNcbiAgICAubWFwKChjb2wpID0+IGAnJHtjb2x9J2ApXG4gICAgLmpvaW4oXCIsXCIpfV0sICcke2luZGV4Lm5hbWV9JyR7aW5kZXgudHlwZSA9PT0gXCJmdWxsdGV4dFwiID8gXCIsICdGVUxMVEVYVCdcIiA6IFwiXCJ9XG4gICk7YDtcbn1cblxuLyoqXG4gKiDthYzsnbTruJQg7IOd7ISx7ZWY64qUIOy8gOydtOyKpCAtIEZLIOyDneyEsVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNyZWF0ZUNvZGVfRm9yZWlnbihcbiAgdGFibGU6IHN0cmluZyxcbiAgZm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbik6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZVtdPiB7XG4gIGlmIChmb3JlaWducy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCB7IHVwLCBkb3duIH0gPSBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZvcmVpZ25zKTtcbiAgaWYgKHVwLmxlbmd0aCA9PT0gMCAmJiBkb3duLmxlbmd0aCA9PT0gMCkge1xuICAgIGNvbnNvbGUubG9nKFwiZmsg6rCAIOutlOqwgCDri6TrpoXri4jri6RcIik7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW1xuICAgICdpbXBvcnQgeyBLbmV4IH0gZnJvbSBcImtuZXhcIjsnLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gdXAoa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGByZXR1cm4ga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgXCIvLyBjcmVhdGUgZmtcIixcbiAgICAuLi51cCxcbiAgICBcIn0pO1wiLFxuICAgIFwifVwiLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gZG93bihrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYHJldHVybiBrbmV4LnNjaGVtYS5hbHRlclRhYmxlKFwiJHt0YWJsZX1cIiwgKHRhYmxlKSA9PiB7YCxcbiAgICBcIi8vIGRyb3AgZmtcIixcbiAgICAuLi5kb3duLFxuICAgIFwifSk7XCIsXG4gICAgXCJ9XCIsXG4gIF07XG5cbiAgY29uc3QgZm9yZWlnbktleXNTdHJpbmcgPSBmb3JlaWducy5tYXAoKGZvcmVpZ24pID0+IGZvcmVpZ24uY29sdW1ucy5qb2luKFwiX1wiKSkuam9pbihcIl9cIik7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgdGFibGUsXG4gICAgICB0eXBlOiBcImZvcmVpZ25cIixcbiAgICAgIHRpdGxlOiBgZm9yZWlnbl9fJHt0YWJsZX1fXyR7Zm9yZWlnbktleXNTdHJpbmd9YCxcbiAgICAgIGZvcm1hdHRlZDogZm9ybWF0Q29kZShsaW5lcy5qb2luKFwiXFxuXCIpLCBcInR5cGVzY3JpcHRcIiwgYHNyYy9taWdyYXRpb24vJHt0YWJsZX0udHNgKSxcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIE1pZ3JhdGlvbkZvcmVpZ25bXSDsnb3slrTshJwg7Jm467aA7YKkIGNvbnN0cmFpbnQg7KCV7J2Y7ZWY64qUIOq1rOusuCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuRm9yZWlnbkRlZmluaXRpb25zKFxuICB0YWJsZTogc3RyaW5nLFxuICBmb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuKTogeyB1cDogc3RyaW5nW107IGRvd246IHN0cmluZ1tdIH0ge1xuICByZXR1cm4gZm9yZWlnbnMucmVkdWNlKFxuICAgIChyLCBmb3JlaWduKSA9PiB7XG4gICAgICBjb25zdCBjb2x1bW5zU3RyaW5nUXVvdGUgPSBmb3JlaWduLmNvbHVtbnNcbiAgICAgICAgLm1hcCgoY29sKSA9PiBgJyR7Y29sLnJlcGxhY2UoYCR7dGFibGV9LmAsIFwiXCIpfSdgKVxuICAgICAgICAuam9pbihcIixcIik7XG4gICAgICByLnVwLnB1c2goXG4gICAgICAgIGB0YWJsZS5mb3JlaWduKCcke2ZvcmVpZ24uY29sdW1ucy5qb2luKFwiLFwiKX0nKVxuICAgICAgICAgICAgLnJlZmVyZW5jZXMoJyR7Zm9yZWlnbi50b30nKVxuICAgICAgICAgICAgLm9uVXBkYXRlKCcke2ZvcmVpZ24ub25VcGRhdGV9JylcbiAgICAgICAgICAgIC5vbkRlbGV0ZSgnJHtmb3JlaWduLm9uRGVsZXRlfScpYCxcbiAgICAgICk7XG4gICAgICByLmRvd24ucHVzaChgdGFibGUuZHJvcEZvcmVpZ24oWyR7Y29sdW1uc1N0cmluZ1F1b3RlfV0pYCk7XG4gICAgICByZXR1cm4gcjtcbiAgICB9LFxuICAgIHtcbiAgICAgIHVwOiBbXSBhcyBzdHJpbmdbXSxcbiAgICAgIGRvd246IFtdIGFzIHN0cmluZ1tdLFxuICAgIH0sXG4gICk7XG59XG5cbi8qKlxuICog7YWM7J2067iUIOuzgOqyvSDsvIDsnbTsiqQgLSDsu6zrn7wv7J24642x7IqkIOuzgOqyvVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVzKFxuICB0YWJsZTogc3RyaW5nLFxuICBlbnRpdHlDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgZW50aXR5SW5kZXhlczogTWlncmF0aW9uSW5kZXhbXSxcbiAgZGJDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgZGJJbmRleGVzOiBNaWdyYXRpb25JbmRleFtdLFxuICBkYkZvcmVpZ25zOiBNaWdyYXRpb25Gb3JlaWduW10sXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGVbXT4ge1xuICAvKlxuICAgIOyEuOu2gCDruYTqtZAg7ZuEIOuLpOuluOygkCDssL7slYTshJwg7L2U65OcIOyDneyEsVxuXG4gICAgMS4g7Lus65+86rCv7IiYIOuLpOumhDogTUTsl5Ag7J6I7Jy864KYLCBEQuyXkCDsl4bri6TrqbQg7LaU6rCAXG4gICAgMi4g7Lus65+86rCv7IiYIOuLpOumhDogTUTsl5Ag7JeG7Jy864KYLCBEQuyXkCDsnojri6TrqbQg7IKt7KCcXG4gICAgMy4g6re47Jm4IOy7rOufvCjsu6zrn7wg6rCv7IiY6rCAIOuPmeydvO2VmOqxsOuCmCwg64uk66W4IOqyveyasCDrj5nsnbztlZwg7Lus65+864G866asKSA9PiBhbHRlclxuICAgIDQuIOuLpOuluOqxsCDri6Qg64+Z7J287ZWY6rOgIGluZGV466eMIOuzgOqyveuQmOuKlCDqsr3smrBcblxuICAgICoqIOy7rOufvOuqheydhCDrs4Dqsr3tlZjripQg6rK97Jqw64qUIOuUsOuhnCDtlbjrk6Trp4HtlZjsp4Ag7JWK7J2MXG4gICAgPT4gZHJvcC9hZGQg7ZiV7YOc7J2YIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5zqsIAg7IOd7ISx65CY64qU642wLCDsiJjrj5nsnLzroZwgcmVuYW1lIOy9lOuTnOuhnCDsiJjsoJXtlZjsl6wg7LKY66asXG4gICovXG5cbiAgLy8g6rCBIOy7rOufvCDsnbTrpoQg6riw7KSA7Jy866GcIGFkZCwgZHJvcCwgYWx0ZXIg7Jes67aAIO2ZleyduFxuICBjb25zdCBhbHRlckNvbHVtbnNUbyA9IGdldEFsdGVyQ29sdW1uc1RvKGVudGl0eUNvbHVtbnMsIGRiQ29sdW1ucyk7XG5cbiAgLy8g7LaU7Lac65CcIOy7rOufvOuTpOydhCDquLDspIDsnLzroZwg6rCB6rCBIOudvOyduCDsg53shLFcbiAgY29uc3QgYWx0ZXJDb2x1bW5MaW5lc1RvID0gZ2V0QWx0ZXJDb2x1bW5MaW5lc1RvKFxuICAgIGFsdGVyQ29sdW1uc1RvLFxuICAgIGVudGl0eUNvbHVtbnMsXG4gICAgdGFibGUsXG4gICAgZGJGb3JlaWducyxcbiAgKTtcblxuICAvLyDsnbjrjbHsiqTsnZggYWRkLCBkcm9wIOyXrOu2gCDtmZXsnbhcbiAgY29uc3QgYWx0ZXJJbmRleGVzVG8gPSBnZXRBbHRlckluZGV4ZXNUbyhlbnRpdHlJbmRleGVzLCBkYkluZGV4ZXMpO1xuXG4gIC8vIGZ1bGx0ZXh0IGluZGV4IOu2hOumrFxuICBjb25zdCBbbmdyYW1JbmRleGVzLCBzdGFuZGFyZEluZGV4ZXNdID0gZm9yayhcbiAgICBhbHRlckluZGV4ZXNUby5hZGQsXG4gICAgKGkpID0+IGkudHlwZSA9PT0gXCJmdWxsdGV4dFwiICYmIGkucGFyc2VyID09PSBcIm5ncmFtXCIsXG4gICk7XG5cbiAgLy8g7J24642x7Iqk6rCAIOyCreygnOuQmOuKlCDqsr3smrAsIOy7rOufvOqzvCDqsJnsnbQg7IKt7KCc65CcIOy8gOydtOyKpOyXkOuKlCBkcm9w7JeQ7IScIOygnOyZuO2VtOyVvO2VqCFcbiAgY29uc3QgaW5kZXhOZWVkc1RvRHJvcCA9IGFsdGVySW5kZXhlc1RvLmRyb3AuZmlsdGVyKFxuICAgIChpbmRleCkgPT5cbiAgICAgIGluZGV4LmNvbHVtbnMuZXZlcnkoKGNvbE5hbWUpID0+XG4gICAgICAgIGFsdGVyQ29sdW1uc1RvLmRyb3AubWFwKChjb2wpID0+IGNvbC5uYW1lKS5pbmNsdWRlcyhjb2xOYW1lKSxcbiAgICAgICkgPT09IGZhbHNlLFxuICApO1xuXG4gIC8vIOu5iCDsvZTrk5wg7IOd7ISxIOuwqeyngFxuICBpZiAoXG4gICAgYWx0ZXJDb2x1bW5MaW5lc1RvLmFkZC51cC5sZW5ndGggPT09IDAgJiZcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5sZW5ndGggPT09IDAgJiZcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uYWx0ZXIudXAubGVuZ3RoID09PSAwICYmXG4gICAgc3RhbmRhcmRJbmRleGVzLmxlbmd0aCA9PT0gMCAmJlxuICAgIGluZGV4TmVlZHNUb0Ryb3AubGVuZ3RoID09PSAwXG4gICkge1xuICAgIE5haXRlLnQoXCJtaWdyYXRvcjpnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVzOmVtcHR5Q29kZUdlbmVyYXRpb25FcnJvclwiLCB7XG4gICAgICBlbnRpdHlDb2x1bW5zLFxuICAgICAgZGJDb2x1bW5zLFxuICAgICAgZW50aXR5SW5kZXhlcyxcbiAgICAgIGRiSW5kZXhlcyxcbiAgICB9KTtcbiAgICAvLyB0aHJvdyBuZXcgRXJyb3IoXCLsu6zrn7wv7J24642x7IqkIOuzgOqyvSDsvZTrk5wg7IOd7ISxIOyYpOulmFwiKTtcbiAgfVxuICBOYWl0ZS50KFwibWlncmF0b3I6Z2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlczpkZWJ1Z1wiLCB7XG4gICAgXCJhbHRlckNvbHVtbnNUby5hZGQubGVuZ3RoXCI6IGFsdGVyQ29sdW1uc1RvLmFkZC5sZW5ndGgsXG4gICAgXCJhbHRlckNvbHVtbnNUby5kcm9wLmxlbmd0aFwiOiBhbHRlckNvbHVtbnNUby5kcm9wLmxlbmd0aCxcbiAgICBcImFsdGVyQ29sdW1uc1RvLmFsdGVyLmxlbmd0aFwiOiBhbHRlckNvbHVtbnNUby5hbHRlci5sZW5ndGgsXG4gICAgXCJhbHRlckluZGV4ZXNUby5hZGQubGVuZ3RoXCI6IGFsdGVySW5kZXhlc1RvLmFkZC5sZW5ndGgsXG4gICAgXCJhbHRlckluZGV4ZXNUby5kcm9wLmxlbmd0aFwiOiBhbHRlckluZGV4ZXNUby5kcm9wLmxlbmd0aCxcbiAgICBcInN0YW5kYXJkSW5kZXhlcy5sZW5ndGhcIjogc3RhbmRhcmRJbmRleGVzLmxlbmd0aCxcbiAgICBcImluZGV4TmVlZHNUb0Ryb3AubGVuZ3RoXCI6IGluZGV4TmVlZHNUb0Ryb3AubGVuZ3RoLFxuICB9KTtcbiAgLy8gTmFpdGUudChcIm1pZ3JhdG9yOmdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXM6YWx0ZXJDb2x1bW5zVG9cIiwgYWx0ZXJDb2x1bW5zVG8pO1xuXG4gIC8vIFRPRE86IOyduOuNseyKpOuqhSDrs4Dqsr3rkJwg6rK97JqwIOyymOumrFxuXG4gIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtcbiAgICAnaW1wb3J0IHsgS25leCB9IGZyb20gXCJrbmV4XCI7JyxcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgYXdhaXQga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLy8gMS4gYWRkIGNvbHVtblxuICAgIC4uLihhbHRlckNvbHVtbnNUby5hZGQubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5hZGQudXAgOiBbXSksXG4gICAgLy8gMi4gZHJvcCBjb2x1bW5cbiAgICAuLi4oYWx0ZXJDb2x1bW5zVG8uZHJvcC5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmRyb3AudXAgOiBbXSksXG4gICAgLy8gMy4gYWx0ZXIgY29sdW1uXG4gICAgLi4uKGFsdGVyQ29sdW1uc1RvLmFsdGVyLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uYWx0ZXIudXAgOiBbXSksXG4gICAgLy8gNC4gYWRkIGluZGV4XG4gICAgLi4uc3RhbmRhcmRJbmRleGVzLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICAvLyA1LiBkcm9wIGluZGV4XG4gICAgLi4uaW5kZXhOZWVkc1RvRHJvcC5tYXAoZ2VuSW5kZXhEcm9wRGVmaW5pdGlvbiksXG4gICAgXCJ9KTtcIixcbiAgICAvLyBuZ3JhbeydgCBrbmV4LnJhd+uhnCDsspjrpqztlZjrr4DroZwgYWx0ZXJUYWJsZSDrsJbsl5DshJwg7Iuk7ZaJXG4gICAgLi4ubmdyYW1JbmRleGVzLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICBcIn1cIixcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvd24oa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGByZXR1cm4ga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLi4uKGFsdGVyQ29sdW1uc1RvLmFkZC5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmFkZC5kb3duIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbnNUby5kcm9wLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC5kb3duIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbnNUby5hbHRlci5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmFsdGVyLmRvd24gOiBbXSksXG4gICAgLi4uYWx0ZXJJbmRleGVzVG8uYWRkXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoaW5kZXgpID0+XG4gICAgICAgICAgaW5kZXguY29sdW1ucy5ldmVyeSgoY29sTmFtZSkgPT5cbiAgICAgICAgICAgIGFsdGVyQ29sdW1uc1RvLmFkZC5tYXAoKGNvbCkgPT4gY29sLm5hbWUpLmluY2x1ZGVzKGNvbE5hbWUpLFxuICAgICAgICAgICkgPT09IGZhbHNlLFxuICAgICAgKVxuICAgICAgLm1hcChnZW5JbmRleERyb3BEZWZpbml0aW9uKSxcbiAgICAuLi5pbmRleE5lZWRzVG9Ecm9wLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICBcIn0pO1wiLFxuICAgIFwifVwiLFxuICBdO1xuXG4gIGNvbnN0IGZvcm1hdHRlZCA9IGZvcm1hdENvZGUobGluZXMuam9pbihcIlxcblwiKSwgXCJ0eXBlc2NyaXB0XCIsIGBzcmMvbWlncmF0aW9uLyR7dGFibGV9LnRzYCk7XG4gIGNvbnN0IHRpdGxlID0gW1xuICAgIFwiYWx0ZXJcIixcbiAgICB0YWJsZSxcbiAgICAuLi4oW1wiYWRkXCIsIFwiZHJvcFwiLCBcImFsdGVyXCJdIGFzIGNvbnN0KVxuICAgICAgLm1hcCgoYWN0aW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IGxlbiA9IGFsdGVyQ29sdW1uc1RvW2FjdGlvbl0ubGVuZ3RoO1xuICAgICAgICBpZiAobGVuID4gMCkge1xuICAgICAgICAgIHJldHVybiBhY3Rpb24gKyBsZW47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigocGFydCkgPT4gcGFydCAhPT0gbnVsbCksXG4gIF0uam9pbihcIl9cIik7XG5cbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0YWJsZSxcbiAgICAgIHRpdGxlLFxuICAgICAgZm9ybWF0dGVkLFxuICAgICAgdHlwZTogXCJub3JtYWxcIixcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIOqwgSDsu6zrn7wg7J2066aEIOq4sOykgOycvOuhnCBhZGQsIGRyb3AsIGFsdGVyIOyXrOu2gCDtmZXsnbhcbiAqL1xuZnVuY3Rpb24gZ2V0QWx0ZXJDb2x1bW5zVG8oZW50aXR5Q29sdW1uczogTWlncmF0aW9uQ29sdW1uW10sIGRiQ29sdW1uczogTWlncmF0aW9uQ29sdW1uW10pIHtcbiAgY29uc3QgY29sdW1uc1RvID0ge1xuICAgIGFkZDogW10gYXMgTWlncmF0aW9uQ29sdW1uW10sXG4gICAgZHJvcDogW10gYXMgTWlncmF0aW9uQ29sdW1uW10sXG4gICAgYWx0ZXI6IFtdIGFzIE1pZ3JhdGlvbkNvbHVtbltdLFxuICB9O1xuXG4gIC8vIOy7rOufvOuqhSDquLDspIAg67mE6rWQXG4gIGNvbnN0IGV4dHJhQ29sdW1ucyA9IHtcbiAgICBkYjogZGlmZihkYkNvbHVtbnMsIGVudGl0eUNvbHVtbnMsIChjb2wpID0+IGNvbC5uYW1lKSxcbiAgICBlbnRpdHk6IGRpZmYoZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSksXG4gIH07XG4gIGlmIChleHRyYUNvbHVtbnMuZW50aXR5Lmxlbmd0aCA+IDApIHtcbiAgICBjb2x1bW5zVG8uYWRkID0gY29sdW1uc1RvLmFkZC5jb25jYXQoZXh0cmFDb2x1bW5zLmVudGl0eSk7XG4gIH1cbiAgaWYgKGV4dHJhQ29sdW1ucy5kYi5sZW5ndGggPiAwKSB7XG4gICAgY29sdW1uc1RvLmRyb3AgPSBjb2x1bW5zVG8uZHJvcC5jb25jYXQoZXh0cmFDb2x1bW5zLmRiKTtcbiAgfVxuXG4gIC8vIOuPmeydvCDsu6zrn7zrqoXsnZgg7IS467aAIO2VhOuTnCDruYTqtZBcbiAgY29uc3Qgc2FtZURiQ29sdW1ucyA9IGludGVyc2VjdGlvbkJ5KGRiQ29sdW1ucywgZW50aXR5Q29sdW1ucywgKGNvbCkgPT4gY29sLm5hbWUpO1xuICBjb25zdCBzYW1lTWRDb2x1bW5zID0gaW50ZXJzZWN0aW9uQnkoZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSk7XG4gIGNvbHVtbnNUby5hbHRlciA9IGRpZmZlcmVuY2VXaXRoKHNhbWVEYkNvbHVtbnMsIHNhbWVNZENvbHVtbnMsIChhLCBiKSA9PiBlcXVhbChhLCBiKSk7XG5cbiAgcmV0dXJuIGNvbHVtbnNUbztcbn1cblxuLyoqXG4gKiDstpTstpzrkJwg7Lus65+865Ok7J2EIOq4sOykgOycvOuhnCDqsIHqsIEg65287J24IOyDneyEsVxuICovXG5mdW5jdGlvbiBnZXRBbHRlckNvbHVtbkxpbmVzVG8oXG4gIGNvbHVtbnNUbzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0QWx0ZXJDb2x1bW5zVG8+LFxuICBlbnRpdHlDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgdGFibGU6IHN0cmluZyxcbiAgZGJGb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuKSB7XG4gIGNvbnN0IGxpbmVzVG8gPSB7XG4gICAgYWRkOiB7XG4gICAgICB1cDogW10gYXMgc3RyaW5nW10sXG4gICAgICBkb3duOiBbXSBhcyBzdHJpbmdbXSxcbiAgICB9LFxuICAgIGRyb3A6IHtcbiAgICAgIHVwOiBbXSBhcyBzdHJpbmdbXSxcbiAgICAgIGRvd246IFtdIGFzIHN0cmluZ1tdLFxuICAgIH0sXG4gICAgYWx0ZXI6IHtcbiAgICAgIHVwOiBbXSBhcyBzdHJpbmdbXSxcbiAgICAgIGRvd246IFtdIGFzIHN0cmluZ1tdLFxuICAgIH0sXG4gIH07XG5cbiAgbGluZXNUby5hZGQgPSB7XG4gICAgdXA6IFtcIi8vIGFkZFwiLCAuLi5nZW5Db2x1bW5EZWZpbml0aW9ucyhjb2x1bW5zVG8uYWRkKV0sXG4gICAgZG93bjogW1xuICAgICAgXCIvLyByb2xsYmFjayAtIGFkZFwiLFxuICAgICAgYHRhYmxlLmRyb3BDb2x1bW5zKCR7Y29sdW1uc1RvLmFkZC5tYXAoKGNvbCkgPT4gYCcke2NvbC5uYW1lfSdgKS5qb2luKFwiLCBcIil9KWAsXG4gICAgXSxcbiAgfTtcblxuICAvLyBkcm9w7ZWgIOy7rOufvOyXkCDqsbjrprAgRksg7LC+6riwXG4gIGNvbnN0IGRyb3BDb2x1bW5OYW1lcyA9IGNvbHVtbnNUby5kcm9wLm1hcCgoY29sKSA9PiBjb2wubmFtZSk7XG4gIGNvbnN0IGZrVG9Ecm9wQmVmb3JlQ29sdW1uID0gZGJGb3JlaWducy5maWx0ZXIoKGZrKSA9PlxuICAgIGZrLmNvbHVtbnMuc29tZSgoY29sKSA9PiBkcm9wQ29sdW1uTmFtZXMuaW5jbHVkZXMoY29sKSksXG4gICk7XG5cbiAgY29uc3QgZHJvcEZrTGluZXMgPSBma1RvRHJvcEJlZm9yZUNvbHVtbi5tYXAoKGZrKSA9PiB7XG4gICAgY29uc3QgY29sdW1uc1N0cmluZ1F1b3RlID0gZmsuY29sdW1ucy5tYXAoKGNvbCkgPT4gYCcke2NvbH0nYCkuam9pbihcIixcIik7XG4gICAgcmV0dXJuIGB0YWJsZS5kcm9wRm9yZWlnbihbJHtjb2x1bW5zU3RyaW5nUXVvdGV9XSlgO1xuICB9KTtcblxuICBjb25zdCByZXN0b3JlRmtMaW5lcyA9IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZmtUb0Ryb3BCZWZvcmVDb2x1bW4pLnVwO1xuXG4gIGxpbmVzVG8uZHJvcCA9IHtcbiAgICB1cDogW1xuICAgICAgLi4uKGRyb3BGa0xpbmVzLmxlbmd0aCA+IDBcbiAgICAgICAgPyBbXCIvLyBkcm9wIGZvcmVpZ24ga2V5cyBvbiBjb2x1bW5zIHRvIGJlIGRyb3BwZWRcIiwgLi4uZHJvcEZrTGluZXNdXG4gICAgICAgIDogW10pLFxuICAgICAgXCIvLyBkcm9wIGNvbHVtbnNcIixcbiAgICAgIGB0YWJsZS5kcm9wQ29sdW1ucygke2NvbHVtbnNUby5kcm9wLm1hcCgoY29sKSA9PiBgJyR7Y29sLm5hbWV9J2ApLmpvaW4oXCIsIFwiKX0pYCxcbiAgICBdLFxuICAgIGRvd246IFtcbiAgICAgIFwiLy8gcm9sbGJhY2sgLSBkcm9wIGNvbHVtbnNcIixcbiAgICAgIC4uLmdlbkNvbHVtbkRlZmluaXRpb25zKGNvbHVtbnNUby5kcm9wKSxcbiAgICAgIC4uLihyZXN0b3JlRmtMaW5lcy5sZW5ndGggPiAwID8gW1wiLy8gcmVzdG9yZSBmb3JlaWduIGtleXNcIiwgLi4ucmVzdG9yZUZrTGluZXNdIDogW10pLFxuICAgIF0sXG4gIH07XG4gIGxpbmVzVG8uYWx0ZXIgPSBjb2x1bW5zVG8uYWx0ZXIucmVkdWNlKFxuICAgIChyLCBkYkNvbHVtbikgPT4ge1xuICAgICAgY29uc3QgZW50aXR5Q29sdW1uID0gZW50aXR5Q29sdW1ucy5maW5kKChjb2wpID0+IGNvbC5uYW1lID09PSBkYkNvbHVtbi5uYW1lKTtcbiAgICAgIGlmIChlbnRpdHlDb2x1bW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gcjtcbiAgICAgIH1cblxuICAgICAgLy8g7Lus65+8IOuzgOqyveyCrO2VrVxuICAgICAgY29uc3QgY29sdW1uRGlmZlVwID0gZGlmZihcbiAgICAgICAgZ2VuQ29sdW1uRGVmaW5pdGlvbnMoW2VudGl0eUNvbHVtbl0pLFxuICAgICAgICBnZW5Db2x1bW5EZWZpbml0aW9ucyhbZGJDb2x1bW5dKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBjb2x1bW5EaWZmRG93biA9IGRpZmYoXG4gICAgICAgIGdlbkNvbHVtbkRlZmluaXRpb25zKFtkYkNvbHVtbl0pLFxuICAgICAgICBnZW5Db2x1bW5EZWZpbml0aW9ucyhbZW50aXR5Q29sdW1uXSksXG4gICAgICApO1xuICAgICAgaWYgKGNvbHVtbkRpZmZVcC5sZW5ndGggPiAwKSB7XG4gICAgICAgIHIudXAgPSBbXG4gICAgICAgICAgLi4uci51cCxcbiAgICAgICAgICBcIi8vIGFsdGVyIGNvbHVtblwiLFxuICAgICAgICAgIC4uLmNvbHVtbkRpZmZVcC5tYXAoKGwpID0+IGAke2wucmVwbGFjZShcIjtcIiwgXCJcIil9LmFsdGVyKCk7YCksXG4gICAgICAgIF07XG4gICAgICAgIHIuZG93biA9IFtcbiAgICAgICAgICAuLi5yLmRvd24sXG4gICAgICAgICAgXCIvLyByb2xsYmFjayAtIGFsdGVyIGNvbHVtblwiLFxuICAgICAgICAgIC4uLmNvbHVtbkRpZmZEb3duLm1hcCgobCkgPT4gYCR7bC5yZXBsYWNlKFwiO1wiLCBcIlwiKX0uYWx0ZXIoKTtgKSxcbiAgICAgICAgXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHI7XG4gICAgfSxcbiAgICB7XG4gICAgICB1cDogW10gYXMgc3RyaW5nW10sXG4gICAgICBkb3duOiBbXSBhcyBzdHJpbmdbXSxcbiAgICB9LFxuICApO1xuXG4gIHJldHVybiBsaW5lc1RvO1xufVxuXG4vKipcbiAqIOyduOuNseyKpOydmCBhZGQsIGRyb3Ag7Jes67aAIO2ZleyduFxuICovXG5mdW5jdGlvbiBnZXRBbHRlckluZGV4ZXNUbyhlbnRpdHlJbmRleGVzOiBNaWdyYXRpb25JbmRleFtdLCBkYkluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10pIHtcbiAgLy8g7J24642x7IqkIOu5hOq1kFxuICBjb25zdCBpbmRleGVzVG8gPSB7XG4gICAgYWRkOiBbXSBhcyBNaWdyYXRpb25JbmRleFtdLFxuICAgIGRyb3A6IFtdIGFzIE1pZ3JhdGlvbkluZGV4W10sXG4gIH07XG4gIGNvbnN0IGV4dHJhSW5kZXhlcyA9IHtcbiAgICBkYjogZGlmZihkYkluZGV4ZXMsIGVudGl0eUluZGV4ZXMsIChjb2wpID0+IFtjb2wudHlwZSwgY29sLmNvbHVtbnMuam9pbihcIi1cIildLmpvaW4oXCIvL1wiKSksXG4gICAgZW50aXR5OiBkaWZmKGVudGl0eUluZGV4ZXMsIGRiSW5kZXhlcywgKGNvbCkgPT4gW2NvbC50eXBlLCBjb2wuY29sdW1ucy5qb2luKFwiLVwiKV0uam9pbihcIi8vXCIpKSxcbiAgfTtcbiAgaWYgKGV4dHJhSW5kZXhlcy5lbnRpdHkubGVuZ3RoID4gMCkge1xuICAgIGluZGV4ZXNUby5hZGQgPSBpbmRleGVzVG8uYWRkLmNvbmNhdChleHRyYUluZGV4ZXMuZW50aXR5KTtcbiAgfVxuICBpZiAoZXh0cmFJbmRleGVzLmRiLmxlbmd0aCA+IDApIHtcbiAgICBpbmRleGVzVG8uZHJvcCA9IGluZGV4ZXNUby5kcm9wLmNvbmNhdChleHRyYUluZGV4ZXMuZGIpO1xuICB9XG5cbiAgcmV0dXJuIGluZGV4ZXNUbztcbn1cblxuLyoqXG4gKiDsnbjrjbHsiqQg7IKt7KCcIOygleydmCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuSW5kZXhEcm9wRGVmaW5pdGlvbihpbmRleDogTWlncmF0aW9uSW5kZXgpIHtcbiAgY29uc3QgbWV0aG9kTWFwID0ge1xuICAgIGluZGV4OiBcIkluZGV4XCIsXG4gICAgZnVsbHRleHQ6IFwiSW5kZXhcIixcbiAgICB1bmlxdWU6IFwiVW5pcXVlXCIsXG4gIH07XG5cbiAgcmV0dXJuIGB0YWJsZS5kcm9wJHttZXRob2RNYXBbaW5kZXgudHlwZV19KFske2luZGV4LmNvbHVtbnNcbiAgICAubWFwKChjb2x1bW5OYW1lKSA9PiBgJyR7Y29sdW1uTmFtZX0nYClcbiAgICAuam9pbihcIixcIil9XSwgJyR7aW5kZXgubmFtZX0nKWA7XG59XG5cbi8qKlxuICog7YWM7J2067iUIOuzgOqyvSDsvIDsnbTsiqQgLSBGb3JlaWduIEtleSDrs4Dqsr1cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVBbHRlckNvZGVfRm9yZWlnbnMoXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGVudGl0eUZvcmVpZ25zOiBNaWdyYXRpb25Gb3JlaWduW10sXG4gIGRiRm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgZHJvcHBpbmdDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSA9IFtdLFxuKTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgLy8gY29uc29sZS5sb2coeyBlbnRpdHlGb3JlaWducywgZGJGb3JlaWducyB9KTtcblxuICBjb25zdCBnZXRLZXkgPSAobWY6IE1pZ3JhdGlvbkZvcmVpZ24pOiBzdHJpbmcgPT4ge1xuICAgIHJldHVybiBbbWYuY29sdW1ucy5qb2luKFwiLVwiKSwgbWYudG9dLmpvaW4oXCIvLy9cIik7XG4gIH07XG5cbiAgLy8g7IKt7KCc65CgIOy7rOufvOuqhSDrqqnroZ1cbiAgY29uc3QgZHJvcHBpbmdDb2x1bW5OYW1lcyA9IGRyb3BwaW5nQ29sdW1ucy5tYXAoKGNvbCkgPT4gY29sLm5hbWUpO1xuXG4gIGNvbnN0IGZrVG8gPSBlbnRpdHlGb3JlaWducy5yZWR1Y2UoXG4gICAgKHJlc3VsdCwgZW50aXR5RikgPT4ge1xuICAgICAgY29uc3QgbWF0Y2hpbmdEYkYgPSBkYkZvcmVpZ25zLmZpbmQoKGRiRikgPT4gZ2V0S2V5KGVudGl0eUYpID09PSBnZXRLZXkoZGJGKSk7XG4gICAgICBpZiAoIW1hdGNoaW5nRGJGKSB7XG4gICAgICAgIHJlc3VsdC5hZGQucHVzaChlbnRpdHlGKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgaWYgKGVxdWFsKGVudGl0eUYsIG1hdGNoaW5nRGJGKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmVzdWx0LmFsdGVyU3JjLnB1c2gobWF0Y2hpbmdEYkYpO1xuICAgICAgICByZXN1bHQuYWx0ZXJEc3QucHVzaChlbnRpdHlGKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcbiAgICB7XG4gICAgICBhZGQ6IFtdIGFzIE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgICAgIGRyb3A6IFtdIGFzIE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgICAgIGFsdGVyU3JjOiBbXSBhcyBNaWdyYXRpb25Gb3JlaWduW10sXG4gICAgICBhbHRlckRzdDogW10gYXMgTWlncmF0aW9uRm9yZWlnbltdLFxuICAgIH0sXG4gICk7XG5cbiAgLy8gZGJGb3JlaWduc+yXkOuKlCDsnojsp4Drp4wgZW50aXR5Rm9yZWlnbnPsl5DripQg7JeG64qUIOqyveyasCAo7IKt7KCc65CcIEZLKVxuICAvLyDri6gsIOyCreygnOuQoCDsu6zrn7zsnZggRkvripQg7KCc7Jm4IChnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVz7JeQ7IScIOyymOumrClcbiAgZGJGb3JlaWducy5mb3JFYWNoKChkYkYpID0+IHtcbiAgICBjb25zdCBtYXRjaGluZ0VudGl0eUYgPSBlbnRpdHlGb3JlaWducy5maW5kKChlbnRpdHlGKSA9PiBnZXRLZXkoZW50aXR5RikgPT09IGdldEtleShkYkYpKTtcbiAgICBpZiAoIW1hdGNoaW5nRW50aXR5Rikge1xuICAgICAgLy8g7J20IEZL7J2YIOy7rOufvOydtCDsgq3soJzrkKAg7Lus65+8IOuqqeuhneyXkCDsnojripTsp4Ag7ZmV7J24XG4gICAgICBjb25zdCBpc0NvbHVtbkRyb3BwaW5nID0gZGJGLmNvbHVtbnMuc29tZSgoY29sKSA9PiBkcm9wcGluZ0NvbHVtbk5hbWVzLmluY2x1ZGVzKGNvbCkpO1xuICAgICAgLy8g7Lus65+87J20IOyCreygnOuQmOyngCDslYrripQg6rK97Jqw7JeQ66eMIEZLIGRyb3Ag66qp66Gd7JeQIOy2lOqwgFxuICAgICAgaWYgKCFpc0NvbHVtbkRyb3BwaW5nKSB7XG4gICAgICAgIGZrVG8uZHJvcC5wdXNoKGRiRik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBsaW5lc1RvID0ge1xuICAgIGFkZDogZ2VuRm9yZWlnbkRlZmluaXRpb25zKHRhYmxlLCBma1RvLmFkZCksXG4gICAgZHJvcDogZ2VuRm9yZWlnbkRlZmluaXRpb25zKHRhYmxlLCBma1RvLmRyb3ApLFxuICAgIGFsdGVyU3JjOiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uYWx0ZXJTcmMpLFxuICAgIGFsdGVyRHN0OiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uYWx0ZXJEc3QpLFxuICB9O1xuXG4gIC8vIGRyb3AgZmsgY29sdW1uc+yduCDqsr3smrAo7IOd7ISx65CgIOy9lOuTnCDsl4bripQg6rK97JqwKSDtjKjsiqRcbiAgY29uc3QgaGFzTGluZXMgPSBPYmplY3QudmFsdWVzKGxpbmVzVG8pLnNvbWUoKGwpID0+IGwudXAubGVuZ3RoID4gMCB8fCBsLmRvd24ubGVuZ3RoID4gMCk7XG4gIGlmICghaGFzTGluZXMpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBpZiAoXG4gICAgbGluZXNUby5hZGQudXAubGVuZ3RoID09PSAwICYmXG4gICAgbGluZXNUby5kcm9wLnVwLmxlbmd0aCA9PT0gMCAmJlxuICAgIGxpbmVzVG8uYWx0ZXJTcmMudXAubGVuZ3RoID09PSAwICYmXG4gICAgbGluZXNUby5hbHRlckRzdC51cC5sZW5ndGggPT09IDBcbiAgKSB7XG4gICAgTmFpdGUudChcIm1pZ3JhdG9yOmdlbmVyYXRlQWx0ZXJDb2RlX0ZvcmVpZ25zOmZrQ2hhbmdlQ29kZUdlbmVyYXRpb25FcnJvclwiLCB7XG4gICAgICB0YWJsZSxcbiAgICAgIGVudGl0eUZvcmVpZ25zLFxuICAgICAgZGJGb3JlaWducyxcbiAgICB9KTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJGSyDrs4Dqsr0g7L2U65OcIOyDneyEsSDsmKTrpZhcIik7XG4gIH1cblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXG4gICAgJ2ltcG9ydCB7IEtuZXggfSBmcm9tIFwia25leFwiOycsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cChrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYHJldHVybiBrbmV4LnNjaGVtYS5hbHRlclRhYmxlKFwiJHt0YWJsZX1cIiwgKHRhYmxlKSA9PiB7YCxcbiAgICAuLi5saW5lc1RvLmRyb3AuZG93bixcbiAgICAuLi5saW5lc1RvLmFkZC51cCxcbiAgICAuLi5saW5lc1RvLmFsdGVyU3JjLmRvd24sXG4gICAgLi4ubGluZXNUby5hbHRlckRzdC51cCxcbiAgICBcIn0pXCIsXG4gICAgXCJ9XCIsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb3duKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgcmV0dXJuIGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLFxuICAgIC4uLmxpbmVzVG8uYWRkLmRvd24sXG4gICAgLi4ubGluZXNUby5hbHRlckRzdC5kb3duLFxuICAgIC4uLmxpbmVzVG8uYWx0ZXJTcmMudXAsXG4gICAgLi4ubGluZXNUby5kcm9wLnVwLFxuICAgIFwifSlcIixcbiAgICBcIn1cIixcbiAgXTtcblxuICBjb25zdCBmb3JtYXR0ZWQgPSBmb3JtYXRDb2RlKGxpbmVzLmpvaW4oXCJcXG5cIiksIFwidHlwZXNjcmlwdFwiLCBgc3JjL21pZ3JhdGlvbi8ke3RhYmxlfS50c2ApO1xuICBjb25zdCB0aXRsZSA9IFtcbiAgICBcImFsdGVyXCIsXG4gICAgdGFibGUsXG4gICAgXCJmb3JlaWduc1wiLFxuICAgIC8vIFRPRE8g67CU64CM64qUIOu2gOu2hFxuICBdLmpvaW4oXCJfXCIpO1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgdGFibGUsXG4gICAgICB0aXRsZSxcbiAgICAgIGZvcm1hdHRlZCxcbiAgICAgIHR5cGU6IFwibm9ybWFsXCIsXG4gICAgfSxcbiAgXTtcbn1cblxuLyoqXG4gKiDso7zslrTsp4QgRW50aXR5U2V07J2EIOq4sOuwmOycvOuhnCDthYzsnbTruJQgQ1JFQVRFIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5zrpbwg7IOd7ISx7ZWp64uI64ukLlxuICogQHBhcmFtIGVudGl0eVNldFxuICogQHJldHVybnMgQ1JFQVRFIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5xcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ3JlYXRlQ29kZShlbnRpdHlTZXQ6IE1pZ3JhdGlvblNldCk6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZVtdPiB7XG4gIHJldHVybiBbXG4gICAgYXdhaXQgZ2VuZXJhdGVDcmVhdGVDb2RlX0NvbHVtbkFuZEluZGV4ZXMoXG4gICAgICBlbnRpdHlTZXQudGFibGUsXG4gICAgICBlbnRpdHlTZXQuY29sdW1ucyxcbiAgICAgIGVudGl0eVNldC5pbmRleGVzLFxuICAgICksXG4gICAgLi4uKGF3YWl0IGdlbmVyYXRlQ3JlYXRlQ29kZV9Gb3JlaWduKGVudGl0eVNldC50YWJsZSwgZW50aXR5U2V0LmZvcmVpZ25zKSksXG4gIF07XG59XG5cbi8qKlxuICog7KO87Ja07KeEIGVudGl0eVNldOydhCDrqqntkZzroZwsIGRiU2V07J2EIO2YhCDsg4HtmansnLzroZwg7ZWY7JesIO2FjOydtOu4lCBBTFRFUiDrp4jsnbTqt7jroIjsnbTshZgg7L2U65Oc66W8IOyDneyEse2VqeuLiOuLpC5cbiAqIEBwYXJhbSBlbnRpdHlTZXQg7ZiEIOyDge2ZqeydmCBNaWdyYXRpb25TZXRcbiAqIEBwYXJhbSBkYlNldCDrqqntkZwg7IOB7Zmp7J2YIE1pZ3JhdGlvblNldFxuICogQHJldHVybnMgQUxURVIg66eI7J206re466CI7J207IWYIOy9lOuTnFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVBbHRlckNvZGUoXG4gIGVudGl0eVNldDogTWlncmF0aW9uU2V0LFxuICBkYlNldDogTWlncmF0aW9uU2V0LFxuKTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgY29uc3QgcmVwbGFjZUNvbHVtbkRlZmF1bHRUbyA9IChjb2w6IE1pZ3JhdGlvbkNvbHVtbikgPT4ge1xuICAgIC8vIGZsb2F07J24IOqyveyasCDquLDrs7jqsJLsnYQgMOycvOuhnCDsp4DsoJXtlZjripQg6rK97JqwIFwiMC4wMFwi7Jy866GcIOuzgO2ZmOuQmOuKlCDsvIDsnbTsiqQg64yA7J2RXG4gICAgLy8gaWYgKGNvbC50eXBlID09PSBcImZsb2F0XCIgJiYgY29sLmRlZmF1bHRUbyAmJiBTdHJpbmcoY29sLmRlZmF1bHRUbykuaW5jbHVkZXMoJ1wiJykgPT09IGZhbHNlKSB7XG4gICAgLy8gICBjb2wuZGVmYXVsdFRvID0gYFwiJHtOdW1iZXIoY29sLmRlZmF1bHRUbykudG9GaXhlZChjb2wuc2NhbGUgPz8gMil9XCJgO1xuICAgIC8vIH1cbiAgICAvLyAvLyBzdHJpbmfsnbgg6rK97JqwIOq4sOuzuOqwkuydtCDruYgg7Iqk7Yq466eB7J24IOqyveyasCDrjIDsnZFcbiAgICAvLyBpZiAoY29sLnR5cGUgPT09IFwic3RyaW5nXCIgJiYgY29sLmRlZmF1bHRUbyA9PT0gXCJcIikge1xuICAgIC8vICAgY29sLmRlZmF1bHRUbyA9ICdcIlwiJztcbiAgICAvLyB9XG4gICAgLy8gLy8gYm9vbGVhbuyduCDqsr3smrAg6riw67O46rCSIOygleq3nO2ZlCAoTXlTUUzsl5DshJzripQgVElOWUlOVCgxKeuhnCDsoIDsnqXrkJjrr4DroZwgMCDrmJDripQgMeuhnCDsoJXqt5ztmZQpXG4gICAgLy8gLy8gVE9ETzogZGIudHPsl5AgdHlwZUNhc2Ug7ISk7KCVIO2ZleyduO2VmOyXrCDsspjrpqztlZjrj4TroZ0g7IiY7KCVIO2VhOyalFxuICAgIC8vIGlmIChjb2wudHlwZSA9PT0gXCJib29sZWFuXCIgJiYgY29sLmRlZmF1bHRUbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gICBpZiAoY29sLmRlZmF1bHRUbyA9PT0gXCIwXCIgfHwgY29sLmRlZmF1bHRUby50b0xvd2VyQ2FzZSgpID09PSBcImZhbHNlXCIpIHtcbiAgICAvLyAgICAgY29sLmRlZmF1bHRUbyA9IFwiMFwiO1xuICAgIC8vICAgfSBlbHNlIGlmIChjb2wuZGVmYXVsdFRvID09PSBcIjFcIiB8fCBjb2wuZGVmYXVsdFRvLnRvTG93ZXJDYXNlKCkgPT09IFwidHJ1ZVwiKSB7XG4gICAgLy8gICAgIGNvbC5kZWZhdWx0VG8gPSBcIjFcIjtcbiAgICAvLyAgIH1cbiAgICAvLyB9XG5cbiAgICAvLyBGSVhNRTog7J2864uoIE15U1FMIOyDge2ZqeyXkOyEnCDrsJzsg53tlojrjZgg7J207IqI7J2YIHdvcmthcm91bmQg7J2066+A66GcIFBn7JeQ7IScIOyerO2ZleyduCDtm4Qg64yA7J2RIOy2lOqwgFxuICAgIHJldHVybiBjb2w7XG4gIH07XG4gIGNvbnN0IGVudGl0eUNvbHVtbnMgPSBhbHBoYWJldGljYWwoZW50aXR5U2V0LmNvbHVtbnMsIChhKSA9PiBhLm5hbWUpLm1hcChyZXBsYWNlQ29sdW1uRGVmYXVsdFRvKTtcbiAgY29uc3QgZGJDb2x1bW5zID0gYWxwaGFiZXRpY2FsKGRiU2V0LmNvbHVtbnMsIChhKSA9PiBhLm5hbWUpLm1hcChyZXBsYWNlQ29sdW1uRGVmYXVsdFRvKTtcblxuICAvKiDrlJTrsoTquYXsmqkg7L2U65OcLCDtirnsoJUg7Lus65+87JeQ7IScIOu2iOydvOy5mCDrsJzsg53tlaAg65WMIO2ZleyduFxuICAgICAgICBjb25zdCBlbnRpdHlDb2x1bW4gPSBlbnRpdHlTZXQuY29sdW1ucy5maW5kKFxuICAgICAgICAgIChjb2wpID0+IGNvbC5uYW1lID09PSBcInByaWNlX2tyd1wiXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGRiQ29sdW1uID0gZGJTZXQuY29sdW1ucy5maW5kKFxuICAgICAgICAgIChjb2wpID0+IGNvbC5uYW1lID09PSBcInByaWNlX2tyd1wiXG4gICAgICAgICk7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoeyBlbnRpdHlDb2x1bW4sIGRiQ29sdW1uIH0pO1xuICAgICAgICAgKi9cblxuICBjb25zdCBlbnRpdHlJbmRleGVzID0gYWxwaGFiZXRpY2FsKGVudGl0eVNldC5pbmRleGVzLCAoYSkgPT5cbiAgICBbYS50eXBlLCAuLi5hLmNvbHVtbnNdLmpvaW4oXCItXCIpLFxuICApO1xuICBjb25zdCBkYkluZGV4ZXMgPSBhbHBoYWJldGljYWwoZGJTZXQuaW5kZXhlcywgKGEpID0+XG4gICAgW2EudHlwZSwgLi4uYS5jb2x1bW5zXS5qb2luKFwiLVwiKSxcbiAgKTtcblxuICBjb25zdCByZXBsYWNlTm9BY3Rpb25Pbk15U1FMID0gKGY6IE1pZ3JhdGlvbkZvcmVpZ24pID0+IHtcbiAgICAvLyBNeVNRTOyXkOyEnCBSRVNUUklDVOyZgCBOTyBBQ1RJT07snYAg64+Z7J287ZWoXG4gICAgY29uc3QgeyBvbkRlbGV0ZSwgb25VcGRhdGUgfSA9IGY7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmYsXG4gICAgICBvblVwZGF0ZTogb25VcGRhdGUgPT09IFwiUkVTVFJJQ1RcIiA/IFwiTk8gQUNUSU9OXCIgOiBvblVwZGF0ZSxcbiAgICAgIG9uRGVsZXRlOiBvbkRlbGV0ZSA9PT0gXCJSRVNUUklDVFwiID8gXCJOTyBBQ1RJT05cIiA6IG9uRGVsZXRlLFxuICAgIH07XG4gIH07XG5cbiAgY29uc3QgZW50aXR5Rm9yZWlnbnMgPSBhbHBoYWJldGljYWwoZW50aXR5U2V0LmZvcmVpZ25zLCAoYSkgPT5cbiAgICBbYS50bywgLi4uYS5jb2x1bW5zXS5qb2luKFwiLVwiKSxcbiAgKS5tYXAoKGYpID0+IHJlcGxhY2VOb0FjdGlvbk9uTXlTUUwoZikpO1xuICBjb25zdCBkYkZvcmVpZ25zID0gYWxwaGFiZXRpY2FsKGRiU2V0LmZvcmVpZ25zLCAoYSkgPT4gW2EudG8sIC4uLmEuY29sdW1uc10uam9pbihcIi1cIikpLm1hcCgoZikgPT5cbiAgICByZXBsYWNlTm9BY3Rpb25Pbk15U1FMKGYpLFxuICApO1xuXG4gIC8vIOyCreygnOuQoCDsu6zrn7wg66qp66GdIOqzhOyCsFxuICBjb25zdCBkcm9wcGluZ0NvbHVtbnMgPSBkaWZmKGRiQ29sdW1ucywgZW50aXR5Q29sdW1ucywgKGNvbCkgPT4gY29sLm5hbWUpO1xuXG4gIGNvbnN0IGFsdGVyQ29kZXM6IChHZW5NaWdyYXRpb25Db2RlIHwgR2VuTWlncmF0aW9uQ29kZVtdIHwgbnVsbClbXSA9IFtdO1xuXG4gIC8vIDEuIGNvbHVtbnNBbmRJbmRleGVzIOyymOumrFxuICBjb25zdCBpc0VxdWFsQ29sdW1ucyA9IGVxdWFsKGVudGl0eUNvbHVtbnMsIGRiQ29sdW1ucyk7XG4gIGNvbnN0IGlzRXF1YWxJbmRleGVzID0gZXF1YWwoXG4gICAgZW50aXR5SW5kZXhlcy5tYXAoKGluZGV4KSA9PiBvbWl0KGluZGV4LCBbXCJwYXJzZXJcIl0pKSxcbiAgICBkYkluZGV4ZXMsXG4gICk7XG4gIGlmICghaXNFcXVhbENvbHVtbnMgfHwgIWlzRXF1YWxJbmRleGVzKSB7XG4gICAgYWx0ZXJDb2Rlcy5wdXNoKFxuICAgICAgYXdhaXQgZ2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlDb2x1bW5zLFxuICAgICAgICBlbnRpdHlJbmRleGVzLFxuICAgICAgICBkYkNvbHVtbnMsXG4gICAgICAgIGRiSW5kZXhlcyxcbiAgICAgICAgZGJTZXQuZm9yZWlnbnMsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvLyAyLiBmb3JlaWducyDsspjrpqwgKOyCreygnOuQoCDsu6zrn7wg7KCV67O0IOyghOuLrClcbiAgaWYgKGVxdWFsKGVudGl0eUZvcmVpZ25zLCBkYkZvcmVpZ25zKSA9PT0gZmFsc2UpIHtcbiAgICBhbHRlckNvZGVzLnB1c2goXG4gICAgICBhd2FpdCBnZW5lcmF0ZUFsdGVyQ29kZV9Gb3JlaWducyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlGb3JlaWducyxcbiAgICAgICAgZGJGb3JlaWducyxcbiAgICAgICAgZHJvcHBpbmdDb2x1bW5zLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgaWYgKGFsdGVyQ29kZXMuZXZlcnkoKGFsdGVyQ29kZSkgPT4gYWx0ZXJDb2RlID09PSBudWxsKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBhbHRlckNvZGVzLmZpbHRlcigoYWx0ZXJDb2RlKSA9PiBhbHRlckNvZGUgIT09IG51bGwpLmZsYXQoKTtcbn1cbiJdLCJuYW1lcyI6WyJlcXVhbCIsImFscGhhYmV0aWNhbCIsImRpZmYiLCJmb3JrIiwib21pdCIsIk5haXRlIiwiZm9ybWF0Q29kZSIsImRpZmZlcmVuY2VXaXRoIiwiaW50ZXJzZWN0aW9uQnkiLCJnZW5lcmF0ZUNyZWF0ZUNvZGVfQ29sdW1uQW5kSW5kZXhlcyIsInRhYmxlIiwiY29sdW1ucyIsImluZGV4ZXMiLCJuZ3JhbUluZGV4ZXMiLCJzdGFuZGFyZEluZGV4ZXMiLCJpIiwidHlwZSIsInBhcnNlciIsImxpbmVzIiwiZ2VuQ29sdW1uRGVmaW5pdGlvbnMiLCJtYXAiLCJpbmRleCIsImdlbkluZGV4RGVmaW5pdGlvbiIsInRpdGxlIiwiZm9ybWF0dGVkIiwiam9pbiIsImNvbHVtbiIsImNoYWlucyIsIm5hbWUiLCJlbmRzV2l0aCIsImVsZW1lbnRUeXBlIiwic2xpY2UiLCJwZ1R5cGUiLCJnZXRQZ0FycmF5VHlwZSIsInB1c2giLCJudW1iZXJUeXBlIiwicHJlY2lzaW9uIiwic2NhbGUiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJleHRyYVR5cGUiLCJudWxsYWJsZSIsImRlZmF1bHRUbyIsInN0YXJ0c1dpdGgiLCJFcnJvciIsIm1ldGhvZE1hcCIsImZ1bGx0ZXh0IiwidW5pcXVlIiwiY29sIiwiZ2VuZXJhdGVDcmVhdGVDb2RlX0ZvcmVpZ24iLCJmb3JlaWducyIsInVwIiwiZG93biIsImdlbkZvcmVpZ25EZWZpbml0aW9ucyIsImNvbnNvbGUiLCJsb2ciLCJmb3JlaWduS2V5c1N0cmluZyIsImZvcmVpZ24iLCJyZWR1Y2UiLCJyIiwiY29sdW1uc1N0cmluZ1F1b3RlIiwicmVwbGFjZSIsInRvIiwib25VcGRhdGUiLCJvbkRlbGV0ZSIsImdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXMiLCJlbnRpdHlDb2x1bW5zIiwiZW50aXR5SW5kZXhlcyIsImRiQ29sdW1ucyIsImRiSW5kZXhlcyIsImRiRm9yZWlnbnMiLCJhbHRlckNvbHVtbnNUbyIsImdldEFsdGVyQ29sdW1uc1RvIiwiYWx0ZXJDb2x1bW5MaW5lc1RvIiwiZ2V0QWx0ZXJDb2x1bW5MaW5lc1RvIiwiYWx0ZXJJbmRleGVzVG8iLCJnZXRBbHRlckluZGV4ZXNUbyIsImFkZCIsImluZGV4TmVlZHNUb0Ryb3AiLCJkcm9wIiwiZmlsdGVyIiwiZXZlcnkiLCJjb2xOYW1lIiwiaW5jbHVkZXMiLCJhbHRlciIsInQiLCJnZW5JbmRleERyb3BEZWZpbml0aW9uIiwiYWN0aW9uIiwibGVuIiwicGFydCIsImNvbHVtbnNUbyIsImV4dHJhQ29sdW1ucyIsImRiIiwiZW50aXR5IiwiY29uY2F0Iiwic2FtZURiQ29sdW1ucyIsInNhbWVNZENvbHVtbnMiLCJhIiwiYiIsImxpbmVzVG8iLCJkcm9wQ29sdW1uTmFtZXMiLCJma1RvRHJvcEJlZm9yZUNvbHVtbiIsImZrIiwic29tZSIsImRyb3BGa0xpbmVzIiwicmVzdG9yZUZrTGluZXMiLCJkYkNvbHVtbiIsImVudGl0eUNvbHVtbiIsImZpbmQiLCJjb2x1bW5EaWZmVXAiLCJjb2x1bW5EaWZmRG93biIsImwiLCJpbmRleGVzVG8iLCJleHRyYUluZGV4ZXMiLCJjb2x1bW5OYW1lIiwiZ2VuZXJhdGVBbHRlckNvZGVfRm9yZWlnbnMiLCJlbnRpdHlGb3JlaWducyIsImRyb3BwaW5nQ29sdW1ucyIsImdldEtleSIsIm1mIiwiZHJvcHBpbmdDb2x1bW5OYW1lcyIsImZrVG8iLCJyZXN1bHQiLCJlbnRpdHlGIiwibWF0Y2hpbmdEYkYiLCJkYkYiLCJhbHRlclNyYyIsImFsdGVyRHN0IiwiZm9yRWFjaCIsIm1hdGNoaW5nRW50aXR5RiIsImlzQ29sdW1uRHJvcHBpbmciLCJoYXNMaW5lcyIsIk9iamVjdCIsInZhbHVlcyIsImdlbmVyYXRlQ3JlYXRlQ29kZSIsImVudGl0eVNldCIsImdlbmVyYXRlQWx0ZXJDb2RlIiwiZGJTZXQiLCJyZXBsYWNlQ29sdW1uRGVmYXVsdFRvIiwicmVwbGFjZU5vQWN0aW9uT25NeVNRTCIsImYiLCJhbHRlckNvZGVzIiwiaXNFcXVhbENvbHVtbnMiLCJpc0VxdWFsSW5kZXhlcyIsImFsdGVyQ29kZSIsImZsYXQiXSwibWFwcGluZ3Mi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
807
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb24vY29kZS1nZW5lcmF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBlcXVhbCBmcm9tIFwiZmFzdC1kZWVwLWVxdWFsXCI7XG5pbXBvcnQgeyBhbHBoYWJldGljYWwsIGRpZmYsIG9taXQgfSBmcm9tIFwicmFkYXNoaVwiO1xuaW1wb3J0IHsgTmFpdGUgfSBmcm9tIFwiLi5cIjtcbmltcG9ydCB0eXBlIHtcbiAgR2VuTWlncmF0aW9uQ29kZSxcbiAgTWlncmF0aW9uQ29sdW1uLFxuICBNaWdyYXRpb25Gb3JlaWduLFxuICBNaWdyYXRpb25JbmRleCxcbiAgTWlncmF0aW9uU2V0LFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBkaWZmZXJlbmNlV2l0aCwgaW50ZXJzZWN0aW9uQnkgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcblxuLyoqXG4gKiDsu6zrn7wg7KCV7J2YIOqysOqzvCDtg4DsnoVcbiAqIC0gYnVpbGRlcjogS25leCB0YWJsZSBidWlsZGVyIOuplOyEnOuTnOuhnCDsi6TtlontlaAg6rWs66y4ICh0YWJsZS54eHgoKSlcbiAqIC0gcmF3OiBrbmV4LnJhdygp66GcIOyLpO2Wie2VoCDqtazrrLhcbiAqL1xudHlwZSBDb2x1bW5EZWZpbml0aW9uUmVzdWx0ID0ge1xuICBidWlsZGVyOiBzdHJpbmdbXTtcbiAgcmF3OiBzdHJpbmdbXTtcbn07XG5cbi8qKlxuICog7YWM7J2067iUIOyDneyEse2VmOuKlCDsvIDsnbTsiqQgLSDsu6zrn7wv7J24642x7IqkIOyDneyEsVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNyZWF0ZUNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgdGFibGU6IHN0cmluZyxcbiAgY29sdW1uczogTWlncmF0aW9uQ29sdW1uW10sXG4gIGluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10sXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGU+IHtcbiAgY29uc3QgY29sdW1uRGVmcyA9IGdlbkNvbHVtbkRlZmluaXRpb25zKHRhYmxlLCBjb2x1bW5zKTtcblxuICAvLyDsu6zrn7wsIOyduOuNseyKpCDsspjrpqxcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW1xuICAgICdpbXBvcnQgeyBLbmV4IH0gZnJvbSBcImtuZXhcIjsnLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gdXAoa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGBhd2FpdCBrbmV4LnNjaGVtYS5jcmVhdGVUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLi4uY29sdW1uRGVmcy5idWlsZGVyLFxuICAgIFwifSk7XCIsXG4gICAgLy8gcmF3IOq1rOusuCAoR2VuZXJhdGVkIENvbHVtbiDrk7EpXG4gICAgLi4uY29sdW1uRGVmcy5yYXcsXG4gICAgLy8gaW5kZXjripQga25leC5yYXfroZwg7LKY66as7ZWY66+A66GcIGNyZWF0ZVRhYmxlIOuwluyXkOyEnCDsi6TtlolcbiAgICAuLi5pbmRleGVzLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICBcIn1cIixcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvd24oa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGAgcmV0dXJuIGtuZXguc2NoZW1hLmRyb3BUYWJsZShcIiR7dGFibGV9XCIpO2AsXG4gICAgXCJ9XCIsXG4gIF07XG4gIHJldHVybiB7XG4gICAgdGFibGUsXG4gICAgdHlwZTogXCJub3JtYWxcIixcbiAgICB0aXRsZTogYGNyZWF0ZV9fJHt0YWJsZX1gLFxuICAgIGZvcm1hdHRlZDogZm9ybWF0Q29kZShsaW5lcy5qb2luKFwiXFxuXCIpLCBcInR5cGVzY3JpcHRcIiwgYHNyYy9taWdyYXRpb24vJHt0YWJsZX0udHNgKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBNaWdyYXRpb25Db2x1bW5bXSDsnb3slrTshJwg7Lus65+8IOygleydmO2VmOuKlCDqtazrrLgg7IOd7ISxXG4gKiBAcmV0dXJucyBidWlsZGVyOiB0YWJsZSBidWlsZGVyIOuplOyEnOuTnCwgcmF3OiBrbmV4LnJhdygpIOq1rOusuFxuICovXG5mdW5jdGlvbiBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZTogc3RyaW5nLCBjb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSk6IENvbHVtbkRlZmluaXRpb25SZXN1bHQge1xuICBjb25zdCByZXN1bHQ6IENvbHVtbkRlZmluaXRpb25SZXN1bHQgPSB7XG4gICAgYnVpbGRlcjogW10sXG4gICAgcmF3OiBbXSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2x1bW5zKSB7XG4gICAgLy8gR2VuZXJhdGVkIENvbHVtbuydgCByYXfroZwg7LKY66asXG4gICAgaWYgKGNvbHVtbi5nZW5lcmF0ZWQpIHtcbiAgICAgIHJlc3VsdC5yYXcucHVzaChnZW5HZW5lcmF0ZWRDb2x1bW5EZWZpbml0aW9uKHRhYmxlLCBjb2x1bW4pKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIOydvOuwmCDsu6zrn7zsnYAgYnVpbGRlcuuhnCDsspjrpqxcbiAgICByZXN1bHQuYnVpbGRlci5wdXNoKGdlbk5vcm1hbENvbHVtbkRlZmluaXRpb24oY29sdW1uKSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlZCBDb2x1bW4g7KCV7J2YIOyDneyEsSAoQUxURVIgVEFCTEUgQUREIENPTFVNTiDsgqzsmqkpXG4gKi9cbmZ1bmN0aW9uIGdlbkdlbmVyYXRlZENvbHVtbkRlZmluaXRpb24odGFibGU6IHN0cmluZywgY29sdW1uOiBNaWdyYXRpb25Db2x1bW4pOiBzdHJpbmcge1xuICBpZiAoIWNvbHVtbi5nZW5lcmF0ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJHZW5lcmF0ZWQgY29sdW1uIGRlZmluaXRpb24gcmVxdWlyZWRcIik7XG4gIH1cbiAgY29uc3QgcGdUeXBlID0gZ2V0UGdUeXBlRm9yQ29sdW1uKGNvbHVtbik7XG4gIGNvbnN0IHN0b3JhZ2VUeXBlID0gY29sdW1uLmdlbmVyYXRlZC50eXBlID09PSBcIlZJUlRVQUxcIiA/IFwiIFZJUlRVQUxcIiA6IFwiIFNUT1JFRFwiO1xuICBjb25zdCBudWxsYWJsZUNsYXVzZSA9IGNvbHVtbi5udWxsYWJsZSA/IFwiXCIgOiBcIiBOT1QgTlVMTFwiO1xuICByZXR1cm4gYGF3YWl0IGtuZXgucmF3KFxcYEFMVEVSIFRBQkxFIFwiJHt0YWJsZX1cIiBBREQgQ09MVU1OIFwiJHtjb2x1bW4ubmFtZX1cIiAke3BnVHlwZX0gR0VORVJBVEVEIEFMV0FZUyBBUyAoJHtjb2x1bW4uZ2VuZXJhdGVkLmV4cHJlc3Npb259KSR7c3RvcmFnZVR5cGV9JHtudWxsYWJsZUNsYXVzZX1cXGApO2A7XG59XG5cbi8qKlxuICog7J2867CYIOy7rOufvCDsoJXsnZgg7IOd7ISxICh0YWJsZS54eHgoKSDssrTsnbgpXG4gKi9cbmZ1bmN0aW9uIGdlbk5vcm1hbENvbHVtbkRlZmluaXRpb24oY29sdW1uOiBNaWdyYXRpb25Db2x1bW4pOiBzdHJpbmcge1xuICBjb25zdCBjaGFpbnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGNvbHVtbi5uYW1lID09PSBcImlkXCIpIHtcbiAgICByZXR1cm4gYHRhYmxlLmluY3JlbWVudHMoKS5wcmltYXJ5KCk7YDtcbiAgfVxuXG4gIC8vIOuwsOyXtCDtg4DsnoUg7LKY66asXG4gIGlmIChjb2x1bW4udHlwZS5lbmRzV2l0aChcIltdXCIpKSB7XG4gICAgY29uc3QgZWxlbWVudFR5cGUgPSBjb2x1bW4udHlwZS5zbGljZSgwLCAtMik7IC8vIFwiaW50ZWdlcltdXCIgLT4gXCJpbnRlZ2VyXCJcbiAgICBjb25zdCBwZ1R5cGUgPSBnZXRQZ0FycmF5VHlwZShjb2x1bW4sIGVsZW1lbnRUeXBlKTtcbiAgICBjaGFpbnMucHVzaChgc3BlY2lmaWNUeXBlKCcke2NvbHVtbi5uYW1lfScsICcke3BnVHlwZX0nKWApO1xuICB9IGVsc2UgaWYgKGNvbHVtbi50eXBlID09PSBcInZlY3RvclwiKSB7XG4gICAgLy8gS25leOuKlCB2ZWN0b3Ig7YOA7J6F7J2EIOyngeygkSDsp4Dsm5DtlZjsp4Ag7JWK7Jy866+A66GcIHNwZWNpZmljVHlwZSDsgqzsmqlcbiAgICBjaGFpbnMucHVzaChgc3BlY2lmaWNUeXBlKCcke2NvbHVtbi5uYW1lfScsICd2ZWN0b3IoJHtjb2x1bW4uZGltZW5zaW9uc30pJylgKTtcbiAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gXCJudW1iZXJPck51bWVyaWNcIikge1xuICAgIC8vIG51bWJlclxuICAgIGlmIChjb2x1bW4ubnVtYmVyVHlwZSA9PT0gXCJyZWFsXCIpIHtcbiAgICAgIGNoYWlucy5wdXNoKGBmbG9hdCgnJHtjb2x1bW4ubmFtZX0nKWApO1xuICAgIH0gZWxzZSBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSB7XG4gICAgICBjaGFpbnMucHVzaChgZG91YmxlKCcke2NvbHVtbi5uYW1lfScpYCk7XG4gICAgfSBlbHNlIGlmICgoY29sdW1uLm51bWJlclR5cGUgPz8gXCJudW1lcmljXCIpID09PSBcIm51bWVyaWNcIikge1xuICAgICAgY2hhaW5zLnB1c2goYGRlY2ltYWwoJyR7Y29sdW1uLm5hbWV9JywgJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KWApO1xuICAgIH1cbiAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIC8vIHN0cmluZ1xuICAgIGlmIChjb2x1bW4ubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNoYWlucy5wdXNoKGBzdHJpbmcoJyR7Y29sdW1uLm5hbWV9JywgJHtjb2x1bW4ubGVuZ3RofSlgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2hhaW5zLnB1c2goYHRleHQoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwiZGF0ZVwiKSB7XG4gICAgLy8gZGF0ZVxuICAgIGNoYWlucy5wdXNoKGB0aW1lc3RhbXAoJyR7Y29sdW1uLm5hbWV9JywgeyB1c2VUejogdHJ1ZSB9KWApO1xuICB9IGVsc2UgaWYgKGNvbHVtbi50eXBlID09PSBcImpzb25cIikge1xuICAgIC8vIGpzb25cbiAgICBjaGFpbnMucHVzaChganNvbmIoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB0eXBlLCBsZW5ndGhcbiAgICBsZXQgZXh0cmFUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgY2hhaW5zLnB1c2goXG4gICAgICBgJHtjb2x1bW4udHlwZX0oJyR7Y29sdW1uLm5hbWV9JyR7XG4gICAgICAgIGNvbHVtbi5sZW5ndGggPyBgLCAke2NvbHVtbi5sZW5ndGh9YCA6IFwiXCJcbiAgICAgIH0ke2V4dHJhVHlwZSA/IGAsICcke2V4dHJhVHlwZX0nYCA6IFwiXCJ9KWAsXG4gICAgKTtcbiAgfVxuXG4gIC8vIG51bGxhYmxlXG4gIGNoYWlucy5wdXNoKGNvbHVtbi5udWxsYWJsZSA/IFwibnVsbGFibGUoKVwiIDogXCJub3ROdWxsYWJsZSgpXCIpO1xuXG4gIC8vIGRlZmF1bHRUb1xuICBpZiAoY29sdW1uLmRlZmF1bHRUbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBjb2x1bW4uZGVmYXVsdFRvID09PSBcInN0cmluZ1wiICYmIGNvbHVtbi5kZWZhdWx0VG8uc3RhcnRzV2l0aChgXCJgKSkge1xuICAgICAgY2hhaW5zLnB1c2goYGRlZmF1bHRUbygke2NvbHVtbi5kZWZhdWx0VG99KWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaGFpbnMucHVzaChgZGVmYXVsdFRvKGtuZXgucmF3KCcke2NvbHVtbi5kZWZhdWx0VG99JykpYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGB0YWJsZS4ke2NoYWlucy5qb2luKFwiLlwiKX07YDtcbn1cblxuLyoqXG4gKiBNaWdyYXRpb25Db2x1bW7snZgg7YOA7J6F7J2EIFBvc3RncmVTUUwg7YOA7J6FIOusuOyekOyXtOuhnCDrs4DtmZhcbiAqL1xuZnVuY3Rpb24gZ2V0UGdUeXBlRm9yQ29sdW1uKGNvbHVtbjogTWlncmF0aW9uQ29sdW1uKTogc3RyaW5nIHtcbiAgaWYgKGNvbHVtbi50eXBlLmVuZHNXaXRoKFwiW11cIikpIHtcbiAgICBjb25zdCBlbGVtZW50VHlwZSA9IGNvbHVtbi50eXBlLnNsaWNlKDAsIC0yKTtcbiAgICByZXR1cm4gZ2V0UGdBcnJheVR5cGUoY29sdW1uLCBlbGVtZW50VHlwZSk7XG4gIH1cblxuICBzd2l0Y2ggKGNvbHVtbi50eXBlKSB7XG4gICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgcmV0dXJuIGNvbHVtbi5sZW5ndGggIT09IHVuZGVmaW5lZCA/IGB2YXJjaGFyKCR7Y29sdW1uLmxlbmd0aH0pYCA6IFwidGV4dFwiO1xuICAgIGNhc2UgXCJiaWdJbnRlZ2VyXCI6XG4gICAgICByZXR1cm4gXCJiaWdpbnRcIjtcbiAgICBjYXNlIFwibnVtYmVyT3JOdW1lcmljXCI6XG4gICAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwicmVhbFwiKSByZXR1cm4gXCJyZWFsXCI7XG4gICAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSByZXR1cm4gXCJkb3VibGUgcHJlY2lzaW9uXCI7XG4gICAgICByZXR1cm4gYG51bWVyaWMoJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KWA7XG4gICAgY2FzZSBcImRhdGVcIjpcbiAgICAgIHJldHVybiBcInRpbWVzdGFtcHR6XCI7XG4gICAgY2FzZSBcImpzb25cIjpcbiAgICAgIHJldHVybiBcImpzb25iXCI7XG4gICAgY2FzZSBcInZlY3RvclwiOlxuICAgICAgcmV0dXJuIGB2ZWN0b3IoJHtjb2x1bW4uZGltZW5zaW9uc30pYDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGNvbHVtbi50eXBlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFBnQXJyYXlUeXBlKGNvbHVtbjogTWlncmF0aW9uQ29sdW1uLCBlbGVtZW50VHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcIm51bWJlck9yTnVtZXJpY1wiKSB7XG4gICAgaWYgKGNvbHVtbi5udW1iZXJUeXBlID09PSBcInJlYWxcIikgcmV0dXJuIFwicmVhbFtdXCI7XG4gICAgaWYgKGNvbHVtbi5udW1iZXJUeXBlID09PSBcImRvdWJsZSBwcmVjaXNpb25cIikgcmV0dXJuIFwiZG91YmxlIHByZWNpc2lvbltdXCI7XG4gICAgcmV0dXJuIGBudW1lcmljKCR7Y29sdW1uLnByZWNpc2lvbn0sICR7Y29sdW1uLnNjYWxlfSlbXWA7XG4gIH1cbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIGNvbHVtbi5sZW5ndGggPyBgdmFyY2hhcigke2NvbHVtbi5sZW5ndGh9KVtdYCA6IFwidGV4dFtdXCI7XG4gIH1cbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcImRhdGVcIikgcmV0dXJuIFwidGltZXN0YW1wdHpbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiaW50ZWdlclwiKSByZXR1cm4gXCJpbnRlZ2VyW11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcImJpZ0ludGVnZXJcIikgcmV0dXJuIFwiYmlnaW50W11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcImJvb2xlYW5cIikgcmV0dXJuIFwiYm9vbGVhbltdXCI7XG4gIGlmIChlbGVtZW50VHlwZSA9PT0gXCJ1dWlkXCIpIHJldHVybiBcInV1aWRbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiZW51bVwiKSByZXR1cm4gXCJ0ZXh0W11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcInZlY3RvclwiKSByZXR1cm4gYHZlY3Rvcigke2NvbHVtbi5kaW1lbnNpb25zfSlbXWA7XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGFycmF5IGVsZW1lbnQgdHlwZTogJHtlbGVtZW50VHlwZX1gKTtcbn1cblxuLyoqXG4gKiDqsJzrs4Qg7J24642x7IqkIOygleydmCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4OiBNaWdyYXRpb25JbmRleCwgdGFibGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChpbmRleC50eXBlID09PSBcImhuc3dcIiB8fCBpbmRleC50eXBlID09PSBcIml2ZmZsYXRcIikge1xuICAgIHJldHVybiBnZW5WZWN0b3JJbmRleERlZmluaXRpb24oaW5kZXgsIHRhYmxlKTtcbiAgfVxuXG4gIGNvbnN0IG1ldGhvZE1hcCA9IHtcbiAgICBpbmRleDogXCJJTkRFWFwiLFxuICAgIGZ1bGx0ZXh0OiBcIklOREVYXCIsXG4gICAgdW5pcXVlOiBcIlVOSVFVRSBJTkRFWFwiLFxuICB9O1xuXG4gIGNvbnN0IG51bGxzTm90RGlzdGluY3RDbGF1c2UgPVxuICAgIGluZGV4Lm51bGxzTm90RGlzdGluY3QgPT09IHVuZGVmaW5lZFxuICAgICAgPyBcIlwiXG4gICAgICA6IGAgTlVMTFMgJHtpbmRleC5udWxsc05vdERpc3RpbmN0ID8gXCJOT1QgRElTVElOQ1RcIiA6IFwiRElTVElOQ1RcIn1gO1xuXG4gIHJldHVybiBgYXdhaXQga25leC5yYXcoXG4gIFxcYENSRUFURSAke21ldGhvZE1hcFtpbmRleC50eXBlXX0gJHtpbmRleC5uYW1lfSBPTiAke3RhYmxlfSAoJHtpbmRleC5jb2x1bW5zXG4gICAgLm1hcCgoY29sKSA9PiB7XG4gICAgICBjb25zdCBzb3J0T3JkZXJDbGF1c2UgPSBjb2wuc29ydE9yZGVyID09PSB1bmRlZmluZWQgPyBcIlwiIDogYCAke2NvbC5zb3J0T3JkZXJ9YDtcbiAgICAgIGNvbnN0IG51bGxzRmlyc3RDbGF1c2UgPVxuICAgICAgICBjb2wubnVsbHNGaXJzdCA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IGAgTlVMTFMgJHtjb2wubnVsbHNGaXJzdCA/IFwiRklSU1RcIiA6IFwiTEFTVFwifWA7XG4gICAgICByZXR1cm4gYCR7Y29sLm5hbWV9JHtzb3J0T3JkZXJDbGF1c2V9JHtudWxsc0ZpcnN0Q2xhdXNlfWA7XG4gICAgfSlcbiAgICAuam9pbihcIiwgXCIpfSkke251bGxzTm90RGlzdGluY3RDbGF1c2V9O1xcYFxuICApO2A7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKiAtIEhOU1cgKEhpZXJhcmNoaWNhbCBOYXZpZ2FibGUgU21hbGwgV29ybGQpOiDripDrprAg67mM65OcLCDruaDrpbgg6rKA7IOJIOyGjeuPhCwg64aS7J2AIOuplOuqqOumrCDrsI8g7KCV7ZmV64+EXG4gKiAtIElWRkZsYXQgKEludmVydGVkIEZpbGUgd2l0aCBGbGF0IENvbXByZXNzaW9uKTog67mg66W4IOu5jOuTnCwg7KSR6rCEIOqygOyDiSDsho3rj4QsIOuCruydgCDrqZTrqqjrpqxcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSE5TVyDsnbjrjbHsiqQgKOq2jOyepSAtIOu5oOuluCDqsoDsg4ksIOuGkuydgCDsoJXtmZXrj4QpXG4gKiBDUkVBVEUgSU5ERVggaWR4X2VtYmVkZGluZyBPTiBpdGVtcyBVU0lORyBobnN3IChlbWJlZGRpbmcgdmVjdG9yX2Nvc2luZV9vcHMpIFdJVEggKG0gPSAxNiwgZWZfY29uc3RydWN0aW9uID0gNjQpO1xuICpcbiAqIC8vIElWRkZsYXQg7J24642x7IqkICjrjIDsmqnrn4kg642w7J207YSwLCDruYTsmqkg7KSR7JqUIOyLnClcbiAqIENSRUFURSBJTkRFWCBpZHhfZW1iZWRkaW5nIE9OIGl0ZW1zIFVTSU5HIGl2ZmZsYXQgKGVtYmVkZGluZyB2ZWN0b3JfY29zaW5lX29wcykgV0lUSCAobGlzdHMgPSAxMDApO1xuICovXG5mdW5jdGlvbiBnZW5WZWN0b3JJbmRleERlZmluaXRpb24oaW5kZXg6IE1pZ3JhdGlvbkluZGV4LCB0YWJsZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgY29sdW1uID0gaW5kZXguY29sdW1uc1swXTtcbiAgY29uc3QgdmVjdG9yT3BzID0gY29sdW1uLnZlY3Rvck9wcyA/PyBcInZlY3Rvcl9jb3NpbmVfb3BzXCI7XG5cbiAgLy8gSE5TVyAoSGllcmFyY2hpY2FsIE5hdmlnYWJsZSBTbWFsbCBXb3JsZCkgLSDqtozsnqU6IOu5oOuluCDqsoDsg4ksIOuGkuydgCDsoJXtmZXrj4RcbiAgaWYgKGluZGV4LnR5cGUgPT09IFwiaG5zd1wiKSB7XG4gICAgY29uc3QgbSA9IGluZGV4Lm0gPz8gMTY7XG4gICAgY29uc3QgZWZDb25zdHJ1Y3Rpb24gPSBpbmRleC5lZkNvbnN0cnVjdGlvbiA/PyA2NDtcbiAgICByZXR1cm4gYGF3YWl0IGtuZXgucmF3KFxcYENSRUFURSBJTkRFWCAke2luZGV4Lm5hbWV9IE9OICR7dGFibGV9IFVTSU5HIGhuc3cgKCR7Y29sdW1uLm5hbWV9ICR7dmVjdG9yT3BzfSkgV0lUSCAobSA9ICR7bX0sIGVmX2NvbnN0cnVjdGlvbiA9ICR7ZWZDb25zdHJ1Y3Rpb259KVxcYCk7YDtcbiAgfVxuXG4gIC8vIElWRkZsYXQgKEludmVydGVkIEZpbGUgd2l0aCBGbGF0IENvbXByZXNzaW9uKSAtIOuMgOyaqeufiSwg67mE7JqpIOykkeyalCDsi5xcbiAgaWYgKGluZGV4LnR5cGUgPT09IFwiaXZmZmxhdFwiKSB7XG4gICAgY29uc3QgbGlzdHMgPSBpbmRleC5saXN0cyA/PyAxMDA7XG4gICAgcmV0dXJuIGBhd2FpdCBrbmV4LnJhdyhcXGBDUkVBVEUgSU5ERVggJHtpbmRleC5uYW1lfSBPTiAke3RhYmxlfSBVU0lORyBpdmZmbGF0ICgke2NvbHVtbi5uYW1lfSAke3ZlY3Rvck9wc30pIFdJVEggKGxpc3RzID0gJHtsaXN0c30pXFxgKTtgO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHJhdyBTUUwgaW5kZXggdHlwZTogJHtpbmRleC50eXBlfWApO1xufVxuXG4vKipcbiAqIO2FjOydtOu4lCDsg53shLHtlZjripQg7LyA7J207IqkIC0gRksg7IOd7ISxXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ3JlYXRlQ29kZV9Gb3JlaWduKFxuICB0YWJsZTogc3RyaW5nLFxuICBmb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuKTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgaWYgKGZvcmVpZ25zLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHsgdXAsIGRvd24gfSA9IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZm9yZWlnbnMpO1xuICBpZiAodXAubGVuZ3RoID09PSAwICYmIGRvd24ubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJmayDqsIAg662U6rCAIOuLpOumheuLiOuLpFwiKTtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXG4gICAgJ2ltcG9ydCB7IEtuZXggfSBmcm9tIFwia25leFwiOycsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cChrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYHJldHVybiBrbmV4LnNjaGVtYS5hbHRlclRhYmxlKFwiJHt0YWJsZX1cIiwgKHRhYmxlKSA9PiB7YCxcbiAgICBcIi8vIGNyZWF0ZSBma1wiLFxuICAgIC4uLnVwLFxuICAgIFwifSk7XCIsXG4gICAgXCJ9XCIsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb3duKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgcmV0dXJuIGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLFxuICAgIFwiLy8gZHJvcCBma1wiLFxuICAgIC4uLmRvd24sXG4gICAgXCJ9KTtcIixcbiAgICBcIn1cIixcbiAgXTtcblxuICBjb25zdCBmb3JlaWduS2V5c1N0cmluZyA9IGZvcmVpZ25zLm1hcCgoZm9yZWlnbikgPT4gZm9yZWlnbi5jb2x1bW5zLmpvaW4oXCJfXCIpKS5qb2luKFwiX1wiKTtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0YWJsZSxcbiAgICAgIHR5cGU6IFwiZm9yZWlnblwiLFxuICAgICAgdGl0bGU6IGBmb3JlaWduX18ke3RhYmxlfV9fJHtmb3JlaWduS2V5c1N0cmluZ31gLFxuICAgICAgZm9ybWF0dGVkOiBmb3JtYXRDb2RlKGxpbmVzLmpvaW4oXCJcXG5cIiksIFwidHlwZXNjcmlwdFwiLCBgc3JjL21pZ3JhdGlvbi8ke3RhYmxlfS50c2ApLFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICogTWlncmF0aW9uRm9yZWlnbltdIOydveyWtOyEnCDsmbjrtoDtgqQgY29uc3RyYWludCDsoJXsnZjtlZjripQg6rWs66y4IOyDneyEsVxuICovXG5mdW5jdGlvbiBnZW5Gb3JlaWduRGVmaW5pdGlvbnMoXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGZvcmVpZ25zOiBNaWdyYXRpb25Gb3JlaWduW10sXG4pOiB7IHVwOiBzdHJpbmdbXTsgZG93bjogc3RyaW5nW10gfSB7XG4gIHJldHVybiBmb3JlaWducy5yZWR1Y2UoXG4gICAgKHIsIGZvcmVpZ24pID0+IHtcbiAgICAgIGNvbnN0IGNvbHVtbnNTdHJpbmdRdW90ZSA9IGZvcmVpZ24uY29sdW1uc1xuICAgICAgICAubWFwKChjb2wpID0+IGAnJHtjb2wucmVwbGFjZShgJHt0YWJsZX0uYCwgXCJcIil9J2ApXG4gICAgICAgIC5qb2luKFwiLFwiKTtcbiAgICAgIHIudXAucHVzaChcbiAgICAgICAgYHRhYmxlLmZvcmVpZ24oJyR7Zm9yZWlnbi5jb2x1bW5zLmpvaW4oXCIsXCIpfScpXG4gICAgICAgICAgICAucmVmZXJlbmNlcygnJHtmb3JlaWduLnRvfScpXG4gICAgICAgICAgICAub25VcGRhdGUoJyR7Zm9yZWlnbi5vblVwZGF0ZX0nKVxuICAgICAgICAgICAgLm9uRGVsZXRlKCcke2ZvcmVpZ24ub25EZWxldGV9JylgLFxuICAgICAgKTtcbiAgICAgIHIuZG93bi5wdXNoKGB0YWJsZS5kcm9wRm9yZWlnbihbJHtjb2x1bW5zU3RyaW5nUXVvdGV9XSlgKTtcbiAgICAgIHJldHVybiByO1xuICAgIH0sXG4gICAge1xuICAgICAgdXA6IFtdIGFzIHN0cmluZ1tdLFxuICAgICAgZG93bjogW10gYXMgc3RyaW5nW10sXG4gICAgfSxcbiAgKTtcbn1cblxuLyoqXG4gKiDthYzsnbTruJQg67OA6rK9IOy8gOydtOyKpCAtIOy7rOufvC/snbjrjbHsiqQg67OA6rK9XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXMoXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGVudGl0eUNvbHVtbnM6IE1pZ3JhdGlvbkNvbHVtbltdLFxuICBlbnRpdHlJbmRleGVzOiBNaWdyYXRpb25JbmRleFtdLFxuICBkYkNvbHVtbnM6IE1pZ3JhdGlvbkNvbHVtbltdLFxuICBkYkluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10sXG4gIGRiRm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbik6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZVtdPiB7XG4gIC8qXG4gICAg7IS467aAIOu5hOq1kCDtm4Qg64uk66W47KCQIOywvuyVhOyEnCDsvZTrk5wg7IOd7ISxXG5cbiAgICAxLiDsu6zrn7zqsK/siJgg64uk66aEOiBNROyXkCDsnojsnLzrgpgsIERC7JeQIOyXhuuLpOuptCDstpTqsIBcbiAgICAyLiDsu6zrn7zqsK/siJgg64uk66aEOiBNROyXkCDsl4bsnLzrgpgsIERC7JeQIOyeiOuLpOuptCDsgq3soJxcbiAgICAzLiDqt7jsmbgg7Lus65+8KOy7rOufvCDqsK/siJjqsIAg64+Z7J287ZWY6rGw64KYLCDri6Trpbgg6rK97JqwIOuPmeydvO2VnCDsu6zrn7zrgbzrpqwpID0+IGFsdGVyXG4gICAgNC4g64uk66W46rGwIOuLpCDrj5nsnbztlZjqs6AgaW5kZXjrp4wg67OA6rK965CY64qUIOqyveyasFxuXG4gICAgKiog7Lus65+866qF7J2EIOuzgOqyve2VmOuKlCDqsr3smrDripQg65Sw66GcIO2VuOuTpOunge2VmOyngCDslYrsnYxcbiAgICA9PiBkcm9wL2FkZCDtmJXtg5zsnZgg66eI7J206re466CI7J207IWYIOy9lOuTnOqwgCDsg53shLHrkJjripTrjbAsIOyImOuPmeycvOuhnCByZW5hbWUg7L2U65Oc66GcIOyImOygle2VmOyXrCDsspjrpqxcbiAgKi9cblxuICAvLyDqsIEg7Lus65+8IOydtOumhCDquLDspIDsnLzroZwgYWRkLCBkcm9wLCBhbHRlciDsl6zrtoAg7ZmV7J24XG4gIGNvbnN0IGFsdGVyQ29sdW1uc1RvID0gZ2V0QWx0ZXJDb2x1bW5zVG8oZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zKTtcblxuICAvLyDstpTstpzrkJwg7Lus65+865Ok7J2EIOq4sOykgOycvOuhnCDqsIHqsIEg65287J24IOyDneyEsVxuICBjb25zdCBhbHRlckNvbHVtbkxpbmVzVG8gPSBnZXRBbHRlckNvbHVtbkxpbmVzVG8oXG4gICAgYWx0ZXJDb2x1bW5zVG8sXG4gICAgZW50aXR5Q29sdW1ucyxcbiAgICB0YWJsZSxcbiAgICBkYkZvcmVpZ25zLFxuICApO1xuXG4gIC8vIOyduOuNseyKpOydmCBhZGQsIGRyb3Ag7Jes67aAIO2ZleyduFxuICBjb25zdCBhbHRlckluZGV4ZXNUbyA9IGdldEFsdGVySW5kZXhlc1RvKGVudGl0eUluZGV4ZXMsIGRiSW5kZXhlcyk7XG5cbiAgLy8g7J24642x7Iqk6rCAIOyCreygnOuQmOuKlCDqsr3smrAsIOy7rOufvOqzvCDqsJnsnbQg7IKt7KCc65CcIOy8gOydtOyKpOyXkOuKlCBkcm9w7JeQ7IScIOygnOyZuO2VtOyVvO2VqCFcbiAgY29uc3QgaW5kZXhOZWVkc1RvRHJvcCA9IGFsdGVySW5kZXhlc1RvLmRyb3AuZmlsdGVyKFxuICAgIChpbmRleCkgPT5cbiAgICAgIGluZGV4LmNvbHVtbnMuZXZlcnkoKHsgbmFtZSB9KSA9PlxuICAgICAgICBhbHRlckNvbHVtbnNUby5kcm9wLm1hcCgoY29sKSA9PiBjb2wubmFtZSkuaW5jbHVkZXMobmFtZSksXG4gICAgICApID09PSBmYWxzZSxcbiAgKTtcblxuICAvLyDruYgg7L2U65OcIOyDneyEsSDrsKnsp4BcbiAgY29uc3QgaGFzVXBDaGFuZ2VzID1cbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uYWRkLnVwLmJ1aWxkZXIubGVuZ3RoID4gMCB8fFxuICAgIGFsdGVyQ29sdW1uTGluZXNUby5hZGQudXAucmF3Lmxlbmd0aCA+IDAgfHxcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5idWlsZGVyLmxlbmd0aCA+IDAgfHxcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uYWx0ZXIudXAuYnVpbGRlci5sZW5ndGggPiAwIHx8XG4gICAgYWx0ZXJJbmRleGVzVG8uYWRkLmxlbmd0aCA+IDAgfHxcbiAgICBpbmRleE5lZWRzVG9Ecm9wLmxlbmd0aCA+IDA7XG4gIGlmICghaGFzVXBDaGFuZ2VzKSB7XG4gICAgTmFpdGUudChcIm1pZ3JhdG9yOmdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXM6ZW1wdHlDb2RlR2VuZXJhdGlvbkVycm9yXCIsIHtcbiAgICAgIGVudGl0eUNvbHVtbnMsXG4gICAgICBkYkNvbHVtbnMsXG4gICAgICBlbnRpdHlJbmRleGVzLFxuICAgICAgZGJJbmRleGVzLFxuICAgIH0pO1xuICAgIC8vIHRocm93IG5ldyBFcnJvcihcIuy7rOufvC/snbjrjbHsiqQg67OA6rK9IOy9lOuTnCDsg53shLEg7Jik66WYXCIpO1xuICB9XG4gIE5haXRlLnQoXCJtaWdyYXRvcjpnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVzOmRlYnVnXCIsIHtcbiAgICBcImFsdGVyQ29sdW1uc1RvLmFkZC5sZW5ndGhcIjogYWx0ZXJDb2x1bW5zVG8uYWRkLmxlbmd0aCxcbiAgICBcImFsdGVyQ29sdW1uc1RvLmRyb3AubGVuZ3RoXCI6IGFsdGVyQ29sdW1uc1RvLmRyb3AubGVuZ3RoLFxuICAgIFwiYWx0ZXJDb2x1bW5zVG8uYWx0ZXIubGVuZ3RoXCI6IGFsdGVyQ29sdW1uc1RvLmFsdGVyLmxlbmd0aCxcbiAgICBcImFsdGVySW5kZXhlc1RvLmFkZC5sZW5ndGhcIjogYWx0ZXJJbmRleGVzVG8uYWRkLmxlbmd0aCxcbiAgICBcImFsdGVySW5kZXhlc1RvLmRyb3AubGVuZ3RoXCI6IGFsdGVySW5kZXhlc1RvLmRyb3AubGVuZ3RoLFxuICAgIFwiaW5kZXhOZWVkc1RvRHJvcC5sZW5ndGhcIjogaW5kZXhOZWVkc1RvRHJvcC5sZW5ndGgsXG4gIH0pO1xuICAvLyBOYWl0ZS50KFwibWlncmF0b3I6Z2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlczphbHRlckNvbHVtbnNUb1wiLCBhbHRlckNvbHVtbnNUbyk7XG5cbiAgLy8gVE9ETzog7J24642x7Iqk66qFIOuzgOqyveuQnCDqsr3smrAg7LKY66asXG5cbiAgLy8gdGFibGUgYnVpbGRlciDrqZTshJzrk5zroZwg7Iuk7ZaJ7ZWgIOy9lOuTnCAoZHJvcCDihpIgYWRkIOKGkiBhbHRlciDsiJzshJwpXG4gIGNvbnN0IHVwQnVpbGRlckxpbmVzID0gW1xuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5idWlsZGVyLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5idWlsZGVyIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uYWRkLnVwLmJ1aWxkZXIubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5hZGQudXAuYnVpbGRlciA6IFtdKSxcbiAgICAuLi4oYWx0ZXJDb2x1bW5MaW5lc1RvLmFsdGVyLnVwLmJ1aWxkZXIubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5hbHRlci51cC5idWlsZGVyIDogW10pLFxuICAgIC4uLmluZGV4TmVlZHNUb0Ryb3AubWFwKGdlbkluZGV4RHJvcERlZmluaXRpb24pLFxuICBdO1xuXG4gIC8vIGtuZXgucmF3KCnroZwg7Iuk7ZaJ7ZWgIOy9lOuTnFxuICBjb25zdCB1cFJhd0xpbmVzID0gW1xuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uYWRkLnVwLnJhdy5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmFkZC51cC5yYXcgOiBbXSksXG4gICAgLi4uYWx0ZXJJbmRleGVzVG8uYWRkLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgXTtcblxuICAvLyBkb3du7J2AIHVw7J2YIOyXreyInCAoYWRkLmRvd24gPSBkcm9wIHJvbGxiYWNrLCBkcm9wLmRvd24gPSBhZGQgcm9sbGJhY2spXG4gIGNvbnN0IGRvd25CdWlsZGVyTGluZXMgPSBbXG4gICAgLi4uKGFsdGVyQ29sdW1uTGluZXNUby5hZGQuZG93bi5idWlsZGVyLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uYWRkLmRvd24uYnVpbGRlciA6IFtdKSxcbiAgICAuLi4oYWx0ZXJDb2x1bW5MaW5lc1RvLmFsdGVyLmRvd24uYnVpbGRlci5sZW5ndGggPiAwXG4gICAgICA/IGFsdGVyQ29sdW1uTGluZXNUby5hbHRlci5kb3duLmJ1aWxkZXJcbiAgICAgIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC5kb3duLmJ1aWxkZXIubGVuZ3RoID4gMFxuICAgICAgPyBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC5kb3duLmJ1aWxkZXJcbiAgICAgIDogW10pLFxuICAgIC4uLmFsdGVySW5kZXhlc1RvLmFkZFxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGluZGV4KSA9PlxuICAgICAgICAgIGluZGV4LmNvbHVtbnMuZXZlcnkoKGluZGV4Q29sKSA9PlxuICAgICAgICAgICAgYWx0ZXJDb2x1bW5zVG8uYWRkLm1hcCgoY29sKSA9PiBjb2wubmFtZSkuaW5jbHVkZXMoaW5kZXhDb2wubmFtZSksXG4gICAgICAgICAgKSA9PT0gZmFsc2UsXG4gICAgICApXG4gICAgICAubWFwKGdlbkluZGV4RHJvcERlZmluaXRpb24pLFxuICBdO1xuXG4gIGNvbnN0IGRvd25SYXdMaW5lcyA9IFtcbiAgICAuLi4oYWx0ZXJDb2x1bW5MaW5lc1RvLmRyb3AuZG93bi5yYXcubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5kcm9wLmRvd24ucmF3IDogW10pLFxuICAgIC4uLmluZGV4TmVlZHNUb0Ryb3AubWFwKChpbmRleCkgPT4gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4LCB0YWJsZSkpLFxuICBdO1xuXG4gIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtcbiAgICAnaW1wb3J0IHsgS25leCB9IGZyb20gXCJrbmV4XCI7JyxcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICAuLi4odXBCdWlsZGVyTGluZXMubGVuZ3RoID4gMFxuICAgICAgPyBbYGF3YWl0IGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLCAuLi51cEJ1aWxkZXJMaW5lcywgXCJ9KTtcIl1cbiAgICAgIDogW10pLFxuICAgIC4uLnVwUmF3TGluZXMsXG4gICAgXCJ9XCIsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb3duKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICAuLi4oZG93bkJ1aWxkZXJMaW5lcy5sZW5ndGggPiAwXG4gICAgICA/IFtgYXdhaXQga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsIC4uLmRvd25CdWlsZGVyTGluZXMsIFwifSk7XCJdXG4gICAgICA6IFtdKSxcbiAgICAuLi5kb3duUmF3TGluZXMsXG4gICAgXCJ9XCIsXG4gIF07XG5cbiAgY29uc3QgZm9ybWF0dGVkID0gZm9ybWF0Q29kZShsaW5lcy5qb2luKFwiXFxuXCIpLCBcInR5cGVzY3JpcHRcIiwgYHNyYy9taWdyYXRpb24vJHt0YWJsZX0udHNgKTtcbiAgY29uc3QgdGl0bGUgPSBbXG4gICAgXCJhbHRlclwiLFxuICAgIHRhYmxlLFxuICAgIC4uLihbXCJhZGRcIiwgXCJkcm9wXCIsIFwiYWx0ZXJcIl0gYXMgY29uc3QpXG4gICAgICAubWFwKChhY3Rpb24pID0+IHtcbiAgICAgICAgY29uc3QgbGVuID0gYWx0ZXJDb2x1bW5zVG9bYWN0aW9uXS5sZW5ndGg7XG4gICAgICAgIGlmIChsZW4gPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIGFjdGlvbiArIGxlbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKChwYXJ0KSA9PiBwYXJ0ICE9PSBudWxsKSxcbiAgXS5qb2luKFwiX1wiKTtcblxuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHRhYmxlLFxuICAgICAgdGl0bGUsXG4gICAgICBmb3JtYXR0ZWQsXG4gICAgICB0eXBlOiBcIm5vcm1hbFwiLFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICog7Lus65+8IOu5hOq1kOulvCDsnITtlbQgR2VuZXJhdGVkIENvbHVtbuydmCBleHByZXNzaW9u7J2EIOygnOyZuO2VnCDqsJ3ssrTrpbwg7IOd7ISxXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUNvbHVtbkZvckNvbXBhcmlzb24oY29sOiBNaWdyYXRpb25Db2x1bW4pOiBNaWdyYXRpb25Db2x1bW4ge1xuICBpZiAoY29sLmdlbmVyYXRlZCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5jb2wsXG4gICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgdHlwZTogY29sLmdlbmVyYXRlZC50eXBlLFxuICAgICAgICBleHByZXNzaW9uOiBcIlwiLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIHJldHVybiBjb2w7XG59XG5cbi8qKlxuICog6rCBIOy7rOufvCDsnbTrpoQg6riw7KSA7Jy866GcIGFkZCwgZHJvcCwgYWx0ZXIg7Jes67aAIO2ZleyduFxuICovXG5mdW5jdGlvbiBnZXRBbHRlckNvbHVtbnNUbyhlbnRpdHlDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSwgZGJDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSkge1xuICBjb25zdCBjb2x1bW5zVG8gPSB7XG4gICAgYWRkOiBbXSBhcyBNaWdyYXRpb25Db2x1bW5bXSxcbiAgICBkcm9wOiBbXSBhcyBNaWdyYXRpb25Db2x1bW5bXSxcbiAgICBhbHRlcjogW10gYXMgTWlncmF0aW9uQ29sdW1uW10sXG4gIH07XG5cbiAgLy8g7Lus65+866qFIOq4sOykgCDruYTqtZBcbiAgY29uc3QgZXh0cmFDb2x1bW5zID0ge1xuICAgIGRiOiBkaWZmKGRiQ29sdW1ucywgZW50aXR5Q29sdW1ucywgKGNvbCkgPT4gW2NvbC5uYW1lLCBjb2wuZ2VuZXJhdGVkPy50eXBlXS5qb2luKFwiLy8vXCIpKSxcbiAgICBlbnRpdHk6IGRpZmYoZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zLCAoY29sKSA9PiBbY29sLm5hbWUsIGNvbC5nZW5lcmF0ZWQ/LnR5cGVdLmpvaW4oXCIvLy9cIikpLFxuICB9O1xuICBpZiAoZXh0cmFDb2x1bW5zLmVudGl0eS5sZW5ndGggPiAwKSB7XG4gICAgY29sdW1uc1RvLmFkZCA9IGNvbHVtbnNUby5hZGQuY29uY2F0KGV4dHJhQ29sdW1ucy5lbnRpdHkpO1xuICB9XG4gIGlmIChleHRyYUNvbHVtbnMuZGIubGVuZ3RoID4gMCkge1xuICAgIGNvbHVtbnNUby5kcm9wID0gY29sdW1uc1RvLmRyb3AuY29uY2F0KGV4dHJhQ29sdW1ucy5kYik7XG4gIH1cblxuICAvLyDrj5nsnbwg7Lus65+866qF7J2YIOyEuOu2gCDtlYTrk5wg67mE6rWQIChHZW5lcmF0ZWQgQ29sdW1uIGV4cHJlc3Npb24g7KCc7Jm4KVxuICBjb25zdCBzYW1lRGJDb2x1bW5zID0gaW50ZXJzZWN0aW9uQnkoZGJDb2x1bW5zLCBlbnRpdHlDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSk7XG4gIGNvbnN0IHNhbWVNZENvbHVtbnMgPSBpbnRlcnNlY3Rpb25CeShlbnRpdHlDb2x1bW5zLCBkYkNvbHVtbnMsIChjb2wpID0+IGNvbC5uYW1lKTtcbiAgY29sdW1uc1RvLmFsdGVyID0gZGlmZmVyZW5jZVdpdGgoXG4gICAgc2FtZURiQ29sdW1ucyxcbiAgICBzYW1lTWRDb2x1bW5zLFxuICAgIChhLCBiKSA9PiBlcXVhbCh7IC4uLmEsIGdlbmVyYXRlZDogdW5kZWZpbmVkIH0sIHsgLi4uYiwgZ2VuZXJhdGVkOiB1bmRlZmluZWQgfSksIC8vIGdlbmVyYXRlZCDsu6zrn7zsnYAgYWx0ZXLroZwg7LKY66as7ZWY7KeAIOyViuydjFxuICApO1xuXG4gIHJldHVybiBjb2x1bW5zVG87XG59XG5cbi8qKlxuICog7LaU7Lac65CcIOy7rOufvOuTpOydhCDquLDspIDsnLzroZwg6rCB6rCBIOudvOyduCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2V0QWx0ZXJDb2x1bW5MaW5lc1RvKFxuICBjb2x1bW5zVG86IFJldHVyblR5cGU8dHlwZW9mIGdldEFsdGVyQ29sdW1uc1RvPixcbiAgZW50aXR5Q29sdW1uczogTWlncmF0aW9uQ29sdW1uW10sXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGRiRm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbikge1xuICBjb25zdCBsaW5lc1RvID0ge1xuICAgIGFkZDoge1xuICAgICAgdXA6IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICAgIGRvd246IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICB9LFxuICAgIGRyb3A6IHtcbiAgICAgIHVwOiB7IGJ1aWxkZXI6IFtdIGFzIHN0cmluZ1tdLCByYXc6IFtdIGFzIHN0cmluZ1tdIH0sXG4gICAgICBkb3duOiB7IGJ1aWxkZXI6IFtdIGFzIHN0cmluZ1tdLCByYXc6IFtdIGFzIHN0cmluZ1tdIH0sXG4gICAgfSxcbiAgICBhbHRlcjoge1xuICAgICAgdXA6IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICAgIGRvd246IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICB9LFxuICB9O1xuXG4gIC8vIGFkZCBjb2x1bW5zXG4gIGNvbnN0IGFkZENvbHVtbkRlZnMgPSBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZSwgY29sdW1uc1RvLmFkZCk7XG4gIGxpbmVzVG8uYWRkLnVwID0ge1xuICAgIGJ1aWxkZXI6IGFkZENvbHVtbkRlZnMuYnVpbGRlci5sZW5ndGggPiAwID8gW1wiLy8gYWRkXCIsIC4uLmFkZENvbHVtbkRlZnMuYnVpbGRlcl0gOiBbXSxcbiAgICByYXc6IGFkZENvbHVtbkRlZnMucmF3Lmxlbmd0aCA+IDAgPyBbXCIvLyBhZGQgKGdlbmVyYXRlZClcIiwgLi4uYWRkQ29sdW1uRGVmcy5yYXddIDogW10sXG4gIH07XG4gIGxpbmVzVG8uYWRkLmRvd24gPSB7XG4gICAgYnVpbGRlcjpcbiAgICAgIGNvbHVtbnNUby5hZGQubGVuZ3RoID4gMFxuICAgICAgICA/IFtcbiAgICAgICAgICAgIFwiLy8gcm9sbGJhY2sgLSBhZGRcIixcbiAgICAgICAgICAgIGB0YWJsZS5kcm9wQ29sdW1ucygke2NvbHVtbnNUby5hZGQubWFwKChjb2wpID0+IGAnJHtjb2wubmFtZX0nYCkuam9pbihcIiwgXCIpfSlgLFxuICAgICAgICAgIF1cbiAgICAgICAgOiBbXSxcbiAgICByYXc6IFtdLFxuICB9O1xuXG4gIC8vIGRyb3DtlaAg7Lus65+87JeQIOqxuOumsCBGSyDssL7quLBcbiAgY29uc3QgZHJvcENvbHVtbk5hbWVzID0gY29sdW1uc1RvLmRyb3AubWFwKChjb2wpID0+IGNvbC5uYW1lKTtcbiAgY29uc3QgZmtUb0Ryb3BCZWZvcmVDb2x1bW4gPSBkYkZvcmVpZ25zLmZpbHRlcigoZmspID0+XG4gICAgZmsuY29sdW1ucy5zb21lKChjb2wpID0+IGRyb3BDb2x1bW5OYW1lcy5pbmNsdWRlcyhjb2wpKSxcbiAgKTtcblxuICBjb25zdCBkcm9wRmtMaW5lcyA9IGZrVG9Ecm9wQmVmb3JlQ29sdW1uLm1hcCgoZmspID0+IHtcbiAgICBjb25zdCBjb2x1bW5zU3RyaW5nUXVvdGUgPSBmay5jb2x1bW5zLm1hcCgoY29sKSA9PiBgJyR7Y29sfSdgKS5qb2luKFwiLFwiKTtcbiAgICByZXR1cm4gYHRhYmxlLmRyb3BGb3JlaWduKFske2NvbHVtbnNTdHJpbmdRdW90ZX1dKWA7XG4gIH0pO1xuXG4gIGNvbnN0IHJlc3RvcmVGa0xpbmVzID0gZ2VuRm9yZWlnbkRlZmluaXRpb25zKHRhYmxlLCBma1RvRHJvcEJlZm9yZUNvbHVtbikudXA7XG5cbiAgLy8gZHJvcOydmCByb2xsYmFja+yLnOyXkOuKlCBnZW5lcmF0ZWQgY29sdW1u64+EIOuzteybkO2VtOyVvCDtlahcbiAgY29uc3QgZHJvcENvbHVtbkRlZnMgPSBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZSwgY29sdW1uc1RvLmRyb3ApO1xuICBsaW5lc1RvLmRyb3AgPSB7XG4gICAgdXA6IHtcbiAgICAgIGJ1aWxkZXI6IFtcbiAgICAgICAgLi4uKGRyb3BGa0xpbmVzLmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcIi8vIGRyb3AgZm9yZWlnbiBrZXlzIG9uIGNvbHVtbnMgdG8gYmUgZHJvcHBlZFwiLCAuLi5kcm9wRmtMaW5lc11cbiAgICAgICAgICA6IFtdKSxcbiAgICAgICAgLi4uKGNvbHVtbnNUby5kcm9wLmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgXCIvLyBkcm9wIGNvbHVtbnNcIixcbiAgICAgICAgICAgICAgYHRhYmxlLmRyb3BDb2x1bW5zKCR7Y29sdW1uc1RvLmRyb3AubWFwKChjb2wpID0+IGAnJHtjb2wubmFtZX0nYCkuam9pbihcIiwgXCIpfSlgLFxuICAgICAgICAgICAgXVxuICAgICAgICAgIDogW10pLFxuICAgICAgXSxcbiAgICAgIHJhdzogW10sXG4gICAgfSxcbiAgICBkb3duOiB7XG4gICAgICBidWlsZGVyOiBbXG4gICAgICAgIC4uLihkcm9wQ29sdW1uRGVmcy5idWlsZGVyLmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcIi8vIHJvbGxiYWNrIC0gZHJvcCBjb2x1bW5zXCIsIC4uLmRyb3BDb2x1bW5EZWZzLmJ1aWxkZXJdXG4gICAgICAgICAgOiBbXSksXG4gICAgICAgIC4uLihyZXN0b3JlRmtMaW5lcy5sZW5ndGggPiAwID8gW1wiLy8gcmVzdG9yZSBmb3JlaWduIGtleXNcIiwgLi4ucmVzdG9yZUZrTGluZXNdIDogW10pLFxuICAgICAgXSxcbiAgICAgIHJhdzpcbiAgICAgICAgZHJvcENvbHVtbkRlZnMucmF3Lmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcIi8vIHJvbGxiYWNrIC0gZHJvcCBjb2x1bW5zIChnZW5lcmF0ZWQpXCIsIC4uLmRyb3BDb2x1bW5EZWZzLnJhd11cbiAgICAgICAgICA6IFtdLFxuICAgIH0sXG4gIH07XG5cbiAgLy8gYWx0ZXIgY29sdW1ucyAoR2VuZXJhdGVkIENvbHVtbuydgCBBTFRFUiDrtojqsIDtlZjrr4DroZwgZHJvcCDtm4Qg7J6s7IOd7ISxKVxuICBsaW5lc1RvLmFsdGVyID0gY29sdW1uc1RvLmFsdGVyLnJlZHVjZShcbiAgICAociwgZGJDb2x1bW4pID0+IHtcbiAgICAgIGNvbnN0IGVudGl0eUNvbHVtbiA9IGVudGl0eUNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wubmFtZSA9PT0gZGJDb2x1bW4ubmFtZSk7XG4gICAgICBpZiAoZW50aXR5Q29sdW1uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9XG5cbiAgICAgIC8vIOy7rOufvCDrs4Dqsr3sgqztla1cbiAgICAgIGNvbnN0IGNvbHVtbkRpZmZVcCA9IGRpZmYoXG4gICAgICAgIGdlbkNvbHVtbkRlZmluaXRpb25zKHRhYmxlLCBbZW50aXR5Q29sdW1uXSkuYnVpbGRlcixcbiAgICAgICAgZ2VuQ29sdW1uRGVmaW5pdGlvbnModGFibGUsIFtkYkNvbHVtbl0pLmJ1aWxkZXIsXG4gICAgICApO1xuICAgICAgY29uc3QgY29sdW1uRGlmZkRvd24gPSBkaWZmKFxuICAgICAgICBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZSwgW2RiQ29sdW1uXSkuYnVpbGRlcixcbiAgICAgICAgZ2VuQ29sdW1uRGVmaW5pdGlvbnModGFibGUsIFtlbnRpdHlDb2x1bW5dKS5idWlsZGVyLFxuICAgICAgKTtcbiAgICAgIGlmIChjb2x1bW5EaWZmVXAubGVuZ3RoID4gMCkge1xuICAgICAgICByLnVwLmJ1aWxkZXIgPSBbXG4gICAgICAgICAgLi4uci51cC5idWlsZGVyLFxuICAgICAgICAgIFwiLy8gYWx0ZXIgY29sdW1uXCIsXG4gICAgICAgICAgLi4uY29sdW1uRGlmZlVwLm1hcCgobCkgPT4gYCR7bC5yZXBsYWNlKFwiO1wiLCBcIlwiKX0uYWx0ZXIoKTtgKSxcbiAgICAgICAgXTtcbiAgICAgICAgci5kb3duLmJ1aWxkZXIgPSBbXG4gICAgICAgICAgLi4uci5kb3duLmJ1aWxkZXIsXG4gICAgICAgICAgXCIvLyByb2xsYmFjayAtIGFsdGVyIGNvbHVtblwiLFxuICAgICAgICAgIC4uLmNvbHVtbkRpZmZEb3duLm1hcCgobCkgPT4gYCR7bC5yZXBsYWNlKFwiO1wiLCBcIlwiKX0uYWx0ZXIoKTtgKSxcbiAgICAgICAgXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHI7XG4gICAgfSxcbiAgICB7XG4gICAgICB1cDogeyBidWlsZGVyOiBbXSBhcyBzdHJpbmdbXSwgcmF3OiBbXSBhcyBzdHJpbmdbXSB9LFxuICAgICAgZG93bjogeyBidWlsZGVyOiBbXSBhcyBzdHJpbmdbXSwgcmF3OiBbXSBhcyBzdHJpbmdbXSB9LFxuICAgIH0sXG4gICk7XG5cbiAgcmV0dXJuIGxpbmVzVG87XG59XG5cbi8qKlxuICog7J24642x7Iqk7J2YIGFkZCwgZHJvcCDsl6zrtoAg7ZmV7J24XG4gKi9cbmZ1bmN0aW9uIGdldEFsdGVySW5kZXhlc1RvKGVudGl0eUluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10sIGRiSW5kZXhlczogTWlncmF0aW9uSW5kZXhbXSkge1xuICAvLyDsnbjrjbHsiqQg67mE6rWQXG4gIGNvbnN0IGluZGV4ZXNUbyA9IHtcbiAgICBhZGQ6IFtdIGFzIE1pZ3JhdGlvbkluZGV4W10sXG4gICAgZHJvcDogW10gYXMgTWlncmF0aW9uSW5kZXhbXSxcbiAgfTtcblxuICAvLyDsnbjrjbHsiqQg6rOg7JygIOyLneuzhOyekCDsg53shLEgKG5hbWXsnYQg7KCc7Jm47ZWcIOuqqOuToCDtlYTrk5zrpbwg66y47J6Q7Je066GcIOuzgO2ZmO2VmOyXrCDsobDtlakpXG4gIGNvbnN0IGlkZW50aXR5ID0gPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oaW5kZXg6IFQpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhpbmRleClcbiAgICAgIC5maWx0ZXIoKGtleSkgPT4ga2V5ICE9PSBcIm5hbWVcIilcbiAgICAgIC5zb3J0KCk7XG5cbiAgICByZXR1cm4ga2V5c1xuICAgICAgLm1hcCgoa2V5KSA9PiB7XG4gICAgICAgIGlmIChrZXkgPT09IFwibmFtZVwiKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoa2V5ID09PSBcImNvbHVtbnNcIikge1xuICAgICAgICAgIHJldHVybiAoaW5kZXhba2V5XSBhcyBNaWdyYXRpb25JbmRleFtcImNvbHVtbnNcIl0pLmZsYXRNYXAoaWRlbnRpdHkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgJHtrZXl9PSR7aW5kZXhba2V5IGFzIGtleW9mIE1pZ3JhdGlvbkluZGV4XX1gO1xuICAgICAgfSlcbiAgICAgIC5qb2luKFwiLy9cIik7XG4gIH07XG5cbiAgY29uc3QgZXh0cmFJbmRleGVzID0ge1xuICAgIGRiOiBkaWZmKGRiSW5kZXhlcywgZW50aXR5SW5kZXhlcy5tYXAoc2V0TWlncmF0aW9uSW5kZXhEZWZhdWx0cyksIGlkZW50aXR5KSxcbiAgICBlbnRpdHk6IGRpZmYoZW50aXR5SW5kZXhlcy5tYXAoc2V0TWlncmF0aW9uSW5kZXhEZWZhdWx0cyksIGRiSW5kZXhlcywgaWRlbnRpdHkpLFxuICB9O1xuICBpZiAoZXh0cmFJbmRleGVzLmVudGl0eS5sZW5ndGggPiAwKSB7XG4gICAgaW5kZXhlc1RvLmFkZCA9IGluZGV4ZXNUby5hZGQuY29uY2F0KGV4dHJhSW5kZXhlcy5lbnRpdHkpO1xuICB9XG4gIGlmIChleHRyYUluZGV4ZXMuZGIubGVuZ3RoID4gMCkge1xuICAgIGluZGV4ZXNUby5kcm9wID0gaW5kZXhlc1RvLmRyb3AuY29uY2F0KGV4dHJhSW5kZXhlcy5kYik7XG4gIH1cblxuICByZXR1cm4gaW5kZXhlc1RvO1xufVxuXG4vKipcbiAqIOyduOuNseyKpCDsgq3soJwg7KCV7J2YIOyDneyEsVxuICovXG5mdW5jdGlvbiBnZW5JbmRleERyb3BEZWZpbml0aW9uKGluZGV4OiBNaWdyYXRpb25JbmRleCkge1xuICByZXR1cm4gYHRhYmxlLmRyb3BJbmRleChbJHtpbmRleC5jb2x1bW5zXG4gICAgLm1hcCgoY29sdW1uKSA9PiBgJyR7Y29sdW1uLm5hbWV9J2ApXG4gICAgLmpvaW4oXCIsXCIpfV0sICcke2luZGV4Lm5hbWV9JylgO1xufVxuXG4vKipcbiAqIERCIOyhsO2ajCDqsrDqs7zsmYAg67mE6rWQ7ZWY6riwIOychO2VnCDsnbjrjbHsiqQg6riw67O46rCSIOyEpOyglVxuICovXG5mdW5jdGlvbiBzZXRNaWdyYXRpb25JbmRleERlZmF1bHRzKGluZGV4OiBNaWdyYXRpb25JbmRleCk6IE1pZ3JhdGlvbkluZGV4IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5pbmRleCxcbiAgICBjb2x1bW5zOiBpbmRleC5jb2x1bW5zLm1hcCgoY29sKSA9PiAoe1xuICAgICAgLi4uY29sLFxuICAgICAgc29ydE9yZGVyOiBjb2wuc29ydE9yZGVyID8/IFwiQVNDXCIsXG4gICAgICAvLyBzb3J0T3JkZXLsl5Ag65Sw6528IG51bGxzRmlyc3TsnZggZGVmYXVsdCDqsJIg7ISk7KCVXG4gICAgICBudWxsc0ZpcnN0OiBjb2wubnVsbHNGaXJzdCA/PyBjb2wuc29ydE9yZGVyID09PSBcIkRFU0NcIixcbiAgICB9KSksXG4gICAgbnVsbHNOb3REaXN0aW5jdDogaW5kZXgubnVsbHNOb3REaXN0aW5jdCA/PyBmYWxzZSxcbiAgfTtcbn1cblxuLyoqXG4gKiDthYzsnbTruJQg67OA6rK9IOy8gOydtOyKpCAtIEZvcmVpZ24gS2V5IOuzgOqyvVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUFsdGVyQ29kZV9Gb3JlaWducyhcbiAgdGFibGU6IHN0cmluZyxcbiAgZW50aXR5Rm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgZGJGb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuICBkcm9wcGluZ0NvbHVtbnM6IE1pZ3JhdGlvbkNvbHVtbltdID0gW10sXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGVbXT4ge1xuICAvLyBjb25zb2xlLmxvZyh7IGVudGl0eUZvcmVpZ25zLCBkYkZvcmVpZ25zIH0pO1xuXG4gIGNvbnN0IGdldEtleSA9IChtZjogTWlncmF0aW9uRm9yZWlnbik6IHN0cmluZyA9PiB7XG4gICAgcmV0dXJuIFttZi5jb2x1bW5zLmpvaW4oXCItXCIpLCBtZi50b10uam9pbihcIi8vL1wiKTtcbiAgfTtcblxuICAvLyDsgq3soJzrkKAg7Lus65+866qFIOuqqeuhnVxuICBjb25zdCBkcm9wcGluZ0NvbHVtbk5hbWVzID0gZHJvcHBpbmdDb2x1bW5zLm1hcCgoY29sKSA9PiBjb2wubmFtZSk7XG5cbiAgY29uc3QgZmtUbyA9IGVudGl0eUZvcmVpZ25zLnJlZHVjZShcbiAgICAocmVzdWx0LCBlbnRpdHlGKSA9PiB7XG4gICAgICBjb25zdCBtYXRjaGluZ0RiRiA9IGRiRm9yZWlnbnMuZmluZCgoZGJGKSA9PiBnZXRLZXkoZW50aXR5RikgPT09IGdldEtleShkYkYpKTtcbiAgICAgIGlmICghbWF0Y2hpbmdEYkYpIHtcbiAgICAgICAgcmVzdWx0LmFkZC5wdXNoKGVudGl0eUYpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBpZiAoZXF1YWwoZW50aXR5RiwgbWF0Y2hpbmdEYkYpID09PSBmYWxzZSkge1xuICAgICAgICByZXN1bHQuYWx0ZXJTcmMucHVzaChtYXRjaGluZ0RiRik7XG4gICAgICAgIHJlc3VsdC5hbHRlckRzdC5wdXNoKGVudGl0eUYpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuICAgIHtcbiAgICAgIGFkZDogW10gYXMgTWlncmF0aW9uRm9yZWlnbltdLFxuICAgICAgZHJvcDogW10gYXMgTWlncmF0aW9uRm9yZWlnbltdLFxuICAgICAgYWx0ZXJTcmM6IFtdIGFzIE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgICAgIGFsdGVyRHN0OiBbXSBhcyBNaWdyYXRpb25Gb3JlaWduW10sXG4gICAgfSxcbiAgKTtcblxuICAvLyBkYkZvcmVpZ25z7JeQ64qUIOyeiOyngOunjCBlbnRpdHlGb3JlaWduc+yXkOuKlCDsl4bripQg6rK97JqwICjsgq3soJzrkJwgRkspXG4gIC8vIOuLqCwg7IKt7KCc65CgIOy7rOufvOydmCBGS+uKlCDsoJzsmbggKGdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXPsl5DshJwg7LKY66asKVxuICBkYkZvcmVpZ25zLmZvckVhY2goKGRiRikgPT4ge1xuICAgIGNvbnN0IG1hdGNoaW5nRW50aXR5RiA9IGVudGl0eUZvcmVpZ25zLmZpbmQoKGVudGl0eUYpID0+IGdldEtleShlbnRpdHlGKSA9PT0gZ2V0S2V5KGRiRikpO1xuICAgIGlmICghbWF0Y2hpbmdFbnRpdHlGKSB7XG4gICAgICAvLyDsnbQgRkvsnZgg7Lus65+87J20IOyCreygnOuQoCDsu6zrn7wg66qp66Gd7JeQIOyeiOuKlOyngCDtmZXsnbhcbiAgICAgIGNvbnN0IGlzQ29sdW1uRHJvcHBpbmcgPSBkYkYuY29sdW1ucy5zb21lKChjb2wpID0+IGRyb3BwaW5nQ29sdW1uTmFtZXMuaW5jbHVkZXMoY29sKSk7XG4gICAgICAvLyDsu6zrn7zsnbQg7IKt7KCc65CY7KeAIOyViuuKlCDqsr3smrDsl5Drp4wgRksgZHJvcCDrqqnroZ3sl5Ag7LaU6rCAXG4gICAgICBpZiAoIWlzQ29sdW1uRHJvcHBpbmcpIHtcbiAgICAgICAgZmtUby5kcm9wLnB1c2goZGJGKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGxpbmVzVG8gPSB7XG4gICAgYWRkOiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uYWRkKSxcbiAgICBkcm9wOiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uZHJvcCksXG4gICAgYWx0ZXJTcmM6IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZmtUby5hbHRlclNyYyksXG4gICAgYWx0ZXJEc3Q6IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZmtUby5hbHRlckRzdCksXG4gIH07XG5cbiAgLy8gZHJvcCBmayBjb2x1bW5z7J24IOqyveyasCjsg53shLHrkKAg7L2U65OcIOyXhuuKlCDqsr3smrApIO2MqOyKpFxuICBjb25zdCBoYXNMaW5lcyA9IE9iamVjdC52YWx1ZXMobGluZXNUbykuc29tZSgobCkgPT4gbC51cC5sZW5ndGggPiAwIHx8IGwuZG93bi5sZW5ndGggPiAwKTtcbiAgaWYgKCFoYXNMaW5lcykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGlmIChcbiAgICBsaW5lc1RvLmFkZC51cC5sZW5ndGggPT09IDAgJiZcbiAgICBsaW5lc1RvLmRyb3AudXAubGVuZ3RoID09PSAwICYmXG4gICAgbGluZXNUby5hbHRlclNyYy51cC5sZW5ndGggPT09IDAgJiZcbiAgICBsaW5lc1RvLmFsdGVyRHN0LnVwLmxlbmd0aCA9PT0gMFxuICApIHtcbiAgICBOYWl0ZS50KFwibWlncmF0b3I6Z2VuZXJhdGVBbHRlckNvZGVfRm9yZWlnbnM6ZmtDaGFuZ2VDb2RlR2VuZXJhdGlvbkVycm9yXCIsIHtcbiAgICAgIHRhYmxlLFxuICAgICAgZW50aXR5Rm9yZWlnbnMsXG4gICAgICBkYkZvcmVpZ25zLFxuICAgIH0pO1xuICAgIHRocm93IG5ldyBFcnJvcihcIkZLIOuzgOqyvSDsvZTrk5wg7IOd7ISxIOyYpOulmFwiKTtcbiAgfVxuXG4gIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtcbiAgICAnaW1wb3J0IHsgS25leCB9IGZyb20gXCJrbmV4XCI7JyxcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgcmV0dXJuIGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLFxuICAgIC4uLmxpbmVzVG8uZHJvcC5kb3duLFxuICAgIC4uLmxpbmVzVG8uYWRkLnVwLFxuICAgIC4uLmxpbmVzVG8uYWx0ZXJTcmMuZG93bixcbiAgICAuLi5saW5lc1RvLmFsdGVyRHN0LnVwLFxuICAgIFwifSlcIixcbiAgICBcIn1cIixcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvd24oa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGByZXR1cm4ga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLi4ubGluZXNUby5hZGQuZG93bixcbiAgICAuLi5saW5lc1RvLmFsdGVyRHN0LmRvd24sXG4gICAgLi4ubGluZXNUby5hbHRlclNyYy51cCxcbiAgICAuLi5saW5lc1RvLmRyb3AudXAsXG4gICAgXCJ9KVwiLFxuICAgIFwifVwiLFxuICBdO1xuXG4gIGNvbnN0IGZvcm1hdHRlZCA9IGZvcm1hdENvZGUobGluZXMuam9pbihcIlxcblwiKSwgXCJ0eXBlc2NyaXB0XCIsIGBzcmMvbWlncmF0aW9uLyR7dGFibGV9LnRzYCk7XG4gIGNvbnN0IHRpdGxlID0gW1xuICAgIFwiYWx0ZXJcIixcbiAgICB0YWJsZSxcbiAgICBcImZvcmVpZ25zXCIsXG4gICAgLy8gVE9ETyDrsJTrgIzripQg67aA67aEXG4gIF0uam9pbihcIl9cIik7XG5cbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0YWJsZSxcbiAgICAgIHRpdGxlLFxuICAgICAgZm9ybWF0dGVkLFxuICAgICAgdHlwZTogXCJub3JtYWxcIixcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIOyjvOyWtOynhCBFbnRpdHlTZXTsnYQg6riw67CY7Jy866GcIO2FjOydtOu4lCBDUkVBVEUg66eI7J206re466CI7J207IWYIOy9lOuTnOulvCDsg53shLHtlanri4jri6QuXG4gKiBAcGFyYW0gZW50aXR5U2V0XG4gKiBAcmV0dXJucyBDUkVBVEUg66eI7J206re466CI7J207IWYIOy9lOuTnFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVDcmVhdGVDb2RlKGVudGl0eVNldDogTWlncmF0aW9uU2V0KTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgcmV0dXJuIFtcbiAgICBhd2FpdCBnZW5lcmF0ZUNyZWF0ZUNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgICAgIGVudGl0eVNldC50YWJsZSxcbiAgICAgIGVudGl0eVNldC5jb2x1bW5zLFxuICAgICAgZW50aXR5U2V0LmluZGV4ZXMsXG4gICAgKSxcbiAgICAuLi4oYXdhaXQgZ2VuZXJhdGVDcmVhdGVDb2RlX0ZvcmVpZ24oZW50aXR5U2V0LnRhYmxlLCBlbnRpdHlTZXQuZm9yZWlnbnMpKSxcbiAgXTtcbn1cblxuLyoqXG4gKiDso7zslrTsp4QgZW50aXR5U2V07J2EIOuqqe2RnOuhnCwgZGJTZXTsnYQg7ZiEIOyDge2ZqeycvOuhnCDtlZjsl6wg7YWM7J2067iUIEFMVEVSIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5zrpbwg7IOd7ISx7ZWp64uI64ukLlxuICogQHBhcmFtIGVudGl0eVNldCDtmIQg7IOB7Zmp7J2YIE1pZ3JhdGlvblNldFxuICogQHBhcmFtIGRiU2V0IOuqqe2RnCDsg4HtmansnZggTWlncmF0aW9uU2V0XG4gKiBAcmV0dXJucyBBTFRFUiDrp4jsnbTqt7jroIjsnbTshZgg7L2U65OcXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUFsdGVyQ29kZShcbiAgZW50aXR5U2V0OiBNaWdyYXRpb25TZXQsXG4gIGRiU2V0OiBNaWdyYXRpb25TZXQsXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGVbXT4ge1xuICBjb25zdCByZXBsYWNlQ29sdW1uRGVmYXVsdFRvID0gKGNvbDogTWlncmF0aW9uQ29sdW1uKSA9PiB7XG4gICAgLy8gZmxvYXTsnbgg6rK97JqwIOq4sOuzuOqwkuydhCAw7Jy866GcIOyngOygle2VmOuKlCDqsr3smrAgXCIwLjAwXCLsnLzroZwg67OA7ZmY65CY64qUIOy8gOydtOyKpCDrjIDsnZFcbiAgICAvLyBpZiAoY29sLnR5cGUgPT09IFwiZmxvYXRcIiAmJiBjb2wuZGVmYXVsdFRvICYmIFN0cmluZyhjb2wuZGVmYXVsdFRvKS5pbmNsdWRlcygnXCInKSA9PT0gZmFsc2UpIHtcbiAgICAvLyAgIGNvbC5kZWZhdWx0VG8gPSBgXCIke051bWJlcihjb2wuZGVmYXVsdFRvKS50b0ZpeGVkKGNvbC5zY2FsZSA/PyAyKX1cImA7XG4gICAgLy8gfVxuICAgIC8vIC8vIHN0cmluZ+yduCDqsr3smrAg6riw67O46rCS7J20IOu5iCDsiqTtirjrp4Hsnbgg6rK97JqwIOuMgOydkVxuICAgIC8vIGlmIChjb2wudHlwZSA9PT0gXCJzdHJpbmdcIiAmJiBjb2wuZGVmYXVsdFRvID09PSBcIlwiKSB7XG4gICAgLy8gICBjb2wuZGVmYXVsdFRvID0gJ1wiXCInO1xuICAgIC8vIH1cbiAgICAvLyAvLyBib29sZWFu7J24IOqyveyasCDquLDrs7jqsJIg7KCV6rec7ZmUIChNeVNRTOyXkOyEnOuKlCBUSU5ZSU5UKDEp66GcIOyggOyepeuQmOuvgOuhnCAwIOuYkOuKlCAx66GcIOygleq3nO2ZlClcbiAgICAvLyAvLyBUT0RPOiBkYi50c+yXkCB0eXBlQ2FzZSDshKTsoJUg7ZmV7J247ZWY7JesIOyymOumrO2VmOuPhOuhnSDsiJjsoJUg7ZWE7JqUXG4gICAgLy8gaWYgKGNvbC50eXBlID09PSBcImJvb2xlYW5cIiAmJiBjb2wuZGVmYXVsdFRvICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyAgIGlmIChjb2wuZGVmYXVsdFRvID09PSBcIjBcIiB8fCBjb2wuZGVmYXVsdFRvLnRvTG93ZXJDYXNlKCkgPT09IFwiZmFsc2VcIikge1xuICAgIC8vICAgICBjb2wuZGVmYXVsdFRvID0gXCIwXCI7XG4gICAgLy8gICB9IGVsc2UgaWYgKGNvbC5kZWZhdWx0VG8gPT09IFwiMVwiIHx8IGNvbC5kZWZhdWx0VG8udG9Mb3dlckNhc2UoKSA9PT0gXCJ0cnVlXCIpIHtcbiAgICAvLyAgICAgY29sLmRlZmF1bHRUbyA9IFwiMVwiO1xuICAgIC8vICAgfVxuICAgIC8vIH1cblxuICAgIC8vIEZJWE1FOiDsnbzri6ggTXlTUUwg7IOB7Zmp7JeQ7IScIOuwnOyDne2WiOuNmCDsnbTsiojsnZggd29ya2Fyb3VuZCDsnbTrr4DroZwgUGfsl5DshJwg7J6s7ZmV7J24IO2bhCDrjIDsnZEg7LaU6rCAXG4gICAgcmV0dXJuIGNvbDtcbiAgfTtcbiAgY29uc3QgZW50aXR5Q29sdW1ucyA9IGFscGhhYmV0aWNhbChlbnRpdHlTZXQuY29sdW1ucywgKGEpID0+IGEubmFtZSkubWFwKHJlcGxhY2VDb2x1bW5EZWZhdWx0VG8pO1xuICBjb25zdCBkYkNvbHVtbnMgPSBhbHBoYWJldGljYWwoZGJTZXQuY29sdW1ucywgKGEpID0+IGEubmFtZSkubWFwKHJlcGxhY2VDb2x1bW5EZWZhdWx0VG8pO1xuXG4gIC8qIOuUlOuyhOq5heyaqSDsvZTrk5wsIO2KueyglSDsu6zrn7zsl5DshJwg67aI7J287LmYIOuwnOyDne2VoCDrlYwg7ZmV7J24XG4gICAgICAgIGNvbnN0IGVudGl0eUNvbHVtbiA9IGVudGl0eVNldC5jb2x1bW5zLmZpbmQoXG4gICAgICAgICAgKGNvbCkgPT4gY29sLm5hbWUgPT09IFwicHJpY2Vfa3J3XCJcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZGJDb2x1bW4gPSBkYlNldC5jb2x1bW5zLmZpbmQoXG4gICAgICAgICAgKGNvbCkgPT4gY29sLm5hbWUgPT09IFwicHJpY2Vfa3J3XCJcbiAgICAgICAgKTtcbiAgICAgICAgY29uc29sZS5kZWJ1Zyh7IGVudGl0eUNvbHVtbiwgZGJDb2x1bW4gfSk7XG4gICAgICAgICAqL1xuXG4gIC8vID9cbiAgY29uc3QgZW50aXR5SW5kZXhlcyA9IGFscGhhYmV0aWNhbChlbnRpdHlTZXQuaW5kZXhlcywgKGEpID0+IFthLnR5cGUsIC4uLmEuY29sdW1uc10uam9pbihcIi1cIikpO1xuICBjb25zdCBkYkluZGV4ZXMgPSBhbHBoYWJldGljYWwoZGJTZXQuaW5kZXhlcywgKGEpID0+IFthLnR5cGUsIC4uLmEuY29sdW1uc10uam9pbihcIi1cIikpO1xuXG4gIGNvbnN0IHJlcGxhY2VOb0FjdGlvbk9uTXlTUUwgPSAoZjogTWlncmF0aW9uRm9yZWlnbikgPT4ge1xuICAgIC8vIE15U1FM7JeQ7IScIFJFU1RSSUNU7JmAIE5PIEFDVElPTuydgCDrj5nsnbztlahcbiAgICBjb25zdCB7IG9uRGVsZXRlLCBvblVwZGF0ZSB9ID0gZjtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uZixcbiAgICAgIG9uVXBkYXRlOiBvblVwZGF0ZSA9PT0gXCJSRVNUUklDVFwiID8gXCJOTyBBQ1RJT05cIiA6IG9uVXBkYXRlLFxuICAgICAgb25EZWxldGU6IG9uRGVsZXRlID09PSBcIlJFU1RSSUNUXCIgPyBcIk5PIEFDVElPTlwiIDogb25EZWxldGUsXG4gICAgfTtcbiAgfTtcblxuICBjb25zdCBlbnRpdHlGb3JlaWducyA9IGFscGhhYmV0aWNhbChlbnRpdHlTZXQuZm9yZWlnbnMsIChhKSA9PlxuICAgIFthLnRvLCAuLi5hLmNvbHVtbnNdLmpvaW4oXCItXCIpLFxuICApLm1hcCgoZikgPT4gcmVwbGFjZU5vQWN0aW9uT25NeVNRTChmKSk7XG4gIGNvbnN0IGRiRm9yZWlnbnMgPSBhbHBoYWJldGljYWwoZGJTZXQuZm9yZWlnbnMsIChhKSA9PiBbYS50bywgLi4uYS5jb2x1bW5zXS5qb2luKFwiLVwiKSkubWFwKChmKSA9PlxuICAgIHJlcGxhY2VOb0FjdGlvbk9uTXlTUUwoZiksXG4gICk7XG5cbiAgLy8g7IKt7KCc65CgIOy7rOufvCDrqqnroZ0g6rOE7IKwXG4gIGNvbnN0IGRyb3BwaW5nQ29sdW1ucyA9IGRpZmYoZGJDb2x1bW5zLCBlbnRpdHlDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSk7XG5cbiAgY29uc3QgYWx0ZXJDb2RlczogKEdlbk1pZ3JhdGlvbkNvZGUgfCBHZW5NaWdyYXRpb25Db2RlW10gfCBudWxsKVtdID0gW107XG5cbiAgLy8gMS4gY29sdW1uc0FuZEluZGV4ZXMg7LKY66asXG4gIGNvbnN0IGlzRXF1YWxDb2x1bW5zID0gZXF1YWwoXG4gICAgZW50aXR5Q29sdW1ucy5tYXAobm9ybWFsaXplQ29sdW1uRm9yQ29tcGFyaXNvbiksXG4gICAgZGJDb2x1bW5zLm1hcChub3JtYWxpemVDb2x1bW5Gb3JDb21wYXJpc29uKSxcbiAgKTtcbiAgY29uc3QgaXNFcXVhbEluZGV4ZXMgPSBlcXVhbChcbiAgICBlbnRpdHlJbmRleGVzLm1hcCgoaW5kZXgpID0+IG9taXQoaW5kZXgsIFtcInBhcnNlclwiXSkpLm1hcChzZXRNaWdyYXRpb25JbmRleERlZmF1bHRzKSxcbiAgICBkYkluZGV4ZXMsXG4gICk7XG4gIGlmICghaXNFcXVhbENvbHVtbnMgfHwgIWlzRXF1YWxJbmRleGVzKSB7XG4gICAgYWx0ZXJDb2Rlcy5wdXNoKFxuICAgICAgYXdhaXQgZ2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlDb2x1bW5zLFxuICAgICAgICBlbnRpdHlJbmRleGVzLFxuICAgICAgICBkYkNvbHVtbnMsXG4gICAgICAgIGRiSW5kZXhlcyxcbiAgICAgICAgZGJTZXQuZm9yZWlnbnMsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvLyAyLiBmb3JlaWducyDsspjrpqwgKOyCreygnOuQoCDsu6zrn7wg7KCV67O0IOyghOuLrClcbiAgaWYgKGVxdWFsKGVudGl0eUZvcmVpZ25zLCBkYkZvcmVpZ25zKSA9PT0gZmFsc2UpIHtcbiAgICBhbHRlckNvZGVzLnB1c2goXG4gICAgICBhd2FpdCBnZW5lcmF0ZUFsdGVyQ29kZV9Gb3JlaWducyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlGb3JlaWducyxcbiAgICAgICAgZGJGb3JlaWducyxcbiAgICAgICAgZHJvcHBpbmdDb2x1bW5zLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgaWYgKGFsdGVyQ29kZXMuZXZlcnkoKGFsdGVyQ29kZSkgPT4gYWx0ZXJDb2RlID09PSBudWxsKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBhbHRlckNvZGVzLmZpbHRlcigoYWx0ZXJDb2RlKSA9PiBhbHRlckNvZGUgIT09IG51bGwpLmZsYXQoKTtcbn1cbiJdLCJuYW1lcyI6WyJlcXVhbCIsImFscGhhYmV0aWNhbCIsImRpZmYiLCJvbWl0IiwiTmFpdGUiLCJmb3JtYXRDb2RlIiwiZGlmZmVyZW5jZVdpdGgiLCJpbnRlcnNlY3Rpb25CeSIsImdlbmVyYXRlQ3JlYXRlQ29kZV9Db2x1bW5BbmRJbmRleGVzIiwidGFibGUiLCJjb2x1bW5zIiwiaW5kZXhlcyIsImNvbHVtbkRlZnMiLCJnZW5Db2x1bW5EZWZpbml0aW9ucyIsImxpbmVzIiwiYnVpbGRlciIsInJhdyIsIm1hcCIsImluZGV4IiwiZ2VuSW5kZXhEZWZpbml0aW9uIiwidHlwZSIsInRpdGxlIiwiZm9ybWF0dGVkIiwiam9pbiIsInJlc3VsdCIsImNvbHVtbiIsImdlbmVyYXRlZCIsInB1c2giLCJnZW5HZW5lcmF0ZWRDb2x1bW5EZWZpbml0aW9uIiwiZ2VuTm9ybWFsQ29sdW1uRGVmaW5pdGlvbiIsIkVycm9yIiwicGdUeXBlIiwiZ2V0UGdUeXBlRm9yQ29sdW1uIiwic3RvcmFnZVR5cGUiLCJudWxsYWJsZUNsYXVzZSIsIm51bGxhYmxlIiwibmFtZSIsImV4cHJlc3Npb24iLCJjaGFpbnMiLCJlbmRzV2l0aCIsImVsZW1lbnRUeXBlIiwic2xpY2UiLCJnZXRQZ0FycmF5VHlwZSIsImRpbWVuc2lvbnMiLCJudW1iZXJUeXBlIiwicHJlY2lzaW9uIiwic2NhbGUiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJleHRyYVR5cGUiLCJkZWZhdWx0VG8iLCJzdGFydHNXaXRoIiwiZ2VuVmVjdG9ySW5kZXhEZWZpbml0aW9uIiwibWV0aG9kTWFwIiwiZnVsbHRleHQiLCJ1bmlxdWUiLCJudWxsc05vdERpc3RpbmN0Q2xhdXNlIiwibnVsbHNOb3REaXN0aW5jdCIsImNvbCIsInNvcnRPcmRlckNsYXVzZSIsInNvcnRPcmRlciIsIm51bGxzRmlyc3RDbGF1c2UiLCJudWxsc0ZpcnN0IiwidmVjdG9yT3BzIiwibSIsImVmQ29uc3RydWN0aW9uIiwibGlzdHMiLCJnZW5lcmF0ZUNyZWF0ZUNvZGVfRm9yZWlnbiIsImZvcmVpZ25zIiwidXAiLCJkb3duIiwiZ2VuRm9yZWlnbkRlZmluaXRpb25zIiwiY29uc29sZSIsImxvZyIsImZvcmVpZ25LZXlzU3RyaW5nIiwiZm9yZWlnbiIsInJlZHVjZSIsInIiLCJjb2x1bW5zU3RyaW5nUXVvdGUiLCJyZXBsYWNlIiwidG8iLCJvblVwZGF0ZSIsIm9uRGVsZXRlIiwiZ2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlcyIsImVudGl0eUNvbHVtbnMiLCJlbnRpdHlJbmRleGVzIiwiZGJDb2x1bW5zIiwiZGJJbmRleGVzIiwiZGJGb3JlaWducyIsImFsdGVyQ29sdW1uc1RvIiwiZ2V0QWx0ZXJDb2x1bW5zVG8iLCJhbHRlckNvbHVtbkxpbmVzVG8iLCJnZXRBbHRlckNvbHVtbkxpbmVzVG8iLCJhbHRlckluZGV4ZXNUbyIsImdldEFsdGVySW5kZXhlc1RvIiwiaW5kZXhOZWVkc1RvRHJvcCIsImRyb3AiLCJmaWx0ZXIiLCJldmVyeSIsImluY2x1ZGVzIiwiaGFzVXBDaGFuZ2VzIiwiYWRkIiwiYWx0ZXIiLCJ0IiwidXBCdWlsZGVyTGluZXMiLCJnZW5JbmRleERyb3BEZWZpbml0aW9uIiwidXBSYXdMaW5lcyIsImRvd25CdWlsZGVyTGluZXMiLCJpbmRleENvbCIsImRvd25SYXdMaW5lcyIsImFjdGlvbiIsImxlbiIsInBhcnQiLCJub3JtYWxpemVDb2x1bW5Gb3JDb21wYXJpc29uIiwiY29sdW1uc1RvIiwiZXh0cmFDb2x1bW5zIiwiZGIiLCJlbnRpdHkiLCJjb25jYXQiLCJzYW1lRGJDb2x1bW5zIiwic2FtZU1kQ29sdW1ucyIsImEiLCJiIiwibGluZXNUbyIsImFkZENvbHVtbkRlZnMiLCJkcm9wQ29sdW1uTmFtZXMiLCJma1RvRHJvcEJlZm9yZUNvbHVtbiIsImZrIiwic29tZSIsImRyb3BGa0xpbmVzIiwicmVzdG9yZUZrTGluZXMiLCJkcm9wQ29sdW1uRGVmcyIsImRiQ29sdW1uIiwiZW50aXR5Q29sdW1uIiwiZmluZCIsImNvbHVtbkRpZmZVcCIsImNvbHVtbkRpZmZEb3duIiwibCIsImluZGV4ZXNUbyIsImlkZW50aXR5Iiwia2V5cyIsIk9iamVjdCIsImtleSIsInNvcnQiLCJmbGF0TWFwIiwiZXh0cmFJbmRleGVzIiwic2V0TWlncmF0aW9uSW5kZXhEZWZhdWx0cyIsImdlbmVyYXRlQWx0ZXJDb2RlX0ZvcmVpZ25zIiwiZW50aXR5Rm9yZWlnbnMiLCJkcm9wcGluZ0NvbHVtbnMiLCJnZXRLZXkiLCJtZiIsImRyb3BwaW5nQ29sdW1uTmFtZXMiLCJma1RvIiwiZW50aXR5RiIsIm1hdGNoaW5nRGJGIiwiZGJGIiwiYWx0ZXJTcmMiLCJhbHRlckRzdCIsImZvckVhY2giLCJtYXRjaGluZ0VudGl0eUYiLCJpc0NvbHVtbkRyb3BwaW5nIiwiaGFzTGluZXMiLCJ2YWx1ZXMiLCJnZW5lcmF0ZUNyZWF0ZUNvZGUiLCJlbnRpdHlTZXQiLCJnZW5lcmF0ZUFsdGVyQ29kZSIsImRiU2V0IiwicmVwbGFjZUNvbHVtbkRlZmF1bHRUbyIsInJlcGxhY2VOb0FjdGlvbk9uTXlTUUwiLCJmIiwiYWx0ZXJDb2RlcyIsImlzRXF1YWxDb2x1bW5zIiwiaXNFcXVhbEluZGV4ZXMiLCJhbHRlckNvZGUiLCJmbGF0Il0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxXQUFXLGtCQUFrQjtBQUNwQyxTQUFTQyxZQUFZLEVBQUVDLElBQUksRUFBRUMsSUFBSSxRQUFRLFVBQVU7QUFDbkQsU0FBU0MsS0FBSyxRQUFRLGNBQUs7QUFRM0IsU0FBU0MsVUFBVSxRQUFRLHdCQUFxQjtBQUNoRCxTQUFTQyxjQUFjLEVBQUVDLGNBQWMsUUFBUSxvQkFBaUI7QUFZaEU7O0NBRUMsR0FDRCxlQUFlQyxvQ0FDYkMsS0FBYSxFQUNiQyxPQUEwQixFQUMxQkMsT0FBeUI7SUFFekIsTUFBTUMsYUFBYUMscUJBQXFCSixPQUFPQztJQUUvQyxhQUFhO0lBQ2IsTUFBTUksUUFBa0I7UUFDdEI7UUFDQTtRQUNBO1FBQ0EsQ0FBQywrQkFBK0IsRUFBRUwsTUFBTSxlQUFlLENBQUM7V0FDckRHLFdBQVdHLE9BQU87UUFDckI7UUFDQSw4QkFBOEI7V0FDM0JILFdBQVdJLEdBQUc7UUFDakIsNENBQTRDO1dBQ3pDTCxRQUFRTSxHQUFHLENBQUMsQ0FBQ0MsUUFBVUMsbUJBQW1CRCxPQUFPVDtRQUNwRDtRQUNBO1FBQ0E7UUFDQSxDQUFDLCtCQUErQixFQUFFQSxNQUFNLEdBQUcsQ0FBQztRQUM1QztLQUNEO0lBQ0QsT0FBTztRQUNMQTtRQUNBVyxNQUFNO1FBQ05DLE9BQU8sQ0FBQyxRQUFRLEVBQUVaLE9BQU87UUFDekJhLFdBQVdqQixXQUFXUyxNQUFNUyxJQUFJLENBQUMsT0FBTyxjQUFjLENBQUMsY0FBYyxFQUFF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