diff --git a/config/quality/eslint-suppressions.json b/config/quality/eslint-suppressions.json index 1386fc25dd..c89081a812 100644 --- a/config/quality/eslint-suppressions.json +++ b/config/quality/eslint-suppressions.json @@ -44,6 +44,16 @@ "count": 11 } }, + "open-sse/executors/tinycms.ts": { + "@typescript-eslint/no-explicit-any": { + "count": 3 + } + }, + "open-sse/executors/tinycmsSigner.ts": { + "@typescript-eslint/no-explicit-any": { + "count": 1 + } + }, "open-sse/executors/vertex.ts": { "@typescript-eslint/no-explicit-any": { "count": 3 diff --git a/open-sse/config/providers/index.ts b/open-sse/config/providers/index.ts index 80357cf981..8079c5352f 100644 --- a/open-sse/config/providers/index.ts +++ b/open-sse/config/providers/index.ts @@ -216,6 +216,7 @@ import { grok_cliProvider } from "./registry/grok-cli/index.ts"; import { codebuddy_cnProvider } from "./registry/codebuddy-cn/index.ts"; import { pioneerProvider } from "./registry/pioneer/index.ts"; import { zenmux_freeProvider } from "./registry/zenmux-free/index.ts"; +import { tinycmsProvider } from "./registry/tinycms/index.ts"; import { sumopodProvider } from "./registry/sumopod/index.ts"; import { x5labProvider } from "./registry/x5lab/index.ts"; import { kenariProvider } from "./registry/kenari/index.ts"; @@ -446,6 +447,7 @@ export const REGISTRY: Record = { "codebuddy-cn": codebuddy_cnProvider, pioneer: pioneerProvider, "zenmux-free": zenmux_freeProvider, + "tinycms-web": tinycmsProvider, sumopod: sumopodProvider, x5lab: x5labProvider, kenari: kenariProvider, diff --git a/open-sse/config/providers/registry/tinycms/index.ts b/open-sse/config/providers/registry/tinycms/index.ts new file mode 100644 index 0000000000..b124b3da07 --- /dev/null +++ b/open-sse/config/providers/registry/tinycms/index.ts @@ -0,0 +1,40 @@ +import type { RegistryEntry } from "../../shared.ts"; + +/** + * TinyCMS — session-cookie free-tier and subscription gateway. + * + * Users get a device UUID starting with "R" from site.tinycms.xyz (stored in localStorage + * as app-config-uuid) and paste it as the credential. + * + * Emulates the cryptographic signatures (WASM signer) and Proof of Work expected + * by the TinyCMS server. + */ +export const tinycmsProvider: RegistryEntry = { + id: "tinycms-web", + alias: "tcw", + format: "openai", + executor: "tinycms-web", + baseUrl: "https://gov.freegpt.win/api/openai/oneapi/v1/chat/completions", + authType: "apikey", + authHeader: "uuid", + models: [ + { id: "gpt-5-free", name: "GPT 5 Free" }, + { id: "gpt-5.3-free", name: "GPT 5.3 Free (Multimodal/Vision)" }, + { id: "gpt-5.3-thinking-free", name: "GPT 5.3 Thinking Free", supportsReasoning: true }, + { id: "gpt-5.4-mini", name: "GPT 5.4 Mini" }, + { id: "gpt-5.4-nano", name: "GPT 5.4 Nano" }, + { id: "gpt-5-nano", name: "GPT 5 Nano" }, + { id: "gemini-3.5-flash", name: "Gemini 3.5 Flash" }, + { id: "gemini-3-pro-preview", name: "Gemini 3 Pro Preview" }, + { id: "gemini-3.1-flash-lite-preview", name: "Gemini 3.1 Flash Lite Preview" }, + { id: "grok-4.20-fast", name: "Grok 4.20 Fast" }, + { id: "grok-4.20", name: "Grok 4.20" }, + { id: "grok-imagine", name: "Grok Imagine (Image Gen)" }, + { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash" }, + { id: "claude-sonnet-5", name: "Claude Sonnet 5" }, + { id: "gpt-image-2", name: "GPT Image 2 (Image Gen)" }, + { id: "qwen3.6-plus", name: "Qwen 3.6 Plus" }, + ], +}; + +export default tinycmsProvider; diff --git a/open-sse/executors/index.ts b/open-sse/executors/index.ts index 6b9477338b..1a1d5140ea 100644 --- a/open-sse/executors/index.ts +++ b/open-sse/executors/index.ts @@ -69,6 +69,7 @@ import { MimocodeExecutor } from "./mimocode.ts"; import { GrokCliExecutor } from "./grok-cli.ts"; import { CodeBuddyCnExecutor } from "./codebuddy-cn.ts"; import { ZenmuxFreeExecutor } from "./zenmux-free.ts"; +import { TinyCmsExecutor } from "./tinycms.ts"; import { HyperAgentExecutor } from "./hyperagent.ts"; import { XaiExecutor } from "./xai.ts"; import { PromptQlExecutor } from "./promptql.ts"; @@ -199,6 +200,8 @@ const executors = { "codebuddy-cn": new CodeBuddyCnExecutor(), cbcn: new CodeBuddyCnExecutor(), // Alias for codebuddy-cn "zenmux-free": new ZenmuxFreeExecutor(), + "tinycms-web": new TinyCmsExecutor(), + tcw: new TinyCmsExecutor(), // Alias hyperagent: new HyperAgentExecutor(), ha: new HyperAgentExecutor(), // Alias zmf: new ZenmuxFreeExecutor(), // Alias for zenmux-free @@ -297,6 +300,7 @@ export { MimocodeExecutor } from "./mimocode.ts"; export { GrokCliExecutor } from "./grok-cli.ts"; export { CodeBuddyCnExecutor } from "./codebuddy-cn.ts"; export { ZenmuxFreeExecutor } from "./zenmux-free.ts"; +export { TinyCmsExecutor } from "./tinycms.ts"; export { HyperAgentExecutor } from "./hyperagent.ts"; export { XaiExecutor } from "./xai.ts"; export { MoonshotExecutor } from "./moonshot.ts"; diff --git a/open-sse/executors/tinycms.ts b/open-sse/executors/tinycms.ts new file mode 100644 index 0000000000..4cbb0bf8f8 --- /dev/null +++ b/open-sse/executors/tinycms.ts @@ -0,0 +1,132 @@ +import { BaseExecutor, type ExecuteInput } from "./base.ts"; +import { makeExecutorErrorResult as makeErrorResult } from "../utils/error.ts"; +import { initTinyCmsWasm, generateSecurePayload } from "./tinycmsSigner.ts"; + +const CHAT_URL = "https://gov.freegpt.win/api/openai/oneapi/v1/chat/completions"; +const CHALLENGE_URL = "https://gov.freegpt.win/api/challenge"; + +let publicIp: string | null = null; +let lastIpFetch = 0; + +async function getPublicIp(): Promise { + const now = Date.now(); + if (publicIp && now - lastIpFetch < 300000) { + return publicIp; + } + try { + const res = await fetch("https://api64.ipify.org?format=json"); + const json = (await res.json()) as { ip: string }; + publicIp = json.ip; + lastIpFetch = now; + return publicIp; + } catch { + return publicIp || "127.0.0.1"; + } +} + +async function fetchChallenge(uuid: string): Promise { + const res = await fetch(CHALLENGE_URL, { + method: "GET", + headers: { + "uuid": uuid, + "x-origin": "https://gov.freegpt.win", + "Accept": "application/json", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", + }, + }); + if (!res.ok) { + throw new Error(`Failed to fetch challenge: ${res.status}`); + } + return await res.json(); +} + +export class TinyCmsExecutor extends BaseExecutor { + constructor() { + super("tinycms-web", { id: "tinycms-web", baseUrl: CHAT_URL }); + } + + async execute(input: ExecuteInput) { + const { body, credentials, signal } = input; + const bodyObj = (body || {}) as Record; + + // TinyCMS uses 'uuid' header for identification + const uuid = String(credentials?.apiKey ?? "").trim(); + if (!uuid || !uuid.startsWith("R")) { + return makeErrorResult( + 401, + "TinyCMS: Invalid or missing device UUID (must start with 'R')", + body, + CHAT_URL + ); + } + + try { + await initTinyCmsWasm(); + + const ip = await getPublicIp(); + const challengeObj = await fetchChallenge(uuid); + + const timestamp = Date.now().toString(); + const nonceJs = + typeof crypto !== "undefined" && crypto.randomUUID + ? crypto.randomUUID() + : `${Date.now()}-${Math.random().toString(16).slice(2)}`; + + const securePayload = generateSecurePayload( + uuid, + timestamp, + nonceJs, + challengeObj.challenge, + ip, + challengeObj.difficulty + ); + + const signedHeaders: Record = { + uuid: uuid, + "x-origin": "https://gov.freegpt.win", + referer: "https://gov.freegpt.win/", + "x-secure-challenge-id": challengeObj.challengeId, + "x-secure-challenge-expires-at": String(challengeObj.expiresAt), + "x-secure-challenge-version": challengeObj.version, + "x-secure-signature": securePayload.signature, + "x-secure-fingerprint": securePayload.fingerprint, + "x-secure-client-ip": securePayload.client_ip, + "x-secure-pow-seed-nonce": String(securePayload.pow.seed_nonce), + "x-secure-pow-nonce": String(securePayload.pow.nonce), + "x-secure-pow-hash": securePayload.pow.hash, + "x-secure-pow-difficulty": String(securePayload.pow.difficulty), + "x-secure-timestamp": timestamp, + "x-secure-nonce": nonceJs, + "x-secure-version": securePayload.v, + "x-session-id": nonceJs, + // Use configurable userid from providerSpecificData if present, otherwise generate one + // from the UUID (the server uses it for request attribution, not auth). + userid: String(credentials?.providerSpecificData?.userid ?? "") || uuid.slice(0, 20), + Accept: bodyObj.stream ? "text/event-stream" : "application/json", + "Content-Type": "application/json", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", + }; + + const fetchOptions: RequestInit = { + method: "POST", + headers: signedHeaders, + body: JSON.stringify(bodyObj), + signal, + }; + + const response = await fetch(CHAT_URL, fetchOptions); + return { + status: response.status, + headers: Object.fromEntries(response.headers.entries()), + body: response.body, + }; + } catch (err: any) { + return makeErrorResult( + 500, + `TinyCMS Error: ${err.message}`, + body, + CHAT_URL + ); + } + } +} diff --git a/open-sse/executors/tinycmsSigner.ts b/open-sse/executors/tinycmsSigner.ts new file mode 100644 index 0000000000..61c0a22469 --- /dev/null +++ b/open-sse/executors/tinycmsSigner.ts @@ -0,0 +1,509 @@ +// Runtime DOM shims for the wasm-bindgen glue code (compiled from Rust wasm-pack, +// targeting the browser). These are NOT test mocks — the WASM module calls into +// gl.bindTexImage2D-style canvas APIs via the wasm-bindgen generated JS, which +// expects window, document, HTMLCanvasElement, and CanvasRenderingContext2D at +// module load time. When running in Node.js (the OmniRoute server), these globals +// don't exist, so we provide minimal stubs that satisfy the wasm-bindgen +// constructor shape checks. The stubs are never called for actual rendering -- +// the WASM signer only uses the canvas to compute a hashed fingerprint value. +// +// Deliberately NOT a module-load side effect: installing these globals just by +// importing this file would leak `global.window`/`global.document` stubs into +// every other test file that transitively imports it (e.g. through the provider +// registry), even when that test never touches TinyCMS. `initTinyCmsWasm()` +// below calls `setupDomMocks()` once, right before instantiating the WASM +// module, on the production path. Tests call it explicitly in a before/ +// beforeEach hook and restore the previous globals via the returned callback in +// after/afterEach. +export type DomMockRestore = () => void; + +export function setupDomMocks(): DomMockRestore { + if (typeof global === 'undefined') return () => {}; + // Single typed handle to `global` so the rest of this function reads/writes + // window/document/HTMLCanvasElement/CanvasRenderingContext2D — none of which + // exist on Node's `global` type — through one cast instead of one per site. + const g = global as Record; + const hadWindow = 'window' in g; + const hadWindowCtor = 'Window' in g; + const hadCanvasElement = 'HTMLCanvasElement' in g; + const hadCanvasContext = 'CanvasRenderingContext2D' in g; + const hadDocument = 'document' in g; + + if (!g.window) g.window = g; + if (!g.Window) g.Window = function () {}; + if (!g.HTMLCanvasElement) g.HTMLCanvasElement = function () {}; + if (!g.CanvasRenderingContext2D) g.CanvasRenderingContext2D = function () {}; + if (!g.document) { + g.document = { + createElement(tag: string) { + if (tag === 'canvas') { + const canvas = { + width: 100, + height: 100, + getContext(type: string) { + if (type === '2d') { + const ctx = { + fillStyle: '', + font: '', + fillRect() {}, + fillText() {}, + toDataURL() { return 'data:image/png;base64,MOCK_DATA'; } + }; + Object.setPrototypeOf(ctx, g.CanvasRenderingContext2D.prototype); + return ctx; + } + return null; + }, + toDataURL() { return 'data:image/png;base64,MOCK_DATA'; } + }; + Object.setPrototypeOf(canvas, g.HTMLCanvasElement.prototype); + return canvas; + } + return null; + } + }; + } + Object.setPrototypeOf(g.window, g.Window.prototype); + + return () => { + if (!hadWindow) delete g.window; + if (!hadWindowCtor) delete g.Window; + if (!hadCanvasElement) delete g.HTMLCanvasElement; + if (!hadCanvasContext) delete g.CanvasRenderingContext2D; + if (!hadDocument) delete g.document; + }; +} + +// WASM binary compiled from the TinyCMS signer wasm-bindgen source +// (wasm_signer_bg.wasm). Extracted from the upstream client's +// wasm_signer_bg.js wasm-bindgen glue at build time — the WebAssembly module +// implements the cryptographic signature + Proof-of-Work routines the +// TinyCMS server requires for anti-abuse challenge verification. +// The source .wasm is compiled from Rust via wasm-pack (wasm-bindgen), +// targeting the browser environment. +const WASM_BASE64 = "AGFzbQEAAAABkQIoYAJ/fwF/YAJ/fwBgA39/fwF/YAF/AGADf39/AGAFf39/f38AYAR/f39/AGAAAX9gAW8Bf2AEf39/fwF/YAZ/f39/f38AYAAAYAF/AX9gAn9vAGACb38AYANvf38AYAJ/fwFvYAV/f35/fwBgBX9/fX9/AGAFf398f38AYAV/f39/fwF/YAADf39/YANvb28AYANvf38Bb2ADb39/AX9gBW98fHx8AGAFb39/fHwAYAABb2AAAXxgAXwBb2ABfgFvYAZ/f39+f38AYAZ/f399f38AYAZ/f398f38AYAt/f39/f39/f39/fwN/f39gBn9/f39/fwF/YAR/fX9/AGAEf3x/fwBgBH9+f38AYAF8AX8C9QwcEy4vd2FzbV9zaWduZXJfYmcuanMaX193Ymdfc2V0XzZiZTQyNzY4YzY5MGUzODAAFhMuL3dhc21fc2lnbmVyX2JnLmpzHV9fd2JnX1N0cmluZ184NTY0ZTU1OTc5OWVjY2RhAA0TLi93YXNtX3NpZ25lcl9iZy5qcyhfX3diZ19pbnN0YW5jZW9mX1dpbmRvd18yM2U2NzdkMmM2ODQzOTIyAAgTLi93YXNtX3NpZ25lcl9iZy5qcx9fX3diZ19kb2N1bWVudF9jMDMyMGNkNDE4M2M2ZDliAAgTLi93YXNtX3NpZ25lcl9iZy5qcyRfX3diZ19jcmVhdGVFbGVtZW50XzliMGFhYjI2NWM1NDlkZWQAFxMuL3dhc21fc2lnbmVyX2JnLmpzIV9fd2JnX3NldF9oZWlnaHRfYjY1NDhhMDFiZGNiNjg5YQAOEy4vd2FzbV9zaWduZXJfYmcuanMhX193YmdfZ2V0Q29udGV4dF9mMDRiZjhmMjJkY2IyZDUzABgTLi93YXNtX3NpZ25lcl9iZy5qcyBfX3diZ190b0RhdGFVUkxfYmY5OWQ4NWIzOWNlNTdjYwANEy4vd2FzbV9zaWduZXJfYmcuanMgX193Ymdfc2V0X3dpZHRoX2MwZmNhYTJkYTUzY2Q1NDAADhMuL3dhc21fc2lnbmVyX2JnLmpzM19fd2JnX2luc3RhbmNlb2ZfSHRtbENhbnZhc0VsZW1lbnRfMjYxMjUzMzlmOTM2YmU1MAAIEy4vd2FzbV9zaWduZXJfYmcuanM6X193YmdfaW5zdGFuY2VvZl9DYW52YXNSZW5kZXJpbmdDb250ZXh0MmRfMDhiOWQxOTNjMjJmYTg4NgAIEy4vd2FzbV9zaWduZXJfYmcuanMkX193Ymdfc2V0X2ZpbGxTdHlsZV81ODQxN2I2YjU0OGFlNDc1AA8TLi93YXNtX3NpZ25lcl9iZy5qcx9fX3diZ19zZXRfZm9udF9iMDM4Nzk3YjM1NzNhZTVlAA8TLi93YXNtX3NpZ25lcl9iZy5qcx9fX3diZ19maWxsUmVjdF80ZTU1OTZjYTk1NDIyNmU3ABkTLi93YXNtX3NpZ25lcl9iZy5qcx9fX3diZ19maWxsVGV4dF9iMTcyMmI2MTc5NjkyYjg1ABoTLi93YXNtX3NpZ25lcl9iZy5qcxpfX3diZ19uZXdfYWI3OWRmNWJkN2MyNjA2NwAbEy4vd2FzbV9zaWduZXJfYmcuanMyX193Ymdfc3RhdGljX2FjY2Vzc29yX0dMT0JBTF9USElTX2FkMzU2ZTBkYjkxYzc5MTMABxMuL3dhc21fc2lnbmVyX2JnLmpzK19fd2JnX3N0YXRpY19hY2Nlc3Nvcl9TRUxGX2YyMDdjODU3NTY2ZGIyNDgABxMuL3dhc21fc2lnbmVyX2JnLmpzLV9fd2JnX3N0YXRpY19hY2Nlc3Nvcl9HTE9CQUxfOGFkYjk1NWJkMzNmYWMyZgAHEy4vd2FzbV9zaWduZXJfYmcuanMtX193Ymdfc3RhdGljX2FjY2Vzc29yX1dJTkRPV19iYjlmMWJhNjlkNjFiMzg2AAcTLi93YXNtX3NpZ25lcl9iZy5qcx1fX3diZ19yYW5kb21fNWJiODZjYWU2NWE0NWJmNgAcEy4vd2FzbV9zaWduZXJfYmcuanMnX193YmdfX193YmluZGdlbl90aHJvd182ZGRkNjA5YjYyOTQwZDU1AAETLi93YXNtX3NpZ25lcl9iZy5qcxxfX3diZ19FcnJvcl84Mzc0MmI0NmYwMWNlMjJkABATLi93YXNtX3NpZ25lcl9iZy5qcy5fX3diZ19fX3diaW5kZ2VuX2lzX3VuZGVmaW5lZF81MjcwOWU3MmZiOWYxNzljAAgTLi93YXNtX3NpZ25lcl9iZy5qcx9fX3diaW5kZ2VuX2luaXRfZXh0ZXJucmVmX3RhYmxlAAsTLi93YXNtX3NpZ25lcl9iZy5qcyBfX3di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AEGMmMAAQYCYwAA2AgBBgJjAAEH4l8AANgIAQZSYwABBiJjAADYCAEGImMAAQYCYwAA2AgBBnJjAAEGQmMAANgIAQZCYwABBiJjAADYCAEGkmMAAQZiYwAA2AgBBmJjAAEGQmMAANgIAQayYwABBoJjAADYCAEGgmMAAQZiYwAA2AgBBtJjAAEGomMAANgIAQaiYwABBoJjAADYCAEG8mMAAQbCYwAA2AgBBsJjAAEGomMAANgIAQcSYwABBuJjAADYCAEG4mMAAQbCYwAA2AgBBzJjAAEHAmMAANgIAQcCYwABBuJjAADYCAEHkmMAAIAFBD2pBeHEiAEEIayICNgIAQciYwABBwJjAADYCAEHcmMAAIARBKGsiBCABIABrakEIaiIANgIAIAIgAEEBcjYCBCABIARqQSg2AgRB8JjAAEGAgIABNgIADAgLIAIgA0kgASACTXINACAAKAIMIgNBAXENACADQQF2IAdGDQMLQfSYwABB9JjAACgCACIAIAEgACABSRs2AgAgASAEaiEDQbiWwAAhAAJAAkADQCADIAAoAgAiBkcEQCAAKAIIIgANAQwCCwsgACgCDCIDQQFxDQAgA0EBdiAHRg0BC0G4lsAAIQADQAJAIAIgACgCACIDTwRAIAIgAyAAKAIEaiIGSQ0BCyAAKAIIIQAMAQsLQeSYwAAgAUEPakF4cSIAQQhrIgM2AgBB3JjAACAEQShrIgkgASAAa2pBCGoiADYCACADIABBAXI2AgQgASAJakEoNgIEQfCYwABBgICAATYCACACIAZBIGtBeHFBCGsiACAAIAJBEGpJGyIDQRs2AgRBuJbAACkCACEKIANBEGpBwJbAACkCADcCACADQQhqIgAgCjcCAEHElsAAIAc2AgBBvJbAACAENgIAQbiWwAAgATYCAEHAlsAAIAA2AgAgA0EcaiEAA0AgAEEHNgIAIABBBGoiACAGSQ0ACyACIANGDQcgAyADKAIEQX5xNgIEIAIgAyACayIAQQFyNgIEIAMgADYCACAAQYACTwRAIAIgABApDAgLAkBB0JjAACgCACIBQQEgAEEDdnQiBHFFBEBB0JjAACABIARyNgIAIABB+AFxQciWwABqIgAhAQwBCyAAQfgBcSIAQciWwABqIQEgAEHQlsAAaigCACEACyABIAI2AgggACACNgIMIAIgATYCDCACIAA2AggMBwsgACABNgIAIAAgACgCBCAEajYCBCABQQ9qQXhxQQhrIgQgBUEDcjYCBCAGQQ9qQXhxQQhrIgMgBCAFaiIAayEFIANB5JjAACgCAEYNAyADQeCYwAAoAgBGDQQgAygCBCICQQNxQQFGBEAgAyACQXhxIgEQJyABIAVqIQUgASADaiIDKAIEIQILIAMgAkF+cTYCBCAAIAVBAXI2AgQgACAFaiAFNgIAIAVBgAJPBEAgACAFECkMBgsCQEHQmMAAKAIAIgFBASAFQQN2dCICcUUEQEHQmMAAIAEgAnI2AgAgBUH4AXFByJbAAGoiBSEDDAELIAVB+AFxIgFByJbAAGohAyABQdCWwABqKAIAIQULIAMgADYCCCAFIAA2AgwgACADNgIMIAAgBTYCCAwFC0HcmMAAIAAgBWsiATYCAEHkmMAAQeSYwAAoAgAiACAFaiICNgIAIAIgAUEBcjYCBCAAIAVBA3I2AgQgAEEIaiEADAYLQeCYwAAoAgAhAAJAIAEgBWsiAkEPTQRAQeCYwABBADYCAEHYmMAAQQA2AgAgACABQQNyNgIEIAAgAWoiASABKAIEQQFyNgIEDAELQdiYwAAgAjYCAEHgmMAAIAAgBWoiBDYCACAEIAJBAXI2AgQgACABaiACNgIAIAAgBUEDcjYCBAsgAEEIaiEADAULIAAgBCAGajYCBEHkmMAAQeSYwAAoAgAiAEEPakF4cSIBQQhrIgI2AgBB3JjAAEHcmMAAKAIAIARqIgQgACABa2pBCGoiATYCACACIAFBAXI2AgQgACAEakEoNgIEQfCYwABBgICAATYCAAwDC0HkmMAAIAA2AgBB3JjAAEHcmMAAKAIAIAVqIgE2AgAgACABQQFyNgIEDAELQeCYwAAgADYCAEHYmMAAQdiYwAAoAgAgBWoiATYCACAAIAFBAXI2AgQgACABaiABNgIACyAEQQhqIQAMAQtBACEAQdyYwAAoAgAiASAFTQ0AQdyYwAAgASAFayIBNgIAQeSYwABB5JjAACgCACIAIAVqIgI2AgAgAiABQQFyNgIEIAAgBUEDcjYCBCAAQQhqIQALIAhBEGokACAAC/EDAgh/AX5BASEJQStBgIDEACAAKAIIIgRBgICAAXEiAxshCiADQRV2IAJqIQMCQCAEQYCAgARxRQRAQQAhCQwBCwsCQCAALwEMIgcgA0sEQAJAAkAgBEGAgIAIcUUEQCAHIANrIQdBACEDAkACQAJAIARBHXZBA3FBAWsOAwABAAILIAchAwwBCyAHQf7/A3FBAXYhAwsgBEH///8AcSEIIAAoAgQhBiAAKAIAIQADQCAFQf//A3EgA0H//wNxTw0CQQEhBCAFQQFqIQUgACAIIAYoAhARAABFDQALDAQLIAAgACkCCCILp0GAgID/eXFBsICAgAJyNgIIQQEhBCAAKAIAIgYgACgCBCIIIAogCRBQDQMgByADa0H//wNxIQMDQCAFQf//A3EgA08NAiAFQQFqIQUgBkEwIAgoAhARAABFDQALDAMLQQEhBCAAIAYgCiAJEFANAiAAIAEgAiAGKAIMEQIADQJBACEFIAcgA2tB//8DcSEBA0AgBUH//wNxIgIgAUkhBCABIAJNDQMgBUEBaiEFIAAgCCAGKAIQEQAARQ0ACwwCCyAGIAEgAiAIKAIMEQIADQEgACALNwIIQQAPC0EBIQQgACgCACIDIAAoAgQiACAKIAkQUA0AIAMgASACIAAoAgwRAgAhBAsgBAuUBgEFfyAAQQhrIgEgAEEEaygCACIDQXhxIgBqIQICQAJAIANBAXENACADQQJxRQ0BIAEoAgAiAyAAaiEAIAEgA2siAUHgmMAAKAIARgRAIAIoAgRBA3FBA0cNAUHYmMAAIAA2AgAgAiACKAIEQX5xNgIEIAEgAEEBcjYCBCACIAA2AgAPCyABIAMQJwsCQAJAAkACQAJAIAIoAgQiA0ECcUUEQCACQeSYwAAoAgBGDQIgAkHgmMAAKAIARg0DIAIgA0F4cSICECcgASAAIAJqIgBBAXI2AgQgACABaiAANgIAIAFB4JjAACgCAEcNAUHYmMAAIAA2AgAPCyACIANBfnE2AgQgASAAQQFyNgIEIAAgAWogADYCAAsgAEGAAkkNAiABIAAQKUEAIQFB+JjAAEH4mMAAKAIAQQFrIgA2AgAgAA0EQcCWwAAoAgAiAARAA0AgAUEBaiEBIAAoAggiAA0ACwtB+JjAAEH/HyABIAFB/x9NGzYCAA8LQeSYwAAgATYCAEHcmMAAQdyYwAAoAgAgAGoiADYCACABIABBAXI2AgRB4JjAACgCACABRgRAQdiYwABBADYCAEHgmMAAQQA2AgALIABB8JjAACgCACIDTQ0DQeSYwAAoAgAiAkUNA0EAIQBB3JjAACgCACIEQSlJDQJBuJbAACEBA0AgAiABKAIAIgVPBEAgAiAFIAEoAgRqSQ0ECyABKAIIIQEMAAsAC0HgmMAAIAE2AgBB2JjAAEHYmMAAKAIAIABqIgA2AgAgASAAQQFyNgIEIAAgAWogADYCAA8LAkBB0JjAACgCACICQQEgAEEDdnQiA3FFBEBB0JjAACACIANyNgIAIABB+AFxQciWwABqIgAhAgwBCyAAQfgBcSIAQciWwABqIQIgAEHQlsAAaigCACEACyACIAE2AgggACABNgIMIAEgAjYCDCABIAA2AggPC0HAlsAAKAIAIgEEQANAIABBAWohACABKAIIIgENAAsLQfiYwABB/x8gACAAQf8fTRs2AgAgAyAETw0AQfCYwABBfzYCAAsLiAsBC38CQAJAIAAoAggiDUGAgIDAAXFFDQACQAJAAkACQCANQYCAgIABcQRAIAAvAQ4iBA0BQQAhAgwCCyACQRBPBEACfwJAAkAgAiABQQNqQXxxIgUgAWsiA0kNACACIANrIgtBBEkNACABIAVHBEAgASAFayIFQXxNBEADQCAEIAEgCWoiBiwAAEG/f0pqIAZBAWosAABBv39KaiAGQQJqLAAAQb9/SmogBkEDaiwAAEG/f0pqIQQgCUEEaiIJDQALCyABIAlqIQgDQCAEIAgsAABBv39KaiEEIAhBAWohCCAFQQFqIgUNAAsLIAEgA2ohBQJAIAtBA3EiBkUNACAFIAtBfHFqIgMsAABBv39KIQogBkEBRg0AIAogAywAAUG/f0pqIQogBkECRg0AIAogAywAAkG/f0pqIQoLIAtBAnYhDCAEIApqIQkDQCAFIQMgDEUNAkHAASAMIAxBwAFPGyIHQQNxIQoCQCAHQQJ0IgtB8AdxIgVFBEBBACEIDAELQQAhCCADIQQDQCAIIAQoAgAiBkF/c0EHdiAGQQZ2ckGBgoQIcWogBEEEaigCACIGQX9zQQd2IAZBBnZyQYGChAhxaiAEQQhqKAIAIgZBf3NBB3YgBkEGdnJBgYKECHFqIARBDGooAgAiBkF/c0EHdiAGQQZ2ckGBgoQIcWohCCAEQRBqIQQgBUEQayIFDQALCyAMIAdrIQwgAyALaiEFIAhBCHZB/4H8B3EgCEH/gfwHcWpBgYAEbEEQdiAJaiEJIApFDQALAn8gAyAHQfwBcUECdGoiBCgCACIDQX9zQQd2IANBBnZyQYGChAhxIgUgCkEBRg0AGiAFIAQoAgQiA0F/c0EHdiADQQZ2ckGBgoQIcWoiAyAKQQJGDQAaIAMgBCgCCCIDQX9zQQd2IANBBnZyQYGChAhxagsiA0EIdkH/gRxxIANB/4H8B3FqQYGABGxBEHYgCWohCQwBC0EAIAJFDQEaIAJBA3EhBSACQQRPBEAgAkF8cSEDA0AgCSABIAhqIgQsAABBv39KaiAEQQFqLAAAQb9/SmogBEECaiwAAEG/f0pqIARBA2osAABBv39KaiEJIAMgCEEEaiIIRw0ACwsgBUUNACABIAhqIQQDQCAJIAQsAABBv39KaiEJIARBAWohBCAFQQFrIgUNAAsLIAkLIQcMBAsgAkUEQEEAIQIMBAsgAkEDcSEGIAJBBE8EQCACQQxxIQMDQCAHIAEgBWoiBCwAAEG/f0pqIARBAWosAABBv39KaiAEQQJqLAAAQb9/SmogBEEDaiwAAEG/f0pqIQcgAyAFQQRqIgVHDQALCyAGRQ0DIAEgBWohAwNAIAcgAywAAEG/f0pqIQcgA0EBaiEDIAZBAWsiBg0ACwwDCyABIAJqIQtBACECIAEhAyAEIQUDQCADIgYgC0YNAiACAn8gA0EBaiADLAAAIgJBAE4NABogA0ECaiACQWBJDQAaIANBA2ogAkFwSQ0AGiADQQRqCyIDIAZraiECIAVBAWsiBQ0ACwtBACEFCyAEIAVrIQcLIAcgAC8BDCIDTw0AIAMgB2shBEEAIQdBACEFAkACQAJAIA1BHXZBA3FBAWsOAgABAgsgBCEFDAELIARB/v8DcUEBdiEFCyANQf///wBxIQYgACgCBCEKIAAoAgAhCwNAIAdB//8DcSAFQf//A3FJBEBBASEDIAdBAWohByALIAYgCigCEBEAAEUNAQwDCwtBASEDIAsgASACIAooAgwRAgANAUEAIQcgBCAFa0H//wNxIQEDQCAHQf//A3EiACABSSEDIAAgAU8NAiAHQQFqIQcgCyAGIAooAhARAABFDQALDAELIAAoAgAgASACIAAoAgQoAgwRAgAhAwsgAwuTFAIVfwN+IwBBEGsiFCQAQaSVwAAtAABBAUcEQAJAIwBBIGsiAyQAAkACQAJAQaSVwAAtAABBAWsOAgACAQtBpJXAAEECOgAAQZiVwAAoAgAiCkUNAEGglcAAKAIAIgUEQEGUlcAAKAIAIghBCGohBiAIKQMAQn+FQoCBgoSIkKDAgH+DIRcDQCAXUARAA0AgCEHgAGshCCAGKQMAIAZBCGohBkKAgYKEiJCgwIB/gyIXQoCBgoSIkKDAgH9RDQALIBdCgIGChIiQoMCAf4UhFwsgCCAXeqdBA3ZBdGxqQQRrKAIAIgRBhAhPBEAgBBA8CyAXQgF9IBeDIRcgBUEBayIFDQALCyAKIApBDGxBE2pBeHEiBWpBCWoiBEUNAEGUlcAAKAIAIAVrIAQQdgtBpJXAAEEBOgAAQZSVwABBiInAACkCADcCAEGclcAAQZCJwAApAgA3AgBBkJXAAEEANgIAIANBIGokAAwBCyADQQA2AhggA0EBNgIMIANB2InAADYCCCADQgQ3AhAgA0EIakHgicAAEFIACwtBkJXAACgCAEUEQEGQlcAAQX82AgBBmJXAACgCACIFIABxIQMgAEEZdiIVrUKBgoSIkKDAgAF+IRhBlJXAACgCACEEAkADQCADIARqKQAAIhkgGIUiF0J/hSAXQoGChIiQoMCAAX2DQoCBgoSIkKDAgH+DIhdQRQRAA0AgACAEIBd6p0EDdiADaiAFcUF0bGoiCEEMaygCAEYEQCAIQQhrKAIAIAFGDQQLIBdCAX0gF4MiF1BFDQALCyAZIBlCAYaDQoCBgoSIkKDAgH+DUARAIAMgAkEIaiICaiAFcSEDDAELC0GclcAAKAIARQRAIBRBCGohFiMAQSBrIg4kAAJAQaCVwAAoAgAiCkEBaiIEIApPBEBBmJXAACgCACILIAtBAWoiDEEDdiICQQdsIAtBCEkbIhFBAXYgBEkEQAJAAkACQAJAAkACfyARQQFqIgIgBCACIARLGyICQQ9PBEAgAkH/////AUsNAkF/IAJBA3RBB25BAWtndkEBagwBC0EEIAJBCHFBCGogAkEESRsLIgStQgx+IhdCIIinDQIgF6ciAkF4Sw0CIAJBB2pBeHEiAyAEQQhqIgVqIgYgA0kgBkH4////B0tyDQIgBkEIEHkiAg0BQQggBhB/AAsQSiAOKAIcIQQgDigCGCEDDAYLIAIgA2ohDSAFBEAgDUH/ASAF/AsACyAEQQFrIgkgBEEDdkEHbCAJQQhJGyEQIAoNAUGUlcAAKAIAIQIMAgsQSiAOKAIMIQQgDigCCCEDDAQLIA1BDGshESANQQhqIRJBlJXAACgCACICQQxrIQwgAikDAEJ/hUKAgYKEiJCgwIB/gyEYQQAhBCAKIQUgAiEDA0AgGFAEQANAIARBCGohBCADQQhqIgMpAwBCgIGChIiQoMCAf4MiF0KAgYKEiJCgwIB/UQ0ACyAXQoCBgoSIkKDAgH+FIRgLIA0gDCAYeqdBA3YgBGoiE0F0bGoiCCgCACIGIAgoAgQgBhsiCCAJcSIHaikAAEKAgYKEiJCgwIB/gyIXUARAQQghDwNAIAcgD2ohBiAPQQhqIQ8gDSAGIAlxIgdqKQAAQoCBgoSIkKDAgH+DIhdQDQALCyAYQgF9IBiDIRggDSAXeqdBA3YgB2ogCXEiB2osAABBAE4EQCANKQMAQoCBgoSIkKDAgH+DeqdBA3YhBwsgByANaiAIQRl2IgY6AAAgEiAHQQhrIAlxaiAGOgAAIBEgB0F0bGoiCEEIaiAMIBNBdGxqIgZBCGooAAA2AAAgCCAGKQAANwAAIAVBAWsiBQ0ACwtBmJXAACAJNgIAQZSVwAAgDTYCAEGclcAAIBAgCms2AgBBgYCAgHghAyALRQ0CIAsgC0EMbEETakF4cSIEakEJaiIFRQ0CIAIgBGsgBRB2DAILIAwEQEGUlcAAKAIAIQdBACEEIAIgDEEHcUEAR2oiAkEBcSACQQFHBEAgAkH+////A3EhAgNAIAQgB2oiBSAFKQMAIhdCf4VCB4hCgYKEiJCgwIABgyAXQv/+/fv379+//wCEfDcDACAFQQhqIgUgBSkDACIXQn+FQgeIQoGChIiQoMCAAYMgF0L//v379+/fv/8AhHw3AwAgBEEQaiEEIAJBAmsiAg0ACwsEQCAEIAdqIgIgAikDACIXQn+FQgeIQoGChIiQoMCAAYMgF0L//v379+/fv/8AhHw3AwALIAdBCGohEAJAIAxBCE8EQCAHIAxqIAcpAAA3AAAMAQsgDEUNACAQIAcgDPwKAAALIAdBDGshEkEBIQJBACEEA0AgBCEFIAIhBAJAIAUgB2oiEy0AAEGAAUcNACASIAVBdGxqIQkCQANAIAkoAgAiAiAJKAIEIAIbIgggC3EiAyECIAMgB2opAABCgIGChIiQoMCAf4MiGFAEQEEIIQ8DQCACIA9qIQIgD0EIaiEPIAcgAiALcSICaikAAEKAgYKEiJCgwIB/gyIYUA0ACwsgByAYeqdBA3YgAmogC3EiAmosAABBAE4EQCAHKQMAQoCBgoSIkKDAgH+DeqdBA3YhAgsgAiADayAFIANrcyALcUEITwRAIAIgB2oiAy0AACADIAhBGXYiAzoAACAQIAJBCGsgC3FqIAM6AAAgEiACQXRsaiEDQf8BRg0CIAkoAAAhAiAJIAMoAAA2AAAgAyACNgAAIAMoAAQhAiADIAkoAAQ2AAQgCSACNgAEIAkoAAghAiAJIAMoAAg2AAggAyACNgAIDAELCyATIAhBGXYiAjoAACAQIAVBCGsgC3FqIAI6AAAMAQsgE0H/AToAACAQIAVBCGsgC3FqQf8BOgAAIANBCGogCUEIaigAADYAACADIAkpAAA3AAALIAQgBCAMSSIFaiECIAUNAAsLQZyVwAAgESAKazYCAEGBgICAeCEDDAELEEogDigCBCEEIA4oAgAhAwsgFiAENgIEIBYgAzYCACAOQSBqJAALIAAgARBnIQRBlJXAACgCACIKQZiVwAAoAgAiBSAAcSIDaikAAEKAgYKEiJCgwIB/gyIXUARAQQghBgNAIAMgBmohAiAGQQhqIQYgCiACIAVxIgNqKQAAQoCBgoSIkKDAgH+DIhdQDQALCyAKIBd6p0EDdiADaiAFcSIDaiwAACIGQQBOBEAgCiAKKQMAQoCBgoSIkKDAgH+DeqdBA3YiA2otAAAhBgsgAyAKaiAVOgAAIAogA0EIayAFcWpBCGogFToAAEGclcAAQZyVwAAoAgAgBkEBcWs2AgBBoJXAAEGglcAAKAIAQQFqNgIAIAogA0F0bGoiCEEEayAENgIAIAhBCGsgATYCACAIQQxrIAA2AgALIAhBBGsoAgAQdUGQlcAAQZCVwAAoAgBBAWo2AgAgFEEQaiQADwtB8IjAABCEAQALuAQBCH8jAEEQayIDJAAgAyABNgIEIAMgADYCACADQqCAgIAONwIIAn8CQAJAAkAgAigCECIJBEAgAigCFCIADQEMAgsgAigCDCIARQ0BIAIoAggiASAAQQN0IgBqIQQgAEEIa0EDdkEBaiEGIAIoAgAhAANAAkAgAEEEaigCACIFRQ0AIAMoAgAgACgCACAFIAMoAgQoAgwRAgBFDQBBAQwFC0EBIAEoAgAgAyABQQRqKAIAEQAADQQaIABBCGohACAEIAFBCGoiAUcNAAsMAgsgAEEYbCEKIABBAWtB/////wFxQQFqIQYgAigCCCEEIAIoAgAhAANAAkAgAEEEaigCACIBRQ0AIAMoAgAgACgCACABIAMoAgQoAgwRAgBFDQBBAQwEC0EAIQdBACEIAkACQAJAIAUgCWoiAUEIai8BAEEBaw4CAQIACyABQQpqLwEAIQgMAQsgBCABQQxqKAIAQQN0ai8BBCEICwJAAkACQCABLwEAQQFrDgIBAgALIAFBAmovAQAhBwwBCyAEIAFBBGooAgBBA3RqLwEEIQcLIAMgBzsBDiADIAg7AQwgAyABQRRqKAIANgIIQQEgBCABQRBqKAIAQQN0aiIBKAIAIAMgASgCBBEAAA0DGiAAQQhqIQAgBUEYaiIFIApHDQALDAELCwJAIAYgAigCBE8NACADKAIAIAIoAgAgBkEDdGoiACgCACAAKAIEIAMoAgQoAgwRAgBFDQBBAQwBC0EACyADQRBqJAALjwQBAn8gACABaiECAkACQCAAKAIEIgNBAXENACADQQJxRQ0BIAAoAgAiAyABaiEBIAAgA2siAEHgmMAAKAIARgRAIAIoAgRBA3FBA0cNAUHYmMAAIAE2AgAgAiACKAIEQX5xNgIEIAAgAUEBcjYCBCACIAE2AgAMAgsgACADECcLAkACQAJAIAIoAgQiA0ECcUUEQCACQeSYwAAoAgBGDQIgAkHgmMAAKAIARg0DIAIgA0F4cSICECcgACABIAJqIgFBAXI2AgQgACABaiABNgIAIABB4JjAACgCAEcNAUHYmMAAIAE2AgAPCyACIANBfnE2AgQgACABQQFyNgIEIAAgAWogATYCAAsgAUGAAk8EQCAAIAEQKQ8LAkBB0JjAACgCACICQQEgAUEDdnQiA3FFBEBB0JjAACACIANyNgIAIAFB+AFxQciWwABqIgEhAgwBCyABQfgBcSIBQciWwABqIQIgAUHQlsAAaigCACEBCyACIAA2AgggASAANgIMIAAgAjYCDCAAIAE2AggPC0HkmMAAIAA2AgBB3JjAAEHcmMAAKAIAIAFqIgE2AgAgACABQQFyNgIEIABB4JjAACgCAEcNAUHYmMAAQQA2AgBB4JjAAEEANgIADwtB4JjAACAANgIAQdiYwABB2JjAACgCACABaiIBNgIAIAAgAUEBcjYCBCAAIAFqIAE2AgALC5kEAQd/IwBBMGsiBCQAAkACQAJAAkAgASgCBCICBEAgASgCACEGIAJBA3EhBQJAIAJBBEkEQEEAIQIMAQsgBkEcaiEDIAJBfHEhCEEAIQIDQCADKAIAIANBCGsoAgAgA0EQaygCACADQRhrKAIAIAJqampqIQIgA0EgaiEDIAggB0EEaiIHRw0ACwsgBQRAIAdBA3QgBmpBBGohAwNAIAMoAgAgAmohAiADQQhqIQMgBUEBayIFDQALCyABKAIMRQ0CIAJBD0sNASAGKAIEDQEMAwtBACECIAEoAgxFDQILIAJBACACQQBKG0EBdCECC0EAIQMgAkEATgRAIAJFDQFBASEDIAJBARB5IgUNAgsgAyACEGEAC0EBIQVBACECCyAEQQA2AgwgBCAFNgIIIAQgAjYCBCAEQSBqIAFBEGopAgA3AwAgBEEYaiABQQhqKQIANwMAIAQgASkCADcDECAEQQRqQbCQwAAgBEEQahAiRQRAIAAgBCkCBDcCACAAQQhqIARBDGooAgA2AgAgBEEwaiQADwsjAEFAaiIAJAAgAEHWADYCDCAAQZyPwAA2AgggAEGMj8AANgIUIAAgBEEvajYCECAAQQI2AhwgAEGclMAANgIYIABCAjcCJCAAIABBEGqtQoCAgICACIQ3AzggACAAQQhqrUKAgICA8AeENwMwIAAgAEEwajYCICAAQRhqQfSPwAAQUgALwQMBB38jAEEgayICJAAgAkEANgIMIAJCgICAgBA3AgQgASgCDCEEIAEoAggiAyABKAIEIgdrQQF0IAEoAgAiAUGAgMQAR3IiBQRAIAJBBGpBACAFEDgLIAIgBDYCHCACIAM2AhggAiAHNgIUIAIgATYCECACQRBqEEAiAUGAgMQARwRAIAIoAgwhBANAIAQhAwJ/QQEgAUGAAUkiBQ0AGkECIAFBgBBJDQAaQQNBBCABQYCABEkbCyIHIAIoAgQgBGtLBH8gAkEEaiAEIAcQOCACKAIMBSADCyACKAIIaiEDAkAgBUUEQCABQT9xQYB/ciEFIAFBBnYhBiABQYAQSQRAIAMgBToAASADIAZBwAFyOgAADAILIAFBDHYhCCAGQT9xQYB/ciEGIAFB//8DTQRAIAMgBToAAiADIAY6AAEgAyAIQeABcjoAAAwCCyADIAU6AAMgAyAGOgACIAMgCEE/cUGAf3I6AAEgAyABQRJ2QXByOgAADAELIAMgAToAAAsgAiAEIAdqIgQ2AgwgAkEQahBAIgFBgIDEAEcNAAsLIAAgAikCBDcCACAAQQhqIAJBDGooAgA2AgAgAkEgaiQAC+cCAQV/AkAgAUHN/3tBECAAIABBEE0bIgBrTw0AIABBECABQQtqQXhxIAFBC0kbIgRqQQxqEB0iAkUNACACQQhrIQECQCAAQQFrIgMgAnFFBEAgASEADAELIAJBBGsiBSgCACIGQXhxIAIgA2pBACAAa3FBCGsiAiAAQQAgAiABa0EQTRtqIgAgAWsiAmshAyAGQQNxBEAgACADIAAoAgRBAXFyQQJyNgIEIAAgA2oiAyADKAIEQQFyNgIEIAUgAiAFKAIAQQFxckECcjYCACABIAJqIgMgAygCBEEBcjYCBCABIAIQIwwBCyABKAIAIQEgACADNgIEIAAgASACajYCAAsCQCAAKAIEIgFBA3FFDQAgAUF4cSICIARBEGpNDQAgACAEIAFBAXFyQQJyNgIEIAAgBGoiASACIARrIgRBA3I2AgQgACACaiICIAIoAgRBAXI2AgQgASAEECMLIABBCGohAwsgAwuCAwEEfyAAKAIMIQICQAJAAkAgAUGAAk8EQCAAKAIYIQMCQAJAIAAgAkYEQCAAQRRBECAAKAIUIgIbaigCACIBDQFBACECDAILIAAoAggiASACNgIMIAIgATYCCAwBCyAAQRRqIABBEGogAhshBANAIAQhBSABIgJBFGogAkEQaiACKAIUIgEbIQQgAkEUQRAgARtqKAIAIgENAAsgBUEANgIACyADRQ0CAkAgACgCHEECdEG4lcAAaiIBKAIAIABHBEAgAygCECAARg0BIAMgAjYCFCACDQMMBAsgASACNgIAIAJFDQQMAgsgAyACNgIQIAINAQwCCyAAKAIIIgAgAkcEQCAAIAI2AgwgAiAANgIIDwtB0JjAAEHQmMAAKAIAQX4gAUEDdndxNgIADwsgAiADNgIYIAAoAhAiAQRAIAIgATYCECABIAI2AhgLIAAoAhQiAEUNACACIAA2AhQgACACNgIYDwsPC0HUmMAAQdSYwAAoAgBBfiAAKAIcd3E2AgAL8wIBBX8jAEEQayIDJAACQEH4lMAAKAIARQRAQfiUwABBfzYCAEGIlcAAKAIAIgBBhJXAACgCACIBRgRAAn8gACAAQfyUwAAoAgAiAkcNABrQb0GAASAAIABBgAFNGyIE/A8BIgJBf0YNAwJAQYyVwAAoAgAiAUUEQEGMlcAAIAI2AgAMAQsgACABaiACRw0EC0H8lMAAKAIAIgEgAGsgBE8EQCABIQIgAAwBCyADQQRqIAFBgJXAACgCACAAIARqIgJBBEEEEDQgAygCBEEBRg0DQYCVwAAgAygCCDYCAEH8lMAAIAI2AgBBhJXAACgCAAsiASACTw0CQYCVwAAoAgAgAUECdGogAEEBajYCAEGElcAAIAFBAWoiATYCAAsgACABTw0BQYiVwABBgJXAACgCACAAQQJ0aigCADYCAEH4lMAAQfiUwAAoAgBBAWo2AgBBjJXAACgCACEBIANBEGokACAAIAFqDwtB3IvAABCEAQsAC8QCAQR/IABCADcCECAAAn9BACABQYACSQ0AGkEfIAFB////B0sNABogAUEmIAFBCHZnIgNrdkEBcSADQQF0a0E+agsiAjYCHCACQQJ0QbiVwABqIQRBASACdCIDQdSYwAAoAgBxRQRAIAQgADYCACAAIAQ2AhggACAANgIMIAAgADYCCEHUmMAAQdSYwAAoAgAgA3I2AgAPCwJAAkAgASAEKAIAIgMoAgRBeHFGBEAgAyECDAELIAFBGSACQQF2a0EAIAJBH0cbdCEFA0AgAyAFQR12QQRxaiIEKAIQIgJFDQIgBUEBdCEFIAIhAyACKAIEQXhxIAFHDQALCyACKAIIIgEgADYCDCACIAA2AgggAEEANgIYIAAgAjYCDCAAIAE2AggPCyAEQRBqIAA2AgAgACADNgIYIAAgADYCDCAAIAA2AggLlgICBH8DfiMAQSBrIgMkAEEUIQIgACkDACIIIQYgCELoB1oEQCAIIQcDQCADQQxqIAJqIgBBBGsgByAHQpDOAIAiBkKQzgB+faciBEH//wNxQeQAbiIFQQF0LwDQkEA7AAAgAEECayAEIAVB5ABsa0H//wNxQQF0LwDQkEA7AAAgAkEEayECIAdC/6ziBFYgBiEHDQALCyAGQglWBEAgAkECayICIANBDGpqIAanIgAgAEH//wNxQeQAbiIAQeQAbGtB//8DcUEBdC8A0JBAOwAAIACtIQYLIAhQRSAGUHFFBEAgAkEBayICIANBDGpqIAanQQF0LQDRkEA6AAALIAEgA0EMaiACakEUIAJrEB4gA0EgaiQAC5ICAQd/IwBBEGsiBCQAQQohAiAAKAIAIgUhAyAFQegHTwRAIAUhAANAIARBBmogAmoiBkEEayAAIABBkM4AbiIDQZDOAGxrIgdB//8DcUHkAG4iCEEBdC8A0JBAOwAAIAZBAmsgByAIQeQAbGtB//8DcUEBdC8A0JBAOwAAIAJBBGshAiAAQf+s4gRLIAMhAA0ACwsCQCADQQlNBEAgAyEADAELIAJBAmsiAiAEQQZqaiADIANB//8DcUHkAG4iAEHkAGxrQf//A3FBAXQvANCQQDsAAAtBACAFIAAbRQRAIAJBAWsiAiAEQQZqaiAAQQF0LQDRkEA6AAALIAEgBEEGaiACakEKIAJrEB4gBEEQaiQAC4gCAQZ/IAAoAggiBCECAn9BASABQYABSQ0AGkECIAFBgBBJDQAaQQNBBCABQYCABEkbCyIGIAAoAgAgBGtLBH8gACAEIAYQNyAAKAIIBSACCyAAKAIEaiECAkAgAUGAAU8EQCABQT9xQYB/ciEFIAFBBnYhAyABQYAQSQRAIAIgBToAASACIANBwAFyOgAADAILIAFBDHYhByADQT9xQYB/ciEDIAFB//8DTQRAIAIgBToAAiACIAM6AAEgAiAHQeABcjoAAAwCCyACIAU6AAMgAiADOgACIAIgB0E/cUGAf3I6AAEgAiABQRJ2QXByOgAADAELIAIgAToAAAsgACAEIAZqNgIIQQALiAIBBn8gACgCCCIEIQICf0EBIAFBgAFJDQAaQQIgAUGAEEkNABpBA0EEIAFBgIAESRsLIgYgACgCACAEa0sEfyAAIAQgBhA5IAAoAggFIAILIAAoAgRqIQICQCABQYABTwRAIAFBP3FBgH9yIQUgAUEGdiEDIAFBgBBJBEAgAiAFOgABIAIgA0HAAXI6AAAMAgsgAUEMdiEHIANBP3FBgH9yIQMgAUH//wNNBEAgAiAFOgACIAIgAzoAASACIAdB4AFyOgAADAILIAIgBToAAyACIAM6AAIgAiAHQT9xQYB/cjoAASACIAFBEnZBcHI6AAAMAQsgAiABOgAACyAAIAQgBmo2AghBAAufAgIDfwF+IwBBQGoiAiQAIAEoAgBBgICAgHhGBEAgASgCDCEDIAJBJGoiBEEANgIAIAJCgICAgBA3AhwgAkEwaiADKAIAIgNBCGopAgA3AwAgAkE4aiADQRBqKQIANwMAIAIgAykCADcDKCACQRxqQeCMwAAgAkEoahAiGiACQRhqIAQoAgAiAzYCACACIAIpAhwiBTcDECABQQhqIAM2AgAgASAFNwIACyABKQIAIQUgAUKAgICAEDcCACACQQhqIgMgAUEIaiIBKAIANgIAIAFBADYCACACIAU3AwBBDEEEEHkiAUUEQEEEQQwQfwALIAEgAikDADcCACABQQhqIAMoAgA2AgAgAEHAjsAANgIEIAAgATYCACACQUBrJAAL+QEBB39BCiEDIAEiBUHoB08EQCACQQRrIQcgBSEEA0AgAyAHaiIGIAQgBEGQzgBuIgVBkM4AbGsiCEH//wNxQeQAbiIJQQF0LwDQkEA7AAAgBkECaiAIIAlB5ABsa0H//wNxQQF0LwDQkEA7AAAgA0EEayEDIARB/6ziBEsgBSEEDQALCwJAIAVBCU0EQCAFIQQMAQsgAiADQQJrIgNqIAUgBUH//wNxQeQAbiIEQeQAbGtB//8DcUEBdC8A0JBAOwAAC0EAIAEgBBtFBEAgAiADQQFrIgNqIARBAXQtANGQQDoAAAsgAEEKIANrNgIEIAAgAiADajYCAAuiAgEEfyMAQSBrIgIkAAJAAkACQCABKAIAIgEoAgAiBEECRw0AIAEoAgghAyABQQA2AgggA0UNASACIAMRAwAgAigCBCEFIAIoAgAhAyABKAIAIgRBAkYEQCABIAM2AgAgAUEEaiAFNgIAIAMhBAwBCyADQQJHDQILQQEhAwJAIARBAXFFBEBBACEDDAELIAFBBGooAgAQdSEBCyAAIAE2AgQgACADNgIAIAJBIGokAA8LIAJBADYCGCACQQE2AgwgAkHoisAANgIIIAJCBDcCECACQQhqQfCKwAAQUgALIANFIANBAkZyIAVBhAhJckUEQCAFEDwLIAJBADYCGCACQQE2AgwgAkGQi8AANgIIIAJCBDcCECACQQhqQZiLwAAQUgALxQEBA38jAEEwayIAJAAgAEEgakGwisAAEDACQCAAAn8gACgCIEEBcQRAIAAoAiQMAQsgAEEYakG4isAAEDAgACgCGEEBcQRAIAAoAhwMAQsgAEEQakGsisAAEDAgACgCEEEBcQRAIAAoAhQMAQsgAEEIakG0isAAEDBBgAghASAAKAIIQQFxRQ0BIAAoAgwLIgI2AiwgAEEsaigCACUBEBdFBEAgAiEBDAELQYAIIQEgAkGECEkNACACEDwLIABBMGokACABC5QCAQJ/IwBBIGsiBSQAQYiZwABBiJnAACgCACIGQQFqNgIAAkACf0EAIAZBAEgNABpBAUGEmcAALQAADQAaQYSZwABBAToAAEGAmcAAQYCZwAAoAgBBAWo2AgBBAgtB/wFxIgZBAkcEQCAGQQFxRQ0BIAVBCGogACABKAIYEQEADAELQYyZwAAoAgAiBkEASA0AQYyZwAAgBkEBajYCAEGQmcAAKAIABEAgBSAAIAEoAhQRAQAgBSAEOgAdIAUgAzoAHCAFIAI2AhggBSAFKQMANwIQQZCZwAAoAgAgBUEQakGUmcAAKAIAKAIUEQEAC0GMmcAAQYyZwAAoAgBBAWs2AgBBhJnAAEEAOgAAIANFDQAACwALwQECA38BfiMAQTBrIgIkACABKAIAQYCAgIB4RgRAIAEoAgwhAyACQRRqIgRBADYCACACQoCAgIAQNwIMIAJBIGogAygCACIDQQhqKQIANwMAIAJBKGogA0EQaikCADcDACACIAMpAgA3AxggAkEMakHgjMAAIAJBGGoQIhogAkEIaiAEKAIAIgM2AgAgAiACKQIMIgU3AwAgAUEIaiADNgIAIAEgBTcCAAsgAEHAjsAANgIEIAAgATYCACACQTBqJAALqAECAn8BfkEBIQdBBCEGAkAgBCAFakEBa0EAIARrca0gA61+IghCIIhQRQRAQQAhAwwBCyAIpyIDQYCAgIB4IARrSwRAQQAhAwwBCwJAAkACfyABBEAgAiABIAVsIAQgAxBvDAELIANFBEAgBCEGDAILIAMgBBB5CyIGDQAgACAENgIEDAELIAAgBjYCBEEAIQcLQQghBgsgACAGaiADNgIAIAAgBzYCAAucAQEBfyMAQRBrIgYkAAJAIAEEQCAGQQRqIAEgAyAEIAUgAigCEBEFAAJAIAYoAgQiAiAGKAIMIgFNBEAgBigCCCEFDAELIAJBAnQhAiAGKAIIIQMgAUUEQEEEIQUgAyACEHYMAQsgAyACQQQgAUECdCICEG8iBUUNAgsgACABNgIEIAAgBTYCACAGQRBqJAAPCxB6AAtBBCACEGEAC5oBAQF/IwBBEGsiBSQAAkAgAQRAIAVBBGogASADIAQgAigCEBEGAAJAIAUoAgQiAiAFKAIMIgFNBEAgBSgCCCEEDAELIAJBAnQhAiAFKAIIIQMgAUUEQEEEIQQgAyACEHYMAQsgAyACQQQgAUECdCICEG8iBEUNAgsgACABNgIEIAAgBDYCACAFQRBqJAAPCxB6AAtBBCACEGEAC4cBAQF/IwBBEGsiAyQAIAIgASACaiIBSwRAQQBBABBhAAsgA0EEaiAAKAIAIgIgACgCBEEIIAEgAkEBdCICIAEgAksbIgEgAUEITRsiAUEBQQEQNCADKAIEQQFGBEAgAygCCCADKAIMEGEACyADKAIIIQIgACABNgIAIAAgAjYCBCADQRBqJAAL7AEBBH8jAEEQayIDJAAgAiABIAJqIgRLBEBBAEEAEGEACyADQQRqIQEgACgCACICIQUgACgCBCEGAkBBCCAEIAJBAXQiAiACIARJGyICIAJBCE0bIgJBAEgEQCABQQA2AgQgAUEBNgIADAELAn8gBQRAIAYgBUEBIAIQbwwBCyACQQEQeQsiBEUEQCABIAI2AgggAUEBNgIEIAFBATYCAAwBCyABIAI2AgggASAENgIEIAFBADYCAAsgAygCBEEBRgRAIAMoAgggAygCDBBhAAsgAygCCCEBIAAgAjYCACAAIAE2AgQgA0EQaiQAC/EBAQR/IwBBEGsiAyQAIAIgASACaiIBSwRAQQBBABBhAAsgA0EEaiEEIAAoAgQhBgJ/QQggASAAKAIAIgJBAXQiBSABIAVLGyIBIAFBCE0bIgUiAUEASARAQQEhAkEAIQFBBAwBCwJ/AkACfyACBEAgBiACQQEgARBvDAELIAFFBEBBASECDAILIAFBARB5CyICDQAgBEEBNgIEQQEMAQsgBCACNgIEQQALIQJBCAsgBGogATYCACAEIAI2AgAgAygCBEEBRgRAIAMoAgggAygCDBBhAAsgAygCCCEBIAAgBTYCACAAIAE2AgQgA0EQaiQAC3kBAX8jAEEgayICJAACfyAAKAIAQYCAgIB4RwRAIAEgACgCBCAAKAIIEGoMAQsgAkEQaiAAKAIMKAIAIgBBCGopAgA3AwAgAkEYaiAAQRBqKQIANwMAIAIgACkCADcDCCABKAIAIAEoAgQgAkEIahAiCyACQSBqJAALZwEBfyMAQRBrIgUkACABRQRAEHoACyAFQQhqIAEgAyAEIAIoAhARBgAgACAFKAIIIgJBAkYiATYCCCAAIAUoAgwiA0EAIAEbNgIEIABBACADQYAIIAJBAXEbIAEbNgIAIAVBEGokAAuOAQEBfwJAAkAgAEGECE8EQCAA0G8mAUH4lMAAKAIADQFB+JTAAEF/NgIAIABBjJXAACgCACIBSQ0CIAAgAWsiAEGElcAAKAIATw0CQYCVwAAoAgAgAEECdGpBiJXAACgCADYCAEGIlcAAIAA2AgBB+JTAAEH4lMAAKAIAQQFqNgIACw8LQeyLwAAQhAELAAtiAQF/IwBBEGsiBiQAIAFFBEAQegALIAZBCGogASADIAQgBSACKAIQEQUAIAYoAgwhASAAIAYoAggiAjYCCCAAIAFBACACQQFxIgIbNgIEIABBACABIAIbNgIAIAZBEGokAAsSACMAQTBrIgAkACAAQTBqJAALYAEBfyMAQRBrIgUkACABRQRAEHoACyAFQQhqIAEgAyAEIAIoAhARBgAgBSgCDCEBIAAgBSgCCCICNgIIIAAgAUEAIAJBAXEiAhs2AgQgAEEAIAEgAhs2AgAgBUEQaiQAC2sBAn8gACgCACEBIABBgIDEADYCAAJAIAFBgIDEAEcNAEGAgMQAIQEgACgCBCICIAAoAghGDQAgACACQQFqNgIEIAAgACgCDCIAIAItAAAiAUEPcWotAAA2AgAgACABQQR2ai0AACEBCyABC1oBAX8jAEEQayIFJAAgAUUEQBB6AAsgBUEIaiABIAMgBCACKAIQEQYAIAAgBS0ACCIBNgIIIAAgBSgCDEEAIAEbNgIEIABBACAFLQAJIAEbNgIAIAVBEGokAAtYAQF/IwBBEGsiBCQAIAFFBEAQegALIARBCGogASADIAIoAhARBAAgACAELQAIIgE2AgggACAEKAIMQQAgARs2AgQgAEEAIAQtAAkgARs2AgAgBEEQaiQAC1QBAX8jAEEQayIGJAAgAUUEQBB6AAsgBkEIaiABIAMgBCAFIAIoAhARBQAgBigCDCEBIAAgBigCCCICNgIEIAAgAUEAIAJBAXEbNgIAIAZBEGokAAtUAQF/IwBBEGsiBiQAIAFFBEAQegALIAZBCGogASADIAQgBSACKAIQEREAIAYoAgwhASAAIAYoAggiAjYCBCAAIAFBACACQQFxGzYCACAGQRBqJAALVAEBfyMAQRBrIgYkACABRQRAEHoACyAGQQhqIAEgAyAEIAUgAigCEBESACAGKAIMIQEgACAGKAIIIgI2AgQgACABQQAgAkEBcRs2AgAgBkEQaiQAC1QBAX8jAEEQayIGJAAgAUUEQBB6AAsgBkEIaiABIAMgBCAFIAIoAhAREwAgBigCDCEBIAAgBigCCCICNgIEIAAgAUEAIAJBAXEbNgIAIAZBEGokAAtSAQF/IwBBEGsiBSQAIAFFBEAQegALIAVBCGogASADIAQgAigCEBEGACAFKAIMIQEgACAFKAIIIgI2AgQgACABQQAgAkEBcRs2AgAgBUEQaiQAC1ABAX8jAEEQayIEJAAgAUUEQBB6AAsgBEEIaiABIAMgAigCEBEEACAEKAIMIQEgACAEKAIIIgI2AgQgACABQQAgAkEBcRs2AgAgBEEQaiQAC0cBAX8gACgCACAAKAIIIgNrIAJJBEAgACADIAIQNyAAKAIIIQMLIAIEQCAAKAIEIANqIAEgAvwKAAALIAAgAiADajYCCEEACzkBAX8jAEEgayIAJAAgAEEANgIYIABBATYCDCAAQeyOwAA2AgggAEIENwIQIABBCGpB9I7AABBSAAtHAQF/IAAoAgAgACgCCCIDayACSQRAIAAgAyACEDkgACgCCCEDCyACBEAgACgCBCADaiABIAL8CgAACyAAIAIgA2o2AghBAAtAAQJ/IwBBEGsiAiQAIAJBCGogACgCACUBEAEgAigCCCIDIAIoAgwiACABEIABIAAEQCADIAAQdgsgAkEQaiQAC0QBAn8gASgCBCECIAEoAgAhA0EIQQQQeSIBRQRAQQRBCBB/AAsgASACNgIEIAEgAzYCACAAQbCNwAA2AgQgACABNgIAC0EBAX8jAEEgayICJAAgAkEANgIQIAJBATYCBCACQgQ3AgggAkEuNgIcIAIgADYCGCACIAJBGGo2AgAgAiABEFIAC8JXAyh/BX4BbyMAQRBrIhskACMAQRBrIhwkACAcQQhqIR4gCiEOIwBBwAZrIgskACALIAE2AmQgCyAANgJgIAsgAzYCbCALIAI2AmggCyAFNgJ0IAsgBDYCcCALIAc2AnwgCyAGNgJ4IAsgCTYChAEgCyAINgKAAQJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQEEaQQEQeSIQBEAgEEHt6gE7ABggEELhgMHzl83bvuUANwAQIBBC7sKVi5avmbvhADcACCAQQvj4zfuH7pm29wA3AAAgC0HoAmohFSAQQQNqQXxxIBBrIQ0CQANAAkACQAJAAkAgECASai0AACIRwCIMQQBOBEAgDSASa0EDcQ0BIBJBE08NAgNAIBAgEmoiCkEEaigCACAKKAIAckGAgYKEeHENAyASQQhqIhJBE0kNAAsMAgtCgICAgIAgITNCgICAgBAhNAJAAkACfgJAAkACQAJAAkACQAJAAkACQCARLQCakkBBAmsOAwABAgoLIBJBAWoiDEEaSQ0CQgAhM0IAITQMCQtCACEzIBJBAWoiCkEaSQ0CQgAhNAwIC0IAITMgEkEBaiIKQRpJDQJCACE0DAcLIAwgEGosAABBv39KDQYMBwsgCiAQaiwAACEPAkACQCARQeABayIKBEAgCkENRgRADAIFDAMLAAsgD0FgcUGgf0YNBAwDCyAPQZ9/Sg0CDAMLIAxBH2pB/wFxQQxPBEAgDEF+cUFuRw0CIA9BQEgNAwwCCyAPQUBIDQIMAQsgCiAQaiwAACEKAkACQAJAAkAgEUHwAWsOBQEAAAACAAsgDEEPakH/AXFBAksgCkFATnINAwwCCyAKQfAAakH/AXFBME8NAgwBCyAKQY9/Sg0BCyASQQJqIgpBGk8EQEIAITQMBQsgCiAQaiwAAEG/f0oNAkIAITQgEkEDaiIMQRpPDQQgDCAQaiwAAEFASA0FQoCAgICA4AAMAwtCgICAgIAgDAILQgAhNCASQQJqIgxBGk8NAiAMIBBqLAAAQb9/TA0DC0KAgICAgMAACyEzQoCAgIAQITQLIBUgMyASrYQgNIQ3AgQgFUEBNgIADAYLIAxBAWohEgwCCyASQQFqIRIMAQsgEkEaTw0AA0AgECASaiwAAEEASA0BIBJBAWoiEkEaRw0ACwwBCyASQRpJDQELCyAVQRo2AgggFSAQNgIEIBVBADYCAAsCQCALKALoAkEBRgRAQQhBARB5IgpFDQMgCkLmwrHjpqzYsesANwAAIAtBCDYCkAEgCyAKNgKMASALQQg2AogBIBBBGhB2DAELIAtBGjYCkAEgCyAQNgKMASALQRo2AogBCyALIAtBiAFqrUKAgICAEIQ3A8gBIAsgC0H4AGqtQoCAgIAghCI2NwPAASALQgI3AvQCIAtBAjYC7AIgC0GEgcAANgLoAiALIAtBwAFqNgLwAiALQZQBaiALQegCahAkAn8jAEEgayINJAACQAJAAkBBqJXAAC0AAARAQayVwAAoAgAhDAwBC0H0lMAAKAIAIQpB9JTAAEEANgIAIApFDQEgChEHACEMQaiVwAAtAAANAkGslcAAIAw2AgBBqJXAAEEBOgAACyAMEHUgDUEgaiQADAILIA1BADYCGCANQQE2AgwgDUHoisAANgIIIA1CBDcCECANQQhqQfCKwAAQUgALIAxBgwhLBEAgDBA8CyANQQA2AhggDUEBNgIMIA1BkIvAADYCCCANQgQ3AhAgDUEIakGYi8AAEFIACyIMJQEQAiINIAxBhAhJckUEQCAMEDwLIAtB2ABqIgogDDYCBCAKIA1BAEc2AgAgCygCWEEBcUUEQEGYgsAAQQ8QZyEMIAtBgICAgHg2AuAEIAsgDDYC5AQMCgsgCyALKAJcIhU2ArABIAtB0ABqIg0gC0GwAWooAgAlARADIgo2AgQgDSAKQQBHNgIAIAsoAlBBAXFFBEBBp4LAAEEREGchCiALQYCAgIB4NgLgBCALIAo2AuQEDAcLIAsgCygCVCISNgLQBCALQdAEaigCACUBQbiCwABBBhAEITgQKCIRIDgmAUG0lcAAKAIAIQxBsJXAACgCACEKQbCVwABCADcCACALQcgAaiINIAwgESAKQQFGIgobNgIEIA0gCjYCACALKAJMIRggCygCSEEBcQ0CIAsgGDYC6AIgC0HoAmoiESgCACUBEAlFDQIgCyAYNgLQBSALQdAFaiIKKAIAJQFByAEQCCAKKAIAJQFBMhAFIAooAgAlAUG+gsAAQQIQBiEMQbSVwAAoAgAhDUGwlcAAKAIAIQpBsJXAAEIANwIAIBEgDSAMIApBAUYiChs2AgQgEUECIAxBAEcgChs2AgAgCygC7AIhFyALKALoAiIKQQJGBEAgC0GAgICAeDYC4AQgCyAXNgLkBAwFCyAKQQFxRQRAQcCCwABBDRBnIQogC0GAgICAeDYC4AQgCyAKNgLkBAwFCyALIBc2AugCIAtB6AJqKAIAJQEQCkUEQCALQYCAgIB4NgLgBCALIBc2AuQEDAULIAsgFzYC3AUgC0HcBWoiCkHNgsAAEHggCigCACUBRAAAAAAAAAAARAAAAAAAAAAARAAAAAAAwGJARAAAAAAAAD5AEA0gCigCACUBQdGCwABBFxAMIApB6ILAABB4IAooAgAlAUHsgsAAQQ9EAAAAAAAAJEBEAAAAAAAANEAQDkGwlcAAKAIAIQxBtJXAACgCACENQbCVwABCADcCACALQUBrIgogDTYCBCAKIAxBAUY2AgAgCygCQEEBcQRAIAsoAkQhEQwECyALQegCaiETIwBBEGsiCiQAIApBCGogC0HQBWooAgAlARAHAkBBsJXAACgCAEEBRgRAQbSVwAAoAgAhDEGAgICAeCENDAELIAooAgghDCATIAooAgwiDTYCCAsgEyAMNgIEQbCVwABCADcCACATIA02AgAgCkEQaiQAIAsoAuwCIREgCygC6AIiD0GAgICAeEYNAyALKALwAiEMIAtB6AFqIhRBAEHBAPwLACALQdgBakHwgMAAKQMANwMAIAtB0AFqQeiAwAApAwA3AwAgC0HIAWpB4IDAACkDADcDACALQgA3A+ABIAtB2IDAACkDADcDwAEgESEKIAtBwAFqIRYCQAJAQcAAIBQtAEAiEGsiDSAMTQRAIBBFDQEgDQRAIBAgFGogCiAN/AoAAAsgFiAWKQMgQgF8NwMgIBYgFEEBEBwgCiANaiEKIAwgDWshDAwBCyAMBEAgECAUaiAKIAz8CgAACyAMIBBqIRAMAQsgDEE/cSEQIAxBwABPBEAgFiAWKQMgIAxBBnYiDa18NwMgIBYgCiANEBwLIBBFDQAgFCAKIAxBQHFqIBD8CgAACyAUIBA6AEAgEyAWQfAA/AoAACALQeAEaiEUIwBBQGoiFiQAIAtBkANqIhAtAEAiDCAQaiINQYABOgAAIAytIjRCO4YgEykDICI1QgmGIjMgNEIDhoQiNEKA/gODQiiGhCA0QoCA/AeDQhiGIDRCgICA+A+DQgiGhIQgNUIBhkKAgID4D4MgNUIPiEKAgPwHg4QgNUIfiEKA/gODIDNCOIiEhIQhMwJAAkAgDEE/RwRAIAxBP3MiCgRAIA1BAWpBACAK/AsACyAMQThzQQdLDQELIBMgEEEBEBwgFkEwakIANwMAIBZBKGpCADcDACAWQSBqQgA3AwAgFkEYakIANwMAIBZBEGpCADcDACAWQQhqQgA3AwAgFkIANwMAIBYgMzcDOCATIBZBARAcDAELIBAgMzcAOCATIBBBARAcCyAQQQA6AEAgFCATKAIcIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgAcIBQgEygCGCIKQRh0IApBgP4DcUEIdHIgCkEIdkGA/gNxIApBGHZycjYAGCAUIBMoAhQiCkEYdCAKQYD+A3FBCHRyIApBCHZBgP4DcSAKQRh2cnI2ABQgFCATKAIQIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgAQIBQgEygCDCIKQRh0IApBgP4DcUEIdHIgCkEIdkGA/gNxIApBGHZycjYADCAUIBMoAggiCkEYdCAKQYD+A3FBCHRyIApBCHZBgP4DcSAKQRh2cnI2AAggFCATKAIEIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgAEIBQgEygCACIKQRh0IApBgP4DcUEIdHIgCkEIdkGA/gNxIApBGHZycjYAACAWQUBrJAAgC0GYBmogC0H4BGopAAA3AwAgC0GQBmogC0HwBGopAAA3AwAgC0GIBmogC0HoBGopAAA3AwAgCyALKQDgBDcDgAYgC0H7gsAANgL0AiALIAtBoAZqNgLwAiALQYCAxAA2AugCIAsgC0GABmo2AuwCIBQgExAlIA8EQCARIA8QdgsgF0GECE8EQCAXEDwLIBhBhAhPBEAgGBA8CyASQYQITwRAIBIQPAsgFUGDCE0NCAwHC0EBQRoQYQALQQFBCBBhAAsgC0GAgICAeDYC4AQgCyAYNgLkBAwCCyALQYCAgIB4NgLgBCALIBE2AuQEIBdBhAhJDQAgFxA8CyAYQYQISQ0AIBgQPAsgEkGECEkNACASEDwLIBVBhAhJDQELIBUQPAsgCygC4ARBgICAgHhHDQEgCygC5AQhDAtBCEEBEHkiCkUNAiAKQubg/aqmzty38gA3AAAgC0EINgKoASALIAo2AqQBIAtBCDYCoAEgDEGECEkNASAMEDwMAQsgC0GoAWogC0HoBGooAgA2AgAgCyALKQLgBDcDoAELIAsQFEQAAOD////vQaKc/AM2AqwBIAsgC0GsAWqtQoCAgIAwhDcDgAMgCyALQegAaq1CgICAgCCEIjc3A/gCIAsgC0HgAGqtQoCAgIAghCI1NwPwAiALIDY3A+gCIAtCBDcCzAEgC0EENgLEASALQZiBwAA2AsABIAsgC0HoAmo2AsgBIAtBsAFqIAtBwAFqECQgCygCtAEhDCALKAK4ASENIAtB0ARqIQ9BACEQIwBBEGsiFSQAAkAgDkEDIA4bIh8iFEUEQCAPQQA2AgggD0KAgICAEDcCAAwBCwJAIBStIjNCIIhQBEACQCAzpyIOQQBIDQACQCAORQRAQQEhEQwBC0EBIRAgDkEBEHkiEUUNAQtBACEQIBVBADYCDCAVIBE2AgggFSAONgIEIA5FBEAgFUEEakEAQQEQOCAVKAIMIRAgFSgCCCERCyAQIBFqQdWAwAAtAAA6AAAgEEEBaiEQIBRBAUcEQANAIBAEQCAQIBFqIBEgEPwKAAALIBBBAXQhECAUQQRJIBRBAXYhFEUNAAsLIBUgEDYCDCAOIBBGDQIgDiAQayIKBEAgECARaiARIAr8CgAACyAVIA42AgwMAgsgECAOEGEACyMAQTBrIgAkACAAQRE2AgwgAEGLg8AANgIIIABBATYCFCAAQciQwAA2AhAgAEIBNwIcIAAgAEEIaq1CgICAgPAHhDcDKCAAIABBKGo2AhggAEEQakG8iMAAEFIACyAPIBUpAgQ3AgAgD0EIaiAVQQxqKAIANgIACyAVQRBqJAAgC0GIBWoiGkEAQcEA/AsAIAtB+ARqQfCAwAApAwA3AwAgC0HwBGpB6IDAACkDADcDACALQegEakHggMAAKQMANwMAIAtCADcDgAUgC0HYgMAAKQMANwPgBAJAIA1BwABPBEAgCyANQQZ2IgqtNwOABSALQeAEaiAMIAoQHCANQT9xIgpFBEAgCiENDAILIBogDCANQUBxaiAK/AoAACAKIQ0MAQsgDUUNACAaIAwgDfwKAAALIAsgDToAyAUgC0HgAWoiICALQYAFaiIhKQMANwMAIAtB2AFqIiIgC0H4BGoiIykDADcDACALQdABaiIkIAtB8ARqIiUpAwA3AwAgC0HIAWoiJiALQegEaiInKQMANwMAIAtB8AFqIBpBCGoiKCkDADcDACALQfgBaiAaQRBqIikpAwA3AwAgC0GAAmogGkEYaiIqKQMANwMAIAtBiAJqIBpBIGoiKykDADcDACALQZACaiAaQShqIiwpAwA3AwAgC0GYAmogGkEwaiItKQMANwMAIAtBoAJqIBpBOGoiLikDADcDACALIAspA+AENwPAASALIBopAwA3A+gBIAsgDToAqAIgC0E4akEAIAtB6AJqEC8gCygCPCIOQQBIBEBBAEEAEGEACyALQfwFaiEvIAtBkANqIR0gC0HoAWohGSALKAI4IRIgC0GwBmohMCALQagGaiExIAtBoAZqITIgC0GYBmohEyALQZAGaiEXIAtBiAZqIRhBACEQAkACQANAQQEhCgJAIA5FDQBBASEUIA5BARB5IgoNACAOIQoMBgsgDkUiDUUEQCAKIBIgDvwKAAALAkACQEHAACALLQCoAiIMayIRIA5NBEAgDEUEQCAOIRIgCiEMDAILIBEEQCAMIBlqIAogEfwKAAALIAsgCykD4AFCAXw3A+ABIAtBwAFqIBlBARAcIAogEWohDCAOIBFrIRIMAQsgDUUEQCAMIBlqIAogDvwKAAALIAwgDmohFAwBCyASQT9xIRQgEkHAAE8EQCALIAspA+ABIBJBBnYiDa18NwPgASALQcABaiAMIA0QHAsgFEUNACAZIAwgEkFAcWogFPwKAAALIAsgFDoAqAIgDgRAIAogDhB2CyALQegCaiALQcABakHwAPwKAAAgHSALLQDQAyIMaiINQYABOgAAIAytIjRCO4YgCykDiAMiNkIJhiIzIDRCA4aEIjRCgP4Dg0IohoQgNEKAgPwHg0IYhiA0QoCAgPgPg0IIhoSEIDZCAYZCgICA+A+DIDZCD4hCgID8B4OEIDZCH4hCgP4DgyAzQjiIhISEITMCQAJAIAxBP0cEQCAMQT9zIg4EQCANQQFqQQAgDvwLAAsgDEE4c0EHSw0BCyALQegCaiIOIB1BARAcIDBCADcDACAxQgA3AwAgMkIANwMAIBNCADcDACAXQgA3AwAgGEIANwMAIAtCADcDgAYgCyAzNwO4BiAOIAtBgAZqQQEQHAwBCyALIDM3A8gDIAtB6AJqIB1BARAcCyALIAsoAoQDIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgL4BSALIAsoAoADIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgL0BSALIAsoAvwCIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgLwBSALIAsoAvgCIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgLsBSALIAsoAvQCIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgLoBSALIAsoAvACIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgLkBSALIAsoAuwCIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgLgBSALIAsoAugCIg5BGHQgDkGA/gNxQQh0ciAOQQh2QYD+A3EgDkEYdnJyNgLcBSALQfuCwAA2AvQCIAsgLzYC8AIgC0GAgMQANgLoAiALIAtB3AVqNgLsAiALQdAFaiALQegCahAlIAsoAtQEIQ8gCygC1AUhDiALKALYBSIMIAsoAtgEIg1PBEAgDyEVIA4hEUEAIRICQCANRQ0AA0AgFS0AACIWIBEtAAAiFEYEQCAVQQFqIRUgEUEBaiERIA1BAWsiDQ0BDAILCyAWIBRrIRILIBJFDQILIBBBwJaxAkcEQCALKALQBSINBEAgDiANEHYLIAstAMgFIQ4gICAhKQMANwMAICIgIykDADcDACAkICUpAwA3AwAgJiAnKQMANwMAIBkgGikDADcDACAZQQhqICgpAwA3AwAgGUEQaiApKQMANwMAIBlBGGogKikDADcDACAZQSBqICspAwA3AwAgGUEoaiAsKQMANwMAIBlBMGogLSkDADcDACAZQThqIC4pAwA3AwAgCyALKQPgBDcDwAEgCyAOOgCoAiALQTBqIBBBAWoiECALQegCahAvQQAhFCALKAIwIRIgCygCNCIOQQBODQEMBgsLQQshDUELQQEQeSIKRQ0BIApBB2pB/4DAACgAADYAACAKQfiAwAApAAA3AABBwZaxAiEQIAsoAtAFIgwEQCAOIAwQdgsgCiEOQQshDAwDCyALKALQBSENDAILQQFBCxBhAAtBAUEIEGEACyALKALQBCIKBEAgDyAKEHYLIAsgEDYCvAEgCyAMNgLYBSALIA42AtQFIAsgDTYC0AUgCyALQYABaq1CgICAgCCENwOYAyALIAtBvAFqrUKAgICAMIQ3A5ADIAsgC0HQBWqtQoCAgIAQhDcDiAMgCyALQaABaq1CgICAgBCENwOAAyALIAtB8ABqrUKAgICAIIQ3A/gCIAsgNzcD8AIgCyA1NwPoAiALQgc3AswBIAtBBzYCxAEgC0G4gcAANgLAASALIAtB6AJqIhE2AsgBIAtB3AVqIAtBwAFqECQgCygCmAEhDiALKAKcASENIwBB4AJrIg8kACAPQThqQgA3AwAgD0EwakIANwMAIA9BKGpCADcDACAPQSBqQgA3AwAgD0EYakIANwMAIA9BEGpCADcDACAPQQhqQgA3AwAgD0IANwMAAkAgDUHBAE8EQCAPQaABakIANwMAIA9BmAFqQgA3AwAgD0GQAWpCADcDACAPQYgBakIANwMAIA9BgAFqQgA3AwAgD0H4AGpCADcDACAPQfAAakIANwMAIA9BADoAqAEgD0HIAGpB2IjAACkDADcDACAPQdAAakHgiMAAKQMANwMAIA9B2ABqQeiIwAApAwA3AwAgD0IANwNoIA9B0IjAACkDADcDQCAPIA1BBnYiCq03A2AgD0FAayAOIAoQHCANQT9xIgoEQCAPQegAaiAOIA1BQHFqIAr8CgAACyAPIAo6AKgBIA9BsAFqIA9BQGtB8AD8CgAAIA9B2AFqIg0gDy0AmAIiDGoiDkGAAToAACAMrSI0QjuGIA8pA9ABIjVCCYYiMyA0QgOGhCI0QoD+A4NCKIaEIDRCgID8B4NCGIYgNEKAgID4D4NCCIaEhCA1QgGGQoCAgPgPgyA1Qg+IQoCA/AeDhCA1Qh+IQoD+A4MgM0I4iISEhCEzAkACQCAMQT9HBEAgDEE/cyIKBEAgDkEBakEAIAr8CwALIAxBOHNBB0sNAQsgD0GwAWoiCiANQQEQHCAPQdACakIANwMAIA9ByAJqQgA3AwAgD0HAAmpCADcDACAPQbgCakIANwMAIA9BsAJqQgA3AwAgD0GoAmpCADcDACAPQgA3A6ACIA8gMzcD2AIgCiAPQaACakEBEBwMAQsgDyAzNwOQAiAPQbABaiANQQEQHAsgDyAPKALMASIKQRh0IApBgP4DcUEIdHIgCkEIdkGA/gNxIApBGHZycjYCHCAPIA8oAsgBIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgIYIA8gDygCxAEiCkEYdCAKQYD+A3FBCHRyIApBCHZBgP4DcSAKQRh2cnI2AhQgDyAPKALAASIKQRh0IApBgP4DcUEIdHIgCkEIdkGA/gNxIApBGHZycjYCECAPIA8oArwBIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgIMIA8gDygCuAEiCkEYdCAKQYD+A3FBCHRyIApBCHZBgP4DcSAKQRh2cnI2AgggDyAPKAK0ASIKQRh0IApBgP4DcUEIdHIgCkEIdkGA/gNxIApBGHZycjYCBCAPIA8oArABIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgIADAELIA1FDQAgDyAOIA38CgAACyARIA8pAwA3AAAgEUE4aiAPQThqKQMANwAAIBFBMGogD0EwaikDADcAACARQShqIA9BKGopAwA3AAAgEUEgaiAPQSBqKQMANwAAIBFBGGogD0EYaikDADcAACARQRBqIA9BEGopAwA3AAAgEUEIaiAPQQhqKQMANwAAIA9B4AJqJABBACENA0AgC0HoAmoiDiANaiIMIAwtAABBNnM6AAAgDEEBaiIKIAotAABBNnM6AAAgDEECaiIKIAotAABBNnM6AAAgDEEDaiIKIAotAABBNnM6AAAgDUEEaiINQcAARw0AC0EAIQ0gC0H4BGpB8IDAACkDADcDACALQfAEakHogMAAKQMANwMAIAtB6ARqQeCAwAApAwA3AwAgC0IBNwOABSALQdiAwAApAwA3A+AEIAtB4ARqIA5BARAcA0AgC0HoAmoiDyANaiIOIA4tAABB6gBzOgAAIA5BAWoiCiAKLQAAQeoAczoAACAOQQJqIgogCi0AAEHqAHM6AAAgDkEDaiIKIAotAABB6gBzOgAAIA1BBGoiDUHAAEcNAAsgC0HYAWoiEUHwgMAAKQMANwMAIAtB0AFqIgxB6IDAACkDADcDACALQcgBaiINQeCAwAApAwA3AwAgC0HgAWoiDkIBNwMAIAtB2IDAACkDADcDwAEgC0HAAWoiCiAPQQEQHCALQcgEaiAOKQMANwMAIAtBwARqIBEpAwA3AwAgC0G4BGogDCkDADcDACALQbAEaiANKQMANwMAIAtBiARqIAtB6ARqKQMANwMAIAtBkARqIAtB8ARqKQMANwMAIAtBmARqIAtB+ARqKQMANwMAIAtBoARqIAtBgAVqKQMANwMAIAsgCykDwAE3A6gEIAsgCykD4AQ3A4AEIAtBuANqQQBBwQD8CwAgDyALQYAEakHQAPwKAAAgCiAPQZgB/AoAACALQZACaiERIAsoAuAFIQ4CQAJAIAsoAuQFIgxBwAAgCy0A0AIiDWsiCk8EQCANRQ0BIAoEQCANIBFqIA4gCvwKAAALIAsgCykD4AFCAXw3A+ABIAtBwAFqIBFBARAcIAogDmohDiAMIAprIQwMAQsgDARAIA0gEWogDiAM/AoAAAsgDCANaiENDAELIAxBP3EhDSAMQcAATwRAIAsgCykD4AEgDEEGdiIKrXw3A+ABIAtBwAFqIA4gChAcCyANRQ0AIBEgDiAMQUBxaiAN/AoAAAsgCyANOgDQAiALQegCaiALQcABakGYAfwKAAAgC0G4A2oiDSALLQD4AyIMaiIOQYABOgAAIAytIjRCO4YgCykDiAMiNUIJhiIzIDRCA4aEIjRCgP4Dg0IohoQgNEKAgPwHg0IYhiA0QoCAgPgPg0IIhoSEIDVCAYZCgICA+A+DIDVCD4hCgID8B4OEIDVCH4hCgP4DgyAzQjiIhISEITMCQAJAIAxBP0cEQCAMQT9zIgoEQCAOQQFqQQAgCvwLAAsgDEE4c0EHSw0BCyALQegCaiIKIA1BARAcIAtBkAVqQgA3AwAgC0GIBWpCADcDACALQYAFakIANwMAIAtB+ARqQgA3AwAgC0HwBGpCADcDACALQegEakIANwMAIAtCADcD4AQgCyAzNwOYBSAKIAtB4ARqQQEQHAwBCyALIDM3A/ADIAtB6AJqIA1BARAcCyALIAsoAoQDIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLUAyALIAsoAoADIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLQAyALIAsoAvwCIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLMAyALIAsoAvgCIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLIAyALIAsoAvQCIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLEAyALIAsoAvACIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLAAyALIAsoAuwCIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgK8AyALIAsoAugCIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgK4AyALQSA6APgDIAspA7ADITUgC0HhA2pCADcAACALQYABOgDYAyALQegDakIANwAAIAtCADcA2QMgCyA1QgmGIjNCgAKEIjRCgP4Dg0IohiA0QoCA/AeDQhiGIDRCgICA+A+DQgiGhIQgNUIBhkKAgID4D4MgNUIPiEKAgPwHg4QgNUIfiEKA/gODIDNCOIiEhIQ3A/ADQQEhDiALQZADaiANQQEQHCALIAsoAqwDIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgL8BCALIAsoAqgDIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgL4BCALIAsoAqQDIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgL0BCALIAsoAqADIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLwBCALIAsoApwDIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLsBCALIAsoApgDIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLoBCALIAsoApQDIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLkBCALIAsoApADIgpBGHQgCkGA/gNxQQh0ciAKQQh2QYD+A3EgCkEYdnJyNgLgBCALQfuCwAA2AvQCIAsgC0GABWo2AvACIAtBgIDEADYC6AIgCyALQeAEajYC7AIgC0HcAmogC0HoAmoQJSALQYgGaiALQagBaigCADYCACALIAspA6ABNwOABkEAIQ0CfwJAAkACQCALKAKEASIXQQBIDQAgCygCgAEhCiAXBEBBASENIBdBARB5Ig5FDQELIBcEQCAOIAogF/wKAAALIAtB6ARqIgwgC0HYBWooAgA2AgAgCyALKQLQBTcD4AQgCygCrAEhDSALKAK8ASEKQQNBARB5IhhFDQEgGEECakHygcAALQAAOgAAIBhB8IHAAC8AADsAACALQfACaiALQeQCaigCADYCACALQfwCaiALQYgGaigCADYCACALQZQDaiAMKAIANgIAIAsgCykC3AI3A+gCIAsgCykDgAY3AvQCIAsgFzYCiAMgCyAONgKEAyALIBc2AoADIAsgCykD4AQ3AowDIAtBAzYCrAMgCyAYNgKoAyALQQM2AqQDIAsgHzYCoAMgCyAKNgKcAyALIA02ApgDIAtBADYC0AQgC0HgBGogC0HQBGoQcCALKALkBCEKAkAgCygC4AQiDUUEQCAKIRAMAQsgCyAKNgKEBiALIA02AoAGIAtBKGogCygC7AIgCygC8AIQaCALKAIsIRACQCALKAIoQQFxDQAgC0GEBmoiFkG0gMAAQQkQISAQEHcgC0EgaiALKAL4AiALKAL8AhBoIAsoAiQhECALKAIgQQFxDQAgFkG9gMAAQQsQISAQEHcgC0EYaiAOIBcQaCALKAIcIRAgCygCGEEBcQ0AIBZByIDAAEEJECEgEBB3IAtBEGohEiALQYwDaiERIwBBMGsiEyQAIBNBKGogDRBwIBMoAiwhDQJAIBMoAigiEEUEQEEBIRUMAQsgEyANNgIsIBMgEDYCKCATQSBqIBEoAgwQaUEBIRUgEygCJCEMAkAgEygCIEEBcQ0AIBNBLGoiFEGKgMAAQQoQISAMEHcgE0EYaiARKAIQEGkgEygCHCEMIBMoAhhBAXENACAUQZSAwABBBRAhIAwQdyATQRBqIBEoAgQgESgCCBBoIBMoAhQhDCATKAIQQQFxDQAgFEGZgMAAQQQQISAMEHcgETUCFCEzIwBBMGsiDyQAIA8gMzcDCCATQQhqIhECfyAQLQACRQRAIDO6EGsMAQsgMxAbITgQKCIMIDgmASAMCzYCBCARQQA2AgAgD0EwaiQAIBMoAgwhDCATKAIIQQFxDQAgFEGdgMAAQQoQISAMEHdBACEVDAELIA1BhAhJBEAgDCENDAELIA0QPCAMIQ0LIBIgDTYCBCASIBU2AgAgE0EwaiQAIAsoAhQhECALKAIQQQFxDQAgFkHRgMAAQQMQISAQEHcgC0EIaiAYQQMQaCALKAIMIRAgCygCCEEBcUUNBAsgCkGECEkNACAKEDwLIAsgEDYC/AUgCyALQfwFaq1CgICAgMAAhDcD0AQgC0IBNwLsBCALQQE2AuQEIAtBkILAADYC4AQgCyALQdAEajYC6AQgC0GABmogC0HgBGoQJCALKAKEBiIMIAsoAogGEIIBIQogCygCgAYiDQRAIAwgDRB2CyALKAL8BSINQYQITwRAIA0QPAtBAQwDCyANIBcQYQALQQFBAxBhAAsgFkHUgMAAQQEQISAQEHdBAAshDCALKALoAiINBEAgCygC7AIgDRB2CyALKAL0AiINBEAgCygC+AIgDRB2CyAXBEAgDiAXEHYLIAsoAowDIg4EQCALKAKQAyAOEHYLIBhBAxB2IAsoAtwFIg4EQCALKALgBSAOEHYLIAsoArABIg4EQCALKAK0ASAOEHYLIAsoApQBIg4EQCALKAKYASAOEHYLIAsoAogBIg4EQCALKAKMASAOEHYLIB4gCjYCBCAeIAw2AgAgC0HABmokAAwBCyAUIAoQYQALIBwoAgwhDiAcKAIIIQogCQRAIAggCRB2CyAHBEAgBiAHEHYLIAUEQCAEIAUQdgsgAwRAIAIgAxB2CyABBEAgACABEHYLIBsgCjYCCCAbIA5BACAKQQFxIgAbNgIEIBtBACAOIAAbNgIAIBxBEGokACAbKAIAIBsoAgQgGygCCCAbQRBqJAALOAACQCACQYCAxABGDQAgACACIAEoAhARAABFDQBBAQ8LIANFBEBBAA8LIAAgA0EAIAEoAgwRAgALIgACQCAAIAEQYkUNACAABEAgACABEHkiAUUNAQsgAQ8LAAv6AQICfwF+IwBBEGsiAiQAIAJBATsBDCACIAE2AgggAiAANgIEIwBBEGsiASQAIAJBBGoiACkCACEEIAEgADYCDCABIAQ3AgQjAEEQayIAJAAgAUEEaiIBKAIAIgIoAgwhAwJAAkACQAJAIAIoAgQOAgABAgsgAw0BQQEhAkEAIQMMAgsgAw0AIAIoAgAiAigCBCEDIAIoAgAhAgwBCyAAQYCAgIB4NgIAIAAgATYCDCAAQZSNwAAgASgCBCABKAIIIgAtAAggAC0ACRAyAAsgACADNgIEIAAgAjYCACAAQfiMwAAgASgCBCABKAIIIgAtAAggAC0ACRAyAAsfAAJAIAEgAxBiBEAgACABIAMgAhBvIgANAQsACyAACx0AIABFBEAQegALIAAgAiADIAQgBSABKAIQERQACxsAIABFBEAQegALIAAgAiADIAQgASgCEBEJAAsbACAARQRAEHoACyAAIAIgAyAEIAEoAhARJAALGwAgAEUEQBB6AAsgACACIAMgBCABKAIQEQYACxsAIABFBEAQegALIAAgAiADIAQgASgCEBElAAsbACAARQRAEHoACyAAIAIgAyAEIAEoAhARJgALJQEBfyAAKAIAIgFBgICAgHhyQYCAgIB4RwRAIAAoAgQgARB2CwsZACAARQRAEHoACyAAIAIgAyABKAIQEQQACxkAIABFBEAQegALIAAgAiADIAEoAhARAgALFwAgAEUEQBB6AAsgACACIAEoAhARAAALFwEBfyAA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ASABQSBqNgIQIAFBCGogABBSAAsLyxQHAEGAgMAAC4sJUG93UGF5bG9hZHNlZWRfbm9uY2Vub25jZWhhc2hkaWZmaWN1bHR5U2VjdXJlUGF5bG9hZHNpZ25hdHVyZWZpbmdlcnByaW50Y2xpZW50X2lwcG93djAAAGfmCWqFrme7cvNuPDr1T6V/Ug5RjGgFm6vZgx8ZzeBbcG93X3RpbWVvdXRfAQAAAAAAAACDABAAAQAAADoAAAABAAAAAAAAAJQAEAABAAAAlAAQAAEAAACUABAAAQAAAAEAAAAAAAAAlAAQAAEAAACUABAAAQAAAJQAEAABAAAAlAAQAAEAAACUABAAAQAAAJQAEAABAAAAMy4wc2VyaWFsaXplIHBheWxvYWQgZmFpbGVkOiAAAADzABAAGgAAAE5vIHdpbmRvdyBmb3VuZE5vIGRvY3VtZW50IGZvdW5kY2FudmFzMmRObyAyRCBjb250ZXh0I2Y2MGJvbGQgMTJweCAnQ291cmllciBOZXcnIzA2OUNoYXROZXh0X1NlY3VyZTAxMjM0NTY3ODlhYmNkZWZjYXBhY2l0eSBvdmVyZmxvd2xpYnJhcnkvYWxsb2Mvc3JjL2ZtdC5ycwAvcnVzdGMvZGVkNWMwNmNmMjFkMmI5M2JmZmQ1ZDg4NGFhNmU5NjkzNGVlNDIzNC9saWJyYXJ5L3N0ZC9zcmMvc3lzL3RocmVhZF9sb2NhbC9ub190aHJlYWRzLnJzAEM6XFVzZXJzXEFkbWluaXN0cmF0b3JcLmNhcmdvXHJlZ2lzdHJ5XHNyY1xpbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zlx3YXNtLWJpbmRnZW4tMC4yLjExNFxzcmNcZXh0ZXJucmVmLnJzAC9ydXN0Yy9kZWQ1YzA2Y2YyMWQyYjkzYmZmZDVkODg0YWE2ZTk2OTM0ZWU0MjM0L2xpYnJhcnkvYWxsb2Mvc3JjL3NsaWNlLnJzAC9ydXN0L2RlcHMvaGFzaGJyb3duLTAuMTUuNS9zcmMvcmF3L21vZC5ycwBsaWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjL21vZC5ycwAvcnVzdC9kZXBzL2RsbWFsbG9jLTAuMi4xMC9zcmMvZGxtYWxsb2MucnMAbGlicmFyeS9zdGQvc3JjL2FsbG9jLnJzAEM6XFVzZXJzXEFkbWluaXN0cmF0b3JcLmNhcmdvXHJlZ2lzdHJ5XHNyY1xpbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3ZlxzZXJkZS13YXNtLWJpbmRnZW4tMC42LjVcc3JjXGxpYi5ycwBDOlxVc2Vyc1xBZG1pbmlzdHJhdG9yXC5jYXJnb1xyZWdpc3RyeVxzcmNcaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Zcb25jZV9jZWxsLTEuMjEuNFxzcmNcbGliLnJzAAAAAIYCEABKAAAABwIAADIAAAAAAAAAZ+YJaoWuZ7ty8248OvVPpX9SDlGMaAWbq9mDHxnN4FthAxAAbwAAADUAAAAOAAAA//////////+ABBAAQZiJwAAL8QVBdHRlbXB0ZWQgdG8gaW5pdGlhbGl6ZSB0aHJlYWQtbG9jYWwgd2hpbGUgaXQgaXMgYmVpbmcgZHJvcHBlZAAAmAQQAD4AAAC1ARAAXgAAAGsAAAANAAAAIGNhbid0IGJlIHJlcHJlc2VudGVkIGFzIGEgSmF2YVNjcmlwdCBudW1iZXIBAAAAAAAAAPAEEAAsAAAARAoQAFAKEABcChAAaAoQAExhenkgaW5zdGFuY2UgaGFzIHByZXZpb3VzbHkgYmVlbiBwb2lzb25lZAAAPAUQACoAAADRAxAAZwAAABIDAAAZAAAAcmVlbnRyYW50IGluaXQAAIAFEAAOAAAA0QMQAGcAAACEAgAADQAAAGNsb3N1cmUgaW52b2tlZCByZWN1cnNpdmVseSBvciBhZnRlciBiZWluZyBkcm9wcGVkAAAUAhAAcQAAAH8AAAARAAAAFAIQAHEAAACMAAAAEQAAAHz9izJX5lf5At9Ev+NI569tXcvWLFDrY3hBpldxG4u5bWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAAAHAYQABUAAAAxBhAADQAAAEgDEAAYAAAAZAEAAAkAAAAqAAAADAAAAAQAAAArAAAALAAAAC0AAAAAAAAACAAAAAQAAAAuAAAALwAAADAAAAAxAAAAMgAAABAAAAAEAAAAMwAAADQAAAA1AAAANgAAAAAAAAAIAAAABAAAADcAAABhc3NlcnRpb24gZmFpbGVkOiBwc2l6ZSA+PSBzaXplICsgbWluX292ZXJoZWFkAAAdAxAAKgAAALEEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPD0gc2l6ZSArIG1heF9vdmVyaGVhZAAAHQMQACoAAAC3BAAADQAAACoAAAAMAAAABAAAADgAAABIYXNoIHRhYmxlIGNhcGFjaXR5IG92ZXJmbG93UAcQABwAAADRAhAAKgAAACUAAAAoAAAARXJyb3IAQZSPwAALhgQBAAAAOQAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90AACcARAAGAAAAIoCAAAOAAAAY2FwYWNpdHkgb3ZlcmZsb3cAAAAECBAAEQAAAPwCEAAgAAAAHAAAAAUAAAA6AAAADAAAAAQAAAA7AAAAPAAAAD0AAAABAAAAAAAAADAwMDEwMjAzMDQwNTA2MDcwODA5MTAxMTEyMTMxNDE1MTYxNzE4MTkyMDIxMjIyMzI0MjUyNjI3MjgyOTMwMzEzMjMzMzQzNTM2MzczODM5NDA0MTQyNDM0NDQ1NDY0NzQ4NDk1MDUxNTI1MzU0NTU1NjU3NTg1OTYwNjE2MjYzNjQ2NTY2Njc2ODY5NzA3MTcyNzM3NDc1NzY3Nzc4Nzk4MDgxODI4Mzg0ODU4Njg3ODg4OTkwOTE5MjkzOTQ5NTk2OTc5ODk5OiABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB3JPAAAszAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwMDAwMDAwMDAwMDAwMDAwQEBAQEAEGclMAACygBAAAAAAAAABgJEAACAAAAUmVmQ2VsbCBhbHJlYWR5IGJvcnJvd2VkAEHElMAACzECAAAAAAAAACAAAAACAAAAAAAAACEAAAACAAAAAAAAACIAAAACAAAAAAAAACMAAAAkAEGAlcAACwEEAHwJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AwVydXN0Yx0xLjkyLjAgKGRlZDVjMDZjZiAyMDI1LTEyLTA4KQZ3YWxydXMGMC4yNS4yDHdhc20tYmluZGdlbhMwLjIuMTE0ICgyMmNmZDU1NjgpAGsPdGFyZ2V0X2ZlYXR1cmVzBisPbXV0YWJsZS1nbG9iYWxzKxNub250cmFwcGluZy1mcHRvaW50KwtidWxrLW1lbW9yeSsIc2lnbi1leHQrD3JlZmVyZW5jZS10eXBlcysKbXVsdGl2YWx1ZQ=="; + +// --- wasm-bindgen wrapper starts here --- +/* @ts-self-types="./wasm_signer.d.ts" */ + +/** + * @param {string} username + * @param {string} timestamp + * @param {string} nonce_js + * @param {string} challenge + * @param {string} client_ip + * @param {number} difficulty + * @returns {any} + */ +function generate_secure_payload(username, timestamp, nonce_js, challenge, client_ip, difficulty) { + const ptr0 = passStringToWasm0(username, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(timestamp, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(nonce_js, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passStringToWasm0(challenge, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len3 = WASM_VECTOR_LEN; + const ptr4 = passStringToWasm0(client_ip, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len4 = WASM_VECTOR_LEN; + const ret = wasm.generate_secure_payload(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, difficulty); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return takeFromExternrefTable0(ret[0]); +} + +function __wbg_get_imports() { + const import0 = { + __proto__: null, + __wbg_Error_83742b46f01ce22d: function(arg0, arg1) { + const ret = Error(getStringFromWasm0(arg0, arg1)); + return ret; + }, + __wbg_String_8564e559799eccda: function(arg0, arg1) { + const ret = String(arg1); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }, + __wbg___wbindgen_is_undefined_52709e72fb9f179c: function(arg0) { + const ret = arg0 === undefined; + return ret; + }, + __wbg___wbindgen_throw_6ddd609b62940d55: function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }, + __wbg_createElement_9b0aab265c549ded: function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.createElement(getStringFromWasm0(arg1, arg2)); + return ret; + }, arguments); }, + __wbg_document_c0320cd4183c6d9b: function(arg0) { + const ret = arg0.document; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_fillRect_4e5596ca954226e7: function(arg0, arg1, arg2, arg3, arg4) { + arg0.fillRect(arg1, arg2, arg3, arg4); + }, + __wbg_fillText_b1722b6179692b85: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { + arg0.fillText(getStringFromWasm0(arg1, arg2), arg3, arg4); + }, arguments); }, + __wbg_getContext_f04bf8f22dcb2d53: function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.getContext(getStringFromWasm0(arg1, arg2)); + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, arguments); }, + __wbg_instanceof_CanvasRenderingContext2d_08b9d193c22fa886: function(arg0) { + let result; + try { + result = arg0 instanceof CanvasRenderingContext2D; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }, + __wbg_instanceof_HtmlCanvasElement_26125339f936be50: function(arg0) { + let result; + try { + result = arg0 instanceof HTMLCanvasElement; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }, + __wbg_instanceof_Window_23e677d2c6843922: function(arg0) { + let result; + try { + result = arg0 instanceof Window; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }, + __wbg_new_ab79df5bd7c26067: function() { + const ret = new Object(); + return ret; + }, + __wbg_random_5bb86cae65a45bf6: function() { + const ret = Math.random(); + return ret; + }, + __wbg_set_6be42768c690e380: function(arg0, arg1, arg2) { + arg0[arg1] = arg2; + }, + __wbg_set_fillStyle_58417b6b548ae475: function(arg0, arg1, arg2) { + arg0.fillStyle = getStringFromWasm0(arg1, arg2); + }, + __wbg_set_font_b038797b3573ae5e: function(arg0, arg1, arg2) { + arg0.font = getStringFromWasm0(arg1, arg2); + }, + __wbg_set_height_b6548a01bdcb689a: function(arg0, arg1) { + arg0.height = arg1 >>> 0; + }, + __wbg_set_width_c0fcaa2da53cd540: function(arg0, arg1) { + arg0.width = arg1 >>> 0; + }, + __wbg_static_accessor_GLOBAL_8adb955bd33fac2f: function() { + const ret = typeof global === 'undefined' ? null : global; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_static_accessor_GLOBAL_THIS_ad356e0db91c7913: function() { + const ret = typeof globalThis === 'undefined' ? null : globalThis; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_static_accessor_SELF_f207c857566db248: function() { + const ret = typeof self === 'undefined' ? null : self; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_static_accessor_WINDOW_bb9f1ba69d61b386: function() { + const ret = typeof window === 'undefined' ? null : window; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_toDataURL_bf99d85b39ce57cc: function() { return handleError(function (arg0, arg1) { + const ret = arg1.toDataURL(); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }, arguments); }, + __wbindgen_cast_0000000000000001: function(arg0) { + // Cast intrinsic for `F64 -> Externref`. + const ret = arg0; + return ret; + }, + __wbindgen_cast_0000000000000002: function(arg0, arg1) { + // Cast intrinsic for `Ref(String) -> Externref`. + const ret = getStringFromWasm0(arg0, arg1); + return ret; + }, + __wbindgen_cast_0000000000000003: function(arg0) { + // Cast intrinsic for `U64 -> Externref`. + const ret = BigInt.asUintN(64, arg0); + return ret; + }, + __wbindgen_init_externref_table: function() { + const table = wasm.__wbindgen_externrefs; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + }, + }; + return { + __proto__: null, + "./wasm_signer_bg.js": import0, + }; +} + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_externrefs.set(idx, obj); + return idx; +} + +let cachedDataViewMemory0 = null; +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return decodeText(ptr, len); +} + +let cachedUint8ArrayMemory0 = null; +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_externrefs.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} + +let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +const cachedTextEncoder = new TextEncoder(); + +if (!('encodeInto' in cachedTextEncoder)) { + cachedTextEncoder.encodeInto = function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; + }; +} + +let WASM_VECTOR_LEN = 0; + +let wasmModule, wasm; +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + wasmModule = module; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + wasm.__wbindgen_start(); + return wasm; +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + } catch (e) { + const validResponse = module.ok && expectedResponseType(module.type); + + if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { throw e; } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + } else { + return instance; + } + } + + function expectedResponseType(type) { + switch (type) { + case 'basic': case 'cors': case 'default': return true; + } + return false; + } +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + + if (module !== undefined) { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + const instance = new WebAssembly.Instance(module, imports); + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (module_or_path !== undefined) { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (module_or_path === undefined) { + module_or_path = new URL('wasm_signer_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + + + +// --- wasm-bindgen wrapper ends here --- + +// Exported Initialization Helper +let wasmInitialized = false; +export async function initTinyCmsWasm() { + if (wasmInitialized) return; + // Install the DOM shims the wasm-bindgen glue expects before instantiating + // the module (see setupDomMocks() above). Left installed for the process + // lifetime — generateSecurePayload() keeps calling into the same canvas + // shims on every invocation, not just at init. + setupDomMocks(); + const wasmBuffer = Buffer.from(WASM_BASE64, 'base64'); + await __wbg_init(wasmBuffer); + wasmInitialized = true; +} + +// Add type bindings +export interface PowPayload { + seed_nonce: number; + nonce: number; + hash: string; + difficulty: number; +} + +export interface SecurePayload { + signature: string; + fingerprint: string; + client_ip: string; + pow: PowPayload; + v: string; +} + +// Export wrapper function typed +export function generateSecurePayload( + username: string, + timestamp: string, + nonce_js: string, + challenge: string, + client_ip: string, + difficulty: number +): SecurePayload { + return generate_secure_payload(username, timestamp, nonce_js, challenge, client_ip, difficulty) as SecurePayload; +} diff --git a/src/lib/providers/validation.ts b/src/lib/providers/validation.ts index fea39d669c..76ebda1290 100644 --- a/src/lib/providers/validation.ts +++ b/src/lib/providers/validation.ts @@ -39,6 +39,7 @@ import { import { validateMuseSparkWebProvider, validateAdaptaWebProvider, + validateTinyCmsWebProvider, validateClaudeWebProvider, validateGeminiWebProvider, validateCopilotM365WebProvider, @@ -256,6 +257,7 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi "muse-spark-web": validateMuseSparkWebProvider, "inner-ai": validateInnerAiProvider, "adapta-web": validateAdaptaWebProvider, + "tinycms-web": validateTinyCmsWebProvider, "claude-web": validateClaudeWebProvider, "gemini-web": validateGeminiWebProvider, "notion-web": validateNotionWebProvider, diff --git a/src/lib/providers/validation/webProvidersB.ts b/src/lib/providers/validation/webProvidersB.ts index d455d34ae7..375f078796 100644 --- a/src/lib/providers/validation/webProvidersB.ts +++ b/src/lib/providers/validation/webProvidersB.ts @@ -679,3 +679,34 @@ export async function validateInnerAiProvider({ apiKey, providerSpecificData = { return toValidationErrorResult(error); } } + +export async function validateTinyCmsWebProvider({ apiKey, providerSpecificData = {} }: any) { + try { + const raw = typeof apiKey === "string" ? apiKey.trim() : ""; + if (!raw || !raw.startsWith("R")) { + return { valid: false, error: "TinyCMS UUID must start with 'R'" }; + } + + const response = await validationRead("https://gov.freegpt.win/api/challenge", { + headers: applyCustomUserAgent( + { + uuid: raw, + "x-origin": "https://gov.freegpt.win", + Accept: "application/json", + }, + providerSpecificData + ), + }); + + if (!response.ok) { + return { + valid: false, + error: `TinyCMS UUID validation status: ${response.status} (invalid/expired UUID)`, + }; + } + + return { valid: true, error: null }; + } catch (error: any) { + return toValidationErrorResult(error); + } +} diff --git a/src/shared/constants/providers/web-cookie.ts b/src/shared/constants/providers/web-cookie.ts index dbc9a81e24..097fdd5cd9 100644 --- a/src/shared/constants/providers/web-cookie.ts +++ b/src/shared/constants/providers/web-cookie.ts @@ -379,6 +379,20 @@ export const WEB_COOKIE_PROVIDERS = { authHint: "Login at zenmux.ai, then export all cookies using EditThisCookie or Cookie-Editor and paste the full Cookie header string here. Refresh every ~30 days.", }, + "tinycms-web": { + id: "tinycms-web", + alias: "tcw", + name: "TinyCMS Web (Free/Sub)", + icon: "layers", + color: "#ED8936", + textIcon: "TC", + website: "https://site.tinycms.xyz", + hasFree: true, + freeNote: + "Free tier has access to GPT 5.4, Gemini 3.5, and Grok 4.20 models. No login required. Subscription grants 300 requests/day for advanced models.", + authHint: + "Go to site.tinycms.xyz, open DevTools → Application → Local Storage, copy the value of 'app-config-uuid' (starts with 'R'), and paste it here.", + }, "zai-web": { id: "zai-web", alias: "zw", diff --git a/src/shared/providers/webSessionCredentials.ts b/src/shared/providers/webSessionCredentials.ts index 3bab112a4f..a6ec0abb40 100644 --- a/src/shared/providers/webSessionCredentials.ts +++ b/src/shared/providers/webSessionCredentials.ts @@ -32,6 +32,13 @@ export const WEB_SESSION_CREDENTIAL_REQUIREMENTS = { acceptsFullCookieHeader: true, storageKeys: ["cookie"], }, + "tinycms-web": { + kind: "token", + credentialName: "app-config-uuid", + placeholder: "R...", + acceptsFullCookieHeader: false, + storageKeys: ["apiKey", "token", "uuid", "app-config-uuid"], + }, "chatgpt-web": { kind: "cookie", credentialName: "__Secure-next-auth.session-token", diff --git a/tests/unit/provider-tinycms-web.test.ts b/tests/unit/provider-tinycms-web.test.ts new file mode 100644 index 0000000000..0731d742db --- /dev/null +++ b/tests/unit/provider-tinycms-web.test.ts @@ -0,0 +1,240 @@ +/** + * Tests for TinyCMS Web provider — registration, credential validation, challenge/PoW flow. + * + * Validates: + * - WEB_COOKIE_PROVIDERS contains the tinycms-web entry + * - Registry entry has correct shape and models + * - Executor resolves for both primary id and alias + * - UUID validation (must start with 'R') + * - WASM initialization flow + * - Challenge/PoW flow with mocked network calls + * - Error sanitization (Hard Rule #12: no stack traces) + * - Configurable userid from providerSpecificData + */ +import test, { before, after } from "node:test"; +import assert from "node:assert/strict"; + +import { WEB_COOKIE_PROVIDERS } from "../../src/shared/constants/providers/web-cookie.ts"; +import { REGISTRY } from "../../open-sse/config/providers/index.ts"; +import { getExecutor, TinyCmsExecutor } from "../../open-sse/executors/index.ts"; +import { + setupDomMocks, + type DomMockRestore, +} from "../../open-sse/executors/tinycmsSigner.ts"; + +// tinycmsSigner.ts intentionally does NOT install its window/document/canvas +// shims as a module-load side effect (see setupDomMocks() there) — doing so +// would leak those globals into every other test file that transitively +// imports it (e.g. through the provider registry). Install them explicitly +// for this file only, and restore whatever was there before once this file's +// tests are done. +let restoreDomMocks: DomMockRestore; + +before(() => { + restoreDomMocks = setupDomMocks(); +}); + +after(() => { + restoreDomMocks(); +}); + +// ── Catalog / WEB_COOKIE_PROVIDERS ──────────────────────────────────────────── + +test("tinycms-web is present in WEB_COOKIE_PROVIDERS", () => { + const p = (WEB_COOKIE_PROVIDERS as Record)[ + "tinycms-web" + ] as Record; + assert.ok(p, "WEB_COOKIE_PROVIDERS['tinycms-web'] must exist"); + assert.equal(p.id, "tinycms-web"); + assert.equal(p.alias, "tcw"); + assert.equal((p.name as string).toLowerCase().includes("tinycms"), true); +}); + +test("tinycms-web WEB_COOKIE_PROVIDERS entry is marked as free-tier", () => { + const p = (WEB_COOKIE_PROVIDERS as Record)[ + "tinycms-web" + ] as Record; + assert.equal(p.hasFree, true); + assert.ok(typeof p.freeNote === "string" && (p.freeNote as string).length > 0); + assert.ok(typeof p.authHint === "string" && (p.authHint as string).length > 0); +}); + +// ── Registry / REGISTRY ─────────────────────────────────────────────────────── + +test("tinycms-web is present in the provider REGISTRY with correct shape", () => { + const r = REGISTRY["tinycms-web"]; + assert.ok(r, "REGISTRY['tinycms-web'] must exist"); + assert.equal(r.id, "tinycms-web"); + assert.equal(r.alias, "tcw"); + assert.equal(r.executor, "tinycms-web"); + assert.equal(r.format, "openai"); + assert.equal(r.authType, "apikey"); + assert.equal(r.authHeader, "uuid"); +}); + +test("tinycms-web registry has all expected models", () => { + const r = REGISTRY["tinycms-web"]; + assert.ok(r.models && r.models.length > 0, "must have at least one model"); + const ids = r.models.map((m) => m.id); + + assert.ok(ids.includes("gpt-5-free"), "gpt-5-free must be registered"); + assert.ok(ids.includes("gpt-5.3-free"), "gpt-5.3-free must be registered"); + assert.ok( + ids.includes("gpt-5.3-thinking-free"), + "gpt-5.3-thinking-free must be registered" + ); + assert.ok(ids.includes("deepseek-v4-flash"), "deepseek-v4-flash must be registered"); + assert.ok(ids.includes("claude-sonnet-5"), "claude-sonnet-5 must be registered"); + assert.ok(ids.includes("gemini-3.5-flash"), "gemini-3.5-flash must be registered"); + assert.equal(r.models.length, 16, "must have exactly 16 models"); +}); + +test("tinycms-web model names are human-readable strings", () => { + const r = REGISTRY["tinycms-web"]; + for (const m of r.models) { + assert.ok(m.id && typeof m.id === "string", `model id must be a string: ${JSON.stringify(m)}`); + assert.ok( + m.name && typeof m.name === "string", + `model name must be a string: ${JSON.stringify(m)}` + ); + } +}); + +test("supportsReasoning is set on gpt-5.3-thinking-free", () => { + const r = REGISTRY["tinycms-web"]; + const thinkingModel = r.models.find((m) => m.id === "gpt-5.3-thinking-free"); + assert.ok(thinkingModel, "gpt-5.3-thinking-free must exist"); + assert.equal(thinkingModel!.supportsReasoning, true); +}); + +// ── Executor ────────────────────────────────────────────────────────────────── + +test("getExecutor returns TinyCmsExecutor for 'tinycms-web'", () => { + const e = getExecutor("tinycms-web"); + assert.ok(e instanceof TinyCmsExecutor, "executor must be TinyCmsExecutor"); +}); + +test("getExecutor returns TinyCmsExecutor for 'tcw' alias", () => { + const e = getExecutor("tcw"); + assert.ok(e instanceof TinyCmsExecutor, "alias 'tcw' must resolve to TinyCmsExecutor"); +}); + +test("TinyCmsExecutor can be instantiated", () => { + const executor = new TinyCmsExecutor(); + assert.ok(executor, "must instantiate without errors"); + assert.ok(typeof executor.execute === "function", "must have an execute method"); +}); + +// ── UUID validation (must start with 'R') ───────────────────────────────────── + +test("TinyCmsExecutor returns 401 when UUID is missing", async () => { + const executor = new TinyCmsExecutor(); + const result = await executor.execute({ + model: "gpt-5-free", + body: { messages: [{ role: "user", content: "hi" }] }, + stream: false, + credentials: {}, + signal: AbortSignal.timeout(5000), + }); + assert.ok(result.response, "response must be present"); + assert.equal(result.response.status, 401); + const body = await result.response.json(); + const errMsg = body?.error?.message || ""; + assert.ok( + errMsg.includes("Invalid or missing device UUID"), + "error must mention missing UUID" + ); + // Hard Rule #12: must NOT leak stack traces + assert.ok(!errMsg.includes("at /"), "error must not contain a stack trace path"); +}); + +test("TinyCmsExecutor returns 401 when UUID does not start with 'R'", async () => { + const executor = new TinyCmsExecutor(); + const result = await executor.execute({ + model: "gpt-5-free", + body: { messages: [{ role: "user", content: "hi" }] }, + stream: false, + credentials: { apiKey: "abc123" }, // does not start with 'R' + signal: AbortSignal.timeout(5000), + }); + assert.ok(result.response, "response must be present"); + assert.equal(result.response.status, 401); + const body = await result.response.json(); + const errMsg = body?.error?.message || ""; + assert.ok( + errMsg.includes("Invalid or missing device UUID"), + "error must mention missing UUID" + ); + assert.ok(!errMsg.includes("at /"), "error must not contain a stack trace path"); +}); + +// ── WASM initialization ─────────────────────────────────────────────────────── + +test("initTinyCmsWasm module exports expected functions", async () => { + const signer = await import("../../open-sse/executors/tinycmsSigner.ts"); + assert.ok( + typeof signer.initTinyCmsWasm === "function", + "must export initTinyCmsWasm function" + ); + assert.ok( + typeof signer.generateSecurePayload === "function", + "must export generateSecurePayload function" + ); +}); + +test("initTinyCmsWasm is idempotent (calling twice does not throw)", async () => { + const signer = await import("../../open-sse/executors/tinycmsSigner.ts"); + try { + await signer.initTinyCmsWasm(); + await signer.initTinyCmsWasm(); // Second call should be a no-op + } catch { + // WASM may not be available in all Node.js test environments; + // the important thing is that the function handles errors gracefully + // and both calls behave the same way. + } +}); + +// ── Error sanitization (Hard Rule #12) ──────────────────────────────────────── + +test("TinyCmsExecutor sanitizes errors (no stack traces in error response)", async () => { + const executor = new TinyCmsExecutor(); + const result = await executor.execute({ + model: "gpt-5-free", + body: { messages: [{ role: "user", content: "hi" }] }, + stream: false, + credentials: { apiKey: "" }, // empty UUID + signal: AbortSignal.timeout(5000), + }); + + assert.ok(result.response, "response must be present"); + const body = await result.response.json(); + const errMsg = body?.error?.message || ""; + assert.ok( + errMsg.includes("Invalid or missing device UUID"), + "error must mention missing UUID" + ); + assert.ok(!errMsg.includes("at /"), "error must not contain a stack trace path (Hard Rule #12)"); +}); + +// ── Provider-specific credential requirements ───────────────────────────────── + +test("tinycms-web credential requirement is kind: token with app-config-uuid", async () => { + const { WEB_SESSION_CREDENTIAL_REQUIREMENTS } = + await import("../../src/shared/providers/webSessionCredentials.ts"); + const req = (WEB_SESSION_CREDENTIAL_REQUIREMENTS as Record)[ + "tinycms-web" + ] as Record; + assert.ok(req, "credential requirement must exist for tinycms-web"); + assert.equal(req.kind, "token"); + assert.equal(req.credentialName, "app-config-uuid"); + assert.equal(req.acceptsFullCookieHeader, false); + assert.ok(Array.isArray(req.storageKeys), "must have storageKeys array"); + assert.ok( + (req.storageKeys as string[]).includes("apiKey"), + "apiKey must be in storageKeys" + ); + assert.ok( + (req.storageKeys as string[]).includes("uuid"), + "uuid must be in storageKeys" + ); +});