@bitgo-beta/sdk-coin-canton 1.0.1-beta.82 → 1.0.1-beta.821

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 (181) hide show
  1. package/dist/src/canton.d.ts +22 -1
  2. package/dist/src/canton.d.ts.map +1 -1
  3. package/dist/src/canton.js +293 -10
  4. package/dist/src/cantonToken.d.ts +19 -0
  5. package/dist/src/cantonToken.d.ts.map +1 -0
  6. package/dist/src/cantonToken.js +52 -0
  7. package/dist/src/index.d.ts +1 -0
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +2 -1
  10. package/dist/src/lib/allocationAllocateBuilder.d.ts +126 -0
  11. package/dist/src/lib/allocationAllocateBuilder.d.ts.map +1 -0
  12. package/dist/src/lib/allocationAllocateBuilder.js +248 -0
  13. package/dist/src/lib/allocationAllocateWithdrawnBuilder.d.ts +67 -0
  14. package/dist/src/lib/allocationAllocateWithdrawnBuilder.d.ts.map +1 -0
  15. package/dist/src/lib/allocationAllocateWithdrawnBuilder.js +130 -0
  16. package/dist/src/lib/allocationRejectBuilder.d.ts +51 -0
  17. package/dist/src/lib/allocationRejectBuilder.d.ts.map +1 -0
  18. package/dist/src/lib/allocationRejectBuilder.js +107 -0
  19. package/dist/src/lib/allocationRequestBuilder.d.ts +116 -0
  20. package/dist/src/lib/allocationRequestBuilder.d.ts.map +1 -0
  21. package/dist/src/lib/allocationRequestBuilder.js +243 -0
  22. package/dist/src/lib/amount.d.ts +8 -0
  23. package/dist/src/lib/amount.d.ts.map +1 -0
  24. package/dist/src/lib/amount.js +33 -0
  25. package/dist/src/lib/cantonCommandBuilder.d.ts +72 -0
  26. package/dist/src/lib/cantonCommandBuilder.d.ts.map +1 -0
  27. package/dist/src/lib/cantonCommandBuilder.js +173 -0
  28. package/dist/src/lib/clearSigning.d.ts +58 -0
  29. package/dist/src/lib/clearSigning.d.ts.map +1 -0
  30. package/dist/src/lib/clearSigning.js +66 -0
  31. package/dist/src/lib/cosignDelegationAcceptBuilder.d.ts +56 -0
  32. package/dist/src/lib/cosignDelegationAcceptBuilder.d.ts.map +1 -0
  33. package/dist/src/lib/cosignDelegationAcceptBuilder.js +112 -0
  34. package/dist/src/lib/cosignDelegationProposalBuilder.d.ts +60 -0
  35. package/dist/src/lib/cosignDelegationProposalBuilder.d.ts.map +1 -0
  36. package/dist/src/lib/cosignDelegationProposalBuilder.js +111 -0
  37. package/dist/src/lib/endInvestorOnboardingOfferBuilder.d.ts +58 -0
  38. package/dist/src/lib/endInvestorOnboardingOfferBuilder.d.ts.map +1 -0
  39. package/dist/src/lib/endInvestorOnboardingOfferBuilder.js +112 -0
  40. package/dist/src/lib/iface.d.ts +141 -2
  41. package/dist/src/lib/iface.d.ts.map +1 -1
  42. package/dist/src/lib/iface.js +3 -1
  43. package/dist/src/lib/index.d.ts +13 -0
  44. package/dist/src/lib/index.d.ts.map +1 -1
  45. package/dist/src/lib/index.js +29 -2
  46. package/dist/src/lib/messages/cantonBaseMessage.d.ts +16 -0
  47. package/dist/src/lib/messages/cantonBaseMessage.d.ts.map +1 -0
  48. package/dist/src/lib/messages/cantonBaseMessage.js +28 -0
  49. package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessage.d.ts +14 -0
  50. package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessage.d.ts.map +1 -0
  51. package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessage.js +23 -0
  52. package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessageBuilder.d.ts +17 -0
  53. package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessageBuilder.d.ts.map +1 -0
  54. package/dist/src/lib/messages/cantonSignTopology/cantonSignTopologyMessageBuilder.js +25 -0
  55. package/dist/src/lib/messages/cantonSignTopology/index.d.ts +3 -0
  56. package/dist/src/lib/messages/cantonSignTopology/index.d.ts.map +1 -0
  57. package/dist/src/lib/messages/cantonSignTopology/index.js +19 -0
  58. package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessage.d.ts +13 -0
  59. package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessage.d.ts.map +1 -0
  60. package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessage.js +22 -0
  61. package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessageBuilder.d.ts +14 -0
  62. package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessageBuilder.d.ts.map +1 -0
  63. package/dist/src/lib/messages/cantonSignTransaction/cantonSignTransactionMessageBuilder.js +22 -0
  64. package/dist/src/lib/messages/cantonSignTransaction/index.d.ts +3 -0
  65. package/dist/src/lib/messages/cantonSignTransaction/index.d.ts.map +1 -0
  66. package/dist/src/lib/messages/cantonSignTransaction/index.js +19 -0
  67. package/dist/src/lib/messages/index.d.ts +5 -0
  68. package/dist/src/lib/messages/index.d.ts.map +1 -0
  69. package/dist/src/lib/messages/index.js +21 -0
  70. package/dist/src/lib/messages/messageBuilderFactory.d.ts +7 -0
  71. package/dist/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
  72. package/dist/src/lib/messages/messageBuilderFactory.js +23 -0
  73. package/dist/src/lib/oneStepPreApprovalBuilder.d.ts +8 -0
  74. package/dist/src/lib/oneStepPreApprovalBuilder.d.ts.map +1 -1
  75. package/dist/src/lib/oneStepPreApprovalBuilder.js +15 -1
  76. package/dist/src/lib/resourcesInterface.d.ts +1 -1
  77. package/dist/src/lib/resourcesInterface.d.ts.map +1 -1
  78. package/dist/src/lib/resourcesInterface.js +1 -1
  79. package/dist/src/lib/transaction/transaction.d.ts +17 -1
  80. package/dist/src/lib/transaction/transaction.d.ts.map +1 -1
  81. package/dist/src/lib/transaction/transaction.js +307 -16
  82. package/dist/src/lib/transactionBuilderFactory.d.ts +22 -0
  83. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  84. package/dist/src/lib/transactionBuilderFactory.js +78 -1
  85. package/dist/src/lib/transferAcknowledgeBuilder.d.ts +4 -4
  86. package/dist/src/lib/transferAcknowledgeBuilder.d.ts.map +1 -1
  87. package/dist/src/lib/transferAcknowledgeBuilder.js +5 -7
  88. package/dist/src/lib/transferBuilder.d.ts +84 -2
  89. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  90. package/dist/src/lib/transferBuilder.js +164 -2
  91. package/dist/src/lib/transferOfferWithdrawnBuilder.d.ts +67 -0
  92. package/dist/src/lib/transferOfferWithdrawnBuilder.d.ts.map +1 -0
  93. package/dist/src/lib/transferOfferWithdrawnBuilder.js +130 -0
  94. package/dist/src/lib/transferPreapprovalCancelBuilder.d.ts +68 -0
  95. package/dist/src/lib/transferPreapprovalCancelBuilder.d.ts.map +1 -0
  96. package/dist/src/lib/transferPreapprovalCancelBuilder.js +124 -0
  97. package/dist/src/lib/utils.d.ts +45 -3
  98. package/dist/src/lib/utils.d.ts.map +1 -1
  99. package/dist/src/lib/utils.js +776 -66
  100. package/dist/src/lib/walletInitBuilder.d.ts +2 -1
  101. package/dist/src/lib/walletInitBuilder.d.ts.map +1 -1
  102. package/dist/src/lib/walletInitBuilder.js +4 -1
  103. package/dist/src/lib/walletInitialization/walletInitTransaction.d.ts +2 -1
  104. package/dist/src/lib/walletInitialization/walletInitTransaction.d.ts.map +1 -1
  105. package/dist/src/lib/walletInitialization/walletInitTransaction.js +14 -1
  106. package/dist/src/register.d.ts +2 -0
  107. package/dist/src/register.d.ts.map +1 -1
  108. package/dist/src/register.js +19 -2
  109. package/dist/test/helper.d.ts +3 -0
  110. package/dist/test/helper.d.ts.map +1 -0
  111. package/dist/test/helper.js +9 -0
  112. package/dist/test/integration/canton.integration.d.ts +2 -0
  113. package/dist/test/integration/canton.integration.d.ts.map +1 -0
  114. package/dist/test/integration/canton.integration.js +157 -0
  115. package/dist/test/integration/canton.token.integration.d.ts +2 -0
  116. package/dist/test/integration/canton.token.integration.d.ts.map +1 -0
  117. package/dist/test/integration/canton.token.integration.js +51 -0
  118. package/dist/test/resources.d.ts +263 -2
  119. package/dist/test/resources.d.ts.map +1 -1
  120. package/dist/test/resources.js +269 -7
  121. package/dist/test/unit/builder/allocationAllocate/allocationAllocateBuilder.d.ts +2 -0
  122. package/dist/test/unit/builder/allocationAllocate/allocationAllocateBuilder.d.ts.map +1 -0
  123. package/dist/test/unit/builder/allocationAllocate/allocationAllocateBuilder.js +368 -0
  124. package/dist/test/unit/builder/allocationAllocateWithdrawn/allocationAllocateWithdrawnBuilder.d.ts +2 -0
  125. package/dist/test/unit/builder/allocationAllocateWithdrawn/allocationAllocateWithdrawnBuilder.d.ts.map +1 -0
  126. package/dist/test/unit/builder/allocationAllocateWithdrawn/allocationAllocateWithdrawnBuilder.js +133 -0
  127. package/dist/test/unit/builder/allocationReject/allocationRejectBuilder.d.ts +2 -0
  128. package/dist/test/unit/builder/allocationReject/allocationRejectBuilder.d.ts.map +1 -0
  129. package/dist/test/unit/builder/allocationReject/allocationRejectBuilder.js +121 -0
  130. package/dist/test/unit/builder/allocationRequest/allocationRequestBuilder.d.ts +2 -0
  131. package/dist/test/unit/builder/allocationRequest/allocationRequestBuilder.d.ts.map +1 -0
  132. package/dist/test/unit/builder/allocationRequest/allocationRequestBuilder.js +437 -0
  133. package/dist/test/unit/builder/cantonCommand/cantonCommandBuilder.d.ts +2 -0
  134. package/dist/test/unit/builder/cantonCommand/cantonCommandBuilder.d.ts.map +1 -0
  135. package/dist/test/unit/builder/cantonCommand/cantonCommandBuilder.js +340 -0
  136. package/dist/test/unit/builder/cosignDelegationAccept/cosignDelegationAcceptBuilder.d.ts +2 -0
  137. package/dist/test/unit/builder/cosignDelegationAccept/cosignDelegationAcceptBuilder.d.ts.map +1 -0
  138. package/dist/test/unit/builder/cosignDelegationAccept/cosignDelegationAcceptBuilder.js +116 -0
  139. package/dist/test/unit/builder/cosignDelegationProposal/cosignDelegationProposalBuilder.d.ts +2 -0
  140. package/dist/test/unit/builder/cosignDelegationProposal/cosignDelegationProposalBuilder.d.ts.map +1 -0
  141. package/dist/test/unit/builder/cosignDelegationProposal/cosignDelegationProposalBuilder.js +74 -0
  142. package/dist/test/unit/builder/endInvestorOnboardingOffer/endInvestorOnboardingOfferBuilder.d.ts +2 -0
  143. package/dist/test/unit/builder/endInvestorOnboardingOffer/endInvestorOnboardingOfferBuilder.d.ts.map +1 -0
  144. package/dist/test/unit/builder/endInvestorOnboardingOffer/endInvestorOnboardingOfferBuilder.js +116 -0
  145. package/dist/test/unit/builder/oneStepEnablement/oneStepEnablementBuilder.js +20 -1
  146. package/dist/test/unit/builder/transfer/transferBuilder.d.ts +2 -0
  147. package/dist/test/unit/builder/transfer/transferBuilder.d.ts.map +1 -0
  148. package/dist/test/unit/builder/transfer/transferBuilder.js +100 -0
  149. package/dist/test/unit/builder/transferAccept/transferAcceptBuilder.js +65 -1
  150. package/dist/test/unit/builder/transferAcknowledge/transferAcknowledgeBuilder.js +34 -1
  151. package/dist/test/unit/builder/transferOfferWithdrawn/transferOfferWithdrawnBuilder.d.ts +2 -0
  152. package/dist/test/unit/builder/transferOfferWithdrawn/transferOfferWithdrawnBuilder.d.ts.map +1 -0
  153. package/dist/test/unit/builder/transferOfferWithdrawn/transferOfferWithdrawnBuilder.js +64 -0
  154. package/dist/test/unit/builder/transferPreapprovalCancel/transferPreapprovalCancelBuilder.d.ts +2 -0
  155. package/dist/test/unit/builder/transferPreapprovalCancel/transferPreapprovalCancelBuilder.d.ts.map +1 -0
  156. package/dist/test/unit/builder/transferPreapprovalCancel/transferPreapprovalCancelBuilder.js +74 -0
  157. package/dist/test/unit/builder/transferReject/transferRejectBuilder.js +41 -1
  158. package/dist/test/unit/canton.d.ts +2 -0
  159. package/dist/test/unit/canton.d.ts.map +1 -0
  160. package/dist/test/unit/canton.js +853 -0
  161. package/dist/test/unit/index.d.ts +5 -0
  162. package/dist/test/unit/index.d.ts.map +1 -1
  163. package/dist/test/unit/index.js +6 -1
  164. package/dist/test/unit/messages/cantonSignTopologyMessage.d.ts +2 -0
  165. package/dist/test/unit/messages/cantonSignTopologyMessage.d.ts.map +1 -0
  166. package/dist/test/unit/messages/cantonSignTopologyMessage.js +46 -0
  167. package/dist/test/unit/messages/cantonSignTransactionMessage.d.ts +2 -0
  168. package/dist/test/unit/messages/cantonSignTransactionMessage.d.ts.map +1 -0
  169. package/dist/test/unit/messages/cantonSignTransactionMessage.js +48 -0
  170. package/dist/test/unit/messages/clearSigning.d.ts +2 -0
  171. package/dist/test/unit/messages/clearSigning.d.ts.map +1 -0
  172. package/dist/test/unit/messages/clearSigning.js +72 -0
  173. package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
  174. package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
  175. package/dist/test/unit/messages/messageBuilderFactory.js +52 -0
  176. package/dist/test/unit/register.d.ts +2 -0
  177. package/dist/test/unit/register.d.ts.map +1 -0
  178. package/dist/test/unit/register.js +65 -0
  179. package/dist/test/unit/utils.js +389 -9
  180. package/dist/tsconfig.tsbuildinfo +1 -1
  181. package/package.json +8 -8
@@ -0,0 +1,853 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("should");
4
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
5
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
6
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
7
+ const statics_1 = require("@bitgo-beta/statics");
8
+ const src_1 = require("../../src");
9
+ const resources_1 = require("../resources");
10
+ /**
11
+ * Builds a base64-encoded raw transaction for a OneStepPreApproval (enable token flow).
12
+ * For TSS wallets (which Canton always is), verifyTransaction receives txParams.enableTokens,
13
+ * not txParams.recipients. The wallet SDK's buildTokenEnablements passes enableTokens through
14
+ * unchanged for TSS wallets rather than converting them to recipients.
15
+ */
16
+ function buildOneStepPreApprovalRawTx(prepareResponse, commandId) {
17
+ const data = {
18
+ prepareCommandResponse: prepareResponse,
19
+ txType: 'OneStepPreApproval',
20
+ preparedTransaction: '',
21
+ partySignatures: { signatures: [] },
22
+ deduplicationPeriod: { Empty: {} },
23
+ submissionId: commandId,
24
+ hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V2',
25
+ minLedgerTime: { time: { Empty: {} } },
26
+ };
27
+ return Buffer.from(JSON.stringify(data)).toString('base64');
28
+ }
29
+ /** Returns a mock wallet whose coinSpecific().rootAddress matches the given party ID. */
30
+ function walletWithRootAddress(rootAddress) {
31
+ return { coinSpecific: () => ({ rootAddress }) };
32
+ }
33
+ /** Builds a base64-encoded raw transaction for a non-OneStep txType (e.g. AllocationReject). */
34
+ function buildRawTx(txType, prepareResponse, commandId) {
35
+ const data = {
36
+ prepareCommandResponse: prepareResponse,
37
+ txType,
38
+ preparedTransaction: '',
39
+ partySignatures: { signatures: [] },
40
+ deduplicationPeriod: { Empty: {} },
41
+ submissionId: commandId,
42
+ hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V2',
43
+ minLedgerTime: { time: { Empty: {} } },
44
+ };
45
+ return Buffer.from(JSON.stringify(data)).toString('base64');
46
+ }
47
+ describe('Canton coin:', function () {
48
+ let bitgo;
49
+ let basecoin;
50
+ before(function () {
51
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
52
+ bitgo.safeRegister('canton', src_1.Canton.createInstance);
53
+ bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
54
+ bitgo.initializeTestVars();
55
+ basecoin = bitgo.coin('tcanton');
56
+ });
57
+ describe('supportsMessageSigning', function () {
58
+ it('should return true', function () {
59
+ basecoin.supportsMessageSigning().should.equal(true);
60
+ });
61
+ });
62
+ });
63
+ describe('Canton verifyTransaction:', function () {
64
+ let bitgo;
65
+ let basecoin;
66
+ before(function () {
67
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
68
+ bitgo.safeRegister('canton', src_1.Canton.createInstance);
69
+ bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
70
+ bitgo.initializeTestVars();
71
+ basecoin = bitgo.coin('tcanton');
72
+ });
73
+ describe('OneStepPreApproval (enable token flow):', function () {
74
+ it('should return true when txParams has no type (non-enabletoken flow)', async function () {
75
+ const txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
76
+ const result = await basecoin.verifyTransaction({
77
+ txPrebuild: { txHex },
78
+ txParams: {},
79
+ wallet: {},
80
+ });
81
+ result.should.equal(true);
82
+ });
83
+ it('should return true when enableTokens is absent', async function () {
84
+ const txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
85
+ const result = await basecoin.verifyTransaction({
86
+ txPrebuild: { txHex },
87
+ txParams: { type: 'enabletoken' },
88
+ wallet: {},
89
+ });
90
+ result.should.equal(true);
91
+ });
92
+ it('should return true when enableTokens is empty', async function () {
93
+ const txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
94
+ const result = await basecoin.verifyTransaction({
95
+ txPrebuild: { txHex },
96
+ txParams: { type: 'enabletoken', enableTokens: [] },
97
+ wallet: {},
98
+ });
99
+ result.should.equal(true);
100
+ });
101
+ describe('coin pre-approval (TransferPreapprovalProposal):', function () {
102
+ let txHex;
103
+ let receiver;
104
+ before(function () {
105
+ txHex = buildOneStepPreApprovalRawTx(resources_1.OneStepPreApprovalPrepareResponse, resources_1.OneStepEnablement.commandId);
106
+ // Dynamically derive receiver from parsed transaction to avoid hardcoding protobuf-decoded addresses
107
+ const txBuilder = new src_1.TransactionBuilderFactory(statics_1.coins.get('tcanton')).from(txHex);
108
+ receiver = txBuilder.transaction.toJson().receiver;
109
+ });
110
+ it('should return true when wallet has no coinSpecific (receiver check skipped)', async function () {
111
+ // Typical case: wallet mock has no coinSpecific() method, and no address in enableTokens
112
+ const result = await basecoin.verifyTransaction({
113
+ txPrebuild: { txHex },
114
+ txParams: {
115
+ type: 'enabletoken',
116
+ enableTokens: [{ name: 'canton' }],
117
+ },
118
+ wallet: {},
119
+ });
120
+ result.should.equal(true);
121
+ });
122
+ it('should return true when wallet rootAddress matches receiver', async function () {
123
+ // Typical UI flow: enableTokens has no address, receiver validated from wallet.coinSpecific().rootAddress
124
+ const result = await basecoin.verifyTransaction({
125
+ txPrebuild: { txHex },
126
+ txParams: {
127
+ type: 'enabletoken',
128
+ enableTokens: [{ name: 'canton' }],
129
+ },
130
+ wallet: walletWithRootAddress(receiver),
131
+ });
132
+ result.should.equal(true);
133
+ });
134
+ it('should return true when enableToken.address matches receiver (explicit address)', async function () {
135
+ const result = await basecoin.verifyTransaction({
136
+ txPrebuild: { txHex },
137
+ txParams: {
138
+ type: 'enabletoken',
139
+ enableTokens: [{ name: 'canton', address: receiver }],
140
+ },
141
+ wallet: {},
142
+ });
143
+ result.should.equal(true);
144
+ });
145
+ it('should throw when wallet rootAddress does not match receiver', async function () {
146
+ const wrongAddress = 'wrong-party::1220aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
147
+ await basecoin
148
+ .verifyTransaction({
149
+ txPrebuild: { txHex },
150
+ txParams: {
151
+ type: 'enabletoken',
152
+ enableTokens: [{ name: 'canton' }],
153
+ },
154
+ wallet: walletWithRootAddress(wrongAddress),
155
+ })
156
+ .should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
157
+ });
158
+ it('should throw when explicit enableToken.address does not match receiver', async function () {
159
+ const wrongAddress = 'wrong-party::1220aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
160
+ await basecoin
161
+ .verifyTransaction({
162
+ txPrebuild: { txHex },
163
+ txParams: {
164
+ type: 'enabletoken',
165
+ enableTokens: [{ name: 'canton', address: wrongAddress }],
166
+ },
167
+ wallet: {},
168
+ })
169
+ .should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
170
+ });
171
+ });
172
+ describe('token pre-approval (TransferPreapproval):', function () {
173
+ let txHex;
174
+ let receiver;
175
+ before(function () {
176
+ const commandId = '7d99789d-2f22-49e1-85cb-79d2ce5a69c1';
177
+ txHex = buildOneStepPreApprovalRawTx(resources_1.CantonTokenPreApprovalPrepareResponse, commandId);
178
+ const txBuilder = new src_1.TransactionBuilderFactory(statics_1.coins.get('tcanton')).from(txHex);
179
+ receiver = txBuilder.transaction.toJson().receiver;
180
+ });
181
+ it('should return true when wallet rootAddress matches receiver', async function () {
182
+ const result = await basecoin.verifyTransaction({
183
+ txPrebuild: { txHex },
184
+ txParams: {
185
+ type: 'enabletoken',
186
+ enableTokens: [{ name: 'tcanton:testcoin1' }],
187
+ },
188
+ wallet: walletWithRootAddress(receiver),
189
+ });
190
+ result.should.equal(true);
191
+ });
192
+ it('should return true when enableToken.address matches receiver (explicit address)', async function () {
193
+ const result = await basecoin.verifyTransaction({
194
+ txPrebuild: { txHex },
195
+ txParams: {
196
+ type: 'enabletoken',
197
+ enableTokens: [{ name: 'tcanton:testcoin1', address: receiver }],
198
+ },
199
+ wallet: {},
200
+ });
201
+ result.should.equal(true);
202
+ });
203
+ it('should throw when wallet rootAddress does not match receiver', async function () {
204
+ const wrongAddress = 'wrong-party::1220bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
205
+ await basecoin
206
+ .verifyTransaction({
207
+ txPrebuild: { txHex },
208
+ txParams: {
209
+ type: 'enabletoken',
210
+ enableTokens: [{ name: 'tcanton:testcoin1' }],
211
+ },
212
+ wallet: walletWithRootAddress(wrongAddress),
213
+ })
214
+ .should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
215
+ });
216
+ it('should throw when explicit enableToken.address does not match receiver', async function () {
217
+ const wrongAddress = 'wrong-party::1220bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
218
+ await basecoin
219
+ .verifyTransaction({
220
+ txPrebuild: { txHex },
221
+ txParams: {
222
+ type: 'enabletoken',
223
+ enableTokens: [{ name: 'tcanton:testcoin1', address: wrongAddress }],
224
+ },
225
+ wallet: {},
226
+ })
227
+ .should.be.rejectedWith(/OneStepPreApproval receiver mismatch/);
228
+ });
229
+ });
230
+ });
231
+ describe('TransferPreapprovalCancel (disable token flow):', function () {
232
+ // Real captured TransferPreapproval_Cancel exercise-node fixture: parsed sender === receiver
233
+ // === CancelParty, matching the actual on-chain choice/actingParties shape.
234
+ it('should return true when txParams has no type (non-disabletoken flow)', async function () {
235
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
236
+ const result = await basecoin.verifyTransaction({
237
+ txPrebuild: { txHex },
238
+ txParams: {},
239
+ wallet: {},
240
+ });
241
+ result.should.equal(true);
242
+ });
243
+ it('should return true when enableTokens is absent', async function () {
244
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
245
+ const result = await basecoin.verifyTransaction({
246
+ txPrebuild: { txHex },
247
+ txParams: { type: 'disabletoken' },
248
+ wallet: {},
249
+ });
250
+ result.should.equal(true);
251
+ });
252
+ it('should return true when enableTokens is empty', async function () {
253
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
254
+ const result = await basecoin.verifyTransaction({
255
+ txPrebuild: { txHex },
256
+ txParams: { type: 'disabletoken', enableTokens: [] },
257
+ wallet: {},
258
+ });
259
+ result.should.equal(true);
260
+ });
261
+ it('should return true when wallet has no coinSpecific and no explicit address (receiver check skipped)', async function () {
262
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
263
+ const result = await basecoin.verifyTransaction({
264
+ txPrebuild: { txHex },
265
+ txParams: {
266
+ type: 'disabletoken',
267
+ enableTokens: [{ name: 'canton' }],
268
+ },
269
+ wallet: {},
270
+ });
271
+ result.should.equal(true);
272
+ });
273
+ it('should return true when wallet rootAddress matches the parsed receiver', async function () {
274
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
275
+ const result = await basecoin.verifyTransaction({
276
+ txPrebuild: { txHex },
277
+ txParams: {
278
+ type: 'disabletoken',
279
+ enableTokens: [{ name: 'canton' }],
280
+ },
281
+ wallet: walletWithRootAddress(resources_1.CancelParty),
282
+ });
283
+ result.should.equal(true);
284
+ });
285
+ it('should return true when explicit enableToken.address matches the parsed receiver', async function () {
286
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
287
+ const result = await basecoin.verifyTransaction({
288
+ txPrebuild: { txHex },
289
+ txParams: {
290
+ type: 'disabletoken',
291
+ enableTokens: [{ name: 'canton', address: resources_1.CancelParty }],
292
+ },
293
+ wallet: {},
294
+ });
295
+ result.should.equal(true);
296
+ });
297
+ it('should throw when wallet rootAddress does not match the parsed receiver', async function () {
298
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
299
+ const someAddress = 'some-party::1220aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
300
+ await basecoin
301
+ .verifyTransaction({
302
+ txPrebuild: { txHex },
303
+ txParams: {
304
+ type: 'disabletoken',
305
+ enableTokens: [{ name: 'canton' }],
306
+ },
307
+ wallet: walletWithRootAddress(someAddress),
308
+ })
309
+ .should.be.rejectedWith(/TransferPreapprovalCancel receiver mismatch/);
310
+ });
311
+ it('should throw when explicit enableToken.address does not match the parsed receiver', async function () {
312
+ const txHex = buildRawTx('TransferPreapprovalCancel', resources_1.TransferPreapprovalCancelPrepareResponse, resources_1.OneStepEnablement.commandId);
313
+ const someAddress = 'some-party::1220aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
314
+ await basecoin
315
+ .verifyTransaction({
316
+ txPrebuild: { txHex },
317
+ txParams: {
318
+ type: 'disabletoken',
319
+ enableTokens: [{ name: 'canton', address: someAddress }],
320
+ },
321
+ wallet: {},
322
+ })
323
+ .should.be.rejectedWith(/TransferPreapprovalCancel receiver mismatch/);
324
+ });
325
+ });
326
+ });
327
+ describe('Canton verifyTransaction - AllocationReject:', function () {
328
+ let bitgo;
329
+ let basecoin;
330
+ before(function () {
331
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
332
+ bitgo.safeRegister('canton', src_1.Canton.createInstance);
333
+ bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
334
+ bitgo.initializeTestVars();
335
+ basecoin = bitgo.coin('tcanton');
336
+ });
337
+ it('should return true for an AllocationReject transaction (no recipient info to verify)', async function () {
338
+ const txHex = buildRawTx('AllocationReject', resources_1.CantonAllocationRejectPrepareResponse, resources_1.AllocationRejection.commandId);
339
+ const result = await basecoin.verifyTransaction({
340
+ txPrebuild: { txHex },
341
+ txParams: {},
342
+ wallet: {},
343
+ });
344
+ result.should.equal(true);
345
+ });
346
+ });
347
+ describe('Canton explainTransaction - AllocationReject:', function () {
348
+ it('should return an empty explanation (no funds move on an AllocationRequest reject)', function () {
349
+ // AllocationRequest_Reject fires before the actor has allocated their leg — no Holding
350
+ // was ever locked for this trade, so nothing is returned. Unlike TransferReject (which
351
+ // unwinds a real fund movement), this is a pure "decline to trade" signal with no
352
+ // balance impact, so it intentionally falls through to the default (empty) explanation
353
+ // rather than being reported as an input.
354
+ const tx = new src_1.Transaction(statics_1.coins.get('tcanton'));
355
+ tx.id = resources_1.AllocationRejection.commandId;
356
+ tx.transactionType = sdk_core_1.TransactionType.AllocationReject;
357
+ tx.prepareCommand = resources_1.CantonAllocationRejectPrepareResponse;
358
+ const explanation = tx.explainTransaction();
359
+ explanation.inputs.length.should.equal(0);
360
+ explanation.inputAmount.should.equal('0');
361
+ explanation.outputs.length.should.equal(0);
362
+ explanation.outputAmount.should.equal('0');
363
+ });
364
+ });
365
+ // --------------- ExerciseCommand verification tests ---------------
366
+ const CANTON_CMD_ACT_AS = 'RegRegistrar::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5';
367
+ const CANTON_CMD_TEMPLATE_ID = '7a75ef6e69f69395a4e60919e228528bb8f3881150ccfde3f31bcc73864b18ab:Utility.Registry.App.V0.Service.AllocationFactory:AllocationFactory';
368
+ const CANTON_CMD_CONTRACT_ID = '00f3afdce846a40c6f3f618c4b584b022a0197010057ecd59458200183ab27de0aca1212204aef7ede37a5f41b674a1d95446d42a404461c5558c4e6d1860b65560120ef18';
369
+ const CANTON_CMD_CHOICE = 'AllocationFactory_OfferMint';
370
+ function buildCantonCommandRawTx(prepareResponse, commandId) {
371
+ const data = {
372
+ prepareCommandResponse: prepareResponse,
373
+ txType: 'CantonCommand',
374
+ preparedTransaction: '',
375
+ partySignatures: { signatures: [] },
376
+ deduplicationPeriod: { Empty: {} },
377
+ submissionId: commandId,
378
+ hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V2',
379
+ minLedgerTime: { time: { Empty: {} } },
380
+ };
381
+ return Buffer.from(JSON.stringify(data)).toString('base64');
382
+ }
383
+ describe('Canton verifyTransaction - CantonCommand:', function () {
384
+ let bitgo;
385
+ let basecoin;
386
+ before(function () {
387
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
388
+ bitgo.safeRegister('canton', src_1.Canton.createInstance);
389
+ bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
390
+ bitgo.initializeTestVars();
391
+ basecoin = bitgo.coin('tcanton');
392
+ });
393
+ describe('Happy path tests:', function () {
394
+ let txHex;
395
+ before(function () {
396
+ txHex = buildCantonCommandRawTx(resources_1.CantonExerciseCommandPrepareResponse, 'test-canton-cmd-001');
397
+ });
398
+ it('should return true when cantonCommandParams is undefined (no user params to verify)', async function () {
399
+ const result = await basecoin.verifyTransaction({
400
+ txPrebuild: { txHex },
401
+ txParams: {},
402
+ wallet: {},
403
+ });
404
+ result.should.equal(true);
405
+ });
406
+ it('should return true for matching ExerciseCommand (templateId, choice, contractId, actAs, argument)', async function () {
407
+ const result = await basecoin.verifyTransaction({
408
+ txPrebuild: { txHex },
409
+ txParams: {
410
+ cantonCommandParams: {
411
+ command: {
412
+ ExerciseCommand: {
413
+ templateId: CANTON_CMD_TEMPLATE_ID,
414
+ contractId: CANTON_CMD_CONTRACT_ID,
415
+ choice: CANTON_CMD_CHOICE,
416
+ choiceArgument: {
417
+ expectedAdmin: CANTON_CMD_ACT_AS,
418
+ mint: {
419
+ instrumentId: {
420
+ admin: CANTON_CMD_ACT_AS,
421
+ id: 'TESTTOKEN',
422
+ },
423
+ amount: '100',
424
+ holder: 'RegIssuer::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5',
425
+ reference: 'test-prepare-mint',
426
+ },
427
+ },
428
+ },
429
+ },
430
+ actAs: [CANTON_CMD_ACT_AS],
431
+ readAs: [],
432
+ },
433
+ },
434
+ wallet: {},
435
+ });
436
+ result.should.equal(true);
437
+ });
438
+ it('should return true when contractId is omitted (IMS-resolved)', async function () {
439
+ const result = await basecoin.verifyTransaction({
440
+ txPrebuild: { txHex },
441
+ txParams: {
442
+ cantonCommandParams: {
443
+ command: {
444
+ ExerciseCommand: {
445
+ templateId: CANTON_CMD_TEMPLATE_ID,
446
+ choice: CANTON_CMD_CHOICE,
447
+ choiceArgument: {},
448
+ },
449
+ },
450
+ actAs: [CANTON_CMD_ACT_AS],
451
+ readAs: [],
452
+ },
453
+ },
454
+ wallet: {},
455
+ });
456
+ result.should.equal(true);
457
+ });
458
+ it('should return true with resolveContracts injectAs skipping contractId (empty contractId)', async function () {
459
+ const result = await basecoin.verifyTransaction({
460
+ txPrebuild: { txHex },
461
+ txParams: {
462
+ cantonCommandParams: {
463
+ command: {
464
+ ExerciseCommand: {
465
+ templateId: CANTON_CMD_TEMPLATE_ID,
466
+ contractId: '',
467
+ choice: CANTON_CMD_CHOICE,
468
+ choiceArgument: {},
469
+ },
470
+ },
471
+ actAs: [CANTON_CMD_ACT_AS],
472
+ readAs: [],
473
+ resolveContracts: [
474
+ {
475
+ templateId: CANTON_CMD_TEMPLATE_ID,
476
+ actAs: [CANTON_CMD_ACT_AS],
477
+ injectAs: 'command.ExerciseCommand.contractId',
478
+ },
479
+ ],
480
+ },
481
+ },
482
+ wallet: {},
483
+ });
484
+ result.should.equal(true);
485
+ });
486
+ it('should return true with resolveContracts injectAs skipping non-empty contractId mismatch', async function () {
487
+ // User supplies a placeholder contractId that doesn't match what's on-chain;
488
+ // resolveContracts marks it as IMS-injected, so the mismatch must be ignored.
489
+ const result = await basecoin.verifyTransaction({
490
+ txPrebuild: { txHex },
491
+ txParams: {
492
+ cantonCommandParams: {
493
+ command: {
494
+ ExerciseCommand: {
495
+ templateId: CANTON_CMD_TEMPLATE_ID,
496
+ contractId: '00placeholder_contract_id_not_on_chain',
497
+ choice: CANTON_CMD_CHOICE,
498
+ choiceArgument: {},
499
+ },
500
+ },
501
+ actAs: [CANTON_CMD_ACT_AS],
502
+ readAs: [],
503
+ resolveContracts: [
504
+ {
505
+ templateId: CANTON_CMD_TEMPLATE_ID,
506
+ actAs: [CANTON_CMD_ACT_AS],
507
+ injectAs: 'command.ExerciseCommand.contractId',
508
+ },
509
+ ],
510
+ },
511
+ },
512
+ wallet: {},
513
+ });
514
+ result.should.equal(true);
515
+ });
516
+ });
517
+ describe('Error cases:', function () {
518
+ let txHex;
519
+ before(function () {
520
+ txHex = buildCantonCommandRawTx(resources_1.CantonExerciseCommandPrepareResponse, 'test-canton-cmd-002');
521
+ });
522
+ it('should throw when preparedTransaction is missing on tx prebuild', async function () {
523
+ const emptyPrepare = { ...resources_1.CantonExerciseCommandPrepareResponse, preparedTransaction: undefined };
524
+ const badTx = buildCantonCommandRawTx(emptyPrepare, 'cmd-bad');
525
+ await basecoin
526
+ .verifyTransaction({
527
+ txPrebuild: { txHex: badTx },
528
+ txParams: {
529
+ cantonCommandParams: {
530
+ command: {
531
+ ExerciseCommand: { templateId: CANTON_CMD_TEMPLATE_ID, choice: CANTON_CMD_CHOICE, choiceArgument: {} },
532
+ },
533
+ actAs: [CANTON_CMD_ACT_AS],
534
+ },
535
+ },
536
+ wallet: {},
537
+ })
538
+ .should.be.rejectedWith(/missing preparedTransaction/);
539
+ });
540
+ it('should throw when user command has neither CreateCommand nor ExerciseCommand', async function () {
541
+ await basecoin
542
+ .verifyTransaction({
543
+ txPrebuild: { txHex },
544
+ txParams: {
545
+ cantonCommandParams: {
546
+ command: { UnknownCommand: {} },
547
+ actAs: [CANTON_CMD_ACT_AS],
548
+ },
549
+ },
550
+ wallet: {},
551
+ })
552
+ .should.be.rejectedWith(/must contain a CreateCommand or ExerciseCommand/);
553
+ });
554
+ it('should throw when user command contains both CreateCommand and ExerciseCommand', async function () {
555
+ await basecoin
556
+ .verifyTransaction({
557
+ txPrebuild: { txHex },
558
+ txParams: {
559
+ cantonCommandParams: {
560
+ command: {
561
+ CreateCommand: { templateId: CANTON_CMD_TEMPLATE_ID, createArguments: {} },
562
+ ExerciseCommand: { templateId: CANTON_CMD_TEMPLATE_ID, choice: CANTON_CMD_CHOICE, choiceArgument: {} },
563
+ },
564
+ actAs: [CANTON_CMD_ACT_AS],
565
+ },
566
+ },
567
+ wallet: {},
568
+ })
569
+ .should.be.rejectedWith(/exactly one of CreateCommand or ExerciseCommand/);
570
+ });
571
+ it('should throw on invalid user templateId format', async function () {
572
+ await basecoin
573
+ .verifyTransaction({
574
+ txPrebuild: { txHex },
575
+ txParams: {
576
+ cantonCommandParams: {
577
+ command: {
578
+ ExerciseCommand: {
579
+ templateId: 'InvalidFormat',
580
+ choice: CANTON_CMD_CHOICE,
581
+ choiceArgument: {},
582
+ },
583
+ },
584
+ actAs: [CANTON_CMD_ACT_AS],
585
+ },
586
+ },
587
+ wallet: {},
588
+ })
589
+ .should.be.rejectedWith(/invalid user templateId/);
590
+ });
591
+ it('should throw on templateId module/entity mismatch', async function () {
592
+ await basecoin
593
+ .verifyTransaction({
594
+ txPrebuild: { txHex },
595
+ txParams: {
596
+ cantonCommandParams: {
597
+ command: {
598
+ ExerciseCommand: {
599
+ templateId: 'SomePkg:Wrong.Module:WrongEntity',
600
+ choice: CANTON_CMD_CHOICE,
601
+ choiceArgument: {},
602
+ },
603
+ },
604
+ actAs: [CANTON_CMD_ACT_AS],
605
+ },
606
+ },
607
+ wallet: {},
608
+ })
609
+ .should.be.rejectedWith(/templateId mismatch/);
610
+ });
611
+ it('should throw on submitterInfo.actAs mismatch', async function () {
612
+ await basecoin
613
+ .verifyTransaction({
614
+ txPrebuild: { txHex },
615
+ txParams: {
616
+ cantonCommandParams: {
617
+ command: {
618
+ ExerciseCommand: {
619
+ templateId: CANTON_CMD_TEMPLATE_ID,
620
+ choice: CANTON_CMD_CHOICE,
621
+ choiceArgument: {},
622
+ },
623
+ },
624
+ actAs: ['WrongParty::1220aaaa'],
625
+ },
626
+ },
627
+ wallet: {},
628
+ })
629
+ .should.be.rejectedWith(/submitterInfo.actAs.*does not match user actAs/);
630
+ });
631
+ it('should throw on choice mismatch for ExerciseCommand', async function () {
632
+ await basecoin
633
+ .verifyTransaction({
634
+ txPrebuild: { txHex },
635
+ txParams: {
636
+ cantonCommandParams: {
637
+ command: {
638
+ ExerciseCommand: {
639
+ templateId: CANTON_CMD_TEMPLATE_ID,
640
+ choice: 'WrongChoice',
641
+ choiceArgument: {},
642
+ },
643
+ },
644
+ actAs: [CANTON_CMD_ACT_AS],
645
+ },
646
+ },
647
+ wallet: {},
648
+ })
649
+ .should.be.rejectedWith(/choice mismatch/);
650
+ });
651
+ it('should throw on contractId mismatch when user provides explicit contractId', async function () {
652
+ await basecoin
653
+ .verifyTransaction({
654
+ txPrebuild: { txHex },
655
+ txParams: {
656
+ cantonCommandParams: {
657
+ command: {
658
+ ExerciseCommand: {
659
+ templateId: CANTON_CMD_TEMPLATE_ID,
660
+ contractId: '00wrongcontractid',
661
+ choice: CANTON_CMD_CHOICE,
662
+ choiceArgument: {},
663
+ },
664
+ },
665
+ actAs: [CANTON_CMD_ACT_AS],
666
+ },
667
+ },
668
+ wallet: {},
669
+ })
670
+ .should.be.rejectedWith(/contractId mismatch/);
671
+ });
672
+ it('should throw on argument deep mismatch', async function () {
673
+ await basecoin
674
+ .verifyTransaction({
675
+ txPrebuild: { txHex },
676
+ txParams: {
677
+ cantonCommandParams: {
678
+ command: {
679
+ ExerciseCommand: {
680
+ templateId: CANTON_CMD_TEMPLATE_ID,
681
+ choice: CANTON_CMD_CHOICE,
682
+ choiceArgument: {
683
+ expectedAdmin: 'WrongParty::totally-different',
684
+ },
685
+ },
686
+ },
687
+ actAs: [CANTON_CMD_ACT_AS],
688
+ },
689
+ },
690
+ wallet: {},
691
+ })
692
+ .should.be.rejectedWith(/mismatch/);
693
+ });
694
+ });
695
+ });
696
+ // --------------- CreateCommand verification tests ---------------
697
+ const CREATE_CMD_ACT_AS = 'RegProvider::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5';
698
+ const CREATE_CMD_TEMPLATE_ID = '7a75ef6e69f69395a4e60919e228528bb8f3881150ccfde3f31bcc73864b18ab:Utility.Registry.App.V0.Service.Provider:ProviderServiceRequest';
699
+ const CREATE_CMD_OPERATOR = 'RegOperator::1220508e54fb709dcb1a9b4096408ad415d2217d8881ad9034a9850752933ba88ad5';
700
+ describe('Canton verifyTransaction - CreateCommand:', function () {
701
+ let bitgo;
702
+ let basecoin;
703
+ before(function () {
704
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
705
+ bitgo.safeRegister('canton', src_1.Canton.createInstance);
706
+ bitgo.safeRegister('tcanton', src_1.Tcanton.createInstance);
707
+ bitgo.initializeTestVars();
708
+ basecoin = bitgo.coin('tcanton');
709
+ });
710
+ describe('Happy path tests:', function () {
711
+ let txHex;
712
+ before(function () {
713
+ txHex = buildCantonCommandRawTx(resources_1.CantonCreateCommandPrepareResponse, 'test-create-cmd-001');
714
+ });
715
+ it('should return true for matching CreateCommand (templateId, createArguments, actAs)', async function () {
716
+ const result = await basecoin.verifyTransaction({
717
+ txPrebuild: { txHex },
718
+ txParams: {
719
+ cantonCommandParams: {
720
+ command: {
721
+ CreateCommand: {
722
+ templateId: CREATE_CMD_TEMPLATE_ID,
723
+ createArguments: {
724
+ operator: CREATE_CMD_OPERATOR,
725
+ provider: CREATE_CMD_ACT_AS,
726
+ },
727
+ },
728
+ },
729
+ actAs: [CREATE_CMD_ACT_AS],
730
+ readAs: [],
731
+ },
732
+ },
733
+ wallet: {},
734
+ });
735
+ result.should.equal(true);
736
+ });
737
+ it('should return true when createArguments is empty (no deep-compare)', async function () {
738
+ const result = await basecoin.verifyTransaction({
739
+ txPrebuild: { txHex },
740
+ txParams: {
741
+ cantonCommandParams: {
742
+ command: {
743
+ CreateCommand: {
744
+ templateId: CREATE_CMD_TEMPLATE_ID,
745
+ createArguments: {},
746
+ },
747
+ },
748
+ actAs: [CREATE_CMD_ACT_AS],
749
+ readAs: [],
750
+ },
751
+ },
752
+ wallet: {},
753
+ });
754
+ result.should.equal(true);
755
+ });
756
+ it('should return true with resolveContracts injectAs skipping createArguments field', async function () {
757
+ const result = await basecoin.verifyTransaction({
758
+ txPrebuild: { txHex },
759
+ txParams: {
760
+ cantonCommandParams: {
761
+ command: {
762
+ CreateCommand: {
763
+ templateId: CREATE_CMD_TEMPLATE_ID,
764
+ createArguments: {
765
+ operator: 'placeholder-operator-id',
766
+ provider: CREATE_CMD_ACT_AS,
767
+ },
768
+ },
769
+ },
770
+ actAs: [CREATE_CMD_ACT_AS],
771
+ readAs: [],
772
+ resolveContracts: [
773
+ {
774
+ templateId: 'some-template',
775
+ actAs: [CREATE_CMD_ACT_AS],
776
+ injectAs: 'command.CreateCommand.createArguments.operator',
777
+ },
778
+ ],
779
+ },
780
+ },
781
+ wallet: {},
782
+ });
783
+ result.should.equal(true);
784
+ });
785
+ });
786
+ describe('Error cases:', function () {
787
+ let txHex;
788
+ before(function () {
789
+ txHex = buildCantonCommandRawTx(resources_1.CantonCreateCommandPrepareResponse, 'test-create-cmd-err');
790
+ });
791
+ it('should throw on templateId mismatch for CreateCommand', async function () {
792
+ await basecoin
793
+ .verifyTransaction({
794
+ txPrebuild: { txHex },
795
+ txParams: {
796
+ cantonCommandParams: {
797
+ command: {
798
+ CreateCommand: {
799
+ templateId: 'WrongPkg:Wrong.Module:WrongEntity',
800
+ createArguments: {},
801
+ },
802
+ },
803
+ actAs: [CREATE_CMD_ACT_AS],
804
+ },
805
+ },
806
+ wallet: {},
807
+ })
808
+ .should.be.rejectedWith(/templateId mismatch/);
809
+ });
810
+ it('should throw on createArguments deep mismatch', async function () {
811
+ await basecoin
812
+ .verifyTransaction({
813
+ txPrebuild: { txHex },
814
+ txParams: {
815
+ cantonCommandParams: {
816
+ command: {
817
+ CreateCommand: {
818
+ templateId: CREATE_CMD_TEMPLATE_ID,
819
+ createArguments: {
820
+ operator: 'WrongOperator::totally-different',
821
+ provider: CREATE_CMD_ACT_AS,
822
+ },
823
+ },
824
+ },
825
+ actAs: [CREATE_CMD_ACT_AS],
826
+ },
827
+ },
828
+ wallet: {},
829
+ })
830
+ .should.be.rejectedWith(/mismatch/);
831
+ });
832
+ it('should throw on actAs mismatch for CreateCommand', async function () {
833
+ await basecoin
834
+ .verifyTransaction({
835
+ txPrebuild: { txHex },
836
+ txParams: {
837
+ cantonCommandParams: {
838
+ command: {
839
+ CreateCommand: {
840
+ templateId: CREATE_CMD_TEMPLATE_ID,
841
+ createArguments: {},
842
+ },
843
+ },
844
+ actAs: ['WrongParty::1220aaaa'],
845
+ },
846
+ },
847
+ wallet: {},
848
+ })
849
+ .should.be.rejectedWith(/submitterInfo.actAs.*does not match user actAs/);
850
+ });
851
+ });
852
+ });
853
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FudG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2NhbnRvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGtCQUFnQjtBQUNoQixpREFBK0M7QUFDL0MsbURBQStEO0FBQy9ELG1EQUErRTtBQUMvRSxpREFBNEM7QUFFNUMsbUNBQTZHO0FBRTdHLDRDQVVzQjtBQUV0Qjs7Ozs7R0FLRztBQUNILFNBQVMsNEJBQTRCLENBQ25DLGVBQXlELEVBQ3pELFNBQWlCO0lBRWpCLE1BQU0sSUFBSSxHQUFHO1FBQ1gsc0JBQXNCLEVBQUUsZUFBZTtRQUN2QyxNQUFNLEVBQUUsb0JBQW9CO1FBQzVCLG1CQUFtQixFQUFFLEVBQUU7UUFDdkIsZUFBZSxFQUFFLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRTtRQUNuQyxtQkFBbUIsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUU7UUFDbEMsWUFBWSxFQUFFLFNBQVM7UUFDdkIsb0JBQW9CLEVBQUUsMkJBQTJCO1FBQ2pELGFBQWEsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRTtLQUN2QyxDQUFDO0lBQ0YsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDOUQsQ0FBQztBQUVELHlGQUF5RjtBQUN6RixTQUFTLHFCQUFxQixDQUFDLFdBQW1CO0lBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQXdCLENBQUM7QUFDekUsQ0FBQztBQUVELGdHQUFnRztBQUNoRyxTQUFTLFVBQVUsQ0FBQyxNQUFjLEVBQUUsZUFBd0IsRUFBRSxTQUFpQjtJQUM3RSxNQUFNLElBQUksR0FBRztRQUNYLHNCQUFzQixFQUFFLGVBQWU7UUFDdkMsTUFB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QUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0RBQWtELEVBQUUsS0FBSztZQUMxRCxNQUFNLFFBQVE7aUJBQ1gsaUJBQWlCLENBQUM7Z0JBQ2pCLFVBQVUsRUFBRSxFQUFFLEtBQUssRUFBRTtnQkFDckIsUUFBUSxFQUFFO29CQUNSLG1CQUFtQixFQUFFO3dCQUNuQixPQUFPLEVBQUU7NEJBQ1AsYUFBYSxFQUFFO2dDQUNiLFVBQVUsRUFBRSxzQkFBc0I7Z0NBQ2xDLGVBQWUsRUFBRSxFQUFFOzZCQUNwQjt5QkFDRjt3QkFDRCxLQUFLLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQztxQkFDaEM7aUJBQ3lCO2dCQUM1QixNQUFNLEVBQUUsRUFBYTthQUN0QixDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGdEQUFnRCxDQUFDLENBQUM7UUFDOUUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICdzaG91bGQnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgQ2FudG9uQ29tbWFuZCwgSVdhbGxldCwgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgY29pbnMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcblxuaW1wb3J0IHsgQ2FudG9uLCBDYW50b25UcmFuc2FjdGlvblBhcmFtcywgVGNhbnRvbiwgVHJhbnNhY3Rpb24sIFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkgfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IHsgQ2FudG9uUHJlcGFyZUNvbW1hbmRSZXNwb25zZSB9IGZyb20gJy4uLy4uL3NyYy9saWIvaWZhY2UnO1xuaW1wb3J0IHtcbiAgQWxsb2NhdGlvblJlamVjdGlvbixcbiAgQ2FudG9uQWxsb2NhdGlvblJlamVjdFByZXBhcmVSZXNwb25zZSxcbiAgQ2FudG9uRXhlcmNpc2VDb21tYW5kUHJlcGFyZVJlc3BvbnNlLFxuICBDYW50b25DcmVhdGVDb21tYW5kUHJlcGFyZVJlc3BvbnNlLFxuICBDYW50b25Ub2tlblByZUFwcHJvdmFsUHJlcGFyZVJlc3BvbnNlLFxuICBDYW5jZWxQYXJ0eSxcbiAgT25lU3RlcEVuYWJsZW1lbnQsXG4gIE9uZVN0ZXBQcmVBcHByb3ZhbFByZXBhcmVSZXNwb25zZSxcbiAgVHJhbnNmZXJQcmVhcHByb3ZhbENhbmNlbFByZXBhcmVSZXNwb25zZSxcbn0gZnJvbSAnLi4vcmVzb3VyY2VzJztcblxuLyoqXG4gKiBCdWlsZHMgYSBiYXNlNjQtZW5jb2RlZCByYXcgdHJhbnNhY3Rpb24gZm9yIGEgT25lU3RlcFByZUFwcHJvdmFsIChlbmFibGUgdG9rZW4gZmxvdykuXG4gKiBGb3IgVFNTIHdhbGxldHMgKHdoaWNoIENhbnRvbiBhbHdheXMgaXMpLCB2ZXJpZnlUcmFuc2FjdGlvbiByZWNlaXZlcyB0eFBhcmFtcy5lbmFibGVUb2tlbnMsXG4gKiBub3QgdHhQYXJhbXMucmVjaXBpZW50cy4gVGhlIHdhbGxldCBTREsncyBidWlsZFRva2VuRW5hYmxlbWVudHMgcGFzc2VzIGVuYWJsZVRva2VucyB0aHJvdWdoXG4gKiB1bmNoYW5nZWQgZm9yIFRTUyB3YWxsZXRzIHJhdGhlciB0aGFuIGNvbnZlcnRpbmcgdGhlbSB0byByZWNpcGllbnRzLlxuICovXG5mdW5jdGlvbiBidWlsZE9uZVN0ZXBQcmVBcHByb3ZhbFJhd1R4KFxuICBwcmVwYXJlUmVzcG9uc2U6IHR5cGVvZiBPbmVTdGVwUHJlQXBwcm92YWxQcmVwYXJlUmVzcG9uc2UsXG4gIGNvbW1hbmRJZDogc3RyaW5nXG4pOiBzdHJpbmcge1xuICBjb25zdCBkYXRhID0ge1xuICAgIHByZXBhcmVDb21tYW5kUmVzcG9uc2U6IHByZXBhcmVSZXNwb25zZSxcbiAgICB0eFR5cGU6ICdPbmVTdGVwUHJlQXBwcm92YWwnLFxuICAgIHByZXBhcmVkVHJhbnNhY3Rpb246ICcnLFxuICAgIHBhcnR5U2lnbmF0dXJlczogeyBzaWduYXR1cmVzOiBbXSB9LFxuICAgIGRlZHVwbGljYXRpb25QZXJpb2Q6IHsgRW1wdHk6IHt9IH0sXG4gICAgc3VibWlzc2lvbklkOiBjb21tYW5kSWQsXG4gICAgaGFzaGluZ1NjaGVtZVZlcnNpb246ICdIQVNISU5HX1NDSEVNRV9WRVJTSU9OX1YyJyxcbiAgICBtaW5MZWRnZXJUaW1lOiB7IHRpbWU6IHsgRW1wdHk6IHt9IH0gfSxcbiAgfTtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KGRhdGEpKS50b1N0cmluZygnYmFzZTY0Jyk7XG59XG5cbi8qKiBSZXR1cm5zIGEgbW9jayB3YWxsZXQgd2hvc2UgY29pblNwZWNpZmljKCkucm9vdEFkZHJlc3MgbWF0Y2hlcyB0aGUgZ2l2ZW4gcGFydHkgSUQuICovXG5mdW5jdGlvbiB3YWxsZXRXaXRoUm9vdEFkZHJlc3Mocm9vdEFkZHJlc3M6IHN0cmluZyk6IElXYWxsZXQge1xuICByZXR1cm4geyBjb2luU3BlY2lmaWM6ICgpID0+ICh7IHJvb3RBZGRyZXNzIH0pIH0gYXMgdW5rbm93biBhcyBJV2FsbGV0O1xufVxuXG4vKiogQnVpbGRzIGEgYmFzZTY0LWVuY29kZWQgcmF3IHRyYW5zYWN0aW9uIGZvciBhIG5vbi1PbmVTdGVwIHR4VHlwZSAoZS5nLiBBbGxvY2F0aW9uUmVqZWN0KS4gKi9cbmZ1bmN0aW9uIGJ1aWxkUmF3VHgodHhUeXBlOiBzdHJpbmcsIHByZXBhcmVSZXNwb25zZTogdW5rbm93biwgY29tbWFuZElkOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBkYXRhID0ge1xuICAgIHByZXBhcmVDb21tYW5kUmVzcG9uc2U6IHByZXBhcmVSZXNwb25zZSxcbiAgICB0eFR5cGUsXG4gICAgcHJlcGFyZWRUcmFuc2FjdGlvbjogJycsXG4gICAgcGFydHlTaWduYXR1cmVzOiB7IHNpZ25hdHVyZXM6IFtdIH0sXG4gICAgZGVkdXBsaWNhdGlvblBlcmlvZDogeyBFbXB0eToge30gfSxcbiAgICBzdWJtaXNzaW9uSWQ6IGNvbW1hbmRJZCxcbiAgICBoYXNoaW5nU2NoZW1lVmVyc2lvbjogJ0hBU0hJTkdfU0NIRU1FX1ZFUlNJT05fVjInLFxuICAgIG1pbkxlZGdlclRpbWU6IHsgdGltZTogeyBFbXB0eToge30gfSB9LFxuICB9O1xuICByZXR1cm4gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoZGF0YSkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbn1cblxuZGVzY3JpYmUoJ0NhbnRvbiBjb2luOicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBiYXNlY29pbjogQ2FudG9uO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAnbW9jaycgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdjYW50b24nLCBDYW50b24uY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGNhbnRvbicsIFRjYW50b24uY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGNhbnRvbicpIGFzIENhbnRvbjtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3N1cHBvcnRzTWVzc2FnZVNpZ25pbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luLnN1cHBvcnRzTWVzc2FnZVNpZ25pbmcoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdDYW50b24gdmVyaWZ5VHJhbnNhY3Rpb246JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBDYW50b247XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2NhbnRvbicsIENhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0Y2FudG9uJywgVGNhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0Y2FudG9uJykgYXMgQ2FudG9uO1xuICB9KTtcblxuICBkZXNjcmliZSgnT25lU3RlcFByZUFwcHJvdmFsIChlbmFibGUgdG9rZW4gZmxvdyk6JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiB0eFBhcmFtcyBoYXMgbm8gdHlwZSAobm9uLWVuYWJsZXRva2VuIGZsb3cpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhIZXggPSBidWlsZE9uZVN0ZXBQcmVBcHByb3ZhbFJhd1R4KE9uZVN0ZXBQcmVBcHByb3ZhbFByZXBhcmVSZXNwb25zZSwgT25lU3RlcEVuYWJsZW1lbnQuY29tbWFuZElkKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgIHdhbGxldDoge30gYXMgYW55LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGVuYWJsZVRva2VucyBpcyBhYnNlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEhleCA9IGJ1aWxkT25lU3RlcFByZUFwcHJvdmFsUmF3VHgoT25lU3RlcFByZUFwcHJvdmFsUHJlcGFyZVJlc3BvbnNlLCBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWQpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7IHR5cGU6ICdlbmFibGV0b2tlbicgfSxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gZW5hYmxlVG9rZW5zIGlzIGVtcHR5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhIZXggPSBidWlsZE9uZVN0ZXBQcmVBcHByb3ZhbFJhd1R4KE9uZVN0ZXBQcmVBcHByb3ZhbFByZXBhcmVSZXNwb25zZSwgT25lU3RlcEVuYWJsZW1lbnQuY29tbWFuZElkKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczogeyB0eXBlOiAnZW5hYmxldG9rZW4nLCBlbmFibGVUb2tlbnM6IFtdIH0sXG4gICAgICAgIHdhbGxldDoge30gYXMgYW55LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvaW4gcHJlLWFwcHJvdmFsIChUcmFuc2ZlclByZWFwcHJvdmFsUHJvcG9zYWwpOicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCB0eEhleDogc3RyaW5nO1xuICAgICAgbGV0IHJlY2VpdmVyOiBzdHJpbmc7XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHR4SGV4ID0gYnVpbGRPbmVTdGVwUHJlQXBwcm92YWxSYXdUeChPbmVTdGVwUHJlQXBwcm92YWxQcmVwYXJlUmVzcG9uc2UsIE9uZVN0ZXBFbmFibGVtZW50LmNvbW1hbmRJZCk7XG4gICAgICAgIC8vIER5bmFtaWNhbGx5IGRlcml2ZSByZWNlaXZlciBmcm9tIHBhcnNlZCB0cmFuc2FjdGlvbiB0byBhdm9pZCBoYXJkY29kaW5nIHByb3RvYnVmLWRlY29kZWQgYWRkcmVzc2VzXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndGNhbnRvbicpKS5mcm9tKHR4SGV4KTtcbiAgICAgICAgcmVjZWl2ZXIgPSAodHhCdWlsZGVyLnRyYW5zYWN0aW9uIGFzIGFueSkudG9Kc29uKCkucmVjZWl2ZXIgYXMgc3RyaW5nO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiB3YWxsZXQgaGFzIG5vIGNvaW5TcGVjaWZpYyAocmVjZWl2ZXIgY2hlY2sgc2tpcHBlZCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFR5cGljYWwgY2FzZTogd2FsbGV0IG1vY2sgaGFzIG5vIGNvaW5TcGVjaWZpYygpIG1ldGhvZCwgYW5kIG5vIGFkZHJlc3MgaW4gZW5hYmxlVG9rZW5zXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiB3YWxsZXQgcm9vdEFkZHJlc3MgbWF0Y2hlcyByZWNlaXZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gVHlwaWNhbCBVSSBmbG93OiBlbmFibGVUb2tlbnMgaGFzIG5vIGFkZHJlc3MsIHJlY2VpdmVyIHZhbGlkYXRlZCBmcm9tIHdhbGxldC5jb2luU3BlY2lmaWMoKS5yb290QWRkcmVzc1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAnY2FudG9uJyB9XSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0V2l0aFJvb3RBZGRyZXNzKHJlY2VpdmVyKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGVuYWJsZVRva2VuLmFkZHJlc3MgbWF0Y2hlcyByZWNlaXZlciAoZXhwbGljaXQgYWRkcmVzcyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nLCBhZGRyZXNzOiByZWNlaXZlciB9XSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30gYXMgYW55LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gd2FsbGV0IHJvb3RBZGRyZXNzIGRvZXMgbm90IG1hdGNoIHJlY2VpdmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB3cm9uZ0FkZHJlc3MgPSAnd3JvbmctcGFydHk6OjEyMjBhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhJztcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAnY2FudG9uJyB9XSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldFdpdGhSb290QWRkcmVzcyh3cm9uZ0FkZHJlc3MpLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL09uZVN0ZXBQcmVBcHByb3ZhbCByZWNlaXZlciBtaXNtYXRjaC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiBleHBsaWNpdCBlbmFibGVUb2tlbi5hZGRyZXNzIGRvZXMgbm90IG1hdGNoIHJlY2VpdmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB3cm9uZ0FkZHJlc3MgPSAnd3JvbmctcGFydHk6OjEyMjBhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhJztcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAnY2FudG9uJywgYWRkcmVzczogd3JvbmdBZGRyZXNzIH1dLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdhbGxldDoge30gYXMgYW55LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL09uZVN0ZXBQcmVBcHByb3ZhbCByZWNlaXZlciBtaXNtYXRjaC8pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndG9rZW4gcHJlLWFwcHJvdmFsIChUcmFuc2ZlclByZWFwcHJvdmFsKTonLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgdHhIZXg6IHN0cmluZztcbiAgICAgIGxldCByZWNlaXZlcjogc3RyaW5nO1xuXG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb21tYW5kSWQgPSAnN2Q5OTc4OWQtMmYyMi00OWUxLTg1Y2ItNzlkMmNlNWE2OWMxJztcbiAgICAgICAgdHhIZXggPSBidWlsZE9uZVN0ZXBQcmVBcHByb3ZhbFJhd1R4KENhbnRvblRva2VuUHJlQXBwcm92YWxQcmVwYXJlUmVzcG9uc2UsIGNvbW1hbmRJZCk7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndGNhbnRvbicpKS5mcm9tKHR4SGV4KTtcbiAgICAgICAgcmVjZWl2ZXIgPSAodHhCdWlsZGVyLnRyYW5zYWN0aW9uIGFzIGFueSkudG9Kc29uKCkucmVjZWl2ZXIgYXMgc3RyaW5nO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiB3YWxsZXQgcm9vdEFkZHJlc3MgbWF0Y2hlcyByZWNlaXZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIGVuYWJsZVRva2VuczogW3sgbmFtZTogJ3RjYW50b246dGVzdGNvaW4xJyB9XSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0V2l0aFJvb3RBZGRyZXNzKHJlY2VpdmVyKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGVuYWJsZVRva2VuLmFkZHJlc3MgbWF0Y2hlcyByZWNlaXZlciAoZXhwbGljaXQgYWRkcmVzcyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICd0Y2FudG9uOnRlc3Rjb2luMScsIGFkZHJlc3M6IHJlY2VpdmVyIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB3YWxsZXQgcm9vdEFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggcmVjZWl2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICd3cm9uZy1wYXJ0eTo6MTIyMGJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiJztcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAndGNhbnRvbjp0ZXN0Y29pbjEnIH1dLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0V2l0aFJvb3RBZGRyZXNzKHdyb25nQWRkcmVzcyksXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvT25lU3RlcFByZUFwcHJvdmFsIHJlY2VpdmVyIG1pc21hdGNoLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIGV4cGxpY2l0IGVuYWJsZVRva2VuLmFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggcmVjZWl2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICd3cm9uZy1wYXJ0eTo6MTIyMGJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiJztcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAndGNhbnRvbjp0ZXN0Y29pbjEnLCBhZGRyZXNzOiB3cm9uZ0FkZHJlc3MgfV0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgd2FsbGV0OiB7fSBhcyBhbnksXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvT25lU3RlcFByZUFwcHJvdmFsIHJlY2VpdmVyIG1pc21hdGNoLyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwgKGRpc2FibGUgdG9rZW4gZmxvdyk6JywgZnVuY3Rpb24gKCkge1xuICAgIC8vIFJlYWwgY2FwdHVyZWQgVHJhbnNmZXJQcmVhcHByb3ZhbF9DYW5jZWwgZXhlcmNpc2Utbm9kZSBmaXh0dXJlOiBwYXJzZWQgc2VuZGVyID09PSByZWNlaXZlclxuICAgIC8vID09PSBDYW5jZWxQYXJ0eSwgbWF0Y2hpbmcgdGhlIGFjdHVhbCBvbi1jaGFpbiBjaG9pY2UvYWN0aW5nUGFydGllcyBzaGFwZS5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gdHhQYXJhbXMgaGFzIG5vIHR5cGUgKG5vbi1kaXNhYmxldG9rZW4gZmxvdyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEhleCA9IGJ1aWxkUmF3VHgoXG4gICAgICAgICdUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsJyxcbiAgICAgICAgVHJhbnNmZXJQcmVhcHByb3ZhbENhbmNlbFByZXBhcmVSZXNwb25zZSxcbiAgICAgICAgT25lU3RlcEVuYWJsZW1lbnQuY29tbWFuZElkXG4gICAgICApO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyB1bmtub3duIGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gZW5hYmxlVG9rZW5zIGlzIGFic2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRSYXdUeChcbiAgICAgICAgJ1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwnLFxuICAgICAgICBUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsUHJlcGFyZVJlc3BvbnNlLFxuICAgICAgICBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWRcbiAgICAgICk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2Rpc2FibGV0b2tlbicgfSxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGVuYWJsZVRva2VucyBpcyBlbXB0eScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRSYXdUeChcbiAgICAgICAgJ1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwnLFxuICAgICAgICBUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsUHJlcGFyZVJlc3BvbnNlLFxuICAgICAgICBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWRcbiAgICAgICk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2Rpc2FibGV0b2tlbicsIGVuYWJsZVRva2VuczogW10gfSxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHdhbGxldCBoYXMgbm8gY29pblNwZWNpZmljIGFuZCBubyBleHBsaWNpdCBhZGRyZXNzIChyZWNlaXZlciBjaGVjayBza2lwcGVkKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRSYXdUeChcbiAgICAgICAgJ1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwnLFxuICAgICAgICBUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsUHJlcGFyZVJlc3BvbnNlLFxuICAgICAgICBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWRcbiAgICAgICk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICB0eXBlOiAnZGlzYWJsZXRva2VuJyxcbiAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nIH1dLFxuICAgICAgICB9LFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gd2FsbGV0IHJvb3RBZGRyZXNzIG1hdGNoZXMgdGhlIHBhcnNlZCByZWNlaXZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRSYXdUeChcbiAgICAgICAgJ1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwnLFxuICAgICAgICBUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsUHJlcGFyZVJlc3BvbnNlLFxuICAgICAgICBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWRcbiAgICAgICk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICB0eXBlOiAnZGlzYWJsZXRva2VuJyxcbiAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nIH1dLFxuICAgICAgICB9LFxuICAgICAgICB3YWxsZXQ6IHdhbGxldFdpdGhSb290QWRkcmVzcyhDYW5jZWxQYXJ0eSksXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gZXhwbGljaXQgZW5hYmxlVG9rZW4uYWRkcmVzcyBtYXRjaGVzIHRoZSBwYXJzZWQgcmVjZWl2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEhleCA9IGJ1aWxkUmF3VHgoXG4gICAgICAgICdUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsJyxcbiAgICAgICAgVHJhbnNmZXJQcmVhcHByb3ZhbENhbmNlbFByZXBhcmVSZXNwb25zZSxcbiAgICAgICAgT25lU3RlcEVuYWJsZW1lbnQuY29tbWFuZElkXG4gICAgICApO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgdHlwZTogJ2Rpc2FibGV0b2tlbicsXG4gICAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAnY2FudG9uJywgYWRkcmVzczogQ2FuY2VsUGFydHkgfV0sXG4gICAgICAgIH0sXG4gICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB3YWxsZXQgcm9vdEFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggdGhlIHBhcnNlZCByZWNlaXZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRSYXdUeChcbiAgICAgICAgJ1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwnLFxuICAgICAgICBUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsUHJlcGFyZVJlc3BvbnNlLFxuICAgICAgICBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWRcbiAgICAgICk7XG4gICAgICBjb25zdCBzb21lQWRkcmVzcyA9ICdzb21lLXBhcnR5OjoxMjIwYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSc7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2Rpc2FibGV0b2tlbicsXG4gICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXRXaXRoUm9vdEFkZHJlc3Moc29tZUFkZHJlc3MpLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvVHJhbnNmZXJQcmVhcHByb3ZhbENhbmNlbCByZWNlaXZlciBtaXNtYXRjaC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIGV4cGxpY2l0IGVuYWJsZVRva2VuLmFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggdGhlIHBhcnNlZCByZWNlaXZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRSYXdUeChcbiAgICAgICAgJ1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwnLFxuICAgICAgICBUcmFuc2ZlclByZWFwcHJvdmFsQ2FuY2VsUHJlcGFyZVJlc3BvbnNlLFxuICAgICAgICBPbmVTdGVwRW5hYmxlbWVudC5jb21tYW5kSWRcbiAgICAgICk7XG4gICAgICBjb25zdCBzb21lQWRkcmVzcyA9ICdzb21lLXBhcnR5OjoxMjIwYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSc7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2Rpc2FibGV0b2tlbicsXG4gICAgICAgICAgICBlbmFibGVUb2tlbnM6IFt7IG5hbWU6ICdjYW50b24nLCBhZGRyZXNzOiBzb21lQWRkcmVzcyB9XSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL1RyYW5zZmVyUHJlYXBwcm92YWxDYW5jZWwgcmVjZWl2ZXIgbWlzbWF0Y2gvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0NhbnRvbiB2ZXJpZnlUcmFuc2FjdGlvbiAtIEFsbG9jYXRpb25SZWplY3Q6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBDYW50b247XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2NhbnRvbicsIENhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0Y2FudG9uJywgVGNhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0Y2FudG9uJykgYXMgQ2FudG9uO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBhbiBBbGxvY2F0aW9uUmVqZWN0IHRyYW5zYWN0aW9uIChubyByZWNpcGllbnQgaW5mbyB0byB2ZXJpZnkpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHR4SGV4ID0gYnVpbGRSYXdUeCgnQWxsb2NhdGlvblJlamVjdCcsIENhbnRvbkFsbG9jYXRpb25SZWplY3RQcmVwYXJlUmVzcG9uc2UsIEFsbG9jYXRpb25SZWplY3Rpb24uY29tbWFuZElkKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICB0eFBhcmFtczoge30sXG4gICAgICB3YWxsZXQ6IHt9IGFzIGFueSxcbiAgICB9KTtcbiAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnQ2FudG9uIGV4cGxhaW5UcmFuc2FjdGlvbiAtIEFsbG9jYXRpb25SZWplY3Q6JywgZnVuY3Rpb24gKCkge1xuICBpdCgnc2hvdWxkIHJldHVybiBhbiBlbXB0eSBleHBsYW5hdGlvbiAobm8gZnVuZHMgbW92ZSBvbiBhbiBBbGxvY2F0aW9uUmVxdWVzdCByZWplY3QpJywgZnVuY3Rpb24gKCkge1xuICAgIC8vIEFsbG9jYXRpb25SZXF1ZXN0X1JlamVjdCBmaXJlcyBiZWZvcmUgdGhlIGFjdG9yIGhhcyBhbGxvY2F0ZWQgdGhlaXIgbGVnIOKAlCBubyBIb2xkaW5nXG4gICAgLy8gd2FzIGV2ZXIgbG9ja2VkIGZvciB0aGlzIHRyYWRlLCBzbyBub3RoaW5nIGlzIHJldHVybmVkLiBVbmxpa2UgVHJhbnNmZXJSZWplY3QgKHdoaWNoXG4gICAgLy8gdW53aW5kcyBhIHJlYWwgZnVuZCBtb3ZlbWVudCksIHRoaXMgaXMgYSBwdXJlIFwiZGVjbGluZSB0byB0cmFkZVwiIHNpZ25hbCB3aXRoIG5vXG4gICAgLy8gYmFsYW5jZSBpbXBhY3QsIHNvIGl0IGludGVudGlvbmFsbHkgZmFsbHMgdGhyb3VnaCB0byB0aGUgZGVmYXVsdCAoZW1wdHkpIGV4cGxhbmF0aW9uXG4gICAgLy8gcmF0aGVyIHRoYW4gYmVpbmcgcmVwb3J0ZWQgYXMgYW4gaW5wdXQuXG4gICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oY29pbnMuZ2V0KCd0Y2FudG9uJykpO1xuICAgIHR4LmlkID0gQWxsb2NhdGlvblJlamVjdGlvbi5jb21tYW5kSWQ7XG4gICAgdHgudHJhbnNhY3Rpb25UeXBlID0gVHJhbnNhY3Rpb25UeXBlLkFsbG9jYXRpb25SZWplY3Q7XG4gICAgdHgucHJlcGFyZUNvbW1hbmQgPSBDYW50b25BbGxvY2F0aW9uUmVqZWN0UHJlcGFyZVJlc3BvbnNlO1xuXG4gICAgY29uc3QgZXhwbGFuYXRpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcblxuICAgIGV4cGxhbmF0aW9uLmlucHV0cyEubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICBleHBsYW5hdGlvbi5pbnB1dEFtb3VudCEuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgZXhwbGFuYXRpb24ub3V0cHV0cyEubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICBleHBsYW5hdGlvbi5vdXRwdXRBbW91bnQhLnNob3VsZC5lcXVhbCgnMCcpO1xuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0gRXhlcmNpc2VDb21tYW5kIHZlcmlmaWNhdGlvbiB0ZXN0cyAtLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgQ0FOVE9OX0NNRF9BQ1RfQVMgPSAnUmVnUmVnaXN0cmFyOjoxMjIwNTA4ZTU0ZmI3MDlkY2IxYTliNDA5NjQwOGFkNDE1ZDIyMTdkODg4MWFkOTAzNGE5ODUwNzUyOTMzYmE4OGFkNSc7XG5jb25zdCBDQU5UT05fQ01EX1RFTVBMQVRFX0lEID1cbiAgJzdhNzVlZjZlNjlmNjkzOTVhNGU2MDkxOWUyMjg1MjhiYjhmMzg4MTE1MGNjZmRlM2YzMWJjYzczODY0YjE4YWI6VXRpbGl0eS5SZWdpc3RyeS5BcHAuVjAuU2VydmljZS5BbGxvY2F0aW9uRmFjdG9yeTpBbGxvY2F0aW9uRmFjdG9yeSc7XG5jb25zdCBDQU5UT05fQ01EX0NPTlRSQUNUX0lEID1cbiAgJzAwZjNhZmRjZTg0NmE0MGM2ZjNmNjE4YzRiNTg0YjAyMmEwMTk3MDEwMDU3ZWNkNTk0NTgyMDAxODNhYjI3ZGUwYWNhMTIxMjIwNGFlZjdlZGUzN2E1ZjQxYjY3NGExZDk1NDQ2ZDQyYTQwNDQ2MWM1NTU4YzRlNmQxODYwYjY1NTYwMTIwZWYxOCc7XG5jb25zdCBDQU5UT05fQ01EX0NIT0lDRSA9ICdBbGxvY2F0aW9uRmFjdG9yeV9PZmZlck1pbnQnO1xuXG5mdW5jdGlvbiBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChwcmVwYXJlUmVzcG9uc2U6IFBhcnRpYWw8Q2FudG9uUHJlcGFyZUNvbW1hbmRSZXNwb25zZT4sIGNvbW1hbmRJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZGF0YSA9IHtcbiAgICBwcmVwYXJlQ29tbWFuZFJlc3BvbnNlOiBwcmVwYXJlUmVzcG9uc2UsXG4gICAgdHhUeXBlOiAnQ2FudG9uQ29tbWFuZCcsXG4gICAgcHJlcGFyZWRUcmFuc2FjdGlvbjogJycsXG4gICAgcGFydHlTaWduYXR1cmVzOiB7IHNpZ25hdHVyZXM6IFtdIH0sXG4gICAgZGVkdXBsaWNhdGlvblBlcmlvZDogeyBFbXB0eToge30gfSxcbiAgICBzdWJtaXNzaW9uSWQ6IGNvbW1hbmRJZCxcbiAgICBoYXNoaW5nU2NoZW1lVmVyc2lvbjogJ0hBU0hJTkdfU0NIRU1FX1ZFUlNJT05fVjInLFxuICAgIG1pbkxlZGdlclRpbWU6IHsgdGltZTogeyBFbXB0eToge30gfSB9LFxuICB9O1xuICByZXR1cm4gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoZGF0YSkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbn1cblxuZGVzY3JpYmUoJ0NhbnRvbiB2ZXJpZnlUcmFuc2FjdGlvbiAtIENhbnRvbkNvbW1hbmQ6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBDYW50b247XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2NhbnRvbicsIENhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0Y2FudG9uJywgVGNhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0Y2FudG9uJykgYXMgQ2FudG9uO1xuICB9KTtcblxuICBkZXNjcmliZSgnSGFwcHkgcGF0aCB0ZXN0czonLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHR4SGV4OiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgdHhIZXggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChDYW50b25FeGVyY2lzZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsICd0ZXN0LWNhbnRvbi1jbWQtMDAxJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gY2FudG9uQ29tbWFuZFBhcmFtcyBpcyB1bmRlZmluZWQgKG5vIHVzZXIgcGFyYW1zIHRvIHZlcmlmeSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBtYXRjaGluZyBFeGVyY2lzZUNvbW1hbmQgKHRlbXBsYXRlSWQsIGNob2ljZSwgY29udHJhY3RJZCwgYWN0QXMsIGFyZ3VtZW50KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBjb250cmFjdElkOiBDQU5UT05fQ01EX0NPTlRSQUNUX0lELFxuICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHtcbiAgICAgICAgICAgICAgICAgIGV4cGVjdGVkQWRtaW46IENBTlRPTl9DTURfQUNUX0FTLFxuICAgICAgICAgICAgICAgICAgbWludDoge1xuICAgICAgICAgICAgICAgICAgICBpbnN0cnVtZW50SWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICBhZG1pbjogQ0FOVE9OX0NNRF9BQ1RfQVMsXG4gICAgICAgICAgICAgICAgICAgICAgaWQ6ICdURVNUVE9LRU4nLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBhbW91bnQ6ICcxMDAnLFxuICAgICAgICAgICAgICAgICAgICBob2xkZXI6ICdSZWdJc3N1ZXI6OjEyMjA1MDhlNTRmYjcwOWRjYjFhOWI0MDk2NDA4YWQ0MTVkMjIxN2Q4ODgxYWQ5MDM0YTk4NTA3NTI5MzNiYTg4YWQ1JyxcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlOiAndGVzdC1wcmVwYXJlLW1pbnQnLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgcmVhZEFzOiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gY29udHJhY3RJZCBpcyBvbWl0dGVkIChJTVMtcmVzb2x2ZWQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgcmVhZEFzOiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdpdGggcmVzb2x2ZUNvbnRyYWN0cyBpbmplY3RBcyBza2lwcGluZyBjb250cmFjdElkIChlbXB0eSBjb250cmFjdElkKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBjb250cmFjdElkOiAnJyxcbiAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgIGNob2ljZUFyZ3VtZW50OiB7fSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIHJlYWRBczogW10sXG4gICAgICAgICAgICByZXNvbHZlQ29udHJhY3RzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgICAgIGluamVjdEFzOiAnY29tbWFuZC5FeGVyY2lzZUNvbW1hbmQuY29udHJhY3RJZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2l0aCByZXNvbHZlQ29udHJhY3RzIGluamVjdEFzIHNraXBwaW5nIG5vbi1lbXB0eSBjb250cmFjdElkIG1pc21hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVXNlciBzdXBwbGllcyBhIHBsYWNlaG9sZGVyIGNvbnRyYWN0SWQgdGhhdCBkb2Vzbid0IG1hdGNoIHdoYXQncyBvbi1jaGFpbjtcbiAgICAgIC8vIHJlc29sdmVDb250cmFjdHMgbWFya3MgaXQgYXMgSU1TLWluamVjdGVkLCBzbyB0aGUgbWlzbWF0Y2ggbXVzdCBiZSBpZ25vcmVkLlxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGNvbnRyYWN0SWQ6ICcwMHBsYWNlaG9sZGVyX2NvbnRyYWN0X2lkX25vdF9vbl9jaGFpbicsXG4gICAgICAgICAgICAgICAgY2hvaWNlOiBDQU5UT05fQ01EX0NIT0lDRSxcbiAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge30sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICByZWFkQXM6IFtdLFxuICAgICAgICAgICAgcmVzb2x2ZUNvbnRyYWN0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgICAgICBpbmplY3RBczogJ2NvbW1hbmQuRXhlcmNpc2VDb21tYW5kLmNvbnRyYWN0SWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFcnJvciBjYXNlczonLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHR4SGV4OiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgdHhIZXggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChDYW50b25FeGVyY2lzZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsICd0ZXN0LWNhbnRvbi1jbWQtMDAyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gcHJlcGFyZWRUcmFuc2FjdGlvbiBpcyBtaXNzaW5nIG9uIHR4IHByZWJ1aWxkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW1wdHlQcmVwYXJlID0geyAuLi5DYW50b25FeGVyY2lzZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsIHByZXBhcmVkVHJhbnNhY3Rpb246IHVuZGVmaW5lZCB9O1xuICAgICAgY29uc3QgYmFkVHggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChlbXB0eVByZXBhcmUsICdjbWQtYmFkJyk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXg6IGJhZFR4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICAgIEV4ZXJjaXNlQ29tbWFuZDogeyB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELCBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLCBjaG9pY2VBcmd1bWVudDoge30gfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvbWlzc2luZyBwcmVwYXJlZFRyYW5zYWN0aW9uLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gdXNlciBjb21tYW5kIGhhcyBuZWl0aGVyIENyZWF0ZUNvbW1hbmQgbm9yIEV4ZXJjaXNlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHsgVW5rbm93bkNvbW1hbmQ6IHt9IH0gYXMgdW5rbm93biBhcyBDYW50b25Db21tYW5kLFxuICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9tdXN0IGNvbnRhaW4gYSBDcmVhdGVDb21tYW5kIG9yIEV4ZXJjaXNlQ29tbWFuZC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHVzZXIgY29tbWFuZCBjb250YWlucyBib3RoIENyZWF0ZUNvbW1hbmQgYW5kIEV4ZXJjaXNlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBDcmVhdGVDb21tYW5kOiB7IHRlbXBsYXRlSWQ6IENBTlRPTl9DTURfVEVNUExBVEVfSUQsIGNyZWF0ZUFyZ3VtZW50czoge30gfSxcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHsgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCwgY2hvaWNlOiBDQU5UT05fQ01EX0NIT0lDRSwgY2hvaWNlQXJndW1lbnQ6IHt9IH0sXG4gICAgICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBDYW50b25Db21tYW5kLFxuICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9leGFjdGx5IG9uZSBvZiBDcmVhdGVDb21tYW5kIG9yIEV4ZXJjaXNlQ29tbWFuZC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBpbnZhbGlkIHVzZXIgdGVtcGxhdGVJZCBmb3JtYXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiAnSW52YWxpZEZvcm1hdCcsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL2ludmFsaWQgdXNlciB0ZW1wbGF0ZUlkLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIHRlbXBsYXRlSWQgbW9kdWxlL2VudGl0eSBtaXNtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6ICdTb21lUGtnOldyb25nLk1vZHVsZTpXcm9uZ0VudGl0eScsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbQ0FOVE9OX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3RlbXBsYXRlSWQgbWlzbWF0Y2gvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gc3VibWl0dGVySW5mby5hY3RBcyBtaXNtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6IENBTlRPTl9DTURfVEVNUExBVEVfSUQsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6IENBTlRPTl9DTURfQ0hPSUNFLFxuICAgICAgICAgICAgICAgICAgY2hvaWNlQXJndW1lbnQ6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbJ1dyb25nUGFydHk6OjEyMjBhYWFhJ10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvc3VibWl0dGVySW5mby5hY3RBcy4qZG9lcyBub3QgbWF0Y2ggdXNlciBhY3RBcy8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBjaG9pY2UgbWlzbWF0Y2ggZm9yIEV4ZXJjaXNlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBFeGVyY2lzZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6IENBTlRPTl9DTURfVEVNUExBVEVfSUQsXG4gICAgICAgICAgICAgICAgICBjaG9pY2U6ICdXcm9uZ0Nob2ljZScsXG4gICAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge30sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvY2hvaWNlIG1pc21hdGNoLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIGNvbnRyYWN0SWQgbWlzbWF0Y2ggd2hlbiB1c2VyIHByb3ZpZGVzIGV4cGxpY2l0IGNvbnRyYWN0SWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgRXhlcmNpc2VDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDQU5UT05fQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgICAgY29udHJhY3RJZDogJzAwd3Jvbmdjb250cmFjdGlkJyxcbiAgICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge30sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWN0QXM6IFtDQU5UT05fQ01EX0FDVF9BU10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvY29udHJhY3RJZCBtaXNtYXRjaC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBhcmd1bWVudCBkZWVwIG1pc21hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICAgIEV4ZXJjaXNlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ0FOVE9OX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICAgIGNob2ljZTogQ0FOVE9OX0NNRF9DSE9JQ0UsXG4gICAgICAgICAgICAgICAgICBjaG9pY2VBcmd1bWVudDoge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZEFkbWluOiAnV3JvbmdQYXJ0eTo6dG90YWxseS1kaWZmZXJlbnQnLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhY3RBczogW0NBTlRPTl9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9taXNtYXRjaC8pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0gQ3JlYXRlQ29tbWFuZCB2ZXJpZmljYXRpb24gdGVzdHMgLS0tLS0tLS0tLS0tLS0tXG5cbmNvbnN0IENSRUFURV9DTURfQUNUX0FTID0gJ1JlZ1Byb3ZpZGVyOjoxMjIwNTA4ZTU0ZmI3MDlkY2IxYTliNDA5NjQwOGFkNDE1ZDIyMTdkODg4MWFkOTAzNGE5ODUwNzUyOTMzYmE4OGFkNSc7XG5jb25zdCBDUkVBVEVfQ01EX1RFTVBMQVRFX0lEID1cbiAgJzdhNzVlZjZlNjlmNjkzOTVhNGU2MDkxOWUyMjg1MjhiYjhmMzg4MTE1MGNjZmRlM2YzMWJjYzczODY0YjE4YWI6VXRpbGl0eS5SZWdpc3RyeS5BcHAuVjAuU2VydmljZS5Qcm92aWRlcjpQcm92aWRlclNlcnZpY2VSZXF1ZXN0JztcbmNvbnN0IENSRUFURV9DTURfT1BFUkFUT1IgPSAnUmVnT3BlcmF0b3I6OjEyMjA1MDhlNTRmYjcwOWRjYjFhOWI0MDk2NDA4YWQ0MTVkMjIxN2Q4ODgxYWQ5MDM0YTk4NTA3NTI5MzNiYTg4YWQ1JztcblxuZGVzY3JpYmUoJ0NhbnRvbiB2ZXJpZnlUcmFuc2FjdGlvbiAtIENyZWF0ZUNvbW1hbmQ6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBDYW50b247XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2NhbnRvbicsIENhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0Y2FudG9uJywgVGNhbnRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0Y2FudG9uJykgYXMgQ2FudG9uO1xuICB9KTtcblxuICBkZXNjcmliZSgnSGFwcHkgcGF0aCB0ZXN0czonLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHR4SGV4OiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgdHhIZXggPSBidWlsZENhbnRvbkNvbW1hbmRSYXdUeChDYW50b25DcmVhdGVDb21tYW5kUHJlcGFyZVJlc3BvbnNlLCAndGVzdC1jcmVhdGUtY21kLTAwMScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgbWF0Y2hpbmcgQ3JlYXRlQ29tbWFuZCAodGVtcGxhdGVJZCwgY3JlYXRlQXJndW1lbnRzLCBhY3RBcyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgIENyZWF0ZUNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDUkVBVEVfQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgIGNyZWF0ZUFyZ3VtZW50czoge1xuICAgICAgICAgICAgICAgICAgb3BlcmF0b3I6IENSRUFURV9DTURfT1BFUkFUT1IsXG4gICAgICAgICAgICAgICAgICBwcm92aWRlcjogQ1JFQVRFX0NNRF9BQ1RfQVMsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RBczogW0NSRUFURV9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIHJlYWRBczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGNyZWF0ZUFyZ3VtZW50cyBpcyBlbXB0eSAobm8gZGVlcC1jb21wYXJlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIGNhbnRvbkNvbW1hbmRQYXJhbXM6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgQ3JlYXRlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlSWQ6IENSRUFURV9DTURfVEVNUExBVEVfSUQsXG4gICAgICAgICAgICAgICAgY3JlYXRlQXJndW1lbnRzOiB7fSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhY3RBczogW0NSRUFURV9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIHJlYWRBczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgd2FsbGV0OiB7fSBhcyBJV2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aXRoIHJlc29sdmVDb250cmFjdHMgaW5qZWN0QXMgc2tpcHBpbmcgY3JlYXRlQXJndW1lbnRzIGZpZWxkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgY29tbWFuZDoge1xuICAgICAgICAgICAgICBDcmVhdGVDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ1JFQVRFX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICBjcmVhdGVBcmd1bWVudHM6IHtcbiAgICAgICAgICAgICAgICAgIG9wZXJhdG9yOiAncGxhY2Vob2xkZXItb3BlcmF0b3ItaWQnLFxuICAgICAgICAgICAgICAgICAgcHJvdmlkZXI6IENSRUFURV9DTURfQUNUX0FTLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0QXM6IFtDUkVBVEVfQ01EX0FDVF9BU10sXG4gICAgICAgICAgICByZWFkQXM6IFtdLFxuICAgICAgICAgICAgcmVzb2x2ZUNvbnRyYWN0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogJ3NvbWUtdGVtcGxhdGUnLFxuICAgICAgICAgICAgICAgIGFjdEFzOiBbQ1JFQVRFX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgICAgIGluamVjdEFzOiAnY29tbWFuZC5DcmVhdGVDb21tYW5kLmNyZWF0ZUFyZ3VtZW50cy5vcGVyYXRvcicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgQ2FudG9uVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0Vycm9yIGNhc2VzOicsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgdHhIZXg6IHN0cmluZztcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICB0eEhleCA9IGJ1aWxkQ2FudG9uQ29tbWFuZFJhd1R4KENhbnRvbkNyZWF0ZUNvbW1hbmRQcmVwYXJlUmVzcG9uc2UsICd0ZXN0LWNyZWF0ZS1jbWQtZXJyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIHRlbXBsYXRlSWQgbWlzbWF0Y2ggZm9yIENyZWF0ZUNvbW1hbmQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgQ3JlYXRlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogJ1dyb25nUGtnOldyb25nLk1vZHVsZTpXcm9uZ0VudGl0eScsXG4gICAgICAgICAgICAgICAgICBjcmVhdGVBcmd1bWVudHM6IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFjdEFzOiBbQ1JFQVRFX0NNRF9BQ1RfQVNdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3RlbXBsYXRlSWQgbWlzbWF0Y2gvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gY3JlYXRlQXJndW1lbnRzIGRlZXAgbWlzbWF0Y2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgY2FudG9uQ29tbWFuZFBhcmFtczoge1xuICAgICAgICAgICAgICBjb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgQ3JlYXRlQ29tbWFuZDoge1xuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVJZDogQ1JFQVRFX0NNRF9URU1QTEFURV9JRCxcbiAgICAgICAgICAgICAgICAgIGNyZWF0ZUFyZ3VtZW50czoge1xuICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcjogJ1dyb25nT3BlcmF0b3I6OnRvdGFsbHktZGlmZmVyZW50JyxcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXI6IENSRUFURV9DTURfQUNUX0FTLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhY3RBczogW0NSRUFURV9DTURfQUNUX0FTXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSBhcyBDYW50b25UcmFuc2FjdGlvblBhcmFtcyxcbiAgICAgICAgICB3YWxsZXQ6IHt9IGFzIElXYWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9taXNtYXRjaC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBhY3RBcyBtaXNtYXRjaCBmb3IgQ3JlYXRlQ29tbWFuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICBjYW50b25Db21tYW5kUGFyYW1zOiB7XG4gICAgICAgICAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgICAgICAgICBDcmVhdGVDb21tYW5kOiB7XG4gICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkOiBDUkVBVEVfQ01EX1RFTVBMQVRFX0lELFxuICAgICAgICAgICAgICAgICAgY3JlYXRlQXJndW1lbnRzOiB7fSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhY3RBczogWydXcm9uZ1BhcnR5OjoxMjIwYWFhYSddLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIENhbnRvblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgICAgIHdhbGxldDoge30gYXMgSVdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3N1Ym1pdHRlckluZm8uYWN0QXMuKmRvZXMgbm90IG1hdGNoIHVzZXIgYWN0QXMvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==