UNPKG

@nfid/identitykit

Version:

A React library for adding wallet connections to dApps.

503 lines (494 loc) 55 kB
'use client'; export { SignerAgent } from '@slide-computer/signer-agent'; import { Principal } from '@dfinity/principal'; import { AnonymousIdentity } from '@dfinity/agent'; import { Ed25519KeyIdentity, ECDSAKeyIdentity, isDelegationValid, PartialIdentity, PartialDelegationIdentity, DelegationIdentity, DelegationChain, Delegation } from '@dfinity/identity'; import { IdbStorage, getIdentity, getDelegationChain, setIdentity, setDelegationChain, removeIdentity, removeDelegationChain } from '@slide-computer/signer-storage'; import { SubAccount, LedgerCanister, AccountIdentifier } from '@dfinity/ledger-icp'; import { toBase64, fromBase64 } from '@slide-computer/signer'; export { fromBase64, toBase64 } from '@slide-computer/signer'; class Agent { signerAgentStrategy; agentStrategy; delegation; constructor(signerAgentStrategy, agentStrategy, delegation) { this.signerAgentStrategy = signerAgentStrategy; this.agentStrategy = agentStrategy; this.delegation = delegation; } static async create({ delegation, signerAgent, agent }) { return new Agent(signerAgent, agent, delegation); } async call(...params) { const delegationTargets = this.delegation?.targets; const strategy = this.delegation && (!delegationTargets?.length || delegationTargets?.find((t) => t.compareTo(Principal.from(params[0])) === "eq")) ? this.agentStrategy : this.signerAgentStrategy; return strategy.call(...params); } async query(...params) { const delegationTargets = this.delegation?.targets; const strategy = this.delegation && (!delegationTargets?.length || delegationTargets?.find((t) => t.compareTo(Principal.from(params[0])) === "eq")) ? this.agentStrategy : this.signerAgentStrategy; return strategy.query(...params); } get rootKey() { return this.agentStrategy.rootKey; } async fetchRootKey() { return this.agentStrategy.fetchRootKey(); } async getPrincipal() { return this.agentStrategy.getPrincipal(); } async status() { return this.agentStrategy.status(); } async readState(...params) { const delegationTargets = this.delegation?.targets; const strategy = this.delegation && (!delegationTargets?.length || delegationTargets?.find((t) => t.compareTo(Principal.from(params[0])) === "eq")) ? this.agentStrategy : this.signerAgentStrategy; return strategy.readState(...params); } async createReadStateRequest(...params) { return this.agentStrategy.createReadStateRequest?.(...params); } } const DEFAULT_MAX_TIME_TO_LIVE = BigInt(1.8e12); // 30 min const DEFAULT_IDLE_TIMEOUT = 14_400_000; // 4 hours const TIMEOUT_MAX_DELAY = 2147483647; /** * Detects if the `timeout` ms is over, and calls `onTimeout` and registered callbacks. * To override these defaults, you can pass an `onTimeout` callback, or configure a custom `timeout` in milliseconds */ class TimeoutManager { callbacks = []; timeout; timeoutID = undefined; /** * @param options {@link IdleManagerOptions} */ constructor(options) { const { onTimeout, timeout } = options || {}; this.callbacks = onTimeout ? [onTimeout] : []; this.timeout = timeout > TIMEOUT_MAX_DELAY ? TIMEOUT_MAX_DELAY : timeout; const _resetTimer = this._resetTimer.bind(this); window.addEventListener("load", _resetTimer, true); _resetTimer(); } /** * @param {TimeoutCB} callback function to be called on timeout */ registerCallback(callback) { this.callbacks.push(callback); } /** * Cleans up the timeout manager and its listeners */ exit() { clearTimeout(this.timeoutID); window.removeEventListener("load", this._resetTimer, true); } /** * Resets the timeouts during cleanup */ _resetTimer() { window.clearTimeout(this.timeoutID); this.timeoutID = window.setTimeout(() => { this.callbacks.forEach((cb) => cb()); }, this.timeout); } } const events = ["mousedown", "mousemove", "keydown", "touchstart", "wheel"]; /** * Detects if the user has been idle for a duration of `idleTimeout` ms, and calls `onIdle` and registered callbacks. * By default, the IdleManager will log a user out after 10 minutes of inactivity. * To override these defaults, you can pass an `onIdle` callback, or configure a custom `idleTimeout` in milliseconds */ class IdleManager extends TimeoutManager { constructor(options = {}) { super({ timeout: options.idleTimeout || DEFAULT_IDLE_TIMEOUT, onTimeout: options.onIdle }); const _resetTimer = this._resetTimer.bind(this); events.forEach(function (name) { document.addEventListener(name, _resetTimer, true); }); const debounce = (func, wait) => { let timeout; return (...args) => { // eslint-disable-next-line @typescript-eslint/no-this-alias const context = this; const later = function () { timeout = undefined; func.apply(context, args); }; clearTimeout(timeout); timeout = window.setTimeout(later, wait); }; }; if (options?.captureScroll) { // debounce scroll events const scroll = debounce(_resetTimer, options?.scrollDebounce ?? 100); window.addEventListener("scroll", scroll, true); } } } const STORAGE_KEY = "client"; const STORAGE_CONNECTED_OWNER_KEY = "connected-owner"; const STORAGE_CONNECTED_SUBACCOUNT_KEY = "connected-subaccount"; class SignerClient { options; idleManager; storage = new IdbStorage(); connectedUser; constructor(options) { this.options = options; if (!options?.idleOptions?.disableIdle) { this.idleManager = new IdleManager(options.idleOptions); this.registerDefaultIdleCallback(); } if (options.storage) this.storage = options.storage; } registerDefaultIdleCallback() { /** * Default behavior is to clear stored identity and reload the page. * By either setting the disableDefaultIdleCallback flag or passing in a custom idle callback, we will ignore this config */ if (!this.options?.idleOptions?.disableDefaultIdleCallback) { this.idleManager?.registerCallback(async () => { await this.logout(); }); } } async logout(options) { await this.setConnectedUserToStorage(undefined); this.idleManager?.exit(); this.idleManager = undefined; await this.options.onLogout?.(); if (options?.returnTo) { try { window.history.pushState({}, "", options.returnTo); } catch (e) { window.location.href = options.returnTo; } } } async setConnectedUser(user) { if (!user) this.connectedUser = undefined; else { let subAccount; if (user.subAccount) { const subAccountOrError = SubAccount.fromBytes(new Uint8Array(user.subAccount)); if (typeof subAccountOrError === typeof Error) { throw subAccount; } subAccount = subAccountOrError; } this.connectedUser = { principal: Principal.from(user.owner), subAccount, }; } } async setConnectedUserToStorage(user) { if (!user) { await this.storage.remove(STORAGE_CONNECTED_OWNER_KEY); await this.storage.remove(STORAGE_CONNECTED_SUBACCOUNT_KEY); localStorage.removeItem("connected"); this.setConnectedUser(undefined); return; } await this.storage.set(STORAGE_CONNECTED_OWNER_KEY, user.owner); localStorage.setItem("connected", "1"); if (user.subAccount) await this.storage.set(STORAGE_CONNECTED_SUBACCOUNT_KEY, new TextDecoder().decode(user.subAccount)); this.setConnectedUser({ owner: user.owner, subAccount: user.subAccount, }); } // sync method to check if it's needed to check authorization reading from async storage static shouldCheckIsUserConnected() { return !!localStorage.getItem("connected"); } async getConnectedUserFromStorage() { const owner = await this.storage.get(STORAGE_CONNECTED_OWNER_KEY); if (!owner) return; const subAccount = await this.storage.get(STORAGE_CONNECTED_SUBACCOUNT_KEY); return { owner: owner.toString(), subAccount: subAccount ? new TextEncoder().encode(subAccount.toString()).buffer : undefined, }; } get crypto() { return this.options.crypto ?? globalThis.crypto; } } const ED25519_KEY_LABEL = "Ed25519"; var DelegationType; (function (DelegationType) { DelegationType["ACCOUNT"] = "ACCOUNT"; DelegationType["RELYING_PARTY"] = "RELYING_PARTY"; })(DelegationType || (DelegationType = {})); const NANOS_IN_MILLIS = BigInt(1000000); class DelegationSignerClient extends SignerClient { identity; baseIdentity; targets; maxTimeToLive; expirationManager; constructor(options, identity, baseIdentity, targets, maxTimeToLive = BigInt(DEFAULT_MAX_TIME_TO_LIVE)) { // TODO for delegation use delegation expiration as idle timeout super(options); this.identity = identity; this.baseIdentity = baseIdentity; this.targets = targets; this.maxTimeToLive = maxTimeToLive; } static async create(options) { const storage = options.storage ?? new IdbStorage(); let baseIdentity = options.identity; let identity = new AnonymousIdentity(); if (this.shouldCheckIsUserConnected() && !baseIdentity) { baseIdentity = await getIdentity(STORAGE_KEY, storage); } if (!baseIdentity) { const createdBaseIdentity = await (!options?.keyType || options?.keyType === ED25519_KEY_LABEL ? Ed25519KeyIdentity.generate(crypto.getRandomValues(new Uint8Array(32))) : ECDSAKeyIdentity.generate()); baseIdentity = createdBaseIdentity; } if (this.shouldCheckIsUserConnected()) { const delegationChain = await getDelegationChain(STORAGE_KEY, storage); const delegationValid = baseIdentity && delegationChain && isDelegationValid(delegationChain); identity = delegationValid ? DelegationSignerClient.createIdentity(baseIdentity, delegationChain) : new AnonymousIdentity(); const signerClient = new DelegationSignerClient(options, identity, baseIdentity, options.targets, options.maxTimeToLive); if (delegationValid) { signerClient.initExpirationManager(delegationChain); const storageConnectedUser = await signerClient.getConnectedUserFromStorage(); await signerClient.setConnectedUser(storageConnectedUser); } else { await signerClient.setConnectedUserToStorage(undefined); await signerClient.setConnectedUser(undefined); } return signerClient; } const signerClient = new DelegationSignerClient(options, identity, baseIdentity, options.targets, options.maxTimeToLive); return signerClient; } static createIdentity(baseIdentity, delegationChain) { if (baseIdentity instanceof PartialIdentity) { return PartialDelegationIdentity.fromDelegation(baseIdentity, delegationChain); } return DelegationIdentity.fromDelegation(baseIdentity, delegationChain); } async login() { const params = this.options.derivationOrigin ? { icrc95DerivationOrigin: this.options.derivationOrigin, } : {}; const delegationChainResponse = await this.options.signer.sendRequest({ id: this.crypto.randomUUID(), jsonrpc: "2.0", method: "icrc34_delegation", params: { ...params, publicKey: toBase64(this.baseIdentity.getPublicKey().toDer()), targets: this.targets, maxTimeToLive: this.maxTimeToLive === undefined ? undefined : String(this.maxTimeToLive), }, }); if ("error" in delegationChainResponse) { throw Error(delegationChainResponse.error.message); } const delegationChain = DelegationChain.fromDelegations(delegationChainResponse.result.signerDelegation.map((delegation) => { return { delegation: new Delegation(fromBase64(delegation.delegation.pubkey), BigInt(delegation.delegation.expiration), delegation.delegation.targets?.map((principal) => Principal.fromText(principal))), signature: fromBase64(delegation.signature), }; }), fromBase64(delegationChainResponse.result.publicKey)); if (this.baseIdentity instanceof Ed25519KeyIdentity || this.baseIdentity instanceof ECDSAKeyIdentity) { await setIdentity(STORAGE_KEY, this.baseIdentity, this.storage); } await setDelegationChain(STORAGE_KEY, delegationChain, this.storage); this.identity = DelegationSignerClient.createIdentity(this.baseIdentity, delegationChain); await this.setConnectedUserToStorage({ owner: this.identity.getPrincipal().toString() }); if (!this.options?.idleOptions?.disableIdle && !this.idleManager) { this.idleManager = new IdleManager(this.options.idleOptions); this.registerDefaultIdleCallback(); } return this.initExpirationManager(delegationChain); } initExpirationManager(delegationChain) { if (!this.expirationManager) { const delegationExpirationInMillis = Number(delegationChain.delegations.reduce((acc, value) => { const bigIntValue = BigInt(value.delegation.expiration) / NANOS_IN_MILLIS; return bigIntValue > acc ? bigIntValue : acc; }, BigInt(delegationChain.delegations[0].delegation.expiration) / NANOS_IN_MILLIS)) - Date.now(); this.expirationManager = new TimeoutManager({ timeout: delegationExpirationInMillis }); this.expirationManager?.registerCallback(async () => { await this.logout(); }); } } async logout(options) { await Promise.all([ removeIdentity(STORAGE_KEY, this.storage), removeDelegationChain(STORAGE_KEY, this.storage), ]); this.identity = new AnonymousIdentity(); return super.logout(options); } getIdentity() { return this.identity; } async getDelegationType() { if (!this.connectedUser) throw new Error("Not authorized"); const delegationChain = await getDelegationChain(STORAGE_KEY, this.storage); if (!delegationChain) throw new Error("Not authorized"); return delegationChain.delegations[0].delegation.targets?.length ? DelegationType.ACCOUNT : DelegationType.RELYING_PARTY; } async getDelegation() { const chain = await getDelegationChain(STORAGE_KEY, this.storage); return chain?.delegations[0]; } } class AccountsSignerClient extends SignerClient { static async create(options) { const signerClient = new AccountsSignerClient(options); if (SignerClient.shouldCheckIsUserConnected()) { const storageConnectedUser = await signerClient.getConnectedUserFromStorage(); await signerClient.setConnectedUser(storageConnectedUser); } return signerClient; } async login() { // get and transform accounts from signer const params = this.options.derivationOrigin ? { params: { icrc95DerivationOrigin: this.options.derivationOrigin, }, } : {}; const accountsResponse = await this.options.signer.sendRequest({ method: "icrc27_accounts", id: this.crypto.randomUUID(), jsonrpc: "2.0", ...params, }); if ("error" in accountsResponse) { throw Error(accountsResponse.error.message); } const accounts = accountsResponse.result.accounts.map(({ owner, subaccount }) => { return { owner: Principal.fromText(owner), subaccount: subaccount === undefined ? undefined : fromBase64(subaccount), }; }); await this.setAccounts(accounts); const account = accounts[0]; if (!account.subaccount) { if (!this.options?.idleOptions?.disableIdle && !this.idleManager) { this.idleManager = new IdleManager(this.options.idleOptions); this.registerDefaultIdleCallback(); } await this.setConnectedUserToStorage({ owner: account.owner.toString() }); return; } await this.setConnectedUserToStorage({ owner: account.owner.toString(), subAccount: account.subaccount, }); if (!this.options?.idleOptions?.disableIdle && !this.idleManager) { this.idleManager = new IdleManager(this.options.idleOptions); this.registerDefaultIdleCallback(); } } async logout(options) { await this.storage.remove(`accounts-${STORAGE_KEY}`); return super.logout(options); } async setAccounts(accounts) { return this.storage.set(`accounts-${STORAGE_KEY}`, JSON.stringify(accounts.map((acc) => ({ owner: acc.owner.toString(), subaccount: acc.subaccount && new TextDecoder().decode(acc.subaccount), })))); } async getAccounts() { const storageData = await this.storage.get(`accounts-${STORAGE_KEY}`); if (!storageData || typeof storageData !== "string") return; return JSON.parse(storageData).map(({ owner, subaccount }) => { let subAccount; if (subaccount) { const subAccountOrError = SubAccount.fromBytes(new Uint8Array(new TextEncoder().encode(subaccount))); if (typeof subAccountOrError === typeof Error) { throw subAccount; } subAccount = subAccountOrError; } return { principal: Principal.from(owner), subAccount, }; }); } } var TransportType; (function (TransportType) { TransportType[TransportType["NEW_TAB"] = 0] = "NEW_TAB"; TransportType[TransportType["EXTENSION"] = 1] = "EXTENSION"; TransportType[TransportType["INTERNET_IDENTITY"] = 2] = "INTERNET_IDENTITY"; TransportType[TransportType["STOIC"] = 3] = "STOIC"; })(TransportType || (TransportType = {})); const NFIDW = { id: "NFIDW", description: "Quickly sign in or create an anonymous, self-sovereign wallet with your email address or passkey.", providerUrl: "https://nfid.one/rpc", transportType: TransportType.NEW_TAB, label: "NFID Wallet", icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIHZpZXdCb3g9IjAgMCA2NCA2NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS45MDIyIDMuMTU2MjlDMTYuNzcxNCAzLjA2MzYzIDE3LjQwMDggMi4yODM5OCAxNy4zMDgxIDEuNDE0ODlDMTcuMjE1NSAwLjU0NTgwOSAxNi40MzU4IC0wLjA4MzYwOTkgMTUuNTY2NyAwLjAwOTA0OTQ2TDEyLjMzNDUgMC4zNTM2MzNDMTAuNjc4NiAwLjUzMDE2NSA5LjM1MDQ2IDAuNjcxNzUxIDguMjcxOCAwLjg2NzMwNkM3LjE2MDYgMS4wNjg3NiA2LjIwODI3IDEuMzQ0MTQgNS4zMjM3OCAxLjgzOTgxQzMuODg3NzMgMi42NDQ1NyAyLjY5NzE5IDMuODIzODUgMS44Nzk0NCA1LjI1MTk2QzEuMzc1NjggNi4xMzE3MyAxLjA5MjA0IDcuMDgxMTIgMC44ODExODUgOC4xODk2MUMwLjY3NjUzNSA5LjI2NTQ5IDAuNTIzODkzIDEwLjU5MSAwLjMzMzYyMSAxMi4yNDMyTDAuMzI1NDI0IDEyLjMxNDRMMC4wMDgwNjAwNiAxNS40NzA0Qy0wLjA3OTM4NzUgMTYuMzQgMC41NTQ3MjYgMTcuMTE1OSAxLjQyNDM5IDE3LjIwMzRDMi4yOTQwNiAxNy4yOTA4IDMuMDY5OTUgMTYuNjU2NyAzLjE1NzQgMTUuNzg3MUwzLjQ3MjQ4IDEyLjY1MzhDMy42NzA1NCAxMC45MzQgMy44MTA2NiA5LjcyNzMgMy45OTA2NiA4Ljc4MTAzQzQuMTY3MzEgNy44NTIzNSA0LjM2NDQ5IDcuMjgxODEgNC42MjYyNiA2LjgyNDY3QzUuMTU5MDEgNS44OTQyNyA1LjkzNDg3IDUuMTI1NTkgNi44NzEyMSA0LjYwMDg2QzcuMzMxNTEgNC4zNDI5MSA3LjkwNDg2IDQuMTUwNTEgOC44MzY0NiAzLjk4MTYxQzkuNzg3NjYgMy44MDkxNiAxMS4wMDA1IDMuNjc4ODggMTIuNzI5OSAzLjQ5NDVMMTUuOTAyMiAzLjE1NjI5Wk00Ni42OTE5IDEuNDE0ODlDNDYuNTk5MiAyLjI4Mzk4IDQ3LjIyODYgMy4wNjM2MyA0OC4wOTc4IDMuMTU2MjlMNTEuMjcwMSAzLjQ5NDVDNTIuOTk5NSAzLjY3ODg4IDU0LjIxMjMgMy44MDkxNiA1NS4xNjM1IDMuOTgxNjFDNTYuMDk1MSA0LjE1MDUxIDU2LjY2ODUgNC4zNDI5MSA1Ny4xMjg4IDQuNjAwODZDNTguMDY1MSA1LjEyNTU5IDU4Ljg0MSA1Ljg5NDI3IDU5LjM3MzcgNi44MjQ2N0M1OS42MzU1IDcuMjgxODEgNTkuODMyNyA3Ljg1MjM1IDYwLjAwOTMgOC43ODEwM0M2MC4xODkzIDkuNzI3MyA2MC4zMjk1IDEwLjkzNCA2MC41Mjc1IDEyLjY1MzhMNjAuODQyNiAxNS43ODcxQzYwLjkzIDE2LjY1NjcgNjEuNzA1OSAxNy4yOTA4IDYyLjU3NTYgMTcuMjAzNEM2My40NDUzIDE3LjExNTkgNjQuMDc5NCAxNi4zNCA2My45OTE5IDE1LjQ3MDRMNjMuNjc0NiAxMi4zMTQ0TDYzLjY2NjQgMTIuMjQzMkM2My40NzYxIDEwLjU5MSA2My4zMjM1IDkuMjY1NDkgNjMuMTE4OCA4LjE4OTYxQzYyLjkwOCA3LjA4MTEyIDYyLjYyNDMgNi4xMzE3MyA2Mi4xMjA2IDUuMjUxOTZDNjEuMzAyOCAzLjgyMzg1IDYwLjExMjMgMi42NDQ1NyA1OC42NzYyIDEuODM5ODFDNTcuNzkxNyAxLjM0NDE0IDU2LjgzOTQgMS4wNjg3NiA1NS43MjgyIDAuODY3MzA2QzU0LjY0OTUgMC42NzE3NTEgNTMuMzIxNCAwLjUzMDE2NSA1MS42NjU1IDAuMzUzNjMzTDQ4LjQzMzMgMC4wMDkwNDk0NkM0Ny41NjQyIC0wLjA4MzYwOTkgNDYuNzg0NSAwLjU0NTgwOSA0Ni42OTE5IDEuNDE0ODlaTTQ2LjY5MTkgNjIuNTg1MUM0Ni41OTkyIDYxLjcxNiA0Ny4yMjg2IDYwLjkzNjQgNDguMDk3OCA2MC44NDM3TDUxLjI3MDEgNjAuNTA1NUM1Mi45OTk1IDYwLjMyMTEgNTQuMjEyMyA2MC4xOTA4IDU1LjE2MzUgNjAuMDE4NEM1Ni4wOTUxIDU5Ljg0OTUgNTYuNjY4NSA1OS42NTcxIDU3LjEyODggNTkuMzk5MUM1OC4wNjUxIDU4Ljg3NDQgNTguODQxIDU4LjEwNTcgNTkuMzczNyA1Ny4xNzUzQzU5LjYzNTUgNTYuNzE4MiA1OS44MzI3IDU2LjE0NzYgNjAuMDA5MyA1NS4yMTlDNjAuMTg5MyA1NC4yNzI3IDYwLjMyOTUgNTMuMDY2IDYwLjUyNzUgNTEuMzQ2Mkw2MC44NDI2IDQ4LjIxMjlDNjAuOTMgNDcuMzQzMyA2MS43MDU5IDQ2LjcwOTIgNjIuNTc1NiA0Ni43OTY2QzYzLjQ0NTMgNDYuODg0MSA2NC4wNzk0IDQ3LjY2IDYzLjk5MTkgNDguNTI5Nkw2My42NzQ2IDUxLjY4NTZMNjMuNjY2NCA1MS43NTY4QzYzLjQ3NjEgNTMuNDA5IDYzLjMyMzUgNTQuNzM0NSA2My4xMTg4IDU1LjgxMDRDNjIuOTA4IDU2LjkxODkgNjIuNjI0MyA1Ny44NjgzIDYyLjEyMDYgNTguNzQ4QzYxLjMwMjggNjAuMTc2MiA2MC4xMTIzIDYxLjM1NTQgNTguNjc2MiA2Mi4xNjAyQzU3Ljc5MTcgNjIuNjU1OSA1Ni44Mzk0IDYyLjkzMTIgNTUuNzI4MiA2My4xMzI3QzU0LjY0OTYgNjMuMzI4MiA1My4zMjE2IDYzLjQ2OTggNTEuNjY1OCA2My42NDYzTDUxLjY2NTYgNjMuNjQ2M0w1MS42NjU1IDYzLjY0NjRMNTEuNjY1NSA2My42NDY0TDQ4LjQzMzMgNjMuOTkxQzQ3LjU2NDIgNjQuMDgzNiA0Ni43ODQ1IDYzLjQ1NDIgNDYuNjkxOSA2Mi41ODUxWk0xNy4zMDgxIDYyLjU4NTZDMTcuNDAwOCA2MS43MTY1IDE2Ljc3MTQgNjAuOTM2OSAxNS45MDIyIDYwLjg0NDJMMTIuNzI5OSA2MC41MDZDMTEuMDAwNSA2MC4zMjE2IDkuNzg3NjYgNjAuMTkxMyA4LjgzNjQ2IDYwLjAxODlDNy45MDQ4NiA1OS44NSA3LjMzMTUxIDU5LjY1NzYgNi44NzEyMSA1OS4zOTk2QzUuOTM0ODcgNTguODc0OSA1LjE1OTAxIDU4LjEwNjIgNC42MjYyNiA1Ny4xNzU4QzQuMzY0NDkgNTYuNzE4NyA0LjE2NzMxIDU2LjE0ODEgMy45OTA2NiA1NS4yMTk1QzMuODEwNjYgNTQuMjczMiAzLjY3MDU0IDUzLjA2NjUgMy40NzI0OCA1MS4zNDY3TDMuMTU3NCA0OC4yMTM0QzMuMDY5OTUgNDcuMzQzOCAyLjI5NDA2IDQ2LjcwOTcgMS40MjQzOSA0Ni43OTcxQzAuNTU0NzI2IDQ2Ljg4NDYgLTAuMDc5Mzg3NSA0Ny42NjA0IDAuMDA4MDYwMDYgNDguNTMwMUwwLjMyNTQyNCA1MS42ODYxTDAuMzMzNjIxIDUxLjc1NzNDMC41MjM4OTMgNTMuNDA5NSAwLjY3NjUzNSA1NC43MzUgMC44ODExODUgNTUuODEwOUMxLjA5MjA0IDU2LjkxOTQgMS4zNzU2OCA1Ny44Njg4IDEuODc5NDQgNTguNzQ4NUMyLjY5NzE5IDYwLjE3NjYgMy44ODc3MyA2MS4zNTU5IDUuMzIzNzggNjIuMTYwN0M2LjIwODI3IDYyLjY1NjMgNy4xNjA2IDYyLjkzMTcgOC4yNzE4IDYzLjEzMzJDOS4zNTA0NCA2My4zMjg3IDEwLjY3ODYgNjMuNDcwMyAxMi4zMzQ1IDYzLjY0NjhMMTIuMzM0NSA2My42NDY5TDE1LjU2NjcgNjMuOTkxNEMxNi40MzU4IDY0LjA4NDEgMTcuMjE1NSA2My40NTQ3IDE3LjMwODEgNjIuNTg1NlpNMTYuNDUxMiAxOS43OTU0QzE1LjY5NTUgMTkuNzk1NCAxNS4wODI4IDIwLjQwODEgMTUuMDgyOCAyMS4xNjM4VjQzLjI5NzJDMTUuMDgyOCA0NC4wNTMgMTUuNjk1NSA0NC42NjU2IDE2LjQ1MTIgNDQuNjY1NkgyMC43NDk0QzIxLjUwNTIgNDQuNjY1NiAyMi4xMTc4IDQ0LjA1MyAyMi4xMTc4IDQzLjI5NzJWMjEuMTYzOEMyMi4xMTc4IDIwLjQwODEgMjEuNTA1MiAxOS43OTU0IDIwLjc0OTQgMTkuNzk1NEgxNi40NTEyWk0yOC4xMDgyIDE5Ljc5NTRDMjcuMzUyNSAxOS43OTU0IDI2LjczOTggMjAuNDA4MSAyNi43Mzk4IDIxLjE2MzhWNDMuMjk3MkMyNi43Mzk4IDQ0LjA1MyAyNy4zNTI1IDQ0LjY2NTYgMjguMTA4MiA0NC42NjU2SDM4LjUwMDRDNDEuMjI0NCA0NC42NjU2IDQzLjY0MDUgNDQuMTU2NCA0NS43NDg3IDQzLjEzNzlDNDcuODU2OCA0Mi4xMTk0IDQ5LjQ5MTIgNDAuNjc0NiA1MC42NTE5IDM4LjgwMzRDNTEuODEyNSAzNi45MzIyIDUyLjM5MjkgMzQuNzQxMiA1Mi4zOTI5IDMyLjIzMDVDNTIuMzkyOSAyOS43MTk4IDUxLjgxMjUgMjcuNTI4OSA1MC42NTE5IDI1LjY1NzdDNDkuNDkxMiAyMy43ODY1IDQ3Ljg1NjggMjIuMzQxNyA0NS43NDg3IDIxLjMyMzJDNDMuNjQwNSAyMC4zMDQ3IDQxLjIyNDQgMTkuNzk1NCAzOC41MDA0IDE5Ljc5NTRIMjguMTA4MlpNNDMuMzMyNiAzNy4yNDAxQzQyLjA1MzUgMzguNDQ4MSA0MC4zNDggMzkuMDUyMSAzOC4yMTYyIDM5LjA1MjFIMzQuMTg1NEMzMy45NTg3IDM5LjA1MjEgMzMuNzc0OSAzOC44NjgzIDMzLjc3NDkgMzguNjQxNlYyNS44MTk1QzMzLjc3NDkgMjUuNTkyOCAzMy45NTg3IDI1LjQwOSAzNC4xODU0IDI1LjQwOUgzOC4yMTYyQzQwLjM0OCAyNS40MDkgNDIuMDUzNSAyNi4wMTMgNDMuMzMyNiAyNy4yMjFDNDQuNjM1NCAyOC40Mjg5IDQ1LjI4NjggMzAuMDk4OCA0NS4yODY4IDMyLjIzMDVDNDUuMjg2OCAzNC4zNjIzIDQ0LjYzNTQgMzYuMDMyMSA0My4zMzI2IDM3LjI0MDFaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfODAzODBfNTQpIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfODAzODBfNTQiIHgxPSIwLjc2NTgxMiIgeTE9Ii0yLjcwNDk2ZS0wNyIgeDI9IjYzLjU0MTciIHkyPSI2NC4yNzkzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEE2OTUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUiIHN0b3AtY29sb3I9IiMwMTg0NzciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDA2RjY0Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg==", }; const MockedSigner = { id: "MockedSigner", providerUrl: "https://uimp7-mqaaa-aaaag-qc5ka-cai.icp0.io", transportType: TransportType.NEW_TAB, label: "Mocked Signer Wallet", icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIHZpZXdCb3g9IjAgMCA2NCA2NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS45MDIyIDMuMTU2MjlDMTYuNzcxNCAzLjA2MzYzIDE3LjQwMDggMi4yODM5OCAxNy4zMDgxIDEuNDE0ODlDMTcuMjE1NSAwLjU0NTgwOSAxNi40MzU4IC0wLjA4MzYwOTkgMTUuNTY2NyAwLjAwOTA0OTQ2TDEyLjMzNDUgMC4zNTM2MzNDMTAuNjc4NiAwLjUzMDE2NSA5LjM1MDQ2IDAuNjcxNzUxIDguMjcxOCAwLjg2NzMwNkM3LjE2MDYgMS4wNjg3NiA2LjIwODI3IDEuMzQ0MTQgNS4zMjM3OCAxLjgzOTgxQzMuODg3NzMgMi42NDQ1NyAyLjY5NzE5IDMuODIzODUgMS44Nzk0NCA1LjI1MTk2QzEuMzc1NjggNi4xMzE3MyAxLjA5MjA0IDcuMDgxMTIgMC44ODExODUgOC4xODk2MUMwLjY3NjUzNSA5LjI2NTQ5IDAuNTIzODkzIDEwLjU5MSAwLjMzMzYyMSAxMi4yNDMyTDAuMzI1NDI0IDEyLjMxNDRMMC4wMDgwNjAwNiAxNS40NzA0Qy0wLjA3OTM4NzUgMTYuMzQgMC41NTQ3MjYgMTcuMTE1OSAxLjQyNDM5IDE3LjIwMzRDMi4yOTQwNiAxNy4yOTA4IDMuMDY5OTUgMTYuNjU2NyAzLjE1NzQgMTUuNzg3MUwzLjQ3MjQ4IDEyLjY1MzhDMy42NzA1NCAxMC45MzQgMy44MTA2NiA5LjcyNzMgMy45OTA2NiA4Ljc4MTAzQzQuMTY3MzEgNy44NTIzNSA0LjM2NDQ5IDcuMjgxODEgNC42MjYyNiA2LjgyNDY3QzUuMTU5MDEgNS44OTQyNyA1LjkzNDg3IDUuMTI1NTkgNi44NzEyMSA0LjYwMDg2QzcuMzMxNTEgNC4zNDI5MSA3LjkwNDg2IDQuMTUwNTEgOC44MzY0NiAzLjk4MTYxQzkuNzg3NjYgMy44MDkxNiAxMS4wMDA1IDMuNjc4ODggMTIuNzI5OSAzLjQ5NDVMMTUuOTAyMiAzLjE1NjI5Wk00Ni42OTE5IDEuNDE0ODlDNDYuNTk5MiAyLjI4Mzk4IDQ3LjIyODYgMy4wNjM2MyA0OC4wOTc4IDMuMTU2MjlMNTEuMjcwMSAzLjQ5NDVDNTIuOTk5NSAzLjY3ODg4IDU0LjIxMjMgMy44MDkxNiA1NS4xNjM1IDMuOTgxNjFDNTYuMDk1MSA0LjE1MDUxIDU2LjY2ODUgNC4zNDI5MSA1Ny4xMjg4IDQuNjAwODZDNTguMDY1MSA1LjEyNTU5IDU4Ljg0MSA1Ljg5NDI3IDU5LjM3MzcgNi44MjQ2N0M1OS42MzU1IDcuMjgxODEgNTkuODMyNyA3Ljg1MjM1IDYwLjAwOTMgOC43ODEwM0M2MC4xODkzIDkuNzI3MyA2MC4zMjk1IDEwLjkzNCA2MC41Mjc1IDEyLjY1MzhMNjAuODQyNiAxNS43ODcxQzYwLjkzIDE2LjY1NjcgNjEuNzA1OSAxNy4yOTA4IDYyLjU3NTYgMTcuMjAzNEM2My40NDUzIDE3LjExNTkgNjQuMDc5NCAxNi4zNCA2My45OTE5IDE1LjQ3MDRMNjMuNjc0NiAxMi4zMTQ0TDYzLjY2NjQgMTIuMjQzMkM2My40NzYxIDEwLjU5MSA2My4zMjM1IDkuMjY1NDkgNjMuMTE4OCA4LjE4OTYxQzYyLjkwOCA3LjA4MTEyIDYyLjYyNDMgNi4xMzE3MyA2Mi4xMjA2IDUuMjUxOTZDNjEuMzAyOCAzLjgyMzg1IDYwLjExMjMgMi42NDQ1NyA1OC42NzYyIDEuODM5ODFDNTcuNzkxNyAxLjM0NDE0IDU2LjgzOTQgMS4wNjg3NiA1NS43MjgyIDAuODY3MzA2QzU0LjY0OTUgMC42NzE3NTEgNTMuMzIxNCAwLjUzMDE2NSA1MS42NjU1IDAuMzUzNjMzTDQ4LjQzMzMgMC4wMDkwNDk0NkM0Ny41NjQyIC0wLjA4MzYwOTkgNDYuNzg0NSAwLjU0NTgwOSA0Ni42OTE5IDEuNDE0ODlaTTQ2LjY5MTkgNjIuNTg1MUM0Ni41OTkyIDYxLjcxNiA0Ny4yMjg2IDYwLjkzNjQgNDguMDk3OCA2MC44NDM3TDUxLjI3MDEgNjAuNTA1NUM1Mi45OTk1IDYwLjMyMTEgNTQuMjEyMyA2MC4xOTA4IDU1LjE2MzUgNjAuMDE4NEM1Ni4wOTUxIDU5Ljg0OTUgNTYuNjY4NSA1OS42NTcxIDU3LjEyODggNTkuMzk5MUM1OC4wNjUxIDU4Ljg3NDQgNTguODQxIDU4LjEwNTcgNTkuMzczNyA1Ny4xNzUzQzU5LjYzNTUgNTYuNzE4MiA1OS44MzI3IDU2LjE0NzYgNjAuMDA5MyA1NS4yMTlDNjAuMTg5MyA1NC4yNzI3IDYwLjMyOTUgNTMuMDY2IDYwLjUyNzUgNTEuMzQ2Mkw2MC44NDI2IDQ4LjIxMjlDNjAuOTMgNDcuMzQzMyA2MS43MDU5IDQ2LjcwOTIgNjIuNTc1NiA0Ni43OTY2QzYzLjQ0NTMgNDYuODg0MSA2NC4wNzk0IDQ3LjY2IDYzLjk5MTkgNDguNTI5Nkw2My42NzQ2IDUxLjY4NTZMNjMuNjY2NCA1MS43NTY4QzYzLjQ3NjEgNTMuNDA5IDYzLjMyMzUgNTQuNzM0NSA2My4xMTg4IDU1LjgxMDRDNjIuOTA4IDU2LjkxODkgNjIuNjI0MyA1Ny44NjgzIDYyLjEyMDYgNTguNzQ4QzYxLjMwMjggNjAuMTc2MiA2MC4xMTIzIDYxLjM1NTQgNTguNjc2MiA2Mi4xNjAyQzU3Ljc5MTcgNjIuNjU1OSA1Ni44Mzk0IDYyLjkzMTIgNTUuNzI4MiA2My4xMzI3QzU0LjY0OTYgNjMuMzI4MiA1My4zMjE2IDYzLjQ2OTggNTEuNjY1OCA2My42NDYzTDUxLjY2NTYgNjMuNjQ2M0w1MS42NjU1IDYzLjY0NjRMNTEuNjY1NSA2My42NDY0TDQ4LjQzMzMgNjMuOTkxQzQ3LjU2NDIgNjQuMDgzNiA0Ni43ODQ1IDYzLjQ1NDIgNDYuNjkxOSA2Mi41ODUxWk0xNy4zMDgxIDYyLjU4NTZDMTcuNDAwOCA2MS43MTY1IDE2Ljc3MTQgNjAuOTM2OSAxNS45MDIyIDYwLjg0NDJMMTIuNzI5OSA2MC41MDZDMTEuMDAwNSA2MC4zMjE2IDkuNzg3NjYgNjAuMTkxMyA4LjgzNjQ2IDYwLjAxODlDNy45MDQ4NiA1OS44NSA3LjMzMTUxIDU5LjY1NzYgNi44NzEyMSA1OS4zOTk2QzUuOTM0ODcgNTguODc0OSA1LjE1OTAxIDU4LjEwNjIgNC42MjYyNiA1Ny4xNzU4QzQuMzY0NDkgNTYuNzE4NyA0LjE2NzMxIDU2LjE0ODEgMy45OTA2NiA1NS4yMTk1QzMuODEwNjYgNTQuMjczMiAzLjY3MDU0IDUzLjA2NjUgMy40NzI0OCA1MS4zNDY3TDMuMTU3NCA0OC4yMTM0QzMuMDY5OTUgNDcuMzQzOCAyLjI5NDA2IDQ2LjcwOTcgMS40MjQzOSA0Ni43OTcxQzAuNTU0NzI2IDQ2Ljg4NDYgLTAuMDc5Mzg3NSA0Ny42NjA0IDAuMDA4MDYwMDYgNDguNTMwMUwwLjMyNTQyNCA1MS42ODYxTDAuMzMzNjIxIDUxLjc1NzNDMC41MjM4OTMgNTMuNDA5NSAwLjY3NjUzNSA1NC43MzUgMC44ODExODUgNTUuODEwOUMxLjA5MjA0IDU2LjkxOTQgMS4zNzU2OCA1Ny44Njg4IDEuODc5NDQgNTguNzQ4NUMyLjY5NzE5IDYwLjE3NjYgMy44ODc3MyA2MS4zNTU5IDUuMzIzNzggNjIuMTYwN0M2LjIwODI3IDYyLjY1NjMgNy4xNjA2IDYyLjkzMTcgOC4yNzE4IDYzLjEzMzJDOS4zNTA0NCA2My4zMjg3IDEwLjY3ODYgNjMuNDcwMyAxMi4zMzQ1IDYzLjY0NjhMMTIuMzM0NSA2My42NDY5TDE1LjU2NjcgNjMuOTkxNEMxNi40MzU4IDY0LjA4NDEgMTcuMjE1NSA2My40NTQ3IDE3LjMwODEgNjIuNTg1NlpNMTYuNDUxMiAxOS43OTU0QzE1LjY5NTUgMTkuNzk1NCAxNS4wODI4IDIwLjQwODEgMTUuMDgyOCAyMS4xNjM4VjQzLjI5NzJDMTUuMDgyOCA0NC4wNTMgMTUuNjk1NSA0NC42NjU2IDE2LjQ1MTIgNDQuNjY1NkgyMC43NDk0QzIxLjUwNTIgNDQuNjY1NiAyMi4xMTc4IDQ0LjA1MyAyMi4xMTc4IDQzLjI5NzJWMjEuMTYzOEMyMi4xMTc4IDIwLjQwODEgMjEuNTA1MiAxOS43OTU0IDIwLjc0OTQgMTkuNzk1NEgxNi40NTEyWk0yOC4xMDgyIDE5Ljc5NTRDMjcuMzUyNSAxOS43OTU0IDI2LjczOTggMjAuNDA4MSAyNi43Mzk4IDIxLjE2MzhWNDMuMjk3MkMyNi43Mzk4IDQ0LjA1MyAyNy4zNTI1IDQ0LjY2NTYgMjguMTA4MiA0NC42NjU2SDM4LjUwMDRDNDEuMjI0NCA0NC42NjU2IDQzLjY0MDUgNDQuMTU2NCA0NS43NDg3IDQzLjEzNzlDNDcuODU2OCA0Mi4xMTk0IDQ5LjQ5MTIgNDAuNjc0NiA1MC42NTE5IDM4LjgwMzRDNTEuODEyNSAzNi45MzIyIDUyLjM5MjkgMzQuNzQxMiA1Mi4zOTI5IDMyLjIzMDVDNTIuMzkyOSAyOS43MTk4IDUxLjgxMjUgMjcuNTI4OSA1MC42NTE5IDI1LjY1NzdDNDkuNDkxMiAyMy43ODY1IDQ3Ljg1NjggMjIuMzQxNyA0NS43NDg3IDIxLjMyMzJDNDMuNjQwNSAyMC4zMDQ3IDQxLjIyNDQgMTkuNzk1NCAzOC41MDA0IDE5Ljc5NTRIMjguMTA4MlpNNDMuMzMyNiAzNy4yNDAxQzQyLjA1MzUgMzguNDQ4MSA0MC4zNDggMzkuMDUyMSAzOC4yMTYyIDM5LjA1MjFIMzQuMTg1NEMzMy45NTg3IDM5LjA1MjEgMzMuNzc0OSAzOC44NjgzIDMzLjc3NDkgMzguNjQxNlYyNS44MTk1QzMzLjc3NDkgMjUuNTkyOCAzMy45NTg3IDI1LjQwOSAzNC4xODU0IDI1LjQwOUgzOC4yMTYyQzQwLjM0OCAyNS40MDkgNDIuMDUzNSAyNi4wMTMgNDMuMzMyNiAyNy4yMjFDNDQuNjM1NCAyOC40Mjg5IDQ1LjI4NjggMzAuMDk4OCA0NS4yODY4IDMyLjIzMDVDNDUuMjg2OCAzNC4zNjIzIDQ0LjYzNTQgMzYuMDMyMSA0My4zMzI2IDM3LjI0MDFaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfODAzODBfNTQpIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfODAzODBfNTQiIHgxPSIwLjc2NTgxMiIgeTE9Ii0yLjcwNDk2ZS0wNyIgeDI9IjYzLjU0MTciIHkyPSI2NC4yNzkzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEE2OTUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUiIHN0b3AtY29sb3I9IiMwMTg0NzciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDA2RjY0Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg==", }; const InternetIdentity = { id: "InternetIdentity", providerUrl: "https://id.ai/?feature_flag_guided_upgrade=true", transportType: TransportType.INTERNET_IDENTITY, label: "Internet Identity", icon: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzNTguOCAxNzkuOCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzU4LjggMTc5Ljg7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDp1cmwoI1NWR0lEXzFfKTt9Cgkuc3Qxe2ZpbGw6dXJsKCNTVkdJRF8yXyk7fQoJLnN0MntmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiMyOUFCRTI7fQo8L3N0eWxlPgo8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzFfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIyNC43ODUzIiB5MT0iMjU3Ljc1MzYiIHgyPSIzNDguMDY2MyIgeTI9IjEzMy40NTgxIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIC0xIDAgMjcyKSI+Cgk8c3RvcCAgb2Zmc2V0PSIwLjIxIiBzdHlsZT0ic3RvcC1jb2xvcjojRjE1QTI0Ii8+Cgk8c3RvcCAgb2Zmc2V0PSIwLjY4NDEiIHN0eWxlPSJzdG9wLWNvbG9yOiNGQkIwM0IiLz4KPC9saW5lYXJHcmFkaWVudD4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI3MS42LDBjLTIwLDAtNDEuOSwxMC45LTY1LDMyLjRjLTEwLjksMTAuMS0yMC41LDIxLjEtMjcuNSwyOS44YzAsMCwxMS4yLDEyLjksMjMuNSwyNi44CgljNi43LTguNCwxNi4yLTE5LjgsMjcuMy0zMC4xYzIwLjUtMTkuMiwzMy45LTIzLjEsNDEuNi0yMy4xYzI4LjgsMCw1Mi4yLDI0LjIsNTIuMiw1NC4xYzAsMjkuNi0yMy40LDUzLjgtNTIuMiw1NC4xCgljLTEuNCwwLTMtMC4yLTUtMC42YzguNCwzLjksMTcuNSw2LjcsMjYsNi43YzUyLjgsMCw2My4yLTM2LjUsNjMuOC0zOS4xYzEuNS02LjcsMi40LTEzLjcsMi40LTIwLjlDMzU4LjYsNDAuNCwzMTkuNiwwLDI3MS42LDB6Ii8+CjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMl8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTMzLjk0NjEiIHkxPSIxMDYuNDI2MiIgeDI9IjEwLjY2NTMiIHkyPSIyMzAuNzIxNSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxIDAgMCAtMSAwIDI3MikiPgoJPHN0b3AgIG9mZnNldD0iMC4yMSIgc3R5bGU9InN0b3AtY29sb3I6I0VEMUU3OSIvPgoJPHN0b3AgIG9mZnNldD0iMC44OTI5IiBzdHlsZT0ic3RvcC1jb2xvcjojNTIyNzg1Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik04Ny4xLDE3OS44YzIwLDAsNDEuOS0xMC45LDY1LTMyLjRjMTAuOS0xMC4xLDIwLjUtMjEuMSwyNy41LTI5LjhjMCwwLTExLjItMTIuOS0yMy41LTI2LjgKCWMtNi43LDguNC0xNi4yLDE5LjgtMjcuMywzMC4xYy0yMC41LDE5LTM0LDIzLjEtNDEuNiwyMy4xYy0yOC44LDAtNTIuMi0yNC4yLTUyLjItNTQuMWMwLTI5LjYsMjMuNC01My44LDUyLjItNTQuMQoJYzEuNCwwLDMsMC4yLDUsMC42Yy04LjQtMy45LTE3LjUtNi43LTI2LTYuN0MxMy40LDI5LjYsMyw2Ni4xLDIuNCw2OC44QzAuOSw3NS41LDAsODIuNSwwLDg5LjdDMCwxMzkuNCwzOSwxNzkuOCw4Ny4xLDE3OS44eiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMTI3LjMsNTkuN2MtNS44LTUuNi0zNC0yOC41LTYxLTI5LjNDMTguMSwyOS4yLDQsNjQuMiwyLjcsNjguN0MxMiwyOS41LDQ2LjQsMC4yLDg3LjIsMAoJYzMzLjMsMCw2NywzMi43LDkxLjksNjIuMmMwLDAsMC4xLTAuMSwwLjEtMC4xYzAsMCwxMS4yLDEyLjksMjMuNSwyNi44YzAsMCwxNCwxNi41LDI4LjgsMzFjNS44LDUuNiwzMy45LDI4LjIsNjAuOSwyOQoJYzQ5LjUsMS40LDYzLjItMzUuNiw2My45LTM4LjRjLTkuMSwzOS41LTQzLjYsNjguOS04NC42LDY5LjFjLTMzLjMsMC02Ny0zMi43LTkyLTYyLjJjMCwwLjEtMC4xLDAuMS0wLjEsMC4yCgljMCwwLTExLjItMTIuOS0yMy41LTI2LjhDMTU2LjIsOTAuOCwxNDIuMiw3NC4yLDEyNy4zLDU5Ljd6IE0yLjcsNjkuMWMwLTAuMSwwLTAuMiwwLjEtMC4zQzIuNyw2OC45LDIuNyw2OSwyLjcsNjkuMXoiLz4KPC9zdmc+Cg==", }; const Stoic = { id: "Stoic", providerUrl: "", transportType: TransportType.STOIC, label: "Stoic", icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGoAAABnCAYAAADov9dJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAACu1SURBVHhe7V0HWBVn2j23wL303kFARRGs2BUVFUvEHjWml01PdrP7Z9dks5tkY3p2s8kmMcmmmZhNUewFsAuiiCAoCopKLyK9t1vmP994k1+FJBYucf05zwN37jAzd+53vve85/3mmwE96EEPuhAK0+u1QBEwavJgo4SJkoTBfNtboZDsuGxj+vv/WyigaJYgNXAxl++OK1RSYmHy3jS+l+QNrgFXTZRbyCRbrbXqQYUCT/Jtnwtre/BLIEMF/P1xa5Pxg4qs+EbT6ivGVRHlO2LKUu7wDknyNK3qwdWjgqQtK0rZ86Xp/RXhiojyGj7bWq1o+kShUNxpWtWD6wTJWqdRWD5w9nBcvWnVz+IXieoVHu4ktVrGMIrGmFb1oIvAPJau0+lmlB1NrDCt+kn8LFEXIql5dw9J5gPN11ELSRmRe2RXnWlVp1CaXjvFBbnrIcmcYPsO1SsMIl/9bNCoTK8d4Ddi6m08yHLT2x6YEwpFsKN3QGFdaX66aU0HdMqi75gxVkqD1Vn+2du0qgfmhiRVKXTGvgXH4mtNay5Bp9Kn0Fs/3ENSN0OhcDFaKB8zveuAzomC9IRpsQfdCAUUjwMv/gQnl8F3xKSBSoXquOntNUOyUKFtUjD0YQGAuz2UlmqouV6chUiM4ueSZRYWna6/6PUn973o/eXbiS/Y2fIP28nb8rN/+NvF63/uR2xv1BlQX9WA7PQCpMSfRHurjmuvD0ZIk4pT9iaY3v4IcW6XwMGn961kNsr09pqg93VGzd8Won18P8DRGgqVEgonG6hLa6Cws4KSy8riar5aQ2lvBamwCipXO6isLWEsqoaFlyNUJNpQXAMNj6Wkq9FxX6teLlAYjdCV18PazxlSmw76miZY+zjD2NwGQ3M7bLmvBY9jyZ/26ka08e9KpQJ2ng7yOugNaCyrg47bO/HYGhsNLLUWqOX5tDe1wdrBCrY8Py23ba5tQiP3F3DlccU6iZ9fXVaLNu7v4ecCVw8H9B/cC8PD+yE/+xzqa5vl7a8ZkqK4vjRvr+ndjxCd4xIo5AHWa4eBX7LyubkwuNnJ7+1e3gSLg2fkZfUHO6HIKJSXjX+PgZFfDOyFra9sgrGgEsa6ZtS9ymW+6s/Xo1ws8+9t/FsxlwWauU/+P2Lk5ZrDOTjLYwqcT8hGzteJ8nKbqbEs2QlyY49h759X4xj/ZmAEaNhRKnPOY/ebWxHzt/WoZ6Mr2BHEz95P9+LbZd/jtOl8rbl/+o7j+PKvaxC3MgE6dgwrWy3K2LFWvbUV/35xHcpLauRtHZxt8dAzc+DsZi+/vw6EmV4vQQeiCGrVtaNu6RgY2SvVbFwZrOi6GwVb03H8491QMipH/s8tGPrAJBTEn8Luv0SjpqACIbOHYeZLt8LA6Nr0XDSydp2AR5Anlry2BH1G9sb2j3YhZgU7AMmb+7sZiHp4CrKSzuCzv0ajhCSPnj4Ij76yWCZ3xfPRSIw7Jn+uFaNz7l3j5OVrBf0BZagjOhAlQeFoWrx6UOKax/SFJXu95ki+aWX3w3WoPyqOFmL/s6tRdbIU/pNDMPXVJbBgQ+56cT0yNx2BI6Vz9vJFCJ42EEmrEhH7923Qtegw+cEIzCa5RZklWMVILDhRjNDw/vgNSbR1tMGXL2/EvvUpcKHkPUJ5D79lCGK/S8Knr29GHaU2ZFgg1OoOGeVq4Gx6vQQdpU8BW9PiVcNoZQFJrYQ2rcC05teB80BfjH/jNtgydx16bTMyvz0IKxdbRLwwH6ELR+D4+lTsWL4RTVWNGHn7WMyiVNcwB64mMTmU08BhAbjnzdvgHuCG6Le2YBdl08bBGnc/Nw9TFo9G4pZ0fLZ8A6qZK6fx/cN/nY/aygbs4Xq2n5zLrhWSQvZcHdAxoiSpMzm8IkimnqSsb5Fffy3UZJVAzU4zclkUQu8NR96uTOx5fi3qaVRC5g3H9JdodGgcNv9lDU7vzYJXsDcWMWL8GYlx7+/ATsqmit9lPiNrxgMROJFwCl8wT5VRNsdGDcXDy2+FnvnuQ0rhIcqmP2XzKe7fu7+X/PnCvHQ1rpmUGxkVafk48Oc1qDlThoDIgYh4bbHsIncz+Z9i/nL2d8OsVxcjiOXDgS/iseOfsbLRmPLIFMxkTso/VoivGV3Fp0oxKGIA7qNsWtlosZLmYz9l041u8RHK5mjK5lbK5krKZisd5xDKvrlwUxLlP2sIrGj3DzGfnFqTDBs6sQjmk2CaiIzow9hFB9lKZznq7nDMoFOryq9ANPNZPgkWZuKO12+DC8mIpmzu++4g7Ojo7np+PiYuHImEDan4grIn8tGMpWPxIGWznLL57nNrkJVuvrx8UxKlYcOOZAMGM/8Iex7PSGqkDQ+5dSQiX1iAFtZHWxlxOfuz4c18tpDE+IT6IPadWOz9bJ9cV83/YxSm3DsBxyibq15YiwrWWePnhuE3dIsiej6ibKZSNgMom7/n/sGUzRQ6S3PhpiSqmHmjLqccgXRkE2ijBfbQmp/ZngHnPu64hfkkcFwQEj/Zgz3/2i6XEFOfmIbIxyORk5KL70hC6ekyDJkainsokWpLFb58YR2StqXDs5crHuW6sInB2LwyHl//Mwa6dj2WUDajGGHmwk1JVHtdC5IpT2doo8VIxURGQV+SlvHNQex7fYtsJEbdPxGRjJpyErKWslfEvBQ0NghLX18Ce0pl9KsbkUjZdODyXS8sxNg5w7CPsvnVa5vQyIL6FsrmfZTN0vxKvMv9s9Ly4OrpYDqDrsdNSVQgLXjQ4lHIoV0+8NJ6NFfUI3TJaETQRjdxOeYZ5iMWsD5DemEBbbgodmPf3oaElQnQ2mox/9k5mHj7OKSxkP0PZbP6XC0mMD/d+/wCNJGkj5iPjlI2e4f64imWAX0pm6veicNO5i9z4aYkStIbEUjjME6MPrQbsO+5aOQy17j088QMyp7fqN5IXLELCSt2yqMLkU/NQMRDU3CG5K2m7J2nbA6bORh3vnxBNr96PhopcRnwpmw+RNkbRNnc+OkefEfZNBokLKVs3s6fmgoxlc88uCmJyll7GLmb02Dn54wJrHkCI0Nx7Kv9SBSjD606jH4wAhGskc5llmADZasksxj9JvSXh5CsHW2w9uUNSKJsOlM27yLZI2YOwW66v2/e2IKWxlZE3TcRdz4dhaKzZXiPNj6bsims+aLfTDKdQdfjpiTKlgSdXZeCQ8s3orWmCaF3jEM4XWA9nVucyEc0DL5hAZhH2XIJdEPsm1tw8OtEWDtYY8Fz8zCWsplK2fyOsllHqZxI2bxLjD5w+d90iycYeUGUzSfp9noxSr+ibG6gbOr1BtMZdD1uSqK8wvtjNG14e0MLEphPCvadhNsAb0xjw3oP7YX9lKyDH++Ri+BIRlb4/ZOQnXAK0X+NRkVBBcKihuF20+jDKrrFdLpIX+axhxlxA1hnrftwF9aaZPMOFsiLHp6CoyRvHYtnc+GmJErAgfkknA3rM74fjn6+D0n/jIWRPX70o1MR/tvpKDlagM2MjrKTpQieHIJbX10iX5ta+7f1SNl0RC5471y+CEMom7tWJWI1ZbOtRYfZlM3bSW4uZfMDMTZI2Qxjx/i9+KwAN9Ondz1uWqIEVJZqDKINH0MbXpNXgR2UvdK0fPQa3QezacMdvJ0Q99pmJH+XBFsWyfOfn4+RC0bgMN3bmpc3oqG6ERF0f0spm5Ul1fiExJw8nIN+wwLwBN2iN4lZSdncQtm0o2xOZAlgLty0RLU3tKKYcladfQ4ezCeRlD23YG/sZ2Qlf7ZPvgocuSwKY+4Nx0lK2/oX1qKaOWzEvOFY8reFaGOt9TUdYMbeLPhxvwe5f18eZ+37O7Dh493ypYw7GVnzH4hAKj/nPXGtKv8XJ7xeM25KolqrGnHgme+R8cleHGRkpMr5BBjzu+my9BUyKsQQUvmZMgRHDsQCWm6Rr9a9sA7p247Czd8Nd7yyGAMnBmPHynisNw3azuW+iyibZ+jyVjC68k+VYkTEADwlD9pqsGvjEdMZdD1uSqLKDpxG+0WXWkqSzmIXZa/8RDECwvthFqPDxsUWcSTxyJpk2LnZY/6LCzFszjAcik7G+tc2obmuGZPvDsfiZ+agjJHyKfc/TdkcMKoPHhfR6eOMLyibsbTt4jL8o5TN8BnXNYvhZ2EeolRdfz3mamBhqzUt/R9aaNMTmE/SmU+09laYRhs+4vaxyIw9hk0vrkNdWS1GLhyJhfLoQxP+I0bDE7PhH+qLB0hMQKgPot+JxVbToO3df4rC7HsnIJmF9AeUzTLKZh86S3OhS4lS6I3yaz3rlvaBvvLyrwEvSpYbbXgHSMDp7ccRS8tdLeZOMPnPeXmRuFiKdcwxGdsz4EG3eDulLHhsEOI+2YPN722X/z7viWmY/3gkTrIG+5i5q/B0GUZNDcWTlE0LSxVWUDYPswwwF7qUKCWrdte3Y+UpWToWggJifl93Q6lWIoxOL5Q9Xji/y1FfWoO4F9cjQ8yd8HHC/JcWYRBl6+A3B7HpjS1opZGYQre44OkolJCQlcKGMy+FkrxH6BYdKZUrX92InZRNJy4/+sJCRFA2s48XmT6h69Hl0mdFHXd/ZjU0fBVo+v0MGHq7y8vdDf9pAzGBPd4xsGN9YzQYkR59GDHLN6KRNnzUbWMw7y/zUF9ej2+Zj7IPnUUgXd59b9CG9/XEmre3Ie7LBHm62D3PzsF02vaDccfwMWWz8lwtIimbt5Jcc8EsOUrMmXBkZNl+ug8SbbDBFF1QmicldoZzB87gzLoU2LjbY6K4ujt/OBSdzGUQzm8DpeyUmDvR3wtLWbj2HhGIWDrFbfwR8x/mPzUDsx+aghMHz+BTymZJTjnGzhyMx0yDtu/LU8YyYN1JbuwqmLXltNRs+2fXQEX5END9aRYTyLXPRrtSFNBiZ3y0Sx7nE6MRYqZuyKJRmPzCAth6dLxmJAZqE76IRyxtuL5dj8iHJmP2UzNRmFmClYyugsxiDJrQHw+RRBtHa3zx8gbsXZ8iz5599KVbET5zCGLo/jZ+td90xK6H2bu4klJi88omWK5OhsTeLfX1MP3hwos5IFHWwliMDnowArrmdiSTgNydJ+DMz57x2mL0nRJi2vJS5Kfn4zsSk0fZ7suoupduz93fFavpFnfSLdqSpHvlKWOj5Cljny5fj5qKesxYMhqP/GU+1GbMx13fXOy9HcCGs9icBks6IwX1XEBJe6twuuYphD+LgLlhcAsLwLnkHCSwsK0vrIK934V5jWqNBUY9MAmTn54FKwcred3FaGlowVba8J1i9EKjxkJuN+P+SchIOIXPKHtlhZUYHzVMnjKmazfgA647tDsT/pT32XS75kKXEmW01qBo5UOoe2AiJDbI5VDkV0L1/DqAeg72bkVvJnmRNrq47NIzisSU5vT3d8B9qD8m0xC4Bnsjd08Wtjz1NcooZT7D/DHvjaXoNTzQtNelyIw/iVXMXcL1DZkcggdeWQwN8+3nNA/72encfZ3xmJgyFhmKzZS8lf/Ydv03CPwMupQoifWEiKgm1hdVry+G/geZuxgt7VB8fQDSa1sgiTslrCyhZXTBRmPa4PqRuyFVntIcRhMw9NEpMDDvHHw7Bmkr4+E7ojfc+3nJtZEYNpr6h5mY+OBkWLCIvRx1lO3vacMTxNwJVzv5UvzEBSPkKc2fv7wR9XSLt9D9PfTcXJxnwftfl6M0J0thdLFD7YsL0MIk3pkcSuzV+mWrYUg6CxVtsKqXizyfuivgFOyF8W/eBs+RvVF2JA97mXfqCqowkbZ62N3j0cKev/PVzdhEWRQTXfpNCpZnynqRwMshGSUc2pKGLxlJVWLuxLzhePDFhWhpaqXsrUEqDVMgo/UPzGcDmdfMBbMQZZWQDefn10LFwrJ1wXA00R4bvTtxe81t0H2wE238kbisdLGF3SNToLjOpOxGORO5KOPTvUh9Jw5uob6IfGMJ3Pmax1wT89watJKsSU9OgyUjWdRO1k42mPfXeRi7ZAxULJgvx/mCSnxOG55M2fZiXfbYK0vkKWMbv9iHVcIt0l2GifvBzASzENXIKl1izeT417XQxhyDgV+shYWnYcagTvORnlHVyCJZzyjT0AYrHaxNf7k21OeWy1Oaz6fmIeyJaRj+RCSdoISkf23HYZIXMD4Is+j+XPu4I5MNv+7Z75FA8yCu2Ibx3Bf/7VY4+ziZjvZ/EFd8d3xzAKve2IJmmo4oMWVs2Rz58sY/ef7Zpnu/zAGzEKVn9FQvpzxEDYXVd0mwfnUTFA2t0N8TDsMzc6hNHR9AJvJVAxugiTZYYoNY0KU5Lh3DM7x6OSxjYWrtYY8JYlRhbF+cZ74So+dVLG4n/jEKI++biPbGVux4fQtSvj2IgayDJrF2EjKXJ+bnUYbvpHkIY1HbWcfKY4dawY6QkXQGfQf6yjNl+4T64BDNirlgFqJsth+HmnLSzHqjgUWmkknXij1OtT8b0iBfSMwfCjZgB0j0Gty3mpZXx5xiN3sYlJ0k+V+Cz5RQjGA+EhcHj69MwKG3t8lTxaaTOC/mwwI28FYW4o2sgWaJq7qsgxq4vP6l9dj+/k4UkFhxN0fEneOx5Nm58tzzy9FKqY7+cBdWr7hwx+MdjNyZi0fLy+aAWYhSM+k6PxcN7Y4T0Ad5oOn1JTCM6Qu1mFBimkKsYH5QUZIUtPSXQ8/cVsnkXU8bLLbVBnnCadaVX+a2YUTX5ZxHohjuYXSFMe+NpgMUZiWJ+fDAil3oNao35vK83HlsccfhOm4rLg4uZn0UQOteTjnLOnAavUJ85MscIWODTEe/FBmHzuLdP6/GWUaZRydy2VXokLUdvAOfoFZf0ywNib2/gXKnG+gHZZsetmsPQ0250Q/uBSPzgqK3O1SMGAULRLAOUdGVqScwATN6JPboS0CC2jJL0JpVAivKij2JFr1Kx07QcCQfHswlzSSj6ex5eFGiGug02yob5EscZYnZOEoTYcvPGPPMbPkSfOWJYiS+uRWNjPRw9v5QcZ6Nbdj33g6c3HkCA2cMxownp8tDREfYQbazDhOzYvuGBcLKViPPPnLzdkI+z0fkqovR1qpDOklt4fEEWYk7jl/P1LG2+tL8N0zLP8IsRCmp9bohfjCEeMvjfZq445Dc7CGNpH2lFVbmVgDrUoDaFqiHB8By8gCobLQwnCxh1XzpPb/6qkY0xJ+Cyt4KVgFusKQMGepb4MBC9qeIKqc5cR8WgMEPREBtqUbWNwdxbNV+uA3wQcSy2XDhcYoO52D332OgY103jbVUCIvaJu4fQwd3mtI4hvXSjIcnQ6VS4QA7nIi2YNZgQ+jsygur5KGjy1GYU4792zOud35f9xHlSEOgqm6Cjr1QFzEA6vN1sIw+DAV7M9iACkEW6yxpazoMB85ARfdlyW01o/rAcOY8jJdV+GKKclNaPlrzK2HHHOM0uo8cXT9FlBMjyIW1VENBBQ6/uQVVp85hKA3EkNvHyh0h5fN9OMbzCeDnTXv6Fjh5OiJ7bxa2/ytOzk3zWID3ZwRXsYhd9/dtyDtWCG8W795UBC0L9KHh/eWR8nx2LONlHasL0H1EWZyvhwOrdDUjRz/EH/pwyhudlDo2A6q9JwF/VyhJjGocDUVGEXRiUojBCA0LRmtGlzBaOjHiflkbtFP26mhINF6OsOKP1s0OOnYIZ+aUi4kSdXPepjRkfLQbNh4OGEdj4cEaqpLbJNBZ1pfUYPxjUzFkXhj0jKh9zFkZcccQShNyy+9myOYhLSYdsVxv52yDJZTPvpTvEsr4Ftp7Vy8nhPL8B/KniB2l4bKOdZ3oPqLE0JG+vxesd2fRUByH0dMBRn4psCcq+cUUayl7bCAVC1MLEqNkL24nWbr0AlgyeVsxYqyY59pPlcLY1GY6+gUYmftqKW2CICfKpgvlSBB7MVF5lFVBVL9bR2II5ctSa4ms75OQTgfoSvMwWeQtRnEJo3TnW9vQSimd/tRMDIociGaWCTHvxuEkO8SouWGIenQqrGh49lP+tjESxdXdIex4IrJs7awwkuogorSQJDKtdgW6jyhL9nxxVbc9Ihjq0lpoKTNK5hqjGADlF1OIUetN6ZCSc6AioRZ0YJaURD0dVIu4s5yNYM11dtxfYr3TntdxvlwLZbCa29sIOXKxhRV7vo4922WQH1rL6tB34Uh4k/DGomokk4zy40UYwgI17O7xsmymfLkfR1jj+YUFYCZrK2cfZ5whOTHvxPKvEuY9HYUQ5qMafhchf2fT8zF16VjMooSqVErEUd73bUyVIyuE5x7EeiqPnaXlso51DeiUqA7lnN+IyZkkqvMLNr8AAx1T6Yp74fLvvVCxzmh6MAIKOy20bFDtFwkAe6bxsSlQkhwVG1OiNEkFlbBkz9eSYBVzUevqQ6ylMqChVLnQVluyOG47WoDyT/fBUNdRYsRVW2/WWwE8hpoNKHqeIEI836hgWzpOM7ocKLsjKXX2zEU1lNRkOrp2OrQx909EH9ZzehbjiZ/HI+9ILgZODsWEO8dBQxNylOeRyPNxodub+1gk3OnoymgYNnL/Rp5LFEkfPiEY+jYdNBoL+XXLfw4g+TomuUiQ6opS9nYYbzNLRClYaIqiV7srE0Z+SQN7nZFyoaaUqdhwCp0eCkqWWsgeG1S3PhV62mcLyp2WDaehGWhhLmtkQ6mZh2y5rQMlzUC5a2OCvwTcvyH7HGqY8N2Y48QYn5BAYc9LGCFBlK/hlC9LdpIsylfqZ/vku+Kn/pl5izJYwv3iaNubWJRPpz0fSmPSQincxnrvOA3GyFlDMefxSFnmEjekYjNzlBsJu4fy2ZsuMpf10xdvbMU5djhx600oIzSJ5Uc7Jfoa0X3SZ6SOt00aAIvCSlizcRSUJAPzCegAlTYaKDYcgZSaByWdmZryZEEnp088jTa6QCWj0orE2HB/gzAP61NYO9XBNswfjpQiLYlvYn0lhpkuRrv4DDaOeGpLHolvpDSO+OMs+HKfJspvEuXrHHPSkDvGYhTlS8noS12ViMPfHIAvO8gty6Lgxsg7y+jf+o8Y+fE78/8wC4PYQWrL67D27RicOpyLyYtHYc4Dk2CpUWP7t0nYStsfwO8x796JclQJidpPYyJqq2tE9xFlwxrF6G6P9gn9Ibk7QLvlKNQsCMEEDuYeBW2xIiUPxk10e/zCFiP7QEsSUdeCFhKrZwFsRSdnyyjUkJh6RlY9I0zj7wIH9lhnrm8rqkK7sPsXQcvP9OCxxRSxoEWjYMNozI/LQOr7O6BhHTaB7s+X+aSG8rWHtr2CxmY8G33UktHyI932MVpSGDX9x/XDvD/QttMxHmN0bGJ0WTJvLqVtD6E6iDrq67e2yjlpzj0TECWu7DKyT5BILz8XJMT+lxBlt+0Y7Flk6nnSeha5BvZqNaVNzZ4ubLiCEqUSNpzLBjpAIyVRTROgHRcESzrGVjZO087jsKDECNmzF8Qwt1SxEYULdAgLhCtNiXi2USMbSwymigdUBd0TLj9fwpo/OuaQ9He3o5Dy1ZfnNJrypaV8ZfEcDn2yFw40D9OfnQ2vAd44R/mKpfzVs6yYLkbbuX0bc1jMBzvkp4uFzRiEBU9Ogx2j/SDNzvqPdslPERM3WwsTIeagf8H9W5rbMZTyZw6izGImLKjxTkz+GjqltumD0MZCUxSSmhhGFh0g/JyhZMOpWAspWODq+cWlhjZY3zsBVmKoiY3U+EU8WhiZdlNC4MrkLnJPPRutnE7Nko0U8PhU2AW4Qc981EQSHYI85Ad/iJ5Xw9rs+Ac7YWmrwTCaCGHJW8pqkfLhbtQxEgfTeAyMGgYxUTSNtj2Lx/UfGiA/sMqGkZeXkos9/HwxZ2LWI1PhTzIbGL1baCJKc8sxacEITGLug0HC7rXJSIw5hiB2tCXc34Hm5+XffoVrvSz/U2aia4nilyz96D65scSPDd2PjbjsTuvc9kQklGxYNRtKxQYDXZ+KBFpMHwgV3ZLu64NoZ+/XsEfaM4dYsJFbmbdqmQNUjARPNriNqM+Yb0o+3IVWHsdr3nD4zh8OFZ3fD58pfs7SeYnn/IXSlVmQ4MJdJ5DJfCKmio3hcVyYi2rzK3CA59FMEzGa0iWGkAys7RKZt7ITszGAKjCFsmZFY3SC32MPc5kofhfQ/Ykb1ir4+evpWqvO1+EWfo9xrMGE2xQNuvzJr9DQiUO9EnSL6+N+qGe1b30kD2rmGzGEpKeLs2QPtxSyJ4YMRI6KCIGS5BiF7LFQVLPqt6TsWQS6o435qGVPlnw9yob72zFftFGaqmgqhGzaUzZdhWxS7sqY4+ro2hzovixttXJDiR97NqT32CDoGZlp7+1A/o4T6EP5GvPb6bBm1J/cnIaDbGR7EiceseNL+SqjfG1j3hH3SE0To+3sBPrWdmxbsQspsUcxbEooFv1uJhydbZHE9+tMoxb3L5uNYJohUfAWM9rEoOxuFtuXD9xeBcyfo8RNAs10SUZKmsvyjVAKstiwetGwaiUs1qVeeAImayQlI0cV4g0jTYI+7jiUlC0xhGQlbDi/cMO6wzCyoW3oFh1IrIr5r2rjETTSudmG+MCZbtGBbq364BmUUnpEBNqz+BVECZmsoGwe+XsM9KznRtEY9KaENlc04MDbsSjgPoMXjsB406hFKmulxJUJ8GDEzmXDe/bxkOf4rX9zG5op4/NJ0IhpA+XR9DUsiMUzJiZQ+haRUGvmyV08163/OYhZS8fItnzP5uu6T8r8RAkoKTmtJMHA6LCl3Fgm58LIAtdINyYGZFVsJAVtOFgIi8scYggJlI925i4jk7mG21iTLAsXOzRsSUNT0hn5epQdI9GepDXQWVUwIlSsi5y5v0cEC042YBGNRgMJdg71g5qkNlMixdDUyD/MhD07jjAVSe/GyesiaMUDeI51RdXYSdtewogfd9d4hN8dLgd9/Jf7kcjc1YcO89Y/0rb7OsvXptbQolOacMfTs+RR9CrmvVW08qfSC3AHazAff1fERifLo+jXge4hypL1i0FYc0aHbkwfWPJLaMWgKyNKYsOCuUDJSAFtuJRbAdUQf1iKYpgOsT02A63MBxb8wtbc1pay2cpGrCUJogXtuc6Z0SWx15Zx/0bKjSNl042yac+OUbYnE8Ussm08HeBJt+jJhhb11hHa8zN0Yr2nhmL8UzPk+3VP0tjsZ64Tk1puYfHai8cR89C30L1V8DtMe3AyxtN0iAeKbKOJSGKnGTIhGEu4v7iDI5kGZPV722HDDvcAo1A8s+8oO2HsmkOmlrhmdA9RAlrmKEWbgWT1hk6MPrCRNcxHShaqYD4Ql+HFMBJ2Z8HAL6wUT1DmtlrWXUa6wKZ1KZCY2K2HB8KB+wvHWM0c1UTZtA31gZMwHJTN6viTKGOdpGXDubJjiAHZpoJKueAVt4eK2UcWrH/E05uDZgxGX8qXmI++/504+clig+aEYRLNhZbRmUri4z/fx6LXFfNJnG8/LxTw89YybzXwWAsYMaPFqEVDK6JZVx1hpxg/ayiWmEYtdrMzbaXh6IKBWfPb88uhp7tqpo0Go8UirwJa9mBFTTOke8ZDxUYV44HGlfthYE+0YF1kQ+kRstXOOqqBdZiakenGhhCP0daRgPPcX8dG86JLcxfzxymzRV/tRyUb3Y22vp8YHaBLK4s/hdNfJ8pPaf7BnoseWUlTksTaSutghXAxdscCXNwrlUBjUMvX0Sx8h80cAmO7Hge+PYgMkhE0vDdmsii2ZeScOnQWseLWG+alWx+lbedxxaO1o2lMhJHoCnSL67scwkxo2GiSpVq+zCEJ2WtogXJNMlBYDeVQf6gpeypvJ+hoCNoTsqEOdIMVt7Ue3RdtTOh1dHbibgw7rnMSsseC9zx7fzNl05Gy6c5cYcuOcI6RdY6yaUfZ9OC2YvZRFSP4jCiSaXLcgr1gy0LYhrI3gvWanZsdsukwxaV4UQjPWjYHvSmVFWzwTZS/c2fPI/L+iZi4ZAwkgwExrAv3M6oH8fNupzlxdnfAYdp+8Twk8TzZLkT3Sd8loI1WHy+CSowgDPIFaJsVQvZ2ZsK48wSUPs6wGBkIDRtAjFA0CxvOHi3G++xJrIJSInJU84li2NDlOZIAu2BvVFE2y3cehxUttguJ8aBsNrJx88QQVIsOHpTNXhGUTQs1zpDsc2kFcKdb9KT0ilH2wyxoT2xJx8BZQzDl8WmwJllpzKW7P9kjz+lbKPIWbX8RozD6rW2ooeFZ8MR0jKPcyfLHgvoQZVvcENfF+JWIMkHJXqcST4hkHaNgw6rYiIqSGuiZfKXaFliwN4vxPuHmmtlgrcxzGhEFtOG2rFMaWfxW0wBYcH9Hkug2aQDauH8xiWmvbIQLifGmnGodbVBAV1iWnANndghvukUvOslS2vVsEmPB44uJl14kLYDH6RtOguk2t7+9Dbl0lKMXj8IU06DrfrrWXSy4/UnY7cK2M1pP8rjf0f2Vs+A1E35domToDVAcyYeisAqKYf5QmWTPQLuuIxFqNqCWJFqxcdtS89DASFCywWxH9oEjTYWRUlpOYlq5v5jc4sb9rbn/OcpmOWXTjrIpZM+TbrOSbjNnYyqUKhW8ua43O4G47J7JmqeShsWHLs+Rtl2s2/rSBiiUSsz+UxT6ctsqHn8jTUQxVSDyvkmIYH0k7rmKodmI5/7iZjcz4gYg6gewxpFIjJKNrGbDCHtuPHUOreISPaXSig7OVhTJtNa1lMJWSqLNID840IaLYaRqWvBKyqYVJUpcinfn/g3cpoDbCiPgTgPQy+Q2T3OdmCrmQdnsRbfoTtnMZS7L3n4cdjQrYkZSv3H9MHD6QPlGtXR2mh00LY4ejlj07Bz4M/IKs0qwhsQViX9RYX7cQEQJ0LEZ6fYkFqsWLGQ1Eyl7tlq00Fq3MRo0bCAbNqwNc0rj/lOoicmABY2AA4l1ocSJsb5SRpd8+Z37ezFixIT/AspmBWXTmbLpzSLbk5FXzE5xmgRoSYQfiQ2ibNafq8VRdozG8gb4U3YtaHhKSYi4M37k/OGsoyJk+Uv47hB2fpWANlr8bsINRpQJEm27gbZX1dsdGpKgZU5qp+w1bqDsMZ+I8T4HkmCkLa8U+YjRaM/Gd6V5sKLzKtt2FBUHTsOO+7tzW0+SU8H9cymbKja0F4kJ4P7iSS6Z3L+2oEq+ia0Po9CJEZ0VdwzZzJ2uAa7wZecYSnvuK8wK5W89oyiHzrObcWMSJSAst461ECh1WjasDW24+PdDddGH0cZ8Yj3YD/Z0hdaUqRoxN31PFqz8nOUhJHfKVj2dmRhCEnnEnbLpS9kDLbl4uGIVJdGDstmLbtO1rydyWKOdplt0oGz6CzPB41acLpMnYvpRHsU9CWmMvjjKXzNz4q+AG5coGbTheuaA9qMFsGSPtmZkWdPtNbG314lBVzd7eQjJiZHUyig8J5J6YxucKXueJFYMxBZS9irT8uHMyPDi/m5s+GLKZg5lU8xS8uX+fSib4kmYYgKmuKHNn/sHU3YFSWK6s5gpe4qdRtyR+CvhBifKBDFLtjX+JBSULRu6PXshe1xX+X0S2mmj7ZlPRI4SD6Evo92uTjoDuyBPuNEpurHRK2mx82nP1ZRNLxLjz/1bq5twksSIiZc+tOp9SLa4xNFMW+8j6iq16seZsuKmtl8Z/x1EyaDza2OR3MYIs6Js2VO2rElGbVwGavZkwor1jBNJcKXZqM8oQjFlj+cMN67zYXSJSZriAcC1Z8vgRhvei27RJdAdZymbOZRNZ+YjP1EQk/QfZ8rGHpNHMG4A/BcRZYKhogGNCaegdrK9MIQ0KRjtTPJl3x+CkQ3szHzkIWy4SokiusWa44VwDvVhHdUXriHeKKYNz487DmvKpg+3DWQkGtt08oN/xc3VJXSH4jJHVYHpn5LdGLgyohx9eot/MfrrPLyoE4jLFE10ce3FNbCjbDnRrVl5OeD8xjR5pqxdfy+40um58G8VlMHCrUflq73iRmsxhNR8vg6nKHvinl0/EuglRu953JSVCUgj4fprn39nLlwZUfbegfdQRX69Z7j9BNqZX+oTs6H1cZaHkFxJWCPdXgklTgzaihzlTdkz0GDk0GjU03C4D/GHH12dk7g0T6nTkMAqymn8m1txnjXTjQiFhKa60vy3TG9/RMeI8g5YRME33z9Cug6ICSt1jBo9bbMj5cudEaO2tpTH+