From 8d2feb8433410fcd18f97816d1bb44983b30e3ae Mon Sep 17 00:00:00 2001 From: Daniel McNally Date: Wed, 7 Oct 2020 11:04:55 -0400 Subject: [PATCH 1/3] test(sim): connext collateralization with wait This restores the logic to request collateral in the custom xud builds used for instability tests by adding a one second wait after adding an order on the maker side (who then requests collateralization) but before placing a matching order on the taker side. This appears to work around a brief, transient inability to send a connext payment to a node immediately after that node requests collateral. Related PR #1916 - specifically the persistent simulation test failures that were eventually avoided by removing the collateral requests from custom-xud, which is being restored here. --- test/simulation/custom-xud.patch | 31 ---------------------------- test/simulation/tests-instability.go | 9 ++++++++ 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/test/simulation/custom-xud.patch b/test/simulation/custom-xud.patch index fb1334834..a4edd93a1 100644 --- a/test/simulation/custom-xud.patch +++ b/test/simulation/custom-xud.patch @@ -14,37 +14,6 @@ index 489a50a4..f9391527 100644 try { if (!this.config.rpc.disable) { // start rpc server first, it will respond with UNAVAILABLE error -diff --git a/lib/connextclient/ConnextClient.ts b/lib/connextclient/ConnextClient.ts -index 7fe05a71..240ad137 100644 ---- a/lib/connextclient/ConnextClient.ts -+++ b/lib/connextclient/ConnextClient.ts -@@ -309,24 +309,8 @@ class ConnextClient extends SwapClient { - } - } - -- public setReservedInboundAmount = (reservedInboundAmount: number, currency: string) => { -- const inboundCapacity = this._maxChannelInboundAmount.get(currency) || 0; -- if (inboundCapacity < reservedInboundAmount) { -- // we do not have enough inbound capacity to fill all open orders, so we will request more -- this.logger.debug(`collateral of ${inboundCapacity} for ${currency} is insufficient for reserved order amount of ${reservedInboundAmount}`); -- -- // we want to make a request for the current collateral plus the greater of any -- // minimum request size for the currency or the capacity shortage + 3% buffer -- const quantityToRequest = inboundCapacity + Math.max( -- reservedInboundAmount * 1.03 - inboundCapacity, -- ConnextClient.MIN_COLLATERAL_REQUEST_SIZES[currency] ?? 0, -- ); -- const unitsToRequest = this.unitConverter.amountToUnits({ currency, amount: quantityToRequest }); -- -- // we don't await this request - instead we allow for "lazy collateralization" to complete since -- // we don't expect all orders to be filled at once, we can be patient -- this.requestCollateralInBackground(currency, unitsToRequest); -- } -+ public setReservedInboundAmount = (_reservedInboundAmount: number, _currency: string) => { -+ // we don't request collateral for custom xud simulation tests - } - - protected updateCapacity = async () => { diff --git a/lib/swaps/SwapRecovery.ts b/lib/swaps/SwapRecovery.ts index 3759f6a3..4089dc94 100644 --- a/lib/swaps/SwapRecovery.ts diff --git a/test/simulation/tests-instability.go b/test/simulation/tests-instability.go index 9274cff72..f6a787eab 100644 --- a/test/simulation/tests-instability.go +++ b/test/simulation/tests-instability.go @@ -154,6 +154,9 @@ func testMakerCrashedDuringSwapConnextIn(net *xudtest.NetworkHarness, ht *harnes } ht.act.placeOrderAndBroadcast(net.Alice, net.Bob, aliceOrderReq) + // brief wait for collateralization to complete for Alice + time.Sleep(1 * time.Second) + // Place a matching order on Bob. bobOrderReq := &xudrpc.PlaceOrderRequest{ OrderId: "testMakerCrashedDuringSwapConnextIn", @@ -287,6 +290,9 @@ func testMakerConnextClientCrashedBeforeSettlement(net *xudtest.NetworkHarness, } ht.act.placeOrderAndBroadcast(net.Alice, net.Bob, aliceOrderReq) + // brief wait for collateralization to complete for Alice + time.Sleep(1 * time.Second) + // Place a matching order on Bob. bobOrderReq := &xudrpc.PlaceOrderRequest{ OrderId: "testMakerConnextClientCrashedBeforeSettlement", @@ -519,6 +525,9 @@ func testMakerCrashedAfterSendDelayedSettlementConnextIn(net *xudtest.NetworkHar } ht.act.placeOrderAndBroadcast(net.Alice, net.Bob, aliceOrderReq) + // brief wait for collateralization to complete for Alice + time.Sleep(1 * time.Second) + // Place a matching order on Bob. bobOrderReq := &xudrpc.PlaceOrderRequest{ OrderId: "testMakerCrashedAfterSendDelayedSettlementConnextIn", From be4121fd04156318c68dba28ee5f1a2483fd0c07 Mon Sep 17 00:00:00 2001 From: Daniel McNally Date: Fri, 9 Oct 2020 04:35:55 -0400 Subject: [PATCH 2/3] feat: derive child seed for swap clients This change uses separate mnemonics and seeds for each swap client that are unique to that client, rather than using a single seed and mnemonic across all clients. To accomplish this, a new method is added to the seedutil tool to derive a child mnemonic from a provided mnemonic. This is done by extracting the 16 bytes of entropy from the provided seed, concatenating the entropy with the name of the client (e.g. "LND-BTC") and then hashing the concatenation and taking 16 bytes from the resulting hash. Closes #1576. --- lib/lndclient/LndClient.ts | 9 ++++-- lib/nodekey/NodeKey.ts | 3 +- lib/utils/seedutil.ts | 14 +++++++- seedutil/SeedUtil.spec.ts | 30 +++++++++++++++++ seedutil/__snapshots__/SeedUtil.spec.ts.snap | 10 ++++++ seedutil/main.go | 34 ++++++++++++++++++++ 6 files changed, 96 insertions(+), 4 deletions(-) diff --git a/lib/lndclient/LndClient.ts b/lib/lndclient/LndClient.ts index e48230595..1ba7164f0 100644 --- a/lib/lndclient/LndClient.ts +++ b/lib/lndclient/LndClient.ts @@ -11,7 +11,8 @@ import { LightningClient, WalletUnlockerClient } from '../proto/lndrpc_grpc_pb'; import * as lndrpc from '../proto/lndrpc_pb'; import swapErrors from '../swaps/errors'; import SwapClient, { ChannelBalance, ClientStatus, PaymentState, SwapClientInfo, TradingLimits, WithdrawArguments } from '../swaps/SwapClient'; -import { SwapDeal, CloseChannelParams, OpenChannelParams } from '../swaps/types'; +import { CloseChannelParams, OpenChannelParams, SwapDeal } from '../swaps/types'; +import { deriveChild } from '../utils/seedutil'; import { base64ToHex, hexToUint8Array } from '../utils/utils'; import errors from './errors'; import { Chain, ChannelCount, ClientMethods, LndClientConfig, LndInfo } from './types'; @@ -918,7 +919,11 @@ class LndClient extends SwapClient { public initWallet = async (walletPassword: string, seedMnemonic: string[], restore = false, backup?: Uint8Array): Promise => { const request = new lndrpc.InitWalletRequest(); - request.setCipherSeedMnemonicList(seedMnemonic); + + // from the master seed/mnemonic we derive a child mnemonic for this specific client + const childMnemonic = await deriveChild(seedMnemonic, this.label); + request.setCipherSeedMnemonicList(childMnemonic); + request.setWalletPassword(Uint8Array.from(Buffer.from(walletPassword, 'utf8'))); if (restore) { request.setRecoveryWindow(2500); diff --git a/lib/nodekey/NodeKey.ts b/lib/nodekey/NodeKey.ts index de6b7857a..1f571d0a9 100644 --- a/lib/nodekey/NodeKey.ts +++ b/lib/nodekey/NodeKey.ts @@ -116,8 +116,9 @@ class NodeKey { } /** - * Derives a child seed from the private key for the swap client + * Derives a child mnemonic seed from the private key for the swap client. * @param swapClient the swap client to create the seed for + * @returns a BIP39 mnemonic */ public childSeed = (swapClient: SwapClientType) => { const privKeyHex = this.privKey.toString('hex'); diff --git a/lib/utils/seedutil.ts b/lib/utils/seedutil.ts index 31b1a630d..56f3f49cb 100644 --- a/lib/utils/seedutil.ts +++ b/lib/utils/seedutil.ts @@ -53,6 +53,18 @@ async function decipher(mnemonic: string[]) { return Buffer.from(decipheredSeed, 'hex'); } +async function deriveChild(mnemonic: string[], clientType: string) { + const { stdout, stderr } = await exec(`${seedutilPath} derivechild -client ${clientType} ${mnemonic.join(' ')}`); + + if (stderr) { + throw new Error(stderr); + } + + const childMnenomic = stdout.trim().split(' '); + assert.equal(childMnenomic.length, 24, 'seedutil did not derive child mnemonic of exactly 24 words'); + return childMnenomic; +} + async function generate() { const { stdout, stderr } = await exec(`${seedutilPath} generate`); @@ -65,4 +77,4 @@ async function generate() { return mnemonic; } -export { keystore, encipher, decipher, generate }; +export { keystore, encipher, decipher, deriveChild, generate }; diff --git a/seedutil/SeedUtil.spec.ts b/seedutil/SeedUtil.spec.ts index cc30a4584..adec48150 100644 --- a/seedutil/SeedUtil.spec.ts +++ b/seedutil/SeedUtil.spec.ts @@ -143,6 +143,36 @@ describe('SeedUtil generate', () => { }); }); +describe('SeedUtil derivechild', () => { + test('it errors without a client type', async () => { + const cmd = `./seedutil/seedutil derivechild ${VALID_SEED.seedWords.slice(0, 24).join(' ')}`; + await expect(executeCommand(cmd)) + .rejects.toThrow('client is required'); + }); + + test('it errors with 23 words', async () => { + const cmd = `./seedutil/seedutil derivechild -client BTC ${VALID_SEED.seedWords.slice(0, 23).join(' ')}`; + await expect(executeCommand(cmd)) + .rejects.toThrow(ERRORS.INVALID_ARGS_LENGTH); + }); + + test('it succeeds with 24 words, no aezeed password', async () => { + const cmd = `./seedutil/seedutil derivechild -client BTC ${VALID_SEED_NO_PASS.seedWords.join(' ')}`; + const result = await executeCommand(cmd); + // the mnemonic will change each time due to the salt, but the deciphered seed should stay the same + const decipherCmd = `./seedutil/seedutil decipher ${result}`; + await expect(executeCommand(decipherCmd)).resolves.toMatchSnapshot(); + }); + + test('it succeeds with 24 words, valid aezeed password', async () => { + const cmd = `./seedutil/seedutil derivechild -aezeedpass=${VALID_SEED.seedPassword} -client BTC ${VALID_SEED.seedWords.join(' ')}`; + const result = await executeCommand(cmd); + // the mnemonic will change each time due to the salt, but the deciphered seed should stay the same + const decipherCmd = `./seedutil/seedutil decipher -aezeedpass=${VALID_SEED.seedPassword} ${result}`; + await expect(executeCommand(decipherCmd)).resolves.toMatchSnapshot(); + }); +}); + describe('SeedUtil keystore', () => { beforeEach(async () => { await deleteDir(DEFAULT_KEYSTORE_PATH); diff --git a/seedutil/__snapshots__/SeedUtil.spec.ts.snap b/seedutil/__snapshots__/SeedUtil.spec.ts.snap index 32a2858fc..5c1805510 100644 --- a/seedutil/__snapshots__/SeedUtil.spec.ts.snap +++ b/seedutil/__snapshots__/SeedUtil.spec.ts.snap @@ -10,6 +10,16 @@ exports[`SeedUtil decipher it succeeds with 24 words, valid aezeed password 1`] " `; +exports[`SeedUtil derivechild it succeeds with 24 words, no aezeed password 1`] = ` +"000f4b90d9f9720bfac78aaea09a5193b34811 +" +`; + +exports[`SeedUtil derivechild it succeeds with 24 words, valid aezeed password 1`] = ` +"000ecdef333ecf9054ccb4fb843a3dbbf4ac6a +" +`; + exports[`SeedUtil encipher it succeeds with 24 words, no aezeed password 1`] = ` "00738860374692022c462027a35aaaef3c3289aa0a057e2600000000002cad2e2b " diff --git a/seedutil/main.go b/seedutil/main.go index 2dbedb21d..b247d6493 100644 --- a/seedutil/main.go +++ b/seedutil/main.go @@ -58,6 +58,7 @@ func main() { encipherCommand := flag.NewFlagSet("encipher", flag.ExitOnError) decipherCommand := flag.NewFlagSet("decipher", flag.ExitOnError) generateCommand := flag.NewFlagSet("generate", flag.ExitOnError) + deriveChildCommand := flag.NewFlagSet("derivechild", flag.ExitOnError) if len(os.Args) < 2 { fmt.Println("subcommand is required") @@ -132,6 +133,39 @@ func main() { } fmt.Println(hex.EncodeToString(decipheredSeed[:])) + case "derivechild": + client := deriveChildCommand.String("client", "", "client type") + aezeedPassphrase := deriveChildCommand.String("aezeedpass", defaultAezeedPassphrase, "aezeed passphrase") + deriveChildCommand.Parse(os.Args[2:]) + args = deriveChildCommand.Args() + + if client == nil || len(*client) == 0 { + fmt.Fprintf(os.Stderr, "client is required") + os.Exit(1) + } + + mnemonic := parseMnemonic(args) + cipherSeed := mnemonicToCipherSeed(mnemonic, aezeedPassphrase) + + // derive 64-byte hash from client type + cipherSeed's 16 bytes of entropy + hash := sha512.Sum512(append([]byte(*client), cipherSeed.Entropy[:]...)) + + // use the first 16 byte of the hash as the new entropy + var newEntropy [16]byte + copy(newEntropy[:], hash[:16]) + + childCipherSeed, err := aezeed.New(0, &newEntropy, cipherSeed.BirthdayTime()) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + childMnemonic, err := childCipherSeed.ToMnemonic([]byte(*aezeedPassphrase)) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + fmt.Println(strings.Join([]string(childMnemonic[:]), " ")) case "generate": aezeedPassphrase := generateCommand.String("aezeedpass", defaultAezeedPassphrase, "aezeed passphrase") generateCommand.Parse(os.Args[2:]) From 8b18dd7426f01a760e571a0a5bb2310759229b64 Mon Sep 17 00:00:00 2001 From: Daniel McNally Date: Tue, 13 Oct 2020 14:17:29 -0400 Subject: [PATCH 3/3] feat(rpc): expose reserved balance for GetBalance (#1925) This adds a field to the `GetBalance` response to return the balance that is reserved for open orders. --- docs/api.md | 1 + lib/cli/commands/getbalance.ts | 38 +- lib/grpc/GrpcService.ts | 3 + lib/proto/xudrpc.swagger.json | 5 + lib/proto/xudrpc_pb.d.ts | 4 + lib/proto/xudrpc_pb.js | 29 +- lib/service/Service.ts | 11 +- lib/swaps/SwapClient.ts | 2 + lib/swaps/SwapClientManager.ts | 12 +- proto/xudrpc.proto | 2 + test/jest/Service.spec.ts | 56 ++ test/jest/SwapClientManager.spec.ts | 12 +- .../cli/__snapshots__/getbalance.spec.ts.snap | 81 +++ test/jest/cli/getbalance.spec.ts | 96 ++++ test/simulation/tests-integration.go | 9 +- test/simulation/xudrpc/xudrpc.pb.go | 498 +++++++++--------- 16 files changed, 585 insertions(+), 274 deletions(-) create mode 100644 test/jest/cli/__snapshots__/getbalance.spec.ts.snap create mode 100644 test/jest/cli/getbalance.spec.ts diff --git a/docs/api.md b/docs/api.md index 14334d1d9..9a3224af7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -156,6 +156,7 @@ | inactive_channel_balance | [uint64](#uint64) | | Sum of inactive channel balances denominated in satoshis. | | wallet_balance | [uint64](#uint64) | | Confirmed wallet balance in satoshis. | | unconfirmed_wallet_balance | [uint64](#uint64) | | Unconfirmed wallet balance in satoshis. | +| reserved_balance | [uint64](#uint64) | | The balance that's reserved for open orders. | diff --git a/lib/cli/commands/getbalance.ts b/lib/cli/commands/getbalance.ts index 9a98fbc7d..c058a2b53 100644 --- a/lib/cli/commands/getbalance.ts +++ b/lib/cli/commands/getbalance.ts @@ -8,40 +8,46 @@ import { satsToCoinsStr } from '../utils'; const HEADERS = [ colors.blue('Currency'), colors.blue('Total Balance'), - colors.blue('Channel Balance (Tradable)'), colors.blue('Wallet Balance (Not Tradable)'), + colors.blue('Channel Balance (Tradable)'), + colors.blue('In Orders'), ]; const formatBalances = (balances: GetBalanceResponse.AsObject) => { const formatted: any[] = []; - balances.balancesMap.forEach((balance) => { + balances.balancesMap.forEach((balanceElement) => { + const currency = balanceElement[0]; + const balance = balanceElement[1]; const element = []; element.push( - balance[0], - `${satsToCoinsStr(balance[1].totalBalance)}`, - formatBalance(balance[1].channelBalance, balance[1].pendingChannelBalance, balance[1].inactiveChannelBalance), - formatBalance(balance[1].walletBalance, balance[1].unconfirmedWalletBalance), + currency, + satsToCoinsStr(balance.totalBalance), + formatBalance(balance.channelBalance, balance.pendingChannelBalance, balance.inactiveChannelBalance), + formatBalance(balance.walletBalance, balance.unconfirmedWalletBalance), + satsToCoinsStr(balance.reservedBalance), ); formatted.push(element); }); return formatted; }; -const formatBalance = (confirmedBalance: number, unconfirmedBalance: number, inactiveBalance = 0) => { - const confirmedBalanceStr = satsToCoinsStr(confirmedBalance); - const unconfirmedBalanceStr = unconfirmedBalance > 0 ? `${satsToCoinsStr(unconfirmedBalance)} pending` : undefined; +const formatBalance = (availableBalance: number, pendingBalance: number, inactiveBalance = 0) => { + const availableBalanceStr = satsToCoinsStr(availableBalance); + const unconfirmedBalanceStr = pendingBalance > 0 ? `${satsToCoinsStr(pendingBalance)} pending` : undefined; const inactiveBalanceStr = inactiveBalance > 0 ? `${satsToCoinsStr(inactiveBalance)} inactive` : undefined; if (unconfirmedBalanceStr || inactiveBalanceStr) { - let str = `${confirmedBalanceStr} (`; + let str = availableBalanceStr; + let paranthetical = ''; if (unconfirmedBalanceStr) { - str += inactiveBalanceStr ? `${inactiveBalanceStr} | ${unconfirmedBalanceStr}` : unconfirmedBalanceStr; - } else { - str += inactiveBalanceStr; + paranthetical += paranthetical ? ` | ${unconfirmedBalanceStr}` : unconfirmedBalanceStr; + } + if (inactiveBalanceStr) { + paranthetical += paranthetical ? ` | ${inactiveBalanceStr}` : inactiveBalanceStr; } - str += ')'; + str += ` (${paranthetical})`; return str; } - return confirmedBalanceStr; + return availableBalanceStr; }; const createTable = () => { @@ -51,7 +57,7 @@ const createTable = () => { return table; }; -const displayBalances = (balances: GetBalanceResponse.AsObject) => { +export const displayBalances = (balances: GetBalanceResponse.AsObject) => { const table = createTable(); const formatted = formatBalances(balances); formatted.forEach(balance => table.push(balance)); diff --git a/lib/grpc/GrpcService.ts b/lib/grpc/GrpcService.ts index 2a79d3acb..45a8ca430 100644 --- a/lib/grpc/GrpcService.ts +++ b/lib/grpc/GrpcService.ts @@ -307,6 +307,9 @@ class GrpcService { balance.setInactiveChannelBalance(balanceObj.inactiveChannelBalance); balance.setWalletBalance(balanceObj.walletBalance); balance.setUnconfirmedWalletBalance(balanceObj.unconfirmedWalletBalance); + if (balanceObj.reservedBalance) { + balance.setReservedBalance(balanceObj.reservedBalance); + } balancesMap.set(currency, balance); }); callback(null, response); diff --git a/lib/proto/xudrpc.swagger.json b/lib/proto/xudrpc.swagger.json index bdd789be3..0a1c485ae 100644 --- a/lib/proto/xudrpc.swagger.json +++ b/lib/proto/xudrpc.swagger.json @@ -887,6 +887,11 @@ "type": "string", "format": "uint64", "description": "Unconfirmed wallet balance in satoshis." + }, + "reserved_balance": { + "type": "string", + "format": "uint64", + "description": "The balance that's reserved for open orders." } } }, diff --git a/lib/proto/xudrpc_pb.d.ts b/lib/proto/xudrpc_pb.d.ts index 0c450920a..93e2eb745 100644 --- a/lib/proto/xudrpc_pb.d.ts +++ b/lib/proto/xudrpc_pb.d.ts @@ -84,6 +84,9 @@ export class Balance extends jspb.Message { getUnconfirmedWalletBalance(): number; setUnconfirmedWalletBalance(value: number): void; + getReservedBalance(): number; + setReservedBalance(value: number): void; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): Balance.AsObject; @@ -103,6 +106,7 @@ export namespace Balance { inactiveChannelBalance: number, walletBalance: number, unconfirmedWalletBalance: number, + reservedBalance: number, } } diff --git a/lib/proto/xudrpc_pb.js b/lib/proto/xudrpc_pb.js index e02967cec..08518fe93 100644 --- a/lib/proto/xudrpc_pb.js +++ b/lib/proto/xudrpc_pb.js @@ -546,7 +546,8 @@ proto.xudrpc.Balance.toObject = function(includeInstance, msg) { pendingChannelBalance: jspb.Message.getFieldWithDefault(msg, 3, 0), inactiveChannelBalance: jspb.Message.getFieldWithDefault(msg, 4, 0), walletBalance: jspb.Message.getFieldWithDefault(msg, 5, 0), - unconfirmedWalletBalance: jspb.Message.getFieldWithDefault(msg, 6, 0) + unconfirmedWalletBalance: jspb.Message.getFieldWithDefault(msg, 6, 0), + reservedBalance: jspb.Message.getFieldWithDefault(msg, 7, 0) }; if (includeInstance) { @@ -607,6 +608,10 @@ proto.xudrpc.Balance.deserializeBinaryFromReader = function(msg, reader) { var value = /** @type {number} */ (reader.readUint64()); msg.setUnconfirmedWalletBalance(value); break; + case 7: + var value = /** @type {number} */ (reader.readUint64()); + msg.setReservedBalance(value); + break; default: reader.skipField(); break; @@ -678,6 +683,13 @@ proto.xudrpc.Balance.serializeBinaryToWriter = function(message, writer) { f ); } + f = message.getReservedBalance(); + if (f !== 0) { + writer.writeUint64( + 7, + f + ); + } }; @@ -771,6 +783,21 @@ proto.xudrpc.Balance.prototype.setUnconfirmedWalletBalance = function(value) { }; +/** + * optional uint64 reserved_balance = 7; + * @return {number} + */ +proto.xudrpc.Balance.prototype.getReservedBalance = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0)); +}; + + +/** @param {number} value */ +proto.xudrpc.Balance.prototype.setReservedBalance = function(value) { + jspb.Message.setProto3IntField(this, 7, value); +}; + + /** * Generated by JsPbCodeGenerator. diff --git a/lib/service/Service.ts b/lib/service/Service.ts index 41d9924ae..2c49b2207 100644 --- a/lib/service/Service.ts +++ b/lib/service/Service.ts @@ -8,10 +8,10 @@ import OrderBook from '../orderbook/OrderBook'; import { Currency, isOwnOrder, Order, OrderPortion, OwnLimitOrder, OwnMarketOrder, OwnOrder, PeerOrder, PlaceOrderEvent } from '../orderbook/types'; import Pool from '../p2p/Pool'; import swapsErrors from '../swaps/errors'; -import { TradingLimits } from '../swaps/SwapClient'; +import { ChannelBalance, TradingLimits } from '../swaps/SwapClient'; import SwapClientManager from '../swaps/SwapClientManager'; import Swaps from '../swaps/Swaps'; -import { ResolveRequest, SwapDeal, SwapFailure, SwapSuccess, SwapAccepted } from '../swaps/types'; +import { ResolveRequest, SwapAccepted, SwapDeal, SwapFailure, SwapSuccess } from '../swaps/types'; import { isNodePubKey } from '../utils/aliasUtils'; import { parseUri, toUri, UriParts } from '../utils/uriUtils'; import { checkDecimalPlaces, sortOrders, toEip55Address } from '../utils/utils'; @@ -113,7 +113,7 @@ class Service { /** Gets the total balance for one or all currencies. */ public getBalance = async (args: { currency: string }) => { const { currency } = args; - const channelBalances = new Map(); + const channelBalances = new Map(); const walletBalances = new Map(); if (currency) { @@ -125,6 +125,7 @@ class Service { await swapClient.channelBalance(currency), await swapClient.walletBalance(currency), ]); + channelBalance.reservedBalance = this.swapClientManager.getOutboundReservedAmount(currency); channelBalances.set(currency, channelBalance); walletBalances.set(currency, walletBalance); } else { @@ -135,6 +136,7 @@ class Service { this.swapClientManager.swapClients.forEach((swapClient, currency) => { if (swapClient.isConnected()) { balancePromises.push(swapClient.channelBalance(currency).then((channelBalance) => { + channelBalance.reservedBalance = this.swapClientManager.getOutboundReservedAmount(currency); channelBalances.set(currency, channelBalance); }).catch(this.logger.error)); balancePromises.push(swapClient.walletBalance(currency).then((walletBalance) => { @@ -147,7 +149,7 @@ class Service { const balances = new Map(); channelBalances.forEach((channelBalance, currency) => { const walletBalance = walletBalances.get(currency); @@ -162,6 +164,7 @@ class Service { channelBalance: channelBalance.balance, pendingChannelBalance: channelBalance.pendingOpenBalance, inactiveChannelBalance: channelBalance.inactiveBalance, + reservedBalance: channelBalance.reservedBalance, walletBalance: walletBalance.confirmedBalance, unconfirmedWalletBalance: walletBalance.unconfirmedBalance, }); diff --git a/lib/swaps/SwapClient.ts b/lib/swaps/SwapClient.ts index 14fe24c41..bf158052a 100644 --- a/lib/swaps/SwapClient.ts +++ b/lib/swaps/SwapClient.ts @@ -34,6 +34,8 @@ type ChannelBalance = { pendingOpenBalance: number, /** The cumulative balance of inactive channels denominated in satoshis. */ inactiveBalance: number, + /** The balance that is reserved for open orders denominated in satoshis. */ + reservedBalance?: number, }; type WalletBalance = { diff --git a/lib/swaps/SwapClientManager.ts b/lib/swaps/SwapClientManager.ts index d38fea186..2d76a4bae 100644 --- a/lib/swaps/SwapClientManager.ts +++ b/lib/swaps/SwapClientManager.ts @@ -163,6 +163,14 @@ class SwapClientManager extends EventEmitter { } } + public getOutboundReservedAmount = (currency: string) => { + return this.outboundReservedAmounts.get(currency); + } + + public getInboundReservedAmount = (currency: string) => { + return this.inboundReservedAmounts.get(currency); + } + public addOutboundReservedAmount = (currency: string, amount: number) => { const outboundReservedAmount = this.outboundReservedAmounts.get(currency); const newOutboundReservedAmount = (outboundReservedAmount ?? 0) + amount; @@ -180,13 +188,13 @@ class SwapClientManager extends EventEmitter { public subtractOutboundReservedAmount = (currency: string, amount: number) => { const outboundReservedAmount = this.outboundReservedAmounts.get(currency); assert(outboundReservedAmount && outboundReservedAmount >= amount); - this.outboundReservedAmounts.set(currency, (outboundReservedAmount ?? 0) - amount); + this.outboundReservedAmounts.set(currency, outboundReservedAmount - amount); } public subtractInboundReservedAmount = (currency: string, amount: number) => { const inboundReservedAmount = this.inboundReservedAmounts.get(currency); assert(inboundReservedAmount && inboundReservedAmount >= amount); - this.inboundReservedAmounts.set(currency, (inboundReservedAmount ?? 0) - amount); + this.inboundReservedAmounts.set(currency, inboundReservedAmount - amount); } /** diff --git a/proto/xudrpc.proto b/proto/xudrpc.proto index 15ca3f27b..fce3113a7 100644 --- a/proto/xudrpc.proto +++ b/proto/xudrpc.proto @@ -359,6 +359,8 @@ message Balance { uint64 wallet_balance = 5 [json_name = "wallet_balance"]; // Unconfirmed wallet balance in satoshis. uint64 unconfirmed_wallet_balance = 6 [json_name = "unconfirmed_wallet_balance"]; + // The balance that's reserved for open orders. + uint64 reserved_balance = 7 [json_name = "reserved_balance"]; } message BanRequest { diff --git a/test/jest/Service.spec.ts b/test/jest/Service.spec.ts index a0b5d749a..d50e6a1bb 100644 --- a/test/jest/Service.spec.ts +++ b/test/jest/Service.spec.ts @@ -17,6 +17,7 @@ jest.mock('../../lib/swaps/SwapClientManager', () => { return jest.fn().mockImplementation(() => { return { getType: () => SwapClientType.Lnd, + getOutboundReservedAmount: () => 0, }; }); }); @@ -189,6 +190,61 @@ describe('Service', () => { expect(btcBalance.totalBalance).toEqual(289008); }); + test('returns balance with reserved amounts', async () => { + setup(); + const reservedBalance = 10000; + service['swapClientManager'].getOutboundReservedAmount = jest.fn().mockReturnValue(reservedBalance); + const result = await service.getBalance({ currency: 'BTC' }); + expect(result.size).toEqual(1); + + const btcBalance = result.get('BTC')!; + expect(btcBalance).toBeTruthy(); + expect(btcBalance.channelBalance).toEqual(70000); + expect(btcBalance.pendingChannelBalance).toEqual(190191); + expect(btcBalance.inactiveChannelBalance).toEqual(18817); + expect(btcBalance.walletBalance).toEqual(10000); + expect(btcBalance.unconfirmedWalletBalance).toEqual(0); + expect(btcBalance.totalBalance).toEqual(289008); + expect(btcBalance.reservedBalance).toEqual(reservedBalance); + }); + + test('returns balance with reserved amounts for multiple currencies', async () => { + setup(); + const btcReservedBalance = 10000; + const ltcReservedBalance = 2345; + service['swapClientManager'].getOutboundReservedAmount = jest.fn().mockImplementation((currency) => { + if (currency === 'BTC') { + return btcReservedBalance; + } + if (currency === 'LTC') { + return ltcReservedBalance; + } + return undefined; + }); + const result = await service.getBalance({ currency: '' }); + expect(result.size).toEqual(2); + + const btcBalance = result.get('BTC')!; + expect(btcBalance).toBeTruthy(); + expect(btcBalance.channelBalance).toEqual(70000); + expect(btcBalance.pendingChannelBalance).toEqual(190191); + expect(btcBalance.inactiveChannelBalance).toEqual(18817); + expect(btcBalance.walletBalance).toEqual(10000); + expect(btcBalance.unconfirmedWalletBalance).toEqual(0); + expect(btcBalance.totalBalance).toEqual(289008); + expect(btcBalance.reservedBalance).toEqual(btcReservedBalance); + + const ltcBalance = result.get('LTC')!; + expect(ltcBalance).toBeTruthy(); + expect(ltcBalance.channelBalance).toEqual(0); + expect(ltcBalance.pendingChannelBalance).toEqual(0); + expect(ltcBalance.inactiveChannelBalance).toEqual(12345); + expect(ltcBalance.walletBalance).toEqual(1500); + expect(ltcBalance.unconfirmedWalletBalance).toEqual(500); + expect(ltcBalance.totalBalance).toEqual(14345); + expect(ltcBalance.reservedBalance).toEqual(ltcReservedBalance); + }); + test('throws in case of invalid currency', async () => { setup(); await expect(service.getBalance({ currency: 'A' })).rejects.toMatchSnapshot(); diff --git a/test/jest/SwapClientManager.spec.ts b/test/jest/SwapClientManager.spec.ts index a7fc413a8..d2fe9be39 100644 --- a/test/jest/SwapClientManager.spec.ts +++ b/test/jest/SwapClientManager.spec.ts @@ -185,19 +185,19 @@ describe('Swaps.SwapClientManager', () => { }); test('it adds outbound reserved amounts', () => { - expect(swapClientManager['outboundReservedAmounts'].get(currency)).toBeUndefined(); + expect(swapClientManager.getOutboundReservedAmount(currency)).toBeUndefined(); swapClientManager.addOutboundReservedAmount(currency, amount); - expect(swapClientManager['outboundReservedAmounts'].get(currency)).toEqual(amount); + expect(swapClientManager.getOutboundReservedAmount(currency)).toEqual(amount); swapClientManager.addOutboundReservedAmount(currency, amount); - expect(swapClientManager['outboundReservedAmounts'].get(currency)).toEqual(amount * 2); + expect(swapClientManager.getOutboundReservedAmount(currency)).toEqual(amount * 2); }); test('it subtracts outbound reserved amounts', () => { - expect(swapClientManager['outboundReservedAmounts'].get(currency)).toBeUndefined(); + expect(swapClientManager.getOutboundReservedAmount(currency)).toBeUndefined(); swapClientManager.addOutboundReservedAmount(currency, amount); - expect(swapClientManager['outboundReservedAmounts'].get(currency)).toEqual(amount); + expect(swapClientManager.getOutboundReservedAmount(currency)).toEqual(amount); swapClientManager.subtractOutboundReservedAmount(currency, amount); - expect(swapClientManager['outboundReservedAmounts'].get(currency)).toEqual(0); + expect(swapClientManager.getOutboundReservedAmount(currency)).toEqual(0); }); test('it adds inbound reserved amounts and sets amount on swap client', () => { diff --git a/test/jest/cli/__snapshots__/getbalance.spec.ts.snap b/test/jest/cli/__snapshots__/getbalance.spec.ts.snap new file mode 100644 index 000000000..707c6bd5a --- /dev/null +++ b/test/jest/cli/__snapshots__/getbalance.spec.ts.snap @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`displayBalances should print a table 1`] = ` +Array [ + Array [ + " +Balance:", + ], + Array [ + "┌──────────┬───────────────┬───────────────────────────────┬────────────────────────────┬───────────┐ +│ Currency │ Total Balance │ Wallet Balance (Not Tradable) │ Channel Balance (Tradable) │ In Orders │ +├──────────┼───────────────┼───────────────────────────────┼────────────────────────────┼───────────┤ +│ BTC │ 0.005 │ 0.004 │ 0.001 │ 0 │ +└──────────┴───────────────┴───────────────────────────────┴────────────────────────────┴───────────┘", + ], +] +`; + +exports[`displayBalances should print a table with balance reserved for orders 1`] = ` +Array [ + Array [ + " +Balance:", + ], + Array [ + "┌──────────┬───────────────┬───────────────────────────────┬────────────────────────────┬───────────┐ +│ Currency │ Total Balance │ Wallet Balance (Not Tradable) │ Channel Balance (Tradable) │ In Orders │ +├──────────┼───────────────┼───────────────────────────────┼────────────────────────────┼───────────┤ +│ BTC │ 0.005 │ 0.004 │ 0.001 │ 0.0008 │ +└──────────┴───────────────┴───────────────────────────────┴────────────────────────────┴───────────┘", + ], +] +`; + +exports[`displayBalances should print a table with pending and inactive balances 1`] = ` +Array [ + Array [ + " +Balance:", + ], + Array [ + "┌──────────┬───────────────┬──────────────────────────────────────────┬────────────────────────────┬───────────┐ +│ Currency │ Total Balance │ Wallet Balance (Not Tradable) │ Channel Balance (Tradable) │ In Orders │ +├──────────┼───────────────┼──────────────────────────────────────────┼────────────────────────────┼───────────┤ +│ BTC │ 0.005 │ 0.004 (0.00075 pending | 0.001 inactive) │ 0.001 (0.00025 pending) │ 0 │ +└──────────┴───────────────┴──────────────────────────────────────────┴────────────────────────────┴───────────┘", + ], +] +`; + +exports[`displayBalances should print a table with pending balances 1`] = ` +Array [ + Array [ + " +Balance:", + ], + Array [ + "┌──────────┬───────────────┬───────────────────────────────┬────────────────────────────┬───────────┐ +│ Currency │ Total Balance │ Wallet Balance (Not Tradable) │ Channel Balance (Tradable) │ In Orders │ +├──────────┼───────────────┼───────────────────────────────┼────────────────────────────┼───────────┤ +│ BTC │ 0.005 │ 0.004 (0.00075 pending) │ 0.001 (0.00025 pending) │ 0 │ +└──────────┴───────────────┴───────────────────────────────┴────────────────────────────┴───────────┘", + ], +] +`; + +exports[`displayBalances should print a table with pending, inactive, and reserved balances 1`] = ` +Array [ + Array [ + " +Balance:", + ], + Array [ + "┌──────────┬───────────────┬──────────────────────────────────────────┬────────────────────────────┬───────────┐ +│ Currency │ Total Balance │ Wallet Balance (Not Tradable) │ Channel Balance (Tradable) │ In Orders │ +├──────────┼───────────────┼──────────────────────────────────────────┼────────────────────────────┼───────────┤ +│ BTC │ 0.005 │ 0.004 (0.00075 pending | 0.001 inactive) │ 0.001 (0.00025 pending) │ 0.0008 │ +└──────────┴───────────────┴──────────────────────────────────────────┴────────────────────────────┴───────────┘", + ], +] +`; diff --git a/test/jest/cli/getbalance.spec.ts b/test/jest/cli/getbalance.spec.ts new file mode 100644 index 000000000..647f7509c --- /dev/null +++ b/test/jest/cli/getbalance.spec.ts @@ -0,0 +1,96 @@ +import { displayBalances } from '../../../lib/cli/commands/getbalance'; + +jest.mock('colors/safe', () => { + return { + blue: (str: string) => str, + underline: (str: string) => str, + bold: (str: string) => str, + }; +}); + +describe('displayBalances', () => { + const mockLog = jest.fn(); + console.log = mockLog; + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should print a table', () => { + displayBalances({ + balancesMap: [['BTC', { + totalBalance: 500000, + channelBalance: 400000, + pendingChannelBalance: 0, + inactiveChannelBalance: 0, + walletBalance: 100000, + unconfirmedWalletBalance: 0, + reservedBalance: 0, + }]], + }); + + expect(mockLog.mock.calls).toMatchSnapshot(); + }); + + it('should print a table with pending balances', () => { + displayBalances({ + balancesMap: [['BTC', { + totalBalance: 500000, + channelBalance: 400000, + pendingChannelBalance: 75000, + inactiveChannelBalance: 0, + walletBalance: 100000, + unconfirmedWalletBalance: 25000, + reservedBalance: 0, + }]], + }); + expect(mockLog.mock.calls).toMatchSnapshot(); + }); + + it('should print a table with pending and inactive balances', () => { + displayBalances({ + balancesMap: [['BTC', { + totalBalance: 500000, + channelBalance: 400000, + pendingChannelBalance: 75000, + inactiveChannelBalance: 100000, + walletBalance: 100000, + unconfirmedWalletBalance: 25000, + reservedBalance: 0, + }]], + }); + + expect(mockLog.mock.calls).toMatchSnapshot(); + }); + + it('should print a table with balance reserved for orders', () => { + displayBalances({ + balancesMap: [['BTC', { + totalBalance: 500000, + channelBalance: 400000, + pendingChannelBalance: 0, + inactiveChannelBalance: 0, + walletBalance: 100000, + unconfirmedWalletBalance: 0, + reservedBalance: 80000, + }]], + }); + expect(mockLog.mock.calls).toMatchSnapshot(); + }); + + it('should print a table with pending, inactive, and reserved balances', () => { + displayBalances({ + balancesMap: [['BTC', { + totalBalance: 500000, + channelBalance: 400000, + pendingChannelBalance: 75000, + inactiveChannelBalance: 100000, + walletBalance: 100000, + unconfirmedWalletBalance: 25000, + reservedBalance: 80000, + }]], + }); + expect(mockLog.mock.calls).toMatchSnapshot(); + }); + +}); diff --git a/test/simulation/tests-integration.go b/test/simulation/tests-integration.go index 86ad4d804..1414ef6eb 100644 --- a/test/simulation/tests-integration.go +++ b/test/simulation/tests-integration.go @@ -198,12 +198,19 @@ func testOrderBroadcastAndInvalidation(net *xudtest.NetworkHarness, ht *harnessT Price: 0.02, Quantity: 1000000, PairId: "LTC/BTC", - OrderId: "random_order_id", + OrderId: "testOrderBroadcastAndInvalidation", Side: xudrpc.OrderSide_BUY, } order := ht.act.placeOrderAndBroadcast(net.Alice, net.Bob, req) + resBal, err := net.Alice.Client.GetBalance(ht.ctx, &xudrpc.GetBalanceRequest{Currency: "BTC"}) + ht.assert.NoError(err) + ht.assert.Equal(20000, int(resBal.Balances["BTC"].ReservedBalance)) + ht.act.removeOrderAndInvalidate(net.Alice, net.Bob, order) + resBal, err = net.Alice.Client.GetBalance(ht.ctx, &xudrpc.GetBalanceRequest{Currency: "BTC"}) + ht.assert.NoError(err) + ht.assert.Equal(0, int(resBal.Balances["BTC"].ReservedBalance)) // Cleanup. ht.act.disconnect(net.Alice, net.Bob) diff --git a/test/simulation/xudrpc/xudrpc.pb.go b/test/simulation/xudrpc/xudrpc.pb.go index ecd863ce4..3f484b720 100644 --- a/test/simulation/xudrpc/xudrpc.pb.go +++ b/test/simulation/xudrpc/xudrpc.pb.go @@ -255,10 +255,12 @@ type Balance struct { // Confirmed wallet balance in satoshis. WalletBalance uint64 `protobuf:"varint,5,opt,name=wallet_balance,proto3" json:"wallet_balance,omitempty"` // Unconfirmed wallet balance in satoshis. - UnconfirmedWalletBalance uint64 `protobuf:"varint,6,opt,name=unconfirmed_wallet_balance,proto3" json:"unconfirmed_wallet_balance,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + UnconfirmedWalletBalance uint64 `protobuf:"varint,6,opt,name=unconfirmed_wallet_balance,proto3" json:"unconfirmed_wallet_balance,omitempty"` + // The balance that's reserved for open orders. + ReservedBalance uint64 `protobuf:"varint,7,opt,name=reserved_balance,proto3" json:"reserved_balance,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Balance) Reset() { *m = Balance{} } @@ -328,6 +330,13 @@ func (m *Balance) GetUnconfirmedWalletBalance() uint64 { return 0 } +func (m *Balance) GetReservedBalance() uint64 { + if m != nil { + return m.ReservedBalance + } + return 0 +} + type BanRequest struct { // The node pub key or alias of the node to ban. NodeIdentifier string `protobuf:"bytes,1,opt,name=node_identifier,proto3" json:"node_identifier,omitempty"` @@ -4413,246 +4422,247 @@ func init() { func init() { proto.RegisterFile("xudrpc.proto", fileDescriptor_6960a02cc0a63cf6) } var fileDescriptor_6960a02cc0a63cf6 = []byte{ - // 3823 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3a, 0x4d, 0x8f, 0x1d, 0xc7, - 0x56, 0xd3, 0xf7, 0xce, 0x9d, 0x7b, 0xe7, 0xdc, 0xcf, 0xa9, 0xf9, 0xf0, 0xf5, 0x8d, 0x93, 0xf8, - 0x15, 0x71, 0xe4, 0x38, 0x89, 0x6d, 0x26, 0x84, 0xbc, 0x18, 0x1c, 0xc5, 0x33, 0x1e, 0x62, 0x27, - 0x13, 0xdb, 0xea, 0x71, 0x9e, 0xcd, 0x13, 0xa4, 0xd5, 0xb7, 0xbb, 0xec, 0x69, 0xdc, 0x53, 0x7d, - 0xd3, 0x1f, 0x1e, 0x0f, 0x6c, 0xd0, 0x13, 0x2b, 0x58, 0x22, 0xd6, 0xb0, 0x42, 0x48, 0x20, 0xb6, - 0x88, 0x05, 0x12, 0x6b, 0xb6, 0x2c, 0x90, 0x80, 0x0d, 0x12, 0xbf, 0x00, 0xb1, 0x45, 0x42, 0xf5, - 0xd5, 0x55, 0xd5, 0xdd, 0x77, 0x9e, 0xfd, 0x04, 0x6f, 0xd7, 0x75, 0xea, 0xd4, 0xa9, 0x3a, 0x1f, - 0x75, 0xea, 0x7c, 0x34, 0x0c, 0x5e, 0x15, 0x61, 0xba, 0x08, 0xae, 0x2f, 0xd2, 0x24, 0x4f, 0xd0, - 0x9a, 0x18, 0xcd, 0x36, 0x7c, 0x4a, 0x93, 0xdc, 0xcf, 0xa3, 0x84, 0x66, 0x62, 0x0a, 0x6f, 0xc3, - 0xe6, 0x9d, 0x30, 0xdc, 0x2f, 0xd2, 0x94, 0xd0, 0xe0, 0xcc, 0x25, 0xd9, 0x22, 0xa1, 0x19, 0xc1, - 0xdf, 0xc3, 0xe8, 0x4e, 0x18, 0x3e, 0xf2, 0xa3, 0xd4, 0x25, 0x3f, 0x14, 0x24, 0xcb, 0xd1, 0x7b, - 0x30, 0x9c, 0xfb, 0x19, 0xf1, 0x02, 0x89, 0x3a, 0x75, 0x2e, 0x3b, 0x57, 0xd7, 0x5d, 0x1b, 0x88, - 0xde, 0x87, 0xd1, 0x0f, 0x45, 0x92, 0x1b, 0x68, 0x2d, 0x8e, 0x56, 0x81, 0xe2, 0x0d, 0x18, 0x97, - 0xf4, 0xe5, 0x96, 0x7f, 0xd7, 0x82, 0xee, 0x9e, 0x1f, 0xfb, 0x34, 0x20, 0x6c, 0xb3, 0x3c, 0xc9, - 0xfd, 0xd8, 0x9b, 0x0b, 0x00, 0xdf, 0x6c, 0xd5, 0xb5, 0x81, 0xe8, 0x2a, 0x8c, 0x83, 0x63, 0x9f, - 0x52, 0xa2, 0xf1, 0x5a, 0x1c, 0xaf, 0x0a, 0x46, 0x3f, 0x86, 0x0b, 0x0b, 0x42, 0xc3, 0x88, 0x3e, - 0xf7, 0xaa, 0x2b, 0xda, 0x7c, 0xc5, 0xb2, 0x69, 0x74, 0x0b, 0xa6, 0x11, 0xf5, 0x83, 0x3c, 0x7a, - 0x49, 0x6a, 0x4b, 0x57, 0xf9, 0xd2, 0xa5, 0xf3, 0x4c, 0x18, 0xa7, 0x7e, 0x1c, 0x93, 0xbc, 0x5c, - 0xd1, 0xe1, 0x2b, 0x2a, 0x50, 0xf4, 0x05, 0xcc, 0x0a, 0x1a, 0x24, 0xf4, 0x59, 0x94, 0x9e, 0x90, - 0xd0, 0xab, 0xac, 0x59, 0xe3, 0x6b, 0xce, 0xc1, 0xc0, 0xbf, 0x0e, 0xb0, 0xe7, 0x53, 0xa5, 0xa8, - 0xab, 0x30, 0xa6, 0x49, 0x48, 0xbc, 0x28, 0x24, 0x34, 0x8f, 0x9e, 0x45, 0x24, 0x95, 0xaa, 0xaa, - 0x82, 0xf1, 0x10, 0xfa, 0x7c, 0x9d, 0x54, 0xc0, 0x67, 0xd0, 0xd9, 0x3f, 0xf6, 0x23, 0x8a, 0xb6, - 0xa0, 0x13, 0xb0, 0x0f, 0xb9, 0x4e, 0x0c, 0xd0, 0x14, 0xba, 0x94, 0xe4, 0xa7, 0x49, 0xfa, 0x42, - 0xea, 0x54, 0x0d, 0xf1, 0x02, 0x7a, 0xfb, 0x82, 0xf5, 0x0c, 0xed, 0xc0, 0x9a, 0x90, 0x06, 0x5f, - 0x3c, 0x74, 0xe5, 0x08, 0xcd, 0xa0, 0xa7, 0xe4, 0xc4, 0x97, 0x0f, 0xdd, 0x72, 0xcc, 0x28, 0x4b, - 0xf1, 0x73, 0x6d, 0x0c, 0x5d, 0x35, 0x64, 0xd4, 0x82, 0x38, 0xc9, 0x48, 0xc8, 0x65, 0x3d, 0x74, - 0xe5, 0x08, 0xff, 0x83, 0x03, 0x9b, 0xfb, 0xec, 0x53, 0xee, 0xfb, 0xc6, 0xbc, 0xb3, 0xf3, 0x54, - 0x4c, 0xb4, 0x1c, 0x33, 0xfe, 0x9f, 0x25, 0xa9, 0xb4, 0x8d, 0x9e, 0x2b, 0x06, 0xe8, 0x32, 0xf4, - 0x43, 0x92, 0xe5, 0x11, 0xe5, 0xf7, 0x87, 0x1f, 0x68, 0xdd, 0x35, 0x41, 0x9c, 0xf7, 0x93, 0xa4, - 0xa0, 0xb9, 0xd4, 0xb3, 0x1c, 0xa1, 0x09, 0xb4, 0x9f, 0x11, 0xa5, 0x48, 0xf6, 0x89, 0xbf, 0x84, - 0x2d, 0xfb, 0xf8, 0x42, 0x05, 0xec, 0xfc, 0x79, 0xea, 0xd3, 0x8c, 0x09, 0x26, 0xa1, 0x5e, 0x14, - 0x66, 0x53, 0xe7, 0x72, 0x9b, 0x9d, 0xbf, 0x02, 0xc6, 0x1f, 0xc1, 0x68, 0x3f, 0xa1, 0x94, 0x04, - 0xb9, 0xe2, 0x7d, 0x06, 0x3d, 0xce, 0x64, 0x91, 0x46, 0x92, 0xe9, 0x72, 0xcc, 0xae, 0x5b, 0x89, - 0x2d, 0xb5, 0x7d, 0x03, 0x36, 0xf6, 0x53, 0xe2, 0xe7, 0xe4, 0x41, 0x12, 0x12, 0x83, 0xc6, 0xc2, - 0xcf, 0xb2, 0xd3, 0x24, 0x0d, 0x15, 0x0d, 0x35, 0xc6, 0x7f, 0xe6, 0x00, 0x32, 0x57, 0xc8, 0x23, - 0xff, 0x0a, 0x0c, 0x33, 0x42, 0x42, 0xef, 0x84, 0x92, 0x93, 0x84, 0x46, 0x81, 0x3c, 0xf0, 0x80, - 0x01, 0xbf, 0x95, 0x30, 0xf4, 0x01, 0x4c, 0x22, 0x1a, 0xe5, 0x91, 0x1f, 0x47, 0xbf, 0x4f, 0x42, - 0x2f, 0xa6, 0x61, 0x36, 0x6d, 0x09, 0xc6, 0x0c, 0xf8, 0x21, 0x0d, 0x33, 0x74, 0x03, 0x36, 0x4d, - 0xd4, 0x80, 0x1d, 0xfb, 0x55, 0x2e, 0x55, 0x81, 0x8c, 0xa9, 0x7d, 0x31, 0x83, 0xff, 0xc5, 0x81, - 0x9e, 0xf2, 0x5f, 0x96, 0x5a, 0x9d, 0x8a, 0x5a, 0x6f, 0x43, 0x3f, 0x3b, 0xf5, 0x17, 0x5e, 0x10, - 0x47, 0x84, 0xe6, 0x5c, 0xeb, 0xa3, 0xdd, 0xb7, 0xae, 0x4b, 0x4f, 0xa9, 0x48, 0x5c, 0x3f, 0x3a, - 0xf5, 0x17, 0xfb, 0x1c, 0xc5, 0x35, 0xf1, 0x85, 0x4f, 0x7a, 0x41, 0xa8, 0xe7, 0x87, 0x61, 0x4a, - 0xb2, 0x8c, 0x1f, 0x69, 0xdd, 0xb5, 0x81, 0xec, 0xce, 0x87, 0x24, 0x88, 0x4e, 0xfc, 0xd8, 0x5b, - 0xc4, 0x7e, 0x40, 0x32, 0x69, 0xb9, 0x15, 0x28, 0xc6, 0x00, 0x7a, 0x23, 0xd4, 0x85, 0xf6, 0xe1, - 0x83, 0xbb, 0x93, 0x15, 0xd4, 0x87, 0xee, 0xfe, 0xc3, 0x07, 0x0f, 0x0e, 0x9e, 0x3e, 0x9e, 0xb4, - 0x98, 0x8e, 0xef, 0x92, 0x45, 0x92, 0x45, 0xa6, 0x8e, 0x97, 0xb1, 0x87, 0x3f, 0x84, 0x71, 0x89, - 0x2d, 0x75, 0x33, 0x85, 0xae, 0x3a, 0xac, 0xc0, 0x56, 0x43, 0x66, 0x80, 0x77, 0xa3, 0x2c, 0x48, - 0x5e, 0x92, 0x94, 0x69, 0x33, 0x7b, 0x73, 0xe7, 0xf1, 0x29, 0x6c, 0x57, 0x28, 0xc8, 0x4d, 0x2f, - 0xc1, 0x3a, 0x2d, 0x4e, 0x3c, 0x86, 0x9f, 0x49, 0x27, 0xa0, 0x01, 0xf8, 0x8f, 0x1d, 0x40, 0x07, - 0xaf, 0x48, 0x50, 0xe4, 0x84, 0xf1, 0x6f, 0x30, 0x96, 0xa4, 0x21, 0x49, 0xbd, 0xa8, 0x34, 0x3c, - 0x35, 0xe6, 0xee, 0xc1, 0x8f, 0xf8, 0x94, 0x74, 0x3c, 0x72, 0x88, 0x30, 0x0c, 0x16, 0x84, 0xa4, - 0xde, 0xa2, 0x98, 0x7b, 0x2f, 0xc8, 0x99, 0xd4, 0x88, 0x05, 0x63, 0x94, 0x7f, 0x28, 0x7c, 0x9a, - 0x47, 0xf9, 0x99, 0x74, 0xd8, 0xe5, 0x98, 0xdd, 0x81, 0xaf, 0x48, 0x2e, 0x1f, 0x9d, 0xd7, 0x91, - 0xf1, 0x5f, 0x39, 0x80, 0xcc, 0x15, 0x92, 0xe5, 0xbb, 0xd0, 0x93, 0xbe, 0x58, 0xdc, 0xd7, 0xfe, - 0xee, 0x55, 0x65, 0x56, 0x75, 0xec, 0xeb, 0x72, 0x9c, 0x1d, 0xd0, 0x3c, 0x3d, 0x73, 0xcb, 0x95, - 0xb3, 0x43, 0x18, 0x5a, 0x53, 0xcc, 0x6f, 0x30, 0xae, 0xc4, 0x21, 0xd8, 0x27, 0xba, 0x02, 0x9d, - 0x97, 0x7e, 0x5c, 0x08, 0x17, 0xda, 0xdf, 0x1d, 0xab, 0x5d, 0xd4, 0x16, 0x62, 0xf6, 0x56, 0xeb, - 0xc7, 0x0e, 0x9e, 0xc0, 0xe8, 0x2b, 0x92, 0xdf, 0xa7, 0xcf, 0x12, 0xc9, 0x18, 0xfe, 0xd7, 0x36, - 0x8c, 0x4b, 0x90, 0xb6, 0x90, 0x97, 0x24, 0xcd, 0x98, 0x43, 0x93, 0x16, 0x22, 0x87, 0x4c, 0xb6, - 0x5c, 0xe5, 0x4a, 0xb6, 0x42, 0xf4, 0x16, 0x0c, 0x21, 0x58, 0x2d, 0xd2, 0x88, 0xdd, 0x04, 0x76, - 0x95, 0xf9, 0xb7, 0x52, 0x3f, 0xd3, 0x81, 0xb2, 0x7d, 0x0d, 0x28, 0x67, 0xfd, 0x28, 0xcd, 0xb8, - 0x97, 0x54, 0xb3, 0x0c, 0x80, 0x3e, 0x84, 0x35, 0xae, 0xf5, 0x8c, 0xfb, 0xca, 0xfe, 0xee, 0xa6, - 0xe2, 0xef, 0x21, 0x87, 0xee, 0x33, 0x6f, 0xea, 0x4a, 0x14, 0xb4, 0x0b, 0xed, 0x98, 0x86, 0xd3, - 0x2e, 0x97, 0xf7, 0x65, 0x43, 0xde, 0x26, 0x83, 0xd7, 0x0f, 0x69, 0x28, 0xe4, 0xcc, 0x90, 0x99, - 0x67, 0xf7, 0xe3, 0xc8, 0xcf, 0xa6, 0xeb, 0xe2, 0x65, 0xe3, 0x03, 0xf3, 0x65, 0x03, 0xeb, 0x65, - 0x43, 0x37, 0x61, 0x53, 0x05, 0x06, 0xdc, 0x15, 0x1c, 0xfb, 0xd9, 0x31, 0xc9, 0xa6, 0x7d, 0xce, - 0x6f, 0xd3, 0x14, 0xfa, 0x18, 0xba, 0xca, 0x65, 0x0d, 0x6c, 0x1e, 0xa4, 0xbf, 0xe2, 0xa7, 0x53, - 0x38, 0xb3, 0xaf, 0xa0, 0xa7, 0x4e, 0xf8, 0x06, 0xea, 0x3e, 0xa4, 0x21, 0x27, 0x63, 0xa8, 0xfb, - 0x0b, 0x6e, 0x98, 0xec, 0x26, 0x1a, 0x2a, 0x7f, 0x83, 0xeb, 0xec, 0xc2, 0xa6, 0xb5, 0xbe, 0xf4, - 0xee, 0xe3, 0x94, 0x2c, 0x0a, 0x11, 0x33, 0x1e, 0x05, 0x49, 0x2a, 0xde, 0xf5, 0x0d, 0x17, 0x34, - 0x98, 0xbd, 0x7b, 0x73, 0xf6, 0x8e, 0x89, 0xfb, 0xd9, 0x73, 0xe5, 0x08, 0x5f, 0x80, 0xed, 0xc3, - 0x28, 0xcb, 0xa5, 0x67, 0x8d, 0x4a, 0x2f, 0x83, 0xbf, 0x86, 0x9d, 0xea, 0x84, 0xdc, 0xef, 0x26, - 0x40, 0x50, 0x42, 0xe5, 0x5d, 0x9a, 0x54, 0x5d, 0xb4, 0x6b, 0xe0, 0xe0, 0x7f, 0x72, 0x60, 0x83, - 0x11, 0x13, 0x26, 0xa2, 0x18, 0x37, 0x7c, 0x86, 0x63, 0xfb, 0x8c, 0x4f, 0xa1, 0x93, 0x9c, 0x52, - 0x92, 0x4a, 0xff, 0xff, 0x6e, 0x29, 0xd3, 0x2a, 0x8d, 0xeb, 0x0f, 0x19, 0x9a, 0x2b, 0xb0, 0x99, - 0xe5, 0xc4, 0xd1, 0x49, 0x94, 0xcb, 0x08, 0x45, 0x0c, 0x98, 0x7c, 0x23, 0x1a, 0xc4, 0x45, 0x48, - 0x3c, 0x6e, 0x4a, 0xd2, 0xdd, 0xf7, 0xdc, 0x2a, 0x18, 0xbf, 0x07, 0x1d, 0x4e, 0x0f, 0xf5, 0x60, - 0x75, 0xef, 0xe1, 0xe3, 0x7b, 0x93, 0x15, 0xe6, 0xf4, 0x1f, 0x3e, 0x79, 0x30, 0x71, 0x18, 0xe8, - 0xd1, 0xc1, 0x81, 0x3b, 0x69, 0xe1, 0x3f, 0x77, 0x00, 0x99, 0x07, 0x91, 0x52, 0xf9, 0xa2, 0xbc, - 0x17, 0x42, 0x22, 0xef, 0x37, 0x1d, 0x5a, 0x1a, 0xbc, 0x18, 0x0a, 0x9b, 0x97, 0xab, 0x66, 0xf7, - 0xa1, 0x6f, 0x80, 0x1b, 0x0c, 0xed, 0x3d, 0xdb, 0xd0, 0x46, 0xf6, 0xbd, 0x33, 0xed, 0x0c, 0xc1, - 0x84, 0x6d, 0xca, 0x22, 0xf7, 0x52, 0x9d, 0x1f, 0x08, 0x0d, 0x48, 0x98, 0x3c, 0xf3, 0x16, 0x74, - 0xc4, 0x2d, 0x17, 0xf1, 0x80, 0x18, 0x94, 0xcb, 0x89, 0x96, 0x33, 0xfe, 0x4c, 0x2e, 0x27, 0x26, - 0xcb, 0x18, 0x3a, 0xc2, 0x85, 0x08, 0x8e, 0x07, 0xea, 0x44, 0x0c, 0xcb, 0x15, 0x53, 0xf8, 0xdf, - 0x1d, 0xe8, 0xca, 0xab, 0xc0, 0x6c, 0x30, 0xcb, 0xfd, 0xbc, 0x50, 0x2f, 0x9d, 0x1c, 0xa1, 0x8f, - 0xa0, 0x27, 0xc3, 0xf2, 0x4c, 0x32, 0xa7, 0xcd, 0x49, 0xc2, 0xdd, 0x12, 0x03, 0x5d, 0x81, 0x35, - 0x1e, 0xec, 0x0a, 0x97, 0xd6, 0xdf, 0x1d, 0x1a, 0xb8, 0x11, 0x75, 0xe5, 0x24, 0x0b, 0x05, 0xe7, - 0x71, 0x12, 0xbc, 0x38, 0x26, 0xd1, 0xf3, 0xe3, 0x5c, 0x7a, 0x39, 0x13, 0x54, 0x7a, 0xc6, 0x8e, - 0xe1, 0x19, 0x0d, 0x5f, 0xbb, 0x66, 0xfb, 0xda, 0xd2, 0x2d, 0x75, 0x0d, 0xb7, 0x84, 0xbf, 0x86, - 0x11, 0xbf, 0x8f, 0x3a, 0x68, 0xad, 0xfa, 0x64, 0xa7, 0xc1, 0x27, 0x97, 0xb4, 0x5a, 0x26, 0xad, - 0xbf, 0x74, 0x00, 0x3d, 0x5c, 0x10, 0xfa, 0xff, 0x12, 0x2f, 0xeb, 0xb8, 0xb7, 0x6d, 0xc5, 0xbd, - 0x97, 0xa1, 0xbf, 0x28, 0xb2, 0x63, 0x4f, 0x4e, 0x8a, 0xd7, 0xd7, 0x04, 0xa9, 0xc8, 0xb8, 0xa3, - 0x23, 0xe3, 0xdb, 0xb0, 0x69, 0x9d, 0x53, 0x9a, 0xc3, 0xfb, 0x30, 0xb2, 0x23, 0x60, 0x79, 0xce, - 0x0a, 0x14, 0xff, 0x63, 0x0b, 0x3a, 0xdc, 0x68, 0xb9, 0xfd, 0xa5, 0x91, 0x4c, 0x1d, 0x1d, 0x57, - 0x0c, 0xac, 0x68, 0xa0, 0x65, 0x47, 0x03, 0xa6, 0xcf, 0x68, 0xdb, 0x3e, 0x63, 0x04, 0xad, 0x28, - 0x94, 0x11, 0x7f, 0x2b, 0x0a, 0xd1, 0x97, 0x75, 0xb1, 0x75, 0xb8, 0x6d, 0xed, 0x28, 0x7b, 0xb1, - 0x15, 0xd7, 0x28, 0xce, 0x38, 0x09, 0xfc, 0x98, 0x6d, 0x26, 0x8c, 0xa1, 0x1c, 0xa3, 0x77, 0x00, - 0x02, 0x1e, 0x67, 0x87, 0x9e, 0x9f, 0x73, 0x93, 0x58, 0x75, 0x0d, 0x08, 0xba, 0x02, 0xab, 0x59, - 0x14, 0x92, 0x69, 0x8f, 0x3b, 0xb0, 0x0d, 0xeb, 0xae, 0x1e, 0x45, 0x21, 0x71, 0xf9, 0x34, 0x33, - 0x96, 0x28, 0xf3, 0x92, 0x53, 0xea, 0x71, 0x2f, 0xc0, 0x9f, 0xbc, 0x9e, 0x6b, 0xc1, 0x98, 0x99, - 0x1e, 0x27, 0x71, 0xc8, 0x9f, 0xbd, 0x55, 0x97, 0x7f, 0xe3, 0xbf, 0x70, 0x60, 0xc0, 0x69, 0xb9, - 0xe4, 0x24, 0x79, 0xe9, 0xc7, 0x96, 0xcc, 0x9c, 0xe5, 0x32, 0xab, 0xc4, 0x66, 0x66, 0x44, 0xd7, - 0xae, 0x44, 0x74, 0x26, 0xf7, 0xab, 0x15, 0xee, 0xab, 0xc7, 0xee, 0xd4, 0x8f, 0x8d, 0x8f, 0x61, - 0x4d, 0x78, 0x26, 0xf4, 0x31, 0xc0, 0xbc, 0x38, 0xf3, 0x2c, 0xef, 0x38, 0xb4, 0x24, 0xe2, 0x1a, - 0x08, 0xe8, 0x06, 0xf4, 0x33, 0x12, 0xc7, 0x0a, 0xbf, 0xd5, 0x84, 0x6f, 0x62, 0xe0, 0x4f, 0x94, - 0xe7, 0xe4, 0xb1, 0x07, 0x93, 0x17, 0x73, 0x3d, 0x32, 0xac, 0xe5, 0xdf, 0xcc, 0x86, 0x93, 0x53, - 0x2a, 0x93, 0x5a, 0xf6, 0x89, 0x7f, 0xe6, 0xc8, 0x55, 0xdf, 0x2d, 0x42, 0x3f, 0x27, 0xec, 0x19, - 0x17, 0xbc, 0x38, 0xdc, 0x48, 0xec, 0xfd, 0xee, 0xad, 0xb8, 0x62, 0x16, 0xfd, 0x26, 0x0c, 0x85, - 0x84, 0x52, 0x21, 0x78, 0xe9, 0xaf, 0xb6, 0xec, 0xe3, 0x89, 0xb9, 0x7b, 0x2b, 0xae, 0x8d, 0xbc, - 0x37, 0x82, 0x81, 0x00, 0x14, 0x7c, 0x53, 0xfc, 0x6f, 0x2d, 0x58, 0x65, 0xce, 0x72, 0x79, 0x12, - 0xf0, 0x5a, 0x21, 0xde, 0x97, 0x30, 0x88, 0x69, 0xa8, 0x86, 0xca, 0x2f, 0x5e, 0x32, 0xdd, 0x31, - 0x0b, 0x47, 0x1e, 0x15, 0xf3, 0x6f, 0xc8, 0x99, 0x7c, 0x76, 0xac, 0x15, 0x6c, 0xff, 0x88, 0xce, - 0x93, 0x82, 0x86, 0xf2, 0x6d, 0x54, 0x43, 0xfd, 0x44, 0x74, 0x8c, 0x27, 0x82, 0x79, 0x8d, 0x57, - 0x45, 0xe8, 0xd9, 0xae, 0xd2, 0x04, 0xa1, 0x8f, 0x60, 0x23, 0x23, 0x41, 0x42, 0xc3, 0x4c, 0xa4, - 0x87, 0x41, 0x4e, 0x42, 0x7e, 0x4f, 0x86, 0x6e, 0x7d, 0xa2, 0x39, 0xe6, 0x9b, 0xdd, 0x86, 0x71, - 0xe5, 0xd8, 0x0d, 0xcf, 0xe2, 0x96, 0xf9, 0x2c, 0xae, 0x9b, 0xcf, 0xe0, 0x1f, 0xb6, 0x60, 0xe3, - 0x11, 0xcb, 0xe4, 0xa4, 0x52, 0x84, 0x3b, 0xfd, 0xbf, 0xf4, 0x39, 0xe6, 0xfd, 0x59, 0xad, 0xdc, - 0x1f, 0xe5, 0x01, 0x3a, 0xe7, 0x7b, 0x80, 0x6b, 0x30, 0x49, 0x09, 0xcf, 0x37, 0xbd, 0x92, 0x94, - 0x10, 0x67, 0x0d, 0xce, 0x22, 0xdd, 0xe8, 0xe4, 0x84, 0x84, 0x91, 0x9f, 0x33, 0xa8, 0x17, 0xb0, - 0x7c, 0x22, 0xe6, 0x52, 0xed, 0xb9, 0x4d, 0x53, 0x4c, 0x04, 0xc8, 0x14, 0x81, 0xf4, 0xd4, 0x9f, - 0xb3, 0x54, 0x3f, 0x27, 0x29, 0xf5, 0x63, 0xef, 0xc4, 0xcf, 0x83, 0x63, 0xb2, 0xe4, 0x5e, 0xd6, - 0xd0, 0xd0, 0x6f, 0xc0, 0x88, 0x87, 0xd2, 0x59, 0x11, 0x04, 0x24, 0x63, 0xc1, 0x94, 0xb8, 0xa0, - 0x65, 0x08, 0xcd, 0x32, 0xc6, 0x23, 0x31, 0xe9, 0x56, 0x50, 0xd1, 0x67, 0x2c, 0x52, 0x3d, 0xf1, - 0x23, 0xca, 0x22, 0x72, 0x71, 0xdd, 0xda, 0x0d, 0xd7, 0xcd, 0xad, 0x62, 0xa1, 0xcf, 0x61, 0xc8, - 0x49, 0x3d, 0xf3, 0xa3, 0xb8, 0x48, 0x79, 0x04, 0x57, 0xdb, 0xf4, 0xb7, 0xc4, 0x9c, 0x6b, 0x63, - 0xe2, 0xff, 0x72, 0x60, 0xac, 0x45, 0x70, 0xf0, 0x92, 0xa5, 0xf2, 0x57, 0xa0, 0xc3, 0xf9, 0x59, - 0x7a, 0xd9, 0xf9, 0x2c, 0xfa, 0x1c, 0x06, 0x26, 0x03, 0xf2, 0xae, 0x37, 0x71, 0x7a, 0x6f, 0xc5, - 0xb5, 0x50, 0xd1, 0xe7, 0xaf, 0xc7, 0xe9, 0xbd, 0x95, 0x26, 0x5e, 0x07, 0x26, 0x07, 0xdc, 0xb0, - 0x9a, 0x59, 0x2d, 0x77, 0x95, 0xa8, 0x7b, 0x5d, 0xe8, 0x10, 0xc6, 0x20, 0x4e, 0xa0, 0x6f, 0xa4, - 0x32, 0x4b, 0x03, 0x2f, 0xc3, 0xed, 0xb4, 0x6c, 0xb7, 0x63, 0xc4, 0x41, 0xab, 0xb5, 0x38, 0x48, - 0x14, 0x1e, 0x3b, 0x46, 0xe1, 0x11, 0x7f, 0x02, 0xdb, 0xdc, 0xeb, 0x11, 0x5d, 0xa5, 0xfe, 0xf9, - 0x99, 0xfa, 0x14, 0x76, 0xaa, 0x8b, 0x64, 0xe1, 0xeb, 0x10, 0x90, 0x98, 0xb1, 0xae, 0xee, 0x79, - 0x05, 0x88, 0x73, 0x2e, 0x30, 0xfe, 0x14, 0x36, 0x2d, 0x6a, 0xf2, 0x16, 0xbc, 0x03, 0x13, 0x85, - 0xe2, 0x25, 0xd4, 0xe3, 0x8f, 0xac, 0x63, 0x3c, 0xb2, 0x1f, 0xc3, 0x86, 0x58, 0x66, 0x96, 0xd8, - 0x97, 0x26, 0x2d, 0x78, 0x4b, 0x9d, 0xd9, 0xaa, 0x98, 0xff, 0x51, 0x8b, 0x81, 0xb3, 0x3c, 0x49, - 0xad, 0x22, 0xde, 0x6b, 0x55, 0xe4, 0xcc, 0x4a, 0x5f, 0xcb, 0xae, 0xf4, 0xa1, 0x6f, 0xa0, 0xcf, - 0x3c, 0xf8, 0xdc, 0x0f, 0x5e, 0x14, 0x0b, 0xe5, 0xf2, 0xaf, 0x29, 0x23, 0xa9, 0xef, 0xc8, 0x1e, - 0x80, 0x3d, 0x81, 0x2c, 0x1e, 0x00, 0x88, 0x4b, 0x00, 0xfa, 0x11, 0xef, 0x45, 0x78, 0xa1, 0x9f, - 0xfb, 0x73, 0x3f, 0x13, 0x55, 0xd0, 0x01, 0xf7, 0xe7, 0x77, 0x25, 0x48, 0xfa, 0x62, 0x93, 0xc2, - 0xcf, 0xf3, 0xc5, 0x03, 0xd3, 0x17, 0x13, 0xa6, 0x02, 0xe3, 0x4c, 0xba, 0x30, 0x99, 0x0a, 0xb0, - 0x2c, 0x38, 0x4a, 0x31, 0x28, 0x20, 0xaf, 0x36, 0x7e, 0xc0, 0x5c, 0xa4, 0x44, 0x52, 0x79, 0xbb, - 0x48, 0x62, 0xc7, 0x0a, 0xae, 0xea, 0x8c, 0x1b, 0x30, 0x3e, 0x3a, 0x2e, 0xf2, 0x30, 0x39, 0x55, - 0xa5, 0x76, 0x96, 0xcd, 0x68, 0x90, 0x54, 0xca, 0xaf, 0xc1, 0xce, 0x51, 0x31, 0xcf, 0x82, 0x34, - 0x9a, 0x13, 0x3b, 0x27, 0x9d, 0x41, 0x8f, 0xbc, 0x8a, 0xb2, 0x3c, 0xa2, 0xcf, 0x39, 0x63, 0x3d, - 0xb7, 0x1c, 0xe3, 0x77, 0xe1, 0xed, 0x72, 0x15, 0xbb, 0x85, 0xd9, 0x9d, 0x20, 0x20, 0x8b, 0x9c, - 0x84, 0x6a, 0xab, 0xdb, 0xb0, 0x6d, 0x23, 0x18, 0x7d, 0x19, 0x95, 0x6b, 0xe6, 0xfe, 0x0b, 0x19, - 0x64, 0xf4, 0x5c, 0x1b, 0x88, 0xff, 0xa7, 0x05, 0x03, 0xb6, 0x4c, 0x91, 0x45, 0x17, 0x6b, 0xf6, - 0xde, 0xe5, 0xe3, 0xfb, 0x76, 0x74, 0xd6, 0xaa, 0x44, 0x67, 0xe7, 0xbe, 0x57, 0xcb, 0xea, 0x6c, - 0xfa, 0x5d, 0xec, 0x98, 0xef, 0x62, 0xb5, 0x7a, 0xb7, 0xd6, 0x50, 0xbd, 0xdb, 0x81, 0xb5, 0x94, - 0x97, 0x56, 0x64, 0x6a, 0x24, 0x47, 0xec, 0x69, 0x13, 0x29, 0x84, 0x97, 0x92, 0x80, 0x44, 0x2f, - 0x99, 0x4c, 0x7b, 0x7c, 0xd7, 0x1a, 0x9c, 0xe5, 0x0e, 0x12, 0x96, 0xc9, 0x2e, 0xc3, 0xba, 0x68, - 0xc3, 0xd8, 0x50, 0x74, 0x1d, 0x90, 0x72, 0x1f, 0x06, 0x55, 0x51, 0x11, 0x6a, 0x98, 0x61, 0x67, - 0x28, 0xa1, 0x8a, 0x72, 0x5f, 0x3c, 0xaf, 0x55, 0x38, 0xfe, 0x6b, 0x07, 0xfa, 0x86, 0x77, 0xfd, - 0x05, 0xeb, 0x9d, 0xa6, 0x8c, 0xdb, 0x15, 0x19, 0x57, 0xa5, 0xb9, 0xda, 0x20, 0xcd, 0xf7, 0x61, - 0x24, 0xdd, 0xb9, 0x97, 0x12, 0x3f, 0x4b, 0x94, 0xa3, 0xad, 0x40, 0xf1, 0xdf, 0xb6, 0xc5, 0x69, - 0xe5, 0x0b, 0xf4, 0xcb, 0x35, 0x16, 0xad, 0xf2, 0x8e, 0xa5, 0xf2, 0xab, 0x30, 0xb6, 0x54, 0x4b, - 0x42, 0xa9, 0xf1, 0x2a, 0x98, 0x45, 0x90, 0x5a, 0xb5, 0xb9, 0xd4, 0xb6, 0x09, 0xaa, 0x09, 0x0b, - 0x1a, 0x84, 0x75, 0x19, 0x56, 0xd3, 0x24, 0x26, 0x5c, 0xa5, 0x23, 0x5d, 0x80, 0x70, 0x93, 0x98, - 0xb8, 0x7c, 0x86, 0xc5, 0xa1, 0x15, 0xb3, 0x20, 0x21, 0xaf, 0xfa, 0xad, 0xbb, 0xf5, 0x09, 0x76, - 0x51, 0x4d, 0xb3, 0xc8, 0xa7, 0x43, 0xd1, 0x3f, 0xb0, 0x80, 0x2c, 0xf9, 0x4b, 0xbd, 0x45, 0x4a, - 0xa2, 0x13, 0xff, 0x39, 0x99, 0x8e, 0x38, 0x8a, 0x01, 0xd1, 0x57, 0x69, 0x6c, 0x5c, 0x25, 0xfc, - 0xdf, 0x2d, 0xe8, 0x3c, 0x4e, 0xfd, 0x90, 0xb0, 0x0c, 0xe7, 0x84, 0xdd, 0x78, 0x6f, 0x79, 0xc6, - 0xe1, 0x9a, 0x18, 0x6c, 0x41, 0x6e, 0x2c, 0x68, 0x35, 0x2e, 0x30, 0x30, 0x0c, 0xfd, 0xb4, 0x2d, - 0xfd, 0x9c, 0xa7, 0x53, 0xc3, 0x12, 0x3a, 0xb6, 0x25, 0x94, 0xfc, 0xac, 0x99, 0xae, 0x41, 0xc9, - 0xbe, 0xbb, 0x54, 0xf6, 0x97, 0xa1, 0x4f, 0x44, 0x1b, 0x81, 0x67, 0xc9, 0xc2, 0x12, 0x4c, 0x50, - 0x19, 0x24, 0xaf, 0x9f, 0x1f, 0x24, 0xdf, 0x82, 0x41, 0xc0, 0x0c, 0x83, 0xa4, 0x0b, 0x3f, 0xcd, - 0x85, 0x29, 0x2c, 0x4f, 0xe4, 0x2d, 0x5c, 0xfc, 0x21, 0x6c, 0x72, 0xa9, 0xdf, 0x8b, 0xd8, 0x53, - 0x71, 0x66, 0xa4, 0x01, 0xa2, 0x56, 0xe8, 0x18, 0xb5, 0x42, 0x7c, 0x1b, 0xb6, 0x6c, 0x64, 0xf9, - 0x4e, 0x5d, 0x81, 0xb5, 0x9c, 0xc1, 0x6b, 0x61, 0x32, 0xc7, 0x76, 0xe5, 0x24, 0xde, 0x87, 0x21, - 0x03, 0x44, 0xf4, 0xf9, 0x21, 0x23, 0xc7, 0x2e, 0x65, 0xf7, 0x5b, 0xff, 0xd5, 0x11, 0x89, 0x63, - 0x95, 0x95, 0x9f, 0xf8, 0xaf, 0x3c, 0x96, 0xbc, 0xa2, 0x0b, 0xb0, 0xf6, 0xad, 0xff, 0x6a, 0xaf, - 0x50, 0xe1, 0x4a, 0x97, 0xcd, 0xcc, 0x8b, 0x33, 0xbc, 0x2b, 0xce, 0x50, 0x12, 0x79, 0x9d, 0x48, - 0xea, 0x6f, 0x1c, 0xd8, 0xae, 0x2c, 0x92, 0x27, 0xbf, 0x03, 0x6b, 0x9c, 0x35, 0x75, 0xf2, 0x0f, - 0xcc, 0x93, 0xd7, 0xd0, 0xaf, 0x8b, 0xa1, 0xac, 0x4c, 0x8a, 0x85, 0xb3, 0x47, 0xd0, 0x37, 0xc0, - 0x0d, 0xcf, 0xfe, 0x87, 0x76, 0x65, 0x72, 0xbb, 0x79, 0x0b, 0x23, 0x1a, 0xf8, 0x09, 0x0c, 0xbe, - 0xa3, 0xf3, 0x5f, 0xa0, 0x1d, 0x8e, 0x2e, 0xc1, 0x7a, 0x4a, 0x64, 0xde, 0x28, 0x83, 0x00, 0x0d, - 0xc0, 0x63, 0x18, 0x4a, 0xba, 0xba, 0x81, 0xfa, 0x1d, 0x8d, 0x93, 0xe0, 0xc5, 0xeb, 0x36, 0x50, - 0x7f, 0x0a, 0xc8, 0x5c, 0xa0, 0xc3, 0x94, 0x82, 0x43, 0x2b, 0x61, 0x8a, 0x02, 0xf2, 0x30, 0xe5, - 0x5d, 0xe8, 0x9b, 0x28, 0xa2, 0xdf, 0x02, 0x1a, 0x01, 0xff, 0x89, 0x03, 0xe3, 0x27, 0x51, 0x7e, - 0x1c, 0xa6, 0xfe, 0xe9, 0x6b, 0x28, 0xb5, 0xda, 0xcc, 0x6e, 0x9d, 0xd7, 0xcc, 0x6e, 0x57, 0x9b, - 0xd9, 0x7e, 0x1c, 0xcb, 0x54, 0x9e, 0x7d, 0x9a, 0x45, 0xbc, 0xa1, 0x28, 0xe2, 0xdd, 0x82, 0x89, - 0x3e, 0xcc, 0x9b, 0x55, 0xf0, 0xae, 0x5d, 0x85, 0xf5, 0xf2, 0x8a, 0xa2, 0x2e, 0xb4, 0xf7, 0xbe, - 0xfb, 0xed, 0xc9, 0x0a, 0xea, 0xc1, 0xea, 0xd1, 0xc1, 0xe1, 0xa1, 0x28, 0x96, 0xf3, 0xfa, 0x79, - 0xeb, 0xda, 0x35, 0x58, 0x65, 0x0e, 0x01, 0xad, 0x43, 0xe7, 0xf1, 0x9d, 0x6f, 0x0e, 0xdc, 0xc9, - 0x0a, 0xfb, 0xfc, 0x96, 0x7f, 0x3a, 0x68, 0x00, 0xbd, 0xfb, 0x0f, 0x1e, 0x1f, 0xb8, 0x0f, 0xee, - 0x1c, 0x4e, 0x5a, 0xbb, 0xff, 0xe1, 0x40, 0xf7, 0x69, 0x11, 0xde, 0xa7, 0x51, 0x8e, 0x0e, 0x00, - 0x74, 0x1f, 0x1b, 0x5d, 0x2c, 0x4b, 0xbc, 0xd5, 0x6e, 0xf8, 0x6c, 0xd6, 0x34, 0x25, 0xb5, 0xbf, - 0x82, 0xee, 0x41, 0xdf, 0x08, 0x3b, 0xd1, 0x6c, 0x79, 0x7c, 0x3c, 0x7b, 0xab, 0x71, 0xae, 0xa4, - 0x74, 0x00, 0xa0, 0x0d, 0x43, 0x1f, 0xa8, 0x66, 0x5d, 0xfa, 0x40, 0x75, 0x3b, 0xc2, 0x2b, 0xbb, - 0x7f, 0xbf, 0x03, 0xed, 0xa7, 0x45, 0x88, 0x9e, 0x42, 0xdf, 0xf8, 0xa5, 0x07, 0xd5, 0xda, 0x27, - 0xfa, 0x38, 0x4d, 0x7f, 0xfe, 0xcc, 0x7e, 0xf6, 0xcf, 0xff, 0xf9, 0xa7, 0xad, 0x2d, 0x3c, 0xbe, - 0xf1, 0xf2, 0x57, 0x6f, 0xf8, 0x61, 0xa8, 0x4c, 0xe6, 0x96, 0x73, 0x0d, 0xb9, 0xd0, 0x95, 0x7f, - 0xed, 0xa0, 0x1d, 0x83, 0x86, 0x91, 0xc3, 0xcc, 0x2e, 0xd4, 0xe0, 0x92, 0xee, 0x0e, 0xa7, 0x3b, - 0xc1, 0x7d, 0x49, 0x97, 0x3d, 0x00, 0x8c, 0xe6, 0x1e, 0xb4, 0xf7, 0x7c, 0x8a, 0x90, 0x6e, 0x65, - 0xaa, 0xab, 0x3b, 0xdb, 0xb4, 0x60, 0x92, 0x0e, 0xe2, 0x74, 0x06, 0xb8, 0xcb, 0xe8, 0xcc, 0x7d, - 0xca, 0x68, 0x04, 0x30, 0x30, 0x7f, 0xa7, 0x40, 0xba, 0xa9, 0x5f, 0xff, 0x47, 0x64, 0x76, 0xa9, - 0x79, 0x52, 0x92, 0x9f, 0x72, 0xf2, 0x08, 0x4f, 0x18, 0x79, 0xfe, 0xb7, 0x89, 0x6c, 0x0e, 0x30, - 0xe6, 0xe5, 0x3f, 0x14, 0x9a, 0x79, 0xfb, 0x17, 0x0c, 0xcd, 0x7c, 0xf5, 0x67, 0x0b, 0x8b, 0x79, - 0xe9, 0x51, 0xd8, 0xc1, 0xbf, 0x87, 0xe1, 0x13, 0xfe, 0x2f, 0x8f, 0xec, 0xdc, 0x6b, 0xca, 0x76, - 0xe3, 0x5f, 0x53, 0xae, 0xb4, 0xf8, 0xf1, 0x25, 0x4e, 0x79, 0x07, 0x6f, 0x30, 0xca, 0xe2, 0xbf, - 0xa0, 0x50, 0xa0, 0x30, 0xfa, 0xbf, 0x07, 0x43, 0xab, 0x49, 0x8f, 0x4a, 0xe6, 0x9b, 0xba, 0xff, - 0xb3, 0xb7, 0x97, 0xcc, 0x36, 0xed, 0x15, 0x4a, 0x14, 0xde, 0xd6, 0x67, 0x7b, 0x3d, 0x05, 0xd0, - 0xcd, 0x6e, 0x6d, 0xc5, 0xb5, 0x06, 0xbb, 0xb6, 0xe2, 0x7a, 0x6f, 0x1c, 0x6f, 0xf2, 0x2d, 0x86, - 0xa8, 0x2f, 0xb4, 0x2b, 0x68, 0x1d, 0x42, 0x57, 0xb6, 0x75, 0xb5, 0x7c, 0xec, 0xde, 0xb6, 0x96, - 0x4f, 0xa5, 0xff, 0x8b, 0x27, 0x9c, 0x20, 0xa0, 0x1e, 0x23, 0x18, 0x31, 0x12, 0xbf, 0x03, 0x7d, - 0xa3, 0xd3, 0x89, 0xcc, 0xd3, 0x54, 0xda, 0xa7, 0xfa, 0xa2, 0x34, 0xb4, 0x46, 0xf1, 0x16, 0xa7, - 0x3c, 0x42, 0x03, 0x46, 0x99, 0x49, 0x81, 0x53, 0x7f, 0x02, 0xa0, 0x9b, 0x72, 0x5a, 0x0a, 0xb5, - 0xee, 0xa2, 0x96, 0x42, 0xbd, 0x87, 0xa7, 0x6c, 0x1c, 0x01, 0x23, 0x2d, 0x4b, 0xd7, 0xcf, 0x61, - 0x64, 0xf7, 0x4c, 0xd1, 0xdb, 0x26, 0x85, 0x5a, 0x93, 0x75, 0xf6, 0xce, 0xb2, 0x69, 0xdb, 0x26, - 0xd1, 0x88, 0xdb, 0xa4, 0x26, 0x7b, 0x04, 0xeb, 0x65, 0x37, 0x0f, 0x4d, 0x4d, 0x22, 0x66, 0xd3, - 0x6f, 0x76, 0xb1, 0x61, 0x46, 0x52, 0xde, 0xe0, 0x94, 0xfb, 0x68, 0x9d, 0x51, 0x16, 0x45, 0x5d, - 0x45, 0x94, 0xff, 0x04, 0x60, 0x13, 0x35, 0x5a, 0x81, 0x15, 0xa2, 0x66, 0x43, 0xb0, 0x42, 0x94, - 0xd3, 0xf1, 0xa0, 0x6f, 0xf4, 0x8a, 0xb4, 0x26, 0xeb, 0x8d, 0x2e, 0xad, 0xc9, 0x86, 0xe6, 0x12, - 0xbe, 0xc0, 0x49, 0x6f, 0x08, 0x97, 0x97, 0x2c, 0x08, 0x55, 0x57, 0xfe, 0x77, 0x01, 0x74, 0x79, - 0x4f, 0x2b, 0xb3, 0x56, 0xf8, 0xd5, 0xe6, 0x57, 0xa9, 0x06, 0xe2, 0x8b, 0x9c, 0xf4, 0x26, 0xe6, - 0x42, 0xe6, 0x25, 0x57, 0xae, 0xce, 0x5b, 0xce, 0xb5, 0x9b, 0x0e, 0x7a, 0x06, 0x23, 0x8d, 0x7f, - 0x74, 0x46, 0x83, 0xf3, 0xb6, 0x98, 0x35, 0x4d, 0x49, 0x06, 0xde, 0xe6, 0xbb, 0x5c, 0xc0, 0xc8, - 0xde, 0x25, 0x3b, 0xa3, 0x01, 0xbb, 0x99, 0x3f, 0x85, 0xbe, 0xf1, 0xcb, 0x8d, 0x96, 0x53, 0xfd, - 0x3f, 0x9c, 0x59, 0x53, 0x01, 0xd2, 0x7e, 0x12, 0x64, 0x88, 0x9d, 0x9d, 0xfa, 0x0b, 0x46, 0x9b, - 0xc2, 0xc8, 0xae, 0xb3, 0x69, 0xb3, 0x6c, 0x2c, 0xda, 0x69, 0xb3, 0x5c, 0x52, 0x9e, 0xb3, 0x78, - 0xe1, 0xcd, 0x0d, 0x62, 0x3e, 0x41, 0x73, 0xf6, 0xea, 0x96, 0xf5, 0x36, 0xf3, 0xd5, 0xad, 0x96, - 0xf4, 0xcc, 0x57, 0xb7, 0x56, 0xa0, 0xb3, 0x79, 0x12, 0xdb, 0x28, 0xcd, 0xa0, 0xef, 0x01, 0x74, - 0xb5, 0x4d, 0xeb, 0xa4, 0x56, 0xb0, 0x9b, 0xcd, 0x9a, 0xa6, 0xe4, 0x06, 0x96, 0xe6, 0xc5, 0x06, - 0xea, 0xc9, 0xfb, 0x09, 0xf4, 0x54, 0xd9, 0x08, 0x95, 0x96, 0x53, 0xa9, 0x2d, 0xcd, 0xa6, 0xf5, - 0x89, 0x8a, 0xb9, 0x72, 0xc7, 0x93, 0xc9, 0x59, 0x46, 0x97, 0xc0, 0xb8, 0x52, 0x7a, 0x42, 0xa5, - 0xb4, 0x9b, 0x6b, 0x52, 0x33, 0xfb, 0x0f, 0x1b, 0xd1, 0xaf, 0xc2, 0x6f, 0xf1, 0x0d, 0xb6, 0xd1, - 0x26, 0xdf, 0x40, 0x2d, 0x14, 0x26, 0x75, 0xd3, 0x41, 0x8b, 0x4a, 0x29, 0x4a, 0xd6, 0x34, 0x0c, - 0x87, 0xd4, 0x58, 0xa9, 0x9a, 0x35, 0x95, 0x99, 0xf1, 0x8f, 0xf8, 0x5e, 0x6f, 0xa1, 0x8b, 0xd6, - 0x5e, 0xcc, 0xba, 0x54, 0x95, 0xfd, 0xa6, 0x83, 0xe6, 0x30, 0xb2, 0x49, 0xbe, 0xd1, 0x56, 0x15, - 0x33, 0x46, 0xa8, 0xb6, 0x15, 0xdb, 0xe3, 0x0f, 0x8c, 0xba, 0x9d, 0x55, 0x81, 0x43, 0x57, 0x9a, - 0xf7, 0xaa, 0x54, 0xe8, 0x66, 0x5b, 0xe6, 0x9e, 0x6a, 0x12, 0x63, 0xbe, 0xe9, 0x25, 0x34, 0xab, - 0x6f, 0xea, 0x4b, 0x1c, 0xee, 0x09, 0x06, 0x66, 0x6e, 0xa8, 0x03, 0x98, 0x86, 0xf4, 0x52, 0x07, - 0x30, 0x4d, 0xe9, 0xa4, 0x52, 0x9e, 0x08, 0x60, 0x78, 0xee, 0x78, 0x2c, 0x30, 0x98, 0x85, 0x3c, - 0xaf, 0x26, 0x91, 0x97, 0x96, 0xa4, 0x6c, 0x95, 0x78, 0xa0, 0x31, 0xa1, 0x53, 0x26, 0x8e, 0x36, - 0xd4, 0x56, 0x11, 0x7d, 0x2e, 0xf2, 0x3a, 0xf4, 0x35, 0x74, 0x78, 0xb6, 0x84, 0xb6, 0x74, 0xc8, - 0xaa, 0x93, 0xb2, 0xd9, 0x76, 0x05, 0x6a, 0x3f, 0xa9, 0x98, 0xfb, 0xf8, 0x82, 0xca, 0xe8, 0x6e, - 0x0e, 0x23, 0x11, 0x24, 0xa9, 0x9c, 0x42, 0x5f, 0x9a, 0x4a, 0xca, 0xa3, 0x2f, 0x4d, 0x35, 0xfd, - 0xb0, 0xdd, 0x8a, 0x88, 0x93, 0x4e, 0x25, 0xce, 0x2d, 0xe7, 0xda, 0x7c, 0x8d, 0xff, 0x0d, 0xff, - 0xc9, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x73, 0x92, 0x96, 0x52, 0x38, 0x2f, 0x00, 0x00, + // 3835 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3a, 0x4b, 0x8f, 0x1d, 0xc7, + 0x5a, 0xd3, 0xe7, 0xcc, 0x99, 0x73, 0xe6, 0x3b, 0xcf, 0xa9, 0x79, 0x78, 0x7c, 0xe2, 0x24, 0xbe, + 0x45, 0x1c, 0x39, 0x4e, 0x62, 0x9b, 0x09, 0x21, 0x37, 0x06, 0x47, 0xf1, 0x8c, 0x87, 0xd8, 0xc9, + 0xc4, 0xb6, 0x7a, 0x9c, 0x6b, 0x73, 0x05, 0x69, 0xf5, 0xe9, 0x2e, 0x7b, 0x1a, 0xf7, 0x54, 0x9f, + 0xf4, 0x63, 0x1e, 0xb0, 0x41, 0x57, 0xac, 0x60, 0x89, 0x58, 0xc3, 0x0a, 0x21, 0x81, 0xd8, 0xb3, + 0x40, 0x62, 0xcd, 0x96, 0x05, 0x12, 0xb0, 0x41, 0xf0, 0x0b, 0x10, 0x5b, 0x24, 0x54, 0xaf, 0xae, + 0xaa, 0xee, 0x3e, 0x73, 0xed, 0x2b, 0xb8, 0xbb, 0xae, 0xaf, 0xbe, 0xfa, 0xaa, 0xbe, 0x47, 0x7d, + 0xf5, 0x3d, 0x1a, 0x06, 0x67, 0x45, 0x98, 0xce, 0x83, 0x9b, 0xf3, 0x34, 0xc9, 0x13, 0xb4, 0x22, + 0x46, 0xd3, 0x35, 0x9f, 0xd2, 0x24, 0xf7, 0xf3, 0x28, 0xa1, 0x99, 0x98, 0xc2, 0x9b, 0xb0, 0x7e, + 0x2f, 0x0c, 0xf7, 0x8a, 0x34, 0x25, 0x34, 0x38, 0x77, 0x49, 0x36, 0x4f, 0x68, 0x46, 0xf0, 0xf7, + 0x30, 0xba, 0x17, 0x86, 0x4f, 0xfc, 0x28, 0x75, 0xc9, 0x0f, 0x05, 0xc9, 0x72, 0xf4, 0x1e, 0x0c, + 0x67, 0x7e, 0x46, 0xbc, 0x40, 0xa2, 0x6e, 0x3b, 0x57, 0x9d, 0xeb, 0xab, 0xae, 0x0d, 0x44, 0xef, + 0xc3, 0xe8, 0x87, 0x22, 0xc9, 0x0d, 0xb4, 0x16, 0x47, 0xab, 0x40, 0xf1, 0x1a, 0x8c, 0x4b, 0xfa, + 0x72, 0xcb, 0xff, 0x68, 0x41, 0x77, 0xd7, 0x8f, 0x7d, 0x1a, 0x10, 0xb6, 0x59, 0x9e, 0xe4, 0x7e, + 0xec, 0xcd, 0x04, 0x80, 0x6f, 0xb6, 0xec, 0xda, 0x40, 0x74, 0x1d, 0xc6, 0xc1, 0x91, 0x4f, 0x29, + 0xd1, 0x78, 0x2d, 0x8e, 0x57, 0x05, 0xa3, 0x1f, 0xc3, 0xa5, 0x39, 0xa1, 0x61, 0x44, 0x5f, 0x7a, + 0xd5, 0x15, 0x6d, 0xbe, 0x62, 0xd1, 0x34, 0xba, 0x03, 0xdb, 0x11, 0xf5, 0x83, 0x3c, 0x3a, 0x21, + 0xb5, 0xa5, 0xcb, 0x7c, 0xe9, 0xc2, 0x79, 0x26, 0x8c, 0x53, 0x3f, 0x8e, 0x49, 0x5e, 0xae, 0xe8, + 0xf0, 0x15, 0x15, 0x28, 0xfa, 0x02, 0xa6, 0x05, 0x0d, 0x12, 0xfa, 0x22, 0x4a, 0x8f, 0x49, 0xe8, + 0x55, 0xd6, 0xac, 0xf0, 0x35, 0x17, 0x60, 0xa0, 0x1b, 0x30, 0x49, 0x49, 0x46, 0xd2, 0x13, 0x12, + 0x96, 0xab, 0xba, 0x7c, 0x55, 0x0d, 0x8e, 0x7f, 0x1d, 0x60, 0xd7, 0xa7, 0x4a, 0xa9, 0xd7, 0x61, + 0x4c, 0x93, 0x90, 0x78, 0x51, 0x48, 0x68, 0x1e, 0xbd, 0x88, 0x48, 0x2a, 0xd5, 0x5a, 0x05, 0xe3, + 0x21, 0xf4, 0xf9, 0x3a, 0xa9, 0xac, 0xcf, 0xa0, 0xb3, 0x77, 0xe4, 0x47, 0x14, 0x6d, 0x40, 0x27, + 0x60, 0x1f, 0x72, 0x9d, 0x18, 0xa0, 0x6d, 0xe8, 0x52, 0x92, 0x9f, 0x26, 0xe9, 0x2b, 0xa9, 0x7f, + 0x35, 0xc4, 0x73, 0xe8, 0xed, 0x09, 0x31, 0x65, 0x68, 0x0b, 0x56, 0x84, 0xe4, 0xf8, 0xe2, 0xa1, + 0x2b, 0x47, 0x68, 0x0a, 0x3d, 0x25, 0x53, 0xbe, 0x7c, 0xe8, 0x96, 0x63, 0x46, 0x59, 0xaa, 0x8a, + 0x6b, 0x6e, 0xe8, 0xaa, 0x21, 0xa3, 0x16, 0xc4, 0x49, 0x46, 0x42, 0xae, 0x97, 0xa1, 0x2b, 0x47, + 0xf8, 0xef, 0x1d, 0x58, 0xdf, 0x63, 0x9f, 0x72, 0xdf, 0x37, 0xe6, 0x9d, 0x9d, 0xa7, 0x62, 0xce, + 0xe5, 0x98, 0xf1, 0xff, 0x22, 0x49, 0xa5, 0x1d, 0xf5, 0x5c, 0x31, 0x40, 0x57, 0xa1, 0x1f, 0x92, + 0x2c, 0x8f, 0x28, 0xbf, 0x6b, 0xfc, 0x40, 0xab, 0xae, 0x09, 0xe2, 0xbc, 0x1f, 0x27, 0x05, 0xcd, + 0xa5, 0x4d, 0xc8, 0x11, 0x9a, 0x40, 0xfb, 0x05, 0x51, 0x4a, 0x67, 0x9f, 0xf8, 0x4b, 0xd8, 0xb0, + 0x8f, 0x2f, 0x54, 0xc0, 0xce, 0x9f, 0xa7, 0x3e, 0xcd, 0x98, 0x60, 0x12, 0xea, 0x45, 0x61, 0xb6, + 0xed, 0x5c, 0x6d, 0xb3, 0xf3, 0x57, 0xc0, 0xf8, 0x23, 0x18, 0xed, 0x25, 0x94, 0x92, 0x20, 0x57, + 0xbc, 0x4f, 0xa1, 0xc7, 0x99, 0x2c, 0xd2, 0x48, 0x32, 0x5d, 0x8e, 0xd9, 0xd5, 0x2c, 0xb1, 0xa5, + 0xb6, 0x6f, 0xc1, 0xda, 0x5e, 0x4a, 0xfc, 0x9c, 0x3c, 0x4a, 0x42, 0x62, 0xd0, 0x98, 0xfb, 0x59, + 0x76, 0x9a, 0xa4, 0xa1, 0xa2, 0xa1, 0xc6, 0xf8, 0xcf, 0x1c, 0x40, 0xe6, 0x0a, 0x79, 0xe4, 0x5f, + 0x81, 0x61, 0x46, 0x48, 0xe8, 0x1d, 0x53, 0x72, 0x9c, 0xd0, 0x28, 0x90, 0x07, 0x1e, 0x30, 0xe0, + 0xb7, 0x12, 0x86, 0x3e, 0x80, 0x49, 0x44, 0xa3, 0x3c, 0xf2, 0xe3, 0xe8, 0xf7, 0x49, 0xe8, 0xc5, + 0x34, 0xcc, 0xb6, 0x5b, 0x82, 0x31, 0x03, 0x7e, 0x40, 0xc3, 0x0c, 0xdd, 0x82, 0x75, 0x13, 0x35, + 0x60, 0xc7, 0x3e, 0xcb, 0xa5, 0x2a, 0x90, 0x31, 0xb5, 0x27, 0x66, 0xf0, 0x3f, 0x3b, 0xd0, 0x53, + 0xbe, 0xce, 0x52, 0xab, 0x53, 0x51, 0xeb, 0x5d, 0xe8, 0x67, 0xa7, 0xfe, 0xdc, 0x0b, 0xe2, 0x88, + 0xd0, 0x9c, 0x6b, 0x7d, 0xb4, 0xf3, 0xd6, 0x4d, 0xe9, 0x55, 0x15, 0x89, 0x9b, 0x87, 0xa7, 0xfe, + 0x7c, 0x8f, 0xa3, 0xb8, 0x26, 0xbe, 0xf0, 0x5f, 0xaf, 0x08, 0xf5, 0xfc, 0x30, 0x4c, 0x49, 0x96, + 0xf1, 0x23, 0xad, 0xba, 0x36, 0x90, 0xf9, 0x87, 0x90, 0x04, 0xd1, 0xb1, 0x1f, 0x7b, 0xf3, 0xd8, + 0x0f, 0x48, 0x26, 0x2d, 0xb7, 0x02, 0xc5, 0x18, 0x40, 0x6f, 0x84, 0xba, 0xd0, 0x3e, 0x78, 0x74, + 0x7f, 0xb2, 0x84, 0xfa, 0xd0, 0xdd, 0x7b, 0xfc, 0xe8, 0xd1, 0xfe, 0xf3, 0xa7, 0x93, 0x16, 0xd3, + 0xf1, 0x7d, 0x32, 0x4f, 0xb2, 0xc8, 0xd4, 0xf1, 0x22, 0xf6, 0xf0, 0x87, 0x30, 0x2e, 0xb1, 0xa5, + 0x6e, 0xb6, 0xa1, 0xab, 0x0e, 0x2b, 0xb0, 0xd5, 0x90, 0x19, 0xe0, 0xfd, 0x28, 0x0b, 0x92, 0x13, + 0x92, 0x32, 0x6d, 0x66, 0x6f, 0xee, 0x3c, 0x3e, 0x85, 0xcd, 0x0a, 0x05, 0xb9, 0xe9, 0x15, 0x58, + 0xa5, 0xc5, 0xb1, 0xc7, 0xf0, 0x33, 0xe9, 0x04, 0x34, 0x00, 0xff, 0xb1, 0x03, 0x68, 0xff, 0x8c, + 0x04, 0x45, 0x4e, 0x18, 0xff, 0x06, 0x63, 0x49, 0x1a, 0x92, 0xd4, 0x8b, 0x4a, 0xc3, 0x53, 0x63, + 0xee, 0x1e, 0xfc, 0x88, 0x4f, 0x49, 0xc7, 0x23, 0x87, 0x08, 0xc3, 0x60, 0x4e, 0x48, 0xea, 0xcd, + 0x8b, 0x99, 0xf7, 0x8a, 0x9c, 0x4b, 0x8d, 0x58, 0x30, 0x46, 0xf9, 0x87, 0xc2, 0xa7, 0x79, 0x94, + 0x9f, 0x4b, 0xe7, 0x5e, 0x8e, 0xd9, 0x1d, 0xf8, 0x8a, 0xe4, 0xf2, 0x81, 0x7a, 0x1d, 0x19, 0xff, + 0x95, 0x03, 0xc8, 0x5c, 0x21, 0x59, 0xbe, 0x0f, 0x3d, 0xe9, 0x8b, 0xc5, 0x7d, 0xed, 0xef, 0x5c, + 0x57, 0x66, 0x55, 0xc7, 0xbe, 0x29, 0xc7, 0xd9, 0x3e, 0xcd, 0xd3, 0x73, 0xb7, 0x5c, 0x39, 0x3d, + 0x80, 0xa1, 0x35, 0xc5, 0xfc, 0x06, 0xe3, 0x4a, 0x1c, 0x82, 0x7d, 0xa2, 0x6b, 0xd0, 0x39, 0xf1, + 0xe3, 0x42, 0xb8, 0xd0, 0xfe, 0xce, 0x58, 0xed, 0xa2, 0xb6, 0x10, 0xb3, 0x77, 0x5a, 0x3f, 0x76, + 0xf0, 0x04, 0x46, 0x5f, 0x91, 0xfc, 0x21, 0x7d, 0x91, 0x48, 0xc6, 0xf0, 0xbf, 0xb4, 0x61, 0x5c, + 0x82, 0xb4, 0x85, 0x9c, 0x90, 0x34, 0x63, 0x0e, 0x4d, 0x5a, 0x88, 0x1c, 0x32, 0xd9, 0x72, 0x95, + 0x2b, 0xd9, 0x0a, 0xd1, 0x5b, 0x30, 0x84, 0x60, 0xb9, 0x48, 0x23, 0x76, 0x13, 0xd8, 0x55, 0xe6, + 0xdf, 0x4a, 0xfd, 0x4c, 0x07, 0xca, 0xf6, 0x35, 0xa0, 0x9c, 0xf5, 0xa3, 0x34, 0xe3, 0x5e, 0x52, + 0xcd, 0x32, 0x00, 0xfa, 0x10, 0x56, 0xb8, 0xd6, 0x33, 0xee, 0x2b, 0xfb, 0x3b, 0xeb, 0x8a, 0xbf, + 0xc7, 0x1c, 0xba, 0xc7, 0xbc, 0xa9, 0x2b, 0x51, 0xd0, 0x0e, 0xb4, 0x63, 0x1a, 0x6e, 0x77, 0xb9, + 0xbc, 0xaf, 0x1a, 0xf2, 0x36, 0x19, 0xbc, 0x79, 0x40, 0x43, 0x21, 0x67, 0x86, 0xcc, 0x3c, 0xbb, + 0x1f, 0x47, 0x7e, 0xb6, 0xbd, 0x2a, 0x5e, 0x36, 0x3e, 0x30, 0x5f, 0x36, 0xb0, 0x5e, 0x36, 0x74, + 0x1b, 0xd6, 0x55, 0x10, 0xc1, 0x5d, 0xc1, 0x91, 0x9f, 0x1d, 0x91, 0x6c, 0xbb, 0xcf, 0xf9, 0x6d, + 0x9a, 0x42, 0x1f, 0x43, 0x57, 0xb9, 0xac, 0x81, 0xcd, 0x83, 0xf4, 0x57, 0xfc, 0x74, 0x0a, 0x67, + 0xfa, 0x15, 0xf4, 0xd4, 0x09, 0xdf, 0x40, 0xdd, 0x07, 0x34, 0xe4, 0x64, 0x0c, 0x75, 0x7f, 0xc1, + 0x0d, 0x93, 0xdd, 0x44, 0x43, 0xe5, 0x6f, 0x70, 0x9d, 0x5d, 0x58, 0xb7, 0xd6, 0x97, 0xde, 0x7d, + 0x9c, 0x92, 0x79, 0x21, 0xe2, 0xcb, 0xc3, 0x20, 0x49, 0xc5, 0xbb, 0xbe, 0xe6, 0x82, 0x06, 0xb3, + 0x77, 0x6f, 0xc6, 0xde, 0x31, 0x71, 0x3f, 0x7b, 0xae, 0x1c, 0xe1, 0x4b, 0xb0, 0x79, 0x10, 0x65, + 0xb9, 0xf4, 0xac, 0x51, 0xe9, 0x65, 0xf0, 0xd7, 0xb0, 0x55, 0x9d, 0x90, 0xfb, 0xdd, 0x06, 0x08, + 0x4a, 0xa8, 0xbc, 0x4b, 0x93, 0xaa, 0x8b, 0x76, 0x0d, 0x1c, 0xfc, 0x8f, 0x0e, 0xac, 0x31, 0x62, + 0xc2, 0x44, 0x14, 0xe3, 0x86, 0xcf, 0x70, 0x6c, 0x9f, 0xf1, 0x29, 0x74, 0x92, 0x53, 0x4a, 0x52, + 0xe9, 0xff, 0xdf, 0x2d, 0x65, 0x5a, 0xa5, 0x71, 0xf3, 0x31, 0x43, 0x73, 0x05, 0x36, 0xb3, 0x9c, + 0x38, 0x3a, 0x8e, 0x72, 0x19, 0xa1, 0x88, 0x01, 0x93, 0x6f, 0x44, 0x83, 0xb8, 0x08, 0x89, 0xc7, + 0x4d, 0x49, 0xba, 0xfb, 0x9e, 0x5b, 0x05, 0xe3, 0xf7, 0xa0, 0xc3, 0xe9, 0xa1, 0x1e, 0x2c, 0xef, + 0x3e, 0x7e, 0xfa, 0x60, 0xb2, 0xc4, 0x9c, 0xfe, 0xe3, 0x67, 0x8f, 0x26, 0x0e, 0x03, 0x3d, 0xd9, + 0xdf, 0x77, 0x27, 0x2d, 0xfc, 0xe7, 0x0e, 0x20, 0xf3, 0x20, 0x52, 0x2a, 0x5f, 0x94, 0xf7, 0x42, + 0x48, 0xe4, 0xfd, 0xa6, 0x43, 0x4b, 0x83, 0x17, 0x43, 0x61, 0xf3, 0x72, 0xd5, 0xf4, 0x21, 0xf4, + 0x0d, 0x70, 0x83, 0xa1, 0xbd, 0x67, 0x1b, 0xda, 0xc8, 0xbe, 0x77, 0xa6, 0x9d, 0x21, 0x98, 0xb0, + 0x4d, 0x59, 0x94, 0x5f, 0xaa, 0xf3, 0x03, 0xa1, 0x01, 0x09, 0x93, 0x67, 0xde, 0x80, 0x8e, 0xb8, + 0xe5, 0x22, 0x1e, 0x10, 0x83, 0x72, 0x39, 0xd1, 0x72, 0xc6, 0x9f, 0xc9, 0xe5, 0xc4, 0x64, 0x19, + 0x43, 0x47, 0xb8, 0x10, 0xc1, 0xf1, 0x40, 0x9d, 0x88, 0x61, 0xb9, 0x62, 0x0a, 0xff, 0x9b, 0x03, + 0x5d, 0x79, 0x15, 0x98, 0x0d, 0x66, 0xb9, 0x9f, 0x17, 0xea, 0xa5, 0x93, 0x23, 0xf4, 0x11, 0xf4, + 0x64, 0x08, 0x9f, 0x49, 0xe6, 0xb4, 0x39, 0x49, 0xb8, 0x5b, 0x62, 0xa0, 0x6b, 0xb0, 0xc2, 0x83, + 0x5d, 0xe1, 0xd2, 0xfa, 0x3b, 0x43, 0x03, 0x37, 0xa2, 0xae, 0x9c, 0x64, 0xa1, 0xe0, 0x2c, 0x4e, + 0x82, 0x57, 0x47, 0x24, 0x7a, 0x79, 0x94, 0x4b, 0x2f, 0x67, 0x82, 0x4a, 0xcf, 0xd8, 0x31, 0x3c, + 0xa3, 0xe1, 0x6b, 0x57, 0x6c, 0x5f, 0x5b, 0xba, 0xa5, 0xae, 0xe1, 0x96, 0xf0, 0xd7, 0x30, 0xe2, + 0xf7, 0x51, 0x07, 0xad, 0x55, 0x9f, 0xec, 0x34, 0xf8, 0xe4, 0x92, 0x56, 0xcb, 0xa4, 0xf5, 0x97, + 0x0e, 0xa0, 0xc7, 0x73, 0x42, 0xff, 0x5f, 0xe2, 0x65, 0x1d, 0xf7, 0xb6, 0xad, 0xb8, 0xf7, 0x2a, + 0xf4, 0xe7, 0x45, 0x76, 0xe4, 0xc9, 0x49, 0xf1, 0xfa, 0x9a, 0x20, 0x15, 0x19, 0x77, 0x74, 0x64, + 0x7c, 0x17, 0xd6, 0xad, 0x73, 0x4a, 0x73, 0x78, 0x1f, 0x46, 0x76, 0x04, 0x2c, 0xcf, 0x59, 0x81, + 0xe2, 0x7f, 0x68, 0x41, 0x87, 0x1b, 0x2d, 0xb7, 0xbf, 0x34, 0x92, 0x69, 0xa6, 0xe3, 0x8a, 0x81, + 0x15, 0x0d, 0xb4, 0xec, 0x68, 0xc0, 0xf4, 0x19, 0x6d, 0xdb, 0x67, 0x8c, 0xa0, 0x15, 0x85, 0x32, + 0xe2, 0x6f, 0x45, 0x21, 0xfa, 0xb2, 0x2e, 0xb6, 0x0e, 0xb7, 0xad, 0x2d, 0x65, 0x2f, 0xb6, 0xe2, + 0x1a, 0xc5, 0x19, 0x27, 0x81, 0x1f, 0xb3, 0xcd, 0x84, 0x31, 0x94, 0x63, 0xf4, 0x0e, 0x40, 0xc0, + 0xe3, 0xec, 0xd0, 0xf3, 0x73, 0x99, 0xf4, 0x19, 0x10, 0x74, 0x0d, 0x96, 0xb3, 0x28, 0x24, 0xdb, + 0x3d, 0xee, 0xc0, 0xd6, 0xac, 0xbb, 0x7a, 0x18, 0x85, 0xc4, 0xe5, 0xd3, 0xcc, 0x58, 0xa2, 0xcc, + 0x4b, 0x4e, 0xa9, 0xc7, 0xbd, 0x00, 0x7f, 0xf2, 0x7a, 0xae, 0x05, 0x63, 0x66, 0x7a, 0x94, 0xc4, + 0x21, 0x7f, 0xf6, 0x96, 0x5d, 0xfe, 0x8d, 0xff, 0xc2, 0x81, 0x01, 0xa7, 0xe5, 0x92, 0xe3, 0xe4, + 0xc4, 0x8f, 0x2d, 0x99, 0x39, 0x8b, 0x65, 0x56, 0x89, 0xcd, 0xcc, 0x88, 0xae, 0x5d, 0x89, 0xe8, + 0x4c, 0xee, 0x97, 0x2b, 0xdc, 0x57, 0x8f, 0xdd, 0xa9, 0x1f, 0x1b, 0x1f, 0xc1, 0x8a, 0xf0, 0x4c, + 0xe8, 0x63, 0x80, 0x59, 0x71, 0xee, 0x59, 0xde, 0x71, 0x68, 0x49, 0xc4, 0x35, 0x10, 0xd0, 0x2d, + 0xe8, 0x67, 0x24, 0x8e, 0x15, 0x7e, 0xab, 0x09, 0xdf, 0xc4, 0xc0, 0x9f, 0x28, 0xcf, 0xc9, 0x63, + 0x0f, 0x26, 0x2f, 0xe6, 0x7a, 0x64, 0x58, 0xcb, 0xbf, 0x99, 0x0d, 0x27, 0xa7, 0x54, 0x26, 0xb5, + 0xec, 0x13, 0xff, 0xcc, 0x91, 0xab, 0xbe, 0x9b, 0x87, 0x7e, 0x4e, 0xd8, 0x33, 0x2e, 0x78, 0x71, + 0xb8, 0x91, 0xd8, 0xfb, 0x3d, 0x58, 0x72, 0xc5, 0x2c, 0xfa, 0x4d, 0x18, 0x0a, 0x09, 0xa5, 0x42, + 0xf0, 0xd2, 0x5f, 0x6d, 0xd8, 0xc7, 0x13, 0x73, 0x0f, 0x96, 0x5c, 0x1b, 0x79, 0x77, 0x04, 0x03, + 0x01, 0x28, 0xf8, 0xa6, 0xf8, 0x5f, 0x5b, 0xb0, 0xcc, 0x9c, 0xe5, 0xe2, 0x24, 0xe0, 0xb5, 0x42, + 0xbc, 0x2f, 0x61, 0x10, 0xd3, 0x50, 0x0d, 0x95, 0x5f, 0xbc, 0x62, 0xba, 0x63, 0x16, 0x8e, 0x3c, + 0x29, 0x66, 0xdf, 0x90, 0x73, 0xf9, 0xec, 0x58, 0x2b, 0xd8, 0xfe, 0x11, 0x9d, 0x25, 0x05, 0x0d, + 0xe5, 0xdb, 0xa8, 0x86, 0xfa, 0x89, 0xe8, 0x18, 0x4f, 0x04, 0xf3, 0x1a, 0x67, 0x45, 0xe8, 0xd9, + 0xae, 0xd2, 0x04, 0xa1, 0x8f, 0x60, 0x2d, 0x23, 0x41, 0x42, 0xc3, 0x4c, 0xa4, 0x87, 0x41, 0x4e, + 0x42, 0x7e, 0x4f, 0x86, 0x6e, 0x7d, 0xa2, 0x39, 0xe6, 0x9b, 0xde, 0x85, 0x71, 0xe5, 0xd8, 0x0d, + 0xcf, 0xe2, 0x86, 0xf9, 0x2c, 0xae, 0x9a, 0xcf, 0xe0, 0x1f, 0xb6, 0x60, 0xed, 0x09, 0xcb, 0xe4, + 0xa4, 0x52, 0x84, 0x3b, 0xfd, 0xbf, 0xf4, 0x39, 0xe6, 0xfd, 0x59, 0xae, 0xdc, 0x1f, 0xe5, 0x01, + 0x3a, 0x17, 0x7b, 0x00, 0x5e, 0x43, 0xe2, 0xf9, 0xa6, 0x57, 0x92, 0x12, 0xe2, 0xac, 0xc1, 0x59, + 0xa4, 0x1b, 0x1d, 0x1f, 0x93, 0x30, 0xf2, 0x73, 0x06, 0xf5, 0x02, 0x96, 0x4f, 0xc4, 0x5c, 0xaa, + 0x3d, 0xb7, 0x69, 0x8a, 0x89, 0x00, 0x99, 0x22, 0x90, 0x9e, 0xfa, 0x73, 0x96, 0xea, 0xe7, 0x24, + 0xa5, 0x7e, 0xec, 0x1d, 0xfb, 0x79, 0x70, 0x44, 0x16, 0xdc, 0xcb, 0x1a, 0x1a, 0xfa, 0x0d, 0x18, + 0xf1, 0x50, 0x3a, 0x2b, 0x82, 0x80, 0x64, 0x2c, 0x98, 0x12, 0x17, 0xb4, 0x0c, 0xa1, 0x59, 0xc6, + 0x78, 0x28, 0x26, 0xdd, 0x0a, 0x2a, 0xfa, 0x8c, 0x45, 0xaa, 0xc7, 0x7e, 0x44, 0x59, 0x44, 0x2e, + 0xae, 0x5b, 0xbb, 0xe1, 0xba, 0xb9, 0x55, 0x2c, 0xf4, 0x39, 0x0c, 0x39, 0xa9, 0x17, 0x7e, 0x14, + 0x17, 0x29, 0x8f, 0xe0, 0x6a, 0x9b, 0xfe, 0x96, 0x98, 0x73, 0x6d, 0x4c, 0xfc, 0x5f, 0x0e, 0x8c, + 0xb5, 0x08, 0xf6, 0x4f, 0x58, 0x2a, 0x7f, 0x0d, 0x3a, 0x9c, 0x9f, 0x85, 0x97, 0x9d, 0xcf, 0xa2, + 0xcf, 0x61, 0x60, 0x32, 0x20, 0xef, 0x7a, 0x13, 0xa7, 0x0f, 0x96, 0x5c, 0x0b, 0x15, 0x7d, 0xfe, + 0x7a, 0x9c, 0x3e, 0x58, 0x6a, 0xe2, 0x75, 0x60, 0x72, 0xc0, 0x0d, 0xab, 0x99, 0xd5, 0x72, 0x57, + 0x89, 0xba, 0xdb, 0x85, 0x0e, 0x61, 0x0c, 0xe2, 0x04, 0xfa, 0x46, 0x2a, 0xb3, 0x30, 0xf0, 0x32, + 0xdc, 0x4e, 0xcb, 0x76, 0x3b, 0x46, 0x1c, 0xb4, 0x5c, 0x8b, 0x83, 0x44, 0xe1, 0xb1, 0x63, 0x14, + 0x1e, 0xf1, 0x27, 0xb0, 0xc9, 0xbd, 0x1e, 0xd1, 0x15, 0xed, 0x9f, 0x9f, 0xa9, 0x6f, 0xc3, 0x56, + 0x75, 0x91, 0x2c, 0x7c, 0x1d, 0x00, 0x12, 0x33, 0xd6, 0xd5, 0xbd, 0xa8, 0x00, 0x71, 0xc1, 0x05, + 0xc6, 0x9f, 0xc2, 0xba, 0x45, 0x4d, 0xde, 0x82, 0x77, 0x60, 0xa2, 0x50, 0xbc, 0x84, 0x7a, 0xfc, + 0x91, 0x75, 0x8c, 0x47, 0xf6, 0x63, 0x58, 0x13, 0xcb, 0xcc, 0x72, 0xfc, 0xc2, 0xa4, 0x05, 0x6f, + 0xa8, 0x33, 0x5b, 0xd5, 0xf5, 0x3f, 0x6a, 0x31, 0x70, 0x96, 0x27, 0xa9, 0x55, 0xc4, 0x7b, 0xad, + 0x8a, 0x9c, 0x59, 0xe9, 0x6b, 0xd9, 0x95, 0x3e, 0xf4, 0x0d, 0xf4, 0x99, 0x07, 0x9f, 0xf9, 0xc1, + 0xab, 0x62, 0xae, 0x5c, 0xfe, 0x0d, 0x65, 0x24, 0xf5, 0x1d, 0xd9, 0x03, 0xb0, 0x2b, 0x90, 0xc5, + 0x03, 0x00, 0x71, 0x09, 0x40, 0x3f, 0xe2, 0x7d, 0x0b, 0x2f, 0xf4, 0x73, 0x7f, 0xe6, 0x67, 0xa2, + 0x0a, 0x3a, 0xe0, 0xfe, 0xfc, 0xbe, 0x04, 0x49, 0x5f, 0x6c, 0x52, 0xf8, 0x79, 0xbe, 0x78, 0x60, + 0xfa, 0x62, 0xc2, 0x54, 0x60, 0x9c, 0x49, 0x17, 0x26, 0x53, 0x01, 0x96, 0x05, 0x47, 0x29, 0x06, + 0x05, 0xe4, 0xd5, 0xc6, 0x0f, 0x78, 0x99, 0x5d, 0x20, 0xa9, 0xbc, 0x5d, 0x24, 0xb1, 0x63, 0x05, + 0x57, 0x75, 0xc6, 0x35, 0x18, 0x1f, 0x1e, 0x15, 0x79, 0x98, 0x9c, 0xaa, 0x52, 0x3b, 0xcb, 0x66, + 0x34, 0x48, 0x2a, 0xe5, 0xd7, 0x60, 0xeb, 0xb0, 0x98, 0x65, 0x41, 0x1a, 0xcd, 0x88, 0x9d, 0x93, + 0x4e, 0xa1, 0x47, 0xce, 0xa2, 0x2c, 0x8f, 0xe8, 0x4b, 0xce, 0x58, 0xcf, 0x2d, 0xc7, 0xf8, 0x5d, + 0x78, 0xbb, 0x5c, 0xc5, 0x6e, 0x61, 0x76, 0x2f, 0x08, 0xc8, 0x3c, 0x27, 0xa1, 0xda, 0xea, 0x2e, + 0x6c, 0xda, 0x08, 0x46, 0x0f, 0x47, 0xe5, 0x9a, 0xb9, 0xff, 0x4a, 0x06, 0x19, 0x3d, 0xd7, 0x06, + 0xe2, 0xff, 0x69, 0xc1, 0x80, 0x2d, 0x53, 0x64, 0xd1, 0xe5, 0x9a, 0xbd, 0x77, 0xf9, 0xf8, 0xa1, + 0x1d, 0x9d, 0xb5, 0x2a, 0xd1, 0xd9, 0x85, 0xef, 0xd5, 0xa2, 0x3a, 0x9b, 0x7e, 0x17, 0x3b, 0xe6, + 0xbb, 0x58, 0xad, 0xde, 0xad, 0x34, 0x54, 0xef, 0xb6, 0x60, 0x25, 0xe5, 0xa5, 0x15, 0x99, 0x1a, + 0xc9, 0x11, 0x7b, 0xda, 0x44, 0x0a, 0xe1, 0xa5, 0x24, 0x20, 0xd1, 0x09, 0x93, 0x69, 0x4f, 0xb4, + 0x47, 0xaa, 0x70, 0x96, 0x3b, 0x48, 0x58, 0x26, 0xbb, 0x0c, 0xab, 0xa2, 0x65, 0x63, 0x43, 0xd1, + 0x4d, 0x40, 0xca, 0x7d, 0x18, 0x54, 0x45, 0x45, 0xa8, 0x61, 0x86, 0x9d, 0xa1, 0x84, 0x2a, 0xca, + 0x7d, 0xf1, 0xbc, 0x56, 0xe1, 0xf8, 0xaf, 0x1d, 0xe8, 0x1b, 0xde, 0xf5, 0x17, 0xac, 0x77, 0x9a, + 0x32, 0x6e, 0x57, 0x64, 0x5c, 0x95, 0xe6, 0x72, 0x83, 0x34, 0xdf, 0x87, 0x91, 0x74, 0xe7, 0x5e, + 0x4a, 0xfc, 0x2c, 0x51, 0x8e, 0xb6, 0x02, 0xc5, 0x7f, 0xdb, 0x16, 0xa7, 0x95, 0x2f, 0xd0, 0x2f, + 0xd7, 0x58, 0xb4, 0xca, 0x3b, 0x96, 0xca, 0xaf, 0xc3, 0xd8, 0x52, 0x2d, 0x09, 0xa5, 0xc6, 0xab, + 0x60, 0x16, 0x41, 0x6a, 0xd5, 0xe6, 0x52, 0xdb, 0x26, 0xa8, 0x26, 0x2c, 0x68, 0x10, 0xd6, 0x55, + 0x58, 0x4e, 0x93, 0x98, 0x70, 0x95, 0x8e, 0x74, 0x01, 0xc2, 0x4d, 0x62, 0xe2, 0xf2, 0x19, 0x16, + 0x87, 0x56, 0xcc, 0x82, 0x84, 0xbc, 0xea, 0xb7, 0xea, 0xd6, 0x27, 0xd8, 0x45, 0x35, 0xcd, 0x22, + 0xdf, 0x1e, 0x8a, 0xfe, 0x81, 0x05, 0x64, 0xc9, 0x5f, 0xea, 0xcd, 0x53, 0x12, 0x1d, 0xfb, 0x2f, + 0xc9, 0xf6, 0x88, 0xa3, 0x18, 0x10, 0x7d, 0x95, 0xc6, 0xc6, 0x55, 0xc2, 0xff, 0xdd, 0x82, 0xce, + 0xd3, 0xd4, 0x0f, 0x09, 0xcb, 0x70, 0x8e, 0xd9, 0x8d, 0xf7, 0x16, 0x67, 0x1c, 0xae, 0x89, 0xc1, + 0x16, 0xe4, 0xc6, 0x82, 0x56, 0xe3, 0x02, 0x03, 0xc3, 0xd0, 0x4f, 0xdb, 0xd2, 0xcf, 0x45, 0x3a, + 0x35, 0x2c, 0xa1, 0x63, 0x5b, 0x42, 0xc9, 0xcf, 0x8a, 0xe9, 0x1a, 0x94, 0xec, 0xbb, 0x0b, 0x65, + 0x7f, 0x15, 0xfa, 0x44, 0xb4, 0x11, 0x78, 0x96, 0x2c, 0x2c, 0xc1, 0x04, 0x95, 0x41, 0xf2, 0xea, + 0xc5, 0x41, 0xf2, 0x1d, 0x18, 0x04, 0xcc, 0x30, 0x48, 0x3a, 0xf7, 0xd3, 0x5c, 0x98, 0xc2, 0xe2, + 0x44, 0xde, 0xc2, 0xc5, 0x1f, 0xc2, 0x3a, 0x97, 0xfa, 0x83, 0x88, 0x3d, 0x15, 0xe7, 0x46, 0x1a, + 0x20, 0x6a, 0x85, 0x8e, 0x51, 0x2b, 0xc4, 0x77, 0x61, 0xc3, 0x46, 0x96, 0xef, 0xd4, 0x35, 0x58, + 0xc9, 0x19, 0xbc, 0x16, 0x26, 0x73, 0x6c, 0x57, 0x4e, 0xe2, 0x3d, 0x18, 0x32, 0x40, 0x44, 0x5f, + 0x1e, 0x30, 0x72, 0xec, 0x52, 0x76, 0xbf, 0xf5, 0xcf, 0x0e, 0x49, 0x1c, 0xab, 0xac, 0xfc, 0xd8, + 0x3f, 0xf3, 0x58, 0xf2, 0x8a, 0x2e, 0xc1, 0xca, 0xb7, 0xfe, 0xd9, 0x6e, 0xa1, 0xc2, 0x95, 0x2e, + 0x9b, 0x99, 0x15, 0xe7, 0x78, 0x47, 0x9c, 0xa1, 0x24, 0xf2, 0x3a, 0x91, 0xd4, 0xdf, 0x38, 0xb0, + 0x59, 0x59, 0x24, 0x4f, 0x7e, 0x0f, 0x56, 0x38, 0x6b, 0xea, 0xe4, 0x1f, 0x98, 0x27, 0xaf, 0xa1, + 0xdf, 0x14, 0x43, 0x59, 0x99, 0x14, 0x0b, 0xa7, 0x4f, 0xa0, 0x6f, 0x80, 0x1b, 0x9e, 0xfd, 0x0f, + 0xed, 0xca, 0xe4, 0x66, 0xf3, 0x16, 0x46, 0x34, 0xf0, 0x13, 0x18, 0x7c, 0x47, 0x67, 0xbf, 0x40, + 0x3b, 0x1c, 0x5d, 0x81, 0xd5, 0x94, 0xc8, 0xbc, 0x51, 0x06, 0x01, 0x1a, 0x80, 0xc7, 0x30, 0x94, + 0x74, 0x75, 0x03, 0xf5, 0x3b, 0x1a, 0x27, 0xc1, 0xab, 0xd7, 0x6d, 0xa0, 0xfe, 0x14, 0x90, 0xb9, + 0x40, 0x87, 0x29, 0x05, 0x87, 0x56, 0xc2, 0x14, 0x05, 0xe4, 0x61, 0xca, 0xbb, 0xd0, 0x37, 0x51, + 0x44, 0xbf, 0x05, 0x34, 0x02, 0xfe, 0x13, 0x07, 0xc6, 0xcf, 0xa2, 0xfc, 0x28, 0x4c, 0xfd, 0xd3, + 0xd7, 0x50, 0x6a, 0xb5, 0x99, 0xdd, 0xba, 0xa8, 0x99, 0xdd, 0xae, 0x36, 0xb3, 0xfd, 0x38, 0x96, + 0xa9, 0x3c, 0xfb, 0x34, 0x8b, 0x78, 0x43, 0x51, 0xc4, 0xbb, 0x03, 0x13, 0x7d, 0x98, 0x37, 0xab, + 0xe0, 0xdd, 0xb8, 0x0e, 0xab, 0xe5, 0x15, 0x45, 0x5d, 0x68, 0xef, 0x7e, 0xf7, 0xdb, 0x93, 0x25, + 0xd4, 0x83, 0xe5, 0xc3, 0xfd, 0x83, 0x03, 0x51, 0x2c, 0xe7, 0xf5, 0xf3, 0xd6, 0x8d, 0x1b, 0xb0, + 0xcc, 0x1c, 0x02, 0x5a, 0x85, 0xce, 0xd3, 0x7b, 0xdf, 0xec, 0xbb, 0x93, 0x25, 0xf6, 0xf9, 0x2d, + 0xff, 0x74, 0xd0, 0x00, 0x7a, 0x0f, 0x1f, 0x3d, 0xdd, 0x77, 0x1f, 0xdd, 0x3b, 0x98, 0xb4, 0x76, + 0xfe, 0xdd, 0x81, 0xee, 0xf3, 0x22, 0x7c, 0x48, 0xa3, 0x1c, 0xed, 0x03, 0xe8, 0x3e, 0x36, 0xba, + 0x5c, 0x96, 0x78, 0xab, 0xdd, 0xf0, 0xe9, 0xb4, 0x69, 0x4a, 0x6a, 0x7f, 0x09, 0x3d, 0x80, 0xbe, + 0x11, 0x76, 0xa2, 0xe9, 0xe2, 0xf8, 0x78, 0xfa, 0x56, 0xe3, 0x5c, 0x49, 0x69, 0x1f, 0x40, 0x1b, + 0x86, 0x3e, 0x50, 0xcd, 0xba, 0xf4, 0x81, 0xea, 0x76, 0x84, 0x97, 0x76, 0xfe, 0x6e, 0x0b, 0xda, + 0xcf, 0x8b, 0x10, 0x3d, 0x87, 0xbe, 0xf1, 0xfb, 0x0f, 0xaa, 0xb5, 0x4f, 0xf4, 0x71, 0x9a, 0xfe, + 0x12, 0x9a, 0xfe, 0xec, 0x9f, 0xfe, 0xf3, 0x4f, 0x5b, 0x1b, 0x78, 0x7c, 0xeb, 0xe4, 0x57, 0x6f, + 0xf9, 0x61, 0xa8, 0x4c, 0xe6, 0x8e, 0x73, 0x03, 0xb9, 0xd0, 0x95, 0x7f, 0xf8, 0xa0, 0x2d, 0x83, + 0x86, 0x91, 0xc3, 0x4c, 0x2f, 0xd5, 0xe0, 0x92, 0xee, 0x16, 0xa7, 0x3b, 0xc1, 0x7d, 0x49, 0x97, + 0x3d, 0x00, 0x8c, 0xe6, 0x2e, 0xb4, 0x77, 0x7d, 0x8a, 0x90, 0x6e, 0x65, 0xaa, 0xab, 0x3b, 0x5d, + 0xb7, 0x60, 0x92, 0x0e, 0xe2, 0x74, 0x06, 0xb8, 0xcb, 0xe8, 0xcc, 0x7c, 0xca, 0x68, 0x04, 0x30, + 0x30, 0x7f, 0xa7, 0x40, 0xba, 0xa9, 0x5f, 0xff, 0x47, 0x64, 0x7a, 0xa5, 0x79, 0x52, 0x92, 0xdf, + 0xe6, 0xe4, 0x11, 0x9e, 0x30, 0xf2, 0xfc, 0x6f, 0x13, 0xd9, 0x1c, 0x60, 0xcc, 0xcb, 0x7f, 0x28, + 0x34, 0xf3, 0xf6, 0x2f, 0x18, 0x9a, 0xf9, 0xea, 0xcf, 0x16, 0x16, 0xf3, 0xd2, 0xa3, 0xb0, 0x83, + 0x7f, 0x0f, 0xc3, 0x67, 0xfc, 0xbf, 0x1f, 0xd9, 0xb9, 0xd7, 0x94, 0xed, 0xc6, 0xbf, 0xa6, 0x5c, + 0x69, 0xf1, 0xe3, 0x2b, 0x9c, 0xf2, 0x16, 0x5e, 0x63, 0x94, 0xc5, 0x3f, 0x44, 0xa1, 0x40, 0x61, + 0xf4, 0x7f, 0x0f, 0x86, 0x56, 0x93, 0x1e, 0x95, 0xcc, 0x37, 0x75, 0xff, 0xa7, 0x6f, 0x2f, 0x98, + 0x6d, 0xda, 0x2b, 0x94, 0x28, 0xbc, 0xad, 0xcf, 0xf6, 0x7a, 0x0e, 0xa0, 0x9b, 0xdd, 0xda, 0x8a, + 0x6b, 0x0d, 0x76, 0x6d, 0xc5, 0xf5, 0xde, 0x38, 0x5e, 0xe7, 0x5b, 0x0c, 0x51, 0x5f, 0x68, 0x57, + 0xd0, 0x3a, 0x80, 0xae, 0x6c, 0xeb, 0x6a, 0xf9, 0xd8, 0xbd, 0x6d, 0x2d, 0x9f, 0x4a, 0xff, 0x17, + 0x4f, 0x38, 0x41, 0x40, 0x3d, 0x46, 0x30, 0x62, 0x24, 0x7e, 0x07, 0xfa, 0x46, 0xa7, 0x13, 0x99, + 0xa7, 0xa9, 0xb4, 0x4f, 0xf5, 0x45, 0x69, 0x68, 0x8d, 0xe2, 0x0d, 0x4e, 0x79, 0x84, 0x06, 0x8c, + 0x32, 0x93, 0x02, 0xa7, 0xfe, 0x0c, 0x40, 0x37, 0xe5, 0xb4, 0x14, 0x6a, 0xdd, 0x45, 0x2d, 0x85, + 0x7a, 0x0f, 0x4f, 0xd9, 0x38, 0x02, 0x46, 0x5a, 0x96, 0xae, 0x5f, 0xc2, 0xc8, 0xee, 0x99, 0xa2, + 0xb7, 0x4d, 0x0a, 0xb5, 0x26, 0xeb, 0xf4, 0x9d, 0x45, 0xd3, 0xb6, 0x4d, 0xa2, 0x11, 0xb7, 0x49, + 0x4d, 0xf6, 0x10, 0x56, 0xcb, 0x6e, 0x1e, 0xda, 0x36, 0x89, 0x98, 0x4d, 0xbf, 0xe9, 0xe5, 0x86, + 0x19, 0x49, 0x79, 0x8d, 0x53, 0xee, 0xa3, 0x55, 0x46, 0x59, 0x14, 0x75, 0x15, 0x51, 0xfe, 0x13, + 0x80, 0x4d, 0xd4, 0x68, 0x05, 0x56, 0x88, 0x9a, 0x0d, 0xc1, 0x0a, 0x51, 0x4e, 0xc7, 0x83, 0xbe, + 0xd1, 0x2b, 0xd2, 0x9a, 0xac, 0x37, 0xba, 0xb4, 0x26, 0x1b, 0x9a, 0x4b, 0xf8, 0x12, 0x27, 0xbd, + 0x26, 0x5c, 0x5e, 0x32, 0x27, 0x54, 0x5d, 0xf9, 0xdf, 0x05, 0xd0, 0xe5, 0x3d, 0xad, 0xcc, 0x5a, + 0xe1, 0x57, 0x9b, 0x5f, 0xa5, 0x1a, 0x88, 0x2f, 0x73, 0xd2, 0xeb, 0x98, 0x0b, 0x99, 0x97, 0x5c, + 0xb9, 0x3a, 0xef, 0x38, 0x37, 0x6e, 0x3b, 0xe8, 0x05, 0x8c, 0x34, 0xfe, 0xe1, 0x39, 0x0d, 0x2e, + 0xda, 0x62, 0xda, 0x34, 0x25, 0x19, 0x78, 0x9b, 0xef, 0x72, 0x09, 0x23, 0x7b, 0x97, 0xec, 0x9c, + 0x06, 0xec, 0x66, 0xfe, 0x14, 0xfa, 0xc6, 0x2f, 0x37, 0x5a, 0x4e, 0xf5, 0xff, 0x70, 0xa6, 0x4d, + 0x05, 0x48, 0xfb, 0x49, 0x90, 0x21, 0x76, 0x76, 0xea, 0xcf, 0x19, 0x6d, 0x0a, 0x23, 0xbb, 0xce, + 0xa6, 0xcd, 0xb2, 0xb1, 0x68, 0xa7, 0xcd, 0x72, 0x41, 0x79, 0xce, 0xe2, 0x85, 0x37, 0x37, 0x88, + 0xf9, 0x04, 0xcd, 0xd8, 0xab, 0x5b, 0xd6, 0xdb, 0xcc, 0x57, 0xb7, 0x5a, 0xd2, 0x33, 0x5f, 0xdd, + 0x5a, 0x81, 0xce, 0xe6, 0x49, 0x6c, 0xa3, 0x34, 0x83, 0xbe, 0x07, 0xd0, 0xd5, 0x36, 0xad, 0x93, + 0x5a, 0xc1, 0x6e, 0x3a, 0x6d, 0x9a, 0x92, 0x1b, 0x58, 0x9a, 0x17, 0x1b, 0xa8, 0x27, 0xef, 0x27, + 0xd0, 0x53, 0x65, 0x23, 0x54, 0x5a, 0x4e, 0xa5, 0xb6, 0x34, 0xdd, 0xae, 0x4f, 0x54, 0xcc, 0x95, + 0x3b, 0x9e, 0x4c, 0xce, 0x32, 0xba, 0x04, 0xc6, 0x95, 0xd2, 0x13, 0x2a, 0xa5, 0xdd, 0x5c, 0x93, + 0x9a, 0xda, 0x7f, 0xd8, 0x88, 0x7e, 0x15, 0x7e, 0x8b, 0x6f, 0xb0, 0x89, 0xd6, 0xf9, 0x06, 0x6a, + 0xa1, 0x30, 0xa9, 0xdb, 0x0e, 0x9a, 0x57, 0x4a, 0x51, 0xb2, 0xa6, 0x61, 0x38, 0xa4, 0xc6, 0x4a, + 0xd5, 0xb4, 0xa9, 0xcc, 0x8c, 0x7f, 0xc4, 0xf7, 0x7a, 0x0b, 0x5d, 0xb6, 0xf6, 0x62, 0xd6, 0xa5, + 0xaa, 0xec, 0xb7, 0x1d, 0x34, 0x83, 0x91, 0x4d, 0xf2, 0x8d, 0xb6, 0xaa, 0x98, 0x31, 0x42, 0xb5, + 0xad, 0xd8, 0x1e, 0x7f, 0x60, 0xd4, 0xed, 0xac, 0x0a, 0x1c, 0xba, 0xd6, 0xbc, 0x57, 0xa5, 0x42, + 0x37, 0xdd, 0x30, 0xf7, 0x54, 0x93, 0x18, 0xf3, 0x4d, 0xaf, 0xa0, 0x69, 0x7d, 0x53, 0x5f, 0xe2, + 0x70, 0x4f, 0x30, 0x30, 0x73, 0x43, 0x1d, 0xc0, 0x34, 0xa4, 0x97, 0x3a, 0x80, 0x69, 0x4a, 0x27, + 0x95, 0xf2, 0x44, 0x00, 0xc3, 0x73, 0xc7, 0x23, 0x81, 0xc1, 0x2c, 0xe4, 0x65, 0x35, 0x89, 0xbc, + 0xb2, 0x20, 0x65, 0xab, 0xc4, 0x03, 0x8d, 0x09, 0x9d, 0x32, 0x71, 0xb4, 0xa6, 0xb6, 0x8a, 0xe8, + 0x4b, 0x91, 0xd7, 0xa1, 0xaf, 0xa1, 0xc3, 0xb3, 0x25, 0xb4, 0xa1, 0x43, 0x56, 0x9d, 0x94, 0x4d, + 0x37, 0x2b, 0x50, 0xfb, 0x49, 0xc5, 0xdc, 0xc7, 0x17, 0x54, 0x46, 0x77, 0x33, 0x18, 0x89, 0x20, + 0x49, 0xe5, 0x14, 0xfa, 0xd2, 0x54, 0x52, 0x1e, 0x7d, 0x69, 0xaa, 0xe9, 0x87, 0xed, 0x56, 0x44, + 0x9c, 0x74, 0x2a, 0x71, 0xee, 0x38, 0x37, 0x66, 0x2b, 0xfc, 0xcf, 0xf9, 0x4f, 0xfe, 0x37, 0x00, + 0x00, 0xff, 0xff, 0xd8, 0xb0, 0x15, 0x00, 0x64, 0x2f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used.