@sunnyln/lni 0.1.5 → 0.1.6

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.
@@ -40047,7 +40047,7 @@ var isBun = "Bun" in globalThis;
40047
40047
  var isWebExtension = "chrome" in globalThis && globalThis.chrome.runtime?.id;
40048
40048
  var isWebExtensionContentScript = isWebExtension && "window" in globalThis;
40049
40049
  var userAgent = "navigator" in globalThis ? parseUserAgent(globalThis.navigator.userAgent) || "unknown-user-agent" : void 0;
40050
- var packageVersion = "0.6.1";
40050
+ var packageVersion = "0.6.3";
40051
40051
  var baseEnvStr = "unknown";
40052
40052
  if (isBun) baseEnvStr = `bun/${"version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version"}`;
40053
40053
  else if (isNode) baseEnvStr = `node/${globalThis.process.version}`;
@@ -47398,6 +47398,279 @@ var ClaimLeafKeyTweak_PubkeySharesTweakEntry = {
47398
47398
  return message;
47399
47399
  }
47400
47400
  };
47401
+ function createBaseClaimPackage() {
47402
+ return {
47403
+ leavesToClaim: [],
47404
+ keyTweakPackage: {},
47405
+ userSignature: new Uint8Array(0),
47406
+ directLeavesToClaim: [],
47407
+ directFromCpfpLeavesToClaim: [],
47408
+ hashVariant: 0
47409
+ };
47410
+ }
47411
+ var ClaimPackage = {
47412
+ encode(message, writer = new BinaryWriter()) {
47413
+ for (const v of message.leavesToClaim) UserSignedTxSigningJob.encode(v, writer.uint32(10).fork()).join();
47414
+ Object.entries(message.keyTweakPackage).forEach(([key, value]) => {
47415
+ ClaimPackage_KeyTweakPackageEntry.encode({
47416
+ key,
47417
+ value
47418
+ }, writer.uint32(18).fork()).join();
47419
+ });
47420
+ if (message.userSignature.length !== 0) writer.uint32(26).bytes(message.userSignature);
47421
+ for (const v of message.directLeavesToClaim) UserSignedTxSigningJob.encode(v, writer.uint32(34).fork()).join();
47422
+ for (const v of message.directFromCpfpLeavesToClaim) UserSignedTxSigningJob.encode(v, writer.uint32(42).fork()).join();
47423
+ if (message.hashVariant !== 0) writer.uint32(48).int32(message.hashVariant);
47424
+ return writer;
47425
+ },
47426
+ decode(input, length) {
47427
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
47428
+ const end = length === void 0 ? reader.len : reader.pos + length;
47429
+ const message = createBaseClaimPackage();
47430
+ while (reader.pos < end) {
47431
+ const tag = reader.uint32();
47432
+ switch (tag >>> 3) {
47433
+ case 1:
47434
+ if (tag !== 10) break;
47435
+ message.leavesToClaim.push(UserSignedTxSigningJob.decode(reader, reader.uint32()));
47436
+ continue;
47437
+ case 2: {
47438
+ if (tag !== 18) break;
47439
+ const entry2 = ClaimPackage_KeyTweakPackageEntry.decode(reader, reader.uint32());
47440
+ if (entry2.value !== void 0) message.keyTweakPackage[entry2.key] = entry2.value;
47441
+ continue;
47442
+ }
47443
+ case 3:
47444
+ if (tag !== 26) break;
47445
+ message.userSignature = reader.bytes();
47446
+ continue;
47447
+ case 4:
47448
+ if (tag !== 34) break;
47449
+ message.directLeavesToClaim.push(UserSignedTxSigningJob.decode(reader, reader.uint32()));
47450
+ continue;
47451
+ case 5:
47452
+ if (tag !== 42) break;
47453
+ message.directFromCpfpLeavesToClaim.push(UserSignedTxSigningJob.decode(reader, reader.uint32()));
47454
+ continue;
47455
+ case 6:
47456
+ if (tag !== 48) break;
47457
+ message.hashVariant = reader.int32();
47458
+ continue;
47459
+ }
47460
+ if ((tag & 7) === 4 || tag === 0) break;
47461
+ reader.skip(tag & 7);
47462
+ }
47463
+ return message;
47464
+ },
47465
+ fromJSON(object) {
47466
+ return {
47467
+ leavesToClaim: globalThis.Array.isArray(object?.leavesToClaim) ? object.leavesToClaim.map((e) => UserSignedTxSigningJob.fromJSON(e)) : [],
47468
+ keyTweakPackage: isObject3(object.keyTweakPackage) ? Object.entries(object.keyTweakPackage).reduce((acc, [key, value]) => {
47469
+ acc[key] = bytesFromBase64$3(value);
47470
+ return acc;
47471
+ }, {}) : {},
47472
+ userSignature: isSet$3(object.userSignature) ? bytesFromBase64$3(object.userSignature) : new Uint8Array(0),
47473
+ directLeavesToClaim: globalThis.Array.isArray(object?.directLeavesToClaim) ? object.directLeavesToClaim.map((e) => UserSignedTxSigningJob.fromJSON(e)) : [],
47474
+ directFromCpfpLeavesToClaim: globalThis.Array.isArray(object?.directFromCpfpLeavesToClaim) ? object.directFromCpfpLeavesToClaim.map((e) => UserSignedTxSigningJob.fromJSON(e)) : [],
47475
+ hashVariant: isSet$3(object.hashVariant) ? hashVariantFromJSON(object.hashVariant) : 0
47476
+ };
47477
+ },
47478
+ toJSON(message) {
47479
+ const obj = {};
47480
+ if (message.leavesToClaim?.length) obj.leavesToClaim = message.leavesToClaim.map((e) => UserSignedTxSigningJob.toJSON(e));
47481
+ if (message.keyTweakPackage) {
47482
+ const entries = Object.entries(message.keyTweakPackage);
47483
+ if (entries.length > 0) {
47484
+ obj.keyTweakPackage = {};
47485
+ entries.forEach(([k, v]) => {
47486
+ obj.keyTweakPackage[k] = base64FromBytes$3(v);
47487
+ });
47488
+ }
47489
+ }
47490
+ if (message.userSignature.length !== 0) obj.userSignature = base64FromBytes$3(message.userSignature);
47491
+ if (message.directLeavesToClaim?.length) obj.directLeavesToClaim = message.directLeavesToClaim.map((e) => UserSignedTxSigningJob.toJSON(e));
47492
+ if (message.directFromCpfpLeavesToClaim?.length) obj.directFromCpfpLeavesToClaim = message.directFromCpfpLeavesToClaim.map((e) => UserSignedTxSigningJob.toJSON(e));
47493
+ if (message.hashVariant !== 0) obj.hashVariant = hashVariantToJSON(message.hashVariant);
47494
+ return obj;
47495
+ },
47496
+ create(base) {
47497
+ return ClaimPackage.fromPartial(base ?? {});
47498
+ },
47499
+ fromPartial(object) {
47500
+ const message = createBaseClaimPackage();
47501
+ message.leavesToClaim = object.leavesToClaim?.map((e) => UserSignedTxSigningJob.fromPartial(e)) || [];
47502
+ message.keyTweakPackage = Object.entries(object.keyTweakPackage ?? {}).reduce((acc, [key, value]) => {
47503
+ if (value !== void 0) acc[key] = value;
47504
+ return acc;
47505
+ }, {});
47506
+ message.userSignature = object.userSignature ?? new Uint8Array(0);
47507
+ message.directLeavesToClaim = object.directLeavesToClaim?.map((e) => UserSignedTxSigningJob.fromPartial(e)) || [];
47508
+ message.directFromCpfpLeavesToClaim = object.directFromCpfpLeavesToClaim?.map((e) => UserSignedTxSigningJob.fromPartial(e)) || [];
47509
+ message.hashVariant = object.hashVariant ?? 0;
47510
+ return message;
47511
+ }
47512
+ };
47513
+ function createBaseClaimPackage_KeyTweakPackageEntry() {
47514
+ return {
47515
+ key: "",
47516
+ value: new Uint8Array(0)
47517
+ };
47518
+ }
47519
+ var ClaimPackage_KeyTweakPackageEntry = {
47520
+ encode(message, writer = new BinaryWriter()) {
47521
+ if (message.key !== "") writer.uint32(10).string(message.key);
47522
+ if (message.value.length !== 0) writer.uint32(18).bytes(message.value);
47523
+ return writer;
47524
+ },
47525
+ decode(input, length) {
47526
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
47527
+ const end = length === void 0 ? reader.len : reader.pos + length;
47528
+ const message = createBaseClaimPackage_KeyTweakPackageEntry();
47529
+ while (reader.pos < end) {
47530
+ const tag = reader.uint32();
47531
+ switch (tag >>> 3) {
47532
+ case 1:
47533
+ if (tag !== 10) break;
47534
+ message.key = reader.string();
47535
+ continue;
47536
+ case 2:
47537
+ if (tag !== 18) break;
47538
+ message.value = reader.bytes();
47539
+ continue;
47540
+ }
47541
+ if ((tag & 7) === 4 || tag === 0) break;
47542
+ reader.skip(tag & 7);
47543
+ }
47544
+ return message;
47545
+ },
47546
+ fromJSON(object) {
47547
+ return {
47548
+ key: isSet$3(object.key) ? globalThis.String(object.key) : "",
47549
+ value: isSet$3(object.value) ? bytesFromBase64$3(object.value) : new Uint8Array(0)
47550
+ };
47551
+ },
47552
+ toJSON(message) {
47553
+ const obj = {};
47554
+ if (message.key !== "") obj.key = message.key;
47555
+ if (message.value.length !== 0) obj.value = base64FromBytes$3(message.value);
47556
+ return obj;
47557
+ },
47558
+ create(base) {
47559
+ return ClaimPackage_KeyTweakPackageEntry.fromPartial(base ?? {});
47560
+ },
47561
+ fromPartial(object) {
47562
+ const message = createBaseClaimPackage_KeyTweakPackageEntry();
47563
+ message.key = object.key ?? "";
47564
+ message.value = object.value ?? new Uint8Array(0);
47565
+ return message;
47566
+ }
47567
+ };
47568
+ function createBaseClaimTransferRequest() {
47569
+ return {
47570
+ transferId: "",
47571
+ ownerIdentityPublicKey: new Uint8Array(0),
47572
+ claimPackage: void 0
47573
+ };
47574
+ }
47575
+ var ClaimTransferRequest = {
47576
+ encode(message, writer = new BinaryWriter()) {
47577
+ if (message.transferId !== "") writer.uint32(10).string(message.transferId);
47578
+ if (message.ownerIdentityPublicKey.length !== 0) writer.uint32(18).bytes(message.ownerIdentityPublicKey);
47579
+ if (message.claimPackage !== void 0) ClaimPackage.encode(message.claimPackage, writer.uint32(26).fork()).join();
47580
+ return writer;
47581
+ },
47582
+ decode(input, length) {
47583
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
47584
+ const end = length === void 0 ? reader.len : reader.pos + length;
47585
+ const message = createBaseClaimTransferRequest();
47586
+ while (reader.pos < end) {
47587
+ const tag = reader.uint32();
47588
+ switch (tag >>> 3) {
47589
+ case 1:
47590
+ if (tag !== 10) break;
47591
+ message.transferId = reader.string();
47592
+ continue;
47593
+ case 2:
47594
+ if (tag !== 18) break;
47595
+ message.ownerIdentityPublicKey = reader.bytes();
47596
+ continue;
47597
+ case 3:
47598
+ if (tag !== 26) break;
47599
+ message.claimPackage = ClaimPackage.decode(reader, reader.uint32());
47600
+ continue;
47601
+ }
47602
+ if ((tag & 7) === 4 || tag === 0) break;
47603
+ reader.skip(tag & 7);
47604
+ }
47605
+ return message;
47606
+ },
47607
+ fromJSON(object) {
47608
+ return {
47609
+ transferId: isSet$3(object.transferId) ? globalThis.String(object.transferId) : "",
47610
+ ownerIdentityPublicKey: isSet$3(object.ownerIdentityPublicKey) ? bytesFromBase64$3(object.ownerIdentityPublicKey) : new Uint8Array(0),
47611
+ claimPackage: isSet$3(object.claimPackage) ? ClaimPackage.fromJSON(object.claimPackage) : void 0
47612
+ };
47613
+ },
47614
+ toJSON(message) {
47615
+ const obj = {};
47616
+ if (message.transferId !== "") obj.transferId = message.transferId;
47617
+ if (message.ownerIdentityPublicKey.length !== 0) obj.ownerIdentityPublicKey = base64FromBytes$3(message.ownerIdentityPublicKey);
47618
+ if (message.claimPackage !== void 0) obj.claimPackage = ClaimPackage.toJSON(message.claimPackage);
47619
+ return obj;
47620
+ },
47621
+ create(base) {
47622
+ return ClaimTransferRequest.fromPartial(base ?? {});
47623
+ },
47624
+ fromPartial(object) {
47625
+ const message = createBaseClaimTransferRequest();
47626
+ message.transferId = object.transferId ?? "";
47627
+ message.ownerIdentityPublicKey = object.ownerIdentityPublicKey ?? new Uint8Array(0);
47628
+ message.claimPackage = object.claimPackage !== void 0 && object.claimPackage !== null ? ClaimPackage.fromPartial(object.claimPackage) : void 0;
47629
+ return message;
47630
+ }
47631
+ };
47632
+ function createBaseClaimTransferResponse() {
47633
+ return { transfer: void 0 };
47634
+ }
47635
+ var ClaimTransferResponse = {
47636
+ encode(message, writer = new BinaryWriter()) {
47637
+ if (message.transfer !== void 0) Transfer.encode(message.transfer, writer.uint32(10).fork()).join();
47638
+ return writer;
47639
+ },
47640
+ decode(input, length) {
47641
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
47642
+ const end = length === void 0 ? reader.len : reader.pos + length;
47643
+ const message = createBaseClaimTransferResponse();
47644
+ while (reader.pos < end) {
47645
+ const tag = reader.uint32();
47646
+ switch (tag >>> 3) {
47647
+ case 1:
47648
+ if (tag !== 10) break;
47649
+ message.transfer = Transfer.decode(reader, reader.uint32());
47650
+ continue;
47651
+ }
47652
+ if ((tag & 7) === 4 || tag === 0) break;
47653
+ reader.skip(tag & 7);
47654
+ }
47655
+ return message;
47656
+ },
47657
+ fromJSON(object) {
47658
+ return { transfer: isSet$3(object.transfer) ? Transfer.fromJSON(object.transfer) : void 0 };
47659
+ },
47660
+ toJSON(message) {
47661
+ const obj = {};
47662
+ if (message.transfer !== void 0) obj.transfer = Transfer.toJSON(message.transfer);
47663
+ return obj;
47664
+ },
47665
+ create(base) {
47666
+ return ClaimTransferResponse.fromPartial(base ?? {});
47667
+ },
47668
+ fromPartial(object) {
47669
+ const message = createBaseClaimTransferResponse();
47670
+ message.transfer = object.transfer !== void 0 && object.transfer !== null ? Transfer.fromPartial(object.transfer) : void 0;
47671
+ return message;
47672
+ }
47673
+ };
47401
47674
  function createBaseClaimTransferTweakKeysRequest() {
47402
47675
  return {
47403
47676
  transferId: "",
@@ -51916,6 +52189,14 @@ var SparkServiceDefinition = {
51916
52189
  responseStream: false,
51917
52190
  options: {}
51918
52191
  },
52192
+ claim_transfer: {
52193
+ name: "claim_transfer",
52194
+ requestType: ClaimTransferRequest,
52195
+ requestStream: false,
52196
+ responseType: ClaimTransferResponse,
52197
+ responseStream: false,
52198
+ options: {}
52199
+ },
51919
52200
  get_utxos_for_address: {
51920
52201
  name: "get_utxos_for_address",
51921
52202
  requestType: GetUtxosForAddressRequest,
@@ -52264,7 +52545,7 @@ var BASE_CONFIG = {
52264
52545
  intervalMs: 3e5,
52265
52546
  minOutputsThreshold: 50
52266
52547
  },
52267
- tokenOutputLockExpiryMs: 3e4,
52548
+ tokenOutputLockExpiryMs: 2e4,
52268
52549
  tokenTransactionVersion: "V3"
52269
52550
  };
52270
52551
  var LOCAL_WALLET_CONFIG = {
@@ -55160,761 +55441,363 @@ var SigningService = class {
55160
55441
  return userSignedTxSigningJobs;
55161
55442
  }
55162
55443
  };
55163
- var TokenOutputManager = class {
55164
- outputs = /* @__PURE__ */ new Map();
55165
- locks = /* @__PURE__ */ new Map();
55166
- mutex = new Mutex();
55167
- lockExpiryMs;
55168
- constructor(lockExpiryMs = 3e4) {
55169
- this.lockExpiryMs = lockExpiryMs;
55170
- }
55171
- /**
55172
- * Set token outputs.
55173
- * @param newOutputs - The new outputs to set
55174
- * @param tokenIdentifiers - If provided, only update these tokens (preserving others).
55175
- * If omitted or empty, replaces all outputs.
55176
- */
55177
- async setOutputs(newOutputs, tokenIdentifiers) {
55178
- await this.mutex.runExclusive(() => {
55179
- if (tokenIdentifiers && tokenIdentifiers.length > 0) for (const tokenId of tokenIdentifiers) {
55180
- const outputs = newOutputs.get(tokenId);
55181
- if (outputs && outputs.length > 0) this.outputs.set(tokenId, [...outputs]);
55182
- else this.outputs.delete(tokenId);
55183
- }
55184
- else this.outputs = new Map([...newOutputs.entries()].map(([k, v]) => [k, [...v]]));
55185
- this.cleanupStaleLocks();
55186
- });
55187
- }
55188
- /**
55189
- * Get all outputs for a token (including locked ones).
55190
- */
55191
- async getAllOutputs(tokenIdentifier) {
55192
- return await this.mutex.runExclusive(() => {
55193
- return [...this.outputs.get(tokenIdentifier) ?? []];
55194
- });
55195
- }
55196
- /**
55197
- * Check if outputs map has a token identifier.
55198
- */
55199
- async hasTokenIdentifier(tokenIdentifier) {
55200
- return await this.mutex.runExclusive(() => {
55201
- return this.outputs.has(tokenIdentifier);
55202
- });
55203
- }
55204
- /**
55205
- * Get all token identifiers in the map.
55206
- */
55207
- async getTokenIdentifiers() {
55208
- return await this.mutex.runExclusive(() => {
55209
- return [...this.outputs.keys()];
55210
- });
55211
- }
55212
- /**
55213
- * Iterate over entries (snapshot).
55214
- */
55215
- async entries() {
55216
- return await this.mutex.runExclusive(() => {
55217
- return [...this.outputs.entries()];
55218
- });
55219
- }
55220
- /**
55221
- * Atomically select and lock outputs.
55222
- * Returns the selected outputs and a release function.
55223
- *
55224
- * @param tokenIdentifier - The token to select from
55225
- * @param selector - Function to select outputs from available (unlocked) outputs
55226
- * @param operationId - name of the operation for debugging purposes
55227
- * @returns AcquiredOutputs with outputs and release function
55228
- */
55229
- async acquireOutputs(tokenIdentifier, selector, operationId) {
55230
- return await this.mutex.runExclusive(() => {
55231
- this.cleanupExpiredLocks();
55232
- const available = this.getUnlockedOutputsInternal(tokenIdentifier);
55233
- const selected = selector(available);
55234
- if (selected.length === 0) return {
55235
- outputs: [],
55236
- release: async () => {
55237
- }
55238
- };
55239
- const availableIds = new Set(available.map((o) => o.output.id));
55240
- for (const output of selected) {
55241
- const id = output.output.id;
55242
- if (!availableIds.has(id)) throw new Error(`Selected output ${id} is not in the available set`);
55243
- }
55244
- const now = Date.now();
55245
- const lockedIds = [];
55246
- for (const output of selected) {
55247
- const id = output.output.id;
55248
- this.locks.set(id, {
55249
- lockedAt: now,
55250
- reason: "pending_sent",
55251
- operationId
55252
- });
55253
- lockedIds.push(id);
55254
- }
55255
- const release = async () => {
55256
- await this.releaseOutputsByIds(lockedIds);
55257
- };
55258
- return {
55259
- outputs: selected,
55260
- release
55261
- };
55262
- });
55263
- }
55264
- /**
55265
- * Lock specific outputs by their data.
55266
- */
55267
- async lockOutputs(outputs, reason = "pending_sent", operationId) {
55268
- await this.mutex.runExclusive(() => {
55269
- const now = Date.now();
55270
- for (const output of outputs) {
55271
- const id = output.output.id;
55272
- this.locks.set(id, {
55273
- lockedAt: now,
55274
- reason,
55275
- operationId
55276
- });
55277
- }
55278
- });
55279
- }
55280
- /**
55281
- * Lock specific outputs by ID
55282
- */
55283
- async lockOutputsByIds(outputIds, reason, operationId) {
55284
- await this.mutex.runExclusive(() => {
55285
- const now = Date.now();
55286
- for (const id of outputIds) this.locks.set(id, {
55287
- lockedAt: now,
55288
- reason,
55289
- operationId
55290
- });
55291
- });
55292
- }
55293
- /**
55294
- * Release outputs.
55295
- */
55296
- async releaseOutputs(outputs) {
55297
- await this.mutex.runExclusive(() => {
55298
- for (const output of outputs) {
55299
- const id = output.output.id;
55300
- this.locks.delete(id);
55301
- }
55302
- });
55303
- }
55304
- /**
55305
- * Release outputs by ID.
55306
- */
55307
- async releaseOutputsByIds(outputIds) {
55308
- await this.mutex.runExclusive(() => {
55309
- for (const id of outputIds) this.locks.delete(id);
55310
- });
55311
- }
55312
- /**
55313
- * Check if an output is locked.
55314
- */
55315
- async isLocked(outputId) {
55316
- return await this.mutex.runExclusive(() => {
55317
- this.cleanupExpiredLocks();
55318
- return this.locks.has(outputId);
55319
- });
55320
- }
55321
- /**
55322
- * Check if outputs map is empty.
55323
- */
55324
- async isEmpty() {
55325
- return await this.mutex.runExclusive(() => {
55326
- return this.outputs.size === 0;
55327
- });
55328
- }
55329
- /**
55330
- * Get size of outputs map (number of token identifiers).
55331
- */
55332
- async size() {
55333
- return await this.mutex.runExclusive(() => {
55334
- return this.outputs.size;
55335
- });
55336
- }
55337
- /**
55338
- * Clear all outputs and locks.
55339
- */
55340
- async clear() {
55341
- await this.mutex.runExclusive(() => {
55342
- this.outputs.clear();
55343
- this.locks.clear();
55344
- });
55444
+ var TokenOutputStatus = /* @__PURE__ */ (function(TokenOutputStatus2) {
55445
+ TokenOutputStatus2[TokenOutputStatus2["TOKEN_OUTPUT_STATUS_UNSPECIFIED"] = 0] = "TOKEN_OUTPUT_STATUS_UNSPECIFIED";
55446
+ TokenOutputStatus2[TokenOutputStatus2["TOKEN_OUTPUT_STATUS_AVAILABLE"] = 1] = "TOKEN_OUTPUT_STATUS_AVAILABLE";
55447
+ TokenOutputStatus2[TokenOutputStatus2["TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND"] = 2] = "TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND";
55448
+ TokenOutputStatus2[TokenOutputStatus2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55449
+ return TokenOutputStatus2;
55450
+ })({});
55451
+ function tokenOutputStatusFromJSON(object) {
55452
+ switch (object) {
55453
+ case 0:
55454
+ case "TOKEN_OUTPUT_STATUS_UNSPECIFIED":
55455
+ return TokenOutputStatus.TOKEN_OUTPUT_STATUS_UNSPECIFIED;
55456
+ case 1:
55457
+ case "TOKEN_OUTPUT_STATUS_AVAILABLE":
55458
+ return TokenOutputStatus.TOKEN_OUTPUT_STATUS_AVAILABLE;
55459
+ case 2:
55460
+ case "TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND":
55461
+ return TokenOutputStatus.TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND;
55462
+ case -1:
55463
+ case "UNRECOGNIZED":
55464
+ default:
55465
+ return TokenOutputStatus.UNRECOGNIZED;
55345
55466
  }
55346
- getUnlockedOutputsInternal(tokenIdentifier) {
55347
- return (this.outputs.get(tokenIdentifier) ?? []).filter((o) => !this.locks.has(o.output.id));
55467
+ }
55468
+ function tokenOutputStatusToJSON(object) {
55469
+ switch (object) {
55470
+ case TokenOutputStatus.TOKEN_OUTPUT_STATUS_UNSPECIFIED:
55471
+ return "TOKEN_OUTPUT_STATUS_UNSPECIFIED";
55472
+ case TokenOutputStatus.TOKEN_OUTPUT_STATUS_AVAILABLE:
55473
+ return "TOKEN_OUTPUT_STATUS_AVAILABLE";
55474
+ case TokenOutputStatus.TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND:
55475
+ return "TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND";
55476
+ case TokenOutputStatus.UNRECOGNIZED:
55477
+ default:
55478
+ return "UNRECOGNIZED";
55348
55479
  }
55349
- cleanupExpiredLocks() {
55350
- const now = Date.now();
55351
- for (const [id, lock] of this.locks) if (now - lock.lockedAt > this.lockExpiryMs) this.locks.delete(id);
55480
+ }
55481
+ var TokenTransactionType = /* @__PURE__ */ (function(TokenTransactionType2) {
55482
+ TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_UNSPECIFIED"] = 0] = "TOKEN_TRANSACTION_TYPE_UNSPECIFIED";
55483
+ TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_CREATE"] = 1] = "TOKEN_TRANSACTION_TYPE_CREATE";
55484
+ TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_MINT"] = 2] = "TOKEN_TRANSACTION_TYPE_MINT";
55485
+ TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_TRANSFER"] = 3] = "TOKEN_TRANSACTION_TYPE_TRANSFER";
55486
+ TokenTransactionType2[TokenTransactionType2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55487
+ return TokenTransactionType2;
55488
+ })({});
55489
+ var CommitStatus = /* @__PURE__ */ (function(CommitStatus2) {
55490
+ CommitStatus2[CommitStatus2["COMMIT_UNSPECIFIED"] = 0] = "COMMIT_UNSPECIFIED";
55491
+ CommitStatus2[CommitStatus2["COMMIT_PROCESSING"] = 1] = "COMMIT_PROCESSING";
55492
+ CommitStatus2[CommitStatus2["COMMIT_FINALIZED"] = 2] = "COMMIT_FINALIZED";
55493
+ CommitStatus2[CommitStatus2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55494
+ return CommitStatus2;
55495
+ })({});
55496
+ function commitStatusFromJSON(object) {
55497
+ switch (object) {
55498
+ case 0:
55499
+ case "COMMIT_UNSPECIFIED":
55500
+ return CommitStatus.COMMIT_UNSPECIFIED;
55501
+ case 1:
55502
+ case "COMMIT_PROCESSING":
55503
+ return CommitStatus.COMMIT_PROCESSING;
55504
+ case 2:
55505
+ case "COMMIT_FINALIZED":
55506
+ return CommitStatus.COMMIT_FINALIZED;
55507
+ case -1:
55508
+ case "UNRECOGNIZED":
55509
+ default:
55510
+ return CommitStatus.UNRECOGNIZED;
55352
55511
  }
55353
- cleanupStaleLocks() {
55354
- const allOutputIds = /* @__PURE__ */ new Set();
55355
- for (const outputs of this.outputs.values()) for (const o of outputs) allOutputIds.add(o.output.id);
55356
- for (const lockedId of this.locks.keys()) if (!allOutputIds.has(lockedId)) this.locks.delete(lockedId);
55512
+ }
55513
+ function commitStatusToJSON(object) {
55514
+ switch (object) {
55515
+ case CommitStatus.COMMIT_UNSPECIFIED:
55516
+ return "COMMIT_UNSPECIFIED";
55517
+ case CommitStatus.COMMIT_PROCESSING:
55518
+ return "COMMIT_PROCESSING";
55519
+ case CommitStatus.COMMIT_FINALIZED:
55520
+ return "COMMIT_FINALIZED";
55521
+ case CommitStatus.UNRECOGNIZED:
55522
+ default:
55523
+ return "UNRECOGNIZED";
55357
55524
  }
55358
- };
55359
- function HashSparkInvoice(sparkInvoiceFields, receiverPublicKey, network) {
55360
- if (!sparkInvoiceFields) throw new Error("Missing sparkInvoiceFields");
55361
- if (!receiverPublicKey) throw new Error("Receiver public key is required");
55362
- if (!network) throw new Error("Network is required");
55363
- switch (sparkInvoiceFields.version) {
55525
+ }
55526
+ var TokenTransactionStatus = /* @__PURE__ */ (function(TokenTransactionStatus2) {
55527
+ TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_STARTED"] = 0] = "TOKEN_TRANSACTION_STARTED";
55528
+ TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_SIGNED"] = 1] = "TOKEN_TRANSACTION_SIGNED";
55529
+ TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_REVEALED"] = 5] = "TOKEN_TRANSACTION_REVEALED";
55530
+ TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_FINALIZED"] = 2] = "TOKEN_TRANSACTION_FINALIZED";
55531
+ TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_STARTED_CANCELLED"] = 3] = "TOKEN_TRANSACTION_STARTED_CANCELLED";
55532
+ TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_SIGNED_CANCELLED"] = 4] = "TOKEN_TRANSACTION_SIGNED_CANCELLED";
55533
+ TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_UNKNOWN"] = 10] = "TOKEN_TRANSACTION_UNKNOWN";
55534
+ TokenTransactionStatus2[TokenTransactionStatus2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55535
+ return TokenTransactionStatus2;
55536
+ })({});
55537
+ function tokenTransactionStatusFromJSON(object) {
55538
+ switch (object) {
55539
+ case 0:
55540
+ case "TOKEN_TRANSACTION_STARTED":
55541
+ return TokenTransactionStatus.TOKEN_TRANSACTION_STARTED;
55364
55542
  case 1:
55365
- return HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network);
55543
+ case "TOKEN_TRANSACTION_SIGNED":
55544
+ return TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED;
55545
+ case 5:
55546
+ case "TOKEN_TRANSACTION_REVEALED":
55547
+ return TokenTransactionStatus.TOKEN_TRANSACTION_REVEALED;
55548
+ case 2:
55549
+ case "TOKEN_TRANSACTION_FINALIZED":
55550
+ return TokenTransactionStatus.TOKEN_TRANSACTION_FINALIZED;
55551
+ case 3:
55552
+ case "TOKEN_TRANSACTION_STARTED_CANCELLED":
55553
+ return TokenTransactionStatus.TOKEN_TRANSACTION_STARTED_CANCELLED;
55554
+ case 4:
55555
+ case "TOKEN_TRANSACTION_SIGNED_CANCELLED":
55556
+ return TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED_CANCELLED;
55557
+ case 10:
55558
+ case "TOKEN_TRANSACTION_UNKNOWN":
55559
+ return TokenTransactionStatus.TOKEN_TRANSACTION_UNKNOWN;
55560
+ case -1:
55561
+ case "UNRECOGNIZED":
55366
55562
  default:
55367
- throw new Error(`Unsupported invoice version: ${sparkInvoiceFields.version}`);
55563
+ return TokenTransactionStatus.UNRECOGNIZED;
55368
55564
  }
55369
55565
  }
55370
- function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
55371
- if (!sparkInvoiceFields) throw new Error("Missing sparkInvoiceFields");
55372
- if (!receiverPublicKey) throw new Error("Receiver public key is required");
55373
- if (!network) throw new Error("Network is required");
55374
- const { version: version2, id, paymentType, memo, senderPublicKey, expiryTime } = sparkInvoiceFields;
55375
- const allHashes = [];
55376
- const versionHashObj = sha256.create();
55377
- const versionBytes = uint32be(version2);
55378
- versionHashObj.update(versionBytes);
55379
- allHashes.push(versionHashObj.digest());
55380
- const idHashObj = sha256.create();
55381
- if (!id || id.length !== 16) throw new Error("invoice id must be exactly 16 bytes");
55382
- idHashObj.update(id);
55383
- allHashes.push(idHashObj.digest());
55384
- const networkHashObj = sha256.create();
55385
- hashNetworkMagicInto(networkHashObj, network);
55386
- allHashes.push(networkHashObj.digest());
55387
- const receiverPubKeyHashObj = sha256.create();
55388
- if (!receiverPublicKey || receiverPublicKey.length !== 33) throw new Error("receiver public key must be exactly 33 bytes");
55389
- receiverPubKeyHashObj.update(receiverPublicKey);
55390
- allHashes.push(receiverPubKeyHashObj.digest());
55391
- switch (paymentType?.$case) {
55392
- case "tokensPayment": {
55393
- const tp = paymentType.tokensPayment;
55394
- const discrHash = sha256.create();
55395
- discrHash.update(new Uint8Array([1]));
55396
- allHashes.push(discrHash.digest());
55397
- const tokenIdHash = sha256.create();
55398
- const tokenIdentifier = tp.tokenIdentifier;
55399
- if (!tokenIdentifier || tokenIdentifier.length === 0) tokenIdHash.update(new Uint8Array(32));
55400
- else {
55401
- if (tokenIdentifier.length !== 32) throw new Error("token identifier must be exactly 32 bytes");
55402
- tokenIdHash.update(tokenIdentifier);
55403
- }
55404
- allHashes.push(tokenIdHash.digest());
55405
- const amountHash = sha256.create();
55406
- const amount = tp.amount;
55407
- if (amount && amount.length > 16) throw new Error("token amount exceeds 16 bytes");
55408
- if (amount && amount.length > 0) amountHash.update(amount);
55409
- allHashes.push(amountHash.digest());
55410
- break;
55411
- }
55412
- case "satsPayment": {
55413
- const sp = paymentType.satsPayment;
55414
- const discrHash = sha256.create();
55415
- discrHash.update(new Uint8Array([2]));
55416
- allHashes.push(discrHash.digest());
55417
- const satsHash = sha256.create();
55418
- let sats = 0n;
55419
- if (sp && typeof sp.amount === "number" && sp.amount !== 0) sats = BigInt(sp.amount);
55420
- satsHash.update(uint64be(sats));
55421
- allHashes.push(satsHash.digest());
55422
- break;
55423
- }
55424
- default:
55425
- throw new Error("unsupported or missing payment type");
55426
- }
55427
- const memoHashObj = sha256.create();
55428
- if (memo != null) memoHashObj.update(new TextEncoder().encode(memo));
55429
- allHashes.push(memoHashObj.digest());
55430
- const senderPubKeyHashObj = sha256.create();
55431
- const spk = senderPublicKey;
55432
- if (!spk || spk.length === 0) senderPubKeyHashObj.update(new Uint8Array(33));
55433
- else {
55434
- if (spk.length !== 33) throw new Error("sender public key must be exactly 33 bytes");
55435
- senderPubKeyHashObj.update(spk);
55436
- }
55437
- allHashes.push(senderPubKeyHashObj.digest());
55438
- const expiryHashObj = sha256.create();
55439
- let exp = 0n;
55440
- if (expiryTime instanceof Date) {
55441
- const seconds = Math.floor(expiryTime.getTime() / 1e3);
55442
- if (seconds > 0) exp = BigInt(seconds);
55443
- }
55444
- expiryHashObj.update(uint64be(exp));
55445
- allHashes.push(expiryHashObj.digest());
55446
- const finalHash = sha256.create();
55447
- for (const hash of allHashes) finalHash.update(hash);
55448
- return finalHash.digest();
55449
- }
55450
- function bitcoinNetworkIdentifierFromNetwork(network) {
55451
- switch (network) {
55452
- case "MAINNET":
55453
- return 3652501241;
55454
- case "LOCAL":
55455
- case "REGTEST":
55456
- return 3669344250;
55457
- case "TESTNET":
55458
- return 118034699;
55459
- case "SIGNET":
55460
- return 1087308554;
55566
+ function tokenTransactionStatusToJSON(object) {
55567
+ switch (object) {
55568
+ case TokenTransactionStatus.TOKEN_TRANSACTION_STARTED:
55569
+ return "TOKEN_TRANSACTION_STARTED";
55570
+ case TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED:
55571
+ return "TOKEN_TRANSACTION_SIGNED";
55572
+ case TokenTransactionStatus.TOKEN_TRANSACTION_REVEALED:
55573
+ return "TOKEN_TRANSACTION_REVEALED";
55574
+ case TokenTransactionStatus.TOKEN_TRANSACTION_FINALIZED:
55575
+ return "TOKEN_TRANSACTION_FINALIZED";
55576
+ case TokenTransactionStatus.TOKEN_TRANSACTION_STARTED_CANCELLED:
55577
+ return "TOKEN_TRANSACTION_STARTED_CANCELLED";
55578
+ case TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED_CANCELLED:
55579
+ return "TOKEN_TRANSACTION_SIGNED_CANCELLED";
55580
+ case TokenTransactionStatus.TOKEN_TRANSACTION_UNKNOWN:
55581
+ return "TOKEN_TRANSACTION_UNKNOWN";
55582
+ case TokenTransactionStatus.UNRECOGNIZED:
55461
55583
  default:
55462
- throw new Error("invalid network");
55584
+ return "UNRECOGNIZED";
55463
55585
  }
55464
55586
  }
55465
- function hashNetworkMagicInto(hasher, network) {
55466
- const magicBE = uint32be(bitcoinNetworkIdentifierFromNetwork(network));
55467
- hasher.update(sha256(magicBE));
55468
- }
55469
- function uint32be(n) {
55470
- const b = new Uint8Array(4);
55471
- new DataView(b.buffer).setUint32(0, n >>> 0, false);
55472
- return b;
55473
- }
55474
- function uint64be(value) {
55475
- const b = new Uint8Array(8);
55476
- new DataView(b.buffer).setBigUint64(0, value, false);
55477
- return b;
55478
- }
55479
- var BECH32M_LIMIT = 1024;
55480
- var AddressNetwork = {
55481
- MAINNET: "spark",
55482
- TESTNET: "sparkt",
55483
- REGTEST: "sparkrt",
55484
- SIGNET: "sparks",
55485
- LOCAL: "sparkl"
55486
- };
55487
- var LegacyAddressNetwork = {
55488
- MAINNET: "sp",
55489
- TESTNET: "spt",
55490
- REGTEST: "sprt",
55491
- SIGNET: "sps",
55492
- LOCAL: "spl"
55493
- };
55494
- function encodeSparkAddress(payload) {
55495
- return encodeSparkAddressWithSignature(payload);
55587
+ function createBaseTokenOutputToSpend() {
55588
+ return {
55589
+ prevTokenTransactionHash: new Uint8Array(0),
55590
+ prevTokenTransactionVout: 0
55591
+ };
55496
55592
  }
55497
- function encodeSparkAddressWithSignature(payload, signature) {
55498
- try {
55499
- isValidPublicKey(payload.identityPublicKey);
55500
- const identityPublicKey = hexToBytes(payload.identityPublicKey);
55501
- let sparkInvoiceFields;
55502
- if (payload.sparkInvoiceFields) {
55503
- validateSparkInvoiceFields(payload.sparkInvoiceFields);
55504
- sparkInvoiceFields = payload.sparkInvoiceFields;
55505
- }
55506
- const w = new BinaryWriter();
55507
- w.uint32(10).bytes(identityPublicKey);
55508
- if (sparkInvoiceFields) {
55509
- const inner = encodeSparkInvoiceFieldsV1Canonical(sparkInvoiceFields);
55510
- w.uint32(18).bytes(inner);
55593
+ var TokenOutputToSpend = {
55594
+ encode(message, writer = new BinaryWriter()) {
55595
+ if (message.prevTokenTransactionHash.length !== 0) writer.uint32(10).bytes(message.prevTokenTransactionHash);
55596
+ if (message.prevTokenTransactionVout !== 0) writer.uint32(16).uint32(message.prevTokenTransactionVout);
55597
+ return writer;
55598
+ },
55599
+ decode(input, length) {
55600
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
55601
+ const end = length === void 0 ? reader.len : reader.pos + length;
55602
+ const message = createBaseTokenOutputToSpend();
55603
+ while (reader.pos < end) {
55604
+ const tag = reader.uint32();
55605
+ switch (tag >>> 3) {
55606
+ case 1:
55607
+ if (tag !== 10) break;
55608
+ message.prevTokenTransactionHash = reader.bytes();
55609
+ continue;
55610
+ case 2:
55611
+ if (tag !== 16) break;
55612
+ message.prevTokenTransactionVout = reader.uint32();
55613
+ continue;
55614
+ }
55615
+ if ((tag & 7) === 4 || tag === 0) break;
55616
+ reader.skip(tag & 7);
55511
55617
  }
55512
- if (signature && signature.length) w.uint32(26).bytes(signature);
55513
- const serializedPayload = w.finish();
55514
- const words = bech32m2.toWords(serializedPayload);
55515
- return bech32mEncode(AddressNetwork[payload.network], words);
55516
- } catch (error) {
55517
- throw new SparkValidationError("Failed to encode Spark address", {
55518
- field: "publicKey",
55519
- value: payload.identityPublicKey,
55520
- error
55521
- });
55522
- }
55523
- }
55524
- function decodeSparkAddress(address, network) {
55525
- try {
55526
- if (network !== getNetworkFromSparkAddress(address)) throw new SparkValidationError("Invalid Spark address prefix", {
55527
- field: "address",
55528
- value: address,
55529
- expected: `prefix='${AddressNetwork[network]}' or '${LegacyAddressNetwork[network]}'`
55530
- });
55531
- const decoded = bech32mDecode(address);
55532
- const { identityPublicKey, sparkInvoiceFields, signature } = SparkAddress.decode(bech32m2.fromWords(decoded.words));
55533
- const identityPubkeyHex = bytesToHex(identityPublicKey);
55534
- const signatureHex = signature ? bytesToHex(signature) : void 0;
55535
- isValidPublicKey(identityPubkeyHex);
55618
+ return message;
55619
+ },
55620
+ fromJSON(object) {
55536
55621
  return {
55537
- identityPublicKey: identityPubkeyHex,
55538
- network,
55539
- sparkInvoiceFields: sparkInvoiceFields && {
55540
- version: sparkInvoiceFields.version,
55541
- id: UUID.ofInner(sparkInvoiceFields.id).toString(),
55542
- paymentType: sparkInvoiceFields.paymentType ? sparkInvoiceFields.paymentType.$case === "tokensPayment" ? {
55543
- type: "tokens",
55544
- tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? bytesToHex(sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier) : void 0,
55545
- amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? bytesToNumberBE(sparkInvoiceFields.paymentType.tokensPayment.amount) : void 0
55546
- } : sparkInvoiceFields.paymentType.$case === "satsPayment" ? {
55547
- type: "sats",
55548
- amount: sparkInvoiceFields.paymentType.satsPayment.amount
55549
- } : void 0 : void 0,
55550
- memo: sparkInvoiceFields.memo,
55551
- senderPublicKey: sparkInvoiceFields.senderPublicKey ? bytesToHex(sparkInvoiceFields.senderPublicKey) : void 0,
55552
- expiryTime: sparkInvoiceFields.expiryTime
55553
- },
55554
- signature: signatureHex
55622
+ prevTokenTransactionHash: isSet$2(object.prevTokenTransactionHash) ? bytesFromBase64$2(object.prevTokenTransactionHash) : new Uint8Array(0),
55623
+ prevTokenTransactionVout: isSet$2(object.prevTokenTransactionVout) ? globalThis.Number(object.prevTokenTransactionVout) : 0
55555
55624
  };
55556
- } catch (error) {
55557
- if (error instanceof SparkValidationError) throw error;
55558
- throw new SparkValidationError("Failed to decode Spark address", {
55559
- field: "address",
55560
- value: address,
55561
- error
55562
- });
55625
+ },
55626
+ toJSON(message) {
55627
+ const obj = {};
55628
+ if (message.prevTokenTransactionHash.length !== 0) obj.prevTokenTransactionHash = base64FromBytes$2(message.prevTokenTransactionHash);
55629
+ if (message.prevTokenTransactionVout !== 0) obj.prevTokenTransactionVout = Math.round(message.prevTokenTransactionVout);
55630
+ return obj;
55631
+ },
55632
+ create(base) {
55633
+ return TokenOutputToSpend.fromPartial(base ?? {});
55634
+ },
55635
+ fromPartial(object) {
55636
+ const message = createBaseTokenOutputToSpend();
55637
+ message.prevTokenTransactionHash = object.prevTokenTransactionHash ?? new Uint8Array(0);
55638
+ message.prevTokenTransactionVout = object.prevTokenTransactionVout ?? 0;
55639
+ return message;
55563
55640
  }
55641
+ };
55642
+ function createBaseTokenTransferInput() {
55643
+ return { outputsToSpend: [] };
55564
55644
  }
55565
- var PrefixToNetwork = Object.fromEntries(Object.entries(AddressNetwork).map(([k, v]) => [v, k]));
55566
- var LegacyPrefixToNetwork = Object.fromEntries(Object.entries(LegacyAddressNetwork).map(([k, v]) => [v, k]));
55567
- function getNetworkFromSparkAddress(address) {
55568
- const { prefix: prefix2 } = bech32mDecode(address);
55569
- const network = PrefixToNetwork[prefix2] ?? LegacyPrefixToNetwork[prefix2];
55570
- if (!network) throw new SparkValidationError("Invalid Spark address prefix", {
55571
- field: "network",
55572
- value: address,
55573
- expected: "prefix='spark1', 'sparkt1', 'sparkrt1', 'sparks1', 'sparkl1' or legacy ('sp1', 'spt1', 'sprt1', 'sps1', 'spl1')"
55574
- });
55575
- return network;
55576
- }
55577
- function isLegacySparkAddress(address) {
55578
- try {
55579
- const { prefix: prefix2 } = bech32mDecode(address);
55580
- return prefix2 in LegacyPrefixToNetwork;
55581
- } catch (error) {
55582
- return false;
55583
- }
55584
- }
55585
- function isValidSparkAddress(address) {
55586
- try {
55587
- decodeSparkAddress(address, getNetworkFromSparkAddress(address));
55588
- return true;
55589
- } catch (error) {
55590
- if (error instanceof SparkValidationError) throw error;
55591
- throw new SparkValidationError("Invalid Spark address", {
55592
- field: "address",
55593
- value: address,
55594
- error
55595
- });
55596
- }
55597
- }
55598
- function isValidPublicKey(publicKey) {
55599
- try {
55600
- secp256k12.Point.fromHex(publicKey).assertValidity();
55601
- } catch (error) {
55602
- throw new SparkValidationError("Invalid public key", {
55603
- field: "publicKey",
55604
- value: publicKey,
55605
- error
55606
- });
55645
+ var TokenTransferInput = {
55646
+ encode(message, writer = new BinaryWriter()) {
55647
+ for (const v of message.outputsToSpend) TokenOutputToSpend.encode(v, writer.uint32(10).fork()).join();
55648
+ return writer;
55649
+ },
55650
+ decode(input, length) {
55651
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
55652
+ const end = length === void 0 ? reader.len : reader.pos + length;
55653
+ const message = createBaseTokenTransferInput();
55654
+ while (reader.pos < end) {
55655
+ const tag = reader.uint32();
55656
+ switch (tag >>> 3) {
55657
+ case 1:
55658
+ if (tag !== 10) break;
55659
+ message.outputsToSpend.push(TokenOutputToSpend.decode(reader, reader.uint32()));
55660
+ continue;
55661
+ }
55662
+ if ((tag & 7) === 4 || tag === 0) break;
55663
+ reader.skip(tag & 7);
55664
+ }
55665
+ return message;
55666
+ },
55667
+ fromJSON(object) {
55668
+ return { outputsToSpend: globalThis.Array.isArray(object?.outputsToSpend) ? object.outputsToSpend.map((e) => TokenOutputToSpend.fromJSON(e)) : [] };
55669
+ },
55670
+ toJSON(message) {
55671
+ const obj = {};
55672
+ if (message.outputsToSpend?.length) obj.outputsToSpend = message.outputsToSpend.map((e) => TokenOutputToSpend.toJSON(e));
55673
+ return obj;
55674
+ },
55675
+ create(base) {
55676
+ return TokenTransferInput.fromPartial(base ?? {});
55677
+ },
55678
+ fromPartial(object) {
55679
+ const message = createBaseTokenTransferInput();
55680
+ message.outputsToSpend = object.outputsToSpend?.map((e) => TokenOutputToSpend.fromPartial(e)) || [];
55681
+ return message;
55607
55682
  }
55683
+ };
55684
+ function createBaseTokenMintInput() {
55685
+ return {
55686
+ issuerPublicKey: new Uint8Array(0),
55687
+ tokenIdentifier: void 0
55688
+ };
55608
55689
  }
55609
- function validateSparkInvoiceFields(sparkInvoiceFields) {
55610
- const { version: version2, id, paymentType, memo, senderPublicKey } = sparkInvoiceFields;
55611
- if (version2 !== 1) throw new SparkValidationError("Version must be 1", {
55612
- field: "version",
55613
- value: version2
55614
- });
55615
- try {
55616
- UUID.ofInner(id);
55617
- } catch (error) {
55618
- throw new SparkValidationError("Invalid id", {
55619
- field: "id",
55620
- value: id,
55621
- error
55622
- });
55623
- }
55624
- if (senderPublicKey) try {
55625
- isValidPublicKey(bytesToHex(senderPublicKey));
55626
- } catch (error) {
55627
- throw new SparkValidationError("Invalid sender public key", {
55628
- field: "senderPublicKey",
55629
- value: senderPublicKey,
55630
- error
55631
- });
55632
- }
55633
- if (memo) {
55634
- if (new TextEncoder().encode(memo).length > 120) throw new SparkValidationError("Memo exceeds the maximum allowed byte length of 120.", {
55635
- field: "memo",
55636
- value: memo,
55637
- expected: "less than 120 bytes"
55638
- });
55639
- }
55640
- if (paymentType) if (paymentType.$case === "tokensPayment") {
55641
- const MAX_UINT128 = BigInt(2 ** 128 - 1);
55642
- const { amount: tokensAmount, tokenIdentifier } = paymentType.tokensPayment;
55643
- if (tokenIdentifier) {
55644
- if (!(tokenIdentifier instanceof Uint8Array)) throw new SparkValidationError("Token identifier must be Uint8Array", {
55645
- field: "paymentType.tokensPayment.tokenIdentifier",
55646
- value: tokenIdentifier
55647
- });
55648
- if (tokenIdentifier.length !== 32) throw new SparkValidationError("Token identifier must be 32 bytes", {
55649
- field: "paymentType.tokensPayment.tokenIdentifier",
55650
- value: tokenIdentifier
55651
- });
55652
- }
55653
- if (tokensAmount) {
55654
- if (tokensAmount.length > 16) throw new SparkValidationError("Amount must be less than 16 bytes", {
55655
- field: "paymentType.tokensPayment.amount",
55656
- value: tokensAmount
55657
- });
55658
- const tokensAmountBigInt = bytesToNumberBE(tokensAmount);
55659
- if (tokensAmountBigInt < 0 || tokensAmountBigInt > MAX_UINT128) throw new SparkValidationError("Asset amount must be between 0 and MAX_UINT128", {
55660
- field: "amount",
55661
- value: tokensAmount
55662
- });
55663
- }
55664
- } else if (paymentType.$case === "satsPayment") {
55665
- const { amount } = paymentType.satsPayment;
55666
- if (amount) {
55667
- const MAX_SATS_AMOUNT = 21e14;
55668
- if (amount < 0) throw new SparkValidationError("Amount must be greater than or equal to 0", {
55669
- field: "paymentType.satsPayment.amount",
55670
- value: amount
55671
- });
55672
- if (amount > MAX_SATS_AMOUNT) throw new SparkValidationError(`Amount must be less than ${MAX_SATS_AMOUNT} sats`);
55690
+ var TokenMintInput = {
55691
+ encode(message, writer = new BinaryWriter()) {
55692
+ if (message.issuerPublicKey.length !== 0) writer.uint32(10).bytes(message.issuerPublicKey);
55693
+ if (message.tokenIdentifier !== void 0) writer.uint32(18).bytes(message.tokenIdentifier);
55694
+ return writer;
55695
+ },
55696
+ decode(input, length) {
55697
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
55698
+ const end = length === void 0 ? reader.len : reader.pos + length;
55699
+ const message = createBaseTokenMintInput();
55700
+ while (reader.pos < end) {
55701
+ const tag = reader.uint32();
55702
+ switch (tag >>> 3) {
55703
+ case 1:
55704
+ if (tag !== 10) break;
55705
+ message.issuerPublicKey = reader.bytes();
55706
+ continue;
55707
+ case 2:
55708
+ if (tag !== 18) break;
55709
+ message.tokenIdentifier = reader.bytes();
55710
+ continue;
55711
+ }
55712
+ if ((tag & 7) === 4 || tag === 0) break;
55713
+ reader.skip(tag & 7);
55673
55714
  }
55674
- } else throw new SparkValidationError("Invalid payment type", {
55675
- field: "paymentType",
55676
- value: paymentType
55677
- });
55678
- }
55679
- function validateSparkInvoiceSignature(invoice) {
55680
- try {
55681
- const decoded = bech32mDecode(invoice);
55682
- const network = getNetworkFromSparkAddress(invoice);
55683
- const { identityPublicKey, sparkInvoiceFields, signature } = SparkAddress.decode(bech32m2.fromWords(decoded.words));
55684
- if (!sparkInvoiceFields) throw new SparkValidationError("Spark invoice fields are required", {
55685
- field: "sparkInvoiceFields",
55686
- value: sparkInvoiceFields
55687
- });
55688
- if (!signature) throw new SparkValidationError("Signature is required", {
55689
- field: "signature",
55690
- value: signature
55691
- });
55692
- if (!identityPublicKey) throw new SparkValidationError("Identity public key is required", {
55693
- field: "identityPublicKey",
55694
- value: identityPublicKey
55695
- });
55696
- const hash = HashSparkInvoice(sparkInvoiceFields, identityPublicKey, network);
55697
- const xOnly = secp256k12.Point.fromHex(identityPublicKey).toBytes(true).slice(1);
55698
- if (!schnorr.verify(signature, hash, xOnly)) throw new SparkValidationError("Invalid signature", {
55699
- field: "signature",
55700
- value: signature
55701
- });
55702
- } catch (error) {
55703
- if (error instanceof SparkValidationError) throw error;
55704
- throw new SparkValidationError("Failed to validate Spark invoice signature", {
55705
- field: "invoice",
55706
- value: invoice,
55707
- error
55708
- });
55715
+ return message;
55716
+ },
55717
+ fromJSON(object) {
55718
+ return {
55719
+ issuerPublicKey: isSet$2(object.issuerPublicKey) ? bytesFromBase64$2(object.issuerPublicKey) : new Uint8Array(0),
55720
+ tokenIdentifier: isSet$2(object.tokenIdentifier) ? bytesFromBase64$2(object.tokenIdentifier) : void 0
55721
+ };
55722
+ },
55723
+ toJSON(message) {
55724
+ const obj = {};
55725
+ if (message.issuerPublicKey.length !== 0) obj.issuerPublicKey = base64FromBytes$2(message.issuerPublicKey);
55726
+ if (message.tokenIdentifier !== void 0) obj.tokenIdentifier = base64FromBytes$2(message.tokenIdentifier);
55727
+ return obj;
55728
+ },
55729
+ create(base) {
55730
+ return TokenMintInput.fromPartial(base ?? {});
55731
+ },
55732
+ fromPartial(object) {
55733
+ const message = createBaseTokenMintInput();
55734
+ message.issuerPublicKey = object.issuerPublicKey ?? new Uint8Array(0);
55735
+ message.tokenIdentifier = object.tokenIdentifier ?? void 0;
55736
+ return message;
55709
55737
  }
55710
- }
55711
- function toProtoTimestamp(date) {
55712
- const ms = date.getTime();
55738
+ };
55739
+ function createBaseTokenCreateInput() {
55713
55740
  return {
55714
- seconds: Math.floor(ms / 1e3),
55715
- nanos: ms % 1e3 * 1e6
55741
+ issuerPublicKey: new Uint8Array(0),
55742
+ tokenName: "",
55743
+ tokenTicker: "",
55744
+ decimals: 0,
55745
+ maxSupply: new Uint8Array(0),
55746
+ isFreezable: false,
55747
+ creationEntityPublicKey: void 0,
55748
+ extraMetadata: void 0
55716
55749
  };
55717
55750
  }
55718
- function assertBech32(s) {
55719
- const i = s.lastIndexOf("1");
55720
- if (i <= 0 || i >= s.length - 1) throw new Error("invalid bech32 string");
55721
- }
55722
- function bech32mDecode(address) {
55723
- assertBech32(address);
55724
- return bech32m2.decode(address, BECH32M_LIMIT);
55725
- }
55726
- function bech32mEncode(prefix2, words) {
55727
- return bech32m2.encode(prefix2, words, BECH32M_LIMIT);
55728
- }
55729
- function encodeSparkInvoiceFieldsV1Canonical(f) {
55730
- const w = new BinaryWriter();
55731
- if (f.version !== 0) w.uint32(8).uint32(f.version);
55732
- if (f.id && f.id.length) w.uint32(18).bytes(f.id);
55733
- if (f.memo !== void 0) w.uint32(42).string(f.memo);
55734
- if (f.senderPublicKey !== void 0) w.uint32(50).bytes(f.senderPublicKey);
55735
- if (f.expiryTime !== void 0) Timestamp.encode(toProtoTimestamp(f.expiryTime), w.uint32(58).fork()).join();
55736
- switch (f.paymentType?.$case) {
55737
- case "tokensPayment":
55738
- TokensPayment.encode(f.paymentType.tokensPayment, w.uint32(26).fork()).join();
55739
- break;
55740
- case "satsPayment":
55741
- SatsPayment.encode(f.paymentType.satsPayment, w.uint32(34).fork()).join();
55742
- break;
55743
- }
55744
- return w.finish();
55745
- }
55746
- function isSafeForNumber(bi) {
55747
- return bi >= BigInt(Number.MIN_SAFE_INTEGER) && bi <= BigInt(Number.MAX_SAFE_INTEGER);
55748
- }
55749
- var TokenOutputStatus = /* @__PURE__ */ (function(TokenOutputStatus2) {
55750
- TokenOutputStatus2[TokenOutputStatus2["TOKEN_OUTPUT_STATUS_UNSPECIFIED"] = 0] = "TOKEN_OUTPUT_STATUS_UNSPECIFIED";
55751
- TokenOutputStatus2[TokenOutputStatus2["TOKEN_OUTPUT_STATUS_AVAILABLE"] = 1] = "TOKEN_OUTPUT_STATUS_AVAILABLE";
55752
- TokenOutputStatus2[TokenOutputStatus2["TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND"] = 2] = "TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND";
55753
- TokenOutputStatus2[TokenOutputStatus2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55754
- return TokenOutputStatus2;
55755
- })({});
55756
- function tokenOutputStatusFromJSON(object) {
55757
- switch (object) {
55758
- case 0:
55759
- case "TOKEN_OUTPUT_STATUS_UNSPECIFIED":
55760
- return TokenOutputStatus.TOKEN_OUTPUT_STATUS_UNSPECIFIED;
55761
- case 1:
55762
- case "TOKEN_OUTPUT_STATUS_AVAILABLE":
55763
- return TokenOutputStatus.TOKEN_OUTPUT_STATUS_AVAILABLE;
55764
- case 2:
55765
- case "TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND":
55766
- return TokenOutputStatus.TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND;
55767
- case -1:
55768
- case "UNRECOGNIZED":
55769
- default:
55770
- return TokenOutputStatus.UNRECOGNIZED;
55771
- }
55772
- }
55773
- function tokenOutputStatusToJSON(object) {
55774
- switch (object) {
55775
- case TokenOutputStatus.TOKEN_OUTPUT_STATUS_UNSPECIFIED:
55776
- return "TOKEN_OUTPUT_STATUS_UNSPECIFIED";
55777
- case TokenOutputStatus.TOKEN_OUTPUT_STATUS_AVAILABLE:
55778
- return "TOKEN_OUTPUT_STATUS_AVAILABLE";
55779
- case TokenOutputStatus.TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND:
55780
- return "TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND";
55781
- case TokenOutputStatus.UNRECOGNIZED:
55782
- default:
55783
- return "UNRECOGNIZED";
55784
- }
55785
- }
55786
- var TokenTransactionType = /* @__PURE__ */ (function(TokenTransactionType2) {
55787
- TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_UNSPECIFIED"] = 0] = "TOKEN_TRANSACTION_TYPE_UNSPECIFIED";
55788
- TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_CREATE"] = 1] = "TOKEN_TRANSACTION_TYPE_CREATE";
55789
- TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_MINT"] = 2] = "TOKEN_TRANSACTION_TYPE_MINT";
55790
- TokenTransactionType2[TokenTransactionType2["TOKEN_TRANSACTION_TYPE_TRANSFER"] = 3] = "TOKEN_TRANSACTION_TYPE_TRANSFER";
55791
- TokenTransactionType2[TokenTransactionType2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55792
- return TokenTransactionType2;
55793
- })({});
55794
- var CommitStatus = /* @__PURE__ */ (function(CommitStatus2) {
55795
- CommitStatus2[CommitStatus2["COMMIT_UNSPECIFIED"] = 0] = "COMMIT_UNSPECIFIED";
55796
- CommitStatus2[CommitStatus2["COMMIT_PROCESSING"] = 1] = "COMMIT_PROCESSING";
55797
- CommitStatus2[CommitStatus2["COMMIT_FINALIZED"] = 2] = "COMMIT_FINALIZED";
55798
- CommitStatus2[CommitStatus2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55799
- return CommitStatus2;
55800
- })({});
55801
- function commitStatusFromJSON(object) {
55802
- switch (object) {
55803
- case 0:
55804
- case "COMMIT_UNSPECIFIED":
55805
- return CommitStatus.COMMIT_UNSPECIFIED;
55806
- case 1:
55807
- case "COMMIT_PROCESSING":
55808
- return CommitStatus.COMMIT_PROCESSING;
55809
- case 2:
55810
- case "COMMIT_FINALIZED":
55811
- return CommitStatus.COMMIT_FINALIZED;
55812
- case -1:
55813
- case "UNRECOGNIZED":
55814
- default:
55815
- return CommitStatus.UNRECOGNIZED;
55816
- }
55817
- }
55818
- function commitStatusToJSON(object) {
55819
- switch (object) {
55820
- case CommitStatus.COMMIT_UNSPECIFIED:
55821
- return "COMMIT_UNSPECIFIED";
55822
- case CommitStatus.COMMIT_PROCESSING:
55823
- return "COMMIT_PROCESSING";
55824
- case CommitStatus.COMMIT_FINALIZED:
55825
- return "COMMIT_FINALIZED";
55826
- case CommitStatus.UNRECOGNIZED:
55827
- default:
55828
- return "UNRECOGNIZED";
55829
- }
55830
- }
55831
- var TokenTransactionStatus = /* @__PURE__ */ (function(TokenTransactionStatus2) {
55832
- TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_STARTED"] = 0] = "TOKEN_TRANSACTION_STARTED";
55833
- TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_SIGNED"] = 1] = "TOKEN_TRANSACTION_SIGNED";
55834
- TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_REVEALED"] = 5] = "TOKEN_TRANSACTION_REVEALED";
55835
- TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_FINALIZED"] = 2] = "TOKEN_TRANSACTION_FINALIZED";
55836
- TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_STARTED_CANCELLED"] = 3] = "TOKEN_TRANSACTION_STARTED_CANCELLED";
55837
- TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_SIGNED_CANCELLED"] = 4] = "TOKEN_TRANSACTION_SIGNED_CANCELLED";
55838
- TokenTransactionStatus2[TokenTransactionStatus2["TOKEN_TRANSACTION_UNKNOWN"] = 10] = "TOKEN_TRANSACTION_UNKNOWN";
55839
- TokenTransactionStatus2[TokenTransactionStatus2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
55840
- return TokenTransactionStatus2;
55841
- })({});
55842
- function tokenTransactionStatusFromJSON(object) {
55843
- switch (object) {
55844
- case 0:
55845
- case "TOKEN_TRANSACTION_STARTED":
55846
- return TokenTransactionStatus.TOKEN_TRANSACTION_STARTED;
55847
- case 1:
55848
- case "TOKEN_TRANSACTION_SIGNED":
55849
- return TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED;
55850
- case 5:
55851
- case "TOKEN_TRANSACTION_REVEALED":
55852
- return TokenTransactionStatus.TOKEN_TRANSACTION_REVEALED;
55853
- case 2:
55854
- case "TOKEN_TRANSACTION_FINALIZED":
55855
- return TokenTransactionStatus.TOKEN_TRANSACTION_FINALIZED;
55856
- case 3:
55857
- case "TOKEN_TRANSACTION_STARTED_CANCELLED":
55858
- return TokenTransactionStatus.TOKEN_TRANSACTION_STARTED_CANCELLED;
55859
- case 4:
55860
- case "TOKEN_TRANSACTION_SIGNED_CANCELLED":
55861
- return TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED_CANCELLED;
55862
- case 10:
55863
- case "TOKEN_TRANSACTION_UNKNOWN":
55864
- return TokenTransactionStatus.TOKEN_TRANSACTION_UNKNOWN;
55865
- case -1:
55866
- case "UNRECOGNIZED":
55867
- default:
55868
- return TokenTransactionStatus.UNRECOGNIZED;
55869
- }
55870
- }
55871
- function tokenTransactionStatusToJSON(object) {
55872
- switch (object) {
55873
- case TokenTransactionStatus.TOKEN_TRANSACTION_STARTED:
55874
- return "TOKEN_TRANSACTION_STARTED";
55875
- case TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED:
55876
- return "TOKEN_TRANSACTION_SIGNED";
55877
- case TokenTransactionStatus.TOKEN_TRANSACTION_REVEALED:
55878
- return "TOKEN_TRANSACTION_REVEALED";
55879
- case TokenTransactionStatus.TOKEN_TRANSACTION_FINALIZED:
55880
- return "TOKEN_TRANSACTION_FINALIZED";
55881
- case TokenTransactionStatus.TOKEN_TRANSACTION_STARTED_CANCELLED:
55882
- return "TOKEN_TRANSACTION_STARTED_CANCELLED";
55883
- case TokenTransactionStatus.TOKEN_TRANSACTION_SIGNED_CANCELLED:
55884
- return "TOKEN_TRANSACTION_SIGNED_CANCELLED";
55885
- case TokenTransactionStatus.TOKEN_TRANSACTION_UNKNOWN:
55886
- return "TOKEN_TRANSACTION_UNKNOWN";
55887
- case TokenTransactionStatus.UNRECOGNIZED:
55888
- default:
55889
- return "UNRECOGNIZED";
55890
- }
55891
- }
55892
- function createBaseTokenOutputToSpend() {
55893
- return {
55894
- prevTokenTransactionHash: new Uint8Array(0),
55895
- prevTokenTransactionVout: 0
55896
- };
55897
- }
55898
- var TokenOutputToSpend = {
55751
+ var TokenCreateInput = {
55899
55752
  encode(message, writer = new BinaryWriter()) {
55900
- if (message.prevTokenTransactionHash.length !== 0) writer.uint32(10).bytes(message.prevTokenTransactionHash);
55901
- if (message.prevTokenTransactionVout !== 0) writer.uint32(16).uint32(message.prevTokenTransactionVout);
55753
+ if (message.issuerPublicKey.length !== 0) writer.uint32(10).bytes(message.issuerPublicKey);
55754
+ if (message.tokenName !== "") writer.uint32(18).string(message.tokenName);
55755
+ if (message.tokenTicker !== "") writer.uint32(26).string(message.tokenTicker);
55756
+ if (message.decimals !== 0) writer.uint32(32).uint32(message.decimals);
55757
+ if (message.maxSupply.length !== 0) writer.uint32(42).bytes(message.maxSupply);
55758
+ if (message.isFreezable !== false) writer.uint32(48).bool(message.isFreezable);
55759
+ if (message.creationEntityPublicKey !== void 0) writer.uint32(58).bytes(message.creationEntityPublicKey);
55760
+ if (message.extraMetadata !== void 0) writer.uint32(66).bytes(message.extraMetadata);
55902
55761
  return writer;
55903
55762
  },
55904
55763
  decode(input, length) {
55905
55764
  const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
55906
55765
  const end = length === void 0 ? reader.len : reader.pos + length;
55907
- const message = createBaseTokenOutputToSpend();
55766
+ const message = createBaseTokenCreateInput();
55908
55767
  while (reader.pos < end) {
55909
55768
  const tag = reader.uint32();
55910
55769
  switch (tag >>> 3) {
55911
55770
  case 1:
55912
55771
  if (tag !== 10) break;
55913
- message.prevTokenTransactionHash = reader.bytes();
55772
+ message.issuerPublicKey = reader.bytes();
55914
55773
  continue;
55915
55774
  case 2:
55916
- if (tag !== 16) break;
55917
- message.prevTokenTransactionVout = reader.uint32();
55775
+ if (tag !== 18) break;
55776
+ message.tokenName = reader.string();
55777
+ continue;
55778
+ case 3:
55779
+ if (tag !== 26) break;
55780
+ message.tokenTicker = reader.string();
55781
+ continue;
55782
+ case 4:
55783
+ if (tag !== 32) break;
55784
+ message.decimals = reader.uint32();
55785
+ continue;
55786
+ case 5:
55787
+ if (tag !== 42) break;
55788
+ message.maxSupply = reader.bytes();
55789
+ continue;
55790
+ case 6:
55791
+ if (tag !== 48) break;
55792
+ message.isFreezable = reader.bool();
55793
+ continue;
55794
+ case 7:
55795
+ if (tag !== 58) break;
55796
+ message.creationEntityPublicKey = reader.bytes();
55797
+ continue;
55798
+ case 8:
55799
+ if (tag !== 66) break;
55800
+ message.extraMetadata = reader.bytes();
55918
55801
  continue;
55919
55802
  }
55920
55803
  if ((tag & 7) === 4 || tag === 0) break;
@@ -55924,229 +55807,41 @@ var TokenOutputToSpend = {
55924
55807
  },
55925
55808
  fromJSON(object) {
55926
55809
  return {
55927
- prevTokenTransactionHash: isSet$2(object.prevTokenTransactionHash) ? bytesFromBase64$2(object.prevTokenTransactionHash) : new Uint8Array(0),
55928
- prevTokenTransactionVout: isSet$2(object.prevTokenTransactionVout) ? globalThis.Number(object.prevTokenTransactionVout) : 0
55810
+ issuerPublicKey: isSet$2(object.issuerPublicKey) ? bytesFromBase64$2(object.issuerPublicKey) : new Uint8Array(0),
55811
+ tokenName: isSet$2(object.tokenName) ? globalThis.String(object.tokenName) : "",
55812
+ tokenTicker: isSet$2(object.tokenTicker) ? globalThis.String(object.tokenTicker) : "",
55813
+ decimals: isSet$2(object.decimals) ? globalThis.Number(object.decimals) : 0,
55814
+ maxSupply: isSet$2(object.maxSupply) ? bytesFromBase64$2(object.maxSupply) : new Uint8Array(0),
55815
+ isFreezable: isSet$2(object.isFreezable) ? globalThis.Boolean(object.isFreezable) : false,
55816
+ creationEntityPublicKey: isSet$2(object.creationEntityPublicKey) ? bytesFromBase64$2(object.creationEntityPublicKey) : void 0,
55817
+ extraMetadata: isSet$2(object.extraMetadata) ? bytesFromBase64$2(object.extraMetadata) : void 0
55929
55818
  };
55930
55819
  },
55931
55820
  toJSON(message) {
55932
55821
  const obj = {};
55933
- if (message.prevTokenTransactionHash.length !== 0) obj.prevTokenTransactionHash = base64FromBytes$2(message.prevTokenTransactionHash);
55934
- if (message.prevTokenTransactionVout !== 0) obj.prevTokenTransactionVout = Math.round(message.prevTokenTransactionVout);
55822
+ if (message.issuerPublicKey.length !== 0) obj.issuerPublicKey = base64FromBytes$2(message.issuerPublicKey);
55823
+ if (message.tokenName !== "") obj.tokenName = message.tokenName;
55824
+ if (message.tokenTicker !== "") obj.tokenTicker = message.tokenTicker;
55825
+ if (message.decimals !== 0) obj.decimals = Math.round(message.decimals);
55826
+ if (message.maxSupply.length !== 0) obj.maxSupply = base64FromBytes$2(message.maxSupply);
55827
+ if (message.isFreezable !== false) obj.isFreezable = message.isFreezable;
55828
+ if (message.creationEntityPublicKey !== void 0) obj.creationEntityPublicKey = base64FromBytes$2(message.creationEntityPublicKey);
55829
+ if (message.extraMetadata !== void 0) obj.extraMetadata = base64FromBytes$2(message.extraMetadata);
55935
55830
  return obj;
55936
55831
  },
55937
55832
  create(base) {
55938
- return TokenOutputToSpend.fromPartial(base ?? {});
55833
+ return TokenCreateInput.fromPartial(base ?? {});
55939
55834
  },
55940
55835
  fromPartial(object) {
55941
- const message = createBaseTokenOutputToSpend();
55942
- message.prevTokenTransactionHash = object.prevTokenTransactionHash ?? new Uint8Array(0);
55943
- message.prevTokenTransactionVout = object.prevTokenTransactionVout ?? 0;
55944
- return message;
55945
- }
55946
- };
55947
- function createBaseTokenTransferInput() {
55948
- return { outputsToSpend: [] };
55949
- }
55950
- var TokenTransferInput = {
55951
- encode(message, writer = new BinaryWriter()) {
55952
- for (const v of message.outputsToSpend) TokenOutputToSpend.encode(v, writer.uint32(10).fork()).join();
55953
- return writer;
55954
- },
55955
- decode(input, length) {
55956
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
55957
- const end = length === void 0 ? reader.len : reader.pos + length;
55958
- const message = createBaseTokenTransferInput();
55959
- while (reader.pos < end) {
55960
- const tag = reader.uint32();
55961
- switch (tag >>> 3) {
55962
- case 1:
55963
- if (tag !== 10) break;
55964
- message.outputsToSpend.push(TokenOutputToSpend.decode(reader, reader.uint32()));
55965
- continue;
55966
- }
55967
- if ((tag & 7) === 4 || tag === 0) break;
55968
- reader.skip(tag & 7);
55969
- }
55970
- return message;
55971
- },
55972
- fromJSON(object) {
55973
- return { outputsToSpend: globalThis.Array.isArray(object?.outputsToSpend) ? object.outputsToSpend.map((e) => TokenOutputToSpend.fromJSON(e)) : [] };
55974
- },
55975
- toJSON(message) {
55976
- const obj = {};
55977
- if (message.outputsToSpend?.length) obj.outputsToSpend = message.outputsToSpend.map((e) => TokenOutputToSpend.toJSON(e));
55978
- return obj;
55979
- },
55980
- create(base) {
55981
- return TokenTransferInput.fromPartial(base ?? {});
55982
- },
55983
- fromPartial(object) {
55984
- const message = createBaseTokenTransferInput();
55985
- message.outputsToSpend = object.outputsToSpend?.map((e) => TokenOutputToSpend.fromPartial(e)) || [];
55986
- return message;
55987
- }
55988
- };
55989
- function createBaseTokenMintInput() {
55990
- return {
55991
- issuerPublicKey: new Uint8Array(0),
55992
- tokenIdentifier: void 0
55993
- };
55994
- }
55995
- var TokenMintInput = {
55996
- encode(message, writer = new BinaryWriter()) {
55997
- if (message.issuerPublicKey.length !== 0) writer.uint32(10).bytes(message.issuerPublicKey);
55998
- if (message.tokenIdentifier !== void 0) writer.uint32(18).bytes(message.tokenIdentifier);
55999
- return writer;
56000
- },
56001
- decode(input, length) {
56002
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
56003
- const end = length === void 0 ? reader.len : reader.pos + length;
56004
- const message = createBaseTokenMintInput();
56005
- while (reader.pos < end) {
56006
- const tag = reader.uint32();
56007
- switch (tag >>> 3) {
56008
- case 1:
56009
- if (tag !== 10) break;
56010
- message.issuerPublicKey = reader.bytes();
56011
- continue;
56012
- case 2:
56013
- if (tag !== 18) break;
56014
- message.tokenIdentifier = reader.bytes();
56015
- continue;
56016
- }
56017
- if ((tag & 7) === 4 || tag === 0) break;
56018
- reader.skip(tag & 7);
56019
- }
56020
- return message;
56021
- },
56022
- fromJSON(object) {
56023
- return {
56024
- issuerPublicKey: isSet$2(object.issuerPublicKey) ? bytesFromBase64$2(object.issuerPublicKey) : new Uint8Array(0),
56025
- tokenIdentifier: isSet$2(object.tokenIdentifier) ? bytesFromBase64$2(object.tokenIdentifier) : void 0
56026
- };
56027
- },
56028
- toJSON(message) {
56029
- const obj = {};
56030
- if (message.issuerPublicKey.length !== 0) obj.issuerPublicKey = base64FromBytes$2(message.issuerPublicKey);
56031
- if (message.tokenIdentifier !== void 0) obj.tokenIdentifier = base64FromBytes$2(message.tokenIdentifier);
56032
- return obj;
56033
- },
56034
- create(base) {
56035
- return TokenMintInput.fromPartial(base ?? {});
56036
- },
56037
- fromPartial(object) {
56038
- const message = createBaseTokenMintInput();
56039
- message.issuerPublicKey = object.issuerPublicKey ?? new Uint8Array(0);
56040
- message.tokenIdentifier = object.tokenIdentifier ?? void 0;
56041
- return message;
56042
- }
56043
- };
56044
- function createBaseTokenCreateInput() {
56045
- return {
56046
- issuerPublicKey: new Uint8Array(0),
56047
- tokenName: "",
56048
- tokenTicker: "",
56049
- decimals: 0,
56050
- maxSupply: new Uint8Array(0),
56051
- isFreezable: false,
56052
- creationEntityPublicKey: void 0,
56053
- extraMetadata: void 0
56054
- };
56055
- }
56056
- var TokenCreateInput = {
56057
- encode(message, writer = new BinaryWriter()) {
56058
- if (message.issuerPublicKey.length !== 0) writer.uint32(10).bytes(message.issuerPublicKey);
56059
- if (message.tokenName !== "") writer.uint32(18).string(message.tokenName);
56060
- if (message.tokenTicker !== "") writer.uint32(26).string(message.tokenTicker);
56061
- if (message.decimals !== 0) writer.uint32(32).uint32(message.decimals);
56062
- if (message.maxSupply.length !== 0) writer.uint32(42).bytes(message.maxSupply);
56063
- if (message.isFreezable !== false) writer.uint32(48).bool(message.isFreezable);
56064
- if (message.creationEntityPublicKey !== void 0) writer.uint32(58).bytes(message.creationEntityPublicKey);
56065
- if (message.extraMetadata !== void 0) writer.uint32(66).bytes(message.extraMetadata);
56066
- return writer;
56067
- },
56068
- decode(input, length) {
56069
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
56070
- const end = length === void 0 ? reader.len : reader.pos + length;
56071
- const message = createBaseTokenCreateInput();
56072
- while (reader.pos < end) {
56073
- const tag = reader.uint32();
56074
- switch (tag >>> 3) {
56075
- case 1:
56076
- if (tag !== 10) break;
56077
- message.issuerPublicKey = reader.bytes();
56078
- continue;
56079
- case 2:
56080
- if (tag !== 18) break;
56081
- message.tokenName = reader.string();
56082
- continue;
56083
- case 3:
56084
- if (tag !== 26) break;
56085
- message.tokenTicker = reader.string();
56086
- continue;
56087
- case 4:
56088
- if (tag !== 32) break;
56089
- message.decimals = reader.uint32();
56090
- continue;
56091
- case 5:
56092
- if (tag !== 42) break;
56093
- message.maxSupply = reader.bytes();
56094
- continue;
56095
- case 6:
56096
- if (tag !== 48) break;
56097
- message.isFreezable = reader.bool();
56098
- continue;
56099
- case 7:
56100
- if (tag !== 58) break;
56101
- message.creationEntityPublicKey = reader.bytes();
56102
- continue;
56103
- case 8:
56104
- if (tag !== 66) break;
56105
- message.extraMetadata = reader.bytes();
56106
- continue;
56107
- }
56108
- if ((tag & 7) === 4 || tag === 0) break;
56109
- reader.skip(tag & 7);
56110
- }
56111
- return message;
56112
- },
56113
- fromJSON(object) {
56114
- return {
56115
- issuerPublicKey: isSet$2(object.issuerPublicKey) ? bytesFromBase64$2(object.issuerPublicKey) : new Uint8Array(0),
56116
- tokenName: isSet$2(object.tokenName) ? globalThis.String(object.tokenName) : "",
56117
- tokenTicker: isSet$2(object.tokenTicker) ? globalThis.String(object.tokenTicker) : "",
56118
- decimals: isSet$2(object.decimals) ? globalThis.Number(object.decimals) : 0,
56119
- maxSupply: isSet$2(object.maxSupply) ? bytesFromBase64$2(object.maxSupply) : new Uint8Array(0),
56120
- isFreezable: isSet$2(object.isFreezable) ? globalThis.Boolean(object.isFreezable) : false,
56121
- creationEntityPublicKey: isSet$2(object.creationEntityPublicKey) ? bytesFromBase64$2(object.creationEntityPublicKey) : void 0,
56122
- extraMetadata: isSet$2(object.extraMetadata) ? bytesFromBase64$2(object.extraMetadata) : void 0
56123
- };
56124
- },
56125
- toJSON(message) {
56126
- const obj = {};
56127
- if (message.issuerPublicKey.length !== 0) obj.issuerPublicKey = base64FromBytes$2(message.issuerPublicKey);
56128
- if (message.tokenName !== "") obj.tokenName = message.tokenName;
56129
- if (message.tokenTicker !== "") obj.tokenTicker = message.tokenTicker;
56130
- if (message.decimals !== 0) obj.decimals = Math.round(message.decimals);
56131
- if (message.maxSupply.length !== 0) obj.maxSupply = base64FromBytes$2(message.maxSupply);
56132
- if (message.isFreezable !== false) obj.isFreezable = message.isFreezable;
56133
- if (message.creationEntityPublicKey !== void 0) obj.creationEntityPublicKey = base64FromBytes$2(message.creationEntityPublicKey);
56134
- if (message.extraMetadata !== void 0) obj.extraMetadata = base64FromBytes$2(message.extraMetadata);
56135
- return obj;
56136
- },
56137
- create(base) {
56138
- return TokenCreateInput.fromPartial(base ?? {});
56139
- },
56140
- fromPartial(object) {
56141
- const message = createBaseTokenCreateInput();
56142
- message.issuerPublicKey = object.issuerPublicKey ?? new Uint8Array(0);
56143
- message.tokenName = object.tokenName ?? "";
56144
- message.tokenTicker = object.tokenTicker ?? "";
56145
- message.decimals = object.decimals ?? 0;
56146
- message.maxSupply = object.maxSupply ?? new Uint8Array(0);
56147
- message.isFreezable = object.isFreezable ?? false;
56148
- message.creationEntityPublicKey = object.creationEntityPublicKey ?? void 0;
56149
- message.extraMetadata = object.extraMetadata ?? void 0;
55836
+ const message = createBaseTokenCreateInput();
55837
+ message.issuerPublicKey = object.issuerPublicKey ?? new Uint8Array(0);
55838
+ message.tokenName = object.tokenName ?? "";
55839
+ message.tokenTicker = object.tokenTicker ?? "";
55840
+ message.decimals = object.decimals ?? 0;
55841
+ message.maxSupply = object.maxSupply ?? new Uint8Array(0);
55842
+ message.isFreezable = object.isFreezable ?? false;
55843
+ message.creationEntityPublicKey = object.creationEntityPublicKey ?? void 0;
55844
+ message.extraMetadata = object.extraMetadata ?? void 0;
56150
55845
  return message;
56151
55846
  }
56152
55847
  };
@@ -58469,385 +58164,1058 @@ var TokenTransactionWithStatus = {
58469
58164
  return message;
58470
58165
  }
58471
58166
  };
58472
- function createBaseFreezeTokensPayload() {
58473
- return {
58474
- version: 0,
58475
- ownerPublicKey: new Uint8Array(0),
58476
- tokenPublicKey: void 0,
58477
- tokenIdentifier: void 0,
58478
- issuerProvidedTimestamp: 0,
58479
- operatorIdentityPublicKey: new Uint8Array(0),
58480
- shouldUnfreeze: false
58481
- };
58167
+ function createBaseFreezeTokensPayload() {
58168
+ return {
58169
+ version: 0,
58170
+ ownerPublicKey: new Uint8Array(0),
58171
+ tokenPublicKey: void 0,
58172
+ tokenIdentifier: void 0,
58173
+ issuerProvidedTimestamp: 0,
58174
+ operatorIdentityPublicKey: new Uint8Array(0),
58175
+ shouldUnfreeze: false
58176
+ };
58177
+ }
58178
+ var FreezeTokensPayload = {
58179
+ encode(message, writer = new BinaryWriter()) {
58180
+ if (message.version !== 0) writer.uint32(8).uint32(message.version);
58181
+ if (message.ownerPublicKey.length !== 0) writer.uint32(18).bytes(message.ownerPublicKey);
58182
+ if (message.tokenPublicKey !== void 0) writer.uint32(26).bytes(message.tokenPublicKey);
58183
+ if (message.tokenIdentifier !== void 0) writer.uint32(34).bytes(message.tokenIdentifier);
58184
+ if (message.issuerProvidedTimestamp !== 0) writer.uint32(40).uint64(message.issuerProvidedTimestamp);
58185
+ if (message.operatorIdentityPublicKey.length !== 0) writer.uint32(50).bytes(message.operatorIdentityPublicKey);
58186
+ if (message.shouldUnfreeze !== false) writer.uint32(56).bool(message.shouldUnfreeze);
58187
+ return writer;
58188
+ },
58189
+ decode(input, length) {
58190
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58191
+ const end = length === void 0 ? reader.len : reader.pos + length;
58192
+ const message = createBaseFreezeTokensPayload();
58193
+ while (reader.pos < end) {
58194
+ const tag = reader.uint32();
58195
+ switch (tag >>> 3) {
58196
+ case 1:
58197
+ if (tag !== 8) break;
58198
+ message.version = reader.uint32();
58199
+ continue;
58200
+ case 2:
58201
+ if (tag !== 18) break;
58202
+ message.ownerPublicKey = reader.bytes();
58203
+ continue;
58204
+ case 3:
58205
+ if (tag !== 26) break;
58206
+ message.tokenPublicKey = reader.bytes();
58207
+ continue;
58208
+ case 4:
58209
+ if (tag !== 34) break;
58210
+ message.tokenIdentifier = reader.bytes();
58211
+ continue;
58212
+ case 5:
58213
+ if (tag !== 40) break;
58214
+ message.issuerProvidedTimestamp = longToNumber$2(reader.uint64());
58215
+ continue;
58216
+ case 6:
58217
+ if (tag !== 50) break;
58218
+ message.operatorIdentityPublicKey = reader.bytes();
58219
+ continue;
58220
+ case 7:
58221
+ if (tag !== 56) break;
58222
+ message.shouldUnfreeze = reader.bool();
58223
+ continue;
58224
+ }
58225
+ if ((tag & 7) === 4 || tag === 0) break;
58226
+ reader.skip(tag & 7);
58227
+ }
58228
+ return message;
58229
+ },
58230
+ fromJSON(object) {
58231
+ return {
58232
+ version: isSet$2(object.version) ? globalThis.Number(object.version) : 0,
58233
+ ownerPublicKey: isSet$2(object.ownerPublicKey) ? bytesFromBase64$2(object.ownerPublicKey) : new Uint8Array(0),
58234
+ tokenPublicKey: isSet$2(object.tokenPublicKey) ? bytesFromBase64$2(object.tokenPublicKey) : void 0,
58235
+ tokenIdentifier: isSet$2(object.tokenIdentifier) ? bytesFromBase64$2(object.tokenIdentifier) : void 0,
58236
+ issuerProvidedTimestamp: isSet$2(object.issuerProvidedTimestamp) ? globalThis.Number(object.issuerProvidedTimestamp) : 0,
58237
+ operatorIdentityPublicKey: isSet$2(object.operatorIdentityPublicKey) ? bytesFromBase64$2(object.operatorIdentityPublicKey) : new Uint8Array(0),
58238
+ shouldUnfreeze: isSet$2(object.shouldUnfreeze) ? globalThis.Boolean(object.shouldUnfreeze) : false
58239
+ };
58240
+ },
58241
+ toJSON(message) {
58242
+ const obj = {};
58243
+ if (message.version !== 0) obj.version = Math.round(message.version);
58244
+ if (message.ownerPublicKey.length !== 0) obj.ownerPublicKey = base64FromBytes$2(message.ownerPublicKey);
58245
+ if (message.tokenPublicKey !== void 0) obj.tokenPublicKey = base64FromBytes$2(message.tokenPublicKey);
58246
+ if (message.tokenIdentifier !== void 0) obj.tokenIdentifier = base64FromBytes$2(message.tokenIdentifier);
58247
+ if (message.issuerProvidedTimestamp !== 0) obj.issuerProvidedTimestamp = Math.round(message.issuerProvidedTimestamp);
58248
+ if (message.operatorIdentityPublicKey.length !== 0) obj.operatorIdentityPublicKey = base64FromBytes$2(message.operatorIdentityPublicKey);
58249
+ if (message.shouldUnfreeze !== false) obj.shouldUnfreeze = message.shouldUnfreeze;
58250
+ return obj;
58251
+ },
58252
+ create(base) {
58253
+ return FreezeTokensPayload.fromPartial(base ?? {});
58254
+ },
58255
+ fromPartial(object) {
58256
+ const message = createBaseFreezeTokensPayload();
58257
+ message.version = object.version ?? 0;
58258
+ message.ownerPublicKey = object.ownerPublicKey ?? new Uint8Array(0);
58259
+ message.tokenPublicKey = object.tokenPublicKey ?? void 0;
58260
+ message.tokenIdentifier = object.tokenIdentifier ?? void 0;
58261
+ message.issuerProvidedTimestamp = object.issuerProvidedTimestamp ?? 0;
58262
+ message.operatorIdentityPublicKey = object.operatorIdentityPublicKey ?? new Uint8Array(0);
58263
+ message.shouldUnfreeze = object.shouldUnfreeze ?? false;
58264
+ return message;
58265
+ }
58266
+ };
58267
+ function createBaseFreezeTokensRequest() {
58268
+ return {
58269
+ freezeTokensPayload: void 0,
58270
+ issuerSignature: new Uint8Array(0)
58271
+ };
58272
+ }
58273
+ var FreezeTokensRequest = {
58274
+ encode(message, writer = new BinaryWriter()) {
58275
+ if (message.freezeTokensPayload !== void 0) FreezeTokensPayload.encode(message.freezeTokensPayload, writer.uint32(10).fork()).join();
58276
+ if (message.issuerSignature.length !== 0) writer.uint32(18).bytes(message.issuerSignature);
58277
+ return writer;
58278
+ },
58279
+ decode(input, length) {
58280
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58281
+ const end = length === void 0 ? reader.len : reader.pos + length;
58282
+ const message = createBaseFreezeTokensRequest();
58283
+ while (reader.pos < end) {
58284
+ const tag = reader.uint32();
58285
+ switch (tag >>> 3) {
58286
+ case 1:
58287
+ if (tag !== 10) break;
58288
+ message.freezeTokensPayload = FreezeTokensPayload.decode(reader, reader.uint32());
58289
+ continue;
58290
+ case 2:
58291
+ if (tag !== 18) break;
58292
+ message.issuerSignature = reader.bytes();
58293
+ continue;
58294
+ }
58295
+ if ((tag & 7) === 4 || tag === 0) break;
58296
+ reader.skip(tag & 7);
58297
+ }
58298
+ return message;
58299
+ },
58300
+ fromJSON(object) {
58301
+ return {
58302
+ freezeTokensPayload: isSet$2(object.freezeTokensPayload) ? FreezeTokensPayload.fromJSON(object.freezeTokensPayload) : void 0,
58303
+ issuerSignature: isSet$2(object.issuerSignature) ? bytesFromBase64$2(object.issuerSignature) : new Uint8Array(0)
58304
+ };
58305
+ },
58306
+ toJSON(message) {
58307
+ const obj = {};
58308
+ if (message.freezeTokensPayload !== void 0) obj.freezeTokensPayload = FreezeTokensPayload.toJSON(message.freezeTokensPayload);
58309
+ if (message.issuerSignature.length !== 0) obj.issuerSignature = base64FromBytes$2(message.issuerSignature);
58310
+ return obj;
58311
+ },
58312
+ create(base) {
58313
+ return FreezeTokensRequest.fromPartial(base ?? {});
58314
+ },
58315
+ fromPartial(object) {
58316
+ const message = createBaseFreezeTokensRequest();
58317
+ message.freezeTokensPayload = object.freezeTokensPayload !== void 0 && object.freezeTokensPayload !== null ? FreezeTokensPayload.fromPartial(object.freezeTokensPayload) : void 0;
58318
+ message.issuerSignature = object.issuerSignature ?? new Uint8Array(0);
58319
+ return message;
58320
+ }
58321
+ };
58322
+ function createBaseTokenOutputRef() {
58323
+ return {
58324
+ transactionHash: new Uint8Array(0),
58325
+ vout: 0
58326
+ };
58327
+ }
58328
+ var TokenOutputRef = {
58329
+ encode(message, writer = new BinaryWriter()) {
58330
+ if (message.transactionHash.length !== 0) writer.uint32(10).bytes(message.transactionHash);
58331
+ if (message.vout !== 0) writer.uint32(16).uint32(message.vout);
58332
+ return writer;
58333
+ },
58334
+ decode(input, length) {
58335
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58336
+ const end = length === void 0 ? reader.len : reader.pos + length;
58337
+ const message = createBaseTokenOutputRef();
58338
+ while (reader.pos < end) {
58339
+ const tag = reader.uint32();
58340
+ switch (tag >>> 3) {
58341
+ case 1:
58342
+ if (tag !== 10) break;
58343
+ message.transactionHash = reader.bytes();
58344
+ continue;
58345
+ case 2:
58346
+ if (tag !== 16) break;
58347
+ message.vout = reader.uint32();
58348
+ continue;
58349
+ }
58350
+ if ((tag & 7) === 4 || tag === 0) break;
58351
+ reader.skip(tag & 7);
58352
+ }
58353
+ return message;
58354
+ },
58355
+ fromJSON(object) {
58356
+ return {
58357
+ transactionHash: isSet$2(object.transactionHash) ? bytesFromBase64$2(object.transactionHash) : new Uint8Array(0),
58358
+ vout: isSet$2(object.vout) ? globalThis.Number(object.vout) : 0
58359
+ };
58360
+ },
58361
+ toJSON(message) {
58362
+ const obj = {};
58363
+ if (message.transactionHash.length !== 0) obj.transactionHash = base64FromBytes$2(message.transactionHash);
58364
+ if (message.vout !== 0) obj.vout = Math.round(message.vout);
58365
+ return obj;
58366
+ },
58367
+ create(base) {
58368
+ return TokenOutputRef.fromPartial(base ?? {});
58369
+ },
58370
+ fromPartial(object) {
58371
+ const message = createBaseTokenOutputRef();
58372
+ message.transactionHash = object.transactionHash ?? new Uint8Array(0);
58373
+ message.vout = object.vout ?? 0;
58374
+ return message;
58375
+ }
58376
+ };
58377
+ function createBaseFreezeProgress() {
58378
+ return {
58379
+ frozenOperatorPublicKeys: [],
58380
+ unfrozenOperatorPublicKeys: []
58381
+ };
58382
+ }
58383
+ var FreezeProgress = {
58384
+ encode(message, writer = new BinaryWriter()) {
58385
+ for (const v of message.frozenOperatorPublicKeys) writer.uint32(10).bytes(v);
58386
+ for (const v of message.unfrozenOperatorPublicKeys) writer.uint32(18).bytes(v);
58387
+ return writer;
58388
+ },
58389
+ decode(input, length) {
58390
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58391
+ const end = length === void 0 ? reader.len : reader.pos + length;
58392
+ const message = createBaseFreezeProgress();
58393
+ while (reader.pos < end) {
58394
+ const tag = reader.uint32();
58395
+ switch (tag >>> 3) {
58396
+ case 1:
58397
+ if (tag !== 10) break;
58398
+ message.frozenOperatorPublicKeys.push(reader.bytes());
58399
+ continue;
58400
+ case 2:
58401
+ if (tag !== 18) break;
58402
+ message.unfrozenOperatorPublicKeys.push(reader.bytes());
58403
+ continue;
58404
+ }
58405
+ if ((tag & 7) === 4 || tag === 0) break;
58406
+ reader.skip(tag & 7);
58407
+ }
58408
+ return message;
58409
+ },
58410
+ fromJSON(object) {
58411
+ return {
58412
+ frozenOperatorPublicKeys: globalThis.Array.isArray(object?.frozenOperatorPublicKeys) ? object.frozenOperatorPublicKeys.map((e) => bytesFromBase64$2(e)) : [],
58413
+ unfrozenOperatorPublicKeys: globalThis.Array.isArray(object?.unfrozenOperatorPublicKeys) ? object.unfrozenOperatorPublicKeys.map((e) => bytesFromBase64$2(e)) : []
58414
+ };
58415
+ },
58416
+ toJSON(message) {
58417
+ const obj = {};
58418
+ if (message.frozenOperatorPublicKeys?.length) obj.frozenOperatorPublicKeys = message.frozenOperatorPublicKeys.map((e) => base64FromBytes$2(e));
58419
+ if (message.unfrozenOperatorPublicKeys?.length) obj.unfrozenOperatorPublicKeys = message.unfrozenOperatorPublicKeys.map((e) => base64FromBytes$2(e));
58420
+ return obj;
58421
+ },
58422
+ create(base) {
58423
+ return FreezeProgress.fromPartial(base ?? {});
58424
+ },
58425
+ fromPartial(object) {
58426
+ const message = createBaseFreezeProgress();
58427
+ message.frozenOperatorPublicKeys = object.frozenOperatorPublicKeys?.map((e) => e) || [];
58428
+ message.unfrozenOperatorPublicKeys = object.unfrozenOperatorPublicKeys?.map((e) => e) || [];
58429
+ return message;
58430
+ }
58431
+ };
58432
+ function createBaseFreezeTokensResponse() {
58433
+ return {
58434
+ impactedOutputIds: [],
58435
+ impactedTokenAmount: new Uint8Array(0),
58436
+ impactedTokenOutputs: [],
58437
+ freezeProgress: void 0
58438
+ };
58439
+ }
58440
+ var FreezeTokensResponse = {
58441
+ encode(message, writer = new BinaryWriter()) {
58442
+ for (const v of message.impactedOutputIds) writer.uint32(10).string(v);
58443
+ if (message.impactedTokenAmount.length !== 0) writer.uint32(18).bytes(message.impactedTokenAmount);
58444
+ for (const v of message.impactedTokenOutputs) TokenOutputRef.encode(v, writer.uint32(26).fork()).join();
58445
+ if (message.freezeProgress !== void 0) FreezeProgress.encode(message.freezeProgress, writer.uint32(34).fork()).join();
58446
+ return writer;
58447
+ },
58448
+ decode(input, length) {
58449
+ const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58450
+ const end = length === void 0 ? reader.len : reader.pos + length;
58451
+ const message = createBaseFreezeTokensResponse();
58452
+ while (reader.pos < end) {
58453
+ const tag = reader.uint32();
58454
+ switch (tag >>> 3) {
58455
+ case 1:
58456
+ if (tag !== 10) break;
58457
+ message.impactedOutputIds.push(reader.string());
58458
+ continue;
58459
+ case 2:
58460
+ if (tag !== 18) break;
58461
+ message.impactedTokenAmount = reader.bytes();
58462
+ continue;
58463
+ case 3:
58464
+ if (tag !== 26) break;
58465
+ message.impactedTokenOutputs.push(TokenOutputRef.decode(reader, reader.uint32()));
58466
+ continue;
58467
+ case 4:
58468
+ if (tag !== 34) break;
58469
+ message.freezeProgress = FreezeProgress.decode(reader, reader.uint32());
58470
+ continue;
58471
+ }
58472
+ if ((tag & 7) === 4 || tag === 0) break;
58473
+ reader.skip(tag & 7);
58474
+ }
58475
+ return message;
58476
+ },
58477
+ fromJSON(object) {
58478
+ return {
58479
+ impactedOutputIds: globalThis.Array.isArray(object?.impactedOutputIds) ? object.impactedOutputIds.map((e) => globalThis.String(e)) : [],
58480
+ impactedTokenAmount: isSet$2(object.impactedTokenAmount) ? bytesFromBase64$2(object.impactedTokenAmount) : new Uint8Array(0),
58481
+ impactedTokenOutputs: globalThis.Array.isArray(object?.impactedTokenOutputs) ? object.impactedTokenOutputs.map((e) => TokenOutputRef.fromJSON(e)) : [],
58482
+ freezeProgress: isSet$2(object.freezeProgress) ? FreezeProgress.fromJSON(object.freezeProgress) : void 0
58483
+ };
58484
+ },
58485
+ toJSON(message) {
58486
+ const obj = {};
58487
+ if (message.impactedOutputIds?.length) obj.impactedOutputIds = message.impactedOutputIds;
58488
+ if (message.impactedTokenAmount.length !== 0) obj.impactedTokenAmount = base64FromBytes$2(message.impactedTokenAmount);
58489
+ if (message.impactedTokenOutputs?.length) obj.impactedTokenOutputs = message.impactedTokenOutputs.map((e) => TokenOutputRef.toJSON(e));
58490
+ if (message.freezeProgress !== void 0) obj.freezeProgress = FreezeProgress.toJSON(message.freezeProgress);
58491
+ return obj;
58492
+ },
58493
+ create(base) {
58494
+ return FreezeTokensResponse.fromPartial(base ?? {});
58495
+ },
58496
+ fromPartial(object) {
58497
+ const message = createBaseFreezeTokensResponse();
58498
+ message.impactedOutputIds = object.impactedOutputIds?.map((e) => e) || [];
58499
+ message.impactedTokenAmount = object.impactedTokenAmount ?? new Uint8Array(0);
58500
+ message.impactedTokenOutputs = object.impactedTokenOutputs?.map((e) => TokenOutputRef.fromPartial(e)) || [];
58501
+ message.freezeProgress = object.freezeProgress !== void 0 && object.freezeProgress !== null ? FreezeProgress.fromPartial(object.freezeProgress) : void 0;
58502
+ return message;
58503
+ }
58504
+ };
58505
+ var SparkTokenServiceDefinition = {
58506
+ name: "SparkTokenService",
58507
+ fullName: "spark_token.SparkTokenService",
58508
+ methods: {
58509
+ start_transaction: {
58510
+ name: "start_transaction",
58511
+ requestType: StartTransactionRequest,
58512
+ requestStream: false,
58513
+ responseType: StartTransactionResponse,
58514
+ responseStream: false,
58515
+ options: {}
58516
+ },
58517
+ commit_transaction: {
58518
+ name: "commit_transaction",
58519
+ requestType: CommitTransactionRequest,
58520
+ requestStream: false,
58521
+ responseType: CommitTransactionResponse,
58522
+ responseStream: false,
58523
+ options: {}
58524
+ },
58525
+ query_token_metadata: {
58526
+ name: "query_token_metadata",
58527
+ requestType: QueryTokenMetadataRequest,
58528
+ requestStream: false,
58529
+ responseType: QueryTokenMetadataResponse,
58530
+ responseStream: false,
58531
+ options: {}
58532
+ },
58533
+ query_token_transactions: {
58534
+ name: "query_token_transactions",
58535
+ requestType: QueryTokenTransactionsRequest,
58536
+ requestStream: false,
58537
+ responseType: QueryTokenTransactionsResponse,
58538
+ responseStream: false,
58539
+ options: {}
58540
+ },
58541
+ query_token_outputs: {
58542
+ name: "query_token_outputs",
58543
+ requestType: QueryTokenOutputsRequest,
58544
+ requestStream: false,
58545
+ responseType: QueryTokenOutputsResponse,
58546
+ responseStream: false,
58547
+ options: {}
58548
+ },
58549
+ freeze_tokens: {
58550
+ name: "freeze_tokens",
58551
+ requestType: FreezeTokensRequest,
58552
+ requestStream: false,
58553
+ responseType: FreezeTokensResponse,
58554
+ responseStream: false,
58555
+ options: {}
58556
+ },
58557
+ broadcast_transaction: {
58558
+ name: "broadcast_transaction",
58559
+ requestType: BroadcastTransactionRequest,
58560
+ requestStream: false,
58561
+ responseType: BroadcastTransactionResponse,
58562
+ responseStream: false,
58563
+ options: {}
58564
+ }
58565
+ }
58566
+ };
58567
+ function bytesFromBase64$2(b64) {
58568
+ if (globalThis.Buffer) return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
58569
+ else {
58570
+ const bin = globalThis.atob(b64);
58571
+ const arr = new Uint8Array(bin.length);
58572
+ for (let i = 0; i < bin.length; ++i) arr[i] = bin.charCodeAt(i);
58573
+ return arr;
58574
+ }
58575
+ }
58576
+ function base64FromBytes$2(arr) {
58577
+ if (globalThis.Buffer) return globalThis.Buffer.from(arr).toString("base64");
58578
+ else {
58579
+ const bin = [];
58580
+ arr.forEach((byte) => {
58581
+ bin.push(globalThis.String.fromCharCode(byte));
58582
+ });
58583
+ return globalThis.btoa(bin.join(""));
58584
+ }
58585
+ }
58586
+ function toTimestamp(date) {
58587
+ return {
58588
+ seconds: Math.trunc(date.getTime() / 1e3),
58589
+ nanos: date.getTime() % 1e3 * 1e6
58590
+ };
58591
+ }
58592
+ function fromTimestamp(t) {
58593
+ let millis = (t.seconds || 0) * 1e3;
58594
+ millis += (t.nanos || 0) / 1e6;
58595
+ return new globalThis.Date(millis);
58596
+ }
58597
+ function fromJsonTimestamp(o) {
58598
+ if (o instanceof globalThis.Date) return o;
58599
+ else if (typeof o === "string") return new globalThis.Date(o);
58600
+ else return fromTimestamp(Timestamp.fromJSON(o));
58601
+ }
58602
+ function longToNumber$2(int64) {
58603
+ const num2 = globalThis.Number(int64.toString());
58604
+ if (num2 > globalThis.Number.MAX_SAFE_INTEGER) throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
58605
+ if (num2 < globalThis.Number.MIN_SAFE_INTEGER) throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER");
58606
+ return num2;
58607
+ }
58608
+ function isSet$2(value) {
58609
+ return value !== null && value !== void 0;
58610
+ }
58611
+ var TokenOutputManager = class {
58612
+ availableOutputs = /* @__PURE__ */ new Map();
58613
+ localPendingMap = /* @__PURE__ */ new Map();
58614
+ serverPendingMap = /* @__PURE__ */ new Map();
58615
+ mutex = new Mutex();
58616
+ lockExpiryMs;
58617
+ constructor(lockExpiryMs = 3e4) {
58618
+ this.lockExpiryMs = lockExpiryMs;
58619
+ }
58620
+ /**
58621
+ * Sync all outputs from the server
58622
+ *
58623
+ * @param serverProvidedOutputs - All outputs from the server, grouped by token identifier
58624
+ * @param tokenIdentifiers - If provided, only update these tokens (preserving others).
58625
+ * If omitted or empty, replaces all outputs.
58626
+ */
58627
+ async setOutputs(serverProvidedOutputs, tokenIdentifiers) {
58628
+ await this.mutex.runExclusive(() => {
58629
+ const availableByToken = /* @__PURE__ */ new Map();
58630
+ const pendingByToken = /* @__PURE__ */ new Map();
58631
+ for (const [tokenId, outputs] of serverProvidedOutputs) {
58632
+ const available = [];
58633
+ const pending = [];
58634
+ for (const output of outputs) if (output.output?.status === TokenOutputStatus.TOKEN_OUTPUT_STATUS_PENDING_OUTBOUND) {
58635
+ pending.push(output);
58636
+ if (output.output?.id) this.localPendingMap.delete(output.output.id);
58637
+ } else if (output.output?.status === TokenOutputStatus.TOKEN_OUTPUT_STATUS_AVAILABLE) available.push(output);
58638
+ if (available.length > 0) availableByToken.set(tokenId, available);
58639
+ if (pending.length > 0) pendingByToken.set(tokenId, pending);
58640
+ }
58641
+ if (tokenIdentifiers && tokenIdentifiers.length > 0) for (const tokenId of tokenIdentifiers) {
58642
+ const available = availableByToken.get(tokenId);
58643
+ if (available && available.length > 0) this.availableOutputs.set(tokenId, [...available]);
58644
+ else this.availableOutputs.delete(tokenId);
58645
+ const pending = pendingByToken.get(tokenId);
58646
+ if (pending && pending.length > 0) this.serverPendingMap.set(tokenId, [...pending]);
58647
+ else this.serverPendingMap.delete(tokenId);
58648
+ }
58649
+ else {
58650
+ this.availableOutputs = new Map([...availableByToken.entries()].map(([k, v]) => [k, [...v]]));
58651
+ this.serverPendingMap = new Map([...pendingByToken.entries()].map(([k, v]) => [k, [...v]]));
58652
+ }
58653
+ });
58654
+ }
58655
+ /**
58656
+ * Get pending outbound outputs for a token.
58657
+ */
58658
+ async getPendingOutboundOutputs(tokenIdentifier) {
58659
+ return await this.mutex.runExclusive(() => {
58660
+ return [...this.serverPendingMap.get(tokenIdentifier) ?? []];
58661
+ });
58662
+ }
58663
+ /**
58664
+ * Get available outputs for a token (including client-locked pending ones)
58665
+ */
58666
+ async getAvailableOutputs(tokenIdentifier) {
58667
+ return await this.mutex.runExclusive(() => {
58668
+ return [...this.availableOutputs.get(tokenIdentifier) ?? []];
58669
+ });
58670
+ }
58671
+ /**
58672
+ * Check if outputs map has a token identifier.
58673
+ */
58674
+ async hasTokenIdentifier(tokenIdentifier) {
58675
+ return await this.mutex.runExclusive(() => {
58676
+ return this.availableOutputs.has(tokenIdentifier) || this.serverPendingMap.has(tokenIdentifier);
58677
+ });
58678
+ }
58679
+ /**
58680
+ * Get all token identifiers in the map.
58681
+ */
58682
+ async getTokenIdentifiers() {
58683
+ return await this.mutex.runExclusive(() => {
58684
+ return this.getAllKeys();
58685
+ });
58686
+ }
58687
+ /**
58688
+ * Iterate over entries (snapshot).
58689
+ */
58690
+ async entries() {
58691
+ return await this.mutex.runExclusive(() => {
58692
+ return [...this.availableOutputs.entries()];
58693
+ });
58694
+ }
58695
+ /**
58696
+ * Atomically select and lock outputs.
58697
+ * Returns the selected outputs and a release function.
58698
+ *
58699
+ * @param tokenIdentifier - The token to select from
58700
+ * @param selector - Function to select outputs from available (unlocked) outputs
58701
+ * @param operationId - name of the operation for debugging purposes
58702
+ * @returns AcquiredOutputs with outputs and release function
58703
+ */
58704
+ async acquireOutputs(tokenIdentifier, selector, operationId) {
58705
+ return await this.mutex.runExclusive(() => {
58706
+ this.cleanupExpiredLocks();
58707
+ const available = this.getUnlockedOutputsInternal(tokenIdentifier);
58708
+ const selected = selector(available);
58709
+ if (selected.length === 0) return {
58710
+ outputs: [],
58711
+ release: async () => {
58712
+ }
58713
+ };
58714
+ const availableIds = new Set(available.map((o) => o.output.id));
58715
+ for (const output of selected) {
58716
+ const id = output.output.id;
58717
+ if (!availableIds.has(id)) throw new Error(`Selected output ${id} is not in the available set`);
58718
+ }
58719
+ const now = Date.now();
58720
+ const lockedIds = [];
58721
+ for (const output of selected) {
58722
+ const id = output.output.id;
58723
+ this.localPendingMap.set(id, {
58724
+ lockedAt: now,
58725
+ operationId
58726
+ });
58727
+ lockedIds.push(id);
58728
+ }
58729
+ const release = async () => {
58730
+ await this.releaseOutputsByIds(lockedIds);
58731
+ };
58732
+ return {
58733
+ outputs: selected,
58734
+ release
58735
+ };
58736
+ });
58737
+ }
58738
+ /**
58739
+ * Lock outputs locally.
58740
+ */
58741
+ async lockOutputs(outputs, operationId) {
58742
+ await this.mutex.runExclusive(() => {
58743
+ const now = Date.now();
58744
+ for (const output of outputs) {
58745
+ const id = output.output.id;
58746
+ this.localPendingMap.set(id, {
58747
+ lockedAt: now,
58748
+ operationId
58749
+ });
58750
+ }
58751
+ });
58752
+ }
58753
+ /**
58754
+ * Lock specific outputs by ID
58755
+ */
58756
+ async lockOutputsByIds(outputIds, operationId) {
58757
+ await this.mutex.runExclusive(() => {
58758
+ const now = Date.now();
58759
+ for (const id of outputIds) this.localPendingMap.set(id, {
58760
+ lockedAt: now,
58761
+ operationId
58762
+ });
58763
+ });
58764
+ }
58765
+ /**
58766
+ * Release outputs.
58767
+ */
58768
+ async releaseOutputs(outputs) {
58769
+ await this.mutex.runExclusive(() => {
58770
+ for (const output of outputs) {
58771
+ const id = output.output.id;
58772
+ this.localPendingMap.delete(id);
58773
+ }
58774
+ });
58775
+ }
58776
+ /**
58777
+ * Release outputs by ID.
58778
+ */
58779
+ async releaseOutputsByIds(outputIds) {
58780
+ await this.mutex.runExclusive(() => {
58781
+ for (const id of outputIds) this.localPendingMap.delete(id);
58782
+ });
58783
+ }
58784
+ /**
58785
+ * Check if an output is locked.
58786
+ */
58787
+ async isLocked(outputId) {
58788
+ return await this.mutex.runExclusive(() => {
58789
+ this.cleanupExpiredLocks();
58790
+ return this.localPendingMap.has(outputId);
58791
+ });
58792
+ }
58793
+ /**
58794
+ * Check if outputs map is empty.
58795
+ */
58796
+ async isEmpty() {
58797
+ return await this.mutex.runExclusive(() => {
58798
+ return this.availableOutputs.size === 0 && this.serverPendingMap.size === 0;
58799
+ });
58800
+ }
58801
+ /**
58802
+ * Get size of outputs map (number of token identifiers).
58803
+ */
58804
+ async size() {
58805
+ return await this.mutex.runExclusive(() => {
58806
+ return this.getAllKeys().length;
58807
+ });
58808
+ }
58809
+ /**
58810
+ * Clear all outputs and locks.
58811
+ */
58812
+ async clear() {
58813
+ await this.mutex.runExclusive(() => {
58814
+ this.availableOutputs.clear();
58815
+ this.serverPendingMap.clear();
58816
+ this.localPendingMap.clear();
58817
+ });
58818
+ }
58819
+ getUnlockedOutputsInternal(tokenIdentifier) {
58820
+ return (this.availableOutputs.get(tokenIdentifier) ?? []).filter((o) => !this.localPendingMap.has(o.output.id));
58821
+ }
58822
+ cleanupExpiredLocks() {
58823
+ const now = Date.now();
58824
+ for (const [id, lock] of this.localPendingMap) if (now - lock.lockedAt > this.lockExpiryMs) this.localPendingMap.delete(id);
58825
+ }
58826
+ getAllKeys() {
58827
+ return Array.from(/* @__PURE__ */ new Set([...this.availableOutputs.keys(), ...this.serverPendingMap.keys()]));
58828
+ }
58829
+ };
58830
+ function HashSparkInvoice(sparkInvoiceFields, receiverPublicKey, network) {
58831
+ if (!sparkInvoiceFields) throw new Error("Missing sparkInvoiceFields");
58832
+ if (!receiverPublicKey) throw new Error("Receiver public key is required");
58833
+ if (!network) throw new Error("Network is required");
58834
+ switch (sparkInvoiceFields.version) {
58835
+ case 1:
58836
+ return HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network);
58837
+ default:
58838
+ throw new Error(`Unsupported invoice version: ${sparkInvoiceFields.version}`);
58839
+ }
58482
58840
  }
58483
- var FreezeTokensPayload = {
58484
- encode(message, writer = new BinaryWriter()) {
58485
- if (message.version !== 0) writer.uint32(8).uint32(message.version);
58486
- if (message.ownerPublicKey.length !== 0) writer.uint32(18).bytes(message.ownerPublicKey);
58487
- if (message.tokenPublicKey !== void 0) writer.uint32(26).bytes(message.tokenPublicKey);
58488
- if (message.tokenIdentifier !== void 0) writer.uint32(34).bytes(message.tokenIdentifier);
58489
- if (message.issuerProvidedTimestamp !== 0) writer.uint32(40).uint64(message.issuerProvidedTimestamp);
58490
- if (message.operatorIdentityPublicKey.length !== 0) writer.uint32(50).bytes(message.operatorIdentityPublicKey);
58491
- if (message.shouldUnfreeze !== false) writer.uint32(56).bool(message.shouldUnfreeze);
58492
- return writer;
58493
- },
58494
- decode(input, length) {
58495
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58496
- const end = length === void 0 ? reader.len : reader.pos + length;
58497
- const message = createBaseFreezeTokensPayload();
58498
- while (reader.pos < end) {
58499
- const tag = reader.uint32();
58500
- switch (tag >>> 3) {
58501
- case 1:
58502
- if (tag !== 8) break;
58503
- message.version = reader.uint32();
58504
- continue;
58505
- case 2:
58506
- if (tag !== 18) break;
58507
- message.ownerPublicKey = reader.bytes();
58508
- continue;
58509
- case 3:
58510
- if (tag !== 26) break;
58511
- message.tokenPublicKey = reader.bytes();
58512
- continue;
58513
- case 4:
58514
- if (tag !== 34) break;
58515
- message.tokenIdentifier = reader.bytes();
58516
- continue;
58517
- case 5:
58518
- if (tag !== 40) break;
58519
- message.issuerProvidedTimestamp = longToNumber$2(reader.uint64());
58520
- continue;
58521
- case 6:
58522
- if (tag !== 50) break;
58523
- message.operatorIdentityPublicKey = reader.bytes();
58524
- continue;
58525
- case 7:
58526
- if (tag !== 56) break;
58527
- message.shouldUnfreeze = reader.bool();
58528
- continue;
58841
+ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
58842
+ if (!sparkInvoiceFields) throw new Error("Missing sparkInvoiceFields");
58843
+ if (!receiverPublicKey) throw new Error("Receiver public key is required");
58844
+ if (!network) throw new Error("Network is required");
58845
+ const { version: version2, id, paymentType, memo, senderPublicKey, expiryTime } = sparkInvoiceFields;
58846
+ const allHashes = [];
58847
+ const versionHashObj = sha256.create();
58848
+ const versionBytes = uint32be(version2);
58849
+ versionHashObj.update(versionBytes);
58850
+ allHashes.push(versionHashObj.digest());
58851
+ const idHashObj = sha256.create();
58852
+ if (!id || id.length !== 16) throw new Error("invoice id must be exactly 16 bytes");
58853
+ idHashObj.update(id);
58854
+ allHashes.push(idHashObj.digest());
58855
+ const networkHashObj = sha256.create();
58856
+ hashNetworkMagicInto(networkHashObj, network);
58857
+ allHashes.push(networkHashObj.digest());
58858
+ const receiverPubKeyHashObj = sha256.create();
58859
+ if (!receiverPublicKey || receiverPublicKey.length !== 33) throw new Error("receiver public key must be exactly 33 bytes");
58860
+ receiverPubKeyHashObj.update(receiverPublicKey);
58861
+ allHashes.push(receiverPubKeyHashObj.digest());
58862
+ switch (paymentType?.$case) {
58863
+ case "tokensPayment": {
58864
+ const tp = paymentType.tokensPayment;
58865
+ const discrHash = sha256.create();
58866
+ discrHash.update(new Uint8Array([1]));
58867
+ allHashes.push(discrHash.digest());
58868
+ const tokenIdHash = sha256.create();
58869
+ const tokenIdentifier = tp.tokenIdentifier;
58870
+ if (!tokenIdentifier || tokenIdentifier.length === 0) tokenIdHash.update(new Uint8Array(32));
58871
+ else {
58872
+ if (tokenIdentifier.length !== 32) throw new Error("token identifier must be exactly 32 bytes");
58873
+ tokenIdHash.update(tokenIdentifier);
58529
58874
  }
58530
- if ((tag & 7) === 4 || tag === 0) break;
58531
- reader.skip(tag & 7);
58875
+ allHashes.push(tokenIdHash.digest());
58876
+ const amountHash = sha256.create();
58877
+ const amount = tp.amount;
58878
+ if (amount && amount.length > 16) throw new Error("token amount exceeds 16 bytes");
58879
+ if (amount && amount.length > 0) amountHash.update(amount);
58880
+ allHashes.push(amountHash.digest());
58881
+ break;
58532
58882
  }
58533
- return message;
58534
- },
58535
- fromJSON(object) {
58536
- return {
58537
- version: isSet$2(object.version) ? globalThis.Number(object.version) : 0,
58538
- ownerPublicKey: isSet$2(object.ownerPublicKey) ? bytesFromBase64$2(object.ownerPublicKey) : new Uint8Array(0),
58539
- tokenPublicKey: isSet$2(object.tokenPublicKey) ? bytesFromBase64$2(object.tokenPublicKey) : void 0,
58540
- tokenIdentifier: isSet$2(object.tokenIdentifier) ? bytesFromBase64$2(object.tokenIdentifier) : void 0,
58541
- issuerProvidedTimestamp: isSet$2(object.issuerProvidedTimestamp) ? globalThis.Number(object.issuerProvidedTimestamp) : 0,
58542
- operatorIdentityPublicKey: isSet$2(object.operatorIdentityPublicKey) ? bytesFromBase64$2(object.operatorIdentityPublicKey) : new Uint8Array(0),
58543
- shouldUnfreeze: isSet$2(object.shouldUnfreeze) ? globalThis.Boolean(object.shouldUnfreeze) : false
58544
- };
58545
- },
58546
- toJSON(message) {
58547
- const obj = {};
58548
- if (message.version !== 0) obj.version = Math.round(message.version);
58549
- if (message.ownerPublicKey.length !== 0) obj.ownerPublicKey = base64FromBytes$2(message.ownerPublicKey);
58550
- if (message.tokenPublicKey !== void 0) obj.tokenPublicKey = base64FromBytes$2(message.tokenPublicKey);
58551
- if (message.tokenIdentifier !== void 0) obj.tokenIdentifier = base64FromBytes$2(message.tokenIdentifier);
58552
- if (message.issuerProvidedTimestamp !== 0) obj.issuerProvidedTimestamp = Math.round(message.issuerProvidedTimestamp);
58553
- if (message.operatorIdentityPublicKey.length !== 0) obj.operatorIdentityPublicKey = base64FromBytes$2(message.operatorIdentityPublicKey);
58554
- if (message.shouldUnfreeze !== false) obj.shouldUnfreeze = message.shouldUnfreeze;
58555
- return obj;
58556
- },
58557
- create(base) {
58558
- return FreezeTokensPayload.fromPartial(base ?? {});
58559
- },
58560
- fromPartial(object) {
58561
- const message = createBaseFreezeTokensPayload();
58562
- message.version = object.version ?? 0;
58563
- message.ownerPublicKey = object.ownerPublicKey ?? new Uint8Array(0);
58564
- message.tokenPublicKey = object.tokenPublicKey ?? void 0;
58565
- message.tokenIdentifier = object.tokenIdentifier ?? void 0;
58566
- message.issuerProvidedTimestamp = object.issuerProvidedTimestamp ?? 0;
58567
- message.operatorIdentityPublicKey = object.operatorIdentityPublicKey ?? new Uint8Array(0);
58568
- message.shouldUnfreeze = object.shouldUnfreeze ?? false;
58569
- return message;
58883
+ case "satsPayment": {
58884
+ const sp = paymentType.satsPayment;
58885
+ const discrHash = sha256.create();
58886
+ discrHash.update(new Uint8Array([2]));
58887
+ allHashes.push(discrHash.digest());
58888
+ const satsHash = sha256.create();
58889
+ let sats = 0n;
58890
+ if (sp && typeof sp.amount === "number" && sp.amount !== 0) sats = BigInt(sp.amount);
58891
+ satsHash.update(uint64be(sats));
58892
+ allHashes.push(satsHash.digest());
58893
+ break;
58894
+ }
58895
+ default:
58896
+ throw new Error("unsupported or missing payment type");
58570
58897
  }
58571
- };
58572
- function createBaseFreezeTokensRequest() {
58573
- return {
58574
- freezeTokensPayload: void 0,
58575
- issuerSignature: new Uint8Array(0)
58576
- };
58898
+ const memoHashObj = sha256.create();
58899
+ if (memo != null) memoHashObj.update(new TextEncoder().encode(memo));
58900
+ allHashes.push(memoHashObj.digest());
58901
+ const senderPubKeyHashObj = sha256.create();
58902
+ const spk = senderPublicKey;
58903
+ if (!spk || spk.length === 0) senderPubKeyHashObj.update(new Uint8Array(33));
58904
+ else {
58905
+ if (spk.length !== 33) throw new Error("sender public key must be exactly 33 bytes");
58906
+ senderPubKeyHashObj.update(spk);
58907
+ }
58908
+ allHashes.push(senderPubKeyHashObj.digest());
58909
+ const expiryHashObj = sha256.create();
58910
+ let exp = 0n;
58911
+ if (expiryTime instanceof Date) {
58912
+ const seconds = Math.floor(expiryTime.getTime() / 1e3);
58913
+ if (seconds > 0) exp = BigInt(seconds);
58914
+ }
58915
+ expiryHashObj.update(uint64be(exp));
58916
+ allHashes.push(expiryHashObj.digest());
58917
+ const finalHash = sha256.create();
58918
+ for (const hash of allHashes) finalHash.update(hash);
58919
+ return finalHash.digest();
58577
58920
  }
58578
- var FreezeTokensRequest = {
58579
- encode(message, writer = new BinaryWriter()) {
58580
- if (message.freezeTokensPayload !== void 0) FreezeTokensPayload.encode(message.freezeTokensPayload, writer.uint32(10).fork()).join();
58581
- if (message.issuerSignature.length !== 0) writer.uint32(18).bytes(message.issuerSignature);
58582
- return writer;
58583
- },
58584
- decode(input, length) {
58585
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58586
- const end = length === void 0 ? reader.len : reader.pos + length;
58587
- const message = createBaseFreezeTokensRequest();
58588
- while (reader.pos < end) {
58589
- const tag = reader.uint32();
58590
- switch (tag >>> 3) {
58591
- case 1:
58592
- if (tag !== 10) break;
58593
- message.freezeTokensPayload = FreezeTokensPayload.decode(reader, reader.uint32());
58594
- continue;
58595
- case 2:
58596
- if (tag !== 18) break;
58597
- message.issuerSignature = reader.bytes();
58598
- continue;
58599
- }
58600
- if ((tag & 7) === 4 || tag === 0) break;
58601
- reader.skip(tag & 7);
58602
- }
58603
- return message;
58604
- },
58605
- fromJSON(object) {
58606
- return {
58607
- freezeTokensPayload: isSet$2(object.freezeTokensPayload) ? FreezeTokensPayload.fromJSON(object.freezeTokensPayload) : void 0,
58608
- issuerSignature: isSet$2(object.issuerSignature) ? bytesFromBase64$2(object.issuerSignature) : new Uint8Array(0)
58609
- };
58610
- },
58611
- toJSON(message) {
58612
- const obj = {};
58613
- if (message.freezeTokensPayload !== void 0) obj.freezeTokensPayload = FreezeTokensPayload.toJSON(message.freezeTokensPayload);
58614
- if (message.issuerSignature.length !== 0) obj.issuerSignature = base64FromBytes$2(message.issuerSignature);
58615
- return obj;
58616
- },
58617
- create(base) {
58618
- return FreezeTokensRequest.fromPartial(base ?? {});
58619
- },
58620
- fromPartial(object) {
58621
- const message = createBaseFreezeTokensRequest();
58622
- message.freezeTokensPayload = object.freezeTokensPayload !== void 0 && object.freezeTokensPayload !== null ? FreezeTokensPayload.fromPartial(object.freezeTokensPayload) : void 0;
58623
- message.issuerSignature = object.issuerSignature ?? new Uint8Array(0);
58624
- return message;
58921
+ function bitcoinNetworkIdentifierFromNetwork(network) {
58922
+ switch (network) {
58923
+ case "MAINNET":
58924
+ return 3652501241;
58925
+ case "LOCAL":
58926
+ case "REGTEST":
58927
+ return 3669344250;
58928
+ case "TESTNET":
58929
+ return 118034699;
58930
+ case "SIGNET":
58931
+ return 1087308554;
58932
+ default:
58933
+ throw new Error("invalid network");
58625
58934
  }
58935
+ }
58936
+ function hashNetworkMagicInto(hasher, network) {
58937
+ const magicBE = uint32be(bitcoinNetworkIdentifierFromNetwork(network));
58938
+ hasher.update(sha256(magicBE));
58939
+ }
58940
+ function uint32be(n) {
58941
+ const b = new Uint8Array(4);
58942
+ new DataView(b.buffer).setUint32(0, n >>> 0, false);
58943
+ return b;
58944
+ }
58945
+ function uint64be(value) {
58946
+ const b = new Uint8Array(8);
58947
+ new DataView(b.buffer).setBigUint64(0, value, false);
58948
+ return b;
58949
+ }
58950
+ var BECH32M_LIMIT = 1024;
58951
+ var AddressNetwork = {
58952
+ MAINNET: "spark",
58953
+ TESTNET: "sparkt",
58954
+ REGTEST: "sparkrt",
58955
+ SIGNET: "sparks",
58956
+ LOCAL: "sparkl"
58626
58957
  };
58627
- function createBaseTokenOutputRef() {
58628
- return {
58629
- transactionHash: new Uint8Array(0),
58630
- vout: 0
58631
- };
58958
+ var LegacyAddressNetwork = {
58959
+ MAINNET: "sp",
58960
+ TESTNET: "spt",
58961
+ REGTEST: "sprt",
58962
+ SIGNET: "sps",
58963
+ LOCAL: "spl"
58964
+ };
58965
+ function encodeSparkAddress(payload) {
58966
+ return encodeSparkAddressWithSignature(payload);
58632
58967
  }
58633
- var TokenOutputRef = {
58634
- encode(message, writer = new BinaryWriter()) {
58635
- if (message.transactionHash.length !== 0) writer.uint32(10).bytes(message.transactionHash);
58636
- if (message.vout !== 0) writer.uint32(16).uint32(message.vout);
58637
- return writer;
58638
- },
58639
- decode(input, length) {
58640
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58641
- const end = length === void 0 ? reader.len : reader.pos + length;
58642
- const message = createBaseTokenOutputRef();
58643
- while (reader.pos < end) {
58644
- const tag = reader.uint32();
58645
- switch (tag >>> 3) {
58646
- case 1:
58647
- if (tag !== 10) break;
58648
- message.transactionHash = reader.bytes();
58649
- continue;
58650
- case 2:
58651
- if (tag !== 16) break;
58652
- message.vout = reader.uint32();
58653
- continue;
58654
- }
58655
- if ((tag & 7) === 4 || tag === 0) break;
58656
- reader.skip(tag & 7);
58968
+ function encodeSparkAddressWithSignature(payload, signature) {
58969
+ try {
58970
+ isValidPublicKey(payload.identityPublicKey);
58971
+ const identityPublicKey = hexToBytes(payload.identityPublicKey);
58972
+ let sparkInvoiceFields;
58973
+ if (payload.sparkInvoiceFields) {
58974
+ validateSparkInvoiceFields(payload.sparkInvoiceFields);
58975
+ sparkInvoiceFields = payload.sparkInvoiceFields;
58657
58976
  }
58658
- return message;
58659
- },
58660
- fromJSON(object) {
58661
- return {
58662
- transactionHash: isSet$2(object.transactionHash) ? bytesFromBase64$2(object.transactionHash) : new Uint8Array(0),
58663
- vout: isSet$2(object.vout) ? globalThis.Number(object.vout) : 0
58664
- };
58665
- },
58666
- toJSON(message) {
58667
- const obj = {};
58668
- if (message.transactionHash.length !== 0) obj.transactionHash = base64FromBytes$2(message.transactionHash);
58669
- if (message.vout !== 0) obj.vout = Math.round(message.vout);
58670
- return obj;
58671
- },
58672
- create(base) {
58673
- return TokenOutputRef.fromPartial(base ?? {});
58674
- },
58675
- fromPartial(object) {
58676
- const message = createBaseTokenOutputRef();
58677
- message.transactionHash = object.transactionHash ?? new Uint8Array(0);
58678
- message.vout = object.vout ?? 0;
58679
- return message;
58977
+ const w = new BinaryWriter();
58978
+ w.uint32(10).bytes(identityPublicKey);
58979
+ if (sparkInvoiceFields) {
58980
+ const inner = encodeSparkInvoiceFieldsV1Canonical(sparkInvoiceFields);
58981
+ w.uint32(18).bytes(inner);
58982
+ }
58983
+ if (signature && signature.length) w.uint32(26).bytes(signature);
58984
+ const serializedPayload = w.finish();
58985
+ const words = bech32m2.toWords(serializedPayload);
58986
+ return bech32mEncode(AddressNetwork[payload.network], words);
58987
+ } catch (error) {
58988
+ throw new SparkValidationError("Failed to encode Spark address", {
58989
+ field: "publicKey",
58990
+ value: payload.identityPublicKey,
58991
+ error
58992
+ });
58680
58993
  }
58681
- };
58682
- function createBaseFreezeTokensResponse() {
58683
- return {
58684
- impactedOutputIds: [],
58685
- impactedTokenAmount: new Uint8Array(0),
58686
- impactedTokenOutputs: []
58687
- };
58688
58994
  }
58689
- var FreezeTokensResponse = {
58690
- encode(message, writer = new BinaryWriter()) {
58691
- for (const v of message.impactedOutputIds) writer.uint32(10).string(v);
58692
- if (message.impactedTokenAmount.length !== 0) writer.uint32(18).bytes(message.impactedTokenAmount);
58693
- for (const v of message.impactedTokenOutputs) TokenOutputRef.encode(v, writer.uint32(26).fork()).join();
58694
- return writer;
58695
- },
58696
- decode(input, length) {
58697
- const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
58698
- const end = length === void 0 ? reader.len : reader.pos + length;
58699
- const message = createBaseFreezeTokensResponse();
58700
- while (reader.pos < end) {
58701
- const tag = reader.uint32();
58702
- switch (tag >>> 3) {
58703
- case 1:
58704
- if (tag !== 10) break;
58705
- message.impactedOutputIds.push(reader.string());
58706
- continue;
58707
- case 2:
58708
- if (tag !== 18) break;
58709
- message.impactedTokenAmount = reader.bytes();
58710
- continue;
58711
- case 3:
58712
- if (tag !== 26) break;
58713
- message.impactedTokenOutputs.push(TokenOutputRef.decode(reader, reader.uint32()));
58714
- continue;
58715
- }
58716
- if ((tag & 7) === 4 || tag === 0) break;
58717
- reader.skip(tag & 7);
58718
- }
58719
- return message;
58720
- },
58721
- fromJSON(object) {
58995
+ function decodeSparkAddress(address, network) {
58996
+ try {
58997
+ if (network !== getNetworkFromSparkAddress(address)) throw new SparkValidationError("Invalid Spark address prefix", {
58998
+ field: "address",
58999
+ value: address,
59000
+ expected: `prefix='${AddressNetwork[network]}' or '${LegacyAddressNetwork[network]}'`
59001
+ });
59002
+ const decoded = bech32mDecode(address);
59003
+ const { identityPublicKey, sparkInvoiceFields, signature } = SparkAddress.decode(bech32m2.fromWords(decoded.words));
59004
+ const identityPubkeyHex = bytesToHex(identityPublicKey);
59005
+ const signatureHex = signature ? bytesToHex(signature) : void 0;
59006
+ isValidPublicKey(identityPubkeyHex);
58722
59007
  return {
58723
- impactedOutputIds: globalThis.Array.isArray(object?.impactedOutputIds) ? object.impactedOutputIds.map((e) => globalThis.String(e)) : [],
58724
- impactedTokenAmount: isSet$2(object.impactedTokenAmount) ? bytesFromBase64$2(object.impactedTokenAmount) : new Uint8Array(0),
58725
- impactedTokenOutputs: globalThis.Array.isArray(object?.impactedTokenOutputs) ? object.impactedTokenOutputs.map((e) => TokenOutputRef.fromJSON(e)) : []
59008
+ identityPublicKey: identityPubkeyHex,
59009
+ network,
59010
+ sparkInvoiceFields: sparkInvoiceFields && {
59011
+ version: sparkInvoiceFields.version,
59012
+ id: UUID.ofInner(sparkInvoiceFields.id).toString(),
59013
+ paymentType: sparkInvoiceFields.paymentType ? sparkInvoiceFields.paymentType.$case === "tokensPayment" ? {
59014
+ type: "tokens",
59015
+ tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? bytesToHex(sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier) : void 0,
59016
+ amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? bytesToNumberBE(sparkInvoiceFields.paymentType.tokensPayment.amount) : void 0
59017
+ } : sparkInvoiceFields.paymentType.$case === "satsPayment" ? {
59018
+ type: "sats",
59019
+ amount: sparkInvoiceFields.paymentType.satsPayment.amount
59020
+ } : void 0 : void 0,
59021
+ memo: sparkInvoiceFields.memo,
59022
+ senderPublicKey: sparkInvoiceFields.senderPublicKey ? bytesToHex(sparkInvoiceFields.senderPublicKey) : void 0,
59023
+ expiryTime: sparkInvoiceFields.expiryTime
59024
+ },
59025
+ signature: signatureHex
58726
59026
  };
58727
- },
58728
- toJSON(message) {
58729
- const obj = {};
58730
- if (message.impactedOutputIds?.length) obj.impactedOutputIds = message.impactedOutputIds;
58731
- if (message.impactedTokenAmount.length !== 0) obj.impactedTokenAmount = base64FromBytes$2(message.impactedTokenAmount);
58732
- if (message.impactedTokenOutputs?.length) obj.impactedTokenOutputs = message.impactedTokenOutputs.map((e) => TokenOutputRef.toJSON(e));
58733
- return obj;
58734
- },
58735
- create(base) {
58736
- return FreezeTokensResponse.fromPartial(base ?? {});
58737
- },
58738
- fromPartial(object) {
58739
- const message = createBaseFreezeTokensResponse();
58740
- message.impactedOutputIds = object.impactedOutputIds?.map((e) => e) || [];
58741
- message.impactedTokenAmount = object.impactedTokenAmount ?? new Uint8Array(0);
58742
- message.impactedTokenOutputs = object.impactedTokenOutputs?.map((e) => TokenOutputRef.fromPartial(e)) || [];
58743
- return message;
59027
+ } catch (error) {
59028
+ if (error instanceof SparkValidationError) throw error;
59029
+ throw new SparkValidationError("Failed to decode Spark address", {
59030
+ field: "address",
59031
+ value: address,
59032
+ error
59033
+ });
59034
+ }
59035
+ }
59036
+ var PrefixToNetwork = Object.fromEntries(Object.entries(AddressNetwork).map(([k, v]) => [v, k]));
59037
+ var LegacyPrefixToNetwork = Object.fromEntries(Object.entries(LegacyAddressNetwork).map(([k, v]) => [v, k]));
59038
+ function getNetworkFromSparkAddress(address) {
59039
+ const { prefix: prefix2 } = bech32mDecode(address);
59040
+ const network = PrefixToNetwork[prefix2] ?? LegacyPrefixToNetwork[prefix2];
59041
+ if (!network) throw new SparkValidationError("Invalid Spark address prefix", {
59042
+ field: "network",
59043
+ value: address,
59044
+ expected: "prefix='spark1', 'sparkt1', 'sparkrt1', 'sparks1', 'sparkl1' or legacy ('sp1', 'spt1', 'sprt1', 'sps1', 'spl1')"
59045
+ });
59046
+ return network;
59047
+ }
59048
+ function isLegacySparkAddress(address) {
59049
+ try {
59050
+ const { prefix: prefix2 } = bech32mDecode(address);
59051
+ return prefix2 in LegacyPrefixToNetwork;
59052
+ } catch (error) {
59053
+ return false;
59054
+ }
59055
+ }
59056
+ function isValidSparkAddress(address) {
59057
+ try {
59058
+ decodeSparkAddress(address, getNetworkFromSparkAddress(address));
59059
+ return true;
59060
+ } catch (error) {
59061
+ if (error instanceof SparkValidationError) throw error;
59062
+ throw new SparkValidationError("Invalid Spark address", {
59063
+ field: "address",
59064
+ value: address,
59065
+ error
59066
+ });
59067
+ }
59068
+ }
59069
+ function isValidPublicKey(publicKey) {
59070
+ try {
59071
+ secp256k12.Point.fromHex(publicKey).assertValidity();
59072
+ } catch (error) {
59073
+ throw new SparkValidationError("Invalid public key", {
59074
+ field: "publicKey",
59075
+ value: publicKey,
59076
+ error
59077
+ });
58744
59078
  }
58745
- };
58746
- var SparkTokenServiceDefinition = {
58747
- name: "SparkTokenService",
58748
- fullName: "spark_token.SparkTokenService",
58749
- methods: {
58750
- start_transaction: {
58751
- name: "start_transaction",
58752
- requestType: StartTransactionRequest,
58753
- requestStream: false,
58754
- responseType: StartTransactionResponse,
58755
- responseStream: false,
58756
- options: {}
58757
- },
58758
- commit_transaction: {
58759
- name: "commit_transaction",
58760
- requestType: CommitTransactionRequest,
58761
- requestStream: false,
58762
- responseType: CommitTransactionResponse,
58763
- responseStream: false,
58764
- options: {}
58765
- },
58766
- query_token_metadata: {
58767
- name: "query_token_metadata",
58768
- requestType: QueryTokenMetadataRequest,
58769
- requestStream: false,
58770
- responseType: QueryTokenMetadataResponse,
58771
- responseStream: false,
58772
- options: {}
58773
- },
58774
- query_token_transactions: {
58775
- name: "query_token_transactions",
58776
- requestType: QueryTokenTransactionsRequest,
58777
- requestStream: false,
58778
- responseType: QueryTokenTransactionsResponse,
58779
- responseStream: false,
58780
- options: {}
58781
- },
58782
- query_token_outputs: {
58783
- name: "query_token_outputs",
58784
- requestType: QueryTokenOutputsRequest,
58785
- requestStream: false,
58786
- responseType: QueryTokenOutputsResponse,
58787
- responseStream: false,
58788
- options: {}
58789
- },
58790
- freeze_tokens: {
58791
- name: "freeze_tokens",
58792
- requestType: FreezeTokensRequest,
58793
- requestStream: false,
58794
- responseType: FreezeTokensResponse,
58795
- responseStream: false,
58796
- options: {}
58797
- },
58798
- broadcast_transaction: {
58799
- name: "broadcast_transaction",
58800
- requestType: BroadcastTransactionRequest,
58801
- requestStream: false,
58802
- responseType: BroadcastTransactionResponse,
58803
- responseStream: false,
58804
- options: {}
58805
- }
59079
+ }
59080
+ function validateSparkInvoiceFields(sparkInvoiceFields) {
59081
+ const { version: version2, id, paymentType, memo, senderPublicKey } = sparkInvoiceFields;
59082
+ if (version2 !== 1) throw new SparkValidationError("Version must be 1", {
59083
+ field: "version",
59084
+ value: version2
59085
+ });
59086
+ try {
59087
+ UUID.ofInner(id);
59088
+ } catch (error) {
59089
+ throw new SparkValidationError("Invalid id", {
59090
+ field: "id",
59091
+ value: id,
59092
+ error
59093
+ });
58806
59094
  }
58807
- };
58808
- function bytesFromBase64$2(b64) {
58809
- if (globalThis.Buffer) return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
58810
- else {
58811
- const bin = globalThis.atob(b64);
58812
- const arr = new Uint8Array(bin.length);
58813
- for (let i = 0; i < bin.length; ++i) arr[i] = bin.charCodeAt(i);
58814
- return arr;
59095
+ if (senderPublicKey) try {
59096
+ isValidPublicKey(bytesToHex(senderPublicKey));
59097
+ } catch (error) {
59098
+ throw new SparkValidationError("Invalid sender public key", {
59099
+ field: "senderPublicKey",
59100
+ value: senderPublicKey,
59101
+ error
59102
+ });
59103
+ }
59104
+ if (memo) {
59105
+ if (new TextEncoder().encode(memo).length > 120) throw new SparkValidationError("Memo exceeds the maximum allowed byte length of 120.", {
59106
+ field: "memo",
59107
+ value: memo,
59108
+ expected: "less than 120 bytes"
59109
+ });
58815
59110
  }
59111
+ if (paymentType) if (paymentType.$case === "tokensPayment") {
59112
+ const MAX_UINT128 = BigInt(2 ** 128 - 1);
59113
+ const { amount: tokensAmount, tokenIdentifier } = paymentType.tokensPayment;
59114
+ if (tokenIdentifier) {
59115
+ if (!(tokenIdentifier instanceof Uint8Array)) throw new SparkValidationError("Token identifier must be Uint8Array", {
59116
+ field: "paymentType.tokensPayment.tokenIdentifier",
59117
+ value: tokenIdentifier
59118
+ });
59119
+ if (tokenIdentifier.length !== 32) throw new SparkValidationError("Token identifier must be 32 bytes", {
59120
+ field: "paymentType.tokensPayment.tokenIdentifier",
59121
+ value: tokenIdentifier
59122
+ });
59123
+ }
59124
+ if (tokensAmount) {
59125
+ if (tokensAmount.length > 16) throw new SparkValidationError("Amount must be less than 16 bytes", {
59126
+ field: "paymentType.tokensPayment.amount",
59127
+ value: tokensAmount
59128
+ });
59129
+ const tokensAmountBigInt = bytesToNumberBE(tokensAmount);
59130
+ if (tokensAmountBigInt < 0 || tokensAmountBigInt > MAX_UINT128) throw new SparkValidationError("Asset amount must be between 0 and MAX_UINT128", {
59131
+ field: "amount",
59132
+ value: tokensAmount
59133
+ });
59134
+ }
59135
+ } else if (paymentType.$case === "satsPayment") {
59136
+ const { amount } = paymentType.satsPayment;
59137
+ if (amount) {
59138
+ const MAX_SATS_AMOUNT = 21e14;
59139
+ if (amount < 0) throw new SparkValidationError("Amount must be greater than or equal to 0", {
59140
+ field: "paymentType.satsPayment.amount",
59141
+ value: amount
59142
+ });
59143
+ if (amount > MAX_SATS_AMOUNT) throw new SparkValidationError(`Amount must be less than ${MAX_SATS_AMOUNT} sats`);
59144
+ }
59145
+ } else throw new SparkValidationError("Invalid payment type", {
59146
+ field: "paymentType",
59147
+ value: paymentType
59148
+ });
58816
59149
  }
58817
- function base64FromBytes$2(arr) {
58818
- if (globalThis.Buffer) return globalThis.Buffer.from(arr).toString("base64");
58819
- else {
58820
- const bin = [];
58821
- arr.forEach((byte) => {
58822
- bin.push(globalThis.String.fromCharCode(byte));
59150
+ function validateSparkInvoiceSignature(invoice) {
59151
+ try {
59152
+ const decoded = bech32mDecode(invoice);
59153
+ const network = getNetworkFromSparkAddress(invoice);
59154
+ const { identityPublicKey, sparkInvoiceFields, signature } = SparkAddress.decode(bech32m2.fromWords(decoded.words));
59155
+ if (!sparkInvoiceFields) throw new SparkValidationError("Spark invoice fields are required", {
59156
+ field: "sparkInvoiceFields",
59157
+ value: sparkInvoiceFields
59158
+ });
59159
+ if (!signature) throw new SparkValidationError("Signature is required", {
59160
+ field: "signature",
59161
+ value: signature
59162
+ });
59163
+ if (!identityPublicKey) throw new SparkValidationError("Identity public key is required", {
59164
+ field: "identityPublicKey",
59165
+ value: identityPublicKey
59166
+ });
59167
+ const hash = HashSparkInvoice(sparkInvoiceFields, identityPublicKey, network);
59168
+ const xOnly = secp256k12.Point.fromHex(identityPublicKey).toBytes(true).slice(1);
59169
+ if (!schnorr.verify(signature, hash, xOnly)) throw new SparkValidationError("Invalid signature", {
59170
+ field: "signature",
59171
+ value: signature
59172
+ });
59173
+ } catch (error) {
59174
+ if (error instanceof SparkValidationError) throw error;
59175
+ throw new SparkValidationError("Failed to validate Spark invoice signature", {
59176
+ field: "invoice",
59177
+ value: invoice,
59178
+ error
58823
59179
  });
58824
- return globalThis.btoa(bin.join(""));
58825
59180
  }
58826
59181
  }
58827
- function toTimestamp(date) {
59182
+ function toProtoTimestamp(date) {
59183
+ const ms = date.getTime();
58828
59184
  return {
58829
- seconds: Math.trunc(date.getTime() / 1e3),
58830
- nanos: date.getTime() % 1e3 * 1e6
59185
+ seconds: Math.floor(ms / 1e3),
59186
+ nanos: ms % 1e3 * 1e6
58831
59187
  };
58832
59188
  }
58833
- function fromTimestamp(t) {
58834
- let millis = (t.seconds || 0) * 1e3;
58835
- millis += (t.nanos || 0) / 1e6;
58836
- return new globalThis.Date(millis);
59189
+ function assertBech32(s) {
59190
+ const i = s.lastIndexOf("1");
59191
+ if (i <= 0 || i >= s.length - 1) throw new Error("invalid bech32 string");
58837
59192
  }
58838
- function fromJsonTimestamp(o) {
58839
- if (o instanceof globalThis.Date) return o;
58840
- else if (typeof o === "string") return new globalThis.Date(o);
58841
- else return fromTimestamp(Timestamp.fromJSON(o));
59193
+ function bech32mDecode(address) {
59194
+ assertBech32(address);
59195
+ return bech32m2.decode(address, BECH32M_LIMIT);
58842
59196
  }
58843
- function longToNumber$2(int64) {
58844
- const num2 = globalThis.Number(int64.toString());
58845
- if (num2 > globalThis.Number.MAX_SAFE_INTEGER) throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
58846
- if (num2 < globalThis.Number.MIN_SAFE_INTEGER) throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER");
58847
- return num2;
59197
+ function bech32mEncode(prefix2, words) {
59198
+ return bech32m2.encode(prefix2, words, BECH32M_LIMIT);
58848
59199
  }
58849
- function isSet$2(value) {
58850
- return value !== null && value !== void 0;
59200
+ function encodeSparkInvoiceFieldsV1Canonical(f) {
59201
+ const w = new BinaryWriter();
59202
+ if (f.version !== 0) w.uint32(8).uint32(f.version);
59203
+ if (f.id && f.id.length) w.uint32(18).bytes(f.id);
59204
+ if (f.memo !== void 0) w.uint32(42).string(f.memo);
59205
+ if (f.senderPublicKey !== void 0) w.uint32(50).bytes(f.senderPublicKey);
59206
+ if (f.expiryTime !== void 0) Timestamp.encode(toProtoTimestamp(f.expiryTime), w.uint32(58).fork()).join();
59207
+ switch (f.paymentType?.$case) {
59208
+ case "tokensPayment":
59209
+ TokensPayment.encode(f.paymentType.tokensPayment, w.uint32(26).fork()).join();
59210
+ break;
59211
+ case "satsPayment":
59212
+ SatsPayment.encode(f.paymentType.satsPayment, w.uint32(34).fork()).join();
59213
+ break;
59214
+ }
59215
+ return w.finish();
59216
+ }
59217
+ function isSafeForNumber(bi) {
59218
+ return bi >= BigInt(Number.MIN_SAFE_INTEGER) && bi <= BigInt(Number.MAX_SAFE_INTEGER);
58851
59219
  }
58852
59220
  var Edition = /* @__PURE__ */ (function(Edition2) {
58853
59221
  Edition2[Edition2["EDITION_UNKNOWN"] = 0] = "EDITION_UNKNOWN";
@@ -62355,7 +62723,7 @@ function longToNumber$1(int64) {
62355
62723
  function isSet$1(value) {
62356
62724
  return value !== null && value !== void 0;
62357
62725
  }
62358
- var SPARK_DESCRIPTORS_BASE64 = "Cv8BCh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJvdG9idWYiOwoJVGltZXN0YW1wEhgKB3NlY29uZHMYASABKANSB3NlY29uZHMSFAoFbmFub3MYAiABKAVSBW5hbm9zQoUBChNjb20uZ29vZ2xlLnByb3RvYnVmQg5UaW1lc3RhbXBQcm90b1ABWjJnb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9rbm93bi90aW1lc3RhbXBwYvgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8zCr4BChtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiIHCgVFbXB0eUJ9ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3RvUAFaLmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2VtcHR5cGL4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMwqiZwogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiJbChFGaWxlRGVzY3JpcHRvclNldBI4CgRmaWxlGAEgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9SBGZpbGUqDAiA7Mr/ARCB7Mr/ASLFBQoTRmlsZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhgKB3BhY2thZ2UYAiABKAlSB3BhY2thZ2USHgoKZGVwZW5kZW5jeRgDIAMoCVIKZGVwZW5kZW5jeRIrChFwdWJsaWNfZGVwZW5kZW5jeRgKIAMoBVIQcHVibGljRGVwZW5kZW5jeRInCg93ZWFrX2RlcGVuZGVuY3kYCyADKAVSDndlYWtEZXBlbmRlbmN5EisKEW9wdGlvbl9kZXBlbmRlbmN5GA8gAygJUhBvcHRpb25EZXBlbmRlbmN5EkMKDG1lc3NhZ2VfdHlwZRgEIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SC21lc3NhZ2VUeXBlEkEKCWVudW1fdHlwZRgFIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvUghlbnVtVHlwZRJBCgdzZXJ2aWNlGAYgAygLMicuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG9SB3NlcnZpY2USQwoJZXh0ZW5zaW9uGAcgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUglleHRlbnNpb24SNgoHb3B0aW9ucxgIIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1IHb3B0aW9ucxJJChBzb3VyY2VfY29kZV9pbmZvGAkgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvUg5zb3VyY2VDb2RlSW5mbxIWCgZzeW50YXgYDCABKAlSBnN5bnRheBIyCgdlZGl0aW9uGA4gASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SB2VkaXRpb24i/AYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRJBCgp2aXNpYmlsaXR5GAsgASgOMiEuZ29vZ2xlLnByb3RvYnVmLlN5bWJvbFZpc2liaWxpdHlSCnZpc2liaWxpdHkaegoORXh0ZW5zaW9uUmFuZ2USFAoFc3RhcnQYASABKAVSBXN0YXJ0EhAKA2VuZBgCIAEoBVIDZW5kEkAKB29wdGlvbnMYAyABKAsyJi5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zUgdvcHRpb25zGjcKDVJlc2VydmVkUmFuZ2USFAoFc3RhcnQYASABKAVSBXN0YXJ0EhAKA2VuZBgCIAEoBVIDZW5kIswEChVFeHRlbnNpb25SYW5nZU9wdGlvbnMSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24SWQoLZGVjbGFyYXRpb24YAiADKAsyMi5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zLkRlY2xhcmF0aW9uQgOIAQJSC2RlY2xhcmF0aW9uEjcKCGZlYXR1cmVzGDIgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXRSCGZlYXR1cmVzEm0KDHZlcmlmaWNhdGlvbhgDIAEoDjI4Lmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnMuVmVyaWZpY2F0aW9uU3RhdGU6ClVOVkVSSUZJRURCA4gBAlIMdmVyaWZpY2F0aW9uGpQBCgtEZWNsYXJhdGlvbhIWCgZudW1iZXIYASABKAVSBm51bWJlchIbCglmdWxsX25hbWUYAiABKAlSCGZ1bGxOYW1lEhIKBHR5cGUYAyABKAlSBHR5cGUSGgoIcmVzZXJ2ZWQYBSABKAhSCHJlc2VydmVkEhoKCHJlcGVhdGVkGAYgASgIUghyZXBlYXRlZEoECAQQBSI0ChFWZXJpZmljYXRpb25TdGF0ZRIPCgtERUNMQVJBVElPThAAEg4KClVOVkVSSUZJRUQQASoJCOgHEICAgIACIsEGChRGaWVsZERlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgDIAEoBVIGbnVtYmVyEkEKBWxhYmVsGAQgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsUgVsYWJlbBI+CgR0eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGVSBHR5cGUSGwoJdHlwZV9uYW1lGAYgASgJUgh0eXBlTmFtZRIaCghleHRlbmRlZRgCIAEoCVIIZXh0ZW5kZWUSIwoNZGVmYXVsdF92YWx1ZRgHIAEoCVIMZGVmYXVsdFZhbHVlEh8KC29uZW9mX2luZGV4GAkgASgFUgpvbmVvZkluZGV4EhsKCWpzb25fbmFtZRgKIAEoCVIIanNvbk5hbWUSNwoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnNSB29wdGlvbnMSJwoPcHJvdG8zX29wdGlvbmFsGBEgASgIUg5wcm90bzNPcHRpb25hbCK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVBFQVRFRBADEhIKDkxBQkVMX1JFUVVJUkVEEAIiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyKmAwoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRJBCgp2aXNpYmlsaXR5GAYgASgOMiEuZ29vZ2xlLnByb3RvYnVmLlN5bWJvbFZpc2liaWxpdHlSCnZpc2liaWxpdHkaOwoRRW51bVJlc2VydmVkUmFuZ2USFAoFc3RhcnQYASABKAVSBXN0YXJ0EhAKA2VuZBgCIAEoBVIDZW5kIoMBChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIWCgZudW1iZXIYAiABKAVSBm51bWJlchI7CgdvcHRpb25zGAMgASgLMiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnNSB29wdGlvbnMitQEKFlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI+CgZtZXRob2QYAiADKAsyJi5nb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvUgZtZXRob2QSOQoHb3B0aW9ucxgDIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9uc1IHb3B0aW9uc0oECAQQBVIGc3RyZWFtIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyKtCQoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLgoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoEdHJ1ZVIOY2NFbmFibGVBcmVuYXMSKgoRb2JqY19jbGFzc19wcmVmaXgYJCABKAlSD29iamNDbGFzc1ByZWZpeBIpChBjc2hhcnBfbmFtZXNwYWNlGCUgASgJUg9jc2hhcnBOYW1lc3BhY2USIQoMc3dpZnRfcHJlZml4GCcgASgJUgtzd2lmdFByZWZpeBIoChBwaHBfY2xhc3NfcHJlZml4GCggASgJUg5waHBDbGFzc1ByZWZpeBIjCg1waHBfbmFtZXNwYWNlGCkgASgJUgxwaHBOYW1lc3BhY2USNAoWcGhwX21ldGFkYXRhX25hbWVzcGFjZRgsIAEoCVIUcGhwTWV0YWRhdGFOYW1lc3BhY2USIQoMcnVieV9wYWNrYWdlGC0gASgJUgtydWJ5UGFja2FnZRI3CghmZWF0dXJlcxgyIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJTUUQAyoJCOgHEICAgIACSgQIKhArSgQIJhAnUhRwaHBfZ2VuZXJpY19zZXJ2aWNlcyL0AwoOTWVzc2FnZU9wdGlvbnMSPAoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQYASABKAg6BWZhbHNlUhRtZXNzYWdlU2V0V2lyZUZvcm1hdBJMCh9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yGAIgASgIOgVmYWxzZVIcbm9TdGFuZGFyZERlc2NyaXB0b3JBY2Nlc3NvchIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIbCgltYXBfZW50cnkYByABKAhSCG1hcEVudHJ5ElYKJmRlcHJlY2F0ZWRfbGVnYWN5X2pzb25fZmllbGRfY29uZmxpY3RzGAsgASgIQgIYAVIiZGVwcmVjYXRlZExlZ2FjeUpzb25GaWVsZENvbmZsaWN0cxI3CghmZWF0dXJlcxgMIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACSgQIBBAFSgQIBRAGSgQIBhAHSgQICBAJSgQICRAKIqENCgxGaWVsZE9wdGlvbnMSQQoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkdSBWN0eXBlEhYKBnBhY2tlZBgCIAEoCFIGcGFja2VkEkcKBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUxSBmpzdHlwZRIZCgRsYXp5GAUgASgIOgVmYWxzZVIEbGF6eRIuCg91bnZlcmlmaWVkX2xhenkYDyABKAg6BWZhbHNlUg51bnZlcmlmaWVkTGF6eRIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIdCgR3ZWFrGAogASgIOgVmYWxzZUICGAFSBHdlYWsSKAoMZGVidWdfcmVkYWN0GBAgASgIOgVmYWxzZVILZGVidWdSZWRhY3QSSwoJcmV0ZW50aW9uGBEgASgOMi0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5PcHRpb25SZXRlbnRpb25SCXJldGVudGlvbhJICgd0YXJnZXRzGBMgAygOMi4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5PcHRpb25UYXJnZXRUeXBlUgd0YXJnZXRzElcKEGVkaXRpb25fZGVmYXVsdHMYFCADKAsyLC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkVkaXRpb25EZWZhdWx0Ug9lZGl0aW9uRGVmYXVsdHMSNwoIZmVhdHVyZXMYFSABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFIIZmVhdHVyZXMSVQoPZmVhdHVyZV9zdXBwb3J0GBYgASgLMiwuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5GZWF0dXJlU3VwcG9ydFIOZmVhdHVyZVN1cHBvcnQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24aWgoORWRpdGlvbkRlZmF1bHQSMgoHZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uUgdlZGl0aW9uEhQKBXZhbHVlGAIgASgJUgV2YWx1ZRqWAgoORmVhdHVyZVN1cHBvcnQSRwoSZWRpdGlvbl9pbnRyb2R1Y2VkGAEgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SEWVkaXRpb25JbnRyb2R1Y2VkEkcKEmVkaXRpb25fZGVwcmVjYXRlZBgCIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uUhFlZGl0aW9uRGVwcmVjYXRlZBIvChNkZXByZWNhdGlvbl93YXJuaW5nGAMgASgJUhJkZXByZWNhdGlvbldhcm5pbmcSQQoPZWRpdGlvbl9yZW1vdmVkGAQgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SDmVkaXRpb25SZW1vdmVkIi8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAESDQoJSlNfTlVNQkVSEAIiVQoPT3B0aW9uUmV0ZW50aW9uEhUKEVJFVEVOVElPTl9VTktOT1dOEAASFQoRUkVURU5USU9OX1JVTlRJTUUQARIUChBSRVRFTlRJT05fU09VUkNFEAIijAIKEE9wdGlvblRhcmdldFR5cGUSFwoTVEFSR0VUX1RZUEVfVU5LTk9XThAAEhQKEFRBUkdFVF9UWVBFX0ZJTEUQARIfChtUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UQAhIXChNUQVJHRVRfVFlQRV9NRVNTQUdFEAMSFQoRVEFSR0VUX1RZUEVfRklFTEQQBBIVChFUQVJHRVRfVFlQRV9PTkVPRhAFEhQKEFRBUkdFVF9UWVBFX0VOVU0QBhIaChZUQVJHRVRfVFlQRV9FTlVNX0VOVFJZEAcSFwoTVEFSR0VUX1RZUEVfU0VSVklDRRAIEhYKElRBUkdFVF9UWVBFX01FVEhPRBAJKgkI6AcQgICAgAJKBAgEEAVKBAgSEBMirAEKDE9uZW9mT3B0aW9ucxI3CghmZWF0dXJlcxgBIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItECCgtFbnVtT3B0aW9ucxIfCgthbGxvd19hbGlhcxgCIAEoCFIKYWxsb3dBbGlhcxIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJWCiZkZXByZWNhdGVkX2xlZ2FjeV9qc29uX2ZpZWxkX2NvbmZsaWN0cxgGIAEoCEICGAFSImRlcHJlY2F0ZWRMZWdhY3lKc29uRmllbGRDb25mbGljdHMSNwoIZmVhdHVyZXMYByABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFIIZmVhdHVyZXMSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiLYAgoQRW51bVZhbHVlT3B0aW9ucxIlCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBI3CghmZWF0dXJlcxgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxIoCgxkZWJ1Z19yZWRhY3QYAyABKAg6BWZhbHNlUgtkZWJ1Z1JlZGFjdBJVCg9mZWF0dXJlX3N1cHBvcnQYBCABKAsyLC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkZlYXR1cmVTdXBwb3J0Ug5mZWF0dXJlU3VwcG9ydBJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItUBCg5TZXJ2aWNlT3B0aW9ucxI3CghmZWF0dXJlcxgiIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIpkDCg1NZXRob2RPcHRpb25zEiUKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlUgpkZXByZWNhdGVkEnEKEWlkZW1wb3RlbmN5X2xldmVsGCIgASgOMi8uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVuY3lMZXZlbDoTSURFTVBPVEVOQ1lfVU5LTk9XTlIQaWRlbXBvdGVuY3lMZXZlbBI3CghmZWF0dXJlcxgjIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiJQChBJZGVtcG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VOS05PV04QABITCg9OT19TSURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIqCQjoBxCAgICAAiKaAwoTVW5pbnRlcnByZXRlZE9wdGlvbhJBCgRuYW1lGAIgAygLMi0uZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnRSBG5hbWUSKQoQaWRlbnRpZmllcl92YWx1ZRgDIAEoCVIPaWRlbnRpZmllclZhbHVlEiwKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBFIQcG9zaXRpdmVJbnRWYWx1ZRIsChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKANSEG5lZ2F0aXZlSW50VmFsdWUSIQoMZG91YmxlX3ZhbHVlGAYgASgBUgtkb3VibGVWYWx1ZRIhCgxzdHJpbmdfdmFsdWUYByABKAxSC3N0cmluZ1ZhbHVlEicKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCVIOYWdncmVnYXRlVmFsdWUaSgoITmFtZVBhcnQSGwoJbmFtZV9wYXJ0GAEgAigJUghuYW1lUGFydBIhCgxpc19leHRlbnNpb24YAiACKAhSC2lzRXh0ZW5zaW9uIo4PCgpGZWF0dXJlU2V0EpEBCg5maWVsZF9wcmVzZW5jZRgBIAEoDjIpLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LkZpZWxkUHJlc2VuY2VCP4gBAZgBBJgBAaIBDRIIRVhQTElDSVQYhAeiAQ0SCElNUExJQ0lUGOcHogENEghFWFBMSUNJVBjoB7IBAwjoB1INZmllbGRQcmVzZW5jZRJsCgllbnVtX3R5cGUYAiABKA4yJC5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5FbnVtVHlwZUIpiAEBmAEGmAEBogELEgZDTE9TRUQYhAeiAQkSBE9QRU4Y5weyAQMI6AdSCGVudW1UeXBlEpgBChdyZXBlYXRlZF9maWVsZF9lbmNvZGluZxgDIAEoDjIxLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LlJlcGVhdGVkRmllbGRFbmNvZGluZ0ItiAEBmAEEmAEBogENEghFWFBBTkRFRBiEB6IBCxIGUEFDS0VEGOcHsgEDCOgHUhVyZXBlYXRlZEZpZWxkRW5jb2RpbmcSfgoPdXRmOF92YWxpZGF0aW9uGAQgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuVXRmOFZhbGlkYXRpb25CKYgBAZgBBJgBAaIBCRIETk9ORRiEB6IBCxIGVkVSSUZZGOcHsgEDCOgHUg51dGY4VmFsaWRhdGlvbhJ+ChBtZXNzYWdlX2VuY29kaW5nGAUgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuTWVzc2FnZUVuY29kaW5nQiaIAQGYAQSYAQGiARQSD0xFTkdUSF9QUkVGSVhFRBiEB7IBAwjoB1IPbWVzc2FnZUVuY29kaW5nEoIBCgtqc29uX2Zvcm1hdBgGIAEoDjImLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0Lkpzb25Gb3JtYXRCOYgBAZgBA5gBBpgBAaIBFxISTEVHQUNZX0JFU1RfRUZGT1JUGIQHogEKEgVBTExPVxjnB7IBAwjoB1IKanNvbkZvcm1hdBKrAQoUZW5mb3JjZV9uYW1pbmdfc3R5bGUYByABKA4yLi5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5FbmZvcmNlTmFtaW5nU3R5bGVCSYgBApgBAZgBApgBA5gBBJgBBZgBBpgBB5gBCJgBCaIBERIMU1RZTEVfTEVHQUNZGIQHogEOEglTVFlMRTIwMjQY6QeyAQMI6QdSEmVuZm9yY2VOYW1pbmdTdHlsZRK5AQoZZGVmYXVsdF9zeW1ib2xfdmlzaWJpbGl0eRgIIAEoDjJFLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LlZpc2liaWxpdHlGZWF0dXJlLkRlZmF1bHRTeW1ib2xWaXNpYmlsaXR5QjaIAQKYAQGiAQ8SCkVYUE9SVF9BTEwYhAeiARUSEEVYUE9SVF9UT1BfTEVWRUwY6QeyAQMI6QdSF2RlZmF1bHRTeW1ib2xWaXNpYmlsaXR5GqEBChFWaXNpYmlsaXR5RmVhdHVyZSKBAQoXRGVmYXVsdFN5bWJvbFZpc2liaWxpdHkSJQohREVGQVVMVF9TWU1CT0xfVklTSUJJTElUWV9VTktOT1dOEAASDgoKRVhQT1JUX0FMTBABEhQKEEVYUE9SVF9UT1BfTEVWRUwQAhINCglMT0NBTF9BTEwQAxIKCgZTVFJJQ1QQBEoICAEQgICAgAIiXAoNRmllbGRQcmVzZW5jZRIaChZGSUVMRF9QUkVTRU5DRV9VTktOT1dOEAASDAoIRVhQTElDSVQQARIMCghJTVBMSUNJVBACEhMKD0xFR0FDWV9SRVFVSVJFRBADIjcKCEVudW1UeXBlEhUKEUVOVU1fVFlQRV9VTktOT1dOEAASCAoET1BFThABEgoKBkNMT1NFRBACIlYKFVJlcGVhdGVkRmllbGRFbmNvZGluZxIjCh9SRVBFQVRFRF9GSUVMRF9FTkNPRElOR19VTktOT1dOEAASCgoGUEFDS0VEEAESDAoIRVhQQU5ERUQQAiJJCg5VdGY4VmFsaWRhdGlvbhIbChdVVEY4X1ZBTElEQVRJT05fVU5LTk9XThAAEgoKBlZFUklGWRACEggKBE5PTkUQAyIECAEQASJTCg9NZXNzYWdlRW5jb2RpbmcSHAoYTUVTU0FHRV9FTkNPRElOR19VTktOT1dOEAASEwoPTEVOR1RIX1BSRUZJWEVEEAESDQoJREVMSU1JVEVEEAIiSAoKSnNvbkZvcm1hdBIXChNKU09OX0ZPUk1BVF9VTktOT1dOEAASCQoFQUxMT1cQARIWChJMRUdBQ1lfQkVTVF9FRkZPUlQQAiJXChJFbmZvcmNlTmFtaW5nU3R5bGUSIAocRU5GT1JDRV9OQU1JTkdfU1RZTEVfVU5LTk9XThAAEg0KCVNUWUxFMjAyNBABEhAKDFNUWUxFX0xFR0FDWRACKgYI6AcQi04qBgiLThCQTioGCJBOEJFOSgYI5wcQ6Aci7wMKEkZlYXR1cmVTZXREZWZhdWx0cxJYCghkZWZhdWx0cxgBIAMoCzI8Lmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0RGVmYXVsdHMuRmVhdHVyZVNldEVkaXRpb25EZWZhdWx0UghkZWZhdWx0cxJBCg9taW5pbXVtX2VkaXRpb24YBCABKA4yGC5nb29nbGUucHJvdG9idWYuRWRpdGlvblIObWluaW11bUVkaXRpb24SQQoPbWF4aW11bV9lZGl0aW9uGAUgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SDm1heGltdW1FZGl0aW9uGvgBChhGZWF0dXJlU2V0RWRpdGlvbkRlZmF1bHQSMgoHZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uUgdlZGl0aW9uEk4KFG92ZXJyaWRhYmxlX2ZlYXR1cmVzGAQgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXRSE292ZXJyaWRhYmxlRmVhdHVyZXMSQgoOZml4ZWRfZmVhdHVyZXMYBSABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFINZml4ZWRGZWF0dXJlc0oECAEQAkoECAIQA1IIZmVhdHVyZXMitQIKDlNvdXJjZUNvZGVJbmZvEkQKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uUghsb2NhdGlvbhrOAQoITG9jYXRpb24SFgoEcGF0aBgBIAMoBUICEAFSBHBhdGgSFgoEc3BhbhgCIAMoBUICEAFSBHNwYW4SKQoQbGVhZGluZ19jb21tZW50cxgDIAEoCVIPbGVhZGluZ0NvbW1lbnRzEisKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJUhB0cmFpbGluZ0NvbW1lbnRzEjoKGWxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMYBiADKAlSF2xlYWRpbmdEZXRhY2hlZENvbW1lbnRzKgwIgOzK/wEQgezK/wEi0AIKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhrrAQoKQW5ub3RhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIfCgtzb3VyY2VfZmlsZRgCIAEoCVIKc291cmNlRmlsZRIUCgViZWdpbhgDIAEoBVIFYmVnaW4SEAoDZW5kGAQgASgFUgNlbmQSUgoIc2VtYW50aWMYBSABKA4yNi5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5TZW1hbnRpY1IIc2VtYW50aWMiKAoIU2VtYW50aWMSCAoETk9ORRAAEgcKA1NFVBABEgkKBUFMSUFTEAIqvgIKB0VkaXRpb24SEwoPRURJVElPTl9VTktOT1dOEAASEwoORURJVElPTl9MRUdBQ1kQhAcSEwoORURJVElPTl9QUk9UTzIQ5gcSEwoORURJVElPTl9QUk9UTzMQ5wcSEQoMRURJVElPTl8yMDIzEOgHEhEKDEVESVRJT05fMjAyNBDpBxIVChBFRElUSU9OX1VOU1RBQkxFEI9OEhcKE0VESVRJT05fMV9URVNUX09OTFkQARIXChNFRElUSU9OXzJfVEVTVF9PTkxZEAISHQoXRURJVElPTl85OTk5N19URVNUX09OTFkQnY0GEh0KF0VESVRJT05fOTk5OThfVEVTVF9PTkxZEJ6NBhIdChdFRElUSU9OXzk5OTk5X1RFU1RfT05MWRCfjQYSEwoLRURJVElPTl9NQVgQ/////wcqVQoQU3ltYm9sVmlzaWJpbGl0eRIUChBWSVNJQklMSVRZX1VOU0VUEAASFAoQVklTSUJJTElUWV9MT0NBTBABEhUKEVZJU0lCSUxJVFlfRVhQT1JUEAJCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9kZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbgr7AQoeZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvEg9nb29nbGUucHJvdG9idWYiOgoIRHVyYXRpb24SGAoHc2Vjb25kcxgBIAEoA1IHc2Vjb25kcxIUCgVuYW5vcxgCIAEoBVIFbmFub3NCgwEKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoxZ29vZ2xlLmdvbGFuZy5vcmcvcHJvdG9idWYvdHlwZXMva25vd24vZHVyYXRpb25wYvgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8zCq8xChd2YWxpZGF0ZS92YWxpZGF0ZS5wcm90bxIIdmFsaWRhdGUaIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvGh5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8aH2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8iyAgKCkZpZWxkUnVsZXMSMAoHbWVzc2FnZRgRIAEoCzIWLnZhbGlkYXRlLk1lc3NhZ2VSdWxlc1IHbWVzc2FnZRIsCgVmbG9hdBgBIAEoCzIULnZhbGlkYXRlLkZsb2F0UnVsZXNIAFIFZmxvYXQSLwoGZG91YmxlGAIgASgLMhUudmFsaWRhdGUuRG91YmxlUnVsZXNIAFIGZG91YmxlEiwKBWludDMyGAMgASgLMhQudmFsaWRhdGUuSW50MzJSdWxlc0gAUgVpbnQzMhIsCgVpbnQ2NBgEIAEoCzIULnZhbGlkYXRlLkludDY0UnVsZXNIAFIFaW50NjQSLwoGdWludDMyGAUgASgLMhUudmFsaWRhdGUuVUludDMyUnVsZXNIAFIGdWludDMyEi8KBnVpbnQ2NBgGIAEoCzIVLnZhbGlkYXRlLlVJbnQ2NFJ1bGVzSABSBnVpbnQ2NBIvCgZzaW50MzIYByABKAsyFS52YWxpZGF0ZS5TSW50MzJSdWxlc0gAUgZzaW50MzISLwoGc2ludDY0GAggASgLMhUudmFsaWRhdGUuU0ludDY0UnVsZXNIAFIGc2ludDY0EjIKB2ZpeGVkMzIYCSABKAsyFi52YWxpZGF0ZS5GaXhlZDMyUnVsZXNIAFIHZml4ZWQzMhIyCgdmaXhlZDY0GAogASgLMhYudmFsaWRhdGUuRml4ZWQ2NFJ1bGVzSABSB2ZpeGVkNjQSNQoIc2ZpeGVkMzIYCyABKAsyFy52YWxpZGF0ZS5TRml4ZWQzMlJ1bGVzSABSCHNmaXhlZDMyEjUKCHNmaXhlZDY0GAwgASgLMhcudmFsaWRhdGUuU0ZpeGVkNjRSdWxlc0gAUghzZml4ZWQ2NBIpCgRib29sGA0gASgLMhMudmFsaWRhdGUuQm9vbFJ1bGVzSABSBGJvb2wSLwoGc3RyaW5nGA4gASgLMhUudmFsaWRhdGUuU3RyaW5nUnVsZXNIAFIGc3RyaW5nEiwKBWJ5dGVzGA8gASgLMhQudmFsaWRhdGUuQnl0ZXNSdWxlc0gAUgVieXRlcxIpCgRlbnVtGBAgASgLMhMudmFsaWRhdGUuRW51bVJ1bGVzSABSBGVudW0SNQoIcmVwZWF0ZWQYEiABKAsyFy52YWxpZGF0ZS5SZXBlYXRlZFJ1bGVzSABSCHJlcGVhdGVkEiYKA21hcBgTIAEoCzISLnZhbGlkYXRlLk1hcFJ1bGVzSABSA21hcBImCgNhbnkYFCABKAsyEi52YWxpZGF0ZS5BbnlSdWxlc0gAUgNhbnkSNQoIZHVyYXRpb24YFSABKAsyFy52YWxpZGF0ZS5EdXJhdGlvblJ1bGVzSABSCGR1cmF0aW9uEjgKCXRpbWVzdGFtcBgWIAEoCzIYLnZhbGlkYXRlLlRpbWVzdGFtcFJ1bGVzSABSCXRpbWVzdGFtcEIGCgR0eXBlIrABCgpGbG9hdFJ1bGVzEhQKBWNvbnN0GAEgASgCUgVjb25zdBIOCgJsdBgCIAEoAlICbHQSEAoDbHRlGAMgASgCUgNsdGUSDgoCZ3QYBCABKAJSAmd0EhAKA2d0ZRgFIAEoAlIDZ3RlEg4KAmluGAYgAygCUgJpbhIVCgZub3RfaW4YByADKAJSBW5vdEluEiEKDGlnbm9yZV9lbXB0eRgIIAEoCFILaWdub3JlRW1wdHkisQEKC0RvdWJsZVJ1bGVzEhQKBWNvbnN0GAEgASgBUgVjb25zdBIOCgJsdBgCIAEoAVICbHQSEAoDbHRlGAMgASgBUgNsdGUSDgoCZ3QYBCABKAFSAmd0EhAKA2d0ZRgFIAEoAVIDZ3RlEg4KAmluGAYgAygBUgJpbhIVCgZub3RfaW4YByADKAFSBW5vdEluEiEKDGlnbm9yZV9lbXB0eRgIIAEoCFILaWdub3JlRW1wdHkisAEKCkludDMyUnVsZXMSFAoFY29uc3QYASABKAVSBWNvbnN0Eg4KAmx0GAIgASgFUgJsdBIQCgNsdGUYAyABKAVSA2x0ZRIOCgJndBgEIAEoBVICZ3QSEAoDZ3RlGAUgASgFUgNndGUSDgoCaW4YBiADKAVSAmluEhUKBm5vdF9pbhgHIAMoBVIFbm90SW4SIQoMaWdub3JlX2VtcHR5GAggASgIUgtpZ25vcmVFbXB0eSKwAQoKSW50NjRSdWxlcxIUCgVjb25zdBgBIAEoA1IFY29uc3QSDgoCbHQYAiABKANSAmx0EhAKA2x0ZRgDIAEoA1IDbHRlEg4KAmd0GAQgASgDUgJndBIQCgNndGUYBSABKANSA2d0ZRIOCgJpbhgGIAMoA1ICaW4SFQoGbm90X2luGAcgAygDUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtVSW50MzJSdWxlcxIUCgVjb25zdBgBIAEoDVIFY29uc3QSDgoCbHQYAiABKA1SAmx0EhAKA2x0ZRgDIAEoDVIDbHRlEg4KAmd0GAQgASgNUgJndBIQCgNndGUYBSABKA1SA2d0ZRIOCgJpbhgGIAMoDVICaW4SFQoGbm90X2luGAcgAygNUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtVSW50NjRSdWxlcxIUCgVjb25zdBgBIAEoBFIFY29uc3QSDgoCbHQYAiABKARSAmx0EhAKA2x0ZRgDIAEoBFIDbHRlEg4KAmd0GAQgASgEUgJndBIQCgNndGUYBSABKARSA2d0ZRIOCgJpbhgGIAMoBFICaW4SFQoGbm90X2luGAcgAygEUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtTSW50MzJSdWxlcxIUCgVjb25zdBgBIAEoEVIFY29uc3QSDgoCbHQYAiABKBFSAmx0EhAKA2x0ZRgDIAEoEVIDbHRlEg4KAmd0GAQgASgRUgJndBIQCgNndGUYBSABKBFSA2d0ZRIOCgJpbhgGIAMoEVICaW4SFQoGbm90X2luGAcgAygRUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtTSW50NjRSdWxlcxIUCgVjb25zdBgBIAEoElIFY29uc3QSDgoCbHQYAiABKBJSAmx0EhAKA2x0ZRgDIAEoElIDbHRlEg4KAmd0GAQgASgSUgJndBIQCgNndGUYBSABKBJSA2d0ZRIOCgJpbhgGIAMoElICaW4SFQoGbm90X2luGAcgAygSUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrIBCgxGaXhlZDMyUnVsZXMSFAoFY29uc3QYASABKAdSBWNvbnN0Eg4KAmx0GAIgASgHUgJsdBIQCgNsdGUYAyABKAdSA2x0ZRIOCgJndBgEIAEoB1ICZ3QSEAoDZ3RlGAUgASgHUgNndGUSDgoCaW4YBiADKAdSAmluEhUKBm5vdF9pbhgHIAMoB1IFbm90SW4SIQoMaWdub3JlX2VtcHR5GAggASgIUgtpZ25vcmVFbXB0eSKyAQoMRml4ZWQ2NFJ1bGVzEhQKBWNvbnN0GAEgASgGUgVjb25zdBIOCgJsdBgCIAEoBlICbHQSEAoDbHRlGAMgASgGUgNsdGUSDgoCZ3QYBCABKAZSAmd0EhAKA2d0ZRgFIAEoBlIDZ3RlEg4KAmluGAYgAygGUgJpbhIVCgZub3RfaW4YByADKAZSBW5vdEluEiEKDGlnbm9yZV9lbXB0eRgIIAEoCFILaWdub3JlRW1wdHkiswEKDVNGaXhlZDMyUnVsZXMSFAoFY29uc3QYASABKA9SBWNvbnN0Eg4KAmx0GAIgASgPUgJsdBIQCgNsdGUYAyABKA9SA2x0ZRIOCgJndBgEIAEoD1ICZ3QSEAoDZ3RlGAUgASgPUgNndGUSDgoCaW4YBiADKA9SAmluEhUKBm5vdF9pbhgHIAMoD1IFbm90SW4SIQoMaWdub3JlX2VtcHR5GAggASgIUgtpZ25vcmVFbXB0eSKzAQoNU0ZpeGVkNjRSdWxlcxIUCgVjb25zdBgBIAEoEFIFY29uc3QSDgoCbHQYAiABKBBSAmx0EhAKA2x0ZRgDIAEoEFIDbHRlEg4KAmd0GAQgASgQUgJndBIQCgNndGUYBSABKBBSA2d0ZRIOCgJpbhgGIAMoEFICaW4SFQoGbm90X2luGAcgAygQUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IiEKCUJvb2xSdWxlcxIUCgVjb25zdBgBIAEoCFIFY29uc3Qi1AUKC1N0cmluZ1J1bGVzEhQKBWNvbnN0GAEgASgJUgVjb25zdBIQCgNsZW4YEyABKARSA2xlbhIXCgdtaW5fbGVuGAIgASgEUgZtaW5MZW4SFwoHbWF4X2xlbhgDIAEoBFIGbWF4TGVuEhsKCWxlbl9ieXRlcxgUIAEoBFIIbGVuQnl0ZXMSGwoJbWluX2J5dGVzGAQgASgEUghtaW5CeXRlcxIbCgltYXhfYnl0ZXMYBSABKARSCG1heEJ5dGVzEhgKB3BhdHRlcm4YBiABKAlSB3BhdHRlcm4SFgoGcHJlZml4GAcgASgJUgZwcmVmaXgSFgoGc3VmZml4GAggASgJUgZzdWZmaXgSGgoIY29udGFpbnMYCSABKAlSCGNvbnRhaW5zEiEKDG5vdF9jb250YWlucxgXIAEoCVILbm90Q29udGFpbnMSDgoCaW4YCiADKAlSAmluEhUKBm5vdF9pbhgLIAMoCVIFbm90SW4SFgoFZW1haWwYDCABKAhIAFIFZW1haWwSHAoIaG9zdG5hbWUYDSABKAhIAFIIaG9zdG5hbWUSEAoCaXAYDiABKAhIAFICaXASFAoEaXB2NBgPIAEoCEgAUgRpcHY0EhQKBGlwdjYYECABKAhIAFIEaXB2NhISCgN1cmkYESABKAhIAFIDdXJpEhkKB3VyaV9yZWYYEiABKAhIAFIGdXJpUmVmEhoKB2FkZHJlc3MYFSABKAhIAFIHYWRkcmVzcxIUCgR1dWlkGBYgASgISABSBHV1aWQSQAoQd2VsbF9rbm93bl9yZWdleBgYIAEoDjIULnZhbGlkYXRlLktub3duUmVnZXhIAFIOd2VsbEtub3duUmVnZXgSHAoGc3RyaWN0GBkgASgIOgR0cnVlUgZzdHJpY3QSIQoMaWdub3JlX2VtcHR5GBogASgIUgtpZ25vcmVFbXB0eUIMCgp3ZWxsX2tub3duIuICCgpCeXRlc1J1bGVzEhQKBWNvbnN0GAEgASgMUgVjb25zdBIQCgNsZW4YDSABKARSA2xlbhIXCgdtaW5fbGVuGAIgASgEUgZtaW5MZW4SFwoHbWF4X2xlbhgDIAEoBFIGbWF4TGVuEhgKB3BhdHRlcm4YBCABKAlSB3BhdHRlcm4SFgoGcHJlZml4GAUgASgMUgZwcmVmaXgSFgoGc3VmZml4GAYgASgMUgZzdWZmaXgSGgoIY29udGFpbnMYByABKAxSCGNvbnRhaW5zEg4KAmluGAggAygMUgJpbhIVCgZub3RfaW4YCSADKAxSBW5vdEluEhAKAmlwGAogASgISABSAmlwEhQKBGlwdjQYCyABKAhIAFIEaXB2NBIUCgRpcHY2GAwgASgISABSBGlwdjYSIQoMaWdub3JlX2VtcHR5GA4gASgIUgtpZ25vcmVFbXB0eUIMCgp3ZWxsX2tub3duImsKCUVudW1SdWxlcxIUCgVjb25zdBgBIAEoBVIFY29uc3QSIQoMZGVmaW5lZF9vbmx5GAIgASgIUgtkZWZpbmVkT25seRIOCgJpbhgDIAMoBVICaW4SFQoGbm90X2luGAQgAygFUgVub3RJbiI+CgxNZXNzYWdlUnVsZXMSEgoEc2tpcBgBIAEoCFIEc2tpcBIaCghyZXF1aXJlZBgCIAEoCFIIcmVxdWlyZWQisAEKDVJlcGVhdGVkUnVsZXMSGwoJbWluX2l0ZW1zGAEgASgEUghtaW5JdGVtcxIbCgltYXhfaXRlbXMYAiABKARSCG1heEl0ZW1zEhYKBnVuaXF1ZRgDIAEoCFIGdW5pcXVlEioKBWl0ZW1zGAQgASgLMhQudmFsaWRhdGUuRmllbGRSdWxlc1IFaXRlbXMSIQoMaWdub3JlX2VtcHR5GAUgASgIUgtpZ25vcmVFbXB0eSLcAQoITWFwUnVsZXMSGwoJbWluX3BhaXJzGAEgASgEUghtaW5QYWlycxIbCgltYXhfcGFpcnMYAiABKARSCG1heFBhaXJzEhsKCW5vX3NwYXJzZRgDIAEoCFIIbm9TcGFyc2USKAoEa2V5cxgEIAEoCzIULnZhbGlkYXRlLkZpZWxkUnVsZXNSBGtleXMSLAoGdmFsdWVzGAUgASgLMhQudmFsaWRhdGUuRmllbGRSdWxlc1IGdmFsdWVzEiEKDGlnbm9yZV9lbXB0eRgGIAEoCFILaWdub3JlRW1wdHkiTQoIQW55UnVsZXMSGgoIcmVxdWlyZWQYASABKAhSCHJlcXVpcmVkEg4KAmluGAIgAygJUgJpbhIVCgZub3RfaW4YAyADKAlSBW5vdEluIukCCg1EdXJhdGlvblJ1bGVzEhoKCHJlcXVpcmVkGAEgASgIUghyZXF1aXJlZBIvCgVjb25zdBgCIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblIFY29uc3QSKQoCbHQYAyABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25SAmx0EisKA2x0ZRgEIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblIDbHRlEikKAmd0GAUgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uUgJndBIrCgNndGUYBiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25SA2d0ZRIpCgJpbhgHIAMoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblICaW4SMAoGbm90X2luGAggAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uUgVub3RJbiLzAgoOVGltZXN0YW1wUnVsZXMSGgoIcmVxdWlyZWQYASABKAhSCHJlcXVpcmVkEjAKBWNvbnN0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFIFY29uc3QSKgoCbHQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgJsdBIsCgNsdGUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgNsdGUSKgoCZ3QYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgJndBIsCgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgNndGUSFQoGbHRfbm93GAcgASgIUgVsdE5vdxIVCgZndF9ub3cYCCABKAhSBWd0Tm93EjEKBndpdGhpbhgJIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblIGd2l0aGluKkYKCktub3duUmVnZXgSCwoHVU5LTk9XThAAEhQKEEhUVFBfSEVBREVSX05BTUUQARIVChFIVFRQX0hFQURFUl9WQUxVRRACOjwKCGRpc2FibGVkEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGK8IIAEoCFIIZGlzYWJsZWQ6OgoHaWdub3JlZBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiwCCABKAhSB2lnbm9yZWQ6OgoIcmVxdWlyZWQSHS5nb29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25zGK8IIAEoCFIIcmVxdWlyZWQ6SgoFcnVsZXMSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGK8IIAEoCzIULnZhbGlkYXRlLkZpZWxkUnVsZXNSBXJ1bGVzQlAKGmlvLmVudm95cHJveHkucGd2LnZhbGlkYXRlWjJnaXRodWIuY29tL2Vudm95cHJveHkvcHJvdG9jLWdlbi12YWxpZGF0ZS92YWxpZGF0ZQq3AwoMY29tbW9uLnByb3RvEgZjb21tb24ihwEKClBhY2thZ2VNYXASPAoIcGFja2FnZXMYASADKAsyIC5jb21tb24uUGFja2FnZU1hcC5QYWNrYWdlc0VudHJ5UghwYWNrYWdlcxo7Cg1QYWNrYWdlc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEiRQoRU2lnbmluZ0NvbW1pdG1lbnQSFgoGaGlkaW5nGAEgASgMUgZoaWRpbmcSGAoHYmluZGluZxgCIAEoDFIHYmluZGluZyI4Cg1TaWduaW5nUmVzdWx0EicKD3NpZ25hdHVyZV9zaGFyZRgBIAEoDFIOc2lnbmF0dXJlU2hhcmUqXQoPU2lnbmF0dXJlSW50ZW50EgwKCENSRUFUSU9OEAASDAoIVFJBTlNGRVIQARINCglBR0dSRUdBVEUQAhIPCgdSRUZSRVNIEAMaAggBEg4KBkVYVEVORBAEGgIIAUItWitnaXRodWIuY29tL2xpZ2h0c3BhcmtkZXYvc3BhcmsvcHJvdG8vY29tbW9uYgZwcm90bzMK074CCgtzcGFyay5wcm90bxIFc3BhcmsaH2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8aG2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90bxoXdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8aDGNvbW1vbi5wcm90byJKChhTdWJzY3JpYmVUb0V2ZW50c1JlcXVlc3QSLgoTaWRlbnRpdHlfcHVibGljX2tleRgKIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkiwAEKGVN1YnNjcmliZVRvRXZlbnRzUmVzcG9uc2USMgoIdHJhbnNmZXIYASABKAsyFC5zcGFyay5UcmFuc2ZlckV2ZW50SABSCHRyYW5zZmVyEi8KB2RlcG9zaXQYAiABKAsyEy5zcGFyay5EZXBvc2l0RXZlbnRIAFIHZGVwb3NpdBI1Cgljb25uZWN0ZWQYAyABKAsyFS5zcGFyay5Db25uZWN0ZWRFdmVudEgAUgljb25uZWN0ZWRCBwoFZXZlbnQiEAoOQ29ubmVjdGVkRXZlbnQiPAoNVHJhbnNmZXJFdmVudBIrCgh0cmFuc2ZlchgKIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlciI5CgxEZXBvc2l0RXZlbnQSKQoHZGVwb3NpdBgKIAEoCzIPLnNwYXJrLlRyZWVOb2RlUgdkZXBvc2l0IrQBCgtQYWdlUmVxdWVzdBI0ChB1bnNhZmVfcGFnZV9zaXplGAEgASgFQgr6QgcaBRjoBygAUg51bnNhZmVQYWdlU2l6ZRInCglwYWdlX3NpemUYBCABKA1CCvpCByoFGOgHKABSCHBhZ2VTaXplEhYKBmN1cnNvchgCIAEoCVIGY3Vyc29yEi4KCWRpcmVjdGlvbhgDIAEoDjIQLnNwYXJrLkRpcmVjdGlvblIJZGlyZWN0aW9uIqgBCgxQYWdlUmVzcG9uc2USIgoNaGFzX25leHRfcGFnZRgBIAEoCFILaGFzTmV4dFBhZ2USKgoRaGFzX3ByZXZpb3VzX3BhZ2UYAiABKAhSD2hhc1ByZXZpb3VzUGFnZRIfCgtuZXh0X2N1cnNvchgDIAEoCVIKbmV4dEN1cnNvchInCg9wcmV2aW91c19jdXJzb3IYBCABKAlSDnByZXZpb3VzQ3Vyc29yIoACChNEZXBvc2l0QWRkcmVzc1Byb29mEmAKEmFkZHJlc3Nfc2lnbmF0dXJlcxgBIAMoCzIxLnNwYXJrLkRlcG9zaXRBZGRyZXNzUHJvb2YuQWRkcmVzc1NpZ25hdHVyZXNFbnRyeVIRYWRkcmVzc1NpZ25hdHVyZXMSQQodcHJvb2Zfb2ZfcG9zc2Vzc2lvbl9zaWduYXR1cmUYAiABKAxSGnByb29mT2ZQb3NzZXNzaW9uU2lnbmF0dXJlGkQKFkFkZHJlc3NTaWduYXR1cmVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAxSBXZhbHVlOgI4ASLMAgodR2VuZXJhdGVEZXBvc2l0QWRkcmVzc1JlcXVlc3QSLAoSc2lnbmluZ19wdWJsaWNfa2V5GAEgASgMUhBzaWduaW5nUHVibGljS2V5Ei4KE2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSEWlkZW50aXR5UHVibGljS2V5EjIKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgAFIHbmV0d29yaxImCgdsZWFmX2lkGAQgASgJQgj6QgVyA7ABAUgAUgZsZWFmSWSIAQESIAoJaXNfc3RhdGljGAUgASgISAFSCGlzU3RhdGljiAEBEjUKDGhhc2hfdmFyaWFudBgGIAEoDjISLnNwYXJrLkhhc2hWYXJpYW50UgtoYXNoVmFyaWFudEIKCghfbGVhZl9pZEIMCgpfaXNfc3RhdGljIrUBCgdBZGRyZXNzEhgKB2FkZHJlc3MYASABKAlSB2FkZHJlc3MSIwoNdmVyaWZ5aW5nX2tleRgCIAEoDFIMdmVyaWZ5aW5nS2V5Ek4KFWRlcG9zaXRfYWRkcmVzc19wcm9vZhgDIAEoCzIaLnNwYXJrLkRlcG9zaXRBZGRyZXNzUHJvb2ZSE2RlcG9zaXRBZGRyZXNzUHJvb2YSGwoJaXNfc3RhdGljGAUgASgIUghpc1N0YXRpYyJZCh5HZW5lcmF0ZURlcG9zaXRBZGRyZXNzUmVzcG9uc2USNwoPZGVwb3NpdF9hZGRyZXNzGAEgASgLMg4uc3BhcmsuQWRkcmVzc1IOZGVwb3NpdEFkZHJlc3MigAIKI0dlbmVyYXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXF1ZXN0EjUKEnNpZ25pbmdfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIQc2lnbmluZ1B1YmxpY0tleRI3ChNpZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUhFpZGVudGl0eVB1YmxpY0tleRIyCgduZXR3b3JrGAMgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIABSB25ldHdvcmsSNQoMaGFzaF92YXJpYW50GAQgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50Il8KJEdlbmVyYXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXNwb25zZRI3Cg9kZXBvc2l0X2FkZHJlc3MYASABKAsyDi5zcGFyay5BZGRyZXNzUg5kZXBvc2l0QWRkcmVzcyLFAQohUm90YXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXF1ZXN0EjUKEnNpZ25pbmdfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIQc2lnbmluZ1B1YmxpY0tleRIyCgduZXR3b3JrGAIgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIABSB25ldHdvcmsSNQoMaGFzaF92YXJpYW50GAMgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50Iq4BCiJSb3RhdGVTdGF0aWNEZXBvc2l0QWRkcmVzc1Jlc3BvbnNlEj4KE25ld19kZXBvc2l0X2FkZHJlc3MYASABKAsyDi5zcGFyay5BZGRyZXNzUhFuZXdEZXBvc2l0QWRkcmVzcxJIChhhcmNoaXZlZF9kZXBvc2l0X2FkZHJlc3MYAiABKAsyDi5zcGFyay5BZGRyZXNzUhZhcmNoaXZlZERlcG9zaXRBZGRyZXNzInkKBFVUWE8SFQoGcmF3X3R4GAEgASgMUgVyYXdUeBISCgR2b3V0GAIgASgNUgR2b3V0EjIKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgAFIHbmV0d29yaxISCgR0eGlkGAQgASgMUgR0eGlkIjkKCk5vZGVPdXRwdXQSFwoHbm9kZV9pZBgBIAEoCVIGbm9kZUlkEhIKBHZvdXQYAiABKA1SBHZvdXQipgEKClNpZ25pbmdKb2ISLAoSc2lnbmluZ19wdWJsaWNfa2V5GAEgASgMUhBzaWduaW5nUHVibGljS2V5EhUKBnJhd190eBgCIAEoDFIFcmF3VHgSUwoYc2lnbmluZ19ub25jZV9jb21taXRtZW50GAMgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50UhZzaWduaW5nTm9uY2VDb21taXRtZW50IsoCCg9TaWduaW5nS2V5c2hhcmUSKwoRb3duZXJfaWRlbnRpZmllcnMYASADKAlSEG93bmVySWRlbnRpZmllcnMSHAoJdGhyZXNob2xkGAIgASgNUgl0aHJlc2hvbGQSHQoKcHVibGljX2tleRgDIAEoDFIJcHVibGljS2V5Ek0KDXB1YmxpY19zaGFyZXMYBCADKAsyKC5zcGFyay5TaWduaW5nS2V5c2hhcmUuUHVibGljU2hhcmVzRW50cnlSDHB1YmxpY1NoYXJlcxI9Cgx1cGRhdGVkX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgt1cGRhdGVkVGltZRo/ChFQdWJsaWNTaGFyZXNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU6AjgBIsgECg1TaWduaW5nUmVzdWx0EkUKC3B1YmxpY19rZXlzGAEgAygLMiQuc3BhcmsuU2lnbmluZ1Jlc3VsdC5QdWJsaWNLZXlzRW50cnlSCnB1YmxpY0tleXMSbQoZc2lnbmluZ19ub25jZV9jb21taXRtZW50cxgCIAMoCzIxLnNwYXJrLlNpZ25pbmdSZXN1bHQuU2lnbmluZ05vbmNlQ29tbWl0bWVudHNFbnRyeVIXc2lnbmluZ05vbmNlQ29tbWl0bWVudHMSVAoQc2lnbmF0dXJlX3NoYXJlcxgDIAMoCzIpLnNwYXJrLlNpZ25pbmdSZXN1bHQuU2lnbmF0dXJlU2hhcmVzRW50cnlSD3NpZ25hdHVyZVNoYXJlcxJBChBzaWduaW5nX2tleXNoYXJlGAQgASgLMhYuc3BhcmsuU2lnbmluZ0tleXNoYXJlUg9zaWduaW5nS2V5c2hhcmUaPQoPUHVibGljS2V5c0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEaZQocU2lnbmluZ05vbmNlQ29tbWl0bWVudHNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIvCgV2YWx1ZRgCIAEoCzIZLmNvbW1vbi5TaWduaW5nQ29tbWl0bWVudFIFdmFsdWU6AjgBGkIKFFNpZ25hdHVyZVNoYXJlc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEikgMKEFJlbmV3TGVhZlJlcXVlc3QSFwoHbGVhZl9pZBgBIAEoCVIGbGVhZklkEmoKH3JlbmV3X25vZGVfdGltZWxvY2tfc2lnbmluZ19qb2IYAiABKAsyIi5zcGFyay5SZW5ld05vZGVUaW1lbG9ja1NpZ25pbmdKb2JIAFIbcmVuZXdOb2RlVGltZWxvY2tTaWduaW5nSm9iEnAKIXJlbmV3X3JlZnVuZF90aW1lbG9ja19zaWduaW5nX2pvYhgDIAEoCzIkLnNwYXJrLlJlbmV3UmVmdW5kVGltZWxvY2tTaWduaW5nSm9iSABSHXJlbmV3UmVmdW5kVGltZWxvY2tTaWduaW5nSm9iEncKJHJlbmV3X25vZGVfemVyb190aW1lbG9ja19zaWduaW5nX2pvYhgEIAEoCzImLnNwYXJrLlJlbmV3Tm9kZVplcm9UaW1lbG9ja1NpZ25pbmdKb2JIAFIfcmVuZXdOb2RlWmVyb1RpbWVsb2NrU2lnbmluZ0pvYkIOCgxzaWduaW5nX2pvYnMipwUKG1JlbmV3Tm9kZVRpbWVsb2NrU2lnbmluZ0pvYhJXChlzcGxpdF9ub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIVc3BsaXROb2RlVHhTaWduaW5nSm9iEmQKIHNwbGl0X25vZGVfZGlyZWN0X3R4X3NpZ25pbmdfam9iGAIgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIbc3BsaXROb2RlRGlyZWN0VHhTaWduaW5nSm9iEkwKE25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhBub2RlVHhTaWduaW5nSm9iElAKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSEnJlZnVuZFR4U2lnbmluZ0pvYhJZChpkaXJlY3Rfbm9kZV90eF9zaWduaW5nX2pvYhgFIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSFmRpcmVjdE5vZGVUeFNpZ25pbmdKb2ISXQocZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX2pvYhgGIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJvCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIuoDCh1SZW5ld1JlZnVuZFRpbWVsb2NrU2lnbmluZ0pvYhJMChNub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIQbm9kZVR4U2lnbmluZ0pvYhJQChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISWQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhZkaXJlY3ROb2RlVHhTaWduaW5nSm9iEl0KHGRpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhhkaXJlY3RSZWZ1bmRUeFNpZ25pbmdKb2ISbwomZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBSABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUiBkaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmluZ0pvYiKTAwofUmVuZXdOb2RlWmVyb1RpbWVsb2NrU2lnbmluZ0pvYhJMChNub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIQbm9kZVR4U2lnbmluZ0pvYhJQChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISWQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhZkaXJlY3ROb2RlVHhTaWduaW5nSm9iEm8KJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAUgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIgZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdKb2JKBAgEEAUi0wIKEVJlbmV3TGVhZlJlc3BvbnNlEl0KGnJlbmV3X25vZGVfdGltZWxvY2tfcmVzdWx0GAEgASgLMh4uc3BhcmsuUmVuZXdOb2RlVGltZWxvY2tSZXN1bHRIAFIXcmVuZXdOb2RlVGltZWxvY2tSZXN1bHQSYwoccmVuZXdfcmVmdW5kX3RpbWVsb2NrX3Jlc3VsdBgCIAEoCzIgLnNwYXJrLlJlbmV3UmVmdW5kVGltZWxvY2tSZXN1bHRIAFIZcmVuZXdSZWZ1bmRUaW1lbG9ja1Jlc3VsdBJqCh9yZW5ld19ub2RlX3plcm9fdGltZWxvY2tfcmVzdWx0GAMgASgLMiIuc3BhcmsuUmVuZXdOb2RlWmVyb1RpbWVsb2NrUmVzdWx0SABSG3JlbmV3Tm9kZVplcm9UaW1lbG9ja1Jlc3VsdEIOCgxyZW5ld19yZXN1bHQibgoXUmVuZXdOb2RlVGltZWxvY2tSZXN1bHQSLgoKc3BsaXRfbm9kZRgBIAEoCzIPLnNwYXJrLlRyZWVOb2RlUglzcGxpdE5vZGUSIwoEbm9kZRgCIAEoCzIPLnNwYXJrLlRyZWVOb2RlUgRub2RlIkAKGVJlbmV3UmVmdW5kVGltZWxvY2tSZXN1bHQSIwoEbm9kZRgBIAEoCzIPLnNwYXJrLlRyZWVOb2RlUgRub2RlInIKG1JlbmV3Tm9kZVplcm9UaW1lbG9ja1Jlc3VsdBIuCgpzcGxpdF9ub2RlGAEgASgLMg8uc3BhcmsuVHJlZU5vZGVSCXNwbGl0Tm9kZRIjCgRub2RlGAIgASgLMg8uc3BhcmsuVHJlZU5vZGVSBG5vZGUilwQKE05vZGVTaWduYXR1cmVTaGFyZXMSFwoHbm9kZV9pZBgBIAEoCVIGbm9kZUlkEkkKFm5vZGVfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhNub2RlVHhTaWduaW5nUmVzdWx0Ek0KGHJlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgDIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSFXJlZnVuZFR4U2lnbmluZ1Jlc3VsdBIjCg12ZXJpZnlpbmdfa2V5GAQgASgMUgx2ZXJpZnlpbmdLZXkSWgodZGlyZWN0X25vZGVfdHhfc2lnbmluZ19yZXN1bHQYBSABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0QgIYAVIZZGlyZWN0Tm9kZVR4U2lnbmluZ1Jlc3VsdBJeCh9kaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAYgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdEICGAFSG2RpcmVjdFJlZnVuZFR4U2lnbmluZ1Jlc3VsdBJsCilkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgHIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSI2RpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nUmVzdWx0IsoCCg5Ob2RlU2lnbmF0dXJlcxIXCgdub2RlX2lkGAEgASgJUgZub2RlSWQSKgoRbm9kZV90eF9zaWduYXR1cmUYAiABKAxSD25vZGVUeFNpZ25hdHVyZRIuChNyZWZ1bmRfdHhfc2lnbmF0dXJlGAMgASgMUhFyZWZ1bmRUeFNpZ25hdHVyZRI3ChhkaXJlY3Rfbm9kZV90eF9zaWduYXR1cmUYBCABKAxSFWRpcmVjdE5vZGVUeFNpZ25hdHVyZRI7ChpkaXJlY3RfcmVmdW5kX3R4X3NpZ25hdHVyZRgFIAEoDFIXZGlyZWN0UmVmdW5kVHhTaWduYXR1cmUSTQokZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmF0dXJlGAYgASgMUh9kaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmF0dXJlIooEChhTdGFydFRyZWVDcmVhdGlvblJlcXVlc3QSLgoTaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkSLwoNb25fY2hhaW5fdXR4bxgCIAEoCzILLnNwYXJrLlVUWE9SC29uQ2hhaW5VdHhvEkAKE3Jvb3RfdHhfc2lnbmluZ19qb2IYAyABKAsyES5zcGFyay5TaWduaW5nSm9iUhByb290VHhTaWduaW5nSm9iEkQKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSEnJlZnVuZFR4U2lnbmluZ0pvYhJNChpkaXJlY3Rfcm9vdF90eF9zaWduaW5nX2pvYhgFIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSFmRpcmVjdFJvb3RUeFNpZ25pbmdKb2ISUQocZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX2pvYhgGIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJjCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIo0BChlTdGFydFRyZWVDcmVhdGlvblJlc3BvbnNlEhcKB3RyZWVfaWQYASABKAlSBnRyZWVJZBJXChpyb290X25vZGVfc2lnbmF0dXJlX3NoYXJlcxgCIAEoCzIaLnNwYXJrLk5vZGVTaWduYXR1cmVTaGFyZXNSF3Jvb3ROb2RlU2lnbmF0dXJlU2hhcmVzIpkECh9TdGFydERlcG9zaXRUcmVlQ3JlYXRpb25SZXF1ZXN0Ei4KE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxSEWlkZW50aXR5UHVibGljS2V5Ei8KDW9uX2NoYWluX3V0eG8YAiABKAsyCy5zcGFyay5VVFhPUgtvbkNoYWluVXR4bxJAChNyb290X3R4X3NpZ25pbmdfam9iGAMgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIQcm9vdFR4U2lnbmluZ0pvYhJEChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyES5zcGFyay5TaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISUQoaZGlyZWN0X3Jvb3RfdHhfc2lnbmluZ19qb2IYBSABKAsyES5zcGFyay5TaWduaW5nSm9iQgIYAVIWZGlyZWN0Um9vdFR4U2lnbmluZ0pvYhJVChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAYgASgLMhEuc3BhcmsuU2lnbmluZ0pvYkICGAFSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJjCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIpQBCiBTdGFydERlcG9zaXRUcmVlQ3JlYXRpb25SZXNwb25zZRIXCgd0cmVlX2lkGAEgASgJUgZ0cmVlSWQSVwoacm9vdF9ub2RlX3NpZ25hdHVyZV9zaGFyZXMYAiABKAsyGi5zcGFyay5Ob2RlU2lnbmF0dXJlU2hhcmVzUhdyb290Tm9kZVNpZ25hdHVyZVNoYXJlcyKfAwoiRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVxdWVzdBI3ChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUhFpZGVudGl0eVB1YmxpY0tleRIvCg1vbl9jaGFpbl91dHhvGAIgASgLMgsuc3BhcmsuVVRYT1ILb25DaGFpblV0eG8STAoTcm9vdF90eF9zaWduaW5nX2pvYhgDIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSEHJvb3RUeFNpZ25pbmdKb2ISUAoVcmVmdW5kX3R4X3NpZ25pbmdfam9iGAQgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIScmVmdW5kVHhTaWduaW5nSm9iEm8KJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAUgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIgZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdKb2IiUwojRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVzcG9uc2USLAoJcm9vdF9ub2RlGAEgASgLMg8uc3BhcmsuVHJlZU5vZGVSCHJvb3ROb2RlIpsBChJUb2tlbk91dHB1dFRvU3BlbmQSRgobcHJldl90b2tlbl90cmFuc2FjdGlvbl9oYXNoGAEgASgMQgf6QgR6AmggUhhwcmV2VG9rZW5UcmFuc2FjdGlvbkhhc2gSPQobcHJldl90b2tlbl90cmFuc2FjdGlvbl92b3V0GAIgASgNUhhwcmV2VG9rZW5UcmFuc2FjdGlvblZvdXQiWQoSVG9rZW5UcmFuc2ZlcklucHV0EkMKEG91dHB1dHNfdG9fc3BlbmQYASADKAsyGS5zcGFyay5Ub2tlbk91dHB1dFRvU3BlbmRSDm91dHB1dHNUb1NwZW5kIs8BCg5Ub2tlbk1pbnRJbnB1dBIzChFpc3N1ZXJfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIPaXNzdWVyUHVibGljS2V5EjoKGWlzc3Vlcl9wcm92aWRlZF90aW1lc3RhbXAYAiABKARSF2lzc3VlclByb3ZpZGVkVGltZXN0YW1wEjcKEHRva2VuX2lkZW50aWZpZXIYAyABKAxCB/pCBHoCaCBIAFIPdG9rZW5JZGVudGlmaWVyiAEBQhMKEV90b2tlbl9pZGVudGlmaWVyIvYCChBUb2tlbkNyZWF0ZUlucHV0EjMKEWlzc3Vlcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg9pc3N1ZXJQdWJsaWNLZXkSJgoKdG9rZW5fbmFtZRgCIAEoCUIH+kIEcgIYFFIJdG9rZW5OYW1lEioKDHRva2VuX3RpY2tlchgDIAEoCUIH+kIEcgIYBlILdG9rZW5UaWNrZXISJAoIZGVjaW1hbHMYBCABKA1CCPpCBSoDGP8BUghkZWNpbWFscxImCgptYXhfc3VwcGx5GAUgASgMQgf6QgR6AmgQUgltYXhTdXBwbHkSIQoMaXNfZnJlZXphYmxlGAYgASgIUgtpc0ZyZWV6YWJsZRJJChpjcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleRgHIAEoDEIH+kIEegJoIUgAUhdjcmVhdGlvbkVudGl0eVB1YmxpY0tleYgBAUIdChtfY3JlYXRpb25fZW50aXR5X3B1YmxpY19rZXkixwQKC1Rva2VuT3V0cHV0Eh0KAmlkGAEgASgJQgj6QgVyA7ABAUgAUgJpZIgBARIxChBvd25lcl9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUg5vd25lclB1YmxpY0tleRJBChVyZXZvY2F0aW9uX2NvbW1pdG1lbnQYAyABKAxCB/pCBHoCaCFIAVIUcmV2b2NhdGlvbkNvbW1pdG1lbnSIAQESMQoSd2l0aGRyYXdfYm9uZF9zYXRzGAQgASgESAJSEHdpdGhkcmF3Qm9uZFNhdHOIAQESTAogd2l0aGRyYXdfcmVsYXRpdmVfYmxvY2tfbG9ja3RpbWUYBSABKARIA1Idd2l0aGRyYXdSZWxhdGl2ZUJsb2NrTG9ja3RpbWWIAQESNgoQdG9rZW5fcHVibGljX2tleRgGIAEoDEIH+kIEegJoIUgEUg50b2tlblB1YmxpY0tleYgBARI3ChB0b2tlbl9pZGVudGlmaWVyGAggASgMQgf6QgR6AmggSAVSD3Rva2VuSWRlbnRpZmllcogBARIqCgx0b2tlbl9hbW91bnQYByABKAxCB/pCBHoCaBBSC3Rva2VuQW1vdW50QgUKA19pZEIYChZfcmV2b2NhdGlvbl9jb21taXRtZW50QhUKE193aXRoZHJhd19ib25kX3NhdHNCIwohX3dpdGhkcmF3X3JlbGF0aXZlX2Jsb2NrX2xvY2t0aW1lQhMKEV90b2tlbl9wdWJsaWNfa2V5QhMKEV90b2tlbl9pZGVudGlmaWVyIqUDChBUb2tlblRyYW5zYWN0aW9uEjYKCm1pbnRfaW5wdXQYASABKAsyFS5zcGFyay5Ub2tlbk1pbnRJbnB1dEgAUgltaW50SW5wdXQSQgoOdHJhbnNmZXJfaW5wdXQYAiABKAsyGS5zcGFyay5Ub2tlblRyYW5zZmVySW5wdXRIAFINdHJhbnNmZXJJbnB1dBI8CgxjcmVhdGVfaW5wdXQYBSABKAsyFy5zcGFyay5Ub2tlbkNyZWF0ZUlucHV0SABSC2NyZWF0ZUlucHV0EjcKDXRva2VuX291dHB1dHMYAyADKAsyEi5zcGFyay5Ub2tlbk91dHB1dFIMdG9rZW5PdXRwdXRzEloKI3NwYXJrX29wZXJhdG9yX2lkZW50aXR5X3B1YmxpY19rZXlzGAQgAygMQgz6QgmSAQYiBHoCaCFSH3NwYXJrT3BlcmF0b3JJZGVudGl0eVB1YmxpY0tleXMSMgoHbmV0d29yaxgKIAEoDjIOLnNwYXJrLk5ldHdvcmtCCPpCBYIBAiAAUgduZXR3b3JrQg4KDHRva2VuX2lucHV0cyJeChJTaWduYXR1cmVXaXRoSW5kZXgSJwoJc2lnbmF0dXJlGAEgASgMQgn6QgZ6BBBAGElSCXNpZ25hdHVyZRIfCgtpbnB1dF9pbmRleBgCIAEoDVIKaW5wdXRJbmRleCLFAQovT3BlcmF0b3JTcGVjaWZpY1Rva2VuVHJhbnNhY3Rpb25TaWduYWJsZVBheWxvYWQSSAocZmluYWxfdG9rZW5fdHJhbnNhY3Rpb25faGFzaBgBIAEoDEIH+kIEegJoIFIZZmluYWxUb2tlblRyYW5zYWN0aW9uSGFzaBJIChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUhlvcGVyYXRvcklkZW50aXR5UHVibGljS2V5IrYBCh5PcGVyYXRvclNwZWNpZmljT3duZXJTaWduYXR1cmUSQgoPb3duZXJfc2lnbmF0dXJlGAEgASgLMhkuc3BhcmsuU2lnbmF0dXJlV2l0aEluZGV4Ug5vd25lclNpZ25hdHVyZRJQCgdwYXlsb2FkGAIgASgLMjYuc3BhcmsuT3BlcmF0b3JTcGVjaWZpY1Rva2VuVHJhbnNhY3Rpb25TaWduYWJsZVBheWxvYWRSB3BheWxvYWQicgoZUmV2b2NhdGlvblNlY3JldFdpdGhJbmRleBIfCgtpbnB1dF9pbmRleBgBIAEoDVIKaW5wdXRJbmRleBI0ChFyZXZvY2F0aW9uX3NlY3JldBgCIAEoDEIH+kIEegJoIFIQcmV2b2NhdGlvblNlY3JldCL4AgoTRnJlZXplVG9rZW5zUGF5bG9hZBIxChBvd25lcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg5vd25lclB1YmxpY0tleRIxChB0b2tlbl9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUg50b2tlblB1YmxpY0tleRI6Chlpc3N1ZXJfcHJvdmlkZWRfdGltZXN0YW1wGAMgASgEUhdpc3N1ZXJQcm92aWRlZFRpbWVzdGFtcBJIChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMQgf6QgR6AmghUhlvcGVyYXRvcklkZW50aXR5UHVibGljS2V5EicKD3Nob3VsZF91bmZyZWV6ZRgFIAEoCFIOc2hvdWxkVW5mcmVlemUSNwoQdG9rZW5faWRlbnRpZmllchgGIAEoDEIH+kIEegJoIEgAUg90b2tlbklkZW50aWZpZXKIAQFCEwoRX3Rva2VuX2lkZW50aWZpZXIimwEKE0ZyZWV6ZVRva2Vuc1JlcXVlc3QSTgoVZnJlZXplX3Rva2Vuc19wYXlsb2FkGAEgASgLMhouc3BhcmsuRnJlZXplVG9rZW5zUGF5bG9hZFITZnJlZXplVG9rZW5zUGF5bG9hZBI0ChBpc3N1ZXJfc2lnbmF0dXJlGAIgASgMQgn6QgZ6BBBAGElSD2lzc3VlclNpZ25hdHVyZSKJAQoURnJlZXplVG9rZW5zUmVzcG9uc2USPQoTaW1wYWN0ZWRfb3V0cHV0X2lkcxgBIAMoCUIN+kIKkgEHIgVyA7ABAVIRaW1wYWN0ZWRPdXRwdXRJZHMSMgoVaW1wYWN0ZWRfdG9rZW5fYW1vdW50GAIgASgMUhNpbXBhY3RlZFRva2VuQW1vdW50Iv0FCghUcmVlTm9kZRIOCgJpZBgBIAEoCVICaWQSFwoHdHJlZV9pZBgCIAEoCVIGdHJlZUlkEhQKBXZhbHVlGAMgASgEUgV2YWx1ZRIpCg5wYXJlbnRfbm9kZV9pZBgEIAEoCUgAUgxwYXJlbnROb2RlSWSIAQESFwoHbm9kZV90eBgFIAEoDFIGbm9kZVR4EhsKCXJlZnVuZF90eBgGIAEoDFIIcmVmdW5kVHgSEgoEdm91dBgHIAEoDVIEdm91dBIwChR2ZXJpZnlpbmdfcHVibGljX2tleRgIIAEoDFISdmVyaWZ5aW5nUHVibGljS2V5EjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYCSABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSQQoQc2lnbmluZ19rZXlzaGFyZRgKIAEoCzIWLnNwYXJrLlNpZ25pbmdLZXlzaGFyZVIPc2lnbmluZ0tleXNoYXJlEhYKBnN0YXR1cxgLIAEoCVIGc3RhdHVzEigKB25ldHdvcmsYDCABKA4yDi5zcGFyay5OZXR3b3JrUgduZXR3b3JrEj0KDGNyZWF0ZWRfdGltZRgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSC2NyZWF0ZWRUaW1lEj0KDHVwZGF0ZWRfdGltZRgOIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSC3VwZGF0ZWRUaW1lEjcKGG93bmVyX3NpZ25pbmdfcHVibGljX2tleRgPIAEoDFIVb3duZXJTaWduaW5nUHVibGljS2V5EhsKCWRpcmVjdF90eBgQIAEoDFIIZGlyZWN0VHgSKAoQZGlyZWN0X3JlZnVuZF90eBgRIAEoDFIOZGlyZWN0UmVmdW5kVHgSOgoaZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHgYEiABKAxSFmRpcmVjdEZyb21DcGZwUmVmdW5kVHhCEQoPX3BhcmVudF9ub2RlX2lkIpABCh1GaW5hbGl6ZU5vZGVTaWduYXR1cmVzUmVxdWVzdBIvCgZpbnRlbnQYASABKA4yFy5jb21tb24uU2lnbmF0dXJlSW50ZW50UgZpbnRlbnQSPgoPbm9kZV9zaWduYXR1cmVzGAIgAygLMhUuc3BhcmsuTm9kZVNpZ25hdHVyZXNSDm5vZGVTaWduYXR1cmVzIkcKHkZpbmFsaXplTm9kZVNpZ25hdHVyZXNSZXNwb25zZRIlCgVub2RlcxgBIAMoCzIPLnNwYXJrLlRyZWVOb2RlUgVub2RlcyJICgtTZWNyZXRTaGFyZRIhCgxzZWNyZXRfc2hhcmUYASABKAxSC3NlY3JldFNoYXJlEhYKBnByb29mcxgCIAMoDFIGcHJvb2ZzIiUKC1NlY3JldFByb29mEhYKBnByb29mcxgBIAMoDFIGcHJvb2ZzIq8CChZMZWFmUmVmdW5kVHhTaWduaW5nSm9iEhcKB2xlYWZfaWQYASABKAlSBmxlYWZJZBJEChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyES5zcGFyay5TaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISUQocZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX2pvYhgDIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJjCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIr4CChZVc2VyU2lnbmVkVHhTaWduaW5nSm9iEhcKB2xlYWZfaWQYASABKAlSBmxlYWZJZBIsChJzaWduaW5nX3B1YmxpY19rZXkYAiABKAxSEHNpZ25pbmdQdWJsaWNLZXkSFQoGcmF3X3R4GAMgASgMUgVyYXdUeBJTChhzaWduaW5nX25vbmNlX2NvbW1pdG1lbnQYBCABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnRSFnNpZ25pbmdOb25jZUNvbW1pdG1lbnQSJQoOdXNlcl9zaWduYXR1cmUYBSABKAxSDXVzZXJTaWduYXR1cmUSSgoTc2lnbmluZ19jb21taXRtZW50cxgGIAEoCzIZLnNwYXJrLlNpZ25pbmdDb21taXRtZW50c1ISc2lnbmluZ0NvbW1pdG1lbnRzIvICChlMZWFmUmVmdW5kVHhTaWduaW5nUmVzdWx0EhcKB2xlYWZfaWQYASABKAlSBmxlYWZJZBJNChhyZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhVyZWZ1bmRUeFNpZ25pbmdSZXN1bHQSIwoNdmVyaWZ5aW5nX2tleRgDIAEoDFIMdmVyaWZ5aW5nS2V5EloKH2RpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBCABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhtkaXJlY3RSZWZ1bmRUeFNpZ25pbmdSZXN1bHQSbAopZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBSABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UiNkaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmluZ1Jlc3VsdCL1AwoeU3RhcnRVc2VyU2lnbmVkVHJhbnNmZXJSZXF1ZXN0Eh8KC3RyYW5zZmVyX2lkGAEgASgJUgp0cmFuc2ZlcklkEjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSQwoObGVhdmVzX3RvX3NlbmQYAyADKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUgxsZWF2ZXNUb1NlbmQSPwoccmVjZWl2ZXJfaWRlbnRpdHlfcHVibGljX2tleRgEIAEoDFIZcmVjZWl2ZXJJZGVudGl0eVB1YmxpY0tleRI7CgtleHBpcnlfdGltZRgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSCmV4cGlyeVRpbWUSUAoVZGlyZWN0X2xlYXZlc190b19zZW5kGAYgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlISZGlyZWN0TGVhdmVzVG9TZW5kEmIKH2RpcmVjdF9mcm9tX2NwZnBfbGVhdmVzX3RvX3NlbmQYByADKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhpkaXJlY3RGcm9tQ3BmcExlYXZlc1RvU2VuZCKpAwoUU3RhcnRUcmFuc2ZlclJlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRJDCg5sZWF2ZXNfdG9fc2VuZBgDIAMoCzIdLnNwYXJrLkxlYWZSZWZ1bmRUeFNpZ25pbmdKb2JSDGxlYXZlc1RvU2VuZBI/ChxyZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMUhlyZWNlaXZlcklkZW50aXR5UHVibGljS2V5EjsKC2V4cGlyeV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFIKZXhwaXJ5VGltZRJBChB0cmFuc2Zlcl9wYWNrYWdlGAcgASgLMhYuc3BhcmsuVHJhbnNmZXJQYWNrYWdlUg90cmFuc2ZlclBhY2thZ2USIwoNc3BhcmtfaW52b2ljZRgKIAEoCVIMc3BhcmtJbnZvaWNlSgQIBhAHSgQICRAKIo8BChVTdGFydFRyYW5zZmVyUmVzcG9uc2USKwoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXISSQoPc2lnbmluZ19yZXN1bHRzGAIgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdFIOc2lnbmluZ1Jlc3VsdHMihwQKD1RyYW5zZmVyUGFja2FnZRJDCg5sZWF2ZXNfdG9fc2VuZBgBIAMoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSDGxlYXZlc1RvU2VuZBJXChFrZXlfdHdlYWtfcGFja2FnZRgCIAMoCzIrLnNwYXJrLlRyYW5zZmVyUGFja2FnZS5LZXlUd2Vha1BhY2thZ2VFbnRyeVIPa2V5VHdlYWtQYWNrYWdlEiUKDnVzZXJfc2lnbmF0dXJlGAMgASgMUg11c2VyU2lnbmF0dXJlElAKFWRpcmVjdF9sZWF2ZXNfdG9fc2VuZBgEIAMoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSEmRpcmVjdExlYXZlc1RvU2VuZBJiCh9kaXJlY3RfZnJvbV9jcGZwX2xlYXZlc190b19zZW5kGAUgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIaZGlyZWN0RnJvbUNwZnBMZWF2ZXNUb1NlbmQSNQoMaGFzaF92YXJpYW50GAYgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50GkIKFEtleVR3ZWFrUGFja2FnZUVudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEiUgoRU2VuZExlYWZLZXlUd2Vha3MSPQoObGVhdmVzX3RvX3NlbmQYASADKAsyFy5zcGFyay5TZW5kTGVhZktleVR3ZWFrUgxsZWF2ZXNUb1NlbmQigwQKEFNlbmRMZWFmS2V5VHdlYWsSFwoHbGVhZl9pZBgBIAEoCVIGbGVhZklkEkAKEnNlY3JldF9zaGFyZV90d2VhaxgCIAEoCzISLnNwYXJrLlNlY3JldFNoYXJlUhBzZWNyZXRTaGFyZVR3ZWFrEl4KE3B1YmtleV9zaGFyZXNfdHdlYWsYAyADKAsyLi5zcGFyay5TZW5kTGVhZktleVR3ZWFrLlB1YmtleVNoYXJlc1R3ZWFrRW50cnlSEXB1YmtleVNoYXJlc1R3ZWFrEiMKDXNlY3JldF9jaXBoZXIYBCABKAxSDHNlY3JldENpcGhlchIcCglzaWduYXR1cmUYBSABKAxSCXNpZ25hdHVyZRIpChByZWZ1bmRfc2lnbmF0dXJlGAYgASgMUg9yZWZ1bmRTaWduYXR1cmUSNgoXZGlyZWN0X3JlZnVuZF9zaWduYXR1cmUYByABKAxSFWRpcmVjdFJlZnVuZFNpZ25hdHVyZRJICiFkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF9zaWduYXR1cmUYCCABKAxSHWRpcmVjdEZyb21DcGZwUmVmdW5kU2lnbmF0dXJlGkQKFlB1YmtleVNoYXJlc1R3ZWFrRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAxSBXZhbHVlOgI4ASLmAQoXRmluYWxpemVUcmFuc2ZlclJlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRI9Cg5sZWF2ZXNfdG9fc2VuZBgDIAMoCzIXLnNwYXJrLlNlbmRMZWFmS2V5VHdlYWtSDGxlYXZlc1RvU2VuZBIwChRzcGFya19wYXltZW50X2ludGVudBgEIAEoCVISc3BhcmtQYXltZW50SW50ZW50IssBCipGaW5hbGl6ZVRyYW5zZmVyV2l0aFRyYW5zZmVyUGFja2FnZVJlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRJBChB0cmFuc2Zlcl9wYWNrYWdlGAMgASgLMhYuc3BhcmsuVHJhbnNmZXJQYWNrYWdlUg90cmFuc2ZlclBhY2thZ2UiRwoYRmluYWxpemVUcmFuc2ZlclJlc3BvbnNlEisKCHRyYW5zZmVyGAEgASgLMg8uc3BhcmsuVHJhbnNmZXJSCHRyYW5zZmVyIsgECghUcmFuc2ZlchIOCgJpZBgBIAEoCVICaWQSOwoac2VuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSF3NlbmRlcklkZW50aXR5UHVibGljS2V5Ej8KHHJlY2VpdmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAyABKAxSGXJlY2VpdmVySWRlbnRpdHlQdWJsaWNLZXkSLQoGc3RhdHVzGAQgASgOMhUuc3BhcmsuVHJhbnNmZXJTdGF0dXNSBnN0YXR1cxIfCgt0b3RhbF92YWx1ZRgFIAEoBFIKdG90YWxWYWx1ZRI7CgtleHBpcnlfdGltZRgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSCmV4cGlyeVRpbWUSKwoGbGVhdmVzGAcgAygLMhMuc3BhcmsuVHJhbnNmZXJMZWFmUgZsZWF2ZXMSPQoMY3JlYXRlZF90aW1lGAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFILY3JlYXRlZFRpbWUSPQoMdXBkYXRlZF90aW1lGAkgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFILdXBkYXRlZFRpbWUSJwoEdHlwZRgKIAEoDjITLnNwYXJrLlRyYW5zZmVyVHlwZVIEdHlwZRIjCg1zcGFya19pbnZvaWNlGAsgASgJUgxzcGFya0ludm9pY2USKAoHbmV0d29yaxgMIAEoDjIOLnNwYXJrLk5ldHdvcmtSB25ldHdvcmsihAMKDFRyYW5zZmVyTGVhZhIjCgRsZWFmGAEgASgLMg8uc3BhcmsuVHJlZU5vZGVSBGxlYWYSIwoNc2VjcmV0X2NpcGhlchgCIAEoDFIMc2VjcmV0Q2lwaGVyEhwKCXNpZ25hdHVyZRgDIAEoDFIJc2lnbmF0dXJlEjQKFmludGVybWVkaWF0ZV9yZWZ1bmRfdHgYBCABKAxSFGludGVybWVkaWF0ZVJlZnVuZFR4EkEKHWludGVybWVkaWF0ZV9kaXJlY3RfcmVmdW5kX3R4GAUgASgMUhppbnRlcm1lZGlhdGVEaXJlY3RSZWZ1bmRUeBJTCidpbnRlcm1lZGlhdGVfZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHgYBiABKAxSImludGVybWVkaWF0ZURpcmVjdEZyb21DcGZwUmVmdW5kVHgSPgoccGVuZGluZ19rZXlfdHdlYWtfcHVibGljX2tleRgHIAEoDFIYcGVuZGluZ0tleVR3ZWFrUHVibGljS2V5IooFCg5UcmFuc2ZlckZpbHRlchJBChxyZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMSABSGXJlY2VpdmVySWRlbnRpdHlQdWJsaWNLZXkSPQoac2VuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxIAFIXc2VuZGVySWRlbnRpdHlQdWJsaWNLZXkSUwomc2VuZGVyX29yX3JlY2VpdmVyX2lkZW50aXR5X3B1YmxpY19rZXkYPCABKAxIAFIhc2VuZGVyT3JSZWNlaXZlcklkZW50aXR5UHVibGljS2V5EiEKDHRyYW5zZmVyX2lkcxgDIAMoCVILdHJhbnNmZXJJZHMSFAoFbGltaXQYKCABKANSBWxpbWl0EhYKBm9mZnNldBgyIAEoA1IGb2Zmc2V0EikKBXR5cGVzGEYgAygOMhMuc3BhcmsuVHJhbnNmZXJUeXBlUgV0eXBlcxIoCgduZXR3b3JrGAQgASgOMg4uc3BhcmsuTmV0d29ya1IHbmV0d29yaxIxCghzdGF0dXNlcxhQIAMoDjIVLnNwYXJrLlRyYW5zZmVyU3RhdHVzUghzdGF0dXNlcxIiCgVvcmRlchgFIAEoDjIMLnNwYXJrLk9yZGVyUgVvcmRlchJBCg1jcmVhdGVkX2FmdGVyGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgBUgxjcmVhdGVkQWZ0ZXISQwoOY3JlYXRlZF9iZWZvcmUYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSAFSDWNyZWF0ZWRCZWZvcmVCDQoLcGFydGljaXBhbnRCDQoLdGltZV9maWx0ZXIiXwoWUXVlcnlUcmFuc2ZlcnNSZXNwb25zZRItCgl0cmFuc2ZlcnMYASADKAsyDy5zcGFyay5UcmFuc2ZlclIJdHJhbnNmZXJzEhYKBm9mZnNldBgCIAEoA1IGb2Zmc2V0IpUCChFDbGFpbUxlYWZLZXlUd2VhaxIXCgdsZWFmX2lkGAEgASgJUgZsZWFmSWQSQAoSc2VjcmV0X3NoYXJlX3R3ZWFrGAIgASgLMhIuc3BhcmsuU2VjcmV0U2hhcmVSEHNlY3JldFNoYXJlVHdlYWsSXwoTcHVia2V5X3NoYXJlc190d2VhaxgDIAMoCzIvLnNwYXJrLkNsYWltTGVhZktleVR3ZWFrLlB1YmtleVNoYXJlc1R3ZWFrRW50cnlSEXB1YmtleVNoYXJlc1R3ZWFrGkQKFlB1YmtleVNoYXJlc1R3ZWFrRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAxSBXZhbHVlOgI4ASLBAQodQ2xhaW1UcmFuc2ZlclR3ZWFrS2V5c1JlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRJEChFsZWF2ZXNfdG9fcmVjZWl2ZRgDIAMoCzIYLnNwYXJrLkNsYWltTGVhZktleVR3ZWFrUg9sZWF2ZXNUb1JlY2VpdmUixQEKH0NsYWltVHJhbnNmZXJTaWduUmVmdW5kc1JlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRJACgxzaWduaW5nX2pvYnMYAyADKAsyHS5zcGFyay5MZWFmUmVmdW5kVHhTaWduaW5nSm9iUgtzaWduaW5nSm9ic0oECAQQBSJtCiBDbGFpbVRyYW5zZmVyU2lnblJlZnVuZHNSZXNwb25zZRJJCg9zaWduaW5nX3Jlc3VsdHMYASADKAsyIC5zcGFyay5MZWFmUmVmdW5kVHhTaWduaW5nUmVzdWx0Ug5zaWduaW5nUmVzdWx0cyL3AQoZU3RvcmVQcmVpbWFnZVNoYXJlUmVxdWVzdBIhCgxwYXltZW50X2hhc2gYASABKAxSC3BheW1lbnRIYXNoEjkKDnByZWltYWdlX3NoYXJlGAIgASgLMhIuc3BhcmsuU2VjcmV0U2hhcmVSDXByZWltYWdlU2hhcmUSHAoJdGhyZXNob2xkGAMgASgNUgl0aHJlc2hvbGQSJQoOaW52b2ljZV9zdHJpbmcYBCABKAlSDWludm9pY2VTdHJpbmcSNwoYdXNlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAUgASgMUhV1c2VySWRlbnRpdHlQdWJsaWNLZXkigQIKG1JlcXVlc3RlZFNpZ25pbmdDb21taXRtZW50cxJ7ChlzaWduaW5nX25vbmNlX2NvbW1pdG1lbnRzGAEgAygLMj8uc3BhcmsuUmVxdWVzdGVkU2lnbmluZ0NvbW1pdG1lbnRzLlNpZ25pbmdOb25jZUNvbW1pdG1lbnRzRW50cnlSF3NpZ25pbmdOb25jZUNvbW1pdG1lbnRzGmUKHFNpZ25pbmdOb25jZUNvbW1pdG1lbnRzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSLwoFdmFsdWUYAiABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnRSBXZhbHVlOgI4ASJzChxHZXRTaWduaW5nQ29tbWl0bWVudHNSZXF1ZXN0EhkKCG5vZGVfaWRzGAEgAygJUgdub2RlSWRzEhQKBWNvdW50GAIgASgNUgVjb3VudBIiCg1ub2RlX2lkX2NvdW50GAMgASgNUgtub2RlSWRDb3VudCJ0Ch1HZXRTaWduaW5nQ29tbWl0bWVudHNSZXNwb25zZRJTChNzaWduaW5nX2NvbW1pdG1lbnRzGAEgAygLMiIuc3BhcmsuUmVxdWVzdGVkU2lnbmluZ0NvbW1pdG1lbnRzUhJzaWduaW5nQ29tbWl0bWVudHMi2gEKElNpZ25pbmdDb21taXRtZW50cxJiChNzaWduaW5nX2NvbW1pdG1lbnRzGAEgAygLMjEuc3BhcmsuU2lnbmluZ0NvbW1pdG1lbnRzLlNpZ25pbmdDb21taXRtZW50c0VudHJ5UhJzaWduaW5nQ29tbWl0bWVudHMaYAoXU2lnbmluZ0NvbW1pdG1lbnRzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSLwoFdmFsdWUYAiABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnRSBXZhbHVlOgI4ASLGAgoQVXNlclNpZ25lZFJlZnVuZBIXCgdub2RlX2lkGAEgASgJUgZub2RlSWQSGwoJcmVmdW5kX3R4GAIgASgMUghyZWZ1bmRUeBIlCg51c2VyX3NpZ25hdHVyZRgDIAEoDFINdXNlclNpZ25hdHVyZRJKChNzaWduaW5nX2NvbW1pdG1lbnRzGAQgASgLMhkuc3BhcmsuU2lnbmluZ0NvbW1pdG1lbnRzUhJzaWduaW5nQ29tbWl0bWVudHMSVQoZdXNlcl9zaWduYXR1cmVfY29tbWl0bWVudBgFIAEoCzIZLmNvbW1vbi5TaWduaW5nQ29tbWl0bWVudFIXdXNlclNpZ25hdHVyZUNvbW1pdG1lbnQSMgoHbmV0d29yaxgGIAEoDjIOLnNwYXJrLk5ldHdvcmtCCPpCBYIBAiAAUgduZXR3b3JrIjsKEkludm9pY2VBbW91bnRQcm9vZhIlCg5ib2x0MTFfaW52b2ljZRgBIAEoCVINYm9sdDExSW52b2ljZSJ7Cg1JbnZvaWNlQW1vdW50Eh0KCnZhbHVlX3NhdHMYASABKARSCXZhbHVlU2F0cxJLChRpbnZvaWNlX2Ftb3VudF9wcm9vZhgCIAEoCzIZLnNwYXJrLkludm9pY2VBbW91bnRQcm9vZlISaW52b2ljZUFtb3VudFByb29mItYDChtJbml0aWF0ZVByZWltYWdlU3dhcFJlcXVlc3QSIQoMcGF5bWVudF9oYXNoGAEgASgMUgtwYXltZW50SGFzaBI7Cg5pbnZvaWNlX2Ftb3VudBgCIAEoCzIULnNwYXJrLkludm9pY2VBbW91bnRSDWludm9pY2VBbW91bnQSQQoGcmVhc29uGAMgASgOMikuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXF1ZXN0LlJlYXNvblIGcmVhc29uEkEKCHRyYW5zZmVyGAQgASgLMiUuc3BhcmsuU3RhcnRVc2VyU2lnbmVkVHJhbnNmZXJSZXF1ZXN0Ugh0cmFuc2ZlchI/ChxyZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAUgASgMUhlyZWNlaXZlcklkZW50aXR5UHVibGljS2V5EhkKCGZlZV9zYXRzGAYgASgEUgdmZWVTYXRzEkYKEHRyYW5zZmVyX3JlcXVlc3QYByABKAsyGy5zcGFyay5TdGFydFRyYW5zZmVyUmVxdWVzdFIPdHJhbnNmZXJSZXF1ZXN0Ii0KBlJlYXNvbhIPCgtSRUFTT05fU0VORBAAEhIKDlJFQVNPTl9SRUNFSVZFEAEiZwocSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXNwb25zZRIaCghwcmVpbWFnZRgBIAEoDFIIcHJlaW1hZ2USKwoIdHJhbnNmZXIYAiABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXIiMgoIT3V0UG9pbnQSEgoEdHhpZBgBIAEoDFIEdHhpZBISCgR2b3V0GAIgASgNUgR2b3V0IqoBChZDb29wZXJhdGl2ZUV4aXRSZXF1ZXN0EjcKCHRyYW5zZmVyGAEgASgLMhsuc3BhcmsuU3RhcnRUcmFuc2ZlclJlcXVlc3RSCHRyYW5zZmVyEhcKB2V4aXRfaWQYAiABKAlSBmV4aXRJZBIbCglleGl0X3R4aWQYAyABKAxSCGV4aXRUeGlkEiEKDGNvbm5lY3Rvcl90eBgEIAEoDFILY29ubmVjdG9yVHgikQEKF0Nvb3BlcmF0aXZlRXhpdFJlc3BvbnNlEisKCHRyYW5zZmVyGAEgASgLMg8uc3BhcmsuVHJhbnNmZXJSCHRyYW5zZmVyEkkKD3NpZ25pbmdfcmVzdWx0cxgCIAMoCzIgLnNwYXJrLkxlYWZSZWZ1bmRUeFNpZ25pbmdSZXN1bHRSDnNpZ25pbmdSZXN1bHRzIqACChZDb3VudGVyTGVhZlN3YXBSZXF1ZXN0EjcKCHRyYW5zZmVyGAEgASgLMhsuc3BhcmsuU3RhcnRUcmFuc2ZlclJlcXVlc3RSCHRyYW5zZmVyEhcKB3N3YXBfaWQYAiABKAlSBnN3YXBJZBIsChJhZGFwdG9yX3B1YmxpY19rZXkYAyABKAxSEGFkYXB0b3JQdWJsaWNLZXkSOQoZZGlyZWN0X2FkYXB0b3JfcHVibGljX2tleRgEIAEoDFIWZGlyZWN0QWRhcHRvclB1YmxpY0tleRJLCiNkaXJlY3RfZnJvbV9jcGZwX2FkYXB0b3JfcHVibGljX2tleRgFIAEoDFIeZGlyZWN0RnJvbUNwZnBBZGFwdG9yUHVibGljS2V5IpEBChdDb3VudGVyTGVhZlN3YXBSZXNwb25zZRIrCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlchJJCg9zaWduaW5nX3Jlc3VsdHMYAiADKAsyIC5zcGFyay5MZWFmUmVmdW5kVHhTaWduaW5nUmVzdWx0Ug5zaWduaW5nUmVzdWx0cyKiAQoWUmVmcmVzaFRpbWVsb2NrUmVxdWVzdBIXCgdsZWFmX2lkGAEgASgJUgZsZWFmSWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRI0CgxzaWduaW5nX2pvYnMYAyADKAsyES5zcGFyay5TaWduaW5nSm9iUgtzaWduaW5nSm9icyKAAQocUmVmcmVzaFRpbWVsb2NrU2lnbmluZ1Jlc3VsdBI7Cg5zaWduaW5nX3Jlc3VsdBgBIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSDXNpZ25pbmdSZXN1bHQSIwoNdmVyaWZ5aW5nX2tleRgCIAEoDFIMdmVyaWZ5aW5nS2V5ImcKF1JlZnJlc2hUaW1lbG9ja1Jlc3BvbnNlEkwKD3NpZ25pbmdfcmVzdWx0cxgBIAMoCzIjLnNwYXJrLlJlZnJlc2hUaW1lbG9ja1NpZ25pbmdSZXN1bHRSDnNpZ25pbmdSZXN1bHRzIvYDChFFeHRlbmRMZWFmUmVxdWVzdBIXCgdsZWFmX2lkGAEgASgJUgZsZWFmSWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRJAChNub2RlX3R4X3NpZ25pbmdfam9iGAMgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIQbm9kZVR4U2lnbmluZ0pvYhJEChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyES5zcGFyay5TaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISTQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYBSABKAsyES5zcGFyay5TaWduaW5nSm9iUhZkaXJlY3ROb2RlVHhTaWduaW5nSm9iElEKHGRpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBiABKAsyES5zcGFyay5TaWduaW5nSm9iUhhkaXJlY3RSZWZ1bmRUeFNpZ25pbmdKb2ISYwomZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYByABKAsyES5zcGFyay5TaWduaW5nSm9iUiBkaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmluZ0pvYiJ7ChdFeHRlbmRMZWFmU2lnbmluZ1Jlc3VsdBI7Cg5zaWduaW5nX3Jlc3VsdBgBIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSDXNpZ25pbmdSZXN1bHQSIwoNdmVyaWZ5aW5nX2tleRgCIAEoDFIMdmVyaWZ5aW5nS2V5IpsEChJFeHRlbmRMZWFmUmVzcG9uc2USFwoHbGVhZl9pZBgBIAEoCVIGbGVhZklkElMKFm5vZGVfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyHi5zcGFyay5FeHRlbmRMZWFmU2lnbmluZ1Jlc3VsdFITbm9kZVR4U2lnbmluZ1Jlc3VsdBJXChhyZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYAyABKAsyHi5zcGFyay5FeHRlbmRMZWFmU2lnbmluZ1Jlc3VsdFIVcmVmdW5kVHhTaWduaW5nUmVzdWx0EmAKHWRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfcmVzdWx0GAQgASgLMh4uc3BhcmsuRXh0ZW5kTGVhZlNpZ25pbmdSZXN1bHRSGWRpcmVjdE5vZGVUeFNpZ25pbmdSZXN1bHQSZAofZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgFIAEoCzIeLnNwYXJrLkV4dGVuZExlYWZTaWduaW5nUmVzdWx0UhtkaXJlY3RSZWZ1bmRUeFNpZ25pbmdSZXN1bHQSdgopZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBiABKAsyHi5zcGFyay5FeHRlbmRMZWFmU2lnbmluZ1Jlc3VsdFIjZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdSZXN1bHQicwoSQWRkcmVzc1JlcXVlc3ROb2RlEiYKD3VzZXJfcHVibGljX2tleRgBIAEoDFINdXNlclB1YmxpY0tleRI1CghjaGlsZHJlbhgCIAMoCzIZLnNwYXJrLkFkZHJlc3NSZXF1ZXN0Tm9kZVIIY2hpbGRyZW4igwIKGVByZXBhcmVUcmVlQWRkcmVzc1JlcXVlc3QSQQoScGFyZW50X25vZGVfb3V0cHV0GAEgASgLMhEuc3BhcmsuTm9kZU91dHB1dEgAUhBwYXJlbnROb2RlT3V0cHV0EjEKDW9uX2NoYWluX3V0eG8YAiABKAsyCy5zcGFyay5VVFhPSABSC29uQ2hhaW5VdHhvEi0KBG5vZGUYAyABKAsyGS5zcGFyay5BZGRyZXNzUmVxdWVzdE5vZGVSBG5vZGUSNwoYdXNlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMUhV1c2VySWRlbnRpdHlQdWJsaWNLZXlCCAoGc291cmNlImcKC0FkZHJlc3NOb2RlEigKB2FkZHJlc3MYASABKAsyDi5zcGFyay5BZGRyZXNzUgdhZGRyZXNzEi4KCGNoaWxkcmVuGAIgAygLMhIuc3BhcmsuQWRkcmVzc05vZGVSCGNoaWxkcmVuIkQKGlByZXBhcmVUcmVlQWRkcmVzc1Jlc3BvbnNlEiYKBG5vZGUYASABKAsyEi5zcGFyay5BZGRyZXNzTm9kZVIEbm9kZSLOAwoMQ3JlYXRpb25Ob2RlEkAKE25vZGVfdHhfc2lnbmluZ19qb2IYASABKAsyES5zcGFyay5TaWduaW5nSm9iUhBub2RlVHhTaWduaW5nSm9iEkQKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgCIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSEnJlZnVuZFR4U2lnbmluZ0pvYhIvCghjaGlsZHJlbhgDIAMoCzITLnNwYXJrLkNyZWF0aW9uTm9kZVIIY2hpbGRyZW4STQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYBCABKAsyES5zcGFyay5TaWduaW5nSm9iUhZkaXJlY3ROb2RlVHhTaWduaW5nSm9iElEKHGRpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBSABKAsyES5zcGFyay5TaWduaW5nSm9iUhhkaXJlY3RSZWZ1bmRUeFNpZ25pbmdKb2ISYwomZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBiABKAsyES5zcGFyay5TaWduaW5nSm9iUiBkaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmluZ0pvYiL1AQoRQ3JlYXRlVHJlZVJlcXVlc3QSQQoScGFyZW50X25vZGVfb3V0cHV0GAEgASgLMhEuc3BhcmsuTm9kZU91dHB1dEgAUhBwYXJlbnROb2RlT3V0cHV0EjEKDW9uX2NoYWluX3V0eG8YAiABKAsyCy5zcGFyay5VVFhPSABSC29uQ2hhaW5VdHhvEicKBG5vZGUYAyABKAsyEy5zcGFyay5DcmVhdGlvbk5vZGVSBG5vZGUSNwoYdXNlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMUhV1c2VySWRlbnRpdHlQdWJsaWNLZXlCCAoGc291cmNlIqQEChRDcmVhdGlvblJlc3BvbnNlTm9kZRIXCgdub2RlX2lkGAEgASgJUgZub2RlSWQSSQoWbm9kZV90eF9zaWduaW5nX3Jlc3VsdBgCIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSE25vZGVUeFNpZ25pbmdSZXN1bHQSTQoYcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAMgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdFIVcmVmdW5kVHhTaWduaW5nUmVzdWx0EjcKCGNoaWxkcmVuGAQgAygLMhsuc3BhcmsuQ3JlYXRpb25SZXNwb25zZU5vZGVSCGNoaWxkcmVuElYKHWRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfcmVzdWx0GAUgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdFIZZGlyZWN0Tm9kZVR4U2lnbmluZ1Jlc3VsdBJaCh9kaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAYgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdFIbZGlyZWN0UmVmdW5kVHhTaWduaW5nUmVzdWx0EmwKKWRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAcgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdFIjZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdSZXN1bHQiRQoSQ3JlYXRlVHJlZVJlc3BvbnNlEi8KBG5vZGUYASABKAsyGy5zcGFyay5DcmVhdGlvblJlc3BvbnNlTm9kZVIEbm9kZSKEAQoTU2lnbmluZ09wZXJhdG9ySW5mbxIUCgVpbmRleBgBIAEoBFIFaW5kZXgSHgoKaWRlbnRpZmllchgCIAEoCVIKaWRlbnRpZmllchIdCgpwdWJsaWNfa2V5GAMgASgMUglwdWJsaWNLZXkSGAoHYWRkcmVzcxgEIAEoCVIHYWRkcmVzcyLrAQoeR2V0U2lnbmluZ09wZXJhdG9yTGlzdFJlc3BvbnNlEmgKEXNpZ25pbmdfb3BlcmF0b3JzGAEgAygLMjsuc3BhcmsuR2V0U2lnbmluZ09wZXJhdG9yTGlzdFJlc3BvbnNlLlNpZ25pbmdPcGVyYXRvcnNFbnRyeVIQc2lnbmluZ09wZXJhdG9ycxpfChVTaWduaW5nT3BlcmF0b3JzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSMAoFdmFsdWUYAiABKAsyGi5zcGFyay5TaWduaW5nT3BlcmF0b3JJbmZvUgV2YWx1ZToCOAEicgodUXVlcnlVc2VyU2lnbmVkUmVmdW5kc1JlcXVlc3QSIQoMcGF5bWVudF9oYXNoGAEgASgMUgtwYXltZW50SGFzaBIuChNpZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMUhFpZGVudGl0eVB1YmxpY0tleSKcAQoeUXVlcnlVc2VyU2lnbmVkUmVmdW5kc1Jlc3BvbnNlEkcKE3VzZXJfc2lnbmVkX3JlZnVuZHMYASADKAsyFy5zcGFyay5Vc2VyU2lnbmVkUmVmdW5kUhF1c2VyU2lnbmVkUmVmdW5kcxIrCgh0cmFuc2ZlchgDIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlckoECAIQAyKkAwobUHJlaW1hZ2VSZXF1ZXN0V2l0aFRyYW5zZmVyEioKDHBheW1lbnRfaGFzaBgBIAEoDEIH+kIEegJoIFILcGF5bWVudEhhc2gSQQoYcmVjZWl2ZXJfaWRlbnRpdHlfcHVia2V5GAIgASgMQgf6QgR6AmghUhZyZWNlaXZlcklkZW50aXR5UHVia2V5EjQKBnN0YXR1cxgDIAEoDjIcLnNwYXJrLlByZWltYWdlUmVxdWVzdFN0YXR1c1IGc3RhdHVzEj0KDGNyZWF0ZWRfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSC2NyZWF0ZWRUaW1lEjAKCHRyYW5zZmVyGAUgASgLMg8uc3BhcmsuVHJhbnNmZXJIAFIIdHJhbnNmZXKIAQESHwoIcHJlaW1hZ2UYBiABKAxIAVIIcHJlaW1hZ2WIAQESNAoWc2VuZGVyX2lkZW50aXR5X3B1YmtleRgHIAEoDFIUc2VuZGVySWRlbnRpdHlQdWJrZXlCCwoJX3RyYW5zZmVyQgsKCV9wcmVpbWFnZSLEAgoQUXVlcnlIdGxjUmVxdWVzdBIlCg5wYXltZW50X2hhc2hlcxgBIAMoDFINcGF5bWVudEhhc2hlcxI3ChNpZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUhFpZGVudGl0eVB1YmxpY0tleRI5CgZzdGF0dXMYAyABKA4yHC5zcGFyay5QcmVpbWFnZVJlcXVlc3RTdGF0dXNIAFIGc3RhdHVziAEBEhQKBWxpbWl0GAQgASgDUgVsaW1pdBIWCgZvZmZzZXQYBSABKANSBm9mZnNldBIhCgx0cmFuc2Zlcl9pZHMYBiADKAlSC3RyYW5zZmVySWRzEjkKCm1hdGNoX3JvbGUYByABKA4yGi5zcGFyay5QcmVpbWFnZVJlcXVlc3RSb2xlUgltYXRjaFJvbGVCCQoHX3N0YXR1cyJ8ChFRdWVyeUh0bGNSZXNwb25zZRJPChFwcmVpbWFnZV9yZXF1ZXN0cxgBIAMoCzIiLnNwYXJrLlByZWltYWdlUmVxdWVzdFdpdGhUcmFuc2ZlclIQcHJlaW1hZ2VSZXF1ZXN0cxIWCgZvZmZzZXQYAiABKANSBm9mZnNldCKHAQoWUHJvdmlkZVByZWltYWdlUmVxdWVzdBIhCgxwYXltZW50X2hhc2gYASABKAxSC3BheW1lbnRIYXNoEhoKCHByZWltYWdlGAIgASgMUghwcmVpbWFnZRIuChNpZGVudGl0eV9wdWJsaWNfa2V5GAMgASgMUhFpZGVudGl0eVB1YmxpY0tleSJGChdQcm92aWRlUHJlaW1hZ2VSZXNwb25zZRIrCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlciKFAQoUUXVlcnlQcmVpbWFnZVJlcXVlc3QSKgoMcGF5bWVudF9oYXNoGAEgASgMQgf6QgR6AmggUgtwYXltZW50SGFzaBJBChhyZWNlaXZlcl9pZGVudGl0eV9wdWJrZXkYAiABKAxCB/pCBHoCaCFSFnJlY2VpdmVySWRlbnRpdHlQdWJrZXkiRQoVUXVlcnlQcmVpbWFnZVJlc3BvbnNlEh8KCHByZWltYWdlGAEgASgMSABSCHByZWltYWdliAEBQgsKCV9wcmVpbWFnZSIoCgtUcmVlTm9kZUlkcxIZCghub2RlX2lkcxgBIAMoCVIHbm9kZUlkcyK4AgoRUXVlcnlOb2Rlc1JlcXVlc3QSNAoVb3duZXJfaWRlbnRpdHlfcHVia2V5GAEgASgMSABSE293bmVySWRlbnRpdHlQdWJrZXkSLwoIbm9kZV9pZHMYAiABKAsyEi5zcGFyay5UcmVlTm9kZUlkc0gAUgdub2RlSWRzEicKD2luY2x1ZGVfcGFyZW50cxgDIAEoCFIOaW5jbHVkZVBhcmVudHMSFAoFbGltaXQYBCABKANSBWxpbWl0EhYKBm9mZnNldBgFIAEoA1IGb2Zmc2V0EigKB25ldHdvcmsYBiABKA4yDi5zcGFyay5OZXR3b3JrUgduZXR3b3JrEjEKCHN0YXR1c2VzGAcgAygOMhUuc3BhcmsuVHJlZU5vZGVTdGF0dXNSCHN0YXR1c2VzQggKBnNvdXJjZSKzAQoSUXVlcnlOb2Rlc1Jlc3BvbnNlEjoKBW5vZGVzGAEgAygLMiQuc3BhcmsuUXVlcnlOb2Rlc1Jlc3BvbnNlLk5vZGVzRW50cnlSBW5vZGVzEhYKBm9mZnNldBgCIAEoA1IGb2Zmc2V0GkkKCk5vZGVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSJQoFdmFsdWUYAiABKAsyDy5zcGFyay5UcmVlTm9kZVIFdmFsdWU6AjgBInUKFUNhbmNlbFRyYW5zZmVyUmVxdWVzdBIfCgt0cmFuc2Zlcl9pZBgBIAEoCVIKdHJhbnNmZXJJZBI7ChpzZW5kZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIXc2VuZGVySWRlbnRpdHlQdWJsaWNLZXkiRQoWQ2FuY2VsVHJhbnNmZXJSZXNwb25zZRIrCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlciKsAQoiUXVlcnlVbnVzZWREZXBvc2l0QWRkcmVzc2VzUmVxdWVzdBIuChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMUhFpZGVudGl0eVB1YmxpY0tleRIoCgduZXR3b3JrGAIgASgOMg4uc3BhcmsuTmV0d29ya1IHbmV0d29yaxIUCgVsaW1pdBgDIAEoA1IFbGltaXQSFgoGb2Zmc2V0GAQgASgDUgZvZmZzZXQipQIKIlF1ZXJ5U3RhdGljRGVwb3NpdEFkZHJlc3Nlc1JlcXVlc3QSLgoTaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkSKAoHbmV0d29yaxgCIAEoDjIOLnNwYXJrLk5ldHdvcmtSB25ldHdvcmsSFAoFbGltaXQYBCABKANSBWxpbWl0EhYKBm9mZnNldBgFIAEoA1IGb2Zmc2V0EiwKD2RlcG9zaXRfYWRkcmVzcxgGIAEoCUgAUg5kZXBvc2l0QWRkcmVzc4gBARI1CgxoYXNoX3ZhcmlhbnQYByABKA4yEi5zcGFyay5IYXNoVmFyaWFudFILaGFzaFZhcmlhbnRCEgoQX2RlcG9zaXRfYWRkcmVzcyLKAgoZRGVwb3NpdEFkZHJlc3NRdWVyeVJlc3VsdBInCg9kZXBvc2l0X2FkZHJlc3MYASABKAlSDmRlcG9zaXRBZGRyZXNzEjUKF3VzZXJfc2lnbmluZ19wdWJsaWNfa2V5GAIgASgMUhR1c2VyU2lnbmluZ1B1YmxpY0tleRIwChR2ZXJpZnlpbmdfcHVibGljX2tleRgDIAEoDFISdmVyaWZ5aW5nUHVibGljS2V5EiYKB2xlYWZfaWQYBCABKAlCCPpCBXIDsAEBSABSBmxlYWZJZIgBARJPChNwcm9vZl9vZl9wb3NzZXNzaW9uGAUgASgLMhouc3BhcmsuRGVwb3NpdEFkZHJlc3NQcm9vZkgBUhFwcm9vZk9mUG9zc2Vzc2lvbogBAUIKCghfbGVhZl9pZEIWChRfcHJvb2Zfb2ZfcG9zc2Vzc2lvbiKMAQojUXVlcnlVbnVzZWREZXBvc2l0QWRkcmVzc2VzUmVzcG9uc2USTQoRZGVwb3NpdF9hZGRyZXNzZXMYASADKAsyIC5zcGFyay5EZXBvc2l0QWRkcmVzc1F1ZXJ5UmVzdWx0UhBkZXBvc2l0QWRkcmVzc2VzEhYKBm9mZnNldBgCIAEoA1IGb2Zmc2V0InQKI1F1ZXJ5U3RhdGljRGVwb3NpdEFkZHJlc3Nlc1Jlc3BvbnNlEk0KEWRlcG9zaXRfYWRkcmVzc2VzGAEgAygLMiAuc3BhcmsuRGVwb3NpdEFkZHJlc3NRdWVyeVJlc3VsdFIQZGVwb3NpdEFkZHJlc3NlcyJvChNRdWVyeUJhbGFuY2VSZXF1ZXN0Ei4KE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxSEWlkZW50aXR5UHVibGljS2V5EigKB25ldHdvcmsYAiABKA4yDi5zcGFyay5OZXR3b3JrUgduZXR3b3JrIsUBChRRdWVyeUJhbGFuY2VSZXNwb25zZRIYCgdiYWxhbmNlGAEgASgEUgdiYWxhbmNlElIKDW5vZGVfYmFsYW5jZXMYAiADKAsyLS5zcGFyay5RdWVyeUJhbGFuY2VSZXNwb25zZS5Ob2RlQmFsYW5jZXNFbnRyeVIMbm9kZUJhbGFuY2VzGj8KEU5vZGVCYWxhbmNlc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgEUgV2YWx1ZToCOAEixQEKDFNwYXJrQWRkcmVzcxIuChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMUhFpZGVudGl0eVB1YmxpY0tleRJLChRzcGFya19pbnZvaWNlX2ZpZWxkcxgCIAEoCzIZLnNwYXJrLlNwYXJrSW52b2ljZUZpZWxkc1ISc3BhcmtJbnZvaWNlRmllbGRzEioKCXNpZ25hdHVyZRgDIAEoDEIH+kIEegJoQEgAUglzaWduYXR1cmWIAQFCDAoKX3NpZ25hdHVyZSKcAwoSU3BhcmtJbnZvaWNlRmllbGRzEhgKB3ZlcnNpb24YASABKA1SB3ZlcnNpb24SFwoCaWQYAiABKAxCB/pCBHoCaBBSAmlkEj0KDnRva2Vuc19wYXltZW50GAMgASgLMhQuc3BhcmsuVG9rZW5zUGF5bWVudEgAUg10b2tlbnNQYXltZW50EjcKDHNhdHNfcGF5bWVudBgEIAEoCzISLnNwYXJrLlNhdHNQYXltZW50SABSC3NhdHNQYXltZW50EiAKBG1lbW8YBSABKAlCB/pCBHICKHhIAVIEbWVtb4gBARI4ChFzZW5kZXJfcHVibGljX2tleRgGIAEoDEIH+kIEegJoIUgCUg9zZW5kZXJQdWJsaWNLZXmIAQESQAoLZXhwaXJ5X3RpbWUYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSANSCmV4cGlyeVRpbWWIAQFCDgoMcGF5bWVudF90eXBlQgcKBV9tZW1vQhQKEl9zZW5kZXJfcHVibGljX2tleUIOCgxfZXhwaXJ5X3RpbWUiNQoLU2F0c1BheW1lbnQSGwoGYW1vdW50GAEgASgESABSBmFtb3VudIgBAUIJCgdfYW1vdW50Io4BCg1Ub2tlbnNQYXltZW50EjcKEHRva2VuX2lkZW50aWZpZXIYASABKAxCB/pCBHoCaCBIAFIPdG9rZW5JZGVudGlmaWVyiAEBEiQKBmFtb3VudBgCIAEoDEIH+kIEegIYEEgBUgZhbW91bnSIAQFCEwoRX3Rva2VuX2lkZW50aWZpZXJCCQoHX2Ftb3VudCL9AQomSW5pdGlhdGVTdGF0aWNEZXBvc2l0VXR4b1JlZnVuZFJlcXVlc3QSLwoNb25fY2hhaW5fdXR4bxgBIAEoCzILLnNwYXJrLlVUWE9SC29uQ2hhaW5VdHhvEkQKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgDIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSEnJlZnVuZFR4U2lnbmluZ0pvYhIlCg51c2VyX3NpZ25hdHVyZRgEIAEoDFINdXNlclNpZ25hdHVyZRI1CgxoYXNoX3ZhcmlhbnQYBSABKA4yEi5zcGFyay5IYXNoVmFyaWFudFILaGFzaFZhcmlhbnQiwwEKJ0luaXRpYXRlU3RhdGljRGVwb3NpdFV0eG9SZWZ1bmRSZXNwb25zZRJNChhyZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYASABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhVyZWZ1bmRUeFNpZ25pbmdSZXN1bHQSSQoPZGVwb3NpdF9hZGRyZXNzGAIgASgLMiAuc3BhcmsuRGVwb3NpdEFkZHJlc3NRdWVyeVJlc3VsdFIOZGVwb3NpdEFkZHJlc3MisAMKF0luaXRpYXRlVXR4b1N3YXBSZXF1ZXN0Ei8KDW9uX2NoYWluX3V0eG8YASABKAsyCy5zcGFyay5VVFhPUgtvbkNoYWluVXR4bxI9CgxyZXF1ZXN0X3R5cGUYAiABKA4yGi5zcGFyay5VdHhvU3dhcFJlcXVlc3RUeXBlUgtyZXF1ZXN0VHlwZRIuChJjcmVkaXRfYW1vdW50X3NhdHMYAyABKARIAFIQY3JlZGl0QW1vdW50U2F0cxIiCgxtYXhfZmVlX3NhdHMYBCABKARIAFIKbWF4RmVlU2F0cxIjCg1zc3Bfc2lnbmF0dXJlGAUgASgMUgxzc3BTaWduYXR1cmUSJQoOdXNlcl9zaWduYXR1cmUYBiABKAxSDXVzZXJTaWduYXR1cmUSNwoIdHJhbnNmZXIYByABKAsyGy5zcGFyay5TdGFydFRyYW5zZmVyUmVxdWVzdFIIdHJhbnNmZXISQgoUc3BlbmRfdHhfc2lnbmluZ19qb2IYCCABKAsyES5zcGFyay5TaWduaW5nSm9iUhFzcGVuZFR4U2lnbmluZ0pvYkIICgZhbW91bnQi3wEKGEluaXRpYXRlVXR4b1N3YXBSZXNwb25zZRJLChdzcGVuZF90eF9zaWduaW5nX3Jlc3VsdBgBIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSFHNwZW5kVHhTaWduaW5nUmVzdWx0EisKCHRyYW5zZmVyGAIgASgLMg8uc3BhcmsuVHJhbnNmZXJSCHRyYW5zZmVyEkkKD2RlcG9zaXRfYWRkcmVzcxgDIAEoCzIgLnNwYXJrLkRlcG9zaXRBZGRyZXNzUXVlcnlSZXN1bHRSDmRlcG9zaXRBZGRyZXNzIosBCgtFeGl0aW5nVHJlZRIXCgd0cmVlX2lkGAEgASgJUgZ0cmVlSWQSUQoXdXNlcl9zaWduaW5nX2NvbW1pdG1lbnQYAiABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnRSFXVzZXJTaWduaW5nQ29tbWl0bWVudBIQCgN2aW4YAyABKA1SA3ZpbiKcAQofRXhpdFNpbmdsZU5vZGVUcmVlU2lnbmluZ1Jlc3VsdBIXCgd0cmVlX2lkGAEgASgJUgZ0cmVlSWQSOwoOc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0Ug1zaWduaW5nUmVzdWx0EiMKDXZlcmlmeWluZ19rZXkYAyABKAxSDHZlcmlmeWluZ0tleSJNChhCaXRjb2luVHJhbnNhY3Rpb25PdXRwdXQSFAoFdmFsdWUYASABKANSBXZhbHVlEhsKCXBrX3NjcmlwdBgCIAEoDFIIcGtTY3JpcHQi8wEKGkV4aXRTaW5nbGVOb2RlVHJlZXNSZXF1ZXN0EjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSNwoNZXhpdGluZ190cmVlcxgCIAMoCzISLnNwYXJrLkV4aXRpbmdUcmVlUgxleGl0aW5nVHJlZXMSFQoGcmF3X3R4GAMgASgMUgVyYXdUeBJKChBwcmV2aW91c19vdXRwdXRzGAQgAygLMh8uc3BhcmsuQml0Y29pblRyYW5zYWN0aW9uT3V0cHV0Ug9wcmV2aW91c091dHB1dHMibgobRXhpdFNpbmdsZU5vZGVUcmVlc1Jlc3BvbnNlEk8KD3NpZ25pbmdfcmVzdWx0cxgBIAMoCzImLnNwYXJrLkV4aXRTaW5nbGVOb2RlVHJlZVNpZ25pbmdSZXN1bHRSDnNpZ25pbmdSZXN1bHRzIloKHVF1ZXJ5Tm9kZXNEaXN0cmlidXRpb25SZXF1ZXN0EjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkizwEKHlF1ZXJ5Tm9kZXNEaXN0cmlidXRpb25SZXNwb25zZRJoChFub2RlX2Rpc3RyaWJ1dGlvbhgBIAMoCzI7LnNwYXJrLlF1ZXJ5Tm9kZXNEaXN0cmlidXRpb25SZXNwb25zZS5Ob2RlRGlzdHJpYnV0aW9uRW50cnlSEG5vZGVEaXN0cmlidXRpb24aQwoVTm9kZURpc3RyaWJ1dGlvbkVudHJ5EhAKA2tleRgBIAEoBFIDa2V5EhQKBXZhbHVlGAIgASgEUgV2YWx1ZToCOAEimQEKGFF1ZXJ5Tm9kZXNCeVZhbHVlUmVxdWVzdBI5Chlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMUhZvd25lcklkZW50aXR5UHVibGljS2V5EhQKBXZhbHVlGAIgASgDUgV2YWx1ZRIWCgZvZmZzZXQYAyABKANSBm9mZnNldBIUCgVsaW1pdBgEIAEoA1IFbGltaXQiwQEKGVF1ZXJ5Tm9kZXNCeVZhbHVlUmVzcG9uc2USQQoFbm9kZXMYASADKAsyKy5zcGFyay5RdWVyeU5vZGVzQnlWYWx1ZVJlc3BvbnNlLk5vZGVzRW50cnlSBW5vZGVzEhYKBm9mZnNldBgCIAEoA1IGb2Zmc2V0GkkKCk5vZGVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSJQoFdmFsdWUYAiABKAsyDy5zcGFyay5UcmVlTm9kZVIFdmFsdWU6AjgBIrYBChlHZXRVdHhvc0ZvckFkZHJlc3NSZXF1ZXN0EhgKB2FkZHJlc3MYASABKAlSB2FkZHJlc3MSFgoGb2Zmc2V0GAIgASgEUgZvZmZzZXQSFAoFbGltaXQYAyABKARSBWxpbWl0EigKB25ldHdvcmsYBCABKA4yDi5zcGFyay5OZXR3b3JrUgduZXR3b3JrEicKD2V4Y2x1ZGVfY2xhaW1lZBgFIAEoCFIOZXhjbHVkZUNsYWltZWQiVwoaR2V0VXR4b3NGb3JBZGRyZXNzUmVzcG9uc2USIQoFdXR4b3MYASADKAsyCy5zcGFyay5VVFhPUgV1dHhvcxIWCgZvZmZzZXQYAiABKARSBm9mZnNldCJjChlRdWVyeVNwYXJrSW52b2ljZXNSZXF1ZXN0EhQKBWxpbWl0GAEgASgDUgVsaW1pdBIWCgZvZmZzZXQYAiABKANSBm9mZnNldBIYCgdpbnZvaWNlGAMgAygJUgdpbnZvaWNlIncKGlF1ZXJ5U3BhcmtJbnZvaWNlc1Jlc3BvbnNlEhYKBm9mZnNldBgBIAEoA1IGb2Zmc2V0EkEKEGludm9pY2Vfc3RhdHVzZXMYAiADKAsyFi5zcGFyay5JbnZvaWNlUmVzcG9uc2VSD2ludm9pY2VTdGF0dXNlcyLlAQoPSW52b2ljZVJlc3BvbnNlEhgKB2ludm9pY2UYASABKAlSB2ludm9pY2USLAoGc3RhdHVzGAIgASgOMhQuc3BhcmsuSW52b2ljZVN0YXR1c1IGc3RhdHVzEjoKDXNhdHNfdHJhbnNmZXIYAyABKAsyEy5zcGFyay5TYXRzVHJhbnNmZXJIAFIMc2F0c1RyYW5zZmVyEj0KDnRva2VuX3RyYW5zZmVyGAQgASgLMhQuc3BhcmsuVG9rZW5UcmFuc2ZlckgAUg10b2tlblRyYW5zZmVyQg8KDXRyYW5zZmVyX3R5cGUiOAoMU2F0c1RyYW5zZmVyEigKC3RyYW5zZmVyX2lkGAEgASgMQgf6QgR6AmgQUgp0cmFuc2ZlcklkIlkKDVRva2VuVHJhbnNmZXISSAocZmluYWxfdG9rZW5fdHJhbnNhY3Rpb25faGFzaBgBIAEoDEIH+kIEegJoIFIZZmluYWxUb2tlblRyYW5zYWN0aW9uSGFzaCKtAQoiSW5pdGlhdGVTd2FwUHJpbWFyeVRyYW5zZmVyUmVxdWVzdBI3Cgh0cmFuc2ZlchgBIAEoCzIbLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXF1ZXN0Ugh0cmFuc2ZlchJOChNhZGFwdG9yX3B1YmxpY19rZXlzGAIgASgLMh4uc3BhcmsuQWRhcHRvclB1YmxpY0tleVBhY2thZ2VSEWFkYXB0b3JQdWJsaWNLZXlzIp0BCiNJbml0aWF0ZVN3YXBQcmltYXJ5VHJhbnNmZXJSZXNwb25zZRIrCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlchJJCg9zaWduaW5nX3Jlc3VsdHMYAiADKAsyIC5zcGFyay5MZWFmUmVmdW5kVHhTaWduaW5nUmVzdWx0Ug5zaWduaW5nUmVzdWx0cyLPAQoXQWRhcHRvclB1YmxpY0tleVBhY2thZ2USLAoSYWRhcHRvcl9wdWJsaWNfa2V5GAEgASgMUhBhZGFwdG9yUHVibGljS2V5EjkKGWRpcmVjdF9hZGFwdG9yX3B1YmxpY19rZXkYAiABKAxSFmRpcmVjdEFkYXB0b3JQdWJsaWNLZXkSSwojZGlyZWN0X2Zyb21fY3BmcF9hZGFwdG9yX3B1YmxpY19rZXkYAyABKAxSHmRpcmVjdEZyb21DcGZwQWRhcHRvclB1YmxpY0tleSLmAQoNV2FsbGV0U2V0dGluZxJCChlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUhZvd25lcklkZW50aXR5UHVibGljS2V5EicKD3ByaXZhdGVfZW5hYmxlZBgCIAEoCFIOcHJpdmF0ZUVuYWJsZWQSSQoabWFzdGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAyABKAxCB/pCBHoCaCFIAFIXbWFzdGVySWRlbnRpdHlQdWJsaWNLZXmIAQFCHQobX21hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5IowCChpVcGRhdGVXYWxsZXRTZXR0aW5nUmVxdWVzdBIsCg9wcml2YXRlX2VuYWJsZWQYASABKAhIAVIOcHJpdmF0ZUVuYWJsZWSIAQESRAoec2V0X21hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMSABSGnNldE1hc3RlcklkZW50aXR5UHVibGljS2V5EkgKIGNsZWFyX21hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAMgASgISABSHGNsZWFyTWFzdGVySWRlbnRpdHlQdWJsaWNLZXlCHAoabWFzdGVyX2lkZW50aXR5X3B1YmxpY19rZXlCEgoQX3ByaXZhdGVfZW5hYmxlZCJaChtVcGRhdGVXYWxsZXRTZXR0aW5nUmVzcG9uc2USOwoOd2FsbGV0X3NldHRpbmcYASABKAsyFC5zcGFyay5XYWxsZXRTZXR0aW5nUg13YWxsZXRTZXR0aW5nIhsKGVF1ZXJ5V2FsbGV0U2V0dGluZ1JlcXVlc3QiWQoaUXVlcnlXYWxsZXRTZXR0aW5nUmVzcG9uc2USOwoOd2FsbGV0X3NldHRpbmcYASABKAsyFC5zcGFyay5XYWxsZXRTZXR0aW5nUg13YWxsZXRTZXR0aW5nKk0KB05ldHdvcmsSDwoLVU5TUEVDSUZJRUQQABILCgdNQUlOTkVUEAESCwoHUkVHVEVTVBACEgsKB1RFU1RORVQQAxIKCgZTSUdORVQQBCojCglEaXJlY3Rpb24SCAoETkVYVBAAEgwKCFBSRVZJT1VTEAEq/AMKDlRyYW5zZmVyU3RhdHVzEiQKIFRSQU5TRkVSX1NUQVRVU19TRU5ERVJfSU5JVElBVEVEEAASLAooVFJBTlNGRVJfU1RBVFVTX1NFTkRFUl9LRVlfVFdFQUtfUEVORElORxABEiYKIlRSQU5TRkVSX1NUQVRVU19TRU5ERVJfS0VZX1RXRUFLRUQQAhIoCiRUUkFOU0ZFUl9TVEFUVVNfUkVDRUlWRVJfS0VZX1RXRUFLRUQQAxIqCiZUUkFOU0ZFUl9TVEFUVVNfUkVDRUlWRVJfUkVGVU5EX1NJR05FRBAEEh0KGVRSQU5TRkVSX1NUQVRVU19DT01QTEVURUQQBRIbChdUUkFOU0ZFUl9TVEFUVVNfRVhQSVJFRBAGEhwKGFRSQU5TRkVSX1NUQVRVU19SRVRVUk5FRBAHEjAKLFRSQU5TRkVSX1NUQVRVU19TRU5ERVJfSU5JVElBVEVEX0NPT1JESU5BVE9SEAgSLQopVFJBTlNGRVJfU1RBVFVTX1JFQ0VJVkVSX0tFWV9UV0VBS19MT0NLRUQQCRIuCipUUkFOU0ZFUl9TVEFUVVNfUkVDRUlWRVJfS0VZX1RXRUFLX0FQUExJRUQQChItCilUUkFOU0ZFUl9TVEFUVVNfQVBQTFlJTkdfU0VOREVSX0tFWV9UV0VBSxALKpoBCgxUcmFuc2ZlclR5cGUSEQoNUFJFSU1BR0VfU1dBUBAAEhQKEENPT1BFUkFUSVZFX0VYSVQQARIMCghUUkFOU0ZFUhACEg0KCVVUWE9fU1dBUBADEggKBFNXQVAQHhIQCgxDT1VOVEVSX1NXQVAQKBITCg9QUklNQVJZX1NXQVBfVjMQBBITCg9DT1VOVEVSX1NXQVBfVjMQBSomCgVPcmRlchIOCgpERVNDRU5ESU5HEAASDQoJQVNDRU5ESU5HEAEqnAEKFVByZWltYWdlUmVxdWVzdFN0YXR1cxIwCixQUkVJTUFHRV9SRVFVRVNUX1NUQVRVU19XQUlUSU5HX0ZPUl9QUkVJTUFHRRAAEisKJ1BSRUlNQUdFX1JFUVVFU1RfU1RBVFVTX1BSRUlNQUdFX1NIQVJFRBABEiQKIFBSRUlNQUdFX1JFUVVFU1RfU1RBVFVTX1JFVFVSTkVEEAIqigEKE1ByZWltYWdlUmVxdWVzdFJvbGUSIgoeUFJFSU1BR0VfUkVRVUVTVF9ST0xFX1JFQ0VJVkVSEAASIAocUFJFSU1BR0VfUkVRVUVTVF9ST0xFX1NFTkRFUhABEi0KKVBSRUlNQUdFX1JFUVVFU1RfUk9MRV9SRUNFSVZFUl9BTkRfU0VOREVSEAIqRQoTVXR4b1N3YXBSZXF1ZXN0VHlwZRIJCgVGaXhlZBAAEgoKBk1heEZlZRABEgoKBlJlZnVuZBACEgsKB0luc3RhbnQQAypACgtIYXNoVmFyaWFudBIcChhIQVNIX1ZBUklBTlRfVU5TUEVDSUZJRUQQABITCg9IQVNIX1ZBUklBTlRfVjIQASpOCg1JbnZvaWNlU3RhdHVzEg0KCU5PVF9GT1VORBAAEgsKB1BFTkRJTkcQARINCglGSU5BTElaRUQQAhIMCghSRVRVUk5FRBAEIgQIAxADKoMDCg5UcmVlTm9kZVN0YXR1cxIdChlUUkVFX05PREVfU1RBVFVTX0NSRUFUSU5HEAASHgoaVFJFRV9OT0RFX1NUQVRVU19BVkFJTEFCTEUQARIlCiFUUkVFX05PREVfU1RBVFVTX0ZST1pFTl9CWV9JU1NVRVIQAhIkCiBUUkVFX05PREVfU1RBVFVTX1RSQU5TRkVSX0xPQ0tFRBADEiEKHVRSRUVfTk9ERV9TVEFUVVNfU1BMSVRfTE9DS0VEEAQSHQoZVFJFRV9OT0RFX1NUQVRVU19TUExJVFRFRBAFEh8KG1RSRUVfTk9ERV9TVEFUVVNfQUdHUkVHQVRFRBAGEh0KGVRSRUVfTk9ERV9TVEFUVVNfT05fQ0hBSU4QBxIjCh9UUkVFX05PREVfU1RBVFVTX0FHR1JFR0FURV9MT0NLEAgSGwoXVFJFRV9OT0RFX1NUQVRVU19FWElURUQQCRIhCh1UUkVFX05PREVfU1RBVFVTX1JFTkVXX0xPQ0tFRBAKMokcCgxTcGFya1NlcnZpY2USaQoYZ2VuZXJhdGVfZGVwb3NpdF9hZGRyZXNzEiQuc3BhcmsuR2VuZXJhdGVEZXBvc2l0QWRkcmVzc1JlcXVlc3QaJS5zcGFyay5HZW5lcmF0ZURlcG9zaXRBZGRyZXNzUmVzcG9uc2UiABJ8Ch9nZW5lcmF0ZV9zdGF0aWNfZGVwb3NpdF9hZGRyZXNzEiouc3BhcmsuR2VuZXJhdGVTdGF0aWNEZXBvc2l0QWRkcmVzc1JlcXVlc3QaKy5zcGFyay5HZW5lcmF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVzcG9uc2UiABJ2Ch1yb3RhdGVfc3RhdGljX2RlcG9zaXRfYWRkcmVzcxIoLnNwYXJrLlJvdGF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVxdWVzdBopLnNwYXJrLlJvdGF0ZVN0YXRpY0RlcG9zaXRBZGRyZXNzUmVzcG9uc2UiABJwChtzdGFydF9kZXBvc2l0X3RyZWVfY3JlYXRpb24SJi5zcGFyay5TdGFydERlcG9zaXRUcmVlQ3JlYXRpb25SZXF1ZXN0Gicuc3BhcmsuU3RhcnREZXBvc2l0VHJlZUNyZWF0aW9uUmVzcG9uc2UiABJ5Ch5maW5hbGl6ZV9kZXBvc2l0X3RyZWVfY3JlYXRpb24SKS5zcGFyay5GaW5hbGl6ZURlcG9zaXRUcmVlQ3JlYXRpb25SZXF1ZXN0Giouc3BhcmsuRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVzcG9uc2UiABJ/CidmaW5hbGl6ZV90cmFuc2Zlcl93aXRoX3RyYW5zZmVyX3BhY2thZ2USMS5zcGFyay5GaW5hbGl6ZVRyYW5zZmVyV2l0aFRyYW5zZmVyUGFja2FnZVJlcXVlc3QaHy5zcGFyay5GaW5hbGl6ZVRyYW5zZmVyUmVzcG9uc2UiABJRChdxdWVyeV9wZW5kaW5nX3RyYW5zZmVycxIVLnNwYXJrLlRyYW5zZmVyRmlsdGVyGh0uc3BhcmsuUXVlcnlUcmFuc2ZlcnNSZXNwb25zZSIAEk0KE3F1ZXJ5X2FsbF90cmFuc2ZlcnMSFS5zcGFyay5UcmFuc2ZlckZpbHRlchodLnNwYXJrLlF1ZXJ5VHJhbnNmZXJzUmVzcG9uc2UiABJbChljbGFpbV90cmFuc2Zlcl90d2Vha19rZXlzEiQuc3BhcmsuQ2xhaW1UcmFuc2ZlclR3ZWFrS2V5c1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABJSChRzdG9yZV9wcmVpbWFnZV9zaGFyZRIgLnNwYXJrLlN0b3JlUHJlaW1hZ2VTaGFyZVJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABJmChdnZXRfc2lnbmluZ19jb21taXRtZW50cxIjLnNwYXJrLkdldFNpZ25pbmdDb21taXRtZW50c1JlcXVlc3QaJC5zcGFyay5HZXRTaWduaW5nQ29tbWl0bWVudHNSZXNwb25zZSIAElMKEHByb3ZpZGVfcHJlaW1hZ2USHS5zcGFyay5Qcm92aWRlUHJlaW1hZ2VSZXF1ZXN0Gh4uc3BhcmsuUHJvdmlkZVByZWltYWdlUmVzcG9uc2UiABJNCg5xdWVyeV9wcmVpbWFnZRIbLnNwYXJrLlF1ZXJ5UHJlaW1hZ2VSZXF1ZXN0Ghwuc3BhcmsuUXVlcnlQcmVpbWFnZVJlc3BvbnNlIgASQQoKcXVlcnlfaHRsYxIXLnNwYXJrLlF1ZXJ5SHRsY1JlcXVlc3QaGC5zcGFyay5RdWVyeUh0bGNSZXNwb25zZSIAEkEKCnJlbmV3X2xlYWYSFy5zcGFyay5SZW5ld0xlYWZSZXF1ZXN0Ghguc3BhcmsuUmVuZXdMZWFmUmVzcG9uc2UiABJcChlnZXRfc2lnbmluZ19vcGVyYXRvcl9saXN0EhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5GiUuc3BhcmsuR2V0U2lnbmluZ09wZXJhdG9yTGlzdFJlc3BvbnNlIgASRAoLcXVlcnlfbm9kZXMSGC5zcGFyay5RdWVyeU5vZGVzUmVxdWVzdBoZLnNwYXJrLlF1ZXJ5Tm9kZXNSZXNwb25zZSIAEkoKDXF1ZXJ5X2JhbGFuY2USGi5zcGFyay5RdWVyeUJhbGFuY2VSZXF1ZXN0Ghsuc3BhcmsuUXVlcnlCYWxhbmNlUmVzcG9uc2UiABJqChlxdWVyeV91c2VyX3NpZ25lZF9yZWZ1bmRzEiQuc3BhcmsuUXVlcnlVc2VyU2lnbmVkUmVmdW5kc1JlcXVlc3QaJS5zcGFyay5RdWVyeVVzZXJTaWduZWRSZWZ1bmRzUmVzcG9uc2UiABJ5Ch5xdWVyeV91bnVzZWRfZGVwb3NpdF9hZGRyZXNzZXMSKS5zcGFyay5RdWVyeVVudXNlZERlcG9zaXRBZGRyZXNzZXNSZXF1ZXN0Giouc3BhcmsuUXVlcnlVbnVzZWREZXBvc2l0QWRkcmVzc2VzUmVzcG9uc2UiABJ5Ch5xdWVyeV9zdGF0aWNfZGVwb3NpdF9hZGRyZXNzZXMSKS5zcGFyay5RdWVyeVN0YXRpY0RlcG9zaXRBZGRyZXNzZXNSZXF1ZXN0Giouc3BhcmsuUXVlcnlTdGF0aWNEZXBvc2l0QWRkcmVzc2VzUmVzcG9uc2UiABJcChNzdWJzY3JpYmVfdG9fZXZlbnRzEh8uc3BhcmsuU3Vic2NyaWJlVG9FdmVudHNSZXF1ZXN0GiAuc3BhcmsuU3Vic2NyaWJlVG9FdmVudHNSZXNwb25zZSIAMAEShgEKI2luaXRpYXRlX3N0YXRpY19kZXBvc2l0X3V0eG9fcmVmdW5kEi0uc3BhcmsuSW5pdGlhdGVTdGF0aWNEZXBvc2l0VXR4b1JlZnVuZFJlcXVlc3QaLi5zcGFyay5Jbml0aWF0ZVN0YXRpY0RlcG9zaXRVdHhvUmVmdW5kUmVzcG9uc2UiABJhChZleGl0X3NpbmdsZV9ub2RlX3RyZWVzEiEuc3BhcmsuRXhpdFNpbmdsZU5vZGVUcmVlc1JlcXVlc3QaIi5zcGFyay5FeGl0U2luZ2xlTm9kZVRyZWVzUmVzcG9uc2UiABJWChNjb29wZXJhdGl2ZV9leGl0X3YyEh0uc3BhcmsuQ29vcGVyYXRpdmVFeGl0UmVxdWVzdBoeLnNwYXJrLkNvb3BlcmF0aXZlRXhpdFJlc3BvbnNlIgAScwoeY2xhaW1fdHJhbnNmZXJfc2lnbl9yZWZ1bmRzX3YyEiYuc3BhcmsuQ2xhaW1UcmFuc2ZlclNpZ25SZWZ1bmRzUmVxdWVzdBonLnNwYXJrLkNsYWltVHJhbnNmZXJTaWduUmVmdW5kc1Jlc3BvbnNlIgASbAobZmluYWxpemVfbm9kZV9zaWduYXR1cmVzX3YyEiQuc3BhcmsuRmluYWxpemVOb2RlU2lnbmF0dXJlc1JlcXVlc3QaJS5zcGFyay5GaW5hbGl6ZU5vZGVTaWduYXR1cmVzUmVzcG9uc2UiABJmChlpbml0aWF0ZV9wcmVpbWFnZV9zd2FwX3YyEiIuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXF1ZXN0GiMuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXNwb25zZSIAEmYKGWluaXRpYXRlX3ByZWltYWdlX3N3YXBfdjMSIi5zcGFyay5Jbml0aWF0ZVByZWltYWdlU3dhcFJlcXVlc3QaIy5zcGFyay5Jbml0aWF0ZVByZWltYWdlU3dhcFJlc3BvbnNlIgASUQoSc3RhcnRfbGVhZl9zd2FwX3YyEhsuc3BhcmsuU3RhcnRUcmFuc2ZlclJlcXVlc3QaHC5zcGFyay5TdGFydFRyYW5zZmVyUmVzcG9uc2UiABJQChFzdGFydF90cmFuc2Zlcl92MhIbLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXF1ZXN0Ghwuc3BhcmsuU3RhcnRUcmFuc2ZlclJlc3BvbnNlIgASXgoVZ2V0X3V0eG9zX2Zvcl9hZGRyZXNzEiAuc3BhcmsuR2V0VXR4b3NGb3JBZGRyZXNzUmVxdWVzdBohLnNwYXJrLkdldFV0eG9zRm9yQWRkcmVzc1Jlc3BvbnNlIgASXQoUcXVlcnlfc3BhcmtfaW52b2ljZXMSIC5zcGFyay5RdWVyeVNwYXJrSW52b2ljZXNSZXF1ZXN0GiEuc3BhcmsuUXVlcnlTcGFya0ludm9pY2VzUmVzcG9uc2UiABJ5Ch5pbml0aWF0ZV9zd2FwX3ByaW1hcnlfdHJhbnNmZXISKS5zcGFyay5Jbml0aWF0ZVN3YXBQcmltYXJ5VHJhbnNmZXJSZXF1ZXN0Giouc3BhcmsuSW5pdGlhdGVTd2FwUHJpbWFyeVRyYW5zZmVyUmVzcG9uc2UiABJgChV1cGRhdGVfd2FsbGV0X3NldHRpbmcSIS5zcGFyay5VcGRhdGVXYWxsZXRTZXR0aW5nUmVxdWVzdBoiLnNwYXJrLlVwZGF0ZVdhbGxldFNldHRpbmdSZXNwb25zZSIAEl0KFHF1ZXJ5X3dhbGxldF9zZXR0aW5nEiAuc3BhcmsuUXVlcnlXYWxsZXRTZXR0aW5nUmVxdWVzdBohLnNwYXJrLlF1ZXJ5V2FsbGV0U2V0dGluZ1Jlc3BvbnNlIgBCLFoqZ2l0aHViLmNvbS9saWdodHNwYXJrZGV2L3NwYXJrL3Byb3RvL3NwYXJrYgZwcm90bzMKmGAKEXNwYXJrX3Rva2VuLnByb3RvEgtzcGFya190b2tlbhofZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90bxoLc3BhcmsucHJvdG8aF3ZhbGlkYXRlL3ZhbGlkYXRlLnByb3RvIpsBChJUb2tlbk91dHB1dFRvU3BlbmQSRgobcHJldl90b2tlbl90cmFuc2FjdGlvbl9oYXNoGAEgASgMQgf6QgR6AmggUhhwcmV2VG9rZW5UcmFuc2FjdGlvbkhhc2gSPQobcHJldl90b2tlbl90cmFuc2FjdGlvbl92b3V0GAIgASgNUhhwcmV2VG9rZW5UcmFuc2FjdGlvblZvdXQiXwoSVG9rZW5UcmFuc2ZlcklucHV0EkkKEG91dHB1dHNfdG9fc3BlbmQYASADKAsyHy5zcGFya190b2tlbi5Ub2tlbk91dHB1dFRvU3BlbmRSDm91dHB1dHNUb1NwZW5kIpMBCg5Ub2tlbk1pbnRJbnB1dBIzChFpc3N1ZXJfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIPaXNzdWVyUHVibGljS2V5EjcKEHRva2VuX2lkZW50aWZpZXIYAiABKAxCB/pCBHoCaCBIAFIPdG9rZW5JZGVudGlmaWVyiAEBQhMKEV90b2tlbl9pZGVudGlmaWVyIr8DChBUb2tlbkNyZWF0ZUlucHV0EjMKEWlzc3Vlcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg9pc3N1ZXJQdWJsaWNLZXkSJgoKdG9rZW5fbmFtZRgCIAEoCUIH+kIEcgIYFFIJdG9rZW5OYW1lEioKDHRva2VuX3RpY2tlchgDIAEoCUIH+kIEcgIYBlILdG9rZW5UaWNrZXISJAoIZGVjaW1hbHMYBCABKA1CCPpCBSoDGP8BUghkZWNpbWFscxImCgptYXhfc3VwcGx5GAUgASgMQgf6QgR6AmgQUgltYXhTdXBwbHkSIQoMaXNfZnJlZXphYmxlGAYgASgIUgtpc0ZyZWV6YWJsZRJJChpjcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleRgHIAEoDEIH+kIEegJoIUgAUhdjcmVhdGlvbkVudGl0eVB1YmxpY0tleYgBARI0Cg5leHRyYV9tZXRhZGF0YRgIIAEoDEII+kIFegMYgAhIAVINZXh0cmFNZXRhZGF0YYgBAUIdChtfY3JlYXRpb25fZW50aXR5X3B1YmxpY19rZXlCEQoPX2V4dHJhX21ldGFkYXRhIugFCgtUb2tlbk91dHB1dBIdCgJpZBgBIAEoCUII+kIFcgOwAQFIAFICaWSIAQESMQoQb3duZXJfcHVibGljX2tleRgCIAEoDEIH+kIEegJoIVIOb3duZXJQdWJsaWNLZXkSQQoVcmV2b2NhdGlvbl9jb21taXRtZW50GAMgASgMQgf6QgR6AmghSAFSFHJldm9jYXRpb25Db21taXRtZW50iAEBEjEKEndpdGhkcmF3X2JvbmRfc2F0cxgEIAEoBEgCUhB3aXRoZHJhd0JvbmRTYXRziAEBEkwKIHdpdGhkcmF3X3JlbGF0aXZlX2Jsb2NrX2xvY2t0aW1lGAUgASgESANSHXdpdGhkcmF3UmVsYXRpdmVCbG9ja0xvY2t0aW1liAEBEjYKEHRva2VuX3B1YmxpY19rZXkYBiABKAxCB/pCBHoCaCFIBFIOdG9rZW5QdWJsaWNLZXmIAQESNwoQdG9rZW5faWRlbnRpZmllchgIIAEoDEIH+kIEegJoIEgFUg90b2tlbklkZW50aWZpZXKIAQESKgoMdG9rZW5fYW1vdW50GAcgASgMQgf6QgR6AmgQUgt0b2tlbkFtb3VudBI7ChdzZV93aXRoZHJhd2FsX3NpZ25hdHVyZRgJIAEoDEgGUhVzZVdpdGhkcmF3YWxTaWduYXR1cmWIAQESOwoGc3RhdHVzGAogASgOMh4uc3BhcmtfdG9rZW4uVG9rZW5PdXRwdXRTdGF0dXNIB1IGc3RhdHVziAEBQgUKA19pZEIYChZfcmV2b2NhdGlvbl9jb21taXRtZW50QhUKE193aXRoZHJhd19ib25kX3NhdHNCIwohX3dpdGhkcmF3X3JlbGF0aXZlX2Jsb2NrX2xvY2t0aW1lQhMKEV90b2tlbl9wdWJsaWNfa2V5QhMKEV90b2tlbl9pZGVudGlmaWVyQhoKGF9zZV93aXRoZHJhd2FsX3NpZ25hdHVyZUIJCgdfc3RhdHVzIp4CChJQYXJ0aWFsVG9rZW5PdXRwdXQSMQoQb3duZXJfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIOb3duZXJQdWJsaWNLZXkSLAoSd2l0aGRyYXdfYm9uZF9zYXRzGAIgASgEUhB3aXRoZHJhd0JvbmRTYXRzEkcKIHdpdGhkcmF3X3JlbGF0aXZlX2Jsb2NrX2xvY2t0aW1lGAMgASgEUh13aXRoZHJhd1JlbGF0aXZlQmxvY2tMb2NrdGltZRIyChB0b2tlbl9pZGVudGlmaWVyGAQgASgMQgf6QgR6AmggUg90b2tlbklkZW50aWZpZXISKgoMdG9rZW5fYW1vdW50GAUgASgMQgf6QgR6AmgQUgt0b2tlbkFtb3VudCKjAQoQRmluYWxUb2tlbk91dHB1dBJRChRwYXJ0aWFsX3Rva2VuX291dHB1dBgBIAEoCzIfLnNwYXJrX3Rva2VuLlBhcnRpYWxUb2tlbk91dHB1dFIScGFydGlhbFRva2VuT3V0cHV0EjwKFXJldm9jYXRpb25fY29tbWl0bWVudBgCIAEoDEIH+kIEegJoIVIUcmV2b2NhdGlvbkNvbW1pdG1lbnQimgYKEFRva2VuVHJhbnNhY3Rpb24SGAoHdmVyc2lvbhgBIAEoDVIHdmVyc2lvbhI8CgptaW50X2lucHV0GAIgASgLMhsuc3BhcmtfdG9rZW4uVG9rZW5NaW50SW5wdXRIAFIJbWludElucHV0EkgKDnRyYW5zZmVyX2lucHV0GAMgASgLMh8uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2ZlcklucHV0SABSDXRyYW5zZmVySW5wdXQSQgoMY3JlYXRlX2lucHV0GAggASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5DcmVhdGVJbnB1dEgAUgtjcmVhdGVJbnB1dBI9Cg10b2tlbl9vdXRwdXRzGAQgAygLMhguc3BhcmtfdG9rZW4uVG9rZW5PdXRwdXRSDHRva2VuT3V0cHV0cxJaCiNzcGFya19vcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5cxgFIAMoDEIM+kIJkgEGIgR6AmghUh9zcGFya09wZXJhdG9ySWRlbnRpdHlQdWJsaWNLZXlzEjsKC2V4cGlyeV90aW1lGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFIKZXhwaXJ5VGltZRIyCgduZXR3b3JrGAcgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIABSB25ldHdvcmsSVAoYY2xpZW50X2NyZWF0ZWRfdGltZXN0YW1wGAkgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFIWY2xpZW50Q3JlYXRlZFRpbWVzdGFtcBJPChNpbnZvaWNlX2F0dGFjaG1lbnRzGAogAygLMh4uc3BhcmtfdG9rZW4uSW52b2ljZUF0dGFjaG1lbnRSEmludm9pY2VBdHRhY2htZW50cxI/Chl2YWxpZGl0eV9kdXJhdGlvbl9zZWNvbmRzGAsgASgESAFSF3ZhbGlkaXR5RHVyYXRpb25TZWNvbmRziAEBQg4KDHRva2VuX2lucHV0c0IcChpfdmFsaWRpdHlfZHVyYXRpb25fc2Vjb25kcyKZAwoYVG9rZW5UcmFuc2FjdGlvbk1ldGFkYXRhEloKI3NwYXJrX29wZXJhdG9yX2lkZW50aXR5X3B1YmxpY19rZXlzGAIgAygMQgz6QgmSAQYiBHoCaCFSH3NwYXJrT3BlcmF0b3JJZGVudGl0eVB1YmxpY0tleXMSMgoHbmV0d29yaxgDIAEoDjIOLnNwYXJrLk5ldHdvcmtCCPpCBYIBAiAAUgduZXR3b3JrElQKGGNsaWVudF9jcmVhdGVkX3RpbWVzdGFtcBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSFmNsaWVudENyZWF0ZWRUaW1lc3RhbXASRgoZdmFsaWRpdHlfZHVyYXRpb25fc2Vjb25kcxgFIAEoBEIK+kIHMgUYrAIoAVIXdmFsaWRpdHlEdXJhdGlvblNlY29uZHMSTwoTaW52b2ljZV9hdHRhY2htZW50cxgGIAMoCzIeLnNwYXJrX3Rva2VuLkludm9pY2VBdHRhY2htZW50UhJpbnZvaWNlQXR0YWNobWVudHMiyQMKF1BhcnRpYWxUb2tlblRyYW5zYWN0aW9uEhgKB3ZlcnNpb24YASABKA1SB3ZlcnNpb24SYwoadG9rZW5fdHJhbnNhY3Rpb25fbWV0YWRhdGEYAiABKAsyJS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uTWV0YWRhdGFSGHRva2VuVHJhbnNhY3Rpb25NZXRhZGF0YRI8CgptaW50X2lucHV0GAMgASgLMhsuc3BhcmtfdG9rZW4uVG9rZW5NaW50SW5wdXRIAFIJbWludElucHV0EkgKDnRyYW5zZmVyX2lucHV0GAQgASgLMh8uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2ZlcklucHV0SABSDXRyYW5zZmVySW5wdXQSQgoMY3JlYXRlX2lucHV0GAUgASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5DcmVhdGVJbnB1dEgAUgtjcmVhdGVJbnB1dBJTChVwYXJ0aWFsX3Rva2VuX291dHB1dHMYBiADKAsyHy5zcGFya190b2tlbi5QYXJ0aWFsVG9rZW5PdXRwdXRSE3BhcnRpYWxUb2tlbk91dHB1dHNCDgoMdG9rZW5faW5wdXRzIsEDChVGaW5hbFRva2VuVHJhbnNhY3Rpb24SGAoHdmVyc2lvbhgBIAEoDVIHdmVyc2lvbhJjChp0b2tlbl90cmFuc2FjdGlvbl9tZXRhZGF0YRgCIAEoCzIlLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25NZXRhZGF0YVIYdG9rZW5UcmFuc2FjdGlvbk1ldGFkYXRhEjwKCm1pbnRfaW5wdXQYAyABKAsyGy5zcGFya190b2tlbi5Ub2tlbk1pbnRJbnB1dEgAUgltaW50SW5wdXQSSAoOdHJhbnNmZXJfaW5wdXQYBCABKAsyHy5zcGFya190b2tlbi5Ub2tlblRyYW5zZmVySW5wdXRIAFINdHJhbnNmZXJJbnB1dBJCCgxjcmVhdGVfaW5wdXQYBSABKAsyHS5zcGFya190b2tlbi5Ub2tlbkNyZWF0ZUlucHV0SABSC2NyZWF0ZUlucHV0Ek0KE2ZpbmFsX3Rva2VuX291dHB1dHMYBiADKAsyHS5zcGFya190b2tlbi5GaW5hbFRva2VuT3V0cHV0UhFmaW5hbFRva2VuT3V0cHV0c0IOCgx0b2tlbl9pbnB1dHMiOAoRSW52b2ljZUF0dGFjaG1lbnQSIwoNc3BhcmtfaW52b2ljZRgBIAEoCVIMc3BhcmtJbnZvaWNlIl4KElNpZ25hdHVyZVdpdGhJbmRleBInCglzaWduYXR1cmUYASABKAxCCfpCBnoEEEAYSVIJc2lnbmF0dXJlEh8KC2lucHV0X2luZGV4GAIgASgNUgppbnB1dEluZGV4IrQBCh5JbnB1dFR0eG9TaWduYXR1cmVzUGVyT3BlcmF0b3ISSAoPdHR4b19zaWduYXR1cmVzGAEgAygLMh8uc3BhcmtfdG9rZW4uU2lnbmF0dXJlV2l0aEluZGV4Ug50dHhvU2lnbmF0dXJlcxJIChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUhlvcGVyYXRvcklkZW50aXR5UHVibGljS2V5IvICChdTdGFydFRyYW5zYWN0aW9uUmVxdWVzdBI3ChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUhFpZGVudGl0eVB1YmxpY0tleRJZChlwYXJ0aWFsX3Rva2VuX3RyYW5zYWN0aW9uGAIgASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvblIXcGFydGlhbFRva2VuVHJhbnNhY3Rpb24SewoqcGFydGlhbF90b2tlbl90cmFuc2FjdGlvbl9vd25lcl9zaWduYXR1cmVzGAMgAygLMh8uc3BhcmtfdG9rZW4uU2lnbmF0dXJlV2l0aEluZGV4UiZwYXJ0aWFsVG9rZW5UcmFuc2FjdGlvbk93bmVyU2lnbmF0dXJlcxJGChl2YWxpZGl0eV9kdXJhdGlvbl9zZWNvbmRzGAQgASgEQgr6QgcyBRisAigBUhd2YWxpZGl0eUR1cmF0aW9uU2Vjb25kcyKuAQoYU3RhcnRUcmFuc2FjdGlvblJlc3BvbnNlElUKF2ZpbmFsX3Rva2VuX3RyYW5zYWN0aW9uGAEgASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvblIVZmluYWxUb2tlblRyYW5zYWN0aW9uEjsKDWtleXNoYXJlX2luZm8YAiABKAsyFi5zcGFyay5TaWduaW5nS2V5c2hhcmVSDGtleXNoYXJlSW5mbyL4AgoYQ29tbWl0VHJhbnNhY3Rpb25SZXF1ZXN0ElUKF2ZpbmFsX3Rva2VuX3RyYW5zYWN0aW9uGAEgASgLMh0uc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvblIVZmluYWxUb2tlblRyYW5zYWN0aW9uEkgKHGZpbmFsX3Rva2VuX3RyYW5zYWN0aW9uX2hhc2gYAiABKAxCB/pCBHoCaCBSGWZpbmFsVG9rZW5UcmFuc2FjdGlvbkhhc2gSdwoiaW5wdXRfdHR4b19zaWduYXR1cmVzX3Blcl9vcGVyYXRvchgDIAMoCzIrLnNwYXJrX3Rva2VuLklucHV0VHR4b1NpZ25hdHVyZXNQZXJPcGVyYXRvclIeaW5wdXRUdHhvU2lnbmF0dXJlc1Blck9wZXJhdG9yEkIKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYBCABKAxCB/pCBHoCaCFSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkiugEKDkNvbW1pdFByb2dyZXNzElEKHmNvbW1pdHRlZF9vcGVyYXRvcl9wdWJsaWNfa2V5cxgBIAMoDEIM+kIJkgEGIgR6AmghUhtjb21taXR0ZWRPcGVyYXRvclB1YmxpY0tleXMSVQogdW5jb21taXR0ZWRfb3BlcmF0b3JfcHVibGljX2tleXMYAiADKAxCDPpCCZIBBiIEegJoIVIddW5jb21taXR0ZWRPcGVyYXRvclB1YmxpY0tleXMi7wEKGUNvbW1pdFRyYW5zYWN0aW9uUmVzcG9uc2USPgoNY29tbWl0X3N0YXR1cxgBIAEoDjIZLnNwYXJrX3Rva2VuLkNvbW1pdFN0YXR1c1IMY29tbWl0U3RhdHVzEkQKD2NvbW1pdF9wcm9ncmVzcxgCIAEoCzIbLnNwYXJrX3Rva2VuLkNvbW1pdFByb2dyZXNzUg5jb21taXRQcm9ncmVzcxI3ChB0b2tlbl9pZGVudGlmaWVyGAMgASgMQgf6QgR6AmggSABSD3Rva2VuSWRlbnRpZmllcogBAUITChFfdG9rZW5faWRlbnRpZmllciKmAgobQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXF1ZXN0EjcKE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCFSEWlkZW50aXR5UHVibGljS2V5EmAKGXBhcnRpYWxfdG9rZW5fdHJhbnNhY3Rpb24YAiABKAsyJC5zcGFya190b2tlbi5QYXJ0aWFsVG9rZW5UcmFuc2FjdGlvblIXcGFydGlhbFRva2VuVHJhbnNhY3Rpb24SbAoidG9rZW5fdHJhbnNhY3Rpb25fb3duZXJfc2lnbmF0dXJlcxgDIAMoCzIfLnNwYXJrX3Rva2VuLlNpZ25hdHVyZVdpdGhJbmRleFIfdG9rZW5UcmFuc2FjdGlvbk93bmVyU2lnbmF0dXJlcyLOAgocQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXNwb25zZRJaChdmaW5hbF90b2tlbl90cmFuc2FjdGlvbhgBIAEoCzIiLnNwYXJrX3Rva2VuLkZpbmFsVG9rZW5UcmFuc2FjdGlvblIVZmluYWxUb2tlblRyYW5zYWN0aW9uEj4KDWNvbW1pdF9zdGF0dXMYAiABKA4yGS5zcGFya190b2tlbi5Db21taXRTdGF0dXNSDGNvbW1pdFN0YXR1cxJECg9jb21taXRfcHJvZ3Jlc3MYAyABKAsyGy5zcGFya190b2tlbi5Db21taXRQcm9ncmVzc1IOY29tbWl0UHJvZ3Jlc3MSNwoQdG9rZW5faWRlbnRpZmllchgEIAEoDEIH+kIEegJoIEgAUg90b2tlbklkZW50aWZpZXKIAQFCEwoRX3Rva2VuX2lkZW50aWZpZXIikgEKGVF1ZXJ5VG9rZW5NZXRhZGF0YVJlcXVlc3QSOQoRdG9rZW5faWRlbnRpZmllcnMYASADKAxCDPpCCZIBBiIEegJoIFIQdG9rZW5JZGVudGlmaWVycxI6ChJpc3N1ZXJfcHVibGljX2tleXMYAiADKAxCDPpCCZIBBiIEegJoIVIQaXNzdWVyUHVibGljS2V5cyLwAwoNVG9rZW5NZXRhZGF0YRIzChFpc3N1ZXJfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIPaXNzdWVyUHVibGljS2V5EiYKCnRva2VuX25hbWUYAiABKAlCB/pCBHICGBRSCXRva2VuTmFtZRIqCgx0b2tlbl90aWNrZXIYAyABKAlCB/pCBHICGAZSC3Rva2VuVGlja2VyEiQKCGRlY2ltYWxzGAQgASgNQgj6QgUqAxj/AVIIZGVjaW1hbHMSJgoKbWF4X3N1cHBseRgFIAEoDEIH+kIEegJoEFIJbWF4U3VwcGx5EiEKDGlzX2ZyZWV6YWJsZRgGIAEoCFILaXNGcmVlemFibGUSSQoaY3JlYXRpb25fZW50aXR5X3B1YmxpY19rZXkYByABKAxCB/pCBHoCaCFIAFIXY3JlYXRpb25FbnRpdHlQdWJsaWNLZXmIAQESMgoQdG9rZW5faWRlbnRpZmllchgIIAEoDEIH+kIEegJoIFIPdG9rZW5JZGVudGlmaWVyEjQKDmV4dHJhX21ldGFkYXRhGAkgASgMQgj6QgV6AxiACEgBUg1leHRyYU1ldGFkYXRhiAEBQh0KG19jcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleUIRCg9fZXh0cmFfbWV0YWRhdGEiXwoaUXVlcnlUb2tlbk1ldGFkYXRhUmVzcG9uc2USQQoOdG9rZW5fbWV0YWRhdGEYASADKAsyGi5zcGFya190b2tlbi5Ub2tlbk1ldGFkYXRhUg10b2tlbk1ldGFkYXRhIqwCChhRdWVyeVRva2VuT3V0cHV0c1JlcXVlc3QSOAoRb3duZXJfcHVibGljX2tleXMYASADKAxCDPpCCZIBBiIEegJoIVIPb3duZXJQdWJsaWNLZXlzEjoKEmlzc3Vlcl9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghUhBpc3N1ZXJQdWJsaWNLZXlzEjkKEXRva2VuX2lkZW50aWZpZXJzGAQgAygMQgz6QgmSAQYiBHoCaCBSEHRva2VuSWRlbnRpZmllcnMSKAoHbmV0d29yaxgDIAEoDjIOLnNwYXJrLk5ldHdvcmtSB25ldHdvcmsSNQoMcGFnZV9yZXF1ZXN0GAUgASgLMhIuc3BhcmsuUGFnZVJlcXVlc3RSC3BhZ2VSZXF1ZXN0ItcECh1RdWVyeVRva2VuVHJhbnNhY3Rpb25zUmVxdWVzdBJLCgpieV90eF9oYXNoGAkgASgLMisuc3BhcmtfdG9rZW4uUXVlcnlUb2tlblRyYW5zYWN0aW9uc0J5VHhIYXNoSABSCGJ5VHhIYXNoEk0KCmJ5X2ZpbHRlcnMYCiABKAsyLC5zcGFya190b2tlbi5RdWVyeVRva2VuVHJhbnNhY3Rpb25zQnlGaWx0ZXJzSABSCWJ5RmlsdGVycxIsCgpvdXRwdXRfaWRzGAEgAygJQg36QgqSAQciBXIDsAEBUglvdXRwdXRJZHMSOAoRb3duZXJfcHVibGljX2tleXMYAiADKAxCDPpCCZIBBiIEegJoIVIPb3duZXJQdWJsaWNLZXlzEjoKEmlzc3Vlcl9wdWJsaWNfa2V5cxgDIAMoDEIM+kIJkgEGIgR6AmghUhBpc3N1ZXJQdWJsaWNLZXlzEjkKEXRva2VuX2lkZW50aWZpZXJzGAcgAygMQgz6QgmSAQYiBHoCaCBSEHRva2VuSWRlbnRpZmllcnMSRgoYdG9rZW5fdHJhbnNhY3Rpb25faGFzaGVzGAQgAygMQgz6QgmSAQYiBHoCaCBSFnRva2VuVHJhbnNhY3Rpb25IYXNoZXMSIgoFb3JkZXIYCCABKA4yDC5zcGFyay5PcmRlclIFb3JkZXISIAoFbGltaXQYBSABKANCCvpCByIFGOgHKABSBWxpbWl0Eh8KBm9mZnNldBgGIAEoA0IH+kIEIgIoAFIGb2Zmc2V0QgwKCnF1ZXJ5X3R5cGUiagoeUXVlcnlUb2tlblRyYW5zYWN0aW9uc0J5VHhIYXNoEkgKGHRva2VuX3RyYW5zYWN0aW9uX2hhc2hlcxgBIAMoDEIO+kILkgEICAEiBHoCaCBSFnRva2VuVHJhbnNhY3Rpb25IYXNoZXMitwIKH1F1ZXJ5VG9rZW5UcmFuc2FjdGlvbnNCeUZpbHRlcnMSLAoKb3V0cHV0X2lkcxgBIAMoCUIN+kIKkgEHIgVyA7ABAVIJb3V0cHV0SWRzEjgKEW93bmVyX3B1YmxpY19rZXlzGAIgAygMQgz6QgmSAQYiBHoCaCFSD293bmVyUHVibGljS2V5cxI6ChJpc3N1ZXJfcHVibGljX2tleXMYAyADKAxCDPpCCZIBBiIEegJoIVIQaXNzdWVyUHVibGljS2V5cxI5ChF0b2tlbl9pZGVudGlmaWVycxgEIAMoDEIM+kIJkgEGIgR6AmggUhB0b2tlbklkZW50aWZpZXJzEjUKDHBhZ2VfcmVxdWVzdBgFIAEoCzISLnNwYXJrLlBhZ2VSZXF1ZXN0UgtwYWdlUmVxdWVzdCLgAQoeUXVlcnlUb2tlblRyYW5zYWN0aW9uc1Jlc3BvbnNlEmwKHnRva2VuX3RyYW5zYWN0aW9uc193aXRoX3N0YXR1cxgBIAMoCzInLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25XaXRoU3RhdHVzUht0b2tlblRyYW5zYWN0aW9uc1dpdGhTdGF0dXMSFgoGb2Zmc2V0GAIgASgDUgZvZmZzZXQSOAoNcGFnZV9yZXNwb25zZRgDIAEoCzITLnNwYXJrLlBhZ2VSZXNwb25zZVIMcGFnZVJlc3BvbnNlItYBCiFPdXRwdXRXaXRoUHJldmlvdXNUcmFuc2FjdGlvbkRhdGESMAoGb3V0cHV0GAEgASgLMhguc3BhcmtfdG9rZW4uVG9rZW5PdXRwdXRSBm91dHB1dBJDChlwcmV2aW91c190cmFuc2FjdGlvbl9oYXNoGAIgASgMQgf6QgR6AmggUhdwcmV2aW91c1RyYW5zYWN0aW9uSGFzaBI6ChlwcmV2aW91c190cmFuc2FjdGlvbl92b3V0GAMgASgNUhdwcmV2aW91c1RyYW5zYWN0aW9uVm91dCLaAQoZUXVlcnlUb2tlbk91dHB1dHNSZXNwb25zZRKCAQomb3V0cHV0c193aXRoX3ByZXZpb3VzX3RyYW5zYWN0aW9uX2RhdGEYASADKAsyLi5zcGFya190b2tlbi5PdXRwdXRXaXRoUHJldmlvdXNUcmFuc2FjdGlvbkRhdGFSIm91dHB1dHNXaXRoUHJldmlvdXNUcmFuc2FjdGlvbkRhdGESOAoNcGFnZV9yZXNwb25zZRgCIAEoCzITLnNwYXJrLlBhZ2VSZXNwb25zZVIMcGFnZVJlc3BvbnNlImQKGFNwZW50VG9rZW5PdXRwdXRNZXRhZGF0YRIbCglvdXRwdXRfaWQYASABKAlSCG91dHB1dElkEisKEXJldm9jYXRpb25fc2VjcmV0GAIgASgMUhByZXZvY2F0aW9uU2VjcmV0Io4BCiRUb2tlblRyYW5zYWN0aW9uQ29uZmlybWF0aW9uTWV0YWRhdGESZgocc3BlbnRfdG9rZW5fb3V0cHV0c19tZXRhZGF0YRgBIAMoCzIlLnNwYXJrX3Rva2VuLlNwZW50VG9rZW5PdXRwdXRNZXRhZGF0YVIZc3BlbnRUb2tlbk91dHB1dHNNZXRhZGF0YSLMAgoaVG9rZW5UcmFuc2FjdGlvbldpdGhTdGF0dXMSSgoRdG9rZW5fdHJhbnNhY3Rpb24YASABKAsyHS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uUhB0b2tlblRyYW5zYWN0aW9uEjsKBnN0YXR1cxgCIAEoDjIjLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25TdGF0dXNSBnN0YXR1cxJmChVjb25maXJtYXRpb25fbWV0YWRhdGEYAyABKAsyMS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uQ29uZmlybWF0aW9uTWV0YWRhdGFSFGNvbmZpcm1hdGlvbk1ldGFkYXRhEj0KFnRva2VuX3RyYW5zYWN0aW9uX2hhc2gYBCABKAxCB/pCBHoCaCBSFHRva2VuVHJhbnNhY3Rpb25IYXNoIqwDChNGcmVlemVUb2tlbnNQYXlsb2FkEhgKB3ZlcnNpb24YASABKA1SB3ZlcnNpb24SMQoQb3duZXJfcHVibGljX2tleRgCIAEoDEIH+kIEegJoIVIOb3duZXJQdWJsaWNLZXkSNgoQdG9rZW5fcHVibGljX2tleRgDIAEoDEIH+kIEegJoIUgAUg50b2tlblB1YmxpY0tleYgBARI3ChB0b2tlbl9pZGVudGlmaWVyGAQgASgMQgf6QgR6AmggSAFSD3Rva2VuSWRlbnRpZmllcogBARI6Chlpc3N1ZXJfcHJvdmlkZWRfdGltZXN0YW1wGAUgASgEUhdpc3N1ZXJQcm92aWRlZFRpbWVzdGFtcBJIChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAYgASgMQgf6QgR6AmghUhlvcGVyYXRvcklkZW50aXR5UHVibGljS2V5EicKD3Nob3VsZF91bmZyZWV6ZRgHIAEoCFIOc2hvdWxkVW5mcmVlemVCEwoRX3Rva2VuX3B1YmxpY19rZXlCEwoRX3Rva2VuX2lkZW50aWZpZXIioQEKE0ZyZWV6ZVRva2Vuc1JlcXVlc3QSVAoVZnJlZXplX3Rva2Vuc19wYXlsb2FkGAEgASgLMiAuc3BhcmtfdG9rZW4uRnJlZXplVG9rZW5zUGF5bG9hZFITZnJlZXplVG9rZW5zUGF5bG9hZBI0ChBpc3N1ZXJfc2lnbmF0dXJlGAIgASgMQgn6QgZ6BBBAGElSD2lzc3VlclNpZ25hdHVyZSJYCg5Ub2tlbk91dHB1dFJlZhIyChB0cmFuc2FjdGlvbl9oYXNoGAEgASgMQgf6QgR6AmggUg90cmFuc2FjdGlvbkhhc2gSEgoEdm91dBgCIAEoDVIEdm91dCLeAQoURnJlZXplVG9rZW5zUmVzcG9uc2USPwoTaW1wYWN0ZWRfb3V0cHV0X2lkcxgBIAMoCUIPGAH6QgqSAQciBXIDsAEBUhFpbXBhY3RlZE91dHB1dElkcxIyChVpbXBhY3RlZF90b2tlbl9hbW91bnQYAiABKAxSE2ltcGFjdGVkVG9rZW5BbW91bnQSUQoWaW1wYWN0ZWRfdG9rZW5fb3V0cHV0cxgDIAMoCzIbLnNwYXJrX3Rva2VuLlRva2VuT3V0cHV0UmVmUhRpbXBhY3RlZFRva2VuT3V0cHV0cyqFAQoRVG9rZW5PdXRwdXRTdGF0dXMSIwofVE9LRU5fT1VUUFVUX1NUQVRVU19VTlNQRUNJRklFRBAAEiEKHVRPS0VOX09VVFBVVF9TVEFUVVNfQVZBSUxBQkxFEAESKAokVE9LRU5fT1VUUFVUX1NUQVRVU19QRU5ESU5HX09VVEJPVU5EEAIqpwEKFFRva2VuVHJhbnNhY3Rpb25UeXBlEiYKIlRPS0VOX1RSQU5TQUNUSU9OX1RZUEVfVU5TUEVDSUZJRUQQABIhCh1UT0tFTl9UUkFOU0FDVElPTl9UWVBFX0NSRUFURRABEh8KG1RPS0VOX1RSQU5TQUNUSU9OX1RZUEVfTUlOVBACEiMKH1RPS0VOX1RSQU5TQUNUSU9OX1RZUEVfVFJBTlNGRVIQAypTCgxDb21taXRTdGF0dXMSFgoSQ09NTUlUX1VOU1BFQ0lGSUVEEAASFQoRQ09NTUlUX1BST0NFU1NJTkcQARIUChBDT01NSVRfRklOQUxJWkVEEAIqhgIKFlRva2VuVHJhbnNhY3Rpb25TdGF0dXMSHQoZVE9LRU5fVFJBTlNBQ1RJT05fU1RBUlRFRBAAEhwKGFRPS0VOX1RSQU5TQUNUSU9OX1NJR05FRBABEh4KGlRPS0VOX1RSQU5TQUNUSU9OX1JFVkVBTEVEEAUSHwobVE9LRU5fVFJBTlNBQ1RJT05fRklOQUxJWkVEEAISJwojVE9LRU5fVFJBTlNBQ1RJT05fU1RBUlRFRF9DQU5DRUxMRUQQAxImCiJUT0tFTl9UUkFOU0FDVElPTl9TSUdORURfQ0FOQ0VMTEVEEAQSHQoZVE9LRU5fVFJBTlNBQ1RJT05fVU5LTk9XThAKMvAFChFTcGFya1Rva2VuU2VydmljZRJiChFzdGFydF90cmFuc2FjdGlvbhIkLnNwYXJrX3Rva2VuLlN0YXJ0VHJhbnNhY3Rpb25SZXF1ZXN0GiUuc3BhcmtfdG9rZW4uU3RhcnRUcmFuc2FjdGlvblJlc3BvbnNlIgASZQoSY29tbWl0X3RyYW5zYWN0aW9uEiUuc3BhcmtfdG9rZW4uQ29tbWl0VHJhbnNhY3Rpb25SZXF1ZXN0GiYuc3BhcmtfdG9rZW4uQ29tbWl0VHJhbnNhY3Rpb25SZXNwb25zZSIAEmkKFHF1ZXJ5X3Rva2VuX21ldGFkYXRhEiYuc3BhcmtfdG9rZW4uUXVlcnlUb2tlbk1ldGFkYXRhUmVxdWVzdBonLnNwYXJrX3Rva2VuLlF1ZXJ5VG9rZW5NZXRhZGF0YVJlc3BvbnNlIgASdQoYcXVlcnlfdG9rZW5fdHJhbnNhY3Rpb25zEiouc3BhcmtfdG9rZW4uUXVlcnlUb2tlblRyYW5zYWN0aW9uc1JlcXVlc3QaKy5zcGFya190b2tlbi5RdWVyeVRva2VuVHJhbnNhY3Rpb25zUmVzcG9uc2UiABJmChNxdWVyeV90b2tlbl9vdXRwdXRzEiUuc3BhcmtfdG9rZW4uUXVlcnlUb2tlbk91dHB1dHNSZXF1ZXN0GiYuc3BhcmtfdG9rZW4uUXVlcnlUb2tlbk91dHB1dHNSZXNwb25zZSIAElYKDWZyZWV6ZV90b2tlbnMSIC5zcGFya190b2tlbi5GcmVlemVUb2tlbnNSZXF1ZXN0GiEuc3BhcmtfdG9rZW4uRnJlZXplVG9rZW5zUmVzcG9uc2UiABJuChVicm9hZGNhc3RfdHJhbnNhY3Rpb24SKC5zcGFya190b2tlbi5Ccm9hZGNhc3RUcmFuc2FjdGlvblJlcXVlc3QaKS5zcGFya190b2tlbi5Ccm9hZGNhc3RUcmFuc2FjdGlvblJlc3BvbnNlIgBCMlowZ2l0aHViLmNvbS9saWdodHNwYXJrZGV2L3NwYXJrL3Byb3RvL3NwYXJrX3Rva2VuYgZwcm90bzMKpQQKCm1vY2sucHJvdG8SBG1vY2saG2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90byJAChtDbGVhblVwUHJlaW1hZ2VTaGFyZVJlcXVlc3QSIQoMcGF5bWVudF9oYXNoGAEgASgMUgtwYXltZW50SGFzaCJNChhVcGRhdGVOb2Rlc1N0YXR1c1JlcXVlc3QSGQoIbm9kZV9pZHMYASADKAlSB25vZGVJZHMSFgoGc3RhdHVzGAIgASgJUgZzdGF0dXMiMQoSVHJpZ2dlclRhc2tSZXF1ZXN0EhsKCXRhc2tfbmFtZRgBIAEoCVIIdGFza05hbWUy+gEKC01vY2tTZXJ2aWNlElYKF2NsZWFuX3VwX3ByZWltYWdlX3NoYXJlEiEubW9jay5DbGVhblVwUHJlaW1hZ2VTaGFyZVJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABJPChN1cGRhdGVfbm9kZXNfc3RhdHVzEh4ubW9jay5VcGRhdGVOb2Rlc1N0YXR1c1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABJCCgx0cmlnZ2VyX3Rhc2sSGC5tb2NrLlRyaWdnZXJUYXNrUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIAQitaKWdpdGh1Yi5jb20vbGlnaHRzcGFya2Rldi9zcGFyay9wcm90by9tb2NrYgZwcm90bzMK6gcKEXNwYXJrX2F1dGhuLnByb3RvEgtzcGFya19hdXRobiJ4CglDaGFsbGVuZ2USGAoHdmVyc2lvbhgBIAEoBVIHdmVyc2lvbhIcCgl0aW1lc3RhbXAYAiABKANSCXRpbWVzdGFtcBIUCgVub25jZRgDIAEoDFIFbm9uY2USHQoKcHVibGljX2tleRgEIAEoDFIJcHVibGljS2V5IoUBChJQcm90ZWN0ZWRDaGFsbGVuZ2USGAoHdmVyc2lvbhgBIAEoBVIHdmVyc2lvbhI0CgljaGFsbGVuZ2UYAiABKAsyFi5zcGFya19hdXRobi5DaGFsbGVuZ2VSCWNoYWxsZW5nZRIfCgtzZXJ2ZXJfaG1hYxgDIAEoDFIKc2VydmVySG1hYyI0ChNHZXRDaGFsbGVuZ2VSZXF1ZXN0Eh0KCnB1YmxpY19rZXkYASABKAxSCXB1YmxpY0tleSJoChRHZXRDaGFsbGVuZ2VSZXNwb25zZRJQChNwcm90ZWN0ZWRfY2hhbGxlbmdlGAEgASgLMh8uc3BhcmtfYXV0aG4uUHJvdGVjdGVkQ2hhbGxlbmdlUhJwcm90ZWN0ZWRDaGFsbGVuZ2UipwEKFlZlcmlmeUNoYWxsZW5nZVJlcXVlc3QSUAoTcHJvdGVjdGVkX2NoYWxsZW5nZRgBIAEoCzIfLnNwYXJrX2F1dGhuLlByb3RlY3RlZENoYWxsZW5nZVIScHJvdGVjdGVkQ2hhbGxlbmdlEhwKCXNpZ25hdHVyZRgCIAEoDFIJc2lnbmF0dXJlEh0KCnB1YmxpY19rZXkYAyABKAxSCXB1YmxpY0tleSJxChdWZXJpZnlDaGFsbGVuZ2VSZXNwb25zZRIjCg1zZXNzaW9uX3Rva2VuGAEgASgJUgxzZXNzaW9uVG9rZW4SMQoUZXhwaXJhdGlvbl90aW1lc3RhbXAYAiABKANSE2V4cGlyYXRpb25UaW1lc3RhbXAyzAEKEVNwYXJrQXV0aG5TZXJ2aWNlElYKDWdldF9jaGFsbGVuZ2USIC5zcGFya19hdXRobi5HZXRDaGFsbGVuZ2VSZXF1ZXN0GiEuc3BhcmtfYXV0aG4uR2V0Q2hhbGxlbmdlUmVzcG9uc2UiABJfChB2ZXJpZnlfY2hhbGxlbmdlEiMuc3BhcmtfYXV0aG4uVmVyaWZ5Q2hhbGxlbmdlUmVxdWVzdBokLnNwYXJrX2F1dGhuLlZlcmlmeUNoYWxsZW5nZVJlc3BvbnNlIgBCMlowZ2l0aHViLmNvbS9saWdodHNwYXJrZGV2L3NwYXJrL3Byb3RvL3NwYXJrX2F1dGhuYgZwcm90bzM=";
62726
+ var SPARK_DESCRIPTORS_BASE64 = "Cv8BCh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJvdG9idWYiOwoJVGltZXN0YW1wEhgKB3NlY29uZHMYASABKANSB3NlY29uZHMSFAoFbmFub3MYAiABKAVSBW5hbm9zQoUBChNjb20uZ29vZ2xlLnByb3RvYnVmQg5UaW1lc3RhbXBQcm90b1ABWjJnb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9rbm93bi90aW1lc3RhbXBwYvgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8zCr4BChtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiIHCgVFbXB0eUJ9ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3RvUAFaLmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2VtcHR5cGL4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMwqiZwogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiJbChFGaWxlRGVzY3JpcHRvclNldBI4CgRmaWxlGAEgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9SBGZpbGUqDAiA7Mr/ARCB7Mr/ASLFBQoTRmlsZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhgKB3BhY2thZ2UYAiABKAlSB3BhY2thZ2USHgoKZGVwZW5kZW5jeRgDIAMoCVIKZGVwZW5kZW5jeRIrChFwdWJsaWNfZGVwZW5kZW5jeRgKIAMoBVIQcHVibGljRGVwZW5kZW5jeRInCg93ZWFrX2RlcGVuZGVuY3kYCyADKAVSDndlYWtEZXBlbmRlbmN5EisKEW9wdGlvbl9kZXBlbmRlbmN5GA8gAygJUhBvcHRpb25EZXBlbmRlbmN5EkMKDG1lc3NhZ2VfdHlwZRgEIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SC21lc3NhZ2VUeXBlEkEKCWVudW1fdHlwZRgFIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvUghlbnVtVHlwZRJBCgdzZXJ2aWNlGAYgAygLMicuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG9SB3NlcnZpY2USQwoJZXh0ZW5zaW9uGAcgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUglleHRlbnNpb24SNgoHb3B0aW9ucxgIIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1IHb3B0aW9ucxJJChBzb3VyY2VfY29kZV9pbmZvGAkgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvUg5zb3VyY2VDb2RlSW5mbxIWCgZzeW50YXgYDCABKAlSBnN5bnRheBIyCgdlZGl0aW9uGA4gASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SB2VkaXRpb24i/AYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRJBCgp2aXNpYmlsaXR5GAsgASgOMiEuZ29vZ2xlLnByb3RvYnVmLlN5bWJvbFZpc2liaWxpdHlSCnZpc2liaWxpdHkaegoORXh0ZW5zaW9uUmFuZ2USFAoFc3RhcnQYASABKAVSBXN0YXJ0EhAKA2VuZBgCIAEoBVIDZW5kEkAKB29wdGlvbnMYAyABKAsyJi5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zUgdvcHRpb25zGjcKDVJlc2VydmVkUmFuZ2USFAoFc3RhcnQYASABKAVSBXN0YXJ0EhAKA2VuZBgCIAEoBVIDZW5kIswEChVFeHRlbnNpb25SYW5nZU9wdGlvbnMSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24SWQoLZGVjbGFyYXRpb24YAiADKAsyMi5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zLkRlY2xhcmF0aW9uQgOIAQJSC2RlY2xhcmF0aW9uEjcKCGZlYXR1cmVzGDIgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXRSCGZlYXR1cmVzEm0KDHZlcmlmaWNhdGlvbhgDIAEoDjI4Lmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnMuVmVyaWZpY2F0aW9uU3RhdGU6ClVOVkVSSUZJRURCA4gBAlIMdmVyaWZpY2F0aW9uGpQBCgtEZWNsYXJhdGlvbhIWCgZudW1iZXIYASABKAVSBm51bWJlchIbCglmdWxsX25hbWUYAiABKAlSCGZ1bGxOYW1lEhIKBHR5cGUYAyABKAlSBHR5cGUSGgoIcmVzZXJ2ZWQYBSABKAhSCHJlc2VydmVkEhoKCHJlcGVhdGVkGAYgASgIUghyZXBlYXRlZEoECAQQBSI0ChFWZXJpZmljYXRpb25TdGF0ZRIPCgtERUNMQVJBVElPThAAEg4KClVOVkVSSUZJRUQQASoJCOgHEICAgIACIsEGChRGaWVsZERlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgDIAEoBVIGbnVtYmVyEkEKBWxhYmVsGAQgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsUgVsYWJlbBI+CgR0eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGVSBHR5cGUSGwoJdHlwZV9uYW1lGAYgASgJUgh0eXBlTmFtZRIaCghleHRlbmRlZRgCIAEoCVIIZXh0ZW5kZWUSIwoNZGVmYXVsdF92YWx1ZRgHIAEoCVIMZGVmYXVsdFZhbHVlEh8KC29uZW9mX2luZGV4GAkgASgFUgpvbmVvZkluZGV4EhsKCWpzb25fbmFtZRgKIAEoCVIIanNvbk5hbWUSNwoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnNSB29wdGlvbnMSJwoPcHJvdG8zX29wdGlvbmFsGBEgASgIUg5wcm90bzNPcHRpb25hbCK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVBFQVRFRBADEhIKDkxBQkVMX1JFUVVJUkVEEAIiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyKmAwoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRJBCgp2aXNpYmlsaXR5GAYgASgOMiEuZ29vZ2xlLnByb3RvYnVmLlN5bWJvbFZpc2liaWxpdHlSCnZpc2liaWxpdHkaOwoRRW51bVJlc2VydmVkUmFuZ2USFAoFc3RhcnQYASABKAVSBXN0YXJ0EhAKA2VuZBgCIAEoBVIDZW5kIoMBChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIWCgZudW1iZXIYAiABKAVSBm51bWJlchI7CgdvcHRpb25zGAMgASgLMiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnNSB29wdGlvbnMitQEKFlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI+CgZtZXRob2QYAiADKAsyJi5nb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvUgZtZXRob2QSOQoHb3B0aW9ucxgDIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9uc1IHb3B0aW9uc0oECAQQBVIGc3RyZWFtIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyKtCQoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLgoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoEdHJ1ZVIOY2NFbmFibGVBcmVuYXMSKgoRb2JqY19jbGFzc19wcmVmaXgYJCABKAlSD29iamNDbGFzc1ByZWZpeBIpChBjc2hhcnBfbmFtZXNwYWNlGCUgASgJUg9jc2hhcnBOYW1lc3BhY2USIQoMc3dpZnRfcHJlZml4GCcgASgJUgtzd2lmdFByZWZpeBIoChBwaHBfY2xhc3NfcHJlZml4GCggASgJUg5waHBDbGFzc1ByZWZpeBIjCg1waHBfbmFtZXNwYWNlGCkgASgJUgxwaHBOYW1lc3BhY2USNAoWcGhwX21ldGFkYXRhX25hbWVzcGFjZRgsIAEoCVIUcGhwTWV0YWRhdGFOYW1lc3BhY2USIQoMcnVieV9wYWNrYWdlGC0gASgJUgtydWJ5UGFja2FnZRI3CghmZWF0dXJlcxgyIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJTUUQAyoJCOgHEICAgIACSgQIKhArSgQIJhAnUhRwaHBfZ2VuZXJpY19zZXJ2aWNlcyL0AwoOTWVzc2FnZU9wdGlvbnMSPAoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQYASABKAg6BWZhbHNlUhRtZXNzYWdlU2V0V2lyZUZvcm1hdBJMCh9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yGAIgASgIOgVmYWxzZVIcbm9TdGFuZGFyZERlc2NyaXB0b3JBY2Nlc3NvchIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIbCgltYXBfZW50cnkYByABKAhSCG1hcEVudHJ5ElYKJmRlcHJlY2F0ZWRfbGVnYWN5X2pzb25fZmllbGRfY29uZmxpY3RzGAsgASgIQgIYAVIiZGVwcmVjYXRlZExlZ2FjeUpzb25GaWVsZENvbmZsaWN0cxI3CghmZWF0dXJlcxgMIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACSgQIBBAFSgQIBRAGSgQIBhAHSgQICBAJSgQICRAKIqENCgxGaWVsZE9wdGlvbnMSQQoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkdSBWN0eXBlEhYKBnBhY2tlZBgCIAEoCFIGcGFja2VkEkcKBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUxSBmpzdHlwZRIZCgRsYXp5GAUgASgIOgVmYWxzZVIEbGF6eRIuCg91bnZlcmlmaWVkX2xhenkYDyABKAg6BWZhbHNlUg51bnZlcmlmaWVkTGF6eRIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIdCgR3ZWFrGAogASgIOgVmYWxzZUICGAFSBHdlYWsSKAoMZGVidWdfcmVkYWN0GBAgASgIOgVmYWxzZVILZGVidWdSZWRhY3QSSwoJcmV0ZW50aW9uGBEgASgOMi0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5PcHRpb25SZXRlbnRpb25SCXJldGVudGlvbhJICgd0YXJnZXRzGBMgAygOMi4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5PcHRpb25UYXJnZXRUeXBlUgd0YXJnZXRzElcKEGVkaXRpb25fZGVmYXVsdHMYFCADKAsyLC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkVkaXRpb25EZWZhdWx0Ug9lZGl0aW9uRGVmYXVsdHMSNwoIZmVhdHVyZXMYFSABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFIIZmVhdHVyZXMSVQoPZmVhdHVyZV9zdXBwb3J0GBYgASgLMiwuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5GZWF0dXJlU3VwcG9ydFIOZmVhdHVyZVN1cHBvcnQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24aWgoORWRpdGlvbkRlZmF1bHQSMgoHZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uUgdlZGl0aW9uEhQKBXZhbHVlGAIgASgJUgV2YWx1ZRqWAgoORmVhdHVyZVN1cHBvcnQSRwoSZWRpdGlvbl9pbnRyb2R1Y2VkGAEgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SEWVkaXRpb25JbnRyb2R1Y2VkEkcKEmVkaXRpb25fZGVwcmVjYXRlZBgCIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uUhFlZGl0aW9uRGVwcmVjYXRlZBIvChNkZXByZWNhdGlvbl93YXJuaW5nGAMgASgJUhJkZXByZWNhdGlvbldhcm5pbmcSQQoPZWRpdGlvbl9yZW1vdmVkGAQgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SDmVkaXRpb25SZW1vdmVkIi8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAESDQoJSlNfTlVNQkVSEAIiVQoPT3B0aW9uUmV0ZW50aW9uEhUKEVJFVEVOVElPTl9VTktOT1dOEAASFQoRUkVURU5USU9OX1JVTlRJTUUQARIUChBSRVRFTlRJT05fU09VUkNFEAIijAIKEE9wdGlvblRhcmdldFR5cGUSFwoTVEFSR0VUX1RZUEVfVU5LTk9XThAAEhQKEFRBUkdFVF9UWVBFX0ZJTEUQARIfChtUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UQAhIXChNUQVJHRVRfVFlQRV9NRVNTQUdFEAMSFQoRVEFSR0VUX1RZUEVfRklFTEQQBBIVChFUQVJHRVRfVFlQRV9PTkVPRhAFEhQKEFRBUkdFVF9UWVBFX0VOVU0QBhIaChZUQVJHRVRfVFlQRV9FTlVNX0VOVFJZEAcSFwoTVEFSR0VUX1RZUEVfU0VSVklDRRAIEhYKElRBUkdFVF9UWVBFX01FVEhPRBAJKgkI6AcQgICAgAJKBAgEEAVKBAgSEBMirAEKDE9uZW9mT3B0aW9ucxI3CghmZWF0dXJlcxgBIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItECCgtFbnVtT3B0aW9ucxIfCgthbGxvd19hbGlhcxgCIAEoCFIKYWxsb3dBbGlhcxIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJWCiZkZXByZWNhdGVkX2xlZ2FjeV9qc29uX2ZpZWxkX2NvbmZsaWN0cxgGIAEoCEICGAFSImRlcHJlY2F0ZWRMZWdhY3lKc29uRmllbGRDb25mbGljdHMSNwoIZmVhdHVyZXMYByABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFIIZmVhdHVyZXMSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiLYAgoQRW51bVZhbHVlT3B0aW9ucxIlCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBI3CghmZWF0dXJlcxgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxIoCgxkZWJ1Z19yZWRhY3QYAyABKAg6BWZhbHNlUgtkZWJ1Z1JlZGFjdBJVCg9mZWF0dXJlX3N1cHBvcnQYBCABKAsyLC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkZlYXR1cmVTdXBwb3J0Ug5mZWF0dXJlU3VwcG9ydBJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItUBCg5TZXJ2aWNlT3B0aW9ucxI3CghmZWF0dXJlcxgiIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIpkDCg1NZXRob2RPcHRpb25zEiUKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlUgpkZXByZWNhdGVkEnEKEWlkZW1wb3RlbmN5X2xldmVsGCIgASgOMi8uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVuY3lMZXZlbDoTSURFTVBPVEVOQ1lfVU5LTk9XTlIQaWRlbXBvdGVuY3lMZXZlbBI3CghmZWF0dXJlcxgjIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiJQChBJZGVtcG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VOS05PV04QABITCg9OT19TSURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIqCQjoBxCAgICAAiKaAwoTVW5pbnRlcnByZXRlZE9wdGlvbhJBCgRuYW1lGAIgAygLMi0uZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnRSBG5hbWUSKQoQaWRlbnRpZmllcl92YWx1ZRgDIAEoCVIPaWRlbnRpZmllclZhbHVlEiwKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBFIQcG9zaXRpdmVJbnRWYWx1ZRIsChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKANSEG5lZ2F0aXZlSW50VmFsdWUSIQoMZG91YmxlX3ZhbHVlGAYgASgBUgtkb3VibGVWYWx1ZRIhCgxzdHJpbmdfdmFsdWUYByABKAxSC3N0cmluZ1ZhbHVlEicKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCVIOYWdncmVnYXRlVmFsdWUaSgoITmFtZVBhcnQSGwoJbmFtZV9wYXJ0GAEgAigJUghuYW1lUGFydBIhCgxpc19leHRlbnNpb24YAiACKAhSC2lzRXh0ZW5zaW9uIo4PCgpGZWF0dXJlU2V0EpEBCg5maWVsZF9wcmVzZW5jZRgBIAEoDjIpLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LkZpZWxkUHJlc2VuY2VCP4gBAZgBBJgBAaIBDRIIRVhQTElDSVQYhAeiAQ0SCElNUExJQ0lUGOcHogENEghFWFBMSUNJVBjoB7IBAwjoB1INZmllbGRQcmVzZW5jZRJsCgllbnVtX3R5cGUYAiABKA4yJC5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5FbnVtVHlwZUIpiAEBmAEGmAEBogELEgZDTE9TRUQYhAeiAQkSBE9QRU4Y5weyAQMI6AdSCGVudW1UeXBlEpgBChdyZXBlYXRlZF9maWVsZF9lbmNvZGluZxgDIAEoDjIxLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LlJlcGVhdGVkRmllbGRFbmNvZGluZ0ItiAEBmAEEmAEBogENEghFWFBBTkRFRBiEB6IBCxIGUEFDS0VEGOcHsgEDCOgHUhVyZXBlYXRlZEZpZWxkRW5jb2RpbmcSfgoPdXRmOF92YWxpZGF0aW9uGAQgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuVXRmOFZhbGlkYXRpb25CKYgBAZgBBJgBAaIBCRIETk9ORRiEB6IBCxIGVkVSSUZZGOcHsgEDCOgHUg51dGY4VmFsaWRhdGlvbhJ+ChBtZXNzYWdlX2VuY29kaW5nGAUgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuTWVzc2FnZUVuY29kaW5nQiaIAQGYAQSYAQGiARQSD0xFTkdUSF9QUkVGSVhFRBiEB7IBAwjoB1IPbWVzc2FnZUVuY29kaW5nEoIBCgtqc29uX2Zvcm1hdBgGIAEoDjImLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0Lkpzb25Gb3JtYXRCOYgBAZgBA5gBBpgBAaIBFxISTEVHQUNZX0JFU1RfRUZGT1JUGIQHogEKEgVBTExPVxjnB7IBAwjoB1IKanNvbkZvcm1hdBKrAQoUZW5mb3JjZV9uYW1pbmdfc3R5bGUYByABKA4yLi5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5FbmZvcmNlTmFtaW5nU3R5bGVCSYgBApgBAZgBApgBA5gBBJgBBZgBBpgBB5gBCJgBCaIBERIMU1RZTEVfTEVHQUNZGIQHogEOEglTVFlMRTIwMjQY6QeyAQMI6QdSEmVuZm9yY2VOYW1pbmdTdHlsZRK5AQoZZGVmYXVsdF9zeW1ib2xfdmlzaWJpbGl0eRgIIAEoDjJFLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LlZpc2liaWxpdHlGZWF0dXJlLkRlZmF1bHRTeW1ib2xWaXNpYmlsaXR5QjaIAQKYAQGiAQ8SCkVYUE9SVF9BTEwYhAeiARUSEEVYUE9SVF9UT1BfTEVWRUwY6QeyAQMI6QdSF2RlZmF1bHRTeW1ib2xWaXNpYmlsaXR5GqEBChFWaXNpYmlsaXR5RmVhdHVyZSKBAQoXRGVmYXVsdFN5bWJvbFZpc2liaWxpdHkSJQohREVGQVVMVF9TWU1CT0xfVklTSUJJTElUWV9VTktOT1dOEAASDgoKRVhQT1JUX0FMTBABEhQKEEVYUE9SVF9UT1BfTEVWRUwQAhINCglMT0NBTF9BTEwQAxIKCgZTVFJJQ1QQBEoICAEQgICAgAIiXAoNRmllbGRQcmVzZW5jZRIaChZGSUVMRF9QUkVTRU5DRV9VTktOT1dOEAASDAoIRVhQTElDSVQQARIMCghJTVBMSUNJVBACEhMKD0xFR0FDWV9SRVFVSVJFRBADIjcKCEVudW1UeXBlEhUKEUVOVU1fVFlQRV9VTktOT1dOEAASCAoET1BFThABEgoKBkNMT1NFRBACIlYKFVJlcGVhdGVkRmllbGRFbmNvZGluZxIjCh9SRVBFQVRFRF9GSUVMRF9FTkNPRElOR19VTktOT1dOEAASCgoGUEFDS0VEEAESDAoIRVhQQU5ERUQQAiJJCg5VdGY4VmFsaWRhdGlvbhIbChdVVEY4X1ZBTElEQVRJT05fVU5LTk9XThAAEgoKBlZFUklGWRACEggKBE5PTkUQAyIECAEQASJTCg9NZXNzYWdlRW5jb2RpbmcSHAoYTUVTU0FHRV9FTkNPRElOR19VTktOT1dOEAASEwoPTEVOR1RIX1BSRUZJWEVEEAESDQoJREVMSU1JVEVEEAIiSAoKSnNvbkZvcm1hdBIXChNKU09OX0ZPUk1BVF9VTktOT1dOEAASCQoFQUxMT1cQARIWChJMRUdBQ1lfQkVTVF9FRkZPUlQQAiJXChJFbmZvcmNlTmFtaW5nU3R5bGUSIAocRU5GT1JDRV9OQU1JTkdfU1RZTEVfVU5LTk9XThAAEg0KCVNUWUxFMjAyNBABEhAKDFNUWUxFX0xFR0FDWRACKgYI6AcQi04qBgiLThCQTioGCJBOEJFOSgYI5wcQ6Aci7wMKEkZlYXR1cmVTZXREZWZhdWx0cxJYCghkZWZhdWx0cxgBIAMoCzI8Lmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0RGVmYXVsdHMuRmVhdHVyZVNldEVkaXRpb25EZWZhdWx0UghkZWZhdWx0cxJBCg9taW5pbXVtX2VkaXRpb24YBCABKA4yGC5nb29nbGUucHJvdG9idWYuRWRpdGlvblIObWluaW11bUVkaXRpb24SQQoPbWF4aW11bV9lZGl0aW9uGAUgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb25SDm1heGltdW1FZGl0aW9uGvgBChhGZWF0dXJlU2V0RWRpdGlvbkRlZmF1bHQSMgoHZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uUgdlZGl0aW9uEk4KFG92ZXJyaWRhYmxlX2ZlYXR1cmVzGAQgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXRSE292ZXJyaWRhYmxlRmVhdHVyZXMSQgoOZml4ZWRfZmVhdHVyZXMYBSABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFINZml4ZWRGZWF0dXJlc0oECAEQAkoECAIQA1IIZmVhdHVyZXMitQIKDlNvdXJjZUNvZGVJbmZvEkQKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uUghsb2NhdGlvbhrOAQoITG9jYXRpb24SFgoEcGF0aBgBIAMoBUICEAFSBHBhdGgSFgoEc3BhbhgCIAMoBUICEAFSBHNwYW4SKQoQbGVhZGluZ19jb21tZW50cxgDIAEoCVIPbGVhZGluZ0NvbW1lbnRzEisKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJUhB0cmFpbGluZ0NvbW1lbnRzEjoKGWxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMYBiADKAlSF2xlYWRpbmdEZXRhY2hlZENvbW1lbnRzKgwIgOzK/wEQgezK/wEi0AIKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhrrAQoKQW5ub3RhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIfCgtzb3VyY2VfZmlsZRgCIAEoCVIKc291cmNlRmlsZRIUCgViZWdpbhgDIAEoBVIFYmVnaW4SEAoDZW5kGAQgASgFUgNlbmQSUgoIc2VtYW50aWMYBSABKA4yNi5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5TZW1hbnRpY1IIc2VtYW50aWMiKAoIU2VtYW50aWMSCAoETk9ORRAAEgcKA1NFVBABEgkKBUFMSUFTEAIqvgIKB0VkaXRpb24SEwoPRURJVElPTl9VTktOT1dOEAASEwoORURJVElPTl9MRUdBQ1kQhAcSEwoORURJVElPTl9QUk9UTzIQ5gcSEwoORURJVElPTl9QUk9UTzMQ5wcSEQoMRURJVElPTl8yMDIzEOgHEhEKDEVESVRJT05fMjAyNBDpBxIVChBFRElUSU9OX1VOU1RBQkxFEI9OEhcKE0VESVRJT05fMV9URVNUX09OTFkQARIXChNFRElUSU9OXzJfVEVTVF9PTkxZEAISHQoXRURJVElPTl85OTk5N19URVNUX09OTFkQnY0GEh0KF0VESVRJT05fOTk5OThfVEVTVF9PTkxZEJ6NBhIdChdFRElUSU9OXzk5OTk5X1RFU1RfT05MWRCfjQYSEwoLRURJVElPTl9NQVgQ/////wcqVQoQU3ltYm9sVmlzaWJpbGl0eRIUChBWSVNJQklMSVRZX1VOU0VUEAASFAoQVklTSUJJTElUWV9MT0NBTBABEhUKEVZJU0lCSUxJVFlfRVhQT1JUEAJCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9kZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbgr7AQoeZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvEg9nb29nbGUucHJvdG9idWYiOgoIRHVyYXRpb24SGAoHc2Vjb25kcxgBIAEoA1IHc2Vjb25kcxIUCgVuYW5vcxgCIAEoBVIFbmFub3NCgwEKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoxZ29vZ2xlLmdvbGFuZy5vcmcvcHJvdG9idWYvdHlwZXMva25vd24vZHVyYXRpb25wYvgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8zCq8xChd2YWxpZGF0ZS92YWxpZGF0ZS5wcm90bxIIdmFsaWRhdGUaIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvGh5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8aH2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8iyAgKCkZpZWxkUnVsZXMSMAoHbWVzc2FnZRgRIAEoCzIWLnZhbGlkYXRlLk1lc3NhZ2VSdWxlc1IHbWVzc2FnZRIsCgVmbG9hdBgBIAEoCzIULnZhbGlkYXRlLkZsb2F0UnVsZXNIAFIFZmxvYXQSLwoGZG91YmxlGAIgASgLMhUudmFsaWRhdGUuRG91YmxlUnVsZXNIAFIGZG91YmxlEiwKBWludDMyGAMgASgLMhQudmFsaWRhdGUuSW50MzJSdWxlc0gAUgVpbnQzMhIsCgVpbnQ2NBgEIAEoCzIULnZhbGlkYXRlLkludDY0UnVsZXNIAFIFaW50NjQSLwoGdWludDMyGAUgASgLMhUudmFsaWRhdGUuVUludDMyUnVsZXNIAFIGdWludDMyEi8KBnVpbnQ2NBgGIAEoCzIVLnZhbGlkYXRlLlVJbnQ2NFJ1bGVzSABSBnVpbnQ2NBIvCgZzaW50MzIYByABKAsyFS52YWxpZGF0ZS5TSW50MzJSdWxlc0gAUgZzaW50MzISLwoGc2ludDY0GAggASgLMhUudmFsaWRhdGUuU0ludDY0UnVsZXNIAFIGc2ludDY0EjIKB2ZpeGVkMzIYCSABKAsyFi52YWxpZGF0ZS5GaXhlZDMyUnVsZXNIAFIHZml4ZWQzMhIyCgdmaXhlZDY0GAogASgLMhYudmFsaWRhdGUuRml4ZWQ2NFJ1bGVzSABSB2ZpeGVkNjQSNQoIc2ZpeGVkMzIYCyABKAsyFy52YWxpZGF0ZS5TRml4ZWQzMlJ1bGVzSABSCHNmaXhlZDMyEjUKCHNmaXhlZDY0GAwgASgLMhcudmFsaWRhdGUuU0ZpeGVkNjRSdWxlc0gAUghzZml4ZWQ2NBIpCgRib29sGA0gASgLMhMudmFsaWRhdGUuQm9vbFJ1bGVzSABSBGJvb2wSLwoGc3RyaW5nGA4gASgLMhUudmFsaWRhdGUuU3RyaW5nUnVsZXNIAFIGc3RyaW5nEiwKBWJ5dGVzGA8gASgLMhQudmFsaWRhdGUuQnl0ZXNSdWxlc0gAUgVieXRlcxIpCgRlbnVtGBAgASgLMhMudmFsaWRhdGUuRW51bVJ1bGVzSABSBGVudW0SNQoIcmVwZWF0ZWQYEiABKAsyFy52YWxpZGF0ZS5SZXBlYXRlZFJ1bGVzSABSCHJlcGVhdGVkEiYKA21hcBgTIAEoCzISLnZhbGlkYXRlLk1hcFJ1bGVzSABSA21hcBImCgNhbnkYFCABKAsyEi52YWxpZGF0ZS5BbnlSdWxlc0gAUgNhbnkSNQoIZHVyYXRpb24YFSABKAsyFy52YWxpZGF0ZS5EdXJhdGlvblJ1bGVzSABSCGR1cmF0aW9uEjgKCXRpbWVzdGFtcBgWIAEoCzIYLnZhbGlkYXRlLlRpbWVzdGFtcFJ1bGVzSABSCXRpbWVzdGFtcEIGCgR0eXBlIrABCgpGbG9hdFJ1bGVzEhQKBWNvbnN0GAEgASgCUgVjb25zdBIOCgJsdBgCIAEoAlICbHQSEAoDbHRlGAMgASgCUgNsdGUSDgoCZ3QYBCABKAJSAmd0EhAKA2d0ZRgFIAEoAlIDZ3RlEg4KAmluGAYgAygCUgJpbhIVCgZub3RfaW4YByADKAJSBW5vdEluEiEKDGlnbm9yZV9lbXB0eRgIIAEoCFILaWdub3JlRW1wdHkisQEKC0RvdWJsZVJ1bGVzEhQKBWNvbnN0GAEgASgBUgVjb25zdBIOCgJsdBgCIAEoAVICbHQSEAoDbHRlGAMgASgBUgNsdGUSDgoCZ3QYBCABKAFSAmd0EhAKA2d0ZRgFIAEoAVIDZ3RlEg4KAmluGAYgAygBUgJpbhIVCgZub3RfaW4YByADKAFSBW5vdEluEiEKDGlnbm9yZV9lbXB0eRgIIAEoCFILaWdub3JlRW1wdHkisAEKCkludDMyUnVsZXMSFAoFY29uc3QYASABKAVSBWNvbnN0Eg4KAmx0GAIgASgFUgJsdBIQCgNsdGUYAyABKAVSA2x0ZRIOCgJndBgEIAEoBVICZ3QSEAoDZ3RlGAUgASgFUgNndGUSDgoCaW4YBiADKAVSAmluEhUKBm5vdF9pbhgHIAMoBVIFbm90SW4SIQoMaWdub3JlX2VtcHR5GAggASgIUgtpZ25vcmVFbXB0eSKwAQoKSW50NjRSdWxlcxIUCgVjb25zdBgBIAEoA1IFY29uc3QSDgoCbHQYAiABKANSAmx0EhAKA2x0ZRgDIAEoA1IDbHRlEg4KAmd0GAQgASgDUgJndBIQCgNndGUYBSABKANSA2d0ZRIOCgJpbhgGIAMoA1ICaW4SFQoGbm90X2luGAcgAygDUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtVSW50MzJSdWxlcxIUCgVjb25zdBgBIAEoDVIFY29uc3QSDgoCbHQYAiABKA1SAmx0EhAKA2x0ZRgDIAEoDVIDbHRlEg4KAmd0GAQgASgNUgJndBIQCgNndGUYBSABKA1SA2d0ZRIOCgJpbhgGIAMoDVICaW4SFQoGbm90X2luGAcgAygNUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtVSW50NjRSdWxlcxIUCgVjb25zdBgBIAEoBFIFY29uc3QSDgoCbHQYAiABKARSAmx0EhAKA2x0ZRgDIAEoBFIDbHRlEg4KAmd0GAQgASgEUgJndBIQCgNndGUYBSABKARSA2d0ZRIOCgJpbhgGIAMoBFICaW4SFQoGbm90X2luGAcgAygEUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtTSW50MzJSdWxlcxIUCgVjb25zdBgBIAEoEVIFY29uc3QSDgoCbHQYAiABKBFSAmx0EhAKA2x0ZRgDIAEoEVIDbHRlEg4KAmd0GAQgASgRUgJndBIQCgNndGUYBSABKBFSA2d0ZRIOCgJpbhgGIAMoEVICaW4SFQoGbm90X2luGAcgAygRUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrEBCgtTSW50NjRSdWxlcxIUCgVjb25zdBgBIAEoElIFY29uc3QSDgoCbHQYAiABKBJSAmx0EhAKA2x0ZRgDIAEoElIDbHRlEg4KAmd0GAQgASgSUgJndBIQCgNndGUYBSABKBJSA2d0ZRIOCgJpbhgGIAMoElICaW4SFQoGbm90X2luGAcgAygSUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IrIBCgxGaXhlZDMyUnVsZXMSFAoFY29uc3QYASABKAdSBWNvbnN0Eg4KAmx0GAIgASgHUgJsdBIQCgNsdGUYAyABKAdSA2x0ZRIOCgJndBgEIAEoB1ICZ3QSEAoDZ3RlGAUgASgHUgNndGUSDgoCaW4YBiADKAdSAmluEhUKBm5vdF9pbhgHIAMoB1IFbm90SW4SIQoMaWdub3JlX2VtcHR5GAggASgIUgtpZ25vcmVFbXB0eSKyAQoMRml4ZWQ2NFJ1bGVzEhQKBWNvbnN0GAEgASgGUgVjb25zdBIOCgJsdBgCIAEoBlICbHQSEAoDbHRlGAMgASgGUgNsdGUSDgoCZ3QYBCABKAZSAmd0EhAKA2d0ZRgFIAEoBlIDZ3RlEg4KAmluGAYgAygGUgJpbhIVCgZub3RfaW4YByADKAZSBW5vdEluEiEKDGlnbm9yZV9lbXB0eRgIIAEoCFILaWdub3JlRW1wdHkiswEKDVNGaXhlZDMyUnVsZXMSFAoFY29uc3QYASABKA9SBWNvbnN0Eg4KAmx0GAIgASgPUgJsdBIQCgNsdGUYAyABKA9SA2x0ZRIOCgJndBgEIAEoD1ICZ3QSEAoDZ3RlGAUgASgPUgNndGUSDgoCaW4YBiADKA9SAmluEhUKBm5vdF9pbhgHIAMoD1IFbm90SW4SIQoMaWdub3JlX2VtcHR5GAggASgIUgtpZ25vcmVFbXB0eSKzAQoNU0ZpeGVkNjRSdWxlcxIUCgVjb25zdBgBIAEoEFIFY29uc3QSDgoCbHQYAiABKBBSAmx0EhAKA2x0ZRgDIAEoEFIDbHRlEg4KAmd0GAQgASgQUgJndBIQCgNndGUYBSABKBBSA2d0ZRIOCgJpbhgGIAMoEFICaW4SFQoGbm90X2luGAcgAygQUgVub3RJbhIhCgxpZ25vcmVfZW1wdHkYCCABKAhSC2lnbm9yZUVtcHR5IiEKCUJvb2xSdWxlcxIUCgVjb25zdBgBIAEoCFIFY29uc3Qi1AUKC1N0cmluZ1J1bGVzEhQKBWNvbnN0GAEgASgJUgVjb25zdBIQCgNsZW4YEyABKARSA2xlbhIXCgdtaW5fbGVuGAIgASgEUgZtaW5MZW4SFwoHbWF4X2xlbhgDIAEoBFIGbWF4TGVuEhsKCWxlbl9ieXRlcxgUIAEoBFIIbGVuQnl0ZXMSGwoJbWluX2J5dGVzGAQgASgEUghtaW5CeXRlcxIbCgltYXhfYnl0ZXMYBSABKARSCG1heEJ5dGVzEhgKB3BhdHRlcm4YBiABKAlSB3BhdHRlcm4SFgoGcHJlZml4GAcgASgJUgZwcmVmaXgSFgoGc3VmZml4GAggASgJUgZzdWZmaXgSGgoIY29udGFpbnMYCSABKAlSCGNvbnRhaW5zEiEKDG5vdF9jb250YWlucxgXIAEoCVILbm90Q29udGFpbnMSDgoCaW4YCiADKAlSAmluEhUKBm5vdF9pbhgLIAMoCVIFbm90SW4SFgoFZW1haWwYDCABKAhIAFIFZW1haWwSHAoIaG9zdG5hbWUYDSABKAhIAFIIaG9zdG5hbWUSEAoCaXAYDiABKAhIAFICaXASFAoEaXB2NBgPIAEoCEgAUgRpcHY0EhQKBGlwdjYYECABKAhIAFIEaXB2NhISCgN1cmkYESABKAhIAFIDdXJpEhkKB3VyaV9yZWYYEiABKAhIAFIGdXJpUmVmEhoKB2FkZHJlc3MYFSABKAhIAFIHYWRkcmVzcxIUCgR1dWlkGBYgASgISABSBHV1aWQSQAoQd2VsbF9rbm93bl9yZWdleBgYIAEoDjIULnZhbGlkYXRlLktub3duUmVnZXhIAFIOd2VsbEtub3duUmVnZXgSHAoGc3RyaWN0GBkgASgIOgR0cnVlUgZzdHJpY3QSIQoMaWdub3JlX2VtcHR5GBogASgIUgtpZ25vcmVFbXB0eUIMCgp3ZWxsX2tub3duIuICCgpCeXRlc1J1bGVzEhQKBWNvbnN0GAEgASgMUgVjb25zdBIQCgNsZW4YDSABKARSA2xlbhIXCgdtaW5fbGVuGAIgASgEUgZtaW5MZW4SFwoHbWF4X2xlbhgDIAEoBFIGbWF4TGVuEhgKB3BhdHRlcm4YBCABKAlSB3BhdHRlcm4SFgoGcHJlZml4GAUgASgMUgZwcmVmaXgSFgoGc3VmZml4GAYgASgMUgZzdWZmaXgSGgoIY29udGFpbnMYByABKAxSCGNvbnRhaW5zEg4KAmluGAggAygMUgJpbhIVCgZub3RfaW4YCSADKAxSBW5vdEluEhAKAmlwGAogASgISABSAmlwEhQKBGlwdjQYCyABKAhIAFIEaXB2NBIUCgRpcHY2GAwgASgISABSBGlwdjYSIQoMaWdub3JlX2VtcHR5GA4gASgIUgtpZ25vcmVFbXB0eUIMCgp3ZWxsX2tub3duImsKCUVudW1SdWxlcxIUCgVjb25zdBgBIAEoBVIFY29uc3QSIQoMZGVmaW5lZF9vbmx5GAIgASgIUgtkZWZpbmVkT25seRIOCgJpbhgDIAMoBVICaW4SFQoGbm90X2luGAQgAygFUgVub3RJbiI+CgxNZXNzYWdlUnVsZXMSEgoEc2tpcBgBIAEoCFIEc2tpcBIaCghyZXF1aXJlZBgCIAEoCFIIcmVxdWlyZWQisAEKDVJlcGVhdGVkUnVsZXMSGwoJbWluX2l0ZW1zGAEgASgEUghtaW5JdGVtcxIbCgltYXhfaXRlbXMYAiABKARSCG1heEl0ZW1zEhYKBnVuaXF1ZRgDIAEoCFIGdW5pcXVlEioKBWl0ZW1zGAQgASgLMhQudmFsaWRhdGUuRmllbGRSdWxlc1IFaXRlbXMSIQoMaWdub3JlX2VtcHR5GAUgASgIUgtpZ25vcmVFbXB0eSLcAQoITWFwUnVsZXMSGwoJbWluX3BhaXJzGAEgASgEUghtaW5QYWlycxIbCgltYXhfcGFpcnMYAiABKARSCG1heFBhaXJzEhsKCW5vX3NwYXJzZRgDIAEoCFIIbm9TcGFyc2USKAoEa2V5cxgEIAEoCzIULnZhbGlkYXRlLkZpZWxkUnVsZXNSBGtleXMSLAoGdmFsdWVzGAUgASgLMhQudmFsaWRhdGUuRmllbGRSdWxlc1IGdmFsdWVzEiEKDGlnbm9yZV9lbXB0eRgGIAEoCFILaWdub3JlRW1wdHkiTQoIQW55UnVsZXMSGgoIcmVxdWlyZWQYASABKAhSCHJlcXVpcmVkEg4KAmluGAIgAygJUgJpbhIVCgZub3RfaW4YAyADKAlSBW5vdEluIukCCg1EdXJhdGlvblJ1bGVzEhoKCHJlcXVpcmVkGAEgASgIUghyZXF1aXJlZBIvCgVjb25zdBgCIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblIFY29uc3QSKQoCbHQYAyABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25SAmx0EisKA2x0ZRgEIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblIDbHRlEikKAmd0GAUgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uUgJndBIrCgNndGUYBiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25SA2d0ZRIpCgJpbhgHIAMoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblICaW4SMAoGbm90X2luGAggAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uUgVub3RJbiLzAgoOVGltZXN0YW1wUnVsZXMSGgoIcmVxdWlyZWQYASABKAhSCHJlcXVpcmVkEjAKBWNvbnN0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFIFY29uc3QSKgoCbHQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgJsdBIsCgNsdGUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgNsdGUSKgoCZ3QYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgJndBIsCgNndGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgNndGUSFQoGbHRfbm93GAcgASgIUgVsdE5vdxIVCgZndF9ub3cYCCABKAhSBWd0Tm93EjEKBndpdGhpbhgJIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblIGd2l0aGluKkYKCktub3duUmVnZXgSCwoHVU5LTk9XThAAEhQKEEhUVFBfSEVBREVSX05BTUUQARIVChFIVFRQX0hFQURFUl9WQUxVRRACOjwKCGRpc2FibGVkEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGK8IIAEoCFIIZGlzYWJsZWQ6OgoHaWdub3JlZBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiwCCABKAhSB2lnbm9yZWQ6OgoIcmVxdWlyZWQSHS5nb29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25zGK8IIAEoCFIIcmVxdWlyZWQ6SgoFcnVsZXMSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGK8IIAEoCzIULnZhbGlkYXRlLkZpZWxkUnVsZXNSBXJ1bGVzQlAKGmlvLmVudm95cHJveHkucGd2LnZhbGlkYXRlWjJnaXRodWIuY29tL2Vudm95cHJveHkvcHJvdG9jLWdlbi12YWxpZGF0ZS92YWxpZGF0ZQq3AwoMY29tbW9uLnByb3RvEgZjb21tb24ihwEKClBhY2thZ2VNYXASPAoIcGFja2FnZXMYASADKAsyIC5jb21tb24uUGFja2FnZU1hcC5QYWNrYWdlc0VudHJ5UghwYWNrYWdlcxo7Cg1QYWNrYWdlc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEiRQoRU2lnbmluZ0NvbW1pdG1lbnQSFgoGaGlkaW5nGAEgASgMUgZoaWRpbmcSGAoHYmluZGluZxgCIAEoDFIHYmluZGluZyI4Cg1TaWduaW5nUmVzdWx0EicKD3NpZ25hdHVyZV9zaGFyZRgBIAEoDFIOc2lnbmF0dXJlU2hhcmUqXQoPU2lnbmF0dXJlSW50ZW50EgwKCENSRUFUSU9OEAASDAoIVFJBTlNGRVIQARINCglBR0dSRUdBVEUQAhIPCgdSRUZSRVNIEAMaAggBEg4KBkVYVEVORBAEGgIIAUItWitnaXRodWIuY29tL2xpZ2h0c3BhcmtkZXYvc3BhcmsvcHJvdG8vY29tbW9uYgZwcm90bzMK/cUCCgtzcGFyay5wcm90bxIFc3BhcmsaH2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8aG2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90bxoXdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8aDGNvbW1vbi5wcm90byJKChhTdWJzY3JpYmVUb0V2ZW50c1JlcXVlc3QSLgoTaWRlbnRpdHlfcHVibGljX2tleRgKIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkiwAEKGVN1YnNjcmliZVRvRXZlbnRzUmVzcG9uc2USMgoIdHJhbnNmZXIYASABKAsyFC5zcGFyay5UcmFuc2ZlckV2ZW50SABSCHRyYW5zZmVyEi8KB2RlcG9zaXQYAiABKAsyEy5zcGFyay5EZXBvc2l0RXZlbnRIAFIHZGVwb3NpdBI1Cgljb25uZWN0ZWQYAyABKAsyFS5zcGFyay5Db25uZWN0ZWRFdmVudEgAUgljb25uZWN0ZWRCBwoFZXZlbnQiEAoOQ29ubmVjdGVkRXZlbnQiPAoNVHJhbnNmZXJFdmVudBIrCgh0cmFuc2ZlchgKIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlciI5CgxEZXBvc2l0RXZlbnQSKQoHZGVwb3NpdBgKIAEoCzIPLnNwYXJrLlRyZWVOb2RlUgdkZXBvc2l0IrQBCgtQYWdlUmVxdWVzdBI0ChB1bnNhZmVfcGFnZV9zaXplGAEgASgFQgr6QgcaBRjoBygAUg51bnNhZmVQYWdlU2l6ZRInCglwYWdlX3NpemUYBCABKA1CCvpCByoFGOgHKABSCHBhZ2VTaXplEhYKBmN1cnNvchgCIAEoCVIGY3Vyc29yEi4KCWRpcmVjdGlvbhgDIAEoDjIQLnNwYXJrLkRpcmVjdGlvblIJZGlyZWN0aW9uIqgBCgxQYWdlUmVzcG9uc2USIgoNaGFzX25leHRfcGFnZRgBIAEoCFILaGFzTmV4dFBhZ2USKgoRaGFzX3ByZXZpb3VzX3BhZ2UYAiABKAhSD2hhc1ByZXZpb3VzUGFnZRIfCgtuZXh0X2N1cnNvchgDIAEoCVIKbmV4dEN1cnNvchInCg9wcmV2aW91c19jdXJzb3IYBCABKAlSDnByZXZpb3VzQ3Vyc29yIoACChNEZXBvc2l0QWRkcmVzc1Byb29mEmAKEmFkZHJlc3Nfc2lnbmF0dXJlcxgBIAMoCzIxLnNwYXJrLkRlcG9zaXRBZGRyZXNzUHJvb2YuQWRkcmVzc1NpZ25hdHVyZXNFbnRyeVIRYWRkcmVzc1NpZ25hdHVyZXMSQQodcHJvb2Zfb2ZfcG9zc2Vzc2lvbl9zaWduYXR1cmUYAiABKAxSGnByb29mT2ZQb3NzZXNzaW9uU2lnbmF0dXJlGkQKFkFkZHJlc3NTaWduYXR1cmVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAxSBXZhbHVlOgI4ASLMAgodR2VuZXJhdGVEZXBvc2l0QWRkcmVzc1JlcXVlc3QSLAoSc2lnbmluZ19wdWJsaWNfa2V5GAEgASgMUhBzaWduaW5nUHVibGljS2V5Ei4KE2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSEWlkZW50aXR5UHVibGljS2V5EjIKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgAFIHbmV0d29yaxImCgdsZWFmX2lkGAQgASgJQgj6QgVyA7ABAUgAUgZsZWFmSWSIAQESIAoJaXNfc3RhdGljGAUgASgISAFSCGlzU3RhdGljiAEBEjUKDGhhc2hfdmFyaWFudBgGIAEoDjISLnNwYXJrLkhhc2hWYXJpYW50UgtoYXNoVmFyaWFudEIKCghfbGVhZl9pZEIMCgpfaXNfc3RhdGljIrUBCgdBZGRyZXNzEhgKB2FkZHJlc3MYASABKAlSB2FkZHJlc3MSIwoNdmVyaWZ5aW5nX2tleRgCIAEoDFIMdmVyaWZ5aW5nS2V5Ek4KFWRlcG9zaXRfYWRkcmVzc19wcm9vZhgDIAEoCzIaLnNwYXJrLkRlcG9zaXRBZGRyZXNzUHJvb2ZSE2RlcG9zaXRBZGRyZXNzUHJvb2YSGwoJaXNfc3RhdGljGAUgASgIUghpc1N0YXRpYyJZCh5HZW5lcmF0ZURlcG9zaXRBZGRyZXNzUmVzcG9uc2USNwoPZGVwb3NpdF9hZGRyZXNzGAEgASgLMg4uc3BhcmsuQWRkcmVzc1IOZGVwb3NpdEFkZHJlc3MigAIKI0dlbmVyYXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXF1ZXN0EjUKEnNpZ25pbmdfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIQc2lnbmluZ1B1YmxpY0tleRI3ChNpZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUhFpZGVudGl0eVB1YmxpY0tleRIyCgduZXR3b3JrGAMgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIABSB25ldHdvcmsSNQoMaGFzaF92YXJpYW50GAQgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50Il8KJEdlbmVyYXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXNwb25zZRI3Cg9kZXBvc2l0X2FkZHJlc3MYASABKAsyDi5zcGFyay5BZGRyZXNzUg5kZXBvc2l0QWRkcmVzcyLFAQohUm90YXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXF1ZXN0EjUKEnNpZ25pbmdfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIQc2lnbmluZ1B1YmxpY0tleRIyCgduZXR3b3JrGAIgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIABSB25ldHdvcmsSNQoMaGFzaF92YXJpYW50GAMgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50Iq4BCiJSb3RhdGVTdGF0aWNEZXBvc2l0QWRkcmVzc1Jlc3BvbnNlEj4KE25ld19kZXBvc2l0X2FkZHJlc3MYASABKAsyDi5zcGFyay5BZGRyZXNzUhFuZXdEZXBvc2l0QWRkcmVzcxJIChhhcmNoaXZlZF9kZXBvc2l0X2FkZHJlc3MYAiABKAsyDi5zcGFyay5BZGRyZXNzUhZhcmNoaXZlZERlcG9zaXRBZGRyZXNzInkKBFVUWE8SFQoGcmF3X3R4GAEgASgMUgVyYXdUeBISCgR2b3V0GAIgASgNUgR2b3V0EjIKB25ldHdvcmsYAyABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgAFIHbmV0d29yaxISCgR0eGlkGAQgASgMUgR0eGlkIjkKCk5vZGVPdXRwdXQSFwoHbm9kZV9pZBgBIAEoCVIGbm9kZUlkEhIKBHZvdXQYAiABKA1SBHZvdXQipgEKClNpZ25pbmdKb2ISLAoSc2lnbmluZ19wdWJsaWNfa2V5GAEgASgMUhBzaWduaW5nUHVibGljS2V5EhUKBnJhd190eBgCIAEoDFIFcmF3VHgSUwoYc2lnbmluZ19ub25jZV9jb21taXRtZW50GAMgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50UhZzaWduaW5nTm9uY2VDb21taXRtZW50IsoCCg9TaWduaW5nS2V5c2hhcmUSKwoRb3duZXJfaWRlbnRpZmllcnMYASADKAlSEG93bmVySWRlbnRpZmllcnMSHAoJdGhyZXNob2xkGAIgASgNUgl0aHJlc2hvbGQSHQoKcHVibGljX2tleRgDIAEoDFIJcHVibGljS2V5Ek0KDXB1YmxpY19zaGFyZXMYBCADKAsyKC5zcGFyay5TaWduaW5nS2V5c2hhcmUuUHVibGljU2hhcmVzRW50cnlSDHB1YmxpY1NoYXJlcxI9Cgx1cGRhdGVkX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgt1cGRhdGVkVGltZRo/ChFQdWJsaWNTaGFyZXNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU6AjgBIsgECg1TaWduaW5nUmVzdWx0EkUKC3B1YmxpY19rZXlzGAEgAygLMiQuc3BhcmsuU2lnbmluZ1Jlc3VsdC5QdWJsaWNLZXlzRW50cnlSCnB1YmxpY0tleXMSbQoZc2lnbmluZ19ub25jZV9jb21taXRtZW50cxgCIAMoCzIxLnNwYXJrLlNpZ25pbmdSZXN1bHQuU2lnbmluZ05vbmNlQ29tbWl0bWVudHNFbnRyeVIXc2lnbmluZ05vbmNlQ29tbWl0bWVudHMSVAoQc2lnbmF0dXJlX3NoYXJlcxgDIAMoCzIpLnNwYXJrLlNpZ25pbmdSZXN1bHQuU2lnbmF0dXJlU2hhcmVzRW50cnlSD3NpZ25hdHVyZVNoYXJlcxJBChBzaWduaW5nX2tleXNoYXJlGAQgASgLMhYuc3BhcmsuU2lnbmluZ0tleXNoYXJlUg9zaWduaW5nS2V5c2hhcmUaPQoPUHVibGljS2V5c0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEaZQocU2lnbmluZ05vbmNlQ29tbWl0bWVudHNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIvCgV2YWx1ZRgCIAEoCzIZLmNvbW1vbi5TaWduaW5nQ29tbWl0bWVudFIFdmFsdWU6AjgBGkIKFFNpZ25hdHVyZVNoYXJlc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEikgMKEFJlbmV3TGVhZlJlcXVlc3QSFwoHbGVhZl9pZBgBIAEoCVIGbGVhZklkEmoKH3JlbmV3X25vZGVfdGltZWxvY2tfc2lnbmluZ19qb2IYAiABKAsyIi5zcGFyay5SZW5ld05vZGVUaW1lbG9ja1NpZ25pbmdKb2JIAFIbcmVuZXdOb2RlVGltZWxvY2tTaWduaW5nSm9iEnAKIXJlbmV3X3JlZnVuZF90aW1lbG9ja19zaWduaW5nX2pvYhgDIAEoCzIkLnNwYXJrLlJlbmV3UmVmdW5kVGltZWxvY2tTaWduaW5nSm9iSABSHXJlbmV3UmVmdW5kVGltZWxvY2tTaWduaW5nSm9iEncKJHJlbmV3X25vZGVfemVyb190aW1lbG9ja19zaWduaW5nX2pvYhgEIAEoCzImLnNwYXJrLlJlbmV3Tm9kZVplcm9UaW1lbG9ja1NpZ25pbmdKb2JIAFIfcmVuZXdOb2RlWmVyb1RpbWVsb2NrU2lnbmluZ0pvYkIOCgxzaWduaW5nX2pvYnMipwUKG1JlbmV3Tm9kZVRpbWVsb2NrU2lnbmluZ0pvYhJXChlzcGxpdF9ub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIVc3BsaXROb2RlVHhTaWduaW5nSm9iEmQKIHNwbGl0X25vZGVfZGlyZWN0X3R4X3NpZ25pbmdfam9iGAIgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIbc3BsaXROb2RlRGlyZWN0VHhTaWduaW5nSm9iEkwKE25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhBub2RlVHhTaWduaW5nSm9iElAKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSEnJlZnVuZFR4U2lnbmluZ0pvYhJZChpkaXJlY3Rfbm9kZV90eF9zaWduaW5nX2pvYhgFIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSFmRpcmVjdE5vZGVUeFNpZ25pbmdKb2ISXQocZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX2pvYhgGIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJvCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIuoDCh1SZW5ld1JlZnVuZFRpbWVsb2NrU2lnbmluZ0pvYhJMChNub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIQbm9kZVR4U2lnbmluZ0pvYhJQChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISWQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhZkaXJlY3ROb2RlVHhTaWduaW5nSm9iEl0KHGRpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhhkaXJlY3RSZWZ1bmRUeFNpZ25pbmdKb2ISbwomZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19qb2IYBSABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUiBkaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmluZ0pvYiKTAwofUmVuZXdOb2RlWmVyb1RpbWVsb2NrU2lnbmluZ0pvYhJMChNub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIQbm9kZVR4U2lnbmluZ0pvYhJQChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISWQoaZGlyZWN0X25vZGVfdHhfc2lnbmluZ19qb2IYAyABKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhZkaXJlY3ROb2RlVHhTaWduaW5nSm9iEm8KJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAUgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIgZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdKb2JKBAgEEAUi0wIKEVJlbmV3TGVhZlJlc3BvbnNlEl0KGnJlbmV3X25vZGVfdGltZWxvY2tfcmVzdWx0GAEgASgLMh4uc3BhcmsuUmVuZXdOb2RlVGltZWxvY2tSZXN1bHRIAFIXcmVuZXdOb2RlVGltZWxvY2tSZXN1bHQSYwoccmVuZXdfcmVmdW5kX3RpbWVsb2NrX3Jlc3VsdBgCIAEoCzIgLnNwYXJrLlJlbmV3UmVmdW5kVGltZWxvY2tSZXN1bHRIAFIZcmVuZXdSZWZ1bmRUaW1lbG9ja1Jlc3VsdBJqCh9yZW5ld19ub2RlX3plcm9fdGltZWxvY2tfcmVzdWx0GAMgASgLMiIuc3BhcmsuUmVuZXdOb2RlWmVyb1RpbWVsb2NrUmVzdWx0SABSG3JlbmV3Tm9kZVplcm9UaW1lbG9ja1Jlc3VsdEIOCgxyZW5ld19yZXN1bHQibgoXUmVuZXdOb2RlVGltZWxvY2tSZXN1bHQSLgoKc3BsaXRfbm9kZRgBIAEoCzIPLnNwYXJrLlRyZWVOb2RlUglzcGxpdE5vZGUSIwoEbm9kZRgCIAEoCzIPLnNwYXJrLlRyZWVOb2RlUgRub2RlIkAKGVJlbmV3UmVmdW5kVGltZWxvY2tSZXN1bHQSIwoEbm9kZRgBIAEoCzIPLnNwYXJrLlRyZWVOb2RlUgRub2RlInIKG1JlbmV3Tm9kZVplcm9UaW1lbG9ja1Jlc3VsdBIuCgpzcGxpdF9ub2RlGAEgASgLMg8uc3BhcmsuVHJlZU5vZGVSCXNwbGl0Tm9kZRIjCgRub2RlGAIgASgLMg8uc3BhcmsuVHJlZU5vZGVSBG5vZGUilwQKE05vZGVTaWduYXR1cmVTaGFyZXMSFwoHbm9kZV9pZBgBIAEoCVIGbm9kZUlkEkkKFm5vZGVfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhNub2RlVHhTaWduaW5nUmVzdWx0Ek0KGHJlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgDIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSFXJlZnVuZFR4U2lnbmluZ1Jlc3VsdBIjCg12ZXJpZnlpbmdfa2V5GAQgASgMUgx2ZXJpZnlpbmdLZXkSWgodZGlyZWN0X25vZGVfdHhfc2lnbmluZ19yZXN1bHQYBSABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0QgIYAVIZZGlyZWN0Tm9kZVR4U2lnbmluZ1Jlc3VsdBJeCh9kaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAYgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdEICGAFSG2RpcmVjdFJlZnVuZFR4U2lnbmluZ1Jlc3VsdBJsCilkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgHIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSI2RpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nUmVzdWx0IsoCCg5Ob2RlU2lnbmF0dXJlcxIXCgdub2RlX2lkGAEgASgJUgZub2RlSWQSKgoRbm9kZV90eF9zaWduYXR1cmUYAiABKAxSD25vZGVUeFNpZ25hdHVyZRIuChNyZWZ1bmRfdHhfc2lnbmF0dXJlGAMgASgMUhFyZWZ1bmRUeFNpZ25hdHVyZRI3ChhkaXJlY3Rfbm9kZV90eF9zaWduYXR1cmUYBCABKAxSFWRpcmVjdE5vZGVUeFNpZ25hdHVyZRI7ChpkaXJlY3RfcmVmdW5kX3R4X3NpZ25hdHVyZRgFIAEoDFIXZGlyZWN0UmVmdW5kVHhTaWduYXR1cmUSTQokZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmF0dXJlGAYgASgMUh9kaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmF0dXJlIooEChhTdGFydFRyZWVDcmVhdGlvblJlcXVlc3QSLgoTaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkSLwoNb25fY2hhaW5fdXR4bxgCIAEoCzILLnNwYXJrLlVUWE9SC29uQ2hhaW5VdHhvEkAKE3Jvb3RfdHhfc2lnbmluZ19qb2IYAyABKAsyES5zcGFyay5TaWduaW5nSm9iUhByb290VHhTaWduaW5nSm9iEkQKFXJlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSEnJlZnVuZFR4U2lnbmluZ0pvYhJNChpkaXJlY3Rfcm9vdF90eF9zaWduaW5nX2pvYhgFIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSFmRpcmVjdFJvb3RUeFNpZ25pbmdKb2ISUQocZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX2pvYhgGIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJjCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIo0BChlTdGFydFRyZWVDcmVhdGlvblJlc3BvbnNlEhcKB3RyZWVfaWQYASABKAlSBnRyZWVJZBJXChpyb290X25vZGVfc2lnbmF0dXJlX3NoYXJlcxgCIAEoCzIaLnNwYXJrLk5vZGVTaWduYXR1cmVTaGFyZXNSF3Jvb3ROb2RlU2lnbmF0dXJlU2hhcmVzIpkECh9TdGFydERlcG9zaXRUcmVlQ3JlYXRpb25SZXF1ZXN0Ei4KE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxSEWlkZW50aXR5UHVibGljS2V5Ei8KDW9uX2NoYWluX3V0eG8YAiABKAsyCy5zcGFyay5VVFhPUgtvbkNoYWluVXR4bxJAChNyb290X3R4X3NpZ25pbmdfam9iGAMgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIQcm9vdFR4U2lnbmluZ0pvYhJEChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYBCABKAsyES5zcGFyay5TaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISUQoaZGlyZWN0X3Jvb3RfdHhfc2lnbmluZ19qb2IYBSABKAsyES5zcGFyay5TaWduaW5nSm9iQgIYAVIWZGlyZWN0Um9vdFR4U2lnbmluZ0pvYhJVChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAYgASgLMhEuc3BhcmsuU2lnbmluZ0pvYkICGAFSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJjCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgHIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIpQBCiBTdGFydERlcG9zaXRUcmVlQ3JlYXRpb25SZXNwb25zZRIXCgd0cmVlX2lkGAEgASgJUgZ0cmVlSWQSVwoacm9vdF9ub2RlX3NpZ25hdHVyZV9zaGFyZXMYAiABKAsyGi5zcGFyay5Ob2RlU2lnbmF0dXJlU2hhcmVzUhdyb290Tm9kZVNpZ25hdHVyZVNoYXJlcyKfAwoiRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVxdWVzdBI3ChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUhFpZGVudGl0eVB1YmxpY0tleRIvCg1vbl9jaGFpbl91dHhvGAIgASgLMgsuc3BhcmsuVVRYT1ILb25DaGFpblV0eG8STAoTcm9vdF90eF9zaWduaW5nX2pvYhgDIAEoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSEHJvb3RUeFNpZ25pbmdKb2ISUAoVcmVmdW5kX3R4X3NpZ25pbmdfam9iGAQgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIScmVmdW5kVHhTaWduaW5nSm9iEm8KJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAUgASgLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIgZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdKb2IiUwojRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVzcG9uc2USLAoJcm9vdF9ub2RlGAEgASgLMg8uc3BhcmsuVHJlZU5vZGVSCHJvb3ROb2RlIpsBChJUb2tlbk91dHB1dFRvU3BlbmQSRgobcHJldl90b2tlbl90cmFuc2FjdGlvbl9oYXNoGAEgASgMQgf6QgR6AmggUhhwcmV2VG9rZW5UcmFuc2FjdGlvbkhhc2gSPQobcHJldl90b2tlbl90cmFuc2FjdGlvbl92b3V0GAIgASgNUhhwcmV2VG9rZW5UcmFuc2FjdGlvblZvdXQiWQoSVG9rZW5UcmFuc2ZlcklucHV0EkMKEG91dHB1dHNfdG9fc3BlbmQYASADKAsyGS5zcGFyay5Ub2tlbk91dHB1dFRvU3BlbmRSDm91dHB1dHNUb1NwZW5kIs8BCg5Ub2tlbk1pbnRJbnB1dBIzChFpc3N1ZXJfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIPaXNzdWVyUHVibGljS2V5EjoKGWlzc3Vlcl9wcm92aWRlZF90aW1lc3RhbXAYAiABKARSF2lzc3VlclByb3ZpZGVkVGltZXN0YW1wEjcKEHRva2VuX2lkZW50aWZpZXIYAyABKAxCB/pCBHoCaCBIAFIPdG9rZW5JZGVudGlmaWVyiAEBQhMKEV90b2tlbl9pZGVudGlmaWVyIvYCChBUb2tlbkNyZWF0ZUlucHV0EjMKEWlzc3Vlcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg9pc3N1ZXJQdWJsaWNLZXkSJgoKdG9rZW5fbmFtZRgCIAEoCUIH+kIEcgIYFFIJdG9rZW5OYW1lEioKDHRva2VuX3RpY2tlchgDIAEoCUIH+kIEcgIYBlILdG9rZW5UaWNrZXISJAoIZGVjaW1hbHMYBCABKA1CCPpCBSoDGP8BUghkZWNpbWFscxImCgptYXhfc3VwcGx5GAUgASgMQgf6QgR6AmgQUgltYXhTdXBwbHkSIQoMaXNfZnJlZXphYmxlGAYgASgIUgtpc0ZyZWV6YWJsZRJJChpjcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleRgHIAEoDEIH+kIEegJoIUgAUhdjcmVhdGlvbkVudGl0eVB1YmxpY0tleYgBAUIdChtfY3JlYXRpb25fZW50aXR5X3B1YmxpY19rZXkixwQKC1Rva2VuT3V0cHV0Eh0KAmlkGAEgASgJQgj6QgVyA7ABAUgAUgJpZIgBARIxChBvd25lcl9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUg5vd25lclB1YmxpY0tleRJBChVyZXZvY2F0aW9uX2NvbW1pdG1lbnQYAyABKAxCB/pCBHoCaCFIAVIUcmV2b2NhdGlvbkNvbW1pdG1lbnSIAQESMQoSd2l0aGRyYXdfYm9uZF9zYXRzGAQgASgESAJSEHdpdGhkcmF3Qm9uZFNhdHOIAQESTAogd2l0aGRyYXdfcmVsYXRpdmVfYmxvY2tfbG9ja3RpbWUYBSABKARIA1Idd2l0aGRyYXdSZWxhdGl2ZUJsb2NrTG9ja3RpbWWIAQESNgoQdG9rZW5fcHVibGljX2tleRgGIAEoDEIH+kIEegJoIUgEUg50b2tlblB1YmxpY0tleYgBARI3ChB0b2tlbl9pZGVudGlmaWVyGAggASgMQgf6QgR6AmggSAVSD3Rva2VuSWRlbnRpZmllcogBARIqCgx0b2tlbl9hbW91bnQYByABKAxCB/pCBHoCaBBSC3Rva2VuQW1vdW50QgUKA19pZEIYChZfcmV2b2NhdGlvbl9jb21taXRtZW50QhUKE193aXRoZHJhd19ib25kX3NhdHNCIwohX3dpdGhkcmF3X3JlbGF0aXZlX2Jsb2NrX2xvY2t0aW1lQhMKEV90b2tlbl9wdWJsaWNfa2V5QhMKEV90b2tlbl9pZGVudGlmaWVyIqUDChBUb2tlblRyYW5zYWN0aW9uEjYKCm1pbnRfaW5wdXQYASABKAsyFS5zcGFyay5Ub2tlbk1pbnRJbnB1dEgAUgltaW50SW5wdXQSQgoOdHJhbnNmZXJfaW5wdXQYAiABKAsyGS5zcGFyay5Ub2tlblRyYW5zZmVySW5wdXRIAFINdHJhbnNmZXJJbnB1dBI8CgxjcmVhdGVfaW5wdXQYBSABKAsyFy5zcGFyay5Ub2tlbkNyZWF0ZUlucHV0SABSC2NyZWF0ZUlucHV0EjcKDXRva2VuX291dHB1dHMYAyADKAsyEi5zcGFyay5Ub2tlbk91dHB1dFIMdG9rZW5PdXRwdXRzEloKI3NwYXJrX29wZXJhdG9yX2lkZW50aXR5X3B1YmxpY19rZXlzGAQgAygMQgz6QgmSAQYiBHoCaCFSH3NwYXJrT3BlcmF0b3JJZGVudGl0eVB1YmxpY0tleXMSMgoHbmV0d29yaxgKIAEoDjIOLnNwYXJrLk5ldHdvcmtCCPpCBYIBAiAAUgduZXR3b3JrQg4KDHRva2VuX2lucHV0cyJeChJTaWduYXR1cmVXaXRoSW5kZXgSJwoJc2lnbmF0dXJlGAEgASgMQgn6QgZ6BBBAGElSCXNpZ25hdHVyZRIfCgtpbnB1dF9pbmRleBgCIAEoDVIKaW5wdXRJbmRleCLFAQovT3BlcmF0b3JTcGVjaWZpY1Rva2VuVHJhbnNhY3Rpb25TaWduYWJsZVBheWxvYWQSSAocZmluYWxfdG9rZW5fdHJhbnNhY3Rpb25faGFzaBgBIAEoDEIH+kIEegJoIFIZZmluYWxUb2tlblRyYW5zYWN0aW9uSGFzaBJIChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUhlvcGVyYXRvcklkZW50aXR5UHVibGljS2V5IrYBCh5PcGVyYXRvclNwZWNpZmljT3duZXJTaWduYXR1cmUSQgoPb3duZXJfc2lnbmF0dXJlGAEgASgLMhkuc3BhcmsuU2lnbmF0dXJlV2l0aEluZGV4Ug5vd25lclNpZ25hdHVyZRJQCgdwYXlsb2FkGAIgASgLMjYuc3BhcmsuT3BlcmF0b3JTcGVjaWZpY1Rva2VuVHJhbnNhY3Rpb25TaWduYWJsZVBheWxvYWRSB3BheWxvYWQicgoZUmV2b2NhdGlvblNlY3JldFdpdGhJbmRleBIfCgtpbnB1dF9pbmRleBgBIAEoDVIKaW5wdXRJbmRleBI0ChFyZXZvY2F0aW9uX3NlY3JldBgCIAEoDEIH+kIEegJoIFIQcmV2b2NhdGlvblNlY3JldCL4AgoTRnJlZXplVG9rZW5zUGF5bG9hZBIxChBvd25lcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg5vd25lclB1YmxpY0tleRIxChB0b2tlbl9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUg50b2tlblB1YmxpY0tleRI6Chlpc3N1ZXJfcHJvdmlkZWRfdGltZXN0YW1wGAMgASgEUhdpc3N1ZXJQcm92aWRlZFRpbWVzdGFtcBJIChxvcGVyYXRvcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMQgf6QgR6AmghUhlvcGVyYXRvcklkZW50aXR5UHVibGljS2V5EicKD3Nob3VsZF91bmZyZWV6ZRgFIAEoCFIOc2hvdWxkVW5mcmVlemUSNwoQdG9rZW5faWRlbnRpZmllchgGIAEoDEIH+kIEegJoIEgAUg90b2tlbklkZW50aWZpZXKIAQFCEwoRX3Rva2VuX2lkZW50aWZpZXIimwEKE0ZyZWV6ZVRva2Vuc1JlcXVlc3QSTgoVZnJlZXplX3Rva2Vuc19wYXlsb2FkGAEgASgLMhouc3BhcmsuRnJlZXplVG9rZW5zUGF5bG9hZFITZnJlZXplVG9rZW5zUGF5bG9hZBI0ChBpc3N1ZXJfc2lnbmF0dXJlGAIgASgMQgn6QgZ6BBBAGElSD2lzc3VlclNpZ25hdHVyZSKJAQoURnJlZXplVG9rZW5zUmVzcG9uc2USPQoTaW1wYWN0ZWRfb3V0cHV0X2lkcxgBIAMoCUIN+kIKkgEHIgVyA7ABAVIRaW1wYWN0ZWRPdXRwdXRJZHMSMgoVaW1wYWN0ZWRfdG9rZW5fYW1vdW50GAIgASgMUhNpbXBhY3RlZFRva2VuQW1vdW50Iv0FCghUcmVlTm9kZRIOCgJpZBgBIAEoCVICaWQSFwoHdHJlZV9pZBgCIAEoCVIGdHJlZUlkEhQKBXZhbHVlGAMgASgEUgV2YWx1ZRIpCg5wYXJlbnRfbm9kZV9pZBgEIAEoCUgAUgxwYXJlbnROb2RlSWSIAQESFwoHbm9kZV90eBgFIAEoDFIGbm9kZVR4EhsKCXJlZnVuZF90eBgGIAEoDFIIcmVmdW5kVHgSEgoEdm91dBgHIAEoDVIEdm91dBIwChR2ZXJpZnlpbmdfcHVibGljX2tleRgIIAEoDFISdmVyaWZ5aW5nUHVibGljS2V5EjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYCSABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSQQoQc2lnbmluZ19rZXlzaGFyZRgKIAEoCzIWLnNwYXJrLlNpZ25pbmdLZXlzaGFyZVIPc2lnbmluZ0tleXNoYXJlEhYKBnN0YXR1cxgLIAEoCVIGc3RhdHVzEigKB25ldHdvcmsYDCABKA4yDi5zcGFyay5OZXR3b3JrUgduZXR3b3JrEj0KDGNyZWF0ZWRfdGltZRgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSC2NyZWF0ZWRUaW1lEj0KDHVwZGF0ZWRfdGltZRgOIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSC3VwZGF0ZWRUaW1lEjcKGG93bmVyX3NpZ25pbmdfcHVibGljX2tleRgPIAEoDFIVb3duZXJTaWduaW5nUHVibGljS2V5EhsKCWRpcmVjdF90eBgQIAEoDFIIZGlyZWN0VHgSKAoQZGlyZWN0X3JlZnVuZF90eBgRIAEoDFIOZGlyZWN0UmVmdW5kVHgSOgoaZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHgYEiABKAxSFmRpcmVjdEZyb21DcGZwUmVmdW5kVHhCEQoPX3BhcmVudF9ub2RlX2lkIpABCh1GaW5hbGl6ZU5vZGVTaWduYXR1cmVzUmVxdWVzdBIvCgZpbnRlbnQYASABKA4yFy5jb21tb24uU2lnbmF0dXJlSW50ZW50UgZpbnRlbnQSPgoPbm9kZV9zaWduYXR1cmVzGAIgAygLMhUuc3BhcmsuTm9kZVNpZ25hdHVyZXNSDm5vZGVTaWduYXR1cmVzIkcKHkZpbmFsaXplTm9kZVNpZ25hdHVyZXNSZXNwb25zZRIlCgVub2RlcxgBIAMoCzIPLnNwYXJrLlRyZWVOb2RlUgVub2RlcyJICgtTZWNyZXRTaGFyZRIhCgxzZWNyZXRfc2hhcmUYASABKAxSC3NlY3JldFNoYXJlEhYKBnByb29mcxgCIAMoDFIGcHJvb2ZzIiUKC1NlY3JldFByb29mEhYKBnByb29mcxgBIAMoDFIGcHJvb2ZzIq8CChZMZWFmUmVmdW5kVHhTaWduaW5nSm9iEhcKB2xlYWZfaWQYASABKAlSBmxlYWZJZBJEChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyES5zcGFyay5TaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISUQocZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX2pvYhgDIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSGGRpcmVjdFJlZnVuZFR4U2lnbmluZ0pvYhJjCiZkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX2pvYhgEIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSIGRpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nSm9iIr4CChZVc2VyU2lnbmVkVHhTaWduaW5nSm9iEhcKB2xlYWZfaWQYASABKAlSBmxlYWZJZBIsChJzaWduaW5nX3B1YmxpY19rZXkYAiABKAxSEHNpZ25pbmdQdWJsaWNLZXkSFQoGcmF3X3R4GAMgASgMUgVyYXdUeBJTChhzaWduaW5nX25vbmNlX2NvbW1pdG1lbnQYBCABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnRSFnNpZ25pbmdOb25jZUNvbW1pdG1lbnQSJQoOdXNlcl9zaWduYXR1cmUYBSABKAxSDXVzZXJTaWduYXR1cmUSSgoTc2lnbmluZ19jb21taXRtZW50cxgGIAEoCzIZLnNwYXJrLlNpZ25pbmdDb21taXRtZW50c1ISc2lnbmluZ0NvbW1pdG1lbnRzIvICChlMZWFmUmVmdW5kVHhTaWduaW5nUmVzdWx0EhcKB2xlYWZfaWQYASABKAlSBmxlYWZJZBJNChhyZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhVyZWZ1bmRUeFNpZ25pbmdSZXN1bHQSIwoNdmVyaWZ5aW5nX2tleRgDIAEoDFIMdmVyaWZ5aW5nS2V5EloKH2RpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBCABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhtkaXJlY3RSZWZ1bmRUeFNpZ25pbmdSZXN1bHQSbAopZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBSABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UiNkaXJlY3RGcm9tQ3BmcFJlZnVuZFR4U2lnbmluZ1Jlc3VsdCL1AwoeU3RhcnRVc2VyU2lnbmVkVHJhbnNmZXJSZXF1ZXN0Eh8KC3RyYW5zZmVyX2lkGAEgASgJUgp0cmFuc2ZlcklkEjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSQwoObGVhdmVzX3RvX3NlbmQYAyADKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUgxsZWF2ZXNUb1NlbmQSPwoccmVjZWl2ZXJfaWRlbnRpdHlfcHVibGljX2tleRgEIAEoDFIZcmVjZWl2ZXJJZGVudGl0eVB1YmxpY0tleRI7CgtleHBpcnlfdGltZRgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSCmV4cGlyeVRpbWUSUAoVZGlyZWN0X2xlYXZlc190b19zZW5kGAYgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlISZGlyZWN0TGVhdmVzVG9TZW5kEmIKH2RpcmVjdF9mcm9tX2NwZnBfbGVhdmVzX3RvX3NlbmQYByADKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhpkaXJlY3RGcm9tQ3BmcExlYXZlc1RvU2VuZCKpAwoUU3RhcnRUcmFuc2ZlclJlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRJDCg5sZWF2ZXNfdG9fc2VuZBgDIAMoCzIdLnNwYXJrLkxlYWZSZWZ1bmRUeFNpZ25pbmdKb2JSDGxlYXZlc1RvU2VuZBI/ChxyZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAQgASgMUhlyZWNlaXZlcklkZW50aXR5UHVibGljS2V5EjsKC2V4cGlyeV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFIKZXhwaXJ5VGltZRJBChB0cmFuc2Zlcl9wYWNrYWdlGAcgASgLMhYuc3BhcmsuVHJhbnNmZXJQYWNrYWdlUg90cmFuc2ZlclBhY2thZ2USIwoNc3BhcmtfaW52b2ljZRgKIAEoCVIMc3BhcmtJbnZvaWNlSgQIBhAHSgQICRAKIo8BChVTdGFydFRyYW5zZmVyUmVzcG9uc2USKwoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXISSQoPc2lnbmluZ19yZXN1bHRzGAIgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdFIOc2lnbmluZ1Jlc3VsdHMihwQKD1RyYW5zZmVyUGFja2FnZRJDCg5sZWF2ZXNfdG9fc2VuZBgBIAMoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSDGxlYXZlc1RvU2VuZBJXChFrZXlfdHdlYWtfcGFja2FnZRgCIAMoCzIrLnNwYXJrLlRyYW5zZmVyUGFja2FnZS5LZXlUd2Vha1BhY2thZ2VFbnRyeVIPa2V5VHdlYWtQYWNrYWdlEiUKDnVzZXJfc2lnbmF0dXJlGAMgASgMUg11c2VyU2lnbmF0dXJlElAKFWRpcmVjdF9sZWF2ZXNfdG9fc2VuZBgEIAMoCzIdLnNwYXJrLlVzZXJTaWduZWRUeFNpZ25pbmdKb2JSEmRpcmVjdExlYXZlc1RvU2VuZBJiCh9kaXJlY3RfZnJvbV9jcGZwX2xlYXZlc190b19zZW5kGAUgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIaZGlyZWN0RnJvbUNwZnBMZWF2ZXNUb1NlbmQSNQoMaGFzaF92YXJpYW50GAYgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50GkIKFEtleVR3ZWFrUGFja2FnZUVudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgMUgV2YWx1ZToCOAEiUgoRU2VuZExlYWZLZXlUd2Vha3MSPQoObGVhdmVzX3RvX3NlbmQYASADKAsyFy5zcGFyay5TZW5kTGVhZktleVR3ZWFrUgxsZWF2ZXNUb1NlbmQigwQKEFNlbmRMZWFmS2V5VHdlYWsSFwoHbGVhZl9pZBgBIAEoCVIGbGVhZklkEkAKEnNlY3JldF9zaGFyZV90d2VhaxgCIAEoCzISLnNwYXJrLlNlY3JldFNoYXJlUhBzZWNyZXRTaGFyZVR3ZWFrEl4KE3B1YmtleV9zaGFyZXNfdHdlYWsYAyADKAsyLi5zcGFyay5TZW5kTGVhZktleVR3ZWFrLlB1YmtleVNoYXJlc1R3ZWFrRW50cnlSEXB1YmtleVNoYXJlc1R3ZWFrEiMKDXNlY3JldF9jaXBoZXIYBCABKAxSDHNlY3JldENpcGhlchIcCglzaWduYXR1cmUYBSABKAxSCXNpZ25hdHVyZRIpChByZWZ1bmRfc2lnbmF0dXJlGAYgASgMUg9yZWZ1bmRTaWduYXR1cmUSNgoXZGlyZWN0X3JlZnVuZF9zaWduYXR1cmUYByABKAxSFWRpcmVjdFJlZnVuZFNpZ25hdHVyZRJICiFkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF9zaWduYXR1cmUYCCABKAxSHWRpcmVjdEZyb21DcGZwUmVmdW5kU2lnbmF0dXJlGkQKFlB1YmtleVNoYXJlc1R3ZWFrRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAxSBXZhbHVlOgI4ASLmAQoXRmluYWxpemVUcmFuc2ZlclJlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRI9Cg5sZWF2ZXNfdG9fc2VuZBgDIAMoCzIXLnNwYXJrLlNlbmRMZWFmS2V5VHdlYWtSDGxlYXZlc1RvU2VuZBIwChRzcGFya19wYXltZW50X2ludGVudBgEIAEoCVISc3BhcmtQYXltZW50SW50ZW50IssBCipGaW5hbGl6ZVRyYW5zZmVyV2l0aFRyYW5zZmVyUGFja2FnZVJlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRJBChB0cmFuc2Zlcl9wYWNrYWdlGAMgASgLMhYuc3BhcmsuVHJhbnNmZXJQYWNrYWdlUg90cmFuc2ZlclBhY2thZ2UiRwoYRmluYWxpemVUcmFuc2ZlclJlc3BvbnNlEisKCHRyYW5zZmVyGAEgASgLMg8uc3BhcmsuVHJhbnNmZXJSCHRyYW5zZmVyIsgECghUcmFuc2ZlchIOCgJpZBgBIAEoCVICaWQSOwoac2VuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSF3NlbmRlcklkZW50aXR5UHVibGljS2V5Ej8KHHJlY2VpdmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAyABKAxSGXJlY2VpdmVySWRlbnRpdHlQdWJsaWNLZXkSLQoGc3RhdHVzGAQgASgOMhUuc3BhcmsuVHJhbnNmZXJTdGF0dXNSBnN0YXR1cxIfCgt0b3RhbF92YWx1ZRgFIAEoBFIKdG90YWxWYWx1ZRI7CgtleHBpcnlfdGltZRgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSCmV4cGlyeVRpbWUSKwoGbGVhdmVzGAcgAygLMhMuc3BhcmsuVHJhbnNmZXJMZWFmUgZsZWF2ZXMSPQoMY3JlYXRlZF90aW1lGAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFILY3JlYXRlZFRpbWUSPQoMdXBkYXRlZF90aW1lGAkgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFILdXBkYXRlZFRpbWUSJwoEdHlwZRgKIAEoDjITLnNwYXJrLlRyYW5zZmVyVHlwZVIEdHlwZRIjCg1zcGFya19pbnZvaWNlGAsgASgJUgxzcGFya0ludm9pY2USKAoHbmV0d29yaxgMIAEoDjIOLnNwYXJrLk5ldHdvcmtSB25ldHdvcmsihAMKDFRyYW5zZmVyTGVhZhIjCgRsZWFmGAEgASgLMg8uc3BhcmsuVHJlZU5vZGVSBGxlYWYSIwoNc2VjcmV0X2NpcGhlchgCIAEoDFIMc2VjcmV0Q2lwaGVyEhwKCXNpZ25hdHVyZRgDIAEoDFIJc2lnbmF0dXJlEjQKFmludGVybWVkaWF0ZV9yZWZ1bmRfdHgYBCABKAxSFGludGVybWVkaWF0ZVJlZnVuZFR4EkEKHWludGVybWVkaWF0ZV9kaXJlY3RfcmVmdW5kX3R4GAUgASgMUhppbnRlcm1lZGlhdGVEaXJlY3RSZWZ1bmRUeBJTCidpbnRlcm1lZGlhdGVfZGlyZWN0X2Zyb21fY3BmcF9yZWZ1bmRfdHgYBiABKAxSImludGVybWVkaWF0ZURpcmVjdEZyb21DcGZwUmVmdW5kVHgSPgoccGVuZGluZ19rZXlfdHdlYWtfcHVibGljX2tleRgHIAEoDFIYcGVuZGluZ0tleVR3ZWFrUHVibGljS2V5IooFCg5UcmFuc2ZlckZpbHRlchJBChxyZWNlaXZlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMSABSGXJlY2VpdmVySWRlbnRpdHlQdWJsaWNLZXkSPQoac2VuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxIAFIXc2VuZGVySWRlbnRpdHlQdWJsaWNLZXkSUwomc2VuZGVyX29yX3JlY2VpdmVyX2lkZW50aXR5X3B1YmxpY19rZXkYPCABKAxIAFIhc2VuZGVyT3JSZWNlaXZlcklkZW50aXR5UHVibGljS2V5EiEKDHRyYW5zZmVyX2lkcxgDIAMoCVILdHJhbnNmZXJJZHMSFAoFbGltaXQYKCABKANSBWxpbWl0EhYKBm9mZnNldBgyIAEoA1IGb2Zmc2V0EikKBXR5cGVzGEYgAygOMhMuc3BhcmsuVHJhbnNmZXJUeXBlUgV0eXBlcxIoCgduZXR3b3JrGAQgASgOMg4uc3BhcmsuTmV0d29ya1IHbmV0d29yaxIxCghzdGF0dXNlcxhQIAMoDjIVLnNwYXJrLlRyYW5zZmVyU3RhdHVzUghzdGF0dXNlcxIiCgVvcmRlchgFIAEoDjIMLnNwYXJrLk9yZGVyUgVvcmRlchJBCg1jcmVhdGVkX2FmdGVyGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgBUgxjcmVhdGVkQWZ0ZXISQwoOY3JlYXRlZF9iZWZvcmUYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSAFSDWNyZWF0ZWRCZWZvcmVCDQoLcGFydGljaXBhbnRCDQoLdGltZV9maWx0ZXIiXwoWUXVlcnlUcmFuc2ZlcnNSZXNwb25zZRItCgl0cmFuc2ZlcnMYASADKAsyDy5zcGFyay5UcmFuc2ZlclIJdHJhbnNmZXJzEhYKBm9mZnNldBgCIAEoA1IGb2Zmc2V0IpUCChFDbGFpbUxlYWZLZXlUd2VhaxIXCgdsZWFmX2lkGAEgASgJUgZsZWFmSWQSQAoSc2VjcmV0X3NoYXJlX3R3ZWFrGAIgASgLMhIuc3BhcmsuU2VjcmV0U2hhcmVSEHNlY3JldFNoYXJlVHdlYWsSXwoTcHVia2V5X3NoYXJlc190d2VhaxgDIAMoCzIvLnNwYXJrLkNsYWltTGVhZktleVR3ZWFrLlB1YmtleVNoYXJlc1R3ZWFrRW50cnlSEXB1YmtleVNoYXJlc1R3ZWFrGkQKFlB1YmtleVNoYXJlc1R3ZWFrRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAxSBXZhbHVlOgI4ASJaChJDbGFpbUxlYWZLZXlUd2Vha3MSRAoRbGVhdmVzX3RvX3JlY2VpdmUYASADKAsyGC5zcGFyay5DbGFpbUxlYWZLZXlUd2Vha1IPbGVhdmVzVG9SZWNlaXZlIocECgxDbGFpbVBhY2thZ2USRQoPbGVhdmVzX3RvX2NsYWltGAEgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlINbGVhdmVzVG9DbGFpbRJUChFrZXlfdHdlYWtfcGFja2FnZRgCIAMoCzIoLnNwYXJrLkNsYWltUGFja2FnZS5LZXlUd2Vha1BhY2thZ2VFbnRyeVIPa2V5VHdlYWtQYWNrYWdlEiUKDnVzZXJfc2lnbmF0dXJlGAMgASgMUg11c2VyU2lnbmF0dXJlElIKFmRpcmVjdF9sZWF2ZXNfdG9fY2xhaW0YBCADKAsyHS5zcGFyay5Vc2VyU2lnbmVkVHhTaWduaW5nSm9iUhNkaXJlY3RMZWF2ZXNUb0NsYWltEmQKIGRpcmVjdF9mcm9tX2NwZnBfbGVhdmVzX3RvX2NsYWltGAUgAygLMh0uc3BhcmsuVXNlclNpZ25lZFR4U2lnbmluZ0pvYlIbZGlyZWN0RnJvbUNwZnBMZWF2ZXNUb0NsYWltEjUKDGhhc2hfdmFyaWFudBgGIAEoDjISLnNwYXJrLkhhc2hWYXJpYW50UgtoYXNoVmFyaWFudBpCChRLZXlUd2Vha1BhY2thZ2VFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU6AjgBIqwBChRDbGFpbVRyYW5zZmVyUmVxdWVzdBIfCgt0cmFuc2Zlcl9pZBgBIAEoCVIKdHJhbnNmZXJJZBI5Chlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAIgASgMUhZvd25lcklkZW50aXR5UHVibGljS2V5EjgKDWNsYWltX3BhY2thZ2UYAyABKAsyEy5zcGFyay5DbGFpbVBhY2thZ2VSDGNsYWltUGFja2FnZSJEChVDbGFpbVRyYW5zZmVyUmVzcG9uc2USKwoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXIiwQEKHUNsYWltVHJhbnNmZXJUd2Vha0tleXNSZXF1ZXN0Eh8KC3RyYW5zZmVyX2lkGAEgASgJUgp0cmFuc2ZlcklkEjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSRAoRbGVhdmVzX3RvX3JlY2VpdmUYAyADKAsyGC5zcGFyay5DbGFpbUxlYWZLZXlUd2Vha1IPbGVhdmVzVG9SZWNlaXZlIsUBCh9DbGFpbVRyYW5zZmVyU2lnblJlZnVuZHNSZXF1ZXN0Eh8KC3RyYW5zZmVyX2lkGAEgASgJUgp0cmFuc2ZlcklkEjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSQAoMc2lnbmluZ19qb2JzGAMgAygLMh0uc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ0pvYlILc2lnbmluZ0pvYnNKBAgEEAUibQogQ2xhaW1UcmFuc2ZlclNpZ25SZWZ1bmRzUmVzcG9uc2USSQoPc2lnbmluZ19yZXN1bHRzGAEgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdFIOc2lnbmluZ1Jlc3VsdHMi9wEKGVN0b3JlUHJlaW1hZ2VTaGFyZVJlcXVlc3QSIQoMcGF5bWVudF9oYXNoGAEgASgMUgtwYXltZW50SGFzaBI5Cg5wcmVpbWFnZV9zaGFyZRgCIAEoCzISLnNwYXJrLlNlY3JldFNoYXJlUg1wcmVpbWFnZVNoYXJlEhwKCXRocmVzaG9sZBgDIAEoDVIJdGhyZXNob2xkEiUKDmludm9pY2Vfc3RyaW5nGAQgASgJUg1pbnZvaWNlU3RyaW5nEjcKGHVzZXJfaWRlbnRpdHlfcHVibGljX2tleRgFIAEoDFIVdXNlcklkZW50aXR5UHVibGljS2V5IoECChtSZXF1ZXN0ZWRTaWduaW5nQ29tbWl0bWVudHMSewoZc2lnbmluZ19ub25jZV9jb21taXRtZW50cxgBIAMoCzI/LnNwYXJrLlJlcXVlc3RlZFNpZ25pbmdDb21taXRtZW50cy5TaWduaW5nTm9uY2VDb21taXRtZW50c0VudHJ5UhdzaWduaW5nTm9uY2VDb21taXRtZW50cxplChxTaWduaW5nTm9uY2VDb21taXRtZW50c0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5Ei8KBXZhbHVlGAIgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50UgV2YWx1ZToCOAEicwocR2V0U2lnbmluZ0NvbW1pdG1lbnRzUmVxdWVzdBIZCghub2RlX2lkcxgBIAMoCVIHbm9kZUlkcxIUCgVjb3VudBgCIAEoDVIFY291bnQSIgoNbm9kZV9pZF9jb3VudBgDIAEoDVILbm9kZUlkQ291bnQidAodR2V0U2lnbmluZ0NvbW1pdG1lbnRzUmVzcG9uc2USUwoTc2lnbmluZ19jb21taXRtZW50cxgBIAMoCzIiLnNwYXJrLlJlcXVlc3RlZFNpZ25pbmdDb21taXRtZW50c1ISc2lnbmluZ0NvbW1pdG1lbnRzItoBChJTaWduaW5nQ29tbWl0bWVudHMSYgoTc2lnbmluZ19jb21taXRtZW50cxgBIAMoCzIxLnNwYXJrLlNpZ25pbmdDb21taXRtZW50cy5TaWduaW5nQ29tbWl0bWVudHNFbnRyeVISc2lnbmluZ0NvbW1pdG1lbnRzGmAKF1NpZ25pbmdDb21taXRtZW50c0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5Ei8KBXZhbHVlGAIgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50UgV2YWx1ZToCOAEixgIKEFVzZXJTaWduZWRSZWZ1bmQSFwoHbm9kZV9pZBgBIAEoCVIGbm9kZUlkEhsKCXJlZnVuZF90eBgCIAEoDFIIcmVmdW5kVHgSJQoOdXNlcl9zaWduYXR1cmUYAyABKAxSDXVzZXJTaWduYXR1cmUSSgoTc2lnbmluZ19jb21taXRtZW50cxgEIAEoCzIZLnNwYXJrLlNpZ25pbmdDb21taXRtZW50c1ISc2lnbmluZ0NvbW1pdG1lbnRzElUKGXVzZXJfc2lnbmF0dXJlX2NvbW1pdG1lbnQYBSABKAsyGS5jb21tb24uU2lnbmluZ0NvbW1pdG1lbnRSF3VzZXJTaWduYXR1cmVDb21taXRtZW50EjIKB25ldHdvcmsYBiABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgAFIHbmV0d29yayI7ChJJbnZvaWNlQW1vdW50UHJvb2YSJQoOYm9sdDExX2ludm9pY2UYASABKAlSDWJvbHQxMUludm9pY2UiewoNSW52b2ljZUFtb3VudBIdCgp2YWx1ZV9zYXRzGAEgASgEUgl2YWx1ZVNhdHMSSwoUaW52b2ljZV9hbW91bnRfcHJvb2YYAiABKAsyGS5zcGFyay5JbnZvaWNlQW1vdW50UHJvb2ZSEmludm9pY2VBbW91bnRQcm9vZiLWAwobSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXF1ZXN0EiEKDHBheW1lbnRfaGFzaBgBIAEoDFILcGF5bWVudEhhc2gSOwoOaW52b2ljZV9hbW91bnQYAiABKAsyFC5zcGFyay5JbnZvaWNlQW1vdW50Ug1pbnZvaWNlQW1vdW50EkEKBnJlYXNvbhgDIAEoDjIpLnNwYXJrLkluaXRpYXRlUHJlaW1hZ2VTd2FwUmVxdWVzdC5SZWFzb25SBnJlYXNvbhJBCgh0cmFuc2ZlchgEIAEoCzIlLnNwYXJrLlN0YXJ0VXNlclNpZ25lZFRyYW5zZmVyUmVxdWVzdFIIdHJhbnNmZXISPwoccmVjZWl2ZXJfaWRlbnRpdHlfcHVibGljX2tleRgFIAEoDFIZcmVjZWl2ZXJJZGVudGl0eVB1YmxpY0tleRIZCghmZWVfc2F0cxgGIAEoBFIHZmVlU2F0cxJGChB0cmFuc2Zlcl9yZXF1ZXN0GAcgASgLMhsuc3BhcmsuU3RhcnRUcmFuc2ZlclJlcXVlc3RSD3RyYW5zZmVyUmVxdWVzdCItCgZSZWFzb24SDwoLUkVBU09OX1NFTkQQABISCg5SRUFTT05fUkVDRUlWRRABImcKHEluaXRpYXRlUHJlaW1hZ2VTd2FwUmVzcG9uc2USGgoIcHJlaW1hZ2UYASABKAxSCHByZWltYWdlEisKCHRyYW5zZmVyGAIgASgLMg8uc3BhcmsuVHJhbnNmZXJSCHRyYW5zZmVyIjIKCE91dFBvaW50EhIKBHR4aWQYASABKAxSBHR4aWQSEgoEdm91dBgCIAEoDVIEdm91dCKqAQoWQ29vcGVyYXRpdmVFeGl0UmVxdWVzdBI3Cgh0cmFuc2ZlchgBIAEoCzIbLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXF1ZXN0Ugh0cmFuc2ZlchIXCgdleGl0X2lkGAIgASgJUgZleGl0SWQSGwoJZXhpdF90eGlkGAMgASgMUghleGl0VHhpZBIhCgxjb25uZWN0b3JfdHgYBCABKAxSC2Nvbm5lY3RvclR4IpEBChdDb29wZXJhdGl2ZUV4aXRSZXNwb25zZRIrCgh0cmFuc2ZlchgBIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlchJJCg9zaWduaW5nX3Jlc3VsdHMYAiADKAsyIC5zcGFyay5MZWFmUmVmdW5kVHhTaWduaW5nUmVzdWx0Ug5zaWduaW5nUmVzdWx0cyKgAgoWQ291bnRlckxlYWZTd2FwUmVxdWVzdBI3Cgh0cmFuc2ZlchgBIAEoCzIbLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXF1ZXN0Ugh0cmFuc2ZlchIXCgdzd2FwX2lkGAIgASgJUgZzd2FwSWQSLAoSYWRhcHRvcl9wdWJsaWNfa2V5GAMgASgMUhBhZGFwdG9yUHVibGljS2V5EjkKGWRpcmVjdF9hZGFwdG9yX3B1YmxpY19rZXkYBCABKAxSFmRpcmVjdEFkYXB0b3JQdWJsaWNLZXkSSwojZGlyZWN0X2Zyb21fY3BmcF9hZGFwdG9yX3B1YmxpY19rZXkYBSABKAxSHmRpcmVjdEZyb21DcGZwQWRhcHRvclB1YmxpY0tleSKRAQoXQ291bnRlckxlYWZTd2FwUmVzcG9uc2USKwoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXISSQoPc2lnbmluZ19yZXN1bHRzGAIgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdFIOc2lnbmluZ1Jlc3VsdHMiogEKFlJlZnJlc2hUaW1lbG9ja1JlcXVlc3QSFwoHbGVhZl9pZBgBIAEoCVIGbGVhZklkEjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSNAoMc2lnbmluZ19qb2JzGAMgAygLMhEuc3BhcmsuU2lnbmluZ0pvYlILc2lnbmluZ0pvYnMigAEKHFJlZnJlc2hUaW1lbG9ja1NpZ25pbmdSZXN1bHQSOwoOc2lnbmluZ19yZXN1bHQYASABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0Ug1zaWduaW5nUmVzdWx0EiMKDXZlcmlmeWluZ19rZXkYAiABKAxSDHZlcmlmeWluZ0tleSJnChdSZWZyZXNoVGltZWxvY2tSZXNwb25zZRJMCg9zaWduaW5nX3Jlc3VsdHMYASADKAsyIy5zcGFyay5SZWZyZXNoVGltZWxvY2tTaWduaW5nUmVzdWx0Ug5zaWduaW5nUmVzdWx0cyL2AwoRRXh0ZW5kTGVhZlJlcXVlc3QSFwoHbGVhZl9pZBgBIAEoCVIGbGVhZklkEjkKGW93bmVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSFm93bmVySWRlbnRpdHlQdWJsaWNLZXkSQAoTbm9kZV90eF9zaWduaW5nX2pvYhgDIAEoCzIRLnNwYXJrLlNpZ25pbmdKb2JSEG5vZGVUeFNpZ25pbmdKb2ISRAoVcmVmdW5kX3R4X3NpZ25pbmdfam9iGAQgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIScmVmdW5kVHhTaWduaW5nSm9iEk0KGmRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfam9iGAUgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIWZGlyZWN0Tm9kZVR4U2lnbmluZ0pvYhJRChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAYgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIYZGlyZWN0UmVmdW5kVHhTaWduaW5nSm9iEmMKJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAcgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIgZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdKb2IiewoXRXh0ZW5kTGVhZlNpZ25pbmdSZXN1bHQSOwoOc2lnbmluZ19yZXN1bHQYASABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0Ug1zaWduaW5nUmVzdWx0EiMKDXZlcmlmeWluZ19rZXkYAiABKAxSDHZlcmlmeWluZ0tleSKbBAoSRXh0ZW5kTGVhZlJlc3BvbnNlEhcKB2xlYWZfaWQYASABKAlSBmxlYWZJZBJTChZub2RlX3R4X3NpZ25pbmdfcmVzdWx0GAIgASgLMh4uc3BhcmsuRXh0ZW5kTGVhZlNpZ25pbmdSZXN1bHRSE25vZGVUeFNpZ25pbmdSZXN1bHQSVwoYcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAMgASgLMh4uc3BhcmsuRXh0ZW5kTGVhZlNpZ25pbmdSZXN1bHRSFXJlZnVuZFR4U2lnbmluZ1Jlc3VsdBJgCh1kaXJlY3Rfbm9kZV90eF9zaWduaW5nX3Jlc3VsdBgEIAEoCzIeLnNwYXJrLkV4dGVuZExlYWZTaWduaW5nUmVzdWx0UhlkaXJlY3ROb2RlVHhTaWduaW5nUmVzdWx0EmQKH2RpcmVjdF9yZWZ1bmRfdHhfc2lnbmluZ19yZXN1bHQYBSABKAsyHi5zcGFyay5FeHRlbmRMZWFmU2lnbmluZ1Jlc3VsdFIbZGlyZWN0UmVmdW5kVHhTaWduaW5nUmVzdWx0EnYKKWRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAYgASgLMh4uc3BhcmsuRXh0ZW5kTGVhZlNpZ25pbmdSZXN1bHRSI2RpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nUmVzdWx0InMKEkFkZHJlc3NSZXF1ZXN0Tm9kZRImCg91c2VyX3B1YmxpY19rZXkYASABKAxSDXVzZXJQdWJsaWNLZXkSNQoIY2hpbGRyZW4YAiADKAsyGS5zcGFyay5BZGRyZXNzUmVxdWVzdE5vZGVSCGNoaWxkcmVuIoMCChlQcmVwYXJlVHJlZUFkZHJlc3NSZXF1ZXN0EkEKEnBhcmVudF9ub2RlX291dHB1dBgBIAEoCzIRLnNwYXJrLk5vZGVPdXRwdXRIAFIQcGFyZW50Tm9kZU91dHB1dBIxCg1vbl9jaGFpbl91dHhvGAIgASgLMgsuc3BhcmsuVVRYT0gAUgtvbkNoYWluVXR4bxItCgRub2RlGAMgASgLMhkuc3BhcmsuQWRkcmVzc1JlcXVlc3ROb2RlUgRub2RlEjcKGHVzZXJfaWRlbnRpdHlfcHVibGljX2tleRgEIAEoDFIVdXNlcklkZW50aXR5UHVibGljS2V5QggKBnNvdXJjZSJnCgtBZGRyZXNzTm9kZRIoCgdhZGRyZXNzGAEgASgLMg4uc3BhcmsuQWRkcmVzc1IHYWRkcmVzcxIuCghjaGlsZHJlbhgCIAMoCzISLnNwYXJrLkFkZHJlc3NOb2RlUghjaGlsZHJlbiJEChpQcmVwYXJlVHJlZUFkZHJlc3NSZXNwb25zZRImCgRub2RlGAEgASgLMhIuc3BhcmsuQWRkcmVzc05vZGVSBG5vZGUizgMKDENyZWF0aW9uTm9kZRJAChNub2RlX3R4X3NpZ25pbmdfam9iGAEgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIQbm9kZVR4U2lnbmluZ0pvYhJEChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAiABKAsyES5zcGFyay5TaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISLwoIY2hpbGRyZW4YAyADKAsyEy5zcGFyay5DcmVhdGlvbk5vZGVSCGNoaWxkcmVuEk0KGmRpcmVjdF9ub2RlX3R4X3NpZ25pbmdfam9iGAQgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIWZGlyZWN0Tm9kZVR4U2lnbmluZ0pvYhJRChxkaXJlY3RfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAUgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIYZGlyZWN0UmVmdW5kVHhTaWduaW5nSm9iEmMKJmRpcmVjdF9mcm9tX2NwZnBfcmVmdW5kX3R4X3NpZ25pbmdfam9iGAYgASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIgZGlyZWN0RnJvbUNwZnBSZWZ1bmRUeFNpZ25pbmdKb2Ii9QEKEUNyZWF0ZVRyZWVSZXF1ZXN0EkEKEnBhcmVudF9ub2RlX291dHB1dBgBIAEoCzIRLnNwYXJrLk5vZGVPdXRwdXRIAFIQcGFyZW50Tm9kZU91dHB1dBIxCg1vbl9jaGFpbl91dHhvGAIgASgLMgsuc3BhcmsuVVRYT0gAUgtvbkNoYWluVXR4bxInCgRub2RlGAMgASgLMhMuc3BhcmsuQ3JlYXRpb25Ob2RlUgRub2RlEjcKGHVzZXJfaWRlbnRpdHlfcHVibGljX2tleRgEIAEoDFIVdXNlcklkZW50aXR5UHVibGljS2V5QggKBnNvdXJjZSKkBAoUQ3JlYXRpb25SZXNwb25zZU5vZGUSFwoHbm9kZV9pZBgBIAEoCVIGbm9kZUlkEkkKFm5vZGVfdHhfc2lnbmluZ19yZXN1bHQYAiABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhNub2RlVHhTaWduaW5nUmVzdWx0Ek0KGHJlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgDIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSFXJlZnVuZFR4U2lnbmluZ1Jlc3VsdBI3CghjaGlsZHJlbhgEIAMoCzIbLnNwYXJrLkNyZWF0aW9uUmVzcG9uc2VOb2RlUghjaGlsZHJlbhJWCh1kaXJlY3Rfbm9kZV90eF9zaWduaW5nX3Jlc3VsdBgFIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSGWRpcmVjdE5vZGVUeFNpZ25pbmdSZXN1bHQSWgofZGlyZWN0X3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgGIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSG2RpcmVjdFJlZnVuZFR4U2lnbmluZ1Jlc3VsdBJsCilkaXJlY3RfZnJvbV9jcGZwX3JlZnVuZF90eF9zaWduaW5nX3Jlc3VsdBgHIAEoCzIULnNwYXJrLlNpZ25pbmdSZXN1bHRSI2RpcmVjdEZyb21DcGZwUmVmdW5kVHhTaWduaW5nUmVzdWx0IkUKEkNyZWF0ZVRyZWVSZXNwb25zZRIvCgRub2RlGAEgASgLMhsuc3BhcmsuQ3JlYXRpb25SZXNwb25zZU5vZGVSBG5vZGUihAEKE1NpZ25pbmdPcGVyYXRvckluZm8SFAoFaW5kZXgYASABKARSBWluZGV4Eh4KCmlkZW50aWZpZXIYAiABKAlSCmlkZW50aWZpZXISHQoKcHVibGljX2tleRgDIAEoDFIJcHVibGljS2V5EhgKB2FkZHJlc3MYBCABKAlSB2FkZHJlc3Mi6wEKHkdldFNpZ25pbmdPcGVyYXRvckxpc3RSZXNwb25zZRJoChFzaWduaW5nX29wZXJhdG9ycxgBIAMoCzI7LnNwYXJrLkdldFNpZ25pbmdPcGVyYXRvckxpc3RSZXNwb25zZS5TaWduaW5nT3BlcmF0b3JzRW50cnlSEHNpZ25pbmdPcGVyYXRvcnMaXwoVU2lnbmluZ09wZXJhdG9yc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EjAKBXZhbHVlGAIgASgLMhouc3BhcmsuU2lnbmluZ09wZXJhdG9ySW5mb1IFdmFsdWU6AjgBInIKHVF1ZXJ5VXNlclNpZ25lZFJlZnVuZHNSZXF1ZXN0EiEKDHBheW1lbnRfaGFzaBgBIAEoDFILcGF5bWVudEhhc2gSLgoTaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkinAEKHlF1ZXJ5VXNlclNpZ25lZFJlZnVuZHNSZXNwb25zZRJHChN1c2VyX3NpZ25lZF9yZWZ1bmRzGAEgAygLMhcuc3BhcmsuVXNlclNpZ25lZFJlZnVuZFIRdXNlclNpZ25lZFJlZnVuZHMSKwoIdHJhbnNmZXIYAyABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXJKBAgCEAMipAMKG1ByZWltYWdlUmVxdWVzdFdpdGhUcmFuc2ZlchIqCgxwYXltZW50X2hhc2gYASABKAxCB/pCBHoCaCBSC3BheW1lbnRIYXNoEkEKGHJlY2VpdmVyX2lkZW50aXR5X3B1YmtleRgCIAEoDEIH+kIEegJoIVIWcmVjZWl2ZXJJZGVudGl0eVB1YmtleRI0CgZzdGF0dXMYAyABKA4yHC5zcGFyay5QcmVpbWFnZVJlcXVlc3RTdGF0dXNSBnN0YXR1cxI9CgxjcmVhdGVkX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgtjcmVhdGVkVGltZRIwCgh0cmFuc2ZlchgFIAEoCzIPLnNwYXJrLlRyYW5zZmVySABSCHRyYW5zZmVyiAEBEh8KCHByZWltYWdlGAYgASgMSAFSCHByZWltYWdliAEBEjQKFnNlbmRlcl9pZGVudGl0eV9wdWJrZXkYByABKAxSFHNlbmRlcklkZW50aXR5UHVia2V5QgsKCV90cmFuc2ZlckILCglfcHJlaW1hZ2UixAIKEFF1ZXJ5SHRsY1JlcXVlc3QSJQoOcGF5bWVudF9oYXNoZXMYASADKAxSDXBheW1lbnRIYXNoZXMSNwoTaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDEIH+kIEegJoIVIRaWRlbnRpdHlQdWJsaWNLZXkSOQoGc3RhdHVzGAMgASgOMhwuc3BhcmsuUHJlaW1hZ2VSZXF1ZXN0U3RhdHVzSABSBnN0YXR1c4gBARIUCgVsaW1pdBgEIAEoA1IFbGltaXQSFgoGb2Zmc2V0GAUgASgDUgZvZmZzZXQSIQoMdHJhbnNmZXJfaWRzGAYgAygJUgt0cmFuc2ZlcklkcxI5CgptYXRjaF9yb2xlGAcgASgOMhouc3BhcmsuUHJlaW1hZ2VSZXF1ZXN0Um9sZVIJbWF0Y2hSb2xlQgkKB19zdGF0dXMifAoRUXVlcnlIdGxjUmVzcG9uc2USTwoRcHJlaW1hZ2VfcmVxdWVzdHMYASADKAsyIi5zcGFyay5QcmVpbWFnZVJlcXVlc3RXaXRoVHJhbnNmZXJSEHByZWltYWdlUmVxdWVzdHMSFgoGb2Zmc2V0GAIgASgDUgZvZmZzZXQihwEKFlByb3ZpZGVQcmVpbWFnZVJlcXVlc3QSIQoMcGF5bWVudF9oYXNoGAEgASgMUgtwYXltZW50SGFzaBIaCghwcmVpbWFnZRgCIAEoDFIIcHJlaW1hZ2USLgoTaWRlbnRpdHlfcHVibGljX2tleRgDIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkiRgoXUHJvdmlkZVByZWltYWdlUmVzcG9uc2USKwoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXIihQEKFFF1ZXJ5UHJlaW1hZ2VSZXF1ZXN0EioKDHBheW1lbnRfaGFzaBgBIAEoDEIH+kIEegJoIFILcGF5bWVudEhhc2gSQQoYcmVjZWl2ZXJfaWRlbnRpdHlfcHVia2V5GAIgASgMQgf6QgR6AmghUhZyZWNlaXZlcklkZW50aXR5UHVia2V5IkUKFVF1ZXJ5UHJlaW1hZ2VSZXNwb25zZRIfCghwcmVpbWFnZRgBIAEoDEgAUghwcmVpbWFnZYgBAUILCglfcHJlaW1hZ2UiKAoLVHJlZU5vZGVJZHMSGQoIbm9kZV9pZHMYASADKAlSB25vZGVJZHMiuAIKEVF1ZXJ5Tm9kZXNSZXF1ZXN0EjQKFW93bmVyX2lkZW50aXR5X3B1YmtleRgBIAEoDEgAUhNvd25lcklkZW50aXR5UHVia2V5Ei8KCG5vZGVfaWRzGAIgASgLMhIuc3BhcmsuVHJlZU5vZGVJZHNIAFIHbm9kZUlkcxInCg9pbmNsdWRlX3BhcmVudHMYAyABKAhSDmluY2x1ZGVQYXJlbnRzEhQKBWxpbWl0GAQgASgDUgVsaW1pdBIWCgZvZmZzZXQYBSABKANSBm9mZnNldBIoCgduZXR3b3JrGAYgASgOMg4uc3BhcmsuTmV0d29ya1IHbmV0d29yaxIxCghzdGF0dXNlcxgHIAMoDjIVLnNwYXJrLlRyZWVOb2RlU3RhdHVzUghzdGF0dXNlc0IICgZzb3VyY2UiswEKElF1ZXJ5Tm9kZXNSZXNwb25zZRI6CgVub2RlcxgBIAMoCzIkLnNwYXJrLlF1ZXJ5Tm9kZXNSZXNwb25zZS5Ob2Rlc0VudHJ5UgVub2RlcxIWCgZvZmZzZXQYAiABKANSBm9mZnNldBpJCgpOb2Rlc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EiUKBXZhbHVlGAIgASgLMg8uc3BhcmsuVHJlZU5vZGVSBXZhbHVlOgI4ASJ1ChVDYW5jZWxUcmFuc2ZlclJlcXVlc3QSHwoLdHJhbnNmZXJfaWQYASABKAlSCnRyYW5zZmVySWQSOwoac2VuZGVyX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxSF3NlbmRlcklkZW50aXR5UHVibGljS2V5IkUKFkNhbmNlbFRyYW5zZmVyUmVzcG9uc2USKwoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXIirAEKIlF1ZXJ5VW51c2VkRGVwb3NpdEFkZHJlc3Nlc1JlcXVlc3QSLgoTaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkSKAoHbmV0d29yaxgCIAEoDjIOLnNwYXJrLk5ldHdvcmtSB25ldHdvcmsSFAoFbGltaXQYAyABKANSBWxpbWl0EhYKBm9mZnNldBgEIAEoA1IGb2Zmc2V0IqUCCiJRdWVyeVN0YXRpY0RlcG9zaXRBZGRyZXNzZXNSZXF1ZXN0Ei4KE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxSEWlkZW50aXR5UHVibGljS2V5EigKB25ldHdvcmsYAiABKA4yDi5zcGFyay5OZXR3b3JrUgduZXR3b3JrEhQKBWxpbWl0GAQgASgDUgVsaW1pdBIWCgZvZmZzZXQYBSABKANSBm9mZnNldBIsCg9kZXBvc2l0X2FkZHJlc3MYBiABKAlIAFIOZGVwb3NpdEFkZHJlc3OIAQESNQoMaGFzaF92YXJpYW50GAcgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50QhIKEF9kZXBvc2l0X2FkZHJlc3MiygIKGURlcG9zaXRBZGRyZXNzUXVlcnlSZXN1bHQSJwoPZGVwb3NpdF9hZGRyZXNzGAEgASgJUg5kZXBvc2l0QWRkcmVzcxI1Chd1c2VyX3NpZ25pbmdfcHVibGljX2tleRgCIAEoDFIUdXNlclNpZ25pbmdQdWJsaWNLZXkSMAoUdmVyaWZ5aW5nX3B1YmxpY19rZXkYAyABKAxSEnZlcmlmeWluZ1B1YmxpY0tleRImCgdsZWFmX2lkGAQgASgJQgj6QgVyA7ABAUgAUgZsZWFmSWSIAQESTwoTcHJvb2Zfb2ZfcG9zc2Vzc2lvbhgFIAEoCzIaLnNwYXJrLkRlcG9zaXRBZGRyZXNzUHJvb2ZIAVIRcHJvb2ZPZlBvc3Nlc3Npb26IAQFCCgoIX2xlYWZfaWRCFgoUX3Byb29mX29mX3Bvc3Nlc3Npb24ijAEKI1F1ZXJ5VW51c2VkRGVwb3NpdEFkZHJlc3Nlc1Jlc3BvbnNlEk0KEWRlcG9zaXRfYWRkcmVzc2VzGAEgAygLMiAuc3BhcmsuRGVwb3NpdEFkZHJlc3NRdWVyeVJlc3VsdFIQZGVwb3NpdEFkZHJlc3NlcxIWCgZvZmZzZXQYAiABKANSBm9mZnNldCJ0CiNRdWVyeVN0YXRpY0RlcG9zaXRBZGRyZXNzZXNSZXNwb25zZRJNChFkZXBvc2l0X2FkZHJlc3NlcxgBIAMoCzIgLnNwYXJrLkRlcG9zaXRBZGRyZXNzUXVlcnlSZXN1bHRSEGRlcG9zaXRBZGRyZXNzZXMibwoTUXVlcnlCYWxhbmNlUmVxdWVzdBIuChNpZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMUhFpZGVudGl0eVB1YmxpY0tleRIoCgduZXR3b3JrGAIgASgOMg4uc3BhcmsuTmV0d29ya1IHbmV0d29yayLFAQoUUXVlcnlCYWxhbmNlUmVzcG9uc2USGAoHYmFsYW5jZRgBIAEoBFIHYmFsYW5jZRJSCg1ub2RlX2JhbGFuY2VzGAIgAygLMi0uc3BhcmsuUXVlcnlCYWxhbmNlUmVzcG9uc2UuTm9kZUJhbGFuY2VzRW50cnlSDG5vZGVCYWxhbmNlcxo/ChFOb2RlQmFsYW5jZXNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoBFIFdmFsdWU6AjgBIsUBCgxTcGFya0FkZHJlc3MSLgoTaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDFIRaWRlbnRpdHlQdWJsaWNLZXkSSwoUc3BhcmtfaW52b2ljZV9maWVsZHMYAiABKAsyGS5zcGFyay5TcGFya0ludm9pY2VGaWVsZHNSEnNwYXJrSW52b2ljZUZpZWxkcxIqCglzaWduYXR1cmUYAyABKAxCB/pCBHoCaEBIAFIJc2lnbmF0dXJliAEBQgwKCl9zaWduYXR1cmUinAMKElNwYXJrSW52b2ljZUZpZWxkcxIYCgd2ZXJzaW9uGAEgASgNUgd2ZXJzaW9uEhcKAmlkGAIgASgMQgf6QgR6AmgQUgJpZBI9Cg50b2tlbnNfcGF5bWVudBgDIAEoCzIULnNwYXJrLlRva2Vuc1BheW1lbnRIAFINdG9rZW5zUGF5bWVudBI3CgxzYXRzX3BheW1lbnQYBCABKAsyEi5zcGFyay5TYXRzUGF5bWVudEgAUgtzYXRzUGF5bWVudBIgCgRtZW1vGAUgASgJQgf6QgRyAih4SAFSBG1lbW+IAQESOAoRc2VuZGVyX3B1YmxpY19rZXkYBiABKAxCB/pCBHoCaCFIAlIPc2VuZGVyUHVibGljS2V5iAEBEkAKC2V4cGlyeV90aW1lGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgDUgpleHBpcnlUaW1liAEBQg4KDHBheW1lbnRfdHlwZUIHCgVfbWVtb0IUChJfc2VuZGVyX3B1YmxpY19rZXlCDgoMX2V4cGlyeV90aW1lIjUKC1NhdHNQYXltZW50EhsKBmFtb3VudBgBIAEoBEgAUgZhbW91bnSIAQFCCQoHX2Ftb3VudCKOAQoNVG9rZW5zUGF5bWVudBI3ChB0b2tlbl9pZGVudGlmaWVyGAEgASgMQgf6QgR6AmggSABSD3Rva2VuSWRlbnRpZmllcogBARIkCgZhbW91bnQYAiABKAxCB/pCBHoCGBBIAVIGYW1vdW50iAEBQhMKEV90b2tlbl9pZGVudGlmaWVyQgkKB19hbW91bnQi/QEKJkluaXRpYXRlU3RhdGljRGVwb3NpdFV0eG9SZWZ1bmRSZXF1ZXN0Ei8KDW9uX2NoYWluX3V0eG8YASABKAsyCy5zcGFyay5VVFhPUgtvbkNoYWluVXR4bxJEChVyZWZ1bmRfdHhfc2lnbmluZ19qb2IYAyABKAsyES5zcGFyay5TaWduaW5nSm9iUhJyZWZ1bmRUeFNpZ25pbmdKb2ISJQoOdXNlcl9zaWduYXR1cmUYBCABKAxSDXVzZXJTaWduYXR1cmUSNQoMaGFzaF92YXJpYW50GAUgASgOMhIuc3BhcmsuSGFzaFZhcmlhbnRSC2hhc2hWYXJpYW50IsMBCidJbml0aWF0ZVN0YXRpY0RlcG9zaXRVdHhvUmVmdW5kUmVzcG9uc2USTQoYcmVmdW5kX3R4X3NpZ25pbmdfcmVzdWx0GAEgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdFIVcmVmdW5kVHhTaWduaW5nUmVzdWx0EkkKD2RlcG9zaXRfYWRkcmVzcxgCIAEoCzIgLnNwYXJrLkRlcG9zaXRBZGRyZXNzUXVlcnlSZXN1bHRSDmRlcG9zaXRBZGRyZXNzIrADChdJbml0aWF0ZVV0eG9Td2FwUmVxdWVzdBIvCg1vbl9jaGFpbl91dHhvGAEgASgLMgsuc3BhcmsuVVRYT1ILb25DaGFpblV0eG8SPQoMcmVxdWVzdF90eXBlGAIgASgOMhouc3BhcmsuVXR4b1N3YXBSZXF1ZXN0VHlwZVILcmVxdWVzdFR5cGUSLgoSY3JlZGl0X2Ftb3VudF9zYXRzGAMgASgESABSEGNyZWRpdEFtb3VudFNhdHMSIgoMbWF4X2ZlZV9zYXRzGAQgASgESABSCm1heEZlZVNhdHMSIwoNc3NwX3NpZ25hdHVyZRgFIAEoDFIMc3NwU2lnbmF0dXJlEiUKDnVzZXJfc2lnbmF0dXJlGAYgASgMUg11c2VyU2lnbmF0dXJlEjcKCHRyYW5zZmVyGAcgASgLMhsuc3BhcmsuU3RhcnRUcmFuc2ZlclJlcXVlc3RSCHRyYW5zZmVyEkIKFHNwZW5kX3R4X3NpZ25pbmdfam9iGAggASgLMhEuc3BhcmsuU2lnbmluZ0pvYlIRc3BlbmRUeFNpZ25pbmdKb2JCCAoGYW1vdW50It8BChhJbml0aWF0ZVV0eG9Td2FwUmVzcG9uc2USSwoXc3BlbmRfdHhfc2lnbmluZ19yZXN1bHQYASABKAsyFC5zcGFyay5TaWduaW5nUmVzdWx0UhRzcGVuZFR4U2lnbmluZ1Jlc3VsdBIrCgh0cmFuc2ZlchgCIAEoCzIPLnNwYXJrLlRyYW5zZmVyUgh0cmFuc2ZlchJJCg9kZXBvc2l0X2FkZHJlc3MYAyABKAsyIC5zcGFyay5EZXBvc2l0QWRkcmVzc1F1ZXJ5UmVzdWx0Ug5kZXBvc2l0QWRkcmVzcyKLAQoLRXhpdGluZ1RyZWUSFwoHdHJlZV9pZBgBIAEoCVIGdHJlZUlkElEKF3VzZXJfc2lnbmluZ19jb21taXRtZW50GAIgASgLMhkuY29tbW9uLlNpZ25pbmdDb21taXRtZW50UhV1c2VyU2lnbmluZ0NvbW1pdG1lbnQSEAoDdmluGAMgASgNUgN2aW4inAEKH0V4aXRTaW5nbGVOb2RlVHJlZVNpZ25pbmdSZXN1bHQSFwoHdHJlZV9pZBgBIAEoCVIGdHJlZUlkEjsKDnNpZ25pbmdfcmVzdWx0GAIgASgLMhQuc3BhcmsuU2lnbmluZ1Jlc3VsdFINc2lnbmluZ1Jlc3VsdBIjCg12ZXJpZnlpbmdfa2V5GAMgASgMUgx2ZXJpZnlpbmdLZXkiTQoYQml0Y29pblRyYW5zYWN0aW9uT3V0cHV0EhQKBXZhbHVlGAEgASgDUgV2YWx1ZRIbCglwa19zY3JpcHQYAiABKAxSCHBrU2NyaXB0IvMBChpFeGl0U2luZ2xlTm9kZVRyZWVzUmVxdWVzdBI5Chlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMUhZvd25lcklkZW50aXR5UHVibGljS2V5EjcKDWV4aXRpbmdfdHJlZXMYAiADKAsyEi5zcGFyay5FeGl0aW5nVHJlZVIMZXhpdGluZ1RyZWVzEhUKBnJhd190eBgDIAEoDFIFcmF3VHgSSgoQcHJldmlvdXNfb3V0cHV0cxgEIAMoCzIfLnNwYXJrLkJpdGNvaW5UcmFuc2FjdGlvbk91dHB1dFIPcHJldmlvdXNPdXRwdXRzIm4KG0V4aXRTaW5nbGVOb2RlVHJlZXNSZXNwb25zZRJPCg9zaWduaW5nX3Jlc3VsdHMYASADKAsyJi5zcGFyay5FeGl0U2luZ2xlTm9kZVRyZWVTaWduaW5nUmVzdWx0Ug5zaWduaW5nUmVzdWx0cyJaCh1RdWVyeU5vZGVzRGlzdHJpYnV0aW9uUmVxdWVzdBI5Chlvd25lcl9pZGVudGl0eV9wdWJsaWNfa2V5GAEgASgMUhZvd25lcklkZW50aXR5UHVibGljS2V5Is8BCh5RdWVyeU5vZGVzRGlzdHJpYnV0aW9uUmVzcG9uc2USaAoRbm9kZV9kaXN0cmlidXRpb24YASADKAsyOy5zcGFyay5RdWVyeU5vZGVzRGlzdHJpYnV0aW9uUmVzcG9uc2UuTm9kZURpc3RyaWJ1dGlvbkVudHJ5UhBub2RlRGlzdHJpYnV0aW9uGkMKFU5vZGVEaXN0cmlidXRpb25FbnRyeRIQCgNrZXkYASABKARSA2tleRIUCgV2YWx1ZRgCIAEoBFIFdmFsdWU6AjgBIpkBChhRdWVyeU5vZGVzQnlWYWx1ZVJlcXVlc3QSOQoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDFIWb3duZXJJZGVudGl0eVB1YmxpY0tleRIUCgV2YWx1ZRgCIAEoA1IFdmFsdWUSFgoGb2Zmc2V0GAMgASgDUgZvZmZzZXQSFAoFbGltaXQYBCABKANSBWxpbWl0IsEBChlRdWVyeU5vZGVzQnlWYWx1ZVJlc3BvbnNlEkEKBW5vZGVzGAEgAygLMisuc3BhcmsuUXVlcnlOb2Rlc0J5VmFsdWVSZXNwb25zZS5Ob2Rlc0VudHJ5UgVub2RlcxIWCgZvZmZzZXQYAiABKANSBm9mZnNldBpJCgpOb2Rlc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EiUKBXZhbHVlGAIgASgLMg8uc3BhcmsuVHJlZU5vZGVSBXZhbHVlOgI4ASK2AQoZR2V0VXR4b3NGb3JBZGRyZXNzUmVxdWVzdBIYCgdhZGRyZXNzGAEgASgJUgdhZGRyZXNzEhYKBm9mZnNldBgCIAEoBFIGb2Zmc2V0EhQKBWxpbWl0GAMgASgEUgVsaW1pdBIoCgduZXR3b3JrGAQgASgOMg4uc3BhcmsuTmV0d29ya1IHbmV0d29yaxInCg9leGNsdWRlX2NsYWltZWQYBSABKAhSDmV4Y2x1ZGVDbGFpbWVkIlcKGkdldFV0eG9zRm9yQWRkcmVzc1Jlc3BvbnNlEiEKBXV0eG9zGAEgAygLMgsuc3BhcmsuVVRYT1IFdXR4b3MSFgoGb2Zmc2V0GAIgASgEUgZvZmZzZXQiYwoZUXVlcnlTcGFya0ludm9pY2VzUmVxdWVzdBIUCgVsaW1pdBgBIAEoA1IFbGltaXQSFgoGb2Zmc2V0GAIgASgDUgZvZmZzZXQSGAoHaW52b2ljZRgDIAMoCVIHaW52b2ljZSJ3ChpRdWVyeVNwYXJrSW52b2ljZXNSZXNwb25zZRIWCgZvZmZzZXQYASABKANSBm9mZnNldBJBChBpbnZvaWNlX3N0YXR1c2VzGAIgAygLMhYuc3BhcmsuSW52b2ljZVJlc3BvbnNlUg9pbnZvaWNlU3RhdHVzZXMi5QEKD0ludm9pY2VSZXNwb25zZRIYCgdpbnZvaWNlGAEgASgJUgdpbnZvaWNlEiwKBnN0YXR1cxgCIAEoDjIULnNwYXJrLkludm9pY2VTdGF0dXNSBnN0YXR1cxI6Cg1zYXRzX3RyYW5zZmVyGAMgASgLMhMuc3BhcmsuU2F0c1RyYW5zZmVySABSDHNhdHNUcmFuc2ZlchI9Cg50b2tlbl90cmFuc2ZlchgEIAEoCzIULnNwYXJrLlRva2VuVHJhbnNmZXJIAFINdG9rZW5UcmFuc2ZlckIPCg10cmFuc2Zlcl90eXBlIjgKDFNhdHNUcmFuc2ZlchIoCgt0cmFuc2Zlcl9pZBgBIAEoDEIH+kIEegJoEFIKdHJhbnNmZXJJZCJZCg1Ub2tlblRyYW5zZmVyEkgKHGZpbmFsX3Rva2VuX3RyYW5zYWN0aW9uX2hhc2gYASABKAxCB/pCBHoCaCBSGWZpbmFsVG9rZW5UcmFuc2FjdGlvbkhhc2girQEKIkluaXRpYXRlU3dhcFByaW1hcnlUcmFuc2ZlclJlcXVlc3QSNwoIdHJhbnNmZXIYASABKAsyGy5zcGFyay5TdGFydFRyYW5zZmVyUmVxdWVzdFIIdHJhbnNmZXISTgoTYWRhcHRvcl9wdWJsaWNfa2V5cxgCIAEoCzIeLnNwYXJrLkFkYXB0b3JQdWJsaWNLZXlQYWNrYWdlUhFhZGFwdG9yUHVibGljS2V5cyKdAQojSW5pdGlhdGVTd2FwUHJpbWFyeVRyYW5zZmVyUmVzcG9uc2USKwoIdHJhbnNmZXIYASABKAsyDy5zcGFyay5UcmFuc2ZlclIIdHJhbnNmZXISSQoPc2lnbmluZ19yZXN1bHRzGAIgAygLMiAuc3BhcmsuTGVhZlJlZnVuZFR4U2lnbmluZ1Jlc3VsdFIOc2lnbmluZ1Jlc3VsdHMizwEKF0FkYXB0b3JQdWJsaWNLZXlQYWNrYWdlEiwKEmFkYXB0b3JfcHVibGljX2tleRgBIAEoDFIQYWRhcHRvclB1YmxpY0tleRI5ChlkaXJlY3RfYWRhcHRvcl9wdWJsaWNfa2V5GAIgASgMUhZkaXJlY3RBZGFwdG9yUHVibGljS2V5EksKI2RpcmVjdF9mcm9tX2NwZnBfYWRhcHRvcl9wdWJsaWNfa2V5GAMgASgMUh5kaXJlY3RGcm9tQ3BmcEFkYXB0b3JQdWJsaWNLZXki5gEKDVdhbGxldFNldHRpbmcSQgoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIWb3duZXJJZGVudGl0eVB1YmxpY0tleRInCg9wcml2YXRlX2VuYWJsZWQYAiABKAhSDnByaXZhdGVFbmFibGVkEkkKGm1hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5GAMgASgMQgf6QgR6AmghSABSF21hc3RlcklkZW50aXR5UHVibGljS2V5iAEBQh0KG19tYXN0ZXJfaWRlbnRpdHlfcHVibGljX2tleSKMAgoaVXBkYXRlV2FsbGV0U2V0dGluZ1JlcXVlc3QSLAoPcHJpdmF0ZV9lbmFibGVkGAEgASgISAFSDnByaXZhdGVFbmFibGVkiAEBEkQKHnNldF9tYXN0ZXJfaWRlbnRpdHlfcHVibGljX2tleRgCIAEoDEgAUhpzZXRNYXN0ZXJJZGVudGl0eVB1YmxpY0tleRJICiBjbGVhcl9tYXN0ZXJfaWRlbnRpdHlfcHVibGljX2tleRgDIAEoCEgAUhxjbGVhck1hc3RlcklkZW50aXR5UHVibGljS2V5QhwKGm1hc3Rlcl9pZGVudGl0eV9wdWJsaWNfa2V5QhIKEF9wcml2YXRlX2VuYWJsZWQiWgobVXBkYXRlV2FsbGV0U2V0dGluZ1Jlc3BvbnNlEjsKDndhbGxldF9zZXR0aW5nGAEgASgLMhQuc3BhcmsuV2FsbGV0U2V0dGluZ1INd2FsbGV0U2V0dGluZyIbChlRdWVyeVdhbGxldFNldHRpbmdSZXF1ZXN0IlkKGlF1ZXJ5V2FsbGV0U2V0dGluZ1Jlc3BvbnNlEjsKDndhbGxldF9zZXR0aW5nGAEgASgLMhQuc3BhcmsuV2FsbGV0U2V0dGluZ1INd2FsbGV0U2V0dGluZypNCgdOZXR3b3JrEg8KC1VOU1BFQ0lGSUVEEAASCwoHTUFJTk5FVBABEgsKB1JFR1RFU1QQAhILCgdURVNUTkVUEAMSCgoGU0lHTkVUEAQqIwoJRGlyZWN0aW9uEggKBE5FWFQQABIMCghQUkVWSU9VUxABKvwDCg5UcmFuc2ZlclN0YXR1cxIkCiBUUkFOU0ZFUl9TVEFUVVNfU0VOREVSX0lOSVRJQVRFRBAAEiwKKFRSQU5TRkVSX1NUQVRVU19TRU5ERVJfS0VZX1RXRUFLX1BFTkRJTkcQARImCiJUUkFOU0ZFUl9TVEFUVVNfU0VOREVSX0tFWV9UV0VBS0VEEAISKAokVFJBTlNGRVJfU1RBVFVTX1JFQ0VJVkVSX0tFWV9UV0VBS0VEEAMSKgomVFJBTlNGRVJfU1RBVFVTX1JFQ0VJVkVSX1JFRlVORF9TSUdORUQQBBIdChlUUkFOU0ZFUl9TVEFUVVNfQ09NUExFVEVEEAUSGwoXVFJBTlNGRVJfU1RBVFVTX0VYUElSRUQQBhIcChhUUkFOU0ZFUl9TVEFUVVNfUkVUVVJORUQQBxIwCixUUkFOU0ZFUl9TVEFUVVNfU0VOREVSX0lOSVRJQVRFRF9DT09SRElOQVRPUhAIEi0KKVRSQU5TRkVSX1NUQVRVU19SRUNFSVZFUl9LRVlfVFdFQUtfTE9DS0VEEAkSLgoqVFJBTlNGRVJfU1RBVFVTX1JFQ0VJVkVSX0tFWV9UV0VBS19BUFBMSUVEEAoSLQopVFJBTlNGRVJfU1RBVFVTX0FQUExZSU5HX1NFTkRFUl9LRVlfVFdFQUsQCyqaAQoMVHJhbnNmZXJUeXBlEhEKDVBSRUlNQUdFX1NXQVAQABIUChBDT09QRVJBVElWRV9FWElUEAESDAoIVFJBTlNGRVIQAhINCglVVFhPX1NXQVAQAxIICgRTV0FQEB4SEAoMQ09VTlRFUl9TV0FQECgSEwoPUFJJTUFSWV9TV0FQX1YzEAQSEwoPQ09VTlRFUl9TV0FQX1YzEAUqJgoFT3JkZXISDgoKREVTQ0VORElORxAAEg0KCUFTQ0VORElORxABKpwBChVQcmVpbWFnZVJlcXVlc3RTdGF0dXMSMAosUFJFSU1BR0VfUkVRVUVTVF9TVEFUVVNfV0FJVElOR19GT1JfUFJFSU1BR0UQABIrCidQUkVJTUFHRV9SRVFVRVNUX1NUQVRVU19QUkVJTUFHRV9TSEFSRUQQARIkCiBQUkVJTUFHRV9SRVFVRVNUX1NUQVRVU19SRVRVUk5FRBACKooBChNQcmVpbWFnZVJlcXVlc3RSb2xlEiIKHlBSRUlNQUdFX1JFUVVFU1RfUk9MRV9SRUNFSVZFUhAAEiAKHFBSRUlNQUdFX1JFUVVFU1RfUk9MRV9TRU5ERVIQARItCilQUkVJTUFHRV9SRVFVRVNUX1JPTEVfUkVDRUlWRVJfQU5EX1NFTkRFUhACKkUKE1V0eG9Td2FwUmVxdWVzdFR5cGUSCQoFRml4ZWQQABIKCgZNYXhGZWUQARIKCgZSZWZ1bmQQAhILCgdJbnN0YW50EAMqQAoLSGFzaFZhcmlhbnQSHAoYSEFTSF9WQVJJQU5UX1VOU1BFQ0lGSUVEEAASEwoPSEFTSF9WQVJJQU5UX1YyEAEqTgoNSW52b2ljZVN0YXR1cxINCglOT1RfRk9VTkQQABILCgdQRU5ESU5HEAESDQoJRklOQUxJWkVEEAISDAoIUkVUVVJORUQQBCIECAMQAyqDAwoOVHJlZU5vZGVTdGF0dXMSHQoZVFJFRV9OT0RFX1NUQVRVU19DUkVBVElORxAAEh4KGlRSRUVfTk9ERV9TVEFUVVNfQVZBSUxBQkxFEAESJQohVFJFRV9OT0RFX1NUQVRVU19GUk9aRU5fQllfSVNTVUVSEAISJAogVFJFRV9OT0RFX1NUQVRVU19UUkFOU0ZFUl9MT0NLRUQQAxIhCh1UUkVFX05PREVfU1RBVFVTX1NQTElUX0xPQ0tFRBAEEh0KGVRSRUVfTk9ERV9TVEFUVVNfU1BMSVRURUQQBRIfChtUUkVFX05PREVfU1RBVFVTX0FHR1JFR0FURUQQBhIdChlUUkVFX05PREVfU1RBVFVTX09OX0NIQUlOEAcSIwofVFJFRV9OT0RFX1NUQVRVU19BR0dSRUdBVEVfTE9DSxAIEhsKF1RSRUVfTk9ERV9TVEFUVVNfRVhJVEVEEAkSIQodVFJFRV9OT0RFX1NUQVRVU19SRU5FV19MT0NLRUQQCjLYHAoMU3BhcmtTZXJ2aWNlEmkKGGdlbmVyYXRlX2RlcG9zaXRfYWRkcmVzcxIkLnNwYXJrLkdlbmVyYXRlRGVwb3NpdEFkZHJlc3NSZXF1ZXN0GiUuc3BhcmsuR2VuZXJhdGVEZXBvc2l0QWRkcmVzc1Jlc3BvbnNlIgASfAofZ2VuZXJhdGVfc3RhdGljX2RlcG9zaXRfYWRkcmVzcxIqLnNwYXJrLkdlbmVyYXRlU3RhdGljRGVwb3NpdEFkZHJlc3NSZXF1ZXN0Gisuc3BhcmsuR2VuZXJhdGVTdGF0aWNEZXBvc2l0QWRkcmVzc1Jlc3BvbnNlIgASdgodcm90YXRlX3N0YXRpY19kZXBvc2l0X2FkZHJlc3MSKC5zcGFyay5Sb3RhdGVTdGF0aWNEZXBvc2l0QWRkcmVzc1JlcXVlc3QaKS5zcGFyay5Sb3RhdGVTdGF0aWNEZXBvc2l0QWRkcmVzc1Jlc3BvbnNlIgAScAobc3RhcnRfZGVwb3NpdF90cmVlX2NyZWF0aW9uEiYuc3BhcmsuU3RhcnREZXBvc2l0VHJlZUNyZWF0aW9uUmVxdWVzdBonLnNwYXJrLlN0YXJ0RGVwb3NpdFRyZWVDcmVhdGlvblJlc3BvbnNlIgASeQoeZmluYWxpemVfZGVwb3NpdF90cmVlX2NyZWF0aW9uEikuc3BhcmsuRmluYWxpemVEZXBvc2l0VHJlZUNyZWF0aW9uUmVxdWVzdBoqLnNwYXJrLkZpbmFsaXplRGVwb3NpdFRyZWVDcmVhdGlvblJlc3BvbnNlIgASfwonZmluYWxpemVfdHJhbnNmZXJfd2l0aF90cmFuc2Zlcl9wYWNrYWdlEjEuc3BhcmsuRmluYWxpemVUcmFuc2ZlcldpdGhUcmFuc2ZlclBhY2thZ2VSZXF1ZXN0Gh8uc3BhcmsuRmluYWxpemVUcmFuc2ZlclJlc3BvbnNlIgASUQoXcXVlcnlfcGVuZGluZ190cmFuc2ZlcnMSFS5zcGFyay5UcmFuc2ZlckZpbHRlchodLnNwYXJrLlF1ZXJ5VHJhbnNmZXJzUmVzcG9uc2UiABJNChNxdWVyeV9hbGxfdHJhbnNmZXJzEhUuc3BhcmsuVHJhbnNmZXJGaWx0ZXIaHS5zcGFyay5RdWVyeVRyYW5zZmVyc1Jlc3BvbnNlIgASWwoZY2xhaW1fdHJhbnNmZXJfdHdlYWtfa2V5cxIkLnNwYXJrLkNsYWltVHJhbnNmZXJUd2Vha0tleXNSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASUgoUc3RvcmVfcHJlaW1hZ2Vfc2hhcmUSIC5zcGFyay5TdG9yZVByZWltYWdlU2hhcmVSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASZgoXZ2V0X3NpZ25pbmdfY29tbWl0bWVudHMSIy5zcGFyay5HZXRTaWduaW5nQ29tbWl0bWVudHNSZXF1ZXN0GiQuc3BhcmsuR2V0U2lnbmluZ0NvbW1pdG1lbnRzUmVzcG9uc2UiABJTChBwcm92aWRlX3ByZWltYWdlEh0uc3BhcmsuUHJvdmlkZVByZWltYWdlUmVxdWVzdBoeLnNwYXJrLlByb3ZpZGVQcmVpbWFnZVJlc3BvbnNlIgASTQoOcXVlcnlfcHJlaW1hZ2USGy5zcGFyay5RdWVyeVByZWltYWdlUmVxdWVzdBocLnNwYXJrLlF1ZXJ5UHJlaW1hZ2VSZXNwb25zZSIAEkEKCnF1ZXJ5X2h0bGMSFy5zcGFyay5RdWVyeUh0bGNSZXF1ZXN0Ghguc3BhcmsuUXVlcnlIdGxjUmVzcG9uc2UiABJBCgpyZW5ld19sZWFmEhcuc3BhcmsuUmVuZXdMZWFmUmVxdWVzdBoYLnNwYXJrLlJlbmV3TGVhZlJlc3BvbnNlIgASXAoZZ2V0X3NpZ25pbmdfb3BlcmF0b3JfbGlzdBIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRolLnNwYXJrLkdldFNpZ25pbmdPcGVyYXRvckxpc3RSZXNwb25zZSIAEkQKC3F1ZXJ5X25vZGVzEhguc3BhcmsuUXVlcnlOb2Rlc1JlcXVlc3QaGS5zcGFyay5RdWVyeU5vZGVzUmVzcG9uc2UiABJKCg1xdWVyeV9iYWxhbmNlEhouc3BhcmsuUXVlcnlCYWxhbmNlUmVxdWVzdBobLnNwYXJrLlF1ZXJ5QmFsYW5jZVJlc3BvbnNlIgASagoZcXVlcnlfdXNlcl9zaWduZWRfcmVmdW5kcxIkLnNwYXJrLlF1ZXJ5VXNlclNpZ25lZFJlZnVuZHNSZXF1ZXN0GiUuc3BhcmsuUXVlcnlVc2VyU2lnbmVkUmVmdW5kc1Jlc3BvbnNlIgASeQoecXVlcnlfdW51c2VkX2RlcG9zaXRfYWRkcmVzc2VzEikuc3BhcmsuUXVlcnlVbnVzZWREZXBvc2l0QWRkcmVzc2VzUmVxdWVzdBoqLnNwYXJrLlF1ZXJ5VW51c2VkRGVwb3NpdEFkZHJlc3Nlc1Jlc3BvbnNlIgASeQoecXVlcnlfc3RhdGljX2RlcG9zaXRfYWRkcmVzc2VzEikuc3BhcmsuUXVlcnlTdGF0aWNEZXBvc2l0QWRkcmVzc2VzUmVxdWVzdBoqLnNwYXJrLlF1ZXJ5U3RhdGljRGVwb3NpdEFkZHJlc3Nlc1Jlc3BvbnNlIgASXAoTc3Vic2NyaWJlX3RvX2V2ZW50cxIfLnNwYXJrLlN1YnNjcmliZVRvRXZlbnRzUmVxdWVzdBogLnNwYXJrLlN1YnNjcmliZVRvRXZlbnRzUmVzcG9uc2UiADABEoYBCiNpbml0aWF0ZV9zdGF0aWNfZGVwb3NpdF91dHhvX3JlZnVuZBItLnNwYXJrLkluaXRpYXRlU3RhdGljRGVwb3NpdFV0eG9SZWZ1bmRSZXF1ZXN0Gi4uc3BhcmsuSW5pdGlhdGVTdGF0aWNEZXBvc2l0VXR4b1JlZnVuZFJlc3BvbnNlIgASYQoWZXhpdF9zaW5nbGVfbm9kZV90cmVlcxIhLnNwYXJrLkV4aXRTaW5nbGVOb2RlVHJlZXNSZXF1ZXN0GiIuc3BhcmsuRXhpdFNpbmdsZU5vZGVUcmVlc1Jlc3BvbnNlIgASVgoTY29vcGVyYXRpdmVfZXhpdF92MhIdLnNwYXJrLkNvb3BlcmF0aXZlRXhpdFJlcXVlc3QaHi5zcGFyay5Db29wZXJhdGl2ZUV4aXRSZXNwb25zZSIAEnMKHmNsYWltX3RyYW5zZmVyX3NpZ25fcmVmdW5kc192MhImLnNwYXJrLkNsYWltVHJhbnNmZXJTaWduUmVmdW5kc1JlcXVlc3QaJy5zcGFyay5DbGFpbVRyYW5zZmVyU2lnblJlZnVuZHNSZXNwb25zZSIAEmwKG2ZpbmFsaXplX25vZGVfc2lnbmF0dXJlc192MhIkLnNwYXJrLkZpbmFsaXplTm9kZVNpZ25hdHVyZXNSZXF1ZXN0GiUuc3BhcmsuRmluYWxpemVOb2RlU2lnbmF0dXJlc1Jlc3BvbnNlIgASZgoZaW5pdGlhdGVfcHJlaW1hZ2Vfc3dhcF92MhIiLnNwYXJrLkluaXRpYXRlUHJlaW1hZ2VTd2FwUmVxdWVzdBojLnNwYXJrLkluaXRpYXRlUHJlaW1hZ2VTd2FwUmVzcG9uc2UiABJmChlpbml0aWF0ZV9wcmVpbWFnZV9zd2FwX3YzEiIuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXF1ZXN0GiMuc3BhcmsuSW5pdGlhdGVQcmVpbWFnZVN3YXBSZXNwb25zZSIAElEKEnN0YXJ0X2xlYWZfc3dhcF92MhIbLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXF1ZXN0Ghwuc3BhcmsuU3RhcnRUcmFuc2ZlclJlc3BvbnNlIgASUAoRc3RhcnRfdHJhbnNmZXJfdjISGy5zcGFyay5TdGFydFRyYW5zZmVyUmVxdWVzdBocLnNwYXJrLlN0YXJ0VHJhbnNmZXJSZXNwb25zZSIAEk0KDmNsYWltX3RyYW5zZmVyEhsuc3BhcmsuQ2xhaW1UcmFuc2ZlclJlcXVlc3QaHC5zcGFyay5DbGFpbVRyYW5zZmVyUmVzcG9uc2UiABJeChVnZXRfdXR4b3NfZm9yX2FkZHJlc3MSIC5zcGFyay5HZXRVdHhvc0ZvckFkZHJlc3NSZXF1ZXN0GiEuc3BhcmsuR2V0VXR4b3NGb3JBZGRyZXNzUmVzcG9uc2UiABJdChRxdWVyeV9zcGFya19pbnZvaWNlcxIgLnNwYXJrLlF1ZXJ5U3BhcmtJbnZvaWNlc1JlcXVlc3QaIS5zcGFyay5RdWVyeVNwYXJrSW52b2ljZXNSZXNwb25zZSIAEnkKHmluaXRpYXRlX3N3YXBfcHJpbWFyeV90cmFuc2ZlchIpLnNwYXJrLkluaXRpYXRlU3dhcFByaW1hcnlUcmFuc2ZlclJlcXVlc3QaKi5zcGFyay5Jbml0aWF0ZVN3YXBQcmltYXJ5VHJhbnNmZXJSZXNwb25zZSIAEmAKFXVwZGF0ZV93YWxsZXRfc2V0dGluZxIhLnNwYXJrLlVwZGF0ZVdhbGxldFNldHRpbmdSZXF1ZXN0GiIuc3BhcmsuVXBkYXRlV2FsbGV0U2V0dGluZ1Jlc3BvbnNlIgASXQoUcXVlcnlfd2FsbGV0X3NldHRpbmcSIC5zcGFyay5RdWVyeVdhbGxldFNldHRpbmdSZXF1ZXN0GiEuc3BhcmsuUXVlcnlXYWxsZXRTZXR0aW5nUmVzcG9uc2UiAEIsWipnaXRodWIuY29tL2xpZ2h0c3BhcmtkZXYvc3BhcmsvcHJvdG8vc3BhcmtiBnByb3RvMwqPYgoRc3BhcmtfdG9rZW4ucHJvdG8SC3NwYXJrX3Rva2VuGh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvGgtzcGFyay5wcm90bxoXdmFsaWRhdGUvdmFsaWRhdGUucHJvdG8imwEKElRva2VuT3V0cHV0VG9TcGVuZBJGChtwcmV2X3Rva2VuX3RyYW5zYWN0aW9uX2hhc2gYASABKAxCB/pCBHoCaCBSGHByZXZUb2tlblRyYW5zYWN0aW9uSGFzaBI9ChtwcmV2X3Rva2VuX3RyYW5zYWN0aW9uX3ZvdXQYAiABKA1SGHByZXZUb2tlblRyYW5zYWN0aW9uVm91dCJfChJUb2tlblRyYW5zZmVySW5wdXQSSQoQb3V0cHV0c190b19zcGVuZBgBIAMoCzIfLnNwYXJrX3Rva2VuLlRva2VuT3V0cHV0VG9TcGVuZFIOb3V0cHV0c1RvU3BlbmQikwEKDlRva2VuTWludElucHV0EjMKEWlzc3Vlcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg9pc3N1ZXJQdWJsaWNLZXkSNwoQdG9rZW5faWRlbnRpZmllchgCIAEoDEIH+kIEegJoIEgAUg90b2tlbklkZW50aWZpZXKIAQFCEwoRX3Rva2VuX2lkZW50aWZpZXIivwMKEFRva2VuQ3JlYXRlSW5wdXQSMwoRaXNzdWVyX3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCFSD2lzc3VlclB1YmxpY0tleRImCgp0b2tlbl9uYW1lGAIgASgJQgf6QgRyAhgUUgl0b2tlbk5hbWUSKgoMdG9rZW5fdGlja2VyGAMgASgJQgf6QgRyAhgGUgt0b2tlblRpY2tlchIkCghkZWNpbWFscxgEIAEoDUII+kIFKgMY/wFSCGRlY2ltYWxzEiYKCm1heF9zdXBwbHkYBSABKAxCB/pCBHoCaBBSCW1heFN1cHBseRIhCgxpc19mcmVlemFibGUYBiABKAhSC2lzRnJlZXphYmxlEkkKGmNyZWF0aW9uX2VudGl0eV9wdWJsaWNfa2V5GAcgASgMQgf6QgR6AmghSABSF2NyZWF0aW9uRW50aXR5UHVibGljS2V5iAEBEjQKDmV4dHJhX21ldGFkYXRhGAggASgMQgj6QgV6AxiACEgBUg1leHRyYU1ldGFkYXRhiAEBQh0KG19jcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleUIRCg9fZXh0cmFfbWV0YWRhdGEi6AUKC1Rva2VuT3V0cHV0Eh0KAmlkGAEgASgJQgj6QgVyA7ABAUgAUgJpZIgBARIxChBvd25lcl9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUg5vd25lclB1YmxpY0tleRJBChVyZXZvY2F0aW9uX2NvbW1pdG1lbnQYAyABKAxCB/pCBHoCaCFIAVIUcmV2b2NhdGlvbkNvbW1pdG1lbnSIAQESMQoSd2l0aGRyYXdfYm9uZF9zYXRzGAQgASgESAJSEHdpdGhkcmF3Qm9uZFNhdHOIAQESTAogd2l0aGRyYXdfcmVsYXRpdmVfYmxvY2tfbG9ja3RpbWUYBSABKARIA1Idd2l0aGRyYXdSZWxhdGl2ZUJsb2NrTG9ja3RpbWWIAQESNgoQdG9rZW5fcHVibGljX2tleRgGIAEoDEIH+kIEegJoIUgEUg50b2tlblB1YmxpY0tleYgBARI3ChB0b2tlbl9pZGVudGlmaWVyGAggASgMQgf6QgR6AmggSAVSD3Rva2VuSWRlbnRpZmllcogBARIqCgx0b2tlbl9hbW91bnQYByABKAxCB/pCBHoCaBBSC3Rva2VuQW1vdW50EjsKF3NlX3dpdGhkcmF3YWxfc2lnbmF0dXJlGAkgASgMSAZSFXNlV2l0aGRyYXdhbFNpZ25hdHVyZYgBARI7CgZzdGF0dXMYCiABKA4yHi5zcGFya190b2tlbi5Ub2tlbk91dHB1dFN0YXR1c0gHUgZzdGF0dXOIAQFCBQoDX2lkQhgKFl9yZXZvY2F0aW9uX2NvbW1pdG1lbnRCFQoTX3dpdGhkcmF3X2JvbmRfc2F0c0IjCiFfd2l0aGRyYXdfcmVsYXRpdmVfYmxvY2tfbG9ja3RpbWVCEwoRX3Rva2VuX3B1YmxpY19rZXlCEwoRX3Rva2VuX2lkZW50aWZpZXJCGgoYX3NlX3dpdGhkcmF3YWxfc2lnbmF0dXJlQgkKB19zdGF0dXMingIKElBhcnRpYWxUb2tlbk91dHB1dBIxChBvd25lcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg5vd25lclB1YmxpY0tleRIsChJ3aXRoZHJhd19ib25kX3NhdHMYAiABKARSEHdpdGhkcmF3Qm9uZFNhdHMSRwogd2l0aGRyYXdfcmVsYXRpdmVfYmxvY2tfbG9ja3RpbWUYAyABKARSHXdpdGhkcmF3UmVsYXRpdmVCbG9ja0xvY2t0aW1lEjIKEHRva2VuX2lkZW50aWZpZXIYBCABKAxCB/pCBHoCaCBSD3Rva2VuSWRlbnRpZmllchIqCgx0b2tlbl9hbW91bnQYBSABKAxCB/pCBHoCaBBSC3Rva2VuQW1vdW50IqMBChBGaW5hbFRva2VuT3V0cHV0ElEKFHBhcnRpYWxfdG9rZW5fb3V0cHV0GAEgASgLMh8uc3BhcmtfdG9rZW4uUGFydGlhbFRva2VuT3V0cHV0UhJwYXJ0aWFsVG9rZW5PdXRwdXQSPAoVcmV2b2NhdGlvbl9jb21taXRtZW50GAIgASgMQgf6QgR6AmghUhRyZXZvY2F0aW9uQ29tbWl0bWVudCKaBgoQVG9rZW5UcmFuc2FjdGlvbhIYCgd2ZXJzaW9uGAEgASgNUgd2ZXJzaW9uEjwKCm1pbnRfaW5wdXQYAiABKAsyGy5zcGFya190b2tlbi5Ub2tlbk1pbnRJbnB1dEgAUgltaW50SW5wdXQSSAoOdHJhbnNmZXJfaW5wdXQYAyABKAsyHy5zcGFya190b2tlbi5Ub2tlblRyYW5zZmVySW5wdXRIAFINdHJhbnNmZXJJbnB1dBJCCgxjcmVhdGVfaW5wdXQYCCABKAsyHS5zcGFya190b2tlbi5Ub2tlbkNyZWF0ZUlucHV0SABSC2NyZWF0ZUlucHV0Ej0KDXRva2VuX291dHB1dHMYBCADKAsyGC5zcGFya190b2tlbi5Ub2tlbk91dHB1dFIMdG9rZW5PdXRwdXRzEloKI3NwYXJrX29wZXJhdG9yX2lkZW50aXR5X3B1YmxpY19rZXlzGAUgAygMQgz6QgmSAQYiBHoCaCFSH3NwYXJrT3BlcmF0b3JJZGVudGl0eVB1YmxpY0tleXMSOwoLZXhwaXJ5X3RpbWUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgpleHBpcnlUaW1lEjIKB25ldHdvcmsYByABKA4yDi5zcGFyay5OZXR3b3JrQgj6QgWCAQIgAFIHbmV0d29yaxJUChhjbGllbnRfY3JlYXRlZF90aW1lc3RhbXAYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUhZjbGllbnRDcmVhdGVkVGltZXN0YW1wEk8KE2ludm9pY2VfYXR0YWNobWVudHMYCiADKAsyHi5zcGFya190b2tlbi5JbnZvaWNlQXR0YWNobWVudFISaW52b2ljZUF0dGFjaG1lbnRzEj8KGXZhbGlkaXR5X2R1cmF0aW9uX3NlY29uZHMYCyABKARIAVIXdmFsaWRpdHlEdXJhdGlvblNlY29uZHOIAQFCDgoMdG9rZW5faW5wdXRzQhwKGl92YWxpZGl0eV9kdXJhdGlvbl9zZWNvbmRzIpkDChhUb2tlblRyYW5zYWN0aW9uTWV0YWRhdGESWgojc3Bhcmtfb3BlcmF0b3JfaWRlbnRpdHlfcHVibGljX2tleXMYAiADKAxCDPpCCZIBBiIEegJoIVIfc3BhcmtPcGVyYXRvcklkZW50aXR5UHVibGljS2V5cxIyCgduZXR3b3JrGAMgASgOMg4uc3BhcmsuTmV0d29ya0II+kIFggECIABSB25ldHdvcmsSVAoYY2xpZW50X2NyZWF0ZWRfdGltZXN0YW1wGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFIWY2xpZW50Q3JlYXRlZFRpbWVzdGFtcBJGChl2YWxpZGl0eV9kdXJhdGlvbl9zZWNvbmRzGAUgASgEQgr6QgcyBRisAigBUhd2YWxpZGl0eUR1cmF0aW9uU2Vjb25kcxJPChNpbnZvaWNlX2F0dGFjaG1lbnRzGAYgAygLMh4uc3BhcmtfdG9rZW4uSW52b2ljZUF0dGFjaG1lbnRSEmludm9pY2VBdHRhY2htZW50cyLJAwoXUGFydGlhbFRva2VuVHJhbnNhY3Rpb24SGAoHdmVyc2lvbhgBIAEoDVIHdmVyc2lvbhJjChp0b2tlbl90cmFuc2FjdGlvbl9tZXRhZGF0YRgCIAEoCzIlLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25NZXRhZGF0YVIYdG9rZW5UcmFuc2FjdGlvbk1ldGFkYXRhEjwKCm1pbnRfaW5wdXQYAyABKAsyGy5zcGFya190b2tlbi5Ub2tlbk1pbnRJbnB1dEgAUgltaW50SW5wdXQSSAoOdHJhbnNmZXJfaW5wdXQYBCABKAsyHy5zcGFya190b2tlbi5Ub2tlblRyYW5zZmVySW5wdXRIAFINdHJhbnNmZXJJbnB1dBJCCgxjcmVhdGVfaW5wdXQYBSABKAsyHS5zcGFya190b2tlbi5Ub2tlbkNyZWF0ZUlucHV0SABSC2NyZWF0ZUlucHV0ElMKFXBhcnRpYWxfdG9rZW5fb3V0cHV0cxgGIAMoCzIfLnNwYXJrX3Rva2VuLlBhcnRpYWxUb2tlbk91dHB1dFITcGFydGlhbFRva2VuT3V0cHV0c0IOCgx0b2tlbl9pbnB1dHMiwQMKFUZpbmFsVG9rZW5UcmFuc2FjdGlvbhIYCgd2ZXJzaW9uGAEgASgNUgd2ZXJzaW9uEmMKGnRva2VuX3RyYW5zYWN0aW9uX21ldGFkYXRhGAIgASgLMiUuc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvbk1ldGFkYXRhUhh0b2tlblRyYW5zYWN0aW9uTWV0YWRhdGESPAoKbWludF9pbnB1dBgDIAEoCzIbLnNwYXJrX3Rva2VuLlRva2VuTWludElucHV0SABSCW1pbnRJbnB1dBJICg50cmFuc2Zlcl9pbnB1dBgEIAEoCzIfLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNmZXJJbnB1dEgAUg10cmFuc2ZlcklucHV0EkIKDGNyZWF0ZV9pbnB1dBgFIAEoCzIdLnNwYXJrX3Rva2VuLlRva2VuQ3JlYXRlSW5wdXRIAFILY3JlYXRlSW5wdXQSTQoTZmluYWxfdG9rZW5fb3V0cHV0cxgGIAMoCzIdLnNwYXJrX3Rva2VuLkZpbmFsVG9rZW5PdXRwdXRSEWZpbmFsVG9rZW5PdXRwdXRzQg4KDHRva2VuX2lucHV0cyI4ChFJbnZvaWNlQXR0YWNobWVudBIjCg1zcGFya19pbnZvaWNlGAEgASgJUgxzcGFya0ludm9pY2UiXgoSU2lnbmF0dXJlV2l0aEluZGV4EicKCXNpZ25hdHVyZRgBIAEoDEIJ+kIGegQQQBhJUglzaWduYXR1cmUSHwoLaW5wdXRfaW5kZXgYAiABKA1SCmlucHV0SW5kZXgitAEKHklucHV0VHR4b1NpZ25hdHVyZXNQZXJPcGVyYXRvchJICg90dHhvX3NpZ25hdHVyZXMYASADKAsyHy5zcGFya190b2tlbi5TaWduYXR1cmVXaXRoSW5kZXhSDnR0eG9TaWduYXR1cmVzEkgKHG9wZXJhdG9yX2lkZW50aXR5X3B1YmxpY19rZXkYAiABKAxCB/pCBHoCaCFSGW9wZXJhdG9ySWRlbnRpdHlQdWJsaWNLZXki8gIKF1N0YXJ0VHJhbnNhY3Rpb25SZXF1ZXN0EjcKE2lkZW50aXR5X3B1YmxpY19rZXkYASABKAxCB/pCBHoCaCFSEWlkZW50aXR5UHVibGljS2V5ElkKGXBhcnRpYWxfdG9rZW5fdHJhbnNhY3Rpb24YAiABKAsyHS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uUhdwYXJ0aWFsVG9rZW5UcmFuc2FjdGlvbhJ7CipwYXJ0aWFsX3Rva2VuX3RyYW5zYWN0aW9uX293bmVyX3NpZ25hdHVyZXMYAyADKAsyHy5zcGFya190b2tlbi5TaWduYXR1cmVXaXRoSW5kZXhSJnBhcnRpYWxUb2tlblRyYW5zYWN0aW9uT3duZXJTaWduYXR1cmVzEkYKGXZhbGlkaXR5X2R1cmF0aW9uX3NlY29uZHMYBCABKARCCvpCBzIFGKwCKAFSF3ZhbGlkaXR5RHVyYXRpb25TZWNvbmRzIq4BChhTdGFydFRyYW5zYWN0aW9uUmVzcG9uc2USVQoXZmluYWxfdG9rZW5fdHJhbnNhY3Rpb24YASABKAsyHS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uUhVmaW5hbFRva2VuVHJhbnNhY3Rpb24SOwoNa2V5c2hhcmVfaW5mbxgCIAEoCzIWLnNwYXJrLlNpZ25pbmdLZXlzaGFyZVIMa2V5c2hhcmVJbmZvIvgCChhDb21taXRUcmFuc2FjdGlvblJlcXVlc3QSVQoXZmluYWxfdG9rZW5fdHJhbnNhY3Rpb24YASABKAsyHS5zcGFya190b2tlbi5Ub2tlblRyYW5zYWN0aW9uUhVmaW5hbFRva2VuVHJhbnNhY3Rpb24SSAocZmluYWxfdG9rZW5fdHJhbnNhY3Rpb25faGFzaBgCIAEoDEIH+kIEegJoIFIZZmluYWxUb2tlblRyYW5zYWN0aW9uSGFzaBJ3CiJpbnB1dF90dHhvX3NpZ25hdHVyZXNfcGVyX29wZXJhdG9yGAMgAygLMisuc3BhcmtfdG9rZW4uSW5wdXRUdHhvU2lnbmF0dXJlc1Blck9wZXJhdG9yUh5pbnB1dFR0eG9TaWduYXR1cmVzUGVyT3BlcmF0b3ISQgoZb3duZXJfaWRlbnRpdHlfcHVibGljX2tleRgEIAEoDEIH+kIEegJoIVIWb3duZXJJZGVudGl0eVB1YmxpY0tleSK6AQoOQ29tbWl0UHJvZ3Jlc3MSUQoeY29tbWl0dGVkX29wZXJhdG9yX3B1YmxpY19rZXlzGAEgAygMQgz6QgmSAQYiBHoCaCFSG2NvbW1pdHRlZE9wZXJhdG9yUHVibGljS2V5cxJVCiB1bmNvbW1pdHRlZF9vcGVyYXRvcl9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghUh11bmNvbW1pdHRlZE9wZXJhdG9yUHVibGljS2V5cyLvAQoZQ29tbWl0VHJhbnNhY3Rpb25SZXNwb25zZRI+Cg1jb21taXRfc3RhdHVzGAEgASgOMhkuc3BhcmtfdG9rZW4uQ29tbWl0U3RhdHVzUgxjb21taXRTdGF0dXMSRAoPY29tbWl0X3Byb2dyZXNzGAIgASgLMhsuc3BhcmtfdG9rZW4uQ29tbWl0UHJvZ3Jlc3NSDmNvbW1pdFByb2dyZXNzEjcKEHRva2VuX2lkZW50aWZpZXIYAyABKAxCB/pCBHoCaCBIAFIPdG9rZW5JZGVudGlmaWVyiAEBQhMKEV90b2tlbl9pZGVudGlmaWVyIqYCChtCcm9hZGNhc3RUcmFuc2FjdGlvblJlcXVlc3QSNwoTaWRlbnRpdHlfcHVibGljX2tleRgBIAEoDEIH+kIEegJoIVIRaWRlbnRpdHlQdWJsaWNLZXkSYAoZcGFydGlhbF90b2tlbl90cmFuc2FjdGlvbhgCIAEoCzIkLnNwYXJrX3Rva2VuLlBhcnRpYWxUb2tlblRyYW5zYWN0aW9uUhdwYXJ0aWFsVG9rZW5UcmFuc2FjdGlvbhJsCiJ0b2tlbl90cmFuc2FjdGlvbl9vd25lcl9zaWduYXR1cmVzGAMgAygLMh8uc3BhcmtfdG9rZW4uU2lnbmF0dXJlV2l0aEluZGV4Uh90b2tlblRyYW5zYWN0aW9uT3duZXJTaWduYXR1cmVzIs4CChxCcm9hZGNhc3RUcmFuc2FjdGlvblJlc3BvbnNlEloKF2ZpbmFsX3Rva2VuX3RyYW5zYWN0aW9uGAEgASgLMiIuc3BhcmtfdG9rZW4uRmluYWxUb2tlblRyYW5zYWN0aW9uUhVmaW5hbFRva2VuVHJhbnNhY3Rpb24SPgoNY29tbWl0X3N0YXR1cxgCIAEoDjIZLnNwYXJrX3Rva2VuLkNvbW1pdFN0YXR1c1IMY29tbWl0U3RhdHVzEkQKD2NvbW1pdF9wcm9ncmVzcxgDIAEoCzIbLnNwYXJrX3Rva2VuLkNvbW1pdFByb2dyZXNzUg5jb21taXRQcm9ncmVzcxI3ChB0b2tlbl9pZGVudGlmaWVyGAQgASgMQgf6QgR6AmggSABSD3Rva2VuSWRlbnRpZmllcogBAUITChFfdG9rZW5faWRlbnRpZmllciKSAQoZUXVlcnlUb2tlbk1ldGFkYXRhUmVxdWVzdBI5ChF0b2tlbl9pZGVudGlmaWVycxgBIAMoDEIM+kIJkgEGIgR6AmggUhB0b2tlbklkZW50aWZpZXJzEjoKEmlzc3Vlcl9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghUhBpc3N1ZXJQdWJsaWNLZXlzIvADCg1Ub2tlbk1ldGFkYXRhEjMKEWlzc3Vlcl9wdWJsaWNfa2V5GAEgASgMQgf6QgR6AmghUg9pc3N1ZXJQdWJsaWNLZXkSJgoKdG9rZW5fbmFtZRgCIAEoCUIH+kIEcgIYFFIJdG9rZW5OYW1lEioKDHRva2VuX3RpY2tlchgDIAEoCUIH+kIEcgIYBlILdG9rZW5UaWNrZXISJAoIZGVjaW1hbHMYBCABKA1CCPpCBSoDGP8BUghkZWNpbWFscxImCgptYXhfc3VwcGx5GAUgASgMQgf6QgR6AmgQUgltYXhTdXBwbHkSIQoMaXNfZnJlZXphYmxlGAYgASgIUgtpc0ZyZWV6YWJsZRJJChpjcmVhdGlvbl9lbnRpdHlfcHVibGljX2tleRgHIAEoDEIH+kIEegJoIUgAUhdjcmVhdGlvbkVudGl0eVB1YmxpY0tleYgBARIyChB0b2tlbl9pZGVudGlmaWVyGAggASgMQgf6QgR6AmggUg90b2tlbklkZW50aWZpZXISNAoOZXh0cmFfbWV0YWRhdGEYCSABKAxCCPpCBXoDGIAISAFSDWV4dHJhTWV0YWRhdGGIAQFCHQobX2NyZWF0aW9uX2VudGl0eV9wdWJsaWNfa2V5QhEKD19leHRyYV9tZXRhZGF0YSJfChpRdWVyeVRva2VuTWV0YWRhdGFSZXNwb25zZRJBCg50b2tlbl9tZXRhZGF0YRgBIAMoCzIaLnNwYXJrX3Rva2VuLlRva2VuTWV0YWRhdGFSDXRva2VuTWV0YWRhdGEirAIKGFF1ZXJ5VG9rZW5PdXRwdXRzUmVxdWVzdBI4ChFvd25lcl9wdWJsaWNfa2V5cxgBIAMoDEIM+kIJkgEGIgR6AmghUg9vd25lclB1YmxpY0tleXMSOgoSaXNzdWVyX3B1YmxpY19rZXlzGAIgAygMQgz6QgmSAQYiBHoCaCFSEGlzc3VlclB1YmxpY0tleXMSOQoRdG9rZW5faWRlbnRpZmllcnMYBCADKAxCDPpCCZIBBiIEegJoIFIQdG9rZW5JZGVudGlmaWVycxIoCgduZXR3b3JrGAMgASgOMg4uc3BhcmsuTmV0d29ya1IHbmV0d29yaxI1CgxwYWdlX3JlcXVlc3QYBSABKAsyEi5zcGFyay5QYWdlUmVxdWVzdFILcGFnZVJlcXVlc3Qi1wQKHVF1ZXJ5VG9rZW5UcmFuc2FjdGlvbnNSZXF1ZXN0EksKCmJ5X3R4X2hhc2gYCSABKAsyKy5zcGFya190b2tlbi5RdWVyeVRva2VuVHJhbnNhY3Rpb25zQnlUeEhhc2hIAFIIYnlUeEhhc2gSTQoKYnlfZmlsdGVycxgKIAEoCzIsLnNwYXJrX3Rva2VuLlF1ZXJ5VG9rZW5UcmFuc2FjdGlvbnNCeUZpbHRlcnNIAFIJYnlGaWx0ZXJzEiwKCm91dHB1dF9pZHMYASADKAlCDfpCCpIBByIFcgOwAQFSCW91dHB1dElkcxI4ChFvd25lcl9wdWJsaWNfa2V5cxgCIAMoDEIM+kIJkgEGIgR6AmghUg9vd25lclB1YmxpY0tleXMSOgoSaXNzdWVyX3B1YmxpY19rZXlzGAMgAygMQgz6QgmSAQYiBHoCaCFSEGlzc3VlclB1YmxpY0tleXMSOQoRdG9rZW5faWRlbnRpZmllcnMYByADKAxCDPpCCZIBBiIEegJoIFIQdG9rZW5JZGVudGlmaWVycxJGChh0b2tlbl90cmFuc2FjdGlvbl9oYXNoZXMYBCADKAxCDPpCCZIBBiIEegJoIFIWdG9rZW5UcmFuc2FjdGlvbkhhc2hlcxIiCgVvcmRlchgIIAEoDjIMLnNwYXJrLk9yZGVyUgVvcmRlchIgCgVsaW1pdBgFIAEoA0IK+kIHIgUY6AcoAFIFbGltaXQSHwoGb2Zmc2V0GAYgASgDQgf6QgQiAigAUgZvZmZzZXRCDAoKcXVlcnlfdHlwZSJqCh5RdWVyeVRva2VuVHJhbnNhY3Rpb25zQnlUeEhhc2gSSAoYdG9rZW5fdHJhbnNhY3Rpb25faGFzaGVzGAEgAygMQg76QguSAQgIASIEegJoIFIWdG9rZW5UcmFuc2FjdGlvbkhhc2hlcyK3AgofUXVlcnlUb2tlblRyYW5zYWN0aW9uc0J5RmlsdGVycxIsCgpvdXRwdXRfaWRzGAEgAygJQg36QgqSAQciBXIDsAEBUglvdXRwdXRJZHMSOAoRb3duZXJfcHVibGljX2tleXMYAiADKAxCDPpCCZIBBiIEegJoIVIPb3duZXJQdWJsaWNLZXlzEjoKEmlzc3Vlcl9wdWJsaWNfa2V5cxgDIAMoDEIM+kIJkgEGIgR6AmghUhBpc3N1ZXJQdWJsaWNLZXlzEjkKEXRva2VuX2lkZW50aWZpZXJzGAQgAygMQgz6QgmSAQYiBHoCaCBSEHRva2VuSWRlbnRpZmllcnMSNQoMcGFnZV9yZXF1ZXN0GAUgASgLMhIuc3BhcmsuUGFnZVJlcXVlc3RSC3BhZ2VSZXF1ZXN0IuABCh5RdWVyeVRva2VuVHJhbnNhY3Rpb25zUmVzcG9uc2USbAoedG9rZW5fdHJhbnNhY3Rpb25zX3dpdGhfc3RhdHVzGAEgAygLMicuc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvbldpdGhTdGF0dXNSG3Rva2VuVHJhbnNhY3Rpb25zV2l0aFN0YXR1cxIWCgZvZmZzZXQYAiABKANSBm9mZnNldBI4Cg1wYWdlX3Jlc3BvbnNlGAMgASgLMhMuc3BhcmsuUGFnZVJlc3BvbnNlUgxwYWdlUmVzcG9uc2Ui1gEKIU91dHB1dFdpdGhQcmV2aW91c1RyYW5zYWN0aW9uRGF0YRIwCgZvdXRwdXQYASABKAsyGC5zcGFya190b2tlbi5Ub2tlbk91dHB1dFIGb3V0cHV0EkMKGXByZXZpb3VzX3RyYW5zYWN0aW9uX2hhc2gYAiABKAxCB/pCBHoCaCBSF3ByZXZpb3VzVHJhbnNhY3Rpb25IYXNoEjoKGXByZXZpb3VzX3RyYW5zYWN0aW9uX3ZvdXQYAyABKA1SF3ByZXZpb3VzVHJhbnNhY3Rpb25Wb3V0ItoBChlRdWVyeVRva2VuT3V0cHV0c1Jlc3BvbnNlEoIBCiZvdXRwdXRzX3dpdGhfcHJldmlvdXNfdHJhbnNhY3Rpb25fZGF0YRgBIAMoCzIuLnNwYXJrX3Rva2VuLk91dHB1dFdpdGhQcmV2aW91c1RyYW5zYWN0aW9uRGF0YVIib3V0cHV0c1dpdGhQcmV2aW91c1RyYW5zYWN0aW9uRGF0YRI4Cg1wYWdlX3Jlc3BvbnNlGAIgASgLMhMuc3BhcmsuUGFnZVJlc3BvbnNlUgxwYWdlUmVzcG9uc2UiZAoYU3BlbnRUb2tlbk91dHB1dE1ldGFkYXRhEhsKCW91dHB1dF9pZBgBIAEoCVIIb3V0cHV0SWQSKwoRcmV2b2NhdGlvbl9zZWNyZXQYAiABKAxSEHJldm9jYXRpb25TZWNyZXQijgEKJFRva2VuVHJhbnNhY3Rpb25Db25maXJtYXRpb25NZXRhZGF0YRJmChxzcGVudF90b2tlbl9vdXRwdXRzX21ldGFkYXRhGAEgAygLMiUuc3BhcmtfdG9rZW4uU3BlbnRUb2tlbk91dHB1dE1ldGFkYXRhUhlzcGVudFRva2VuT3V0cHV0c01ldGFkYXRhIswCChpUb2tlblRyYW5zYWN0aW9uV2l0aFN0YXR1cxJKChF0b2tlbl90cmFuc2FjdGlvbhgBIAEoCzIdLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25SEHRva2VuVHJhbnNhY3Rpb24SOwoGc3RhdHVzGAIgASgOMiMuc3BhcmtfdG9rZW4uVG9rZW5UcmFuc2FjdGlvblN0YXR1c1IGc3RhdHVzEmYKFWNvbmZpcm1hdGlvbl9tZXRhZGF0YRgDIAEoCzIxLnNwYXJrX3Rva2VuLlRva2VuVHJhbnNhY3Rpb25Db25maXJtYXRpb25NZXRhZGF0YVIUY29uZmlybWF0aW9uTWV0YWRhdGESPQoWdG9rZW5fdHJhbnNhY3Rpb25faGFzaBgEIAEoDEIH+kIEegJoIFIUdG9rZW5UcmFuc2FjdGlvbkhhc2girAMKE0ZyZWV6ZVRva2Vuc1BheWxvYWQSGAoHdmVyc2lvbhgBIAEoDVIHdmVyc2lvbhIxChBvd25lcl9wdWJsaWNfa2V5GAIgASgMQgf6QgR6AmghUg5vd25lclB1YmxpY0tleRI2ChB0b2tlbl9wdWJsaWNfa2V5GAMgASgMQgf6QgR6AmghSABSDnRva2VuUHVibGljS2V5iAEBEjcKEHRva2VuX2lkZW50aWZpZXIYBCABKAxCB/pCBHoCaCBIAVIPdG9rZW5JZGVudGlmaWVyiAEBEjoKGWlzc3Vlcl9wcm92aWRlZF90aW1lc3RhbXAYBSABKARSF2lzc3VlclByb3ZpZGVkVGltZXN0YW1wEkgKHG9wZXJhdG9yX2lkZW50aXR5X3B1YmxpY19rZXkYBiABKAxCB/pCBHoCaCFSGW9wZXJhdG9ySWRlbnRpdHlQdWJsaWNLZXkSJwoPc2hvdWxkX3VuZnJlZXplGAcgASgIUg5zaG91bGRVbmZyZWV6ZUITChFfdG9rZW5fcHVibGljX2tleUITChFfdG9rZW5faWRlbnRpZmllciKhAQoTRnJlZXplVG9rZW5zUmVxdWVzdBJUChVmcmVlemVfdG9rZW5zX3BheWxvYWQYASABKAsyIC5zcGFya190b2tlbi5GcmVlemVUb2tlbnNQYXlsb2FkUhNmcmVlemVUb2tlbnNQYXlsb2FkEjQKEGlzc3Vlcl9zaWduYXR1cmUYAiABKAxCCfpCBnoEEEAYSVIPaXNzdWVyU2lnbmF0dXJlIlgKDlRva2VuT3V0cHV0UmVmEjIKEHRyYW5zYWN0aW9uX2hhc2gYASABKAxCB/pCBHoCaCBSD3RyYW5zYWN0aW9uSGFzaBISCgR2b3V0GAIgASgNUgR2b3V0Iq4BCg5GcmVlemVQcm9ncmVzcxJLChtmcm96ZW5fb3BlcmF0b3JfcHVibGljX2tleXMYASADKAxCDPpCCZIBBiIEegJoIVIYZnJvemVuT3BlcmF0b3JQdWJsaWNLZXlzEk8KHXVuZnJvemVuX29wZXJhdG9yX3B1YmxpY19rZXlzGAIgAygMQgz6QgmSAQYiBHoCaCFSGnVuZnJvemVuT3BlcmF0b3JQdWJsaWNLZXlzIqQCChRGcmVlemVUb2tlbnNSZXNwb25zZRI/ChNpbXBhY3RlZF9vdXRwdXRfaWRzGAEgAygJQg8YAfpCCpIBByIFcgOwAQFSEWltcGFjdGVkT3V0cHV0SWRzEjIKFWltcGFjdGVkX3Rva2VuX2Ftb3VudBgCIAEoDFITaW1wYWN0ZWRUb2tlbkFtb3VudBJRChZpbXBhY3RlZF90b2tlbl9vdXRwdXRzGAMgAygLMhsuc3BhcmtfdG9rZW4uVG9rZW5PdXRwdXRSZWZSFGltcGFjdGVkVG9rZW5PdXRwdXRzEkQKD2ZyZWV6ZV9wcm9ncmVzcxgEIAEoCzIbLnNwYXJrX3Rva2VuLkZyZWV6ZVByb2dyZXNzUg5mcmVlemVQcm9ncmVzcyqFAQoRVG9rZW5PdXRwdXRTdGF0dXMSIwofVE9LRU5fT1VUUFVUX1NUQVRVU19VTlNQRUNJRklFRBAAEiEKHVRPS0VOX09VVFBVVF9TVEFUVVNfQVZBSUxBQkxFEAESKAokVE9LRU5fT1VUUFVUX1NUQVRVU19QRU5ESU5HX09VVEJPVU5EEAIqpwEKFFRva2VuVHJhbnNhY3Rpb25UeXBlEiYKIlRPS0VOX1RSQU5TQUNUSU9OX1RZUEVfVU5TUEVDSUZJRUQQABIhCh1UT0tFTl9UUkFOU0FDVElPTl9UWVBFX0NSRUFURRABEh8KG1RPS0VOX1RSQU5TQUNUSU9OX1RZUEVfTUlOVBACEiMKH1RPS0VOX1RSQU5TQUNUSU9OX1RZUEVfVFJBTlNGRVIQAypTCgxDb21taXRTdGF0dXMSFgoSQ09NTUlUX1VOU1BFQ0lGSUVEEAASFQoRQ09NTUlUX1BST0NFU1NJTkcQARIUChBDT01NSVRfRklOQUxJWkVEEAIqhgIKFlRva2VuVHJhbnNhY3Rpb25TdGF0dXMSHQoZVE9LRU5fVFJBTlNBQ1RJT05fU1RBUlRFRBAAEhwKGFRPS0VOX1RSQU5TQUNUSU9OX1NJR05FRBABEh4KGlRPS0VOX1RSQU5TQUNUSU9OX1JFVkVBTEVEEAUSHwobVE9LRU5fVFJBTlNBQ1RJT05fRklOQUxJWkVEEAISJwojVE9LRU5fVFJBTlNBQ1RJT05fU1RBUlRFRF9DQU5DRUxMRUQQAxImCiJUT0tFTl9UUkFOU0FDVElPTl9TSUdORURfQ0FOQ0VMTEVEEAQSHQoZVE9LRU5fVFJBTlNBQ1RJT05fVU5LTk9XThAKMvAFChFTcGFya1Rva2VuU2VydmljZRJiChFzdGFydF90cmFuc2FjdGlvbhIkLnNwYXJrX3Rva2VuLlN0YXJ0VHJhbnNhY3Rpb25SZXF1ZXN0GiUuc3BhcmtfdG9rZW4uU3RhcnRUcmFuc2FjdGlvblJlc3BvbnNlIgASZQoSY29tbWl0X3RyYW5zYWN0aW9uEiUuc3BhcmtfdG9rZW4uQ29tbWl0VHJhbnNhY3Rpb25SZXF1ZXN0GiYuc3BhcmtfdG9rZW4uQ29tbWl0VHJhbnNhY3Rpb25SZXNwb25zZSIAEmkKFHF1ZXJ5X3Rva2VuX21ldGFkYXRhEiYuc3BhcmtfdG9rZW4uUXVlcnlUb2tlbk1ldGFkYXRhUmVxdWVzdBonLnNwYXJrX3Rva2VuLlF1ZXJ5VG9rZW5NZXRhZGF0YVJlc3BvbnNlIgASdQoYcXVlcnlfdG9rZW5fdHJhbnNhY3Rpb25zEiouc3BhcmtfdG9rZW4uUXVlcnlUb2tlblRyYW5zYWN0aW9uc1JlcXVlc3QaKy5zcGFya190b2tlbi5RdWVyeVRva2VuVHJhbnNhY3Rpb25zUmVzcG9uc2UiABJmChNxdWVyeV90b2tlbl9vdXRwdXRzEiUuc3BhcmtfdG9rZW4uUXVlcnlUb2tlbk91dHB1dHNSZXF1ZXN0GiYuc3BhcmtfdG9rZW4uUXVlcnlUb2tlbk91dHB1dHNSZXNwb25zZSIAElYKDWZyZWV6ZV90b2tlbnMSIC5zcGFya190b2tlbi5GcmVlemVUb2tlbnNSZXF1ZXN0GiEuc3BhcmtfdG9rZW4uRnJlZXplVG9rZW5zUmVzcG9uc2UiABJuChVicm9hZGNhc3RfdHJhbnNhY3Rpb24SKC5zcGFya190b2tlbi5Ccm9hZGNhc3RUcmFuc2FjdGlvblJlcXVlc3QaKS5zcGFya190b2tlbi5Ccm9hZGNhc3RUcmFuc2FjdGlvblJlc3BvbnNlIgBCMlowZ2l0aHViLmNvbS9saWdodHNwYXJrZGV2L3NwYXJrL3Byb3RvL3NwYXJrX3Rva2VuYgZwcm90bzMKpQQKCm1vY2sucHJvdG8SBG1vY2saG2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90byJAChtDbGVhblVwUHJlaW1hZ2VTaGFyZVJlcXVlc3QSIQoMcGF5bWVudF9oYXNoGAEgASgMUgtwYXltZW50SGFzaCJNChhVcGRhdGVOb2Rlc1N0YXR1c1JlcXVlc3QSGQoIbm9kZV9pZHMYASADKAlSB25vZGVJZHMSFgoGc3RhdHVzGAIgASgJUgZzdGF0dXMiMQoSVHJpZ2dlclRhc2tSZXF1ZXN0EhsKCXRhc2tfbmFtZRgBIAEoCVIIdGFza05hbWUy+gEKC01vY2tTZXJ2aWNlElYKF2NsZWFuX3VwX3ByZWltYWdlX3NoYXJlEiEubW9jay5DbGVhblVwUHJlaW1hZ2VTaGFyZVJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABJPChN1cGRhdGVfbm9kZXNfc3RhdHVzEh4ubW9jay5VcGRhdGVOb2Rlc1N0YXR1c1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABJCCgx0cmlnZ2VyX3Rhc2sSGC5tb2NrLlRyaWdnZXJUYXNrUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIAQitaKWdpdGh1Yi5jb20vbGlnaHRzcGFya2Rldi9zcGFyay9wcm90by9tb2NrYgZwcm90bzMK6gcKEXNwYXJrX2F1dGhuLnByb3RvEgtzcGFya19hdXRobiJ4CglDaGFsbGVuZ2USGAoHdmVyc2lvbhgBIAEoBVIHdmVyc2lvbhIcCgl0aW1lc3RhbXAYAiABKANSCXRpbWVzdGFtcBIUCgVub25jZRgDIAEoDFIFbm9uY2USHQoKcHVibGljX2tleRgEIAEoDFIJcHVibGljS2V5IoUBChJQcm90ZWN0ZWRDaGFsbGVuZ2USGAoHdmVyc2lvbhgBIAEoBVIHdmVyc2lvbhI0CgljaGFsbGVuZ2UYAiABKAsyFi5zcGFya19hdXRobi5DaGFsbGVuZ2VSCWNoYWxsZW5nZRIfCgtzZXJ2ZXJfaG1hYxgDIAEoDFIKc2VydmVySG1hYyI0ChNHZXRDaGFsbGVuZ2VSZXF1ZXN0Eh0KCnB1YmxpY19rZXkYASABKAxSCXB1YmxpY0tleSJoChRHZXRDaGFsbGVuZ2VSZXNwb25zZRJQChNwcm90ZWN0ZWRfY2hhbGxlbmdlGAEgASgLMh8uc3BhcmtfYXV0aG4uUHJvdGVjdGVkQ2hhbGxlbmdlUhJwcm90ZWN0ZWRDaGFsbGVuZ2UipwEKFlZlcmlmeUNoYWxsZW5nZVJlcXVlc3QSUAoTcHJvdGVjdGVkX2NoYWxsZW5nZRgBIAEoCzIfLnNwYXJrX2F1dGhuLlByb3RlY3RlZENoYWxsZW5nZVIScHJvdGVjdGVkQ2hhbGxlbmdlEhwKCXNpZ25hdHVyZRgCIAEoDFIJc2lnbmF0dXJlEh0KCnB1YmxpY19rZXkYAyABKAxSCXB1YmxpY0tleSJxChdWZXJpZnlDaGFsbGVuZ2VSZXNwb25zZRIjCg1zZXNzaW9uX3Rva2VuGAEgASgJUgxzZXNzaW9uVG9rZW4SMQoUZXhwaXJhdGlvbl90aW1lc3RhbXAYAiABKANSE2V4cGlyYXRpb25UaW1lc3RhbXAyzAEKEVNwYXJrQXV0aG5TZXJ2aWNlElYKDWdldF9jaGFsbGVuZ2USIC5zcGFya19hdXRobi5HZXRDaGFsbGVuZ2VSZXF1ZXN0GiEuc3BhcmtfYXV0aG4uR2V0Q2hhbGxlbmdlUmVzcG9uc2UiABJfChB2ZXJpZnlfY2hhbGxlbmdlEiMuc3BhcmtfYXV0aG4uVmVyaWZ5Q2hhbGxlbmdlUmVxdWVzdBokLnNwYXJrX2F1dGhuLlZlcmlmeUNoYWxsZW5nZVJlc3BvbnNlIgBCMlowZ2l0aHViLmNvbS9saWdodHNwYXJrZGV2L3NwYXJrL3Byb3RvL3NwYXJrX2F1dGhuYgZwcm90bzM=";
62359
62727
  function getSparkDescriptorBytes() {
62360
62728
  const binaryString = atob(SPARK_DESCRIPTORS_BASE64);
62361
62729
  const bytes = new Uint8Array(binaryString.length);
@@ -63739,7 +64107,7 @@ function validateTokenTransaction(finalTokenTransaction, partialTokenTransaction
63739
64107
  expected: partialTokenTransaction.clientCreatedTimestamp
63740
64108
  });
63741
64109
  }
63742
- function sumAvailableTokens(outputs) {
64110
+ function sumTokenOutputs(outputs) {
63743
64111
  try {
63744
64112
  return outputs.reduce((sum$1, output) => sum$1 + BigInt(bytesToNumberBE(output.output.tokenAmount)), BigInt(0));
63745
64113
  } catch (error) {
@@ -63747,11 +64115,20 @@ function sumAvailableTokens(outputs) {
63747
64115
  }
63748
64116
  }
63749
64117
  function filterTokenBalanceForTokenIdentifier(tokenBalances, tokenIdentifier) {
63750
- if (!tokenBalances) return { balance: 0n };
64118
+ if (!tokenBalances) return {
64119
+ ownedBalance: 0n,
64120
+ availableToSendBalance: 0n
64121
+ };
63751
64122
  const tokenIdentifierBytes = decodeBech32mTokenIdentifier(tokenIdentifier).tokenIdentifier;
63752
64123
  const tokenBalance = [...tokenBalances.entries()].find(([, info]) => equalBytes(info.tokenMetadata.rawTokenIdentifier, tokenIdentifierBytes));
63753
- if (!tokenBalance) return { balance: 0n };
63754
- return { balance: tokenBalance[1].balance };
64124
+ if (!tokenBalance) return {
64125
+ ownedBalance: 0n,
64126
+ availableToSendBalance: 0n
64127
+ };
64128
+ return {
64129
+ ownedBalance: tokenBalance[1].ownedBalance,
64130
+ availableToSendBalance: tokenBalance[1].availableToSendBalance
64131
+ };
63755
64132
  }
63756
64133
  var QUERY_TOKEN_OUTPUTS_PAGE_SIZE = 100;
63757
64134
  var MAX_TOKEN_OUTPUTS_TX = 500;
@@ -63776,7 +64153,7 @@ var TokenTransactionService = class {
63776
64153
  if (outputsToUse.length > MAX_TOKEN_OUTPUTS_TX) {
63777
64154
  const sortedOutputs = [...tokenOutputs.get(tokenIdentifier)];
63778
64155
  this.sortTokenOutputsByStrategy(sortedOutputs, outputSelectionStrategy);
63779
- const maxAmount = sumAvailableTokens(sortedOutputs.slice(0, MAX_TOKEN_OUTPUTS_TX));
64156
+ const maxAmount = sumTokenOutputs(sortedOutputs.slice(0, MAX_TOKEN_OUTPUTS_TX));
63780
64157
  throw new SparkValidationError(`Cannot transfer more than ${MAX_TOKEN_OUTPUTS_TX} TTXOs in a single transaction (${outputsToUse.length} selected). Maximum transferable amount is: ${maxAmount}`, {
63781
64158
  field: "outputsToUse",
63782
64159
  value: outputsToUse.length,
@@ -63810,7 +64187,7 @@ var TokenTransactionService = class {
63810
64187
  }
63811
64188
  async constructTransferTokenTransaction(selectedOutputs, tokenOutputData, sparkInvoices) {
63812
64189
  selectedOutputs.sort((a, b) => a.previousTransactionVout - b.previousTransactionVout);
63813
- const availableTokenAmount = sumAvailableTokens(selectedOutputs);
64190
+ const availableTokenAmount = sumTokenOutputs(selectedOutputs);
63814
64191
  const totalRequestedAmount = tokenOutputData.reduce((sum$1, output) => sum$1 + output.tokenAmount, 0n);
63815
64192
  const tokenOutputs = tokenOutputData.map((output) => ({
63816
64193
  ownerPublicKey: output.receiverPublicKey,
@@ -63846,7 +64223,7 @@ var TokenTransactionService = class {
63846
64223
  }
63847
64224
  async constructPartialTransferTokenTransaction(selectedOutputs, tokenOutputData, sparkInvoices) {
63848
64225
  selectedOutputs.sort((a, b) => a.previousTransactionVout - b.previousTransactionVout);
63849
- const availableTokenAmount = sumAvailableTokens(selectedOutputs);
64226
+ const availableTokenAmount = sumTokenOutputs(selectedOutputs);
63850
64227
  const totalRequestedAmount = tokenOutputData.reduce((sum$1, output) => sum$1 + output.tokenAmount, 0n);
63851
64228
  const partialTokenOutputs = tokenOutputData.map((output) => ({
63852
64229
  ownerPublicKey: output.receiverPublicKey,
@@ -64228,9 +64605,9 @@ var TokenTransactionService = class {
64228
64605
  value: tokenAmount,
64229
64606
  expected: "Greater than 0"
64230
64607
  });
64231
- if (sumAvailableTokens(tokenOutputs) < tokenAmount) throw new SparkValidationError("Insufficient token amount", {
64608
+ if (sumTokenOutputs(tokenOutputs) < tokenAmount) throw new SparkValidationError("Insufficient token amount", {
64232
64609
  field: "tokenAmount",
64233
- value: sumAvailableTokens(tokenOutputs),
64610
+ value: sumTokenOutputs(tokenOutputs),
64234
64611
  expected: tokenAmount
64235
64612
  });
64236
64613
  const exactMatch = tokenOutputs.find((item) => bytesToNumberBE(item.output.tokenAmount) === tokenAmount);
@@ -65418,7 +65795,6 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
65418
65795
  leavesMutex = new Mutex();
65419
65796
  mutexes = /* @__PURE__ */ new Map();
65420
65797
  optimizationInProgress = false;
65421
- pendingWithdrawnOutputIds = /* @__PURE__ */ new Map();
65422
65798
  sparkAddress;
65423
65799
  streamController = null;
65424
65800
  tokenOptimizationInProgress = false;
@@ -65725,7 +66101,7 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
65725
66101
  if (outputsToConsolidate.length === 0) continue;
65726
66102
  try {
65727
66103
  const receiverSparkAddress = await this.getSparkAddress();
65728
- const totalAmount = sumAvailableTokens(outputsToConsolidate);
66104
+ const totalAmount = sumTokenOutputs(outputsToConsolidate);
65729
66105
  const txId = await this.tokenTransactionService.tokenTransfer({
65730
66106
  tokenOutputs: /* @__PURE__ */ new Map([[tokenIdentifier, outputsToConsolidate]]),
65731
66107
  receiverOutputs: [{
@@ -65735,7 +66111,7 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
65735
66111
  }],
65736
66112
  outputSelectionStrategy: "SMALL_FIRST"
65737
66113
  });
65738
- await this.markOutputsAsPendingWithdrawalAfterTransferSuccess(tokenIdentifier, outputsToConsolidate);
66114
+ await this.tokenOutputManager.lockOutputs(outputsToConsolidate);
65739
66115
  console.log(`Consolidated ${outputsToConsolidate.length} outputs for token ${tokenIdentifier} in transaction ${txId}`);
65740
66116
  break;
65741
66117
  } catch (error) {
@@ -65779,23 +66155,6 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
65779
66155
  }
65780
66156
  }
65781
66157
  /**
65782
- * Marks token outputs as pending withdrawal so they're excluded from
65783
- * availability until the server confirms they're gone.
65784
- */
65785
- async markOutputsAsPendingWithdrawalAfterTransferSuccess(tokenIdentifier, outputs) {
65786
- const outputIds = [];
65787
- for (const output of outputs) {
65788
- if (!output.output?.id) throw new SparkValidationError("Output ID is required", {
65789
- field: "output",
65790
- value: output,
65791
- expected: "output.output.id to be set"
65792
- });
65793
- outputIds.push(output.output.id);
65794
- if (!this.pendingWithdrawnOutputIds.has(tokenIdentifier)) this.pendingWithdrawnOutputIds.set(tokenIdentifier, /* @__PURE__ */ new Set());
65795
- this.pendingWithdrawnOutputIds.get(tokenIdentifier).add(output.output.id);
65796
- }
65797
- }
65798
- /**
65799
66158
  * Gets the identity public key of the wallet.
65800
66159
  *
65801
66160
  * @returns {Promise<string>} The identity public key as a hex string.
@@ -66166,13 +66525,17 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
66166
66525
  const tokenMetadataMap = await this.getTokenMetadata();
66167
66526
  const result = /* @__PURE__ */ new Map();
66168
66527
  for (const [tokenIdentifier, tokenMetadata] of tokenMetadataMap) {
66169
- const outputs = await this.tokenOutputManager.getAllOutputs(tokenIdentifier);
66528
+ const availableOutputs = await this.tokenOutputManager.getAvailableOutputs(tokenIdentifier);
66170
66529
  const humanReadableTokenIdentifier = encodeBech32mTokenIdentifier({
66171
66530
  tokenIdentifier: tokenMetadata.rawTokenIdentifier,
66172
66531
  network: this.config.getNetworkType()
66173
66532
  });
66533
+ const pendingOutputs = await this.tokenOutputManager.getPendingOutboundOutputs(humanReadableTokenIdentifier);
66534
+ const allOutputsSum = sumTokenOutputs([...availableOutputs, ...pendingOutputs]);
66535
+ const availableToSendBalance = sumTokenOutputs(availableOutputs);
66174
66536
  result.set(humanReadableTokenIdentifier, {
66175
- balance: outputs ? sumAvailableTokens(outputs) : BigInt(0),
66537
+ ownedBalance: allOutputsSum,
66538
+ availableToSendBalance,
66176
66539
  tokenMetadata
66177
66540
  });
66178
66541
  }
@@ -67623,7 +67986,7 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
67623
67986
  receiverOutputs,
67624
67987
  selectedOutputs: acquiredOutputs
67625
67988
  });
67626
- await this.markOutputsAsPendingWithdrawalAfterTransferSuccess(tokenIdB32, acquiredOutputs);
67989
+ await this.tokenOutputManager.lockOutputs(acquiredOutputs);
67627
67990
  return {
67628
67991
  ok: true,
67629
67992
  tokenIdentifier: tokenIdB32,
@@ -68038,55 +68401,23 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
68038
68401
  async syncTokenOutputs(tokenIdentifiers) {
68039
68402
  const filterByIdentifiers = Array.isArray(tokenIdentifiers) && tokenIdentifiers.length > 0;
68040
68403
  const rawTokenIdentifiers = filterByIdentifiers ? tokenIdentifiers.map((id) => decodeBech32mTokenIdentifier(id, this.config.getNetworkType()).tokenIdentifier) : void 0;
68041
- const outputsWithIdentifiers = (await this.tokenTransactionService.fetchOwnedTokenOutputs({
68404
+ const unsortedTokenOutputs = await this.tokenTransactionService.fetchOwnedTokenOutputs({
68042
68405
  ownerPublicKeys: [await this.config.signer.getIdentityPublicKey()],
68043
68406
  tokenIdentifiers: rawTokenIdentifiers
68044
- })).map((output) => {
68407
+ });
68408
+ const groupedOutputs = /* @__PURE__ */ new Map();
68409
+ for (const output of unsortedTokenOutputs) {
68045
68410
  if (!output.output?.tokenIdentifier || !output.output.id) throw new SparkValidationError("Server returned incomplete token output", {
68046
68411
  field: "output",
68047
68412
  value: output,
68048
68413
  expected: "output.output.tokenIdentifier and output.output.id to be defined"
68049
68414
  });
68050
- return {
68051
- output,
68052
- bech32mTokenIdentifier: encodeBech32mTokenIdentifier({
68053
- tokenIdentifier: output.output.tokenIdentifier,
68054
- network: this.config.getNetworkType()
68055
- }),
68056
- outputUuid: output.output.id
68057
- };
68058
- });
68059
- const availableOutputs = outputsWithIdentifiers.filter(({ bech32mTokenIdentifier, outputUuid }) => {
68060
- const pendingSet = this.pendingWithdrawnOutputIds.get(bech32mTokenIdentifier);
68061
- return !pendingSet || !pendingSet.has(outputUuid);
68062
- });
68063
- if (filterByIdentifiers) {
68064
- const fetchedIdsByToken = /* @__PURE__ */ new Map();
68065
- for (const { bech32mTokenIdentifier, outputUuid } of outputsWithIdentifiers) {
68066
- if (!fetchedIdsByToken.has(bech32mTokenIdentifier)) fetchedIdsByToken.set(bech32mTokenIdentifier, /* @__PURE__ */ new Set());
68067
- fetchedIdsByToken.get(bech32mTokenIdentifier).add(outputUuid);
68068
- }
68069
- for (const tokenId of tokenIdentifiers) {
68070
- const pendingSet = this.pendingWithdrawnOutputIds.get(tokenId);
68071
- if (!pendingSet) continue;
68072
- const fetchedIds = fetchedIdsByToken.get(tokenId) ?? /* @__PURE__ */ new Set();
68073
- for (const outputUuid of pendingSet) if (!fetchedIds.has(outputUuid)) pendingSet.delete(outputUuid);
68074
- if (pendingSet.size === 0) this.pendingWithdrawnOutputIds.delete(tokenId);
68075
- }
68076
- } else {
68077
- const allFetchedIds = new Set(outputsWithIdentifiers.map(({ outputUuid }) => outputUuid));
68078
- for (const [tokenId, pendingSet] of this.pendingWithdrawnOutputIds) {
68079
- for (const outputUuid of pendingSet) if (!allFetchedIds.has(outputUuid)) pendingSet.delete(outputUuid);
68080
- if (pendingSet.size === 0) this.pendingWithdrawnOutputIds.delete(tokenId);
68081
- }
68082
- }
68083
- const groupedOutputs = /* @__PURE__ */ new Map();
68084
- for (const { output, bech32mTokenIdentifier } of availableOutputs) {
68085
- if (!groupedOutputs.has(bech32mTokenIdentifier)) groupedOutputs.set(bech32mTokenIdentifier, []);
68086
- groupedOutputs.get(bech32mTokenIdentifier).push({
68087
- ...output,
68088
- previousTransactionVout: output.previousTransactionVout
68415
+ const bech32mTokenIdentifier = encodeBech32mTokenIdentifier({
68416
+ tokenIdentifier: output.output.tokenIdentifier,
68417
+ network: this.config.getNetworkType()
68089
68418
  });
68419
+ if (!groupedOutputs.has(bech32mTokenIdentifier)) groupedOutputs.set(bech32mTokenIdentifier, []);
68420
+ groupedOutputs.get(bech32mTokenIdentifier).push(output);
68090
68421
  }
68091
68422
  await this.tokenOutputManager.setOutputs(groupedOutputs, filterByIdentifiers ? tokenIdentifiers : void 0);
68092
68423
  }
@@ -68123,7 +68454,7 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
68123
68454
  outputSelectionStrategy: strategy,
68124
68455
  selectedOutputs: acquiredOutputs
68125
68456
  });
68126
- await this.markOutputsAsPendingWithdrawalAfterTransferSuccess(tokenIdentifier, acquiredOutputs);
68457
+ await this.tokenOutputManager.lockOutputs(acquiredOutputs);
68127
68458
  return txHash;
68128
68459
  } finally {
68129
68460
  await release();
@@ -68177,7 +68508,7 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
68177
68508
  outputSelectionStrategy,
68178
68509
  selectedOutputs: acquiredOutputs
68179
68510
  });
68180
- await this.markOutputsAsPendingWithdrawalAfterTransferSuccess(firstBech32mTokenIdentifier, acquiredOutputs);
68511
+ await this.tokenOutputManager.lockOutputs(acquiredOutputs);
68181
68512
  return txHash;
68182
68513
  } finally {
68183
68514
  await release();
@@ -68249,10 +68580,10 @@ var SparkWallet = class SparkWallet2 extends import_index.default {
68249
68580
  });
68250
68581
  }
68251
68582
  async getTokenOutputStats(tokenIdentifier) {
68252
- const outputs = await this.tokenOutputManager.getAllOutputs(tokenIdentifier);
68583
+ const availableOutputs = await this.tokenOutputManager.getAvailableOutputs(tokenIdentifier);
68253
68584
  return {
68254
- outputCount: outputs.length,
68255
- totalAmount: sumAvailableTokens(outputs)
68585
+ outputCount: availableOutputs.length,
68586
+ totalAmount: sumTokenOutputs(availableOutputs)
68256
68587
  };
68257
68588
  }
68258
68589
  /**
@@ -69133,6 +69464,7 @@ function longToNumber(int64) {
69133
69464
  function isSet(value) {
69134
69465
  return value !== null && value !== void 0;
69135
69466
  }
69467
+ var TOKEN_EXPIRY_BUFFER_SEC = 60;
69136
69468
  var ConnectionManager = class ConnectionManager2 {
69137
69469
  static DATE_HEADER = "date";
69138
69470
  static PROCESSING_TIME_HEADER = "x-processing-time-ms";
@@ -69184,24 +69516,37 @@ var ConnectionManager = class ConnectionManager2 {
69184
69516
  return `${address}|${identityHex}`;
69185
69517
  }
69186
69518
  static getCachedAuthToken(address, identityHex) {
69187
- return ConnectionManager2.authTokenCache.get(ConnectionManager2.makeAuthTokenKey(address, identityHex));
69519
+ const key = ConnectionManager2.makeAuthTokenKey(address, identityHex);
69520
+ const entry = ConnectionManager2.authTokenCache.get(key);
69521
+ if (!entry) return void 0;
69522
+ const bufferMs = TOKEN_EXPIRY_BUFFER_SEC * 1e3;
69523
+ if (getMonotonicTime() >= entry.expiresAtMono - bufferMs || Date.now() >= entry.expiresAtWallMs - bufferMs) {
69524
+ ConnectionManager2.authTokenCache.delete(key);
69525
+ return;
69526
+ }
69527
+ return entry.token;
69188
69528
  }
69189
- static setCachedAuthToken(address, identityHex, authToken) {
69190
- ConnectionManager2.authTokenCache.set(ConnectionManager2.makeAuthTokenKey(address, identityHex), authToken);
69529
+ static setCachedAuthToken(address, identityHex, authToken, expiresAtSec, nowSec) {
69530
+ const ttlMs = (expiresAtSec - nowSec) * 1e3;
69531
+ ConnectionManager2.authTokenCache.set(ConnectionManager2.makeAuthTokenKey(address, identityHex), {
69532
+ token: authToken,
69533
+ expiresAtMono: getMonotonicTime() + ttlMs,
69534
+ expiresAtWallMs: Date.now() + ttlMs
69535
+ });
69191
69536
  }
69192
69537
  static invalidateCachedAuthToken(address, identityHex) {
69193
69538
  ConnectionManager2.authTokenCache.delete(ConnectionManager2.makeAuthTokenKey(address, identityHex));
69194
69539
  }
69195
- static async getOrCreateAuthToken(address, identityHex, authenticate) {
69540
+ static async getOrCreateAuthToken(address, identityHex, getNowSec, authenticate) {
69196
69541
  const cached = ConnectionManager2.getCachedAuthToken(address, identityHex);
69197
69542
  if (cached) return cached;
69198
69543
  const tokenKey = ConnectionManager2.makeAuthTokenKey(address, identityHex);
69199
69544
  let authPromise = ConnectionManager2.authInflight.get(tokenKey);
69200
69545
  if (!authPromise) {
69201
69546
  authPromise = (async () => {
69202
- const authToken = await authenticate();
69203
- ConnectionManager2.setCachedAuthToken(address, identityHex, authToken);
69204
- return authToken;
69547
+ const result = await authenticate();
69548
+ ConnectionManager2.setCachedAuthToken(address, identityHex, result.token, result.expiresAtSec, getNowSec());
69549
+ return result.token;
69205
69550
  })();
69206
69551
  ConnectionManager2.authInflight.set(tokenKey, authPromise);
69207
69552
  }
@@ -69294,7 +69639,7 @@ var ConnectionManager = class ConnectionManager2 {
69294
69639
  }
69295
69640
  async authenticate(address) {
69296
69641
  const identityHex = await this.getIdentityPublicKeyHex();
69297
- return ConnectionManager2.getOrCreateAuthToken(address, identityHex, async () => {
69642
+ return ConnectionManager2.getOrCreateAuthToken(address, identityHex, () => Math.floor(this.getCurrentServerTime().getTime() / 1e3), async () => {
69298
69643
  const MAX_ATTEMPTS = 8;
69299
69644
  let lastError;
69300
69645
  const identityPublicKey = await this.config.signer.getIdentityPublicKey();
@@ -69314,7 +69659,10 @@ var ConnectionManager = class ConnectionManager2 {
69314
69659
  publicKey: identityPublicKey
69315
69660
  });
69316
69661
  if (sparkAuthnClient.close) sparkAuthnClient.close();
69317
- return verifyResp.sessionToken;
69662
+ return {
69663
+ token: verifyResp.sessionToken,
69664
+ expiresAtSec: verifyResp.expirationTimestamp
69665
+ };
69318
69666
  } catch (error) {
69319
69667
  if (isError(error)) {
69320
69668
  if (sparkAuthnClient.close) sparkAuthnClient.close();
@@ -70085,8 +70433,8 @@ export {
70085
70433
  splitSecretWithProofs,
70086
70434
  subtractPrivateKeys,
70087
70435
  subtractPublicKeys,
70088
- sumAvailableTokens,
70089
70436
  sumOfPrivateKeys,
70437
+ sumTokenOutputs,
70090
70438
  toProtoTimestamp,
70091
70439
  validateOutboundAdaptorSignature,
70092
70440
  validateShare,