@wevi/mcp 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +16 -2
- package/dist/chunk-IDFFE3P7.js +981 -0
- package/dist/chunk-IDFFE3P7.js.map +1 -0
- package/dist/http.d.ts +2 -0
- package/dist/http.js +171 -0
- package/dist/http.js.map +1 -0
- package/dist/index.js +14 -777
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/wevi-api-client.ts","../src/capabilities.ts","../src/tools/templates.tools.ts","../src/types/index.ts","../src/tools/projects.tools.ts","../src/tools/renders.tools.ts","../src/tools/ai.tools.ts","../src/tools/browse.tools.ts","../src/tools/index.ts","../src/brand.ts"],"sourcesContent":["import {\n WeviConfig,\n WeviCreditBalance,\n WeviEditableLayer,\n WeviExportStatus,\n WeviProject,\n WeviPublishStatus,\n WeviSceneInput,\n WeviTemplateSummary,\n} from \"../types/index.js\";\n\nconst USER_AGENT = \"Wevi-MCP-Server/0.2.1\";\n\nfunction toObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return {};\n return value as Record<string, unknown>;\n}\n\nexport class WeviApiClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(config: WeviConfig) {\n this.apiKey = config.apiKey.trim();\n this.baseUrl = config.apiUrl.replace(/\\/+$/, \"\");\n }\n\n /** True when the configured key is a `wevi_test_` sandbox key. */\n get isSandbox() {\n return this.apiKey.startsWith(\"wevi_test_\");\n }\n\n /** True for a Wevi API key (wevi_live_/wevi_test_); false for OAuth access tokens. */\n private get isApiKey() {\n return this.apiKey.startsWith(\"wevi_live_\") || this.apiKey.startsWith(\"wevi_test_\");\n }\n\n private get headers(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n // API keys go in both headers for compatibility; OAuth tokens are bearer-only.\n ...(this.isApiKey ? { \"X-API-Key\": this.apiKey } : {}),\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": USER_AGENT,\n };\n }\n\n private async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const url = `${this.baseUrl}${endpoint.startsWith(\"/\") ? \"\" : \"/\"}${endpoint}`;\n\n let response: Response;\n try {\n response = await fetch(url, {\n ...options,\n headers: { ...this.headers, ...(options.headers || {}) },\n });\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to connect to Wevi API at ${this.baseUrl}: ${msg}`);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> = {};\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n } catch {\n // non-JSON error\n }\n\n const errObj = errorBody.error;\n const rawMessage =\n (typeof errorBody.message === \"string\" && errorBody.message) ||\n (Array.isArray(errorBody.message) && errorBody.message.join(\"; \")) ||\n (typeof errObj === \"string\" && errObj) ||\n (typeof errObj === \"object\" &&\n errObj !== null &&\n typeof (errObj as { message?: unknown }).message === \"string\" &&\n (errObj as { message: string }).message) ||\n `Wevi API error (${response.status} ${response.statusText})`;\n const message = String(rawMessage);\n\n if (response.status === 402) {\n const topUpUrl =\n typeof errorBody.topUpUrl === \"string\"\n ? errorBody.topUpUrl\n : \"https://app.wevi.ai/app/profile?id=api-keys&topup=1\";\n const required = errorBody.creditsRequired;\n const available = errorBody.creditsAvailable;\n const detail =\n typeof required === \"number\" && typeof available === \"number\"\n ? ` Needs ${required} credit${required === 1 ? \"\" : \"s\"}, ${available} available.`\n : \"\";\n throw new Error(\n `[402 Payment Required] Not enough API credits.${detail} Buy a credit pack or upgrade at ${topUpUrl}. Call wevi_get_credits to see the balance.\\nDetails: ${message}`,\n );\n }\n if (response.status === 401) {\n throw new Error(\n this.isApiKey\n ? `[401 Unauthorized] Invalid or revoked Wevi API key. Check WEVI_API_KEY at https://app.wevi.ai/app/profile?id=api-keys.`\n : `[401 Unauthorized] Your Wevi connection has expired or was disconnected. Reconnect the Wevi connector in your client and try again.`,\n );\n }\n if (response.status === 429) {\n throw new Error(`[429 Too Many Requests] Slow down: ${message}`);\n }\n throw new Error(`[Wevi API Error ${response.status}] ${message}`);\n }\n\n if (response.status === 204) {\n return {} as T;\n }\n return (await response.json()) as T;\n }\n\n /**\n * Lists published, active templates. The API already restricts API-key\n * callers to published templates; we also send `status=PUBLISHED` so the\n * intent is explicit in logs.\n */\n async listTemplates(params?: {\n category?: string;\n aspectRatio?: string;\n search?: string;\n limit?: number;\n page?: number;\n }): Promise<{ items: WeviTemplateSummary[]; total: number; categories: string[] }> {\n const query = new URLSearchParams();\n query.set(\"status\", \"PUBLISHED\");\n if (params?.category) query.set(\"category\", params.category);\n if (params?.aspectRatio) query.set(\"aspectRatio\", params.aspectRatio);\n if (params?.search) query.set(\"search\", params.search);\n if (params?.limit) query.set(\"limit\", String(params.limit));\n if (params?.page) query.set(\"page\", String(params.page));\n\n const result = await this.request<{ data?: unknown }>(`/templates?${query.toString()}`);\n const data = toObject(result?.data ?? result);\n const items = (Array.isArray(data.templates) ? data.templates : []) as WeviTemplateSummary[];\n const meta = toObject(data.meta);\n const total = typeof meta.total === \"number\" ? meta.total : items.length;\n const categories = Array.isArray(data.categories)\n ? (data.categories as unknown[]).filter((c): c is string => typeof c === \"string\")\n : [];\n return { items, total, categories };\n }\n\n async getTemplate(templateId: string): Promise<WeviTemplateSummary> {\n const res = await this.request<{ data?: WeviTemplateSummary }>(\n `/templates/${encodeURIComponent(templateId)}`,\n );\n return (res?.data ?? res) as WeviTemplateSummary;\n }\n\n /** Guidance an agent needs to place a template in the right scene role. */\n static extractGuidance(template: WeviTemplateSummary) {\n const meta = template.semanticMeta ?? null;\n const instructions = meta?.instructions ?? {};\n const guide = template.smartGuide ?? meta?.smartGuide ?? null;\n return {\n purpose: instructions.purpose ?? null,\n sceneIntent: instructions.designProtocol?.sceneIntent ?? [],\n avoid: instructions.designProtocol?.avoid ?? [],\n tone: instructions.scriptGuidelines?.tone ?? null,\n onScreenTextFormat: instructions.scriptGuidelines?.onScreenTextFormat ?? null,\n do: guide?.do ?? [],\n dont: guide?.dont ?? [],\n };\n }\n\n /**\n * Flattens the template's `layerMeta` into the editable parameters an agent\n * can set. Hidden and protected layers are omitted.\n */\n static extractEditableLayers(template: WeviTemplateSummary): WeviEditableLayer[] {\n const layerMeta = toObject(template.layerMeta);\n const rawLayers = Array.isArray(template.layers) ? template.layers : [];\n const orderedKeys: string[] = [];\n for (const raw of rawLayers) {\n const key = toObject(raw).key;\n if (typeof key === \"string\" && key && !orderedKeys.includes(key)) orderedKeys.push(key);\n }\n for (const key of Object.keys(layerMeta)) {\n if (!orderedKeys.includes(key)) orderedKeys.push(key);\n }\n\n const layers: WeviEditableLayer[] = [];\n for (const key of orderedKeys) {\n if (key.startsWith(\"__ui\")) continue;\n const meta = toObject(layerMeta[key]);\n if (meta.hidden === true || meta.isProtected === true) continue;\n const control = toObject(meta.control);\n const options = Array.isArray(control.options)\n ? (control.options as unknown[]).filter((o): o is string => typeof o === \"string\")\n : [];\n const validation = toObject(meta.validation);\n const rawLayer = toObject(rawLayers.find((raw) => toObject(raw).key === key));\n layers.push({\n key,\n label: String(meta.humanLabel || meta.label || rawLayer.label || key),\n type: String(meta.type || rawLayer.type || \"text\").toLowerCase(),\n role: typeof meta.role === \"string\" ? meta.role : undefined,\n description: typeof meta.description === \"string\" ? meta.description : undefined,\n aiHint: typeof meta.aiHint === \"string\" ? meta.aiHint : undefined,\n required: meta.required === true,\n defaultValue: meta.defaultValue ?? rawLayer.defaultValue ?? null,\n ...(options.length ? { options } : {}),\n ...(Object.keys(validation).length ? { validation } : {}),\n });\n }\n return layers;\n }\n\n /**\n * Creates a render-ready project. All scenes land in ONE project so the\n * publish step exports a single concatenated video.\n */\n async createProject(data: {\n title?: string;\n scenes: WeviSceneInput[];\n brandId?: string;\n }): Promise<WeviProject> {\n const res = await this.request<{ data?: WeviProject }>(\"/projects\", {\n method: \"POST\",\n body: JSON.stringify(data),\n });\n return (res?.data ?? res) as WeviProject;\n }\n\n async getProject(projectId: string): Promise<Record<string, unknown>> {\n const res = await this.request<{ data?: unknown }>(`/projects/${encodeURIComponent(projectId)}`);\n const data = toObject(res?.data ?? res);\n return (toObject(data.project) as Record<string, unknown>) && Object.keys(toObject(data.project)).length\n ? toObject(data.project)\n : data;\n }\n\n /** Renders every scene and queues one concatenated export. */\n async publishProject(\n projectId: string,\n options?: {\n quality?: \"720p\" | \"1080p\" | \"4K\";\n includeMusic?: boolean;\n includeVoiceover?: boolean;\n includeSoundEffects?: boolean;\n },\n ): Promise<WeviPublishStatus> {\n const res = await this.request<{ data?: WeviPublishStatus }>(\n `/projects/${encodeURIComponent(projectId)}/publish`,\n { method: \"POST\", body: JSON.stringify(options ?? {}) },\n );\n return (res?.data ?? res) as WeviPublishStatus;\n }\n\n async getPublishStatus(projectId: string): Promise<WeviPublishStatus> {\n const res = await this.request<{ data?: WeviPublishStatus }>(\n `/projects/${encodeURIComponent(projectId)}/publish/status`,\n );\n return (res?.data ?? res) as WeviPublishStatus;\n }\n\n /**\n * Polls publish status until the video is ready, a failure is reported, or\n * the time budget is spent. Returns the last status either way.\n */\n async waitForPublish(\n projectId: string,\n waitSeconds: number,\n pollIntervalMs = 5000,\n ): Promise<WeviPublishStatus> {\n const deadline = Date.now() + waitSeconds * 1000;\n let status = await this.getPublishStatus(projectId);\n while (\n Date.now() < deadline &&\n (status.phase === \"rendering\" || status.phase === \"exporting\")\n ) {\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n status = await this.getPublishStatus(projectId);\n }\n return status;\n }\n\n async getRenderStatus(exportId: string): Promise<WeviExportStatus> {\n const res = await this.request<{ data?: unknown }>(`/exports/${encodeURIComponent(exportId)}`);\n const data = toObject(res?.data ?? res);\n return (Object.keys(toObject(data.export)).length ? data.export : data) as WeviExportStatus;\n }\n\n /**\n * Cheap credential check used by the remote server before handling a\n * request: true when the API accepts the bearer, false on 401.\n */\n async verifyCredentials(): Promise<boolean> {\n try {\n await this.request<unknown>(\"/billing/credits\");\n return true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.startsWith(\"[401\")) return false;\n // Other failures (network, 5xx) should not masquerade as auth errors.\n return true;\n }\n }\n\n /** Credit balance for live keys, plus the packs on sale and per-action costs. */\n async getCredits(): Promise<WeviCreditBalance> {\n const res = await this.request<{ data?: WeviCreditBalance }>(\"/billing/credits\");\n return (res?.data ?? res) as WeviCreditBalance;\n }\n\n async generateStoryboard(data: {\n prompt: string;\n brandName?: string;\n brandUrl?: string;\n brandVoice?: string;\n maxScenes?: number;\n }): Promise<Record<string, unknown>> {\n const res = await this.request<{ data?: unknown }>(\"/ai/storyboard/draft\", {\n method: \"POST\",\n body: JSON.stringify(data),\n });\n const payload = toObject(res?.data ?? res);\n return Object.keys(toObject(payload.draft)).length ? toObject(payload.draft) : payload;\n }\n\n /** Headless UI capture into a scene: loads the URL, auto-picks components, makes the scene render-ready. */\n async captureScene(\n projectId: string,\n sceneId: string,\n data: { url: string; selectors?: string[]; focus?: string[]; autoSelect?: boolean },\n ): Promise<Record<string, unknown>> {\n const res = await this.request<{ data?: unknown }>(\n `/projects/${encodeURIComponent(projectId)}/scenes/${encodeURIComponent(sceneId)}/auto-capture`,\n { method: \"POST\", body: JSON.stringify(data) },\n );\n return toObject(res?.data ?? res);\n }\n\n /** Re-pick components from a capture already taken (no page reload). */\n async selectCaptureComponents(\n projectId: string,\n sceneId: string,\n data: { captureId: string; selectedComponentIds: string[] },\n ): Promise<Record<string, unknown>> {\n const res = await this.request<{ data?: unknown }>(\n `/projects/${encodeURIComponent(projectId)}/scenes/${encodeURIComponent(sceneId)}/capture-selection`,\n { method: \"POST\", body: JSON.stringify(data) },\n );\n return toObject(res?.data ?? res);\n }\n\n async listPendingCaptures(projectId: string): Promise<Array<Record<string, unknown>>> {\n const res = await this.request<{ data?: { scenes?: unknown[] } }>(\n `/projects/${encodeURIComponent(projectId)}/captures/pending`,\n );\n const data = toObject(res?.data ?? res);\n return Array.isArray(data.scenes) ? (data.scenes as Array<Record<string, unknown>>) : [];\n }\n\n async captureWebUi(data: {\n url: string;\n selector?: string;\n viewport?: \"desktop\" | \"mobile\" | \"tablet\";\n }): Promise<Record<string, unknown>> {\n const res = await this.request<{ data?: unknown }>(\"/browse/capture\", {\n method: \"POST\",\n body: JSON.stringify(data),\n });\n return toObject(res?.data ?? res);\n }\n}\n","/**\n * The capability statement is the agent's map of Wevi: what it makes, what it\n * cannot make, and what to ask before building. It is sent to clients as the\n * MCP server `instructions` on connect and is also returned by the\n * `wevi_get_capabilities` tool for clients that ignore instructions.\n */\nexport const WEVI_CAPABILITIES = {\n summary:\n \"Wevi turns published motion templates into short marketing videos for software products: launch videos, feature explainers, product showcases, social promos, and call-to-action outros. Each scene is a pre-designed motion template (roughly 3 to 15 seconds) whose text, colors, logos, sliders and image slots you fill in. Wevi renders every scene in the cloud and joins them into one MP4 with background music and an AI voiceover.\",\n canDo: [\n \"Multi-scene videos where every scene is a published Wevi template with your copy, brand colors and logo.\",\n \"16:9 (1920x1080) widescreen videos and 16:12 (1920x1440) desktop-app frame videos. All scenes in one video must share one ratio.\",\n \"AI voiceover generated from each scene's voiceoverText, mixed with a music track at export.\",\n \"UI-capture templates: capture a live product page into a scene with wevi_capture_scene. Components are auto-selected; steer with focus keywords or CSS selectors, or re-pick with wevi_select_capture.\",\n \"Standalone web screenshots (wevi_capture_web_ui) for templates with a plain image slot.\",\n \"AI storyboard drafts (wevi_generate_storyboard) to plan scenes, copy and narration from a brief.\",\n \"Exports at 720p, 1080p or 4K, quality permitting by plan.\",\n ],\n cannotDo: [\n \"Generate free-form or generative video: no dance videos, people, characters, animals, scenery, or anything not built from a template.\",\n \"Upload or edit the user's own video footage, or stitch external clips.\",\n \"Change a template's animation, layout, duration or camera motion; only its exposed layers are editable.\",\n \"Mix aspect ratios in one video, or output vertical 9:16 video.\",\n \"Clone a specific voice; voiceover uses Wevi's voice library.\",\n ],\n storyboard: [\n \"Plan the beats in order: hook (attention, title) → problem → solution (product UI, features) → proof (stats, testimonial, social) → cta (outro). Transition templates sit between beats. Every template from wevi_list_templates carries storyboardRole (its best beat) and fitsBeats (all beats it can play).\",\n \"3 to 6 scenes, 15 to 45 seconds total. Vary templates; do not repeat the same one back to back.\",\n \"Voiceover per scene must fit voiceoverBudget (about 2.4 words per second, complete sentences). Anything longer is trimmed at export and sounds cut off.\",\n \"One idea per scene; on-screen text ≤ 6 words for titles; narration says what the visual shows.\",\n ],\n uiCapture: [\n \"Templates with requiresUiCapture show real product UI. After wevi_create_project, run wevi_capture_scene for each scene in scenesNeedingCapture with the page that best shows that scene's message.\",\n \"Slots (uiCaptureSlots): fullPageBackground templates take the whole page and need no picks; others take min..max components.\",\n \"How it works: the page is opened in a real browser, every visible element is measured from the DOM and listed as a candidate; chosen elements are cut onto their own layer and the background is recaptured with them hidden, so animations move a clean component over an intact page.\",\n \"Choose cards, buttons, inputs or media that carry the message; avoid full-width sections and paragraphs unless the template is a text template (then pick a headline first).\",\n \"Unsure? Call wevi_capture_scene with autoSelect=false, read candidates (label, type, size, selector), then wevi_select_capture with the ids. Re-picking is free.\",\n ],\n askBeforeBuilding: [\n \"What is the product or brand, and is there a website to pull colors and a logo from?\",\n \"What is the goal of the video: launch, feature explainer, social promo, or a call to action?\",\n \"Who is the audience and what tone fits (confident, playful, technical)?\",\n \"How long, or how many scenes? Typical videos are 3 to 6 scenes, 15 to 45 seconds.\",\n \"Key messages or on-screen text for each scene, if the user has them; otherwise draft with wevi_generate_storyboard and confirm.\",\n \"Should there be a voiceover, and any brand colors (hex) to apply?\",\n \"Which aspect ratio: 16:9 for general use, 16:12 for desktop-app focused frames.\",\n ],\n workflow: [\n \"1. wevi_list_templates to see what exists; group by aspect ratio and read purpose, sceneIntent and avoid to match scenes to roles (hook, feature, proof, CTA).\",\n \"2. wevi_get_template_schema for each chosen template to get exact layer keys and constraints.\",\n \"3. wevi_create_project with ALL scenes in one project. Never one project per scene. The response lists scenesNeedingCapture.\",\n \"3b. For each scene in scenesNeedingCapture, wevi_capture_scene with the product URL that best shows that scene's message (ask the user for URLs if unknown).\",\n \"4. wevi_trigger_render, then wevi_get_render_status until phase is completed; share videoUrl.\",\n \"Before large batches, wevi_get_credits. Sandbox keys (wevi_test_) are free, watermarked, 720p, and capped daily.\",\n ],\n limits: {\n aspectRatios: [\"16:9\", \"16:12\"],\n maxScenesPerProject: 12,\n sandbox: { sceneRendersPerDay: 20, exportsPerDay: 5, maxScenesPerProject: 4 },\n credits: { sceneRender: 1, export720p: 1, export1080p: 2, export4K: 4, storyboardDraft: 1, webCapture: 1 },\n },\n} as const;\n\nexport function buildServerInstructions() {\n const c = WEVI_CAPABILITIES;\n return [\n c.summary,\n \"\",\n \"Wevi CAN: \" + c.canDo.map((line) => `- ${line}`).join(\"\\n\"),\n \"\",\n \"Wevi CANNOT: \" + c.cannotDo.map((line) => `- ${line}`).join(\"\\n\"),\n \"\",\n \"If a request is outside these capabilities (e.g. a dance video, editing the user's footage, vertical video), say so clearly and offer what Wevi can do instead. Do not attempt it.\",\n \"\",\n \"Before building, ask the user what is missing from: \" + c.askBeforeBuilding.map((q) => `- ${q}`).join(\"\\n\"),\n \"\",\n \"Storyboard rules: \" + c.storyboard.map((r) => `- ${r}`).join(\"\\n\"),\n \"\",\n \"UI capture: \" + c.uiCapture.map((r) => `- ${r}`).join(\"\\n\"),\n \"\",\n \"Workflow: \" + c.workflow.map((step) => `- ${step}`).join(\"\\n\"),\n ].join(\"\\n\");\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { WeviApiClient } from \"../client/wevi-api-client.js\";\nimport { WEVI_ASPECT_RATIOS } from \"../types/index.js\";\n\nconst BEATS = [\"hook\", \"problem\", \"solution\", \"proof\", \"cta\", \"transition\"] as const;\nconst BEAT_ALIASES: Record<string, (typeof BEATS)[number]> = { hero: \"hook\", intro: \"hook\", outro: \"cta\", value: \"solution\", feature: \"solution\" };\n\n/** Storyboard placement: prefer what the API computed; fall back to the template's scene intents. */\nfunction storyboardFit(template: { storyboard?: { fitsBeats: string[]; bestUsedAs: string | null } }, intents: string[]) {\n if (template.storyboard) return { storyboardRole: template.storyboard.bestUsedAs, fitsBeats: template.storyboard.fitsBeats };\n const fits = new Set<string>();\n for (const raw of intents) {\n const key = raw.toLowerCase().trim();\n const beat = (BEATS as readonly string[]).includes(key) ? key : BEAT_ALIASES[key];\n if (beat) fits.add(beat);\n }\n const fitsBeats = BEATS.filter((b) => fits.has(b));\n return { storyboardRole: fitsBeats[0] ?? null, fitsBeats };\n}\n\nfunction errorResult(prefix: string, err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n isError: true as const,\n content: [{ type: \"text\" as const, text: `${prefix}: ${msg}` }],\n };\n}\n\nexport function registerTemplateTools(server: McpServer, client: WeviApiClient) {\n // 1. wevi_list_templates\n server.tool(\n \"wevi_list_templates\",\n [\n \"List PUBLISHED Wevi video templates (only published templates can be used in projects).\",\n \"Filter by aspect ratio, category or keyword. Every scene in one project must share the same aspectRatio,\",\n \"so pick all templates for a video from a single aspectRatio group.\",\n \"Templates with requiresUiCapture=true show real product UI: after creating the project, capture a page into those scenes with wevi_capture_scene.\",\n ].join(\" \"),\n {\n category: z\n .string()\n .optional()\n .describe(\"Category filter (e.g. 'SaaS', 'CTA', 'Problem', 'Solution', 'Motion')\"),\n aspectRatio: z\n .enum(WEVI_ASPECT_RATIOS)\n .optional()\n .describe(\n \"'16:9' = widescreen 1920x1080 (default for most videos). '16:12' = 1920x1440 desktop-app focus frame.\",\n ),\n search: z\n .string()\n .optional()\n .describe(\"Keyword matched against template names, slugs and descriptions\"),\n limit: z\n .number()\n .min(1)\n .max(50)\n .optional()\n .default(20)\n .describe(\"Number of templates to return (default 20, max 50)\"),\n page: z.number().min(1).optional().describe(\"Page number for pagination (default 1)\"),\n },\n { title: \"List video templates\", readOnlyHint: true },\n async (args) => {\n try {\n const result = await client.listTemplates(args);\n const captureTemplates = result.items.filter((t) => t.requiresUiCapture === true);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n {\n totalPublishedTemplates: result.total,\n returned: result.items.length,\n needCaptureStep: captureTemplates.length,\n categories: result.categories,\n sandbox: client.isSandbox,\n templates: result.items.map((t) => {\n const guidance = WeviApiClient.extractGuidance(t);\n return {\n id: t.id,\n slug: t.slug,\n name: t.displayName || t.name,\n description: t.aiDescription || t.description || null,\n purpose: guidance.purpose,\n ...storyboardFit(t, guidance.sceneIntent),\n voiceoverBudget: t.voiceover\n ? `${t.voiceover.maxWords} words / ${t.voiceover.maxChars} chars for ${t.voiceover.seconds ?? \"?\"}s`\n : null,\n uiCaptureSlots: t.uiCaptureSlots ?? null,\n avoid: guidance.avoid,\n tone: guidance.tone,\n category: t.category ?? null,\n aspectRatio: t.aspectRatio,\n durationSeconds: t.durationSeconds ?? null,\n requiresUiCapture: t.requiresUiCapture === true,\n tags: t.tags ?? [],\n previewVideoUrl: t.previewUrl ?? null,\n thumbnailUrl: t.thumbnailUrl ?? null,\n };\n }),\n hint:\n \"Storyboard beats in order: hook → problem → solution → proof → cta (transition templates sit between beats). Use storyboardRole as the template's best beat and fitsBeats for alternatives. Respect each template's avoid list, keep every scene in one aspectRatio, and keep each voiceover within voiceoverBudget or it is cut at export.\",\n },\n null,\n 2,\n ),\n },\n ],\n };\n } catch (err) {\n return errorResult(\"Error listing templates\", err);\n }\n },\n );\n\n // 2. wevi_get_template_schema\n server.tool(\n \"wevi_get_template_schema\",\n [\n \"Inspect the editable parameters (layer keys) of a published template: text, colors, sliders, toggles, dropdown options, media.\",\n \"Call this before wevi_create_project so the `parameters` you pass use exact layer keys and valid values.\",\n ].join(\" \"),\n {\n templateId: z.string().describe(\"Template ID or slug\"),\n },\n { title: \"Get template fields\", readOnlyHint: true },\n async (args) => {\n try {\n const template = await client.getTemplate(args.templateId);\n const editableLayers = WeviApiClient.extractEditableLayers(template);\n const guidance = WeviApiClient.extractGuidance(template);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n {\n id: template.id,\n slug: template.slug,\n name: template.displayName || template.name,\n description: template.aiDescription || template.description || null,\n category: template.category ?? null,\n aspectRatio: template.aspectRatio,\n durationSeconds: template.durationSeconds ?? null,\n requiresUiCapture: template.requiresUiCapture === true,\n captureStep: template.requiresUiCapture === true ? \"After wevi_create_project, call wevi_capture_scene for this scene with a product page URL.\" : null,\n guidance,\n ...storyboardFit(template, guidance.sceneIntent),\n voiceoverBudget: template.voiceover ?? null,\n uiCaptureSlots: template.uiCaptureSlots ?? null,\n editableLayers,\n usage:\n \"Pass values as { parameters: { [layerKey]: value } } inside a scene of wevi_create_project. Colors are hex strings, sliders are numbers within validation.min/max, toggles are booleans, dropdowns must use one of `options`.\",\n },\n null,\n 2,\n ),\n },\n ],\n };\n } catch (err) {\n return errorResult(\"Error fetching template schema\", err);\n }\n },\n );\n}\n","export interface WeviConfig {\n apiKey: string;\n apiUrl: string;\n}\n\n/** Aspect ratios Wevi templates are authored in. Mirrors the API constants. */\nexport const WEVI_ASPECT_RATIOS = [\"16:9\", \"16:12\"] as const;\nexport type WeviAspectRatio = (typeof WEVI_ASPECT_RATIOS)[number];\n\nexport interface WeviTemplateSummary {\n id: string;\n name: string;\n slug: string;\n displayName?: string;\n description?: string | null;\n aiDescription?: string | null;\n category?: string | null;\n aspectRatio: WeviAspectRatio;\n requiresUiCapture?: boolean;\n uiCaptureSlots?: { min: number; max: number; fullPageBackground: boolean } | null;\n storyboard?: { fitsBeats: string[]; bestUsedAs: string | null };\n voiceover?: { seconds: number | null; maxChars: number; maxWords: number };\n durationSeconds?: number | null;\n tags?: string[];\n previewUrl?: string | null;\n thumbnailUrl?: string | null;\n layers?: unknown;\n layerMeta?: Record<string, Record<string, unknown>>;\n semanticMeta?: {\n aiDescription?: string;\n tags?: string[];\n instructions?: {\n purpose?: string;\n designProtocol?: { sceneIntent?: string[]; avoid?: string[] };\n scriptGuidelines?: { tone?: string; onScreenTextFormat?: string };\n logicalConstraints?: { requiresUiCapture?: boolean };\n };\n smartGuide?: { do?: string[]; dont?: string[] };\n } | null;\n smartGuide?: { do?: string[]; dont?: string[] } | null;\n}\n\nexport interface WeviEditableLayer {\n key: string;\n label: string;\n type: string;\n role?: string;\n description?: string;\n aiHint?: string;\n required?: boolean;\n defaultValue?: unknown;\n options?: string[];\n validation?: Record<string, unknown>;\n}\n\nexport interface WeviSceneInput {\n templateId: string;\n title?: string;\n voiceoverText?: string;\n parameters?: Record<string, string | number | boolean | null>;\n}\n\nexport interface WeviProject {\n id: string;\n title: string;\n status: string;\n aspectRatio: WeviAspectRatio;\n sandbox?: boolean;\n sceneCount?: number;\n scenes?: Array<{\n id: string;\n position: number;\n title: string;\n templateId: string | null;\n templateSlug?: string | null;\n templateName?: string | null;\n parameters?: Record<string, unknown>;\n }>;\n nextStep?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type WeviPublishPhase =\n | \"idle\"\n | \"rendering\"\n | \"render_failed\"\n | \"exporting\"\n | \"completed\"\n | \"failed\";\n\nexport interface WeviPublishStatus {\n phase: WeviPublishPhase;\n message: string;\n sandbox: boolean;\n project: { id: string; title: string | null; status: string };\n render: {\n runId: string;\n state: string;\n sceneCount: number;\n doneScenes: number;\n failedScenes: number;\n inProgressScenes: number;\n progressPercent: number;\n failures: Array<{\n sceneId: string;\n position: number;\n title: string;\n error: string;\n }>;\n } | null;\n export: {\n id: string;\n status: string;\n progress: number;\n currentStep: string | null;\n quality: string;\n format: string;\n durationSeconds: number | null;\n errorMessage: string | null;\n completedAt: string | null;\n } | null;\n videoUrl: string | null;\n thumbnailUrl: string | null;\n}\n\nexport interface WeviExportStatus {\n id: string;\n projectId: string;\n status: \"QUEUED\" | \"DOWNLOADING\" | \"PROCESSING\" | \"UPLOADING\" | \"SUCCESS\" | \"FAILED\";\n progress?: number;\n currentStep?: string | null;\n outputUrl?: string | null;\n thumbnailUrl?: string | null;\n quality?: string;\n sandbox?: boolean;\n errorMessage?: string | null;\n createdAt: string;\n completedAt?: string | null;\n}\n\nexport interface WeviCreditBalance {\n plan: {\n slug: string;\n name: string;\n allowance: number | null;\n used: number;\n remaining: number | null;\n resetMode: \"lifetime\" | \"monthly\";\n periodStart: string | null;\n periodEnd: string | null;\n };\n purchased: { balance: number };\n totalAvailable: number | null;\n costs: Record<string, number>;\n packs: Array<{ id: string; name: string; credits: number; priceCents: number; description: string }>;\n topUpUrl: string;\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { WeviApiClient } from \"../client/wevi-api-client.js\";\n\nconst parameterValue = z.union([z.string(), z.number(), z.boolean(), z.null()]);\n\nconst sceneSchema = z.object({\n templateId: z.string().describe(\"Published template ID or slug for this scene\"),\n title: z.string().max(120).optional().describe(\"Optional scene title\"),\n voiceoverText: z\n .string()\n .max(600)\n .optional()\n .describe(\"Optional narration for this scene (voiceover is generated at export when enabled)\"),\n parameters: z\n .record(z.string(), parameterValue)\n .optional()\n .describe(\"Layer key → value map from wevi_get_template_schema (e.g. { TXTTYPINGVAR: 'Ship faster', CLRTEXTTYPINGVAR: '#F8FAFC' })\"),\n});\n\nexport function registerProjectTools(server: McpServer, client: WeviApiClient) {\n // 3. wevi_create_project\n server.tool(\n \"wevi_create_project\",\n [\n \"Create a Wevi video project from one or more published templates.\",\n \"Pass ALL scenes of the video in `scenes` (in order) — they are rendered and exported together as ONE concatenated video.\",\n \"Do not create one project per scene. All templates must share the same aspectRatio. Templates with requiresUiCapture need wevi_capture_scene afterwards; the response lists them under scenesNeedingCapture.\",\n \"The aspect ratio is taken from the templates automatically.\",\n ].join(\" \"),\n {\n title: z.string().max(160).optional().describe(\"Project title (e.g. 'Q3 Product Launch')\"),\n scenes: z\n .array(sceneSchema)\n .min(1)\n .max(12)\n .describe(\"Ordered scenes; each maps to one template with its parameters\"),\n brandId: z\n .string()\n .uuid()\n .optional()\n .describe(\"Optional Wevi brand ID. Defaults to your latest brand.\"),\n },\n { title: \"Create video project\" },\n async (args) => {\n try {\n const project = await client.createProject(args);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n {\n message: `Project created with ${project.sceneCount ?? project.scenes?.length ?? 0} scene(s).`,\n projectId: project.id,\n title: project.title,\n status: project.status,\n aspectRatio: project.aspectRatio,\n sandbox: project.sandbox === true,\n scenes: project.scenes ?? [],\n scenesNeedingCapture: (project as unknown as { scenesNeedingCapture?: unknown }).scenesNeedingCapture ?? [],\n nextStep:\n project.nextStep ??\n \"Call wevi_trigger_render with this projectId to render and export one video.\",\n },\n null,\n 2,\n ),\n },\n ],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n isError: true,\n content: [{ type: \"text\", text: `Error creating project: ${msg}` }],\n };\n }\n },\n );\n\n // 4. wevi_get_project\n server.tool(\n \"wevi_get_project\",\n \"Inspect an existing Wevi project: scenes, layer values, lifecycle status and render state.\",\n {\n projectId: z.string().describe(\"Wevi project ID\"),\n },\n { title: \"Get project details\", readOnlyHint: true },\n async (args) => {\n try {\n const project = await client.getProject(args.projectId);\n let pendingCaptures: unknown[] = [];\n try {\n pendingCaptures = (await client.listPendingCaptures(args.projectId)) as unknown[];\n } catch {\n // Older API without capture endpoints: keep the project payload only.\n }\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n {\n ...(project as Record<string, unknown>),\n pendingCaptures,\n nextStep: pendingCaptures.length\n ? \"Capture each scene in pendingCaptures with wevi_capture_scene, then call wevi_trigger_render.\"\n : undefined,\n },\n null,\n 2,\n ),\n },\n ],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n isError: true,\n content: [{ type: \"text\", text: `Error fetching project: ${msg}` }],\n };\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { WeviApiClient } from \"../client/wevi-api-client.js\";\nimport { WeviPublishStatus } from \"../types/index.js\";\n\n/** Keep in-tool waits short: MCP clients often time out a single call at ~60s. */\nconst DEFAULT_WAIT_SECONDS = 45;\nconst MAX_WAIT_SECONDS = 55;\n\nfunction formatPublishStatus(status: WeviPublishStatus, projectId: string) {\n const base = {\n projectId,\n phase: status.phase,\n message: status.message,\n sandbox: status.sandbox,\n render: status.render\n ? {\n state: status.render.state,\n progressPercent: status.render.progressPercent,\n doneScenes: status.render.doneScenes,\n sceneCount: status.render.sceneCount,\n failedScenes: status.render.failedScenes,\n failures: status.render.failures,\n }\n : null,\n export: status.export\n ? {\n id: status.export.id,\n status: status.export.status,\n progress: status.export.progress,\n currentStep: status.export.currentStep,\n quality: status.export.quality,\n errorMessage: status.export.errorMessage,\n }\n : null,\n };\n\n if (status.phase === \"completed\") {\n return {\n ...base,\n videoUrl: status.videoUrl,\n thumbnailUrl: status.thumbnailUrl,\n durationSeconds: status.export?.durationSeconds ?? null,\n note: status.sandbox\n ? \"Sandbox (wevi_test_ key): this video is watermarked and capped at 720p. Use a wevi_live_ key for production output.\"\n : undefined,\n };\n }\n\n if (status.phase === \"rendering\" || status.phase === \"exporting\") {\n return {\n ...base,\n nextStep: `Still ${status.phase}. Call wevi_get_render_status with projectId \"${projectId}\" again in ~10 seconds.`,\n };\n }\n\n return base;\n}\n\nexport function registerRenderTools(server: McpServer, client: WeviApiClient) {\n // 5. wevi_trigger_render\n server.tool(\n \"wevi_trigger_render\",\n [\n \"Render every scene of a project and export them as ONE concatenated MP4 (music + voiceover mixed in).\",\n \"Waits up to `waitSeconds` for completion; if the video is not ready yet it returns the current phase and you should poll wevi_get_render_status.\",\n \"Sandbox keys (wevi_test_) produce watermarked 720p videos without using credits, capped at 20 scene renders and 5 exports per key per UTC day and 4 scenes per project.\",\n ].join(\" \"),\n {\n projectId: z.string().describe(\"Project ID from wevi_create_project\"),\n quality: z\n .enum([\"720p\", \"1080p\", \"4K\"])\n .optional()\n .default(\"1080p\")\n .describe(\"Export quality. Free plans and sandbox keys are capped at 720p.\"),\n includeMusic: z.boolean().optional().default(true).describe(\"Mix background music\"),\n includeVoiceover: z\n .boolean()\n .optional()\n .default(true)\n .describe(\"Generate and mix voiceover from each scene's voiceoverText\"),\n waitSeconds: z\n .number()\n .min(0)\n .max(MAX_WAIT_SECONDS)\n .optional()\n .default(DEFAULT_WAIT_SECONDS)\n .describe(`Seconds to wait in this call before returning progress (0-${MAX_WAIT_SECONDS}, default ${DEFAULT_WAIT_SECONDS})`),\n },\n { title: \"Render and export video\" },\n async (args) => {\n try {\n let status = await client.publishProject(args.projectId, {\n quality: args.quality,\n includeMusic: args.includeMusic,\n includeVoiceover: args.includeVoiceover,\n });\n\n if (\n args.waitSeconds > 0 &&\n (status.phase === \"rendering\" || status.phase === \"exporting\")\n ) {\n status = await client.waitForPublish(args.projectId, args.waitSeconds);\n }\n\n const isFailure = status.phase === \"failed\" || status.phase === \"render_failed\";\n return {\n ...(isFailure ? { isError: true as const } : {}),\n content: [\n {\n type: \"text\",\n text: JSON.stringify(formatPublishStatus(status, args.projectId), null, 2),\n },\n ],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n isError: true,\n content: [{ type: \"text\", text: `Error triggering render: ${msg}` }],\n };\n }\n },\n );\n\n // 6. wevi_get_render_status\n server.tool(\n \"wevi_get_render_status\",\n [\n \"Check render + export progress for a project started with wevi_trigger_render and get the final video URL when ready.\",\n \"Optionally waits up to `waitSeconds` before returning. Pass `exportId` instead to look up a single export record.\",\n ].join(\" \"),\n {\n projectId: z.string().optional().describe(\"Project ID (preferred)\"),\n exportId: z.string().optional().describe(\"Export ID (legacy lookup of one export record)\"),\n waitSeconds: z\n .number()\n .min(0)\n .max(MAX_WAIT_SECONDS)\n .optional()\n .default(0)\n .describe(`Seconds to wait for completion before returning (0-${MAX_WAIT_SECONDS})`),\n },\n { title: \"Check render status\", readOnlyHint: true },\n async (args) => {\n try {\n if (args.projectId) {\n const status =\n args.waitSeconds > 0\n ? await client.waitForPublish(args.projectId, args.waitSeconds)\n : await client.getPublishStatus(args.projectId);\n const isFailure = status.phase === \"failed\" || status.phase === \"render_failed\";\n return {\n ...(isFailure ? { isError: true as const } : {}),\n content: [\n {\n type: \"text\",\n text: JSON.stringify(formatPublishStatus(status, args.projectId), null, 2),\n },\n ],\n };\n }\n\n if (args.exportId) {\n const record = await client.getRenderStatus(args.exportId);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n {\n exportId: record.id,\n projectId: record.projectId,\n status: record.status,\n progress: record.progress ?? null,\n currentStep: record.currentStep ?? null,\n quality: record.quality ?? null,\n sandbox: record.sandbox === true,\n videoUrl: record.status === \"SUCCESS\" ? record.outputUrl ?? null : null,\n thumbnailUrl: record.thumbnailUrl ?? null,\n errorMessage: record.errorMessage ?? null,\n completedAt: record.completedAt ?? null,\n },\n null,\n 2,\n ),\n },\n ],\n };\n }\n\n return {\n isError: true,\n content: [{ type: \"text\", text: \"Provide projectId (preferred) or exportId.\" }],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n isError: true,\n content: [{ type: \"text\", text: `Error checking render status: ${msg}` }],\n };\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { WeviApiClient } from \"../client/wevi-api-client.js\";\nimport { WEVI_CAPABILITIES } from \"../capabilities.js\";\n\nexport function registerAiTools(server: McpServer, client: WeviApiClient) {\n // wevi_get_capabilities\n server.tool(\n \"wevi_get_capabilities\",\n [\n \"What Wevi can and cannot make, the questions to ask the user before building, supported aspect ratios, sandbox limits and credit costs.\",\n \"Call this first in a new conversation, and whenever a request sounds outside Wevi's scope (e.g. 'make a dance video', 'edit my footage', 'vertical video'). No API call is made.\",\n ].join(\" \"),\n {},\n { title: \"What Wevi can do\", readOnlyHint: true },\n async () => ({\n content: [{ type: \"text\", text: JSON.stringify({ ...WEVI_CAPABILITIES, sandboxKey: client.isSandbox }, null, 2) }],\n }),\n );\n\n // 0. wevi_get_credits\n server.tool(\n \"wevi_get_credits\",\n [\n \"Show the API credit balance for this key: plan allowance used/remaining, purchased credits, what each action costs, and the top-up link.\",\n \"Call it before a large batch, or when a tool fails with 402. Sandbox keys (wevi_test_) do not use credits.\",\n ].join(\" \"),\n {},\n { title: \"Check credit balance\", readOnlyHint: true },\n async () => {\n try {\n const balance = await client.getCredits();\n const unlimited = balance.totalAvailable === null;\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n {\n sandboxKey: client.isSandbox,\n plan: balance.plan,\n purchasedCredits: balance.purchased.balance,\n totalAvailable: unlimited ? \"unlimited\" : balance.totalAvailable,\n costs: balance.costs,\n packs: balance.packs.map((pack) => ({\n id: pack.id,\n name: pack.name,\n credits: pack.credits,\n price: `$${(pack.priceCents / 100).toFixed(2)}`,\n })),\n topUpUrl: balance.topUpUrl,\n note: client.isSandbox\n ? \"This is a sandbox key: renders are free, watermarked and capped daily. Credits shown apply to your live keys.\"\n : \"A 3-scene 1080p video costs 5 credits (3 renders + 2 export).\",\n },\n null,\n 2,\n ),\n },\n ],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { isError: true, content: [{ type: \"text\", text: `Error fetching credits: ${msg}` }] };\n }\n },\n );\n\n // 7. wevi_generate_storyboard\n server.tool(\n \"wevi_generate_storyboard\",\n [\n \"Draft a multi-scene storyboard (scene titles, purposes, on-screen text and voiceover) from a brief.\",\n \"Use the draft to choose templates with wevi_list_templates and fill their parameters in wevi_create_project.\",\n ].join(\" \"),\n {\n prompt: z\n .string()\n .describe(\"Marketing goal, product description, audience and tone (e.g. '30-second SaaS promo for an AI email writer')\"),\n brandName: z.string().optional().describe(\"Brand or product name\"),\n brandUrl: z.string().url().optional().describe(\"Website URL used for brand context\"),\n brandVoice: z.string().optional().describe(\"Tone of voice (e.g. 'confident, modern, energetic')\"),\n maxScenes: z\n .number()\n .int()\n .min(3)\n .max(12)\n .optional()\n .describe(\"Soft cap on scene count (3-12)\"),\n },\n { title: \"Draft a storyboard\" },\n async (args) => {\n try {\n const result = await client.generateStoryboard(args);\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n isError: true,\n content: [{ type: \"text\", text: `Error generating storyboard: ${msg}` }],\n };\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type { ServerNotification, ServerRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { WeviApiClient } from \"../client/wevi-api-client.js\";\n\ntype ToolExtra = RequestHandlerExtra<ServerRequest, ServerNotification>;\n\n/**\n * A capture opens the page in a real browser and can take over a minute.\n * Emit progress every few seconds so clients that reset their request\n * timeout on progress keep waiting instead of giving up at 60s.\n */\nfunction startProgress(extra: ToolExtra, message: string) {\n const progressToken = extra._meta?.progressToken;\n if (progressToken === undefined) return () => {};\n let tick = 0;\n const send = () => {\n tick += 1;\n void extra\n .sendNotification({ method: \"notifications/progress\", params: { progressToken, progress: tick, message } })\n .catch(() => {});\n };\n send();\n const timer = setInterval(send, 5000);\n return () => clearInterval(timer);\n}\n\nexport function registerBrowseTools(server: McpServer, client: WeviApiClient) {\n // wevi_capture_scene\n server.tool(\n \"wevi_capture_scene\",\n [\n \"Capture a live web page into a scene whose template needs a UI capture (requiresUiCapture = true).\",\n \"Loads the URL, detects UI components, auto-selects the best ones, and makes the scene render-ready.\",\n \"Steer the choice with `focus` keywords (e.g. 'pricing table') or exact CSS `selectors`. If the result is not right, call wevi_select_capture with ids from `candidates`.\",\n \"Costs 1 credit on live keys. Use the URL of the product page that best illustrates the scene's message.\",\n ].join(\" \"),\n {\n projectId: z.string().describe(\"Project ID\"),\n sceneId: z.string().describe(\"Scene ID from wevi_create_project (see scenesNeedingCapture)\"),\n url: z.string().url().describe(\"Page to capture, e.g. 'https://stripe.com/pricing'\"),\n focus: z\n .array(z.string().max(80))\n .max(6)\n .optional()\n .describe(\"Keywords describing what to show, matched against component labels and text\"),\n selectors: z\n .array(z.string().max(255))\n .max(6)\n .optional()\n .describe(\"Exact CSS selectors to use, in order (overrides auto-selection)\"),\n autoSelect: z\n .boolean()\n .optional()\n .default(true)\n .describe(\"false = capture and list candidates only, then choose with wevi_select_capture (recommended when the page is unfamiliar)\"),\n },\n { title: \"Capture a page into a scene\" },\n async (args, extra) => {\n const stopProgress = startProgress(extra, \"Opening the page in a real browser and detecting components…\");\n try {\n const result = await client.captureScene(args.projectId, args.sceneId, {\n url: args.url,\n focus: args.focus,\n selectors: args.selectors,\n autoSelect: args.autoSelect,\n });\n const ready = result.renderReady === true;\n const intentionalPreview = args.autoSelect === false;\n return {\n ...(ready || intentionalPreview ? {} : { isError: true as const }),\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { isError: true, content: [{ type: \"text\", text: `Error capturing scene: ${msg}` }] };\n } finally {\n stopProgress();\n }\n },\n );\n\n // wevi_select_capture\n server.tool(\n \"wevi_select_capture\",\n \"Pick different components from a capture returned by wevi_capture_scene (use `captureId` and ids from `candidates`). No page reload, no credit.\",\n {\n projectId: z.string(),\n sceneId: z.string(),\n captureId: z.string().describe(\"captureId from wevi_capture_scene\"),\n selectedComponentIds: z.array(z.string()).min(1).max(6).describe(\"Component ids, in order. For text templates the first must be the text element.\"),\n },\n { title: \"Choose captured components\" },\n async (args) => {\n try {\n const result = await client.selectCaptureComponents(args.projectId, args.sceneId, {\n captureId: args.captureId,\n selectedComponentIds: args.selectedComponentIds,\n });\n return { content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }] };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { isError: true, content: [{ type: \"text\", text: `Error selecting components: ${msg}` }] };\n }\n },\n );\n\n // 8. wevi_capture_web_ui\n server.tool(\n \"wevi_capture_web_ui\",\n \"Take a standalone screenshot of a URL and get an image URL back, for templates with a plain image slot (logo/avatar/background). For templates that need a UI capture, use wevi_capture_scene instead.\",\n {\n url: z\n .string()\n .url()\n .describe(\"The website URL to capture (e.g. 'https://stripe.com')\"),\n selector: z\n .string()\n .optional()\n .describe(\"Optional CSS selector to crop a specific component or hero element\"),\n viewport: z\n .enum([\"desktop\", \"mobile\", \"tablet\"])\n .optional()\n .default(\"desktop\")\n .describe(\"Target viewport size: 'desktop' (1440x900), 'tablet' (768x1024), or 'mobile' (375x812)\"),\n },\n { title: \"Capture a web page\" },\n async (args) => {\n try {\n const result = await client.captureWebUi(args);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n isError: true,\n content: [{ type: \"text\", text: `Error capturing web UI: ${msg}` }],\n };\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { WeviApiClient } from \"../client/wevi-api-client.js\";\nimport { registerTemplateTools } from \"./templates.tools.js\";\nimport { registerProjectTools } from \"./projects.tools.js\";\nimport { registerRenderTools } from \"./renders.tools.js\";\nimport { registerAiTools } from \"./ai.tools.js\";\nimport { registerBrowseTools } from \"./browse.tools.js\";\n\nexport function registerAllTools(server: McpServer, client: WeviApiClient) {\n registerTemplateTools(server, client);\n registerProjectTools(server, client);\n registerRenderTools(server, client);\n registerAiTools(server, client);\n registerBrowseTools(server, client);\n}\n","/**\n * Wevi mark, embedded so the package needs no asset files. Served by the\n * remote server at /icon.png and /favicon.ico and declared in serverInfo.icons.\n * Regenerate from the docs icon with the script in the repo history if the mark changes.\n */\nexport const BRAND_NAME = \"Wevi\";\nexport const BRAND_WEBSITE = \"https://wevi.ai\";\nexport const ICON_PNG_512_BASE64 = \"iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AACm30lEQVR42uy9d3ycV5X//zn33meqJJfEhjiBgBOanS6lF0kBAr8ssI0Z2AbsLliQHhJCKMtoWDqkOAWQCcuWL+yXmd3vsrAbCAlIkzhOs0JIYtNCICQYiOMmjaY9z73n98dItmxLtsrMaCSd92v92mBPfeY+93PuqYAgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIwCsklWMBwRmNgS3P9xgNwSKed/DiCUO/7n6lzoFfP5iVWdq3lLCWtXMyFiZFLMB9u5JTCABQAYPtaxpYtfNjn9PYyiJrzxk2lFHp7Gb29YoAKQt2Od+RyQFALQ2Iq92qidy09P3rgyHXBgcTQFw+AMD0yGY0EACQYvb1ALzDTG+noH97xR0Tag60AmMVB4LBPPbydQQ5OLV+i+IWRx3/z+r9/Wn5oQagvJ931+bhbuez1dqTEIKJp3drWAqEwgnLg/7Tz0v+d8cGlF0AvkMBaymazQDIr3gQxAIT9rGtkFTB6qp9A7FfdteEUvazlpXZP3gF8hFLqSjBP/osyAIKmWOwkZTQmfWwNVkn1n3gq3xMUMrA7hnYx+NfjPmn9FuYBL6Km9oPMzQ1EzXtz09Qv3mFRM7zOc7Npuel/DmrU9+DJ1zSN3lqEJXpp62pYN+mb0aFeXhE4sLD54uN0OCufCMxuPTF2qCWtyg7nf7P1vMsem8goSGTXUhZiDIgBsJhFP5ut3rvJ/eNrL7677/RwS8uKYCT/lxSJvJrLZQvgFL10SQhB1ZvH1h56Xxi9/7lUssTVnWDGGy4d+m1oyq9LYGaQpw2FvH0v0CBRpWYW/9E9uxaCsP9vU8PLSLX8Obg2r0P13Pi4ruI/u4/Ph38+AWwdXLkSYILD/zTuB9KRsD78azDI6Krd4WkEu4YrDDymo562hcpPvSXxb/jDQ9u3nHvVIxjn7UwAyE6wDwpiACzMWH52LY1f7C+661/j3lJ9Hg+P/K0Kh17G5Uq7WtpmuOLvvdG5VAFbF+z14hFPYf8iIprlua0WJ/+DjR8GHfpoVY/TPzX56Z9m9UX5oM/ebOJffZmJP2tzif/UPiPNifiPN+T5EEbI2AmACJPsATQ9e8OB9ncj0gTXi0G819unlVGR0N6HqJAHf/dwoEPeZgD/wtY98sRZlwyOvUoik9EAkE0kHIgYghgAWEhx/XFW7oonMy3RijvL7Rp6N4x3qoqFX8l+UD0lF0tgxwGp/Q5MarIYXt1+WDrseb55FyTV9rTXvOI/8Wdv3pM/mlz8G3P6r/fJv95rlw53vWi8oV81EJjBpMjoSBjkGQR78lZFQw+C8XUu2oefOH+cMcAZnUXS1W2TEcQAaGhC32gZzYvv7jvdeN51IDpJxSJV0bcWrlwJiMYO1aRAs/tdqM4rY2GJ/3w9+U/82Zvz5F/juD8tRvGfggHQLOI/2XMZDIJjdiBSWkXD1XDBnoJTsdBG1uqbdmfpX7d2X5bfZwiIR0AMgPko/Cu2ELrTAQAcdddX2rWnr4fGW1UkDK74cOWyJaJDuumaU/xnH8MV8RfxF/FvvPjP9jPMSvwPfiozsQMDRKRVLAwyGlwJfkZG3ZL/7cj/eeriK4fGwgNZyREQAwDzJblvdLGuuvuOU8mjDxFRgiJh8HCBAXaj7nw1H0S0EeI/X1z/tU5OpCYU/71J5CL+8yfpr8nFfwr/zAA7ZoYKhbSKhOAC+1Ol6dYxQ6B9c5832L7NSm8BMQCaN8FvdHGu6t9wCrH6MGmdoEgIblT4iUg39Y8p4t+YG4WaWPybKO7fLOI/d0l/80T8p3v6PzSO2fGYIQDHP3Mjxc89fu5l/7TXGyCJgmIANBX9KYPudLD8zvVtsaXL3gHgVigFzhcYQN2FX5L+JOlPkv7qU+7X1OLfgLg/TeWaUV3e24HZ6WjYsHVwQfBNZ92nt5x/xY/3elvFCBADYM5d/gO9Gt3p4OjvfelkhLx/0ktaT7O799hqMXZV+Gk+/IiS9CfiL67/psv4n9dJf7V4X2YHgHRrjNhaENPlhWd3/svP/uSDw539/SbX3R1AEANgTsR/1AJddc+G9+qW2Je44oMrFQtSulEXWJL+RPwX7Mlfkv4WTtLfLN+bmS0RwSxt0TZf/NHuQunCZ7qv3t3ZnzK5rl4r3gAxABpG++Y+b7Cjxz/me19ZzjHzRTDeBmsZzjGIlIj/3LTPXbhJfyL+Iv4LKulvxs9l5kDHIgaEn9qR4o1PnHfFVyQkIAZA4+jvN+juDo753g3LEVv2Q2ptOdnt2G0B7Ncuk+bDjyfiL0l/kvQnSX9zm/Q37ecyO6cjIUUhA1h7eXn3tn/e2p3Oj0/EFjDN2RzClE7+6O4Ojr77y+vQtnIjjHeyfWG3DyIR/wUk/mhi8UdTiz/X5vPW9Qaa50l/i1z8QQxSpGy54uxIKaCQd6uJv2jjq+/+1BGgtNvbdVUQD0A93P6r7vnypXrJktu4VAaXKxYTZPhL0p+U+y2+kz/X7meVpL8myfhvMvEfm2s2/m8c+15bzLPFyuP+rmL31jdesxOZjJbhQmIA1Fz8j/p+32VmaeutLl8IwI4AEf+FlPRHTX7yl7h/g8v95pn411aEm1/8944dcByYtrixpfLj0aDY/eA5YgRAQgD1EP+Wqvg7pxem+M/Pz910rn+qvZtaxF/Ev/H1/k10VKTJ/4oUmWB4JNDR0EklE+1/9d2fOgLJpJVwgHgAaiP+9/RdZtpab3X5EQvHE07mk7i/JP2J61+S/haG+DdHxv/4uP9Ufq+qJyBmbKHyeHnIXvjT11++QzwBYgBgxgN9kkl7zPe/chktjd3q8gURfxF/Ef96xP2l018TdfprfvE/lMdmbzigUHqiPLSn+6ev/7AYAWIATI/O/n6T6xpwR/3gmEtMW/yQJ3+J+0vSn4i/uP5F/OdY/A/oFVD1BJSfKA+57p++/vIdUiIIyQGYEqmUyXV3By/6/tHH6mj4VpcvOBH/+ZT0J+LfmLi/iP+8E39mnvGfuUj6m+FzicgEQ4VAR8MnhltV/+kP3XrE6N4ueicegEOKv0I67Y76dt+Rqs27m5Q6iSsVjO/u11Ru/3E3JoMCafM7n8f7Okn6W0Sd/qgGL07Tu2hKGaNndPpnhrMuGNtvaN9DzHjVbXjcf0qegLixw4XH/bYXTl+xvcvlurvspK6FRYiRSzB+sM+Aesm5L3mx9ei7KhY5yQ3l3UTiP5efsjo3mxwBBGMMUO0+rOJR76A7ZI7EX1z/0z0N8n6fqNlO/3QIQ2Uxiv9sT/9j9wjP4uQ/rfdXBFfyYQvFXZjwvQ/j+mcos7RlCSkF8D7jxY4UAVddu87aAMxcNQoIoFlcZqpNFUzVEzASeEtbTuId/N5cd/ct1XwASD6AeABwYNJfCMlkZdXdX/mGWbHkL+wLuysgCs3VRaPxtx+zAwFQWqtoGOQZcGBhh0f2kNZgZ0fA3EdQlpmJxnpiH8J0UXCoR0BsPvjYVFO9mGv666ea6EXVNK/nvIubqlq/P7OKhskWy89HI97X/R1D5B3RNi1rORguhALPe4/SFIKtXl8mVoDqIUUt7JhNa3QpGQObLwLWwTlrwcD4UeiNFP/9nq8o0LGIsSOlS/74rEv7BtCrcpSWKYJiAGC//v6r7u67REXDt3DZ58m8Iw0Uf1c1t5VW8SjYOXBgh7nsf1eF9FZXsfmyLvcBKxEOP2ufO+eaovyQgiA0irM23RAdagtrbAd0mN9NylvCgf+3ZPRyFQm1QinYoQIYbIlIHdZRRlyfZENmhlZOR8O6uHPoFVu7r3lKkgLFABg1kDMalLSr7u57p17a9s9ueGQ06W+OLlh17KWmkAfSGmxtHsz/ayv2AXPcEf/yzMv/dPdET2vv6/PQLpuSIAgH0zK8jXNdaTvTsEX7hg3mwP1lsKPHP2gf+nZfLHhJKBQU8u/UnncmQG9TYaPcSAlgZ8GYNKG61qf/A9MYVNgDO/uoLpbf0uL2bJcxwovdAKjG/fVL1c9XWPY2ktEv43KZJ+ryV/8ZJcwASLfG4YplB8Jv4Lub6RUv/tffHPumXeM/c/vgBjM4/EpGV5cdF4SWxBZBEBqZkURj+SudAymdb11FBxoFpz5+Rwcsv9/59i1kdJwDC1fxAyIyjRL/8UmBoZVLjf/7Xd987Pwr396+ebM32NHhiwGwWNm82UNHh3/0PV/5plrWmnQ7hwIoaqzrn5kBdhQKaQIcjP4mO76xtG34p9uTl+UBVKsTuroUurqszLwWBKG5jQKgcyClu7rg0qNu9vaffv1If8euv4SnP2haYqv8HUNMNFo9UC/X/8Tpob6KRWCHi+9+/Pwr/jXBGZ2lxdskiBbx6V+DyK66u++dKh77CpfKALPXyIvEjgMVMoaiEXC5/CuEVPLZM9+5ee8D+lMG4qYSBGHe7rOjtfejhsAp965fg9bYP3DZfxuUIlepOFK1LbOmQ277cDoaUs63Tweucs6fn7VrexppXqweVFq0rn+AVv7gjhWeZzaRUau5WHEgqAae/AO9rM24keJzYNwwMjL0TzsvvnIImYxGYgtjES9KQRAW3p7bvmGDGeyphghOHfxyh3MuQyHv5S5fGtvrVCOaDDFz4C1rNcGe4cxjZ13+9vbBHjPYscEXA2CxsLnPQ/u6YNU9d2T0spa3ul3DjXT9OzCIYmFiIGuHih/73Rt7frrXWpbMVEEQsHCbrSXWrqVsMmlftfGzrZFQ24cpbK7nUgUusE7Nou/KtPZqTYEKea5SKJ/85LlX/BSZhEYya8UAwOIY8vPSO7+0xi6J/wiligK4MeLP7EhrRdEwXKH0mecufPeHAAB9fR7W9QRy4hcEYTHtwwBwwkO3dmjo/6dC5iV2pGhJKV1XIaOxUICnnB88UKyMvOGkbS8vZBMJt9jCrWoRuv6x/M71bTYW+goxh8CsGiP+zlIsopjoOVeqnPHche/+EPr7DTil0NPji/gLgrBoSCYtmAn9KfPkmZdvJld5LVv7nI5HNTtn633kJYJyhZINLW05O6ZCf5lNJm3nQK+GDANawAz0aiSTNuJF/kovaT2HiyXbkLg/O0vRqIZ1zzk/eO1zXX/3CDij0d0diMtfEIRFCRGjOx109qfMY2df9YvSrpFpGwGzaj1Oimy+aMmErj1n4x2tK7vW8tghUQyAhXj671rLy+/8tzbyzDVupGChFDVO/O1vXbF44bbXr/s5+vsNSOZTC4Ig5EaNgJ++/tqfI1++kIPgtzoe0cxs6xXwJjCIoGyxAhWPHF/kwl9mafF5ARaRByCrQEkbUYW/UvHYcVwqH/T96yr+pVL3by963y/QnzLo7pY+1IIgCAcYAY91XfWL8kilmwP7Wx07tBEw3bj/hCPQiciVK47C+to1/be1rNy+dVF5AdTiif1v4Rfd9cWVFDHXcLnsQIrq/J6OYlHNQbBtf/GXIRSCIAiTGQE/6brqFxipdDs/2DaZETBT8T9w8iERlCuVWcXDx4ej7l3ZZNYmslklBsCCOvxnFSjtvEjo1RSLHMelMtf19M/M8AxzYJ/lcrlLxF8QBGF6noBKodLlfFs1ApzjWog/TfYg65gdvw0AkICEABYiLuB1ZB3jgFkUVIfkFhWNaF303/Lbi973C/T1eSL+giAI0/MEUKHcxX7wnIqELHh2vnma9O9J2UKZdSx80qmDt5+URcKlJqkOEwMA8879r5BMumPu7jtRRcNvdaUyA/uaTdQn7h9Rbs/IZ5+56D2Pt2/u89DT48ttLQiCMHUjoL2vz3us66pf8Ej5zSocMtOu0Z8s7j+BBcDOsgp5bSgFHwQRb81mSQwALAj3f/WH1DiftA7DOh5bGjX/hZ2zavkSzcXid557/Xuu7xzoVRONzBQEQRAOzWBPj9++uc/7k67djwe7858z8YhiZldT8R9XEuhKvoOnT2vf3Hfkmi1bFkUy4GIJAbBz6m/YuTpO9mGmcIjcUGGbtvTBRCajc9u3SnMfQRCEmRoB7euCNHo5WHbUPwT54jYV8sZGp88o6e8QT1G2WGITj7w6KBZOSPemeTEkA6pF4/6PRV7NxbIbc//XPu4PB0BxKX/xMxe95ydZAIuxt7QgCEJNmwVls2rr2oRPDherkKcOGQqYUtLfZGpI4GqO2N8uls6sasG7/xlwSp1HRi9FNZOUau/650AtbdNcLn/7t2+4/PE1T2ZCY32uBUEQBMyqbXACWfXYeVc8Hgznv6CroQBb+0E3RBxY6LA58/SHbj1iMYQB1CIYd8RgvJOtBag+0/0o5Ck3UvhdQPwhANi6dotk/AuCINTqLIeEAxgmEv1wkC9uU2FPAXCzivtPEAZwxbIzseirKg4nptNpl8DCDgOohTx2EomEe9FdfWeqWPiVXKpY4tp/X2Z2FI8oV6x88veve9/W9sENRvr7C4Ig1DYU0D64wQy2rwsA+pSOhmm/hMBZiv9+YYDAsgK/G8yELCQEMC9Zu5ZAxJq4hUKhZQgsg2ru/Xcq5Bm7a/i3FrF/RiajqwtUEARBQI0TAtHbSxxf8s/+zuFtKhIyAFytxJ/GtQcmx69YDKOBF64BkNjCYBC0ehcqPpOqvfefq+1+QcSf+cMb3jHSmVhBi22etCAIQqO8AJ29XerxU94xQsZ8UoW8gGl8GGD24k8MZUtlq+Lh40+7b317NpFwKU4pMQDma/wfWIO6hP7hyPOM3b3nabsU/wRmyqFLEv8EQRDqxNgeO+SZrwfDI6SIDLiq/DPd5Gl/I4M4sKxCoeWssQpEvBVrSQyA+cRo9cfxd65vU0oZOMfTrQg57FsQAtUSYxD9x+86egrV2L+c/gVBEOrqBehPGfV8qQTQf6uWKJhgZ+r6p4nfAxxYJmd3Q0IA85GMAqVdIRzpUi3xk7hUsSCq6XclhuGRAsHivwBgsH2dnP4FQRDqTL51FT118ZVlIroHhKCm4j96vGMwsVJ/BwBZbFmwBzuDhd0HqAjn6vC6CFRrzPCe4f/87UXvfTDBGZ0lsk1VAdFb/c/OgS6V6xoYly3b5BUK4z77/ndrE39uBgGpg/eTXgBpqQgRBNQ6GRA90J73Dbsnf6vSSrNlBtXQy1t9udMW+rVc0AaAIj4KdfNEkYMy9wCgpwd3KQB2jq0dArIKA1sI3ekAaYzGzA4QoExGI7GFm0pQmQnZrOpMrKAcde/97Ps/JqUwAIUBuKYRVWbqHBjQOeoOgPSEp4T2zX3eqHeIJUQkCLUJAyQ4o7ds2VIMl5f9p4qGk8FIydI09IymFOalQnVf7RUDYH4x6rJhXFVtAMS1awHEzMpo44bye+J59XUAPGaRzumpmciNGSHH9N92PFOMlA1CBL6MtN4QQOXDAJ7uSv4CANCfMuiCm3NDIJPRqHpPbA7Ay35wx7EqpkIol/c9JhzG0/R3v8BY44+x7lxzJagM6hzo1zmiIAcEAPCaLf/xisrzu5gpIAAIr2hD6XeFocGO9/xh79pgHvudBEGYBU8P7lJbO9KVUzat30JhD8gXeao9XmlqRgbgnAURg1MkBsB8rAGo16m86h6K+/G2uc+hyGQ0kkn7orv+NR5ucX8FT3ciX3gbNGsiDYqFwcXyew0zLBjH/nBDFir49DNdl/xo78l6LowABrUP9pnBjqSPVMqsvvjYJJG5yOYLSVgvCjVuafoOqx/82rdRrDxAYfUfvyR6as4+e9XRyDl0B8f3bzgGiq9mpTqCoaELoB0UaYABf6gMZYI/HP/g175Hyv2f4HfDT/yK6A9gllJRQZglLe2vHDvkFdi3bqo9Xmhq+V3KlStWx8KvOuW+G05+DNc8nuKUSi/ABm8LuQyQwajHD+ZUNAImfGvZstWFRPUEy3Mp/i/57m1rQ15pk4qE+hTRXwKkEViwtXBDhYB9y7AWsA6qJZYgCj96bP9Xvnns3V88FZR2yGR0w13+BAx29Pgv+8GXkqsvXr0JZL4Opd5JSkW54oOt2/cnCJi0eQtFwp+GDv1ide6OG1/6P19c1vDPXv3cDICOv+8rN7DGVtUae78KmQtcqcxwXP28zoFLZZA2L1Ih8062dLda0fbEKzZ99XWjJwq1GEaNCgLqXA4Y41JfMFwYUVqZw00JpGnEd9m3rKKRI+GZl4GwYEsBF6wBcMymG6KkVQTMNXUpAOQQ8gDCI4MdHf7Tq3fNyTXs7O83SCbtS+/uu0ItaX2SPHOS2z1s3VAhOOBDGxqXHOOGCwFbCxWLJKmt5dFjf9j3ESSTtmFCWg1X8FHf7ou+bONXbydjvgngdJcfsW5oJADzwa48InLDI9aVStaNFJmi3tVmWeSJY+764gkN++z7BJuO27jhv/XytvfDudZgKB+4YskedAIhAgcBB0MjARfLjMBfQZHQ3cff2/e1qtciK0aAIMySwEQIXIcD2Oj9C3YVSBngPKI/ZUBp5wptr1MtsZO4WAkA0rUR/zEVdYDj6Fx9xfa+Pi/X3R289O6+K9SylvVcrjhUAgciDdo/rEMHfxEDAC5fDLhQtnpJ6yeO/WHfR6pGRcrUPWmuC+ql9319WXgJ3WWWtlzCzlo3UrREauyz0yQ3pAZIg4hcvhiQoqNDrZG7V991c9UIYFb1PfkTgwjHbdzw37ol9mZ/+64yGEwgM+n6IiICDBQRrGM7lA/0kpZ3HX9f39dAyep0qhr3pxCExQebmk8GpOrtq+swPFYMAMy/ZIL9uk1qDRBF5+bknzKDPT3+S7/f9zfqiLb1Nj8SwDkCHfxb0qG/lIFzyu7JB6qt5RMva9txQq47HSCTqNtpun1wg8l1pwMqD33IHLnsvOD3O0sAaaJpGmhExhVLlohejNa2u1/63RuPApFDqm4tO+nYX30tsvrevv/WLbE3B7uGfALC0yk7IiIikAl2Dfl6Scu7jr+372vtg30G2Yzcg4IwQ0xQYoCHDqXTMxH/xYJsPtMSf2bSpN1IsQTQnQAw+PQy18gYdG4A7ph7vnQ0PNXLxbKDZTXjIUdEBIbiYtlxxHzz2P6vLU0gUZdTaWd/ygy2rwte9sMNb1CtsSv87bt8aBWe8RuR0q5QClQ49GIVbfnwsf1fi2DtWqpLqIXI6V+XL/eOXPrmYNdwmUh5M1pI1VOFF+wcqpgjl7xrd8G+HcmkrbvnRRAW4nTAzX3epvM+OMzMG3RLFDxakVMLLScxAIQJ0UpxsVR6bsdd9wMAEomGGQDtgxtM+6pVmpT+nFraupqLJUcTdDikaSW8QHG5wnpJ66ucrbwzm0zazoFUzb0AK7evZRAxs/1HIgrDOTXr2kyljN2dD8yy1suIKyfXIR+Act3dQfvmvhgRXW13DVkCQrPdTAhk7NCIA6vrj9mUiea6eqWLpCDMvCeLrZmI165gXAyABXX6Hx8CUIqWv/S8OBpc6z/Y0eO/8Er/CAK93e3cw1DK1GTRK0WuULAqpK85vn/DMV0Dva6WCWoJzuhsMmlfmuv7c90SO93mC3babv/JfyTisu+I3J/WIdfCgEG7htxleknsKFfNs6Bpr6GDLQDlyhVn2uJrQqXtF471N5c7ThAws8ksNdrwaZFdOTEAZugC0kXd0JrQztHfil3ozRQNKaCmma+KSz4pL/QSH15LOk0O6K3ZvbBlyxZdfRNqp4jHILJUyxXMTpHSF3f299dSRGmwp8fvHEhpEF3pCmXQNPtm0CEWEjGIrYNS6k8AINcFaRAkCA3avxdz3F8MgHm4FvKrVo1WIeL1FPIAHCwYNMuYGgMO1n8jACSyW6lWeQtb1yI46tt9MTCfyYUKKUDXzmInzaVyQPHIq5/ln3VWKwJqFwbYjhURKArBMWol/nsvuG/BjIuq/zstzYEEYQ7FnyZ094oBIDQTDvmJehtQDdomkVGKlfsjAHh+xZra2UGUdmxKcRAu5HIF4BqvO64m1zkoU1P3P4CyDv2taY0d4YLAn3Gy5aE2HkUj4v4XhGY0GsQAkIXQfB9Q1feL03BdFpqnHBgjNSurpYMqNHC4TmAz9GCEoRTV9vQ/lgdQ9k1b/FXPmRf/GQiSByAIs9zCauf6ZwkBYH7PAmYskjAQYX5YP7X8nA37raY5Tpqm/0WJLIvwC0Kj95bDuv4XfmKAWbh5ocosSPEfdUPzTC3eyb78vjXfUhcd9Z2Ch/isWzM3+IciRcFUjclpiT/DqXDIC4ZGfkYF/z/BoBylA9nKBaFxFgMdLrYoHoB5xkA1OU7DXcNBMDoKeEGZNsHYkKOafjFignUA0w8AYGXX2tqtfk4p1pUCM22icAigGWa8H+qmZbbErmafebCnJwAAV6Gv2aGRHcoYr+YhBiLAceSpi68sy44sCI0VMVrErv9FEAJA20I6/Q9u21ZtduH4dq74SnGN3MY0Pis9sB7RfwJAFlu4Zh27BlfpP7zhAyNEdKeKeI5nMaVxAnedVZGQdsXKVl2p3ItMRlf77NeG9l335EfngtfW9U/MpBUYlKv+RUpmAghCg07/Iv4L3QBQFCwo139vb3WMbNj+ypX9X1Mk7CYqBZyRmjIC1RJVsPZeKhaerba/rd3s68H2dQEAWCp+w+0ZUURkwOCa3LSOQSGP2LmBGp+kubO/32QTGceg21Q8PGGr0RnG/cHMjrRmJvwHAHQOSEKuIMxdsgCL92SBJQHSgkr6I+LOgS71m/Mv2UXMn6JYWPFsXN50QAa9Y8DyXU9dfGV5Zdf22t4NSjE4pUIjvI2te5DCHgPsZi3+zEyeR65U2UM+voBUSmHLlpp99lx3twMRe96e9W6o8Dx5Rh0YBpiJ+MOxU7GoZ/OFZ6Ic9IOZct0S/xeEuYn7s4RPxBCcSlSBAhWPgkB927suHenkfgOihq2eXHe3RSajy0dEvmF37vm5CoUJM3Gnj/vy7NjXy9uMKxTv+vWF6z7b2d9vsjV0oe81MAA8dfGVZU/Rm9kPCMYQeApGwKEy/gmWIiHlSuUNT7++5zdYu5aQTteyo57r7O83Pzvvg8PMuMUsb9MMVGYl/gyGUY6YS47t32/tvixfy66LgiDMNOlPDICFlAOg6hRaADF2gojzgz+nhn8rAH845R0jitxbKGQUFBgzjKkzO6vjEc+NFJ4FcFUik9G5gYH6tKSltEtwRv+8q2cHfLdORUMKiviQiXV0yM9eUa1xY0dKj/7qwvddh/5+g2TS1sXoYlb5pdGbgx177jFLW8PMzp/pbsLMgVnWZmyx/O9Pd17yw2rOQlraAAuCNPsRA2DWdFW/k9N0E2kN8MEn9NmqtiPnzdn3Gx0f++sL//CLIF/4kF7SqhEyih0H07kL2HGgYzHNgX0uyBcvfKa756fZxBau8Ql6P7KUtAlk1K9e13OHv2fk3Soe01CKAbZTvmmZmR0HZklriCvBTnaVS5BKKdTLcKnuEPyHU94x8sutmy+2I8V7zNJWD8z+NF/GMrNvlrd5wZ7hb/6y8/fvbu/r85BIivgLgiT9iQFQSxzhDxNlblMtFlMD3f4Tn0qr8eJnX9vzGfvCnqtJ66f18jZTFVK24MkEdfTfCVYviRsO/GeDfKH7uTde9hT6U6YRJ9EsJW375j7vN69731fd0PDfq0hIkefpajiALRhurMEBjRd9ZgtmR8aQWRI3zg/u5uHyG3594WUP1cH1f1D+BVIphZ4N/tIt7mI3UrrHLG/zqg59dgwEEyY1jv/ckbA2y1o9O5zPPHXuur8AgMF1PQFIdiFBaMakPxIDYB5/MUeheoh/8yzstEN/yjxz0Xtvtnn/fJsv/he00SoW1aotrkdd627fH2bVGtcUCWsVj2lU/E9Uni+c+twbL3sKmYxGA5PQBjt6fGQy+levveSfgqGRNc4PHlZtcaViUU2RkAKzI+ZqeIDZkWdIt8a1ikcVa7XdFkqf+uWZ77ro6YveuxmZjK6H6/8g0mmHVEoNrusJlmxxF9tS+a8oHKpQLKJMa8xAUTUfY9znhtZkxj634/uCcvDHT9297S/ADPQCIv6CIEl/kE6AqHsrYKplt7xmoTsdoD9lnu1+9zYAf/aSH2xY62zwOhOPXwil3kJhj+AYUAS2Fuz4Tleu3Ovy5Tufe33PEwCAVEo1REAxcSgj133pT476dl93y5GxVwQ7XriSleowLbETuTIaZg955PKFPzBwnwqHNgS+/+RvOnt+B04p9FZfp2GfOZ126K2OCQbwjeO+d9vDamn0dLb053DuYhWLRNm6arqoMeQKxd0usPc4Q//2y7P//tvjXocAGf8rCM2a9EdiAMiAn3lBdzoAMyGbVc++NrkFwBYA64/pv+MEY61GpQKEQlDs+Fdn/s3je5+XSin09jKI3JyGMjilfkc9BQA/BvB3x/Z/LUKR0KtsscwAYCIhCgrF539z3rt/N/a8zv6UmbO2uQQeu96/fGPyKQBPAfj34/pvO56NjmO4BPIMc4siV1K7nj7zb3+z97n7vBVyBBGEJk36o0V0g8oQkoVgQVRzEiw4pYC1BADPUfLJgx6XyWgkAGALg9IO6XRzhDKYCeilzgGoXPfflkaNgf3o7O83ua4uh95ezHnN/PjrnV1LnStWUK67+6mJHtrZ329y27czkkk3J54WQZCkP4n7L1YDYEHF/acipuP671cDzeP+UJMKUFVQOQeMGgOg6mdG9XP39iLX3R006/XOHXS9m/xzC8ICngcs4i8GQG1cOfN5RVDaAWMn/PS86ni4/8+WnofXe55dc0FY0EjEbdEZABqSOCAIgrBYTv9qFuJP0gdAmMpqELtAEARBwsRiACzKhcJSwSUIgrBAMv4hBoAgK0IQBAGLJu4vW70YANN0/UsyiSAIgiT9iQEg4i8IgiDMO/GX078YANNYDfsvKiaS9SMIgiBRXjEAFvZi4QmaC3BFrowgCEIzyZjE/cUAqGvJHxOsA4CjwCnVMrxN4gKCIAhzihPxFwOg/nF/AjSPlEBM714xsCKWGxvEIwiCIIjbXwyARZD0R5D+7oIgCAtZIkgMABF/MSgFQRAW1emfaHFs8pIDAKkhFQRBEPFffEqgZEUcIuNfEARBWFTiv5iKvJWsCPHpC4IgiPgvLvFfXAaAdPoTBEEQRPwXmQEg4i8IgiCnfxH//TCyXET8BUEQpNZfPACS9CcIgiCI618MAEn6EwRBECTpTwyABbVY5PQvCIKwWEVMZrouwhyAWom/80YIDAJ6JZIgCILQYIpbtlX34AdE/MUAaDBRZYJqEkFa5F8QBKHBbGVU9+BNLHuwGAANdP0zky23xI/J3AAbaSFdys/+RY+ZJxfxuSb/rM/No2spNIRjZDktSNxDxlObbvADkDedbX3qp38WA0DEf7+VQ2wtCGj1GD/Dka2sAFBL6+w/YHm6SS08NyUyKwBUalN2SaP/i2r5G68E4NcyqYhrk5hE9Uxu4um/BjUqUYgP/XZU//Wbn8r1muQNlgIYqXtymqvZd572/USoSVUUzfAJNMO9bezpljSDKBYMjQBEnoi/GACT3BBcy7oRgtHLqVbiRfUV/5oaALOeksUHfa6aGgBU65+jBpsi1VNAePqvQY1aO3z451N91+6UBIYa+d4HPognNLFoFu9JM/qAXP/vOqV9ZAbr2TmwYzn5iwEw2Q1Rhx/UD7gmS2UC8ec6nP65huI/89fiun02AsA1En+ukfhzDcSfa3D651mKP9ejwRY1eO3OUPy5nr8d8dy874T7Dtf/PQ97zXk26fwkjeHEAGhYsx+iGuSRTvvkP30nX3Od/Kkun61+J3+aB65/qpvrn+pZn01ocG04T+TznsM+IVzzVPTZuf6pCVz/c13vf7B30kgJpYh/8zQR4jlz+9f6cy94t/88j/vTPI/70xzexDSLBzVEGOcq7o+axP0bVvJH0kNhPmPr4s6pl6g2bdJfHV6PFuhsiGYR/7m96M0o/o27d6Ye95978UejxZ+aWfx5UXaKXZSdAEX85zbpD017+ud5YOHM86S/ZhB/WjjiX/+QY733ERF/MQAWsRUh4r8wxL+u8fIGbJa1En80VcZ/k4k/eI7et7bhUarZE5oh4Y4X9YwY6QTYSGGtswXezOKPphb/Gr4ONZn40/wp96u7p2SuxZ/mUPybrt6fmzLpDzJHQWiE+Dd1SYok/Yn4z4H4z9ekv5l+wMUr/jLhTwyAxRb3hyT9QZL+GndtqEmuXTMk/VHzJf3NhfhDMv7l9C8GgCT9Sdxfkv6aI29gcYr/3Gxg3NiTuCT9iQEgiPhL0t/CTvqjZk76o4VV7jcn7vSaPombwHEl4i8GgCT9LXLxhyT9zXPxR7PX+s91xn8N4v6zEX9qcD6TJP1BqgDmv/gvnKQ/SNKfiP9cLtk5bfO7MJL+MA+S/iThTzwA0uZ3Dm/a+ZD0Rwss6Y8k6W9Wrn9I0t+CSfoT178YAJL0N6ffu/ld/9Lmt0F5A5LxX3Pxl6Q/SfqDhAAk6U/i/pLxX4uTPy3kHv8LMONfkv5E/MUDIEl/Iv7NkvSH5uj70FQZ/zQXtpMk/S3WpD8RfzEAFl3Sn7T5laS/pk36a4Y8Dkn6k6S/ppszIAaAJP1Jm9+G/yCS9NdcA37mss0vLaKkP5Kkv9oaG5AcABH/yffGgMcWOu1b87T//5zkXXnawzC4xu4zntHV4gndalzD34Jr8Do8g+s8+evU4rMcTmSpbp9j5s/nvZ9t0teg+l/L/Z/Lh71ejb12XOfv27gEV56hF5FnKP48w72LJ349U2vXP0kSoIj/oVaiao2ZvWq/yJP+anbKbcZOfzR3cf+5S/rjeZ/x35iTvzvokbP9vlMWxwNO/gSehmlUr7h//U7/h3L9B8NFgLmm4s+LxAqQKoBp7YvMpDWxcwU3lH8PoEpMjkipaaiNndZb6oUReGj495zrD6andK1t0y95jfm5ezXmc9uaX2vb7Nd89IPqGX57XdNUQGZYF4OiDUpRlK3jUYdVDQ554gGQ0/8k646ZK795bc83xCISBEGYWzoeuuV2EKLjw0Ozymkg6QMg4n9oI4CW9N+0dA9259G6ijC8bd6knHbKfiEIwjwn37qKWoa3cTnc1hbAUTWffXa7+2IT/0VnANSs3I+AELwA3ekAzASieWMA5GTvEAQB8z4cSyDiMx5cH+wLtu1LWhWPP6QMsN61/oIgCML83udrkzQgBkBzGopyTwiCIIj4i/gvTg+AnP4FQRBkj5e9fZEZAKpObX5XyD0nCIIwb8V/MSb9LSoDQE7+giAIgmzrMgtgzgd8CIIgCE2yrctmLgaAWI2CIAgi/mIACLMc7ysIgiDISU4MABF/QRAEoXm2ddnMxQAQ8RcEQZBDvxgAgiAIgiBWwAQPtxADQE7/giAIwiJx/ZN4AET8BUEQhMXYHpixGBrJiwEg4i8IgiAlf/uJv3gARPwx2XghGTEkCIIg9f5iAAiCIAjCAkj6G3e4Y2bAsRgAcvoXBEEQFnTS337iD/IMsaOwGAAi/uL6FwRBWBziz8oYZYuV32vPPAUGrcEWFgNATv6CIAjCgsv4H6f/BKfChlyh9NsHzrjqyRRSlKa0W4jXzIj4TwU5+QtCPUlkMvr5FVsIAHJdvRZEE992BCQyGXXAY+UGFfEHU81Oc0xGEUg9DmbaiuSCPSMaWToi/oLQ+NuKqXOgV+e6ei0AZInGtVxLH9I6zyaT+z+WQQBTAlnKUtLKxZWT/8xL/pjJaHDFDiutPgkAa7CGxQBYtHF/QRBqQiqlEr1rKdu7hUHkckAwJvZrN95+kYqFjqRyxbLld1PIO8ZVKkwg2s81GwkpLlUyTNhi2mLGbh++9wm68jmAODu6fyeyWYUEIMaAWAHTrfdnZufFIsbfPfzvD5117S8TfJROU9qKASDiLwjCDE/7iWxWZZNJmx093J+68dZVvKzl3GB3/n3K6BeB1BodCYE9A/YDwDnoSPjgm5YZqiX6MSgCaQPy9B9OefQrL3AQfMdW7H1PEt2ZHWvgPmZwiCEg4j+VZj/MTNqQLQd5sPlCilMKCzT5b3EZAJL0JwhzI/zIqiyRzQL25B996WgViZzl7xi5zDd6jVFq5ZjIu1LF+TuHHAjV/2Oa9Dblsu8AgJihPPMiOPciFQmvJeVff8qjG55wleBOF7h7nzzvsjuzaTEEhKl1+mOw8+IRHewZ+beHzn7/L17KGb3Q14wR8ZfTvyDUU/jXPnz7S3QotI6tew87epGKhsCBRbBjKCCQGr0xFRGpqdyoNFq9RERgP2D2ibnsO2IoFQ2dqKPhEzXzB0/adPsDYPepx8+9/H+yaQCcUugFkF6YGd3CzPd2ZnY6GkGQL/44XNxzRWd/ymSx8A1GSQIU8RcE1DKb/0Dhh+N3k9YvdkUffnG4KvoEENGM9599rV6JABABCgS4YsUxmAFAx8Nnk1LfOemB2x4A06cfp0u/AwCd/SmT604H8mtJpGDcPzrTEjHlUvHTue50kMhkNGjhi4FZ0N9M4v6C0DA6+1Mm250M1uZuf4lu9XoA/D1p/WJXKsGOlCwRqTHRn00Y7jAbuSIQQAxbLFkwoKPhs1U0/O1TftR3IxX8W3LnXvZMYhG4d4Upuv6ZrWmJGn/XcGbZUu9bo2vDySyABXSeF/EXhHrdZCmFTELnutPB2o23X0SGN6po+CNc9l8c7M5bDiyTUnr0tF4/8d/7IB59LGki0rZUtv7OIV+FQ++35B486f6b35SlpAWzAqdkHsoiFn8wM3naIbDDKPnXfe+VV5bXILFo2r4qSRKdvvhLEqEgjBN/Sjsks/aEjbf+o7e85S7S6qX+jqGArdtP+Bsi/hPcywTSisgLdg5ZUurFoSOXfefk+2+5AUQOlHZiBCxS8QfAIBta0uL5I+W/f+DcDzzT2d9v0kSLJkfEiPgLgjAT2jf3eYPU46/9weeOU21tXyVSncGuYQsGTRTfb4j40+TPJaU0HLvKjiHW0fD7T9785bP8wvB7ttIHtkpewOLL6WLHVrdGTGXX8H9Ey0Pfqa6BbtuoslgkgOcHthy0YlduX8sAkE0mXb09EWIAzOD0L8ECARLvN7mOHn/txvXHKc/LqUj46GBoJCDAzJnVTVP6K0UAbKkSmLb4OcrFB0659/NduQvECFhMez8zW68tqoNC5fEHv7PrbQCA3l4G0nXb3lOcUgMDUDmiYG+vCkwhqXbLFq5X5cqCNQDGcgDdIReCuP4FYbr7amd/v851dwcn3HtLSkUj74XjFwe78z4p8upx70wn7j/V5xFggj35QEdDKygSH1hz7/qu3AVXihGwKOL+YGW0c4Ersu9fi3TadfanTI4oqOeJP11NOnWd/TctVS9fsqby/K6rKWSWcBAwjw6/UMbAWXebiZrt9665/IGxtteJTEbv3wJbDICGlvuJ+AsCgExG5bq7g7Ubb/uUWdb6oWDPCNhaR5q8yW6puRD/KT2NyNhixepoeIUXxcApYgQsirg/wIF3RKtX/sPuvofOvvbu9s3rvFxH2q9X+2sQuSxgz3rkhjMU0QcDwsmmUjlOxyNVf1Rkf7tZOX49EeG8x255UIXoc5Xdw09kz0k+Bd7bGZvFABDxFwQ0PObfvsWuvXf9p82y1uv9XUM+gTQpUs0m/jR1I0DbYtnqaHiFi2Dg5B/c2J3rfv8WZDIaSSkTXHBJf8zWxCKe/8Lwf5Ll69o3r/MGT9/g160nRjJpT+5PLW1ZufLdmujzAMB+AH/3iJ10kRIBzNCx8Fmk9f/z4i1D5225/Z0be3u/zcxMANVqAqZkv4r4C8Lhxb+vzxvs6PFP+MGyE0xby/XBrmFLIA80+R4yFxn/M3nfMSNAGb1CtUV/2L7p1hMTAJBJaPnlF9DJn5l1yGgOAt/AXv7gOdcU39R+lK1HUleCq+J/9v2fX9my7Ij7Tch83o4UbZAvWlcJHBHpsTLVg/4Amoi0K1ZsMFSw7AdtXtT7r/P/dPm/ERGnAAIziQEgnf4Eof5kEnqwp8df03/D8YiH/tdW/ICY1WHa9TZL0t+UjQBXKPs6HlnpQDdkk0nbvvp1ckBaONs+k1EBKzXiiv5b7mu/+vfgjE5T7ZPrxppMnX1/aqWKhQZ02KwJduZ9jAr+Xt2lwy7v6uOZubJz2Det0b88/7Gbvp4mcqneXqqOwRYDQFz/glDHOv9EIoETN37xVSoaHVAh7xguVTQU0Zx63aaZ9DeV9yRFnr87H1As9PqTN936hcGOHr99c58ni6D5T/6Hr/dn6x2xxLMjpa8+eM413+vEgEYdOkHuFf+7UitVbPmAjoReEwwXAxyYIEvTuAeIiEBeZdewb1rjf3n+j276+tbetdQ+2Dfrihsl4i/iLwiT0TkAlaWkdWxvMG3xo+1IySetqF73Tj2T/qb4/sYWykFoxZJrTrn/lusHO3r8zv5+mZnS9Hs7T7p6mNnqWNhUXtjzLRtq/VD75j4vh+76if/9n1+pVi4f0BHvNcFQITioJwbN7B4gkFfZOVzxlrX+5e8e+c3tgx09fsLNLkylRPxF/AVhslr/ldvX8gn33/IJHYv8kb9zOCBNXjOKfy3flwAV7BkJKOxdfeKmW0/s6uqSboHzdZ9nZhXytKv41ihaN9jRUxhs32ZrPuiHU2qv+MdCAyrivcYfLgakaiP+4/7d83fnfRUL//V5g1947Rqs4dQs1qZa+M4hEX9BmP6GltG57nTw0xc9d7Jua/2IK1UcHaZqaL4k/U3hucqVfehoeCUx1qeJXPvgKkkInI8WgdYWCgWu2LdsPHXnjs7+lEGt4/6plOocgDrjwfXHqKhXPfkPFwNVY/EfCwe4wJEK6bgL+HOzzWFYwAaAloQ/QZhh4xIg4dY8eVsLe+H/cIWSBTMWUtLfYRsFERl/d973WqPdp9y3/kPVUEBKQgHzaRk7DkJHthlXKPc9dPY1d7YPrtL16O+wJrHW5LrTgSb/k96yltf4Q8WKUmTqJT/ErIORsvVaIsec+6Mb16aR5sQMK1YWsAFg5fQvCJhJ3L9XJ7JZpfbget0SfbkrB1Svcr+5TPqbUmVA2XcUC1918kO3rV25fSsjJaGA+WHDsjVtMa/0h113tkX5H9o393mDHT1BPcpjt56QrJz14Oeu0rHw35RfGAqUotBB0lOL0/++eRfEgWUd9VaSs2eAwM+vWENiAEDq/QVhdjtndazvT4964RTdFv+IHRqxpGnRif/eUIDvOx0NrSR2t2WTWdv+ZgkFzAvxb4lqO1LaHC3s+eO7T762MNi+Lqi1S7izv98M9vT4Zz9849+EVyy9yZUDVhOFyWom/vsXBrhChcnRpQCQ64ITA0DEXxBm6frPuNV3f2YJe/R/XaFsgcnL/eZK/Bu5MYyGAgIdi3aesklCAfNB/clodtZacrg+150OOgd6da0652F8i18M4Iwff+YY0qo3GCk7OEZ9xZ/3fw4RMc3uNlQi/oIgAEACWYXeXorGW6/RscjxruLjUK5/LJykv8OhueKz8ryrT3/o1iNyXWmbklBAs9YBWBMPGztceusDZ171g8RoMitqHvdHNe5f1J/1lsZXu1LF0YH3Sj3Fv0YoEX9BEJBJ6GzvFl574fKzTDz2D3Z4JCBFeu7uHW5o0t+hHqwI5Mo+q2hohQWuA1I00CWHpyZs9ue85a0m2D3y3YfPvfZb7Zv7vGwdmv109qfM1hPSlbMevOEduiX2dn/ncKCmWeuPJhB/8QAIggAAaF+9TCGddtDqw3DWcR0NZ0JzZfwf6sFj5eKkSAfDhUC3xa47adMRXbnudJDIZCQfoFnE3zrWkbAKdo981zctf5zIZPRo3L/mYbJcF9xZm244Wnk6BWYFnt7Jf9pJf3U0uJWc/gUBi77hz2DHBn9tbv1VOha5OCiUeLKa/wWe9HfAg/mgzd9VAqc0fRicUkjI2mmOvZytCofIVQJ/V7n8tsGOHj+b2MI1j/sDWJPt9dALKIPPe0tjq12xHOzn+qeGa4+CGAAi/oIw0xPNyu1r+fSHbj2CwqHrELhJh4zMx6Q/msWDaaKpgYUSm2i4+7RNS7qylLTiBZhbTFBiECkogIMg8bNzCyMJzmjUYcgPOKW2JtOVzre0raaQSfq78vagNr9oZNyfmYARMQAEQZhxzX82mbQln//exKNH2XLZEjXXvkBz8p58qH9UUN6HpSdAsywQ1RLsHkk+dPa130Z2LdUj7g8GdQ5AdT55W4sP+r+klIY7YGk2Mu7PzCoWJmbcPjazQwwAOf0LwrRO/10DcCfe98VlbLwrbalkoRSJ658P8TDSwUjRUizcfdJFS7qySfECzDGtLrDZh8+/LtvZnzJI1kH8AXQipXPd6aCcL7/NW9ra7ooVWz/XPx/2xlUho4J86fdKm81gUJf0ATj8RRfxFwTsV/aX7k0zE1+uY+FVrlQBTbAnLC7XP0+xSyCU0ubDVS+s0PiNvbpgPL/w/MNnvf/tYKZcd9rWrz8G0PnQ516sQ/p6VyhZEFG9D56TPYcJToU95Yr+L+497apfpJCimc4EUItlPhSh5sOnBWH+in+mOrr05Ae+dI5ui6aDfCEgpfRCqPeve4tgkA5GSlZHI92nbbq1O5tM2gSLF2Au2FvjXzUI6tI1qn2wx+QoHVSgb/aWxI63xQpP5/Rf07g/Va1lIjCDb0YqpbZiLUkOQAPd/hL4ExbKrWHZfoSt5clOsg2Z8FfDkj+axROmNyGWQQTlFH8EDEJWFtOCNJQ5owc7NvhnPfi5d3gt4T/zd+f9/RL/Giz+DLYmGjJBvrTZjOS/nVi7dVY5D0rEXxIIhEV4+k8m7dpNt5xD0dBFtlh2hIOb/szHCX+NEf9RL0ChHJiWaOdpD90iXgAsSPcxrcEWPumuz8dNKJQCw2MLPbed/ojJaIDsJ3Pd6QCJhBxmG6LZJDaAsJA2t5SCw0dJaw3mpkr6Y2bLzAF4ryozgwMwc6OT/g798R0RQ7OjjwBAFltk/jgWUoVMSqcp7VqX6XfpeHh1UCjtS/yrg/gf7gUZbE0sZILh4iNqz8j/joXxxAA4xI/AtRoKIuIvLBCXZjaRcCc+9KJTdUvsdTZftAee/ucs6Y+ZwcymNaq9Za2GPF2NeGpN3tJWQ54hduzmIunvUF4A3RLuPO3+Wy4EpZ14ARaKlyyhV27fyucN3nySioZuC4aLlkipOTms0r5ex6QUw9Ho6R8Szpa6QUGYfgY1+0EXKWXAc5B9P5H4O8fKaFLRMAX50n+7YuWrbG23YnqZDcqdrli5gwP7G7MkppjhgH1lT3MwHGjf89gRAM2KxQuwgHh69TKVTWats/Z65WlwtTk2zU3SH8DsrGmNmWCk/JjqOLUmp39gknafgtgAAhZk3X82m8WaTV9ZTjp4vyv77sByJpqDjH9mtiYW0Wzd761D4vFzLt94wEOeAXDvmk03LKeSud60xT7gCiW4wDpFpBoV95+4tJi0LZQD3RLtbH9wffcgXdmf4NpszsIc5sh0JP1zHrrxr0w8/OdBvmSJRr1kcyD+YGbyDJwf7Abxe3PUHaS4Nk2oxAMwBde/ICyYcb/JpIUtvUfFI6tcueLG1/035CRNB4u/joQ1HD9vR4KLHu/o2djZnzLtm/s8cEohlVLglGrf3OdtPeeanY+d/r7rXLF0LgPbTDyimNnNpHyXalkx5pjA0I7xUQDI9ooXYD4byUAWnU/e1qI89Y9gDrFzNJfjfZnZea1RbUuVr9136jUPd/b3m3SNWh2LB0DEX1gsp3+Mdv0Lq8tdsWxp3Om5MeJ/0HAdZyIhDebng/zI657ouuaJ9s3rvFxH2t/vcWlgEHCjm7N6jJKbTrj/ltcqre6mkHkxKgFNrzEL1/S7EkHbQjkwLbELTrv/xgsfPff94gXAfE38G9DZZDY4++Gz3hFaEn95Zc9IddTvHCT97W35GzJkC6XtiJibE5zRa3oHXA5S0i7iLwjTOf0TMeAu1dHw0a7s89j9PyfiDzgVMmDwC2PiPzaV8JDd3yhp2zf3eU+ee8VPbaH0VhOLGBC5xiT9HeLfHBOYDZP5KAAWL8D8dP3nuruDcx/6zFoTi9zq54tV8Z+rpD8ADmR1JKRc3v/b+0+46jfIAul07QYdiQEgAX9hETCWnObYJbniM9FoT7GG3FMTZvxbFQ2roFC+5Ymua55Yk0mF9nZ1OwyDHT1+++Y+71XnH73Z7hm5QbdE9WTVAYeb8FezbYFQ7QvQGj3/pPtvuRC9aZaKAMwv138COOcnd7RSOHobnCNYp+Ys7g+AHdtQW8wEhfLgjpb83e2b13nZGs86EANAbABhEZT+Ab289v7bz9GtsZe7su8AUnPW5tc5a5a2eMFQsf/J86/6x/bNm72tyXRlOu892L4uyCLhCq6QtiPF36mQwUF9Ag46+XNd9wNyjsBsNLmPgsBSETCP7pFsVmUpaTG0+6+9JfGuoFSphsjmSPzBzBTSYN/fDXZXbD0hXXlT+1E1DyktWAOAHStx/QsCkM1mR3ulu4+QVi3s3Gjoeg7a/DKzCodgi+UXwPYacEoNtn/HzmgYTDarfnbeB4eh1R+reFjt52pogNt/gs+kg0Ip0G3x89sfvL0b6GWZFDg/Tv/Pr1hBr9vct0SFzDX+cHFuxb/a+cp5LVEdjFS+et9p125q71vn1Srxb1EYAKRQEPEXJK6Z0Uhk3IkPfvEsFY++PhgpBkSk5iLjf2/sPxbRruivf/zcK3/UPrhKY6YbWzJpO/tT5rHTLxn0d4/crFujaqJQADVYTIjZwNl/ABFnE+IFwDxI/Mt1dwcFl79Dx8LHuVIZ+w37aUTS34FGsmcoKJR2cdnckuCMftO2o+qSULrwDIDta3n0mp8w5SYnIv7CAuX5FVsIROx8e54yyoPjWS13ml3cn5VnlN0zskMz9yU4owfb1wWz+X65rl4LgL1w+CNBvrhdhQxh3I1PNc74P+w+QqRtoRTotqh4AeYBKU6pXHd3cM7DX3ibjkXe7OdLAaladvzjaSX9jY77tTriKZTsX99//lW/eX7gdqpl4t/CNgC2jFrcTO9h60B0mHndIv4CFq5rM9fVa1ff3beEQt5VrlhxxKznJOlv7PQfjxLY3fzYBVduf3pwlxqb6z6brobtgxvMYEdPkdh9TrdEiFH1AjRa/Mf+31hFAJw/6gVIOFmMzXl/bM1upXM2frZVed7nwBweTfyj2qyNGYg/s/XaYiYYKT3youjQPZ39KZPrztWtnFQt4Ey+gmT7CVjspX8AYpHKJToWPporgSMianjSX9UmqJ7+d+d3FiuVL1dj/7M7/WNcQiA4RRxzd/i78ttVKKTGerfOSXvg0VwA1RY/v33j+u69oRih6e6PbDJryeh36Fj4pa5Y9kmRmivxB4OVp+EqwR7i4JrsCelKVxdcrUbaLC4DgKf23cQGELBgS/8SDkTs4N7BFR/EM7/fp9zjnyYbysVOxyMEpW78efe1L1Rj/8S1mm3QPrhK//jUq3eTps/pWJgAdg0T/wm8iOSYiJ1h4o+JF6BJc2OywPmbbzxNtcZuCPKlAOrQNf9Up1r/cfpvTUtUc6Gy4d6OD97X2Z8y9Uj8kzJAcf0Li2GDA3Dig188y7S2HM2Vip2Fvs3Y7U97TzZG+Xvyu0zJ9CFVu9P/fl6AVEpxMbjD7vUCMM9ZzTChWhGwJHJ++wM3dYkXAE2XG5NNJm1g3YeVpjCPRY0a3OZ3P/GPR8jfM/LAi6LDH23nPm+qfTHEAGi4+IsxLzT56T+xhUHELrAfU4paYRkgzDS0PTO3/77NzemWKBHRDYPdPS+0v7mGp/9xXoDO3i714+6rdzPoczoe3psL0Ii4/4QCwEzEpJ3jlHgBmmvUb647HZzzwA1/buLRNwWFkiVAN0z8J/pHJuiIp8kGn8iekK6sxj0NWStKxB8zzuoUBDTtQJNeftXGO1qV0Se7Upnrd6/zoW8oZlae1v7O4T+EFL4MZqr16X+MHLosmEmHQ18Jdo1sV15ITdVar5347/cgbQulwLTFz+94eH2neAGaIjRMWSRw1qYboips1hO7MFum2kSDZyb+zOy8eFhXdub/fYSW3t3ZnzJZyloxAJqyxZ8YAAKavK65V4OIQ7bwXt0SXeX8wGIGyX80iwfR+JKmlpgjwnceOfPyHe2DG0zNT//jvQAY0IMdPXtIUbUiYArTAmvbJIgP7gsAaOe7tHgBmqHjX0YhmbRK8f9RUe/ooOQHh6r5p3oM+Dkw8c8Y2HKloIb4isGOHn808Q9iAKD2fvrZn/4lc0BobjM31522r37o1iMoZK5wIyUmnn7b31nH/ffdhdqVKoocZQBg8Olldd3cxrwABks3BLuGtquQMYfyAtQq6W9yERjrCxA7r2OTeAHm2vWfTSbtOQ997hTTFn2TLZQt0eQTceud9Dd6+mcd9hScfWuu+9oX0IDEv8ViALSI619YdKf//pRGKkXaqdepttgxzg8C0PTu81qJP4OtaY2SLZb7Hzvvsns6+1MGyTqPyB3tC/DwWX8zREp/TseimIoXoD7iP2YEjXoBeNQLsEW6A2IOXP/Pr1hDr3/s83EKhT8DIDTaEntOkv7Gav5DS2MqKBQfoj35uzv7UwYNSPxb2AbA2rU0ukH9C2kFZmIRf2GxkOvqtUinHflBEhUfhDqIP3iKzyVyvgWU+hiIODfWpbPOVPsCjHoBdg8/r0JGAeRqFfef9v5AY7kAo16AXukO2PiwWErnutPBSJn+LnRE6xtsvugTkW5Ij/9JLEalFVzJzzvH1+e600Gj7o+FbQCs2DJ6udUjoOr2V2vxJ7mfBDSnixNEo1P/4m+xxbIFSNd9wM9Ez2VmZYxypcruyBFLHgcz4W1vs40JguzzAjjQF3RrTLFztp4Z/4efFFj1AgDcK16Aucn6P/vhL5xq2mKfrrywpwJSpu5Jf5OXiFZH/S5r0a5cue3+0z8w0L65z6u7d2xRTQNkF6/HyV/EX0DT1javoarY2AtUyDPs2NV8wRKmWNVEVsVCFoQbH37FXw+3D24w4MZp3mBHj9/ZnzImFL7Z37nne6Y1ZhgIap/0N8XnjXUHbI1WKwJ6e7mzP2Vk1dbf9b8msYbbN6diypjPEBBn6/RkJbFUZ7c/ALBlG1oaM5UdQw9WKurj7Zv7vMGOnmAuLs8CngZIjmos2CL+QjOT604H7Zv7lpA2l9h8gSdzcdYy7j9ZbhMxjB0u6KBS+gqIuF6lf4cOh6zlwY4eHw4f4yAgAhQ1Ku4/wfUZ8wLwaEVArksaiqABrv80pV04aOkJH9l6UTBcqIHrn2d+QzFYGU2uHIwoS9c/eM41xdHEWBYDoD5VyjV5poi/0OTJfwacUkHFf5NZGn+J84Ngqvc3zW7Az0R3jlUtUQfL97aF9Z4EZ3TdSv8O+ZlHxwWfe9Ujrlj+rmmJ0pgXoNHiP35GgG6NnV+tCBAvQL1P/yu3b+VEJqMp7F1d2T1iQUrPVcb/KNZrjSg7Ul4/cMY1ubly/UsrYBF/YSGd/gfgQGlnrfsTV/EPO8+8Pkl/e+NvipgVOf7Yg+dcU8zOaVJkNbFKe17K+cH0ooJUh6Rgx0QExaMVAV1dveIFqBMppCibzNrfvuzZ/6sj3ku44mOiihhqRNx/9PRPRqvK7kIlCMfXJzKzH4ctBkAT+QwEAXPV9z+ddiduuvU03RL7E1coW+Dwtf81Tfrb1/gn0C1RFQwV7n7s/CvurZ7+5+6EA0raBGf05jMufcQVy9/TLVE1JS/AbJP+Jvv7MS9AS/SC0x+67YI0IF6Auqh/SqUp7c576IY36ljoT22xMqV7ol7iP/pPbOIhpcB//sAplzyfHU1YFQOgLjruePrDQCTpT5h/rEkkeLTpzsdJkeHquq/N0p2G+I+ecFmFPLCie0DETw/uUs1j2nsp9gMQmGbf5ncWhpVjIkXkAv/jIOKVc1D+teD1vxc4a9MNUfbUv4FZY5J2v41I+htL/TPxsPJ3j3w713Ht/yCT0XPp+l/4BoDSYfIMYeZjwUX8hXlBmsgd2/+1CJQ6y5bKPJXa/xon/Y1PcPL8XcPbteOvgUFz7eIEgOyoF+Cxcy99JCiU7tItMc3gYNZtfmd4XYlIByNFq1ujF3RsWt+ZTSSdeAFqRydXu+lpZXu81tgRruz7s3P986xaYhODSWuyxfKQbVn212AmNElL6IVnAAzAgZm0xmN2pLRNhbwpDgSRuL8wH5P/+g0AtJn8e3VbbCkH9rDJf7VO+hun/4FujTEx/9/HLrhye/tgn5lrF+eB38qEQh/jwDqabDYC1Vf894usKKJqLgDEC1AjEpzROUoHZ22+8TTdFk/7wwUHPrjdbyOS/vb+tXOBtzyu2OHWTa/++3xd52EsegMgnXZALz11Xs8vuVT5OYWNwmELkEX8BczT0r/uoLP/thZWdK0rlDUdpvFPzXr8T3iyhXJln5j4TgAYbF/WNAluo14AtfmMSx+xhdJdOh7VB+UCzCLpj6bdq4h0kC9Z01rNBRAvQG0MvOexgjp/9bWIVvgUGdXG1uLAQVgNS/qrPjswS+NeZfvwJjU89JlENquawSu2wEMAawnMBONuAJHjQ1pbIv7CPD79p1JqZwRv9Za2HO0qvn+oe7ouGf/jNjrdEtM2X7zv8XOu/F4iM8fJf4coDdMeUmyt3e+wT7NL+pvxh1FEcP7HxQswe9o395kcdQf+8zsuCR255A3B7hGfJin7a0jSH4NJETlrRxThw7nudB6JuU/8W/gGACUt0Eu/+sEf7nTDpQd1NGIAtpLxLywkurq6HNJph4AvZt/W5n6ebtLfvtM/Oet8pfEPYBASzXe9spS0iWxGbT7jqkfcSOn7umXUC1DvpL9JnqOItB0pWtUS7Tzr4fWd2WS1b4GsbMyoEmawo8c/b3B9u26NfMzfMeSDyMxF0h/t86QFpjWmgj2FGwdOq9b8Z5vMKF7AZYBrCem0s85+EkQOUE6S/oSFtOGlidzJG287RcXDf2YLJXuozn/1ivuP9f0nrTWPlIZf0bbzARCQRXPOvX9+yxYCM6lRL8BkLWHr5fo/qC4MxETE1ro0AKzsEi/ATBwpSABv/Pn6MHPwKWXMEudbNTvX/2x/eHJktPGHRsrlttj6FKeayvW/8A0ASlpkMvqZC3//PZcvDKqWqAcePxBEXP/CvB94oSzwj6S05kOUvNbT9b/X/R+PgMFfxNa1tn1z0yX/7SWXTgeJbHavF8C0RDWYbSNd/+NliQBjR4pOxaOdpz902wVjFQuyuKdO+2CfySLphvb4V4ZWLL0o2J33Se3v+qfG1vsDzFDhECniv3hkzeU70tmt1Iz3xMJuBLRlC4PSjID+niuVXWQ8Ve0NIEa2ML/N22wyaY95IBsmcJcrlpmY9Vy4/qtT/7Tn7xnZHajgpmwyaQfbe4JmvnjjvQCw1k5WEFAX1z9NeIBlUsTO+R/H4XoUCAddvMHvbLMJsCKl3u/vGnETuf7RSNc/2Op4WAXDxe/mTr32W+CUQjJrm/HyLWwDIJ12yGTU06/vecKVKrdR2APo4FwAueOE+ZbsBADL+fn36CUtEedcgElUrC71/gd0/lPxqCPg1q3nXLOzfXOfB2puCzuXTgcpgDafcdUjdrh4t26Jama2DXH9T/xaxuaLzsSjnac/dPv54gWYBtmEQjrtnnvkpn/V0fCLXODzzF3/s6v3HzOIYQxcyd+5hFrfilSqqTV24bcCTiYt+vq8X134vo/ZQulh1Ro340MBIv7CvDvxtPcEJ931r3Fmvs6VyoaYzVyIP5iZlDI2P1KJtkVuBoDB7/TY+XAZtyJb9QKE6GPsXACluKoA9RP/QzkamKpeAOZKGixegKmtv4RGIuPOefCGbq8l/Je2UHYHlsE2tN6/+qGC0PIW7Zy97X86egrtb16lQWknBsBcsm2bBacUW9fDJX8nhUIElrtMmJ/xToDBrfm/MEtbj652OSNqaNLfvvOS05EwscVgePtzQylmhfT8GHGbpaTd6wXIl+428YjhCSuF6i/+43MBdCzadfqjVS8AxAtwKOOT0LuG2wc3GPLov5xv3YHtXhpZ7z9qD1vdEvMqO4bvtzH7heqwn+YOhy0OAyCddhiA+vVr3/djV6zcTiGPQLByFwnzjdXtyxyIGNZeNFGTk0Yk/Y1rZlPtnKfVP+S608HAQO+82k+2ZqteAAL1srPBqEpzPZP+DvOLMCliVCofBzN1DmyRM8okJLJZhXTahYKhr+loeImr+AzaN+yn4Ul/AEgRwFzicvDhTa/54PDzK7ZQs4fDFtcCy6RCSKYrq3Nf2qRb42e73XkLNY1GEcxMxhDbYE+Y7TFbuy/Lg5maNeNZWIAuT8raU+770skcUT9ylYABVvWe8DfZcBMVjWibL97z+PlXvh6cUs3s6sQhpsYhnXan3X/jnWZZ6/8XDBUCAkw9k/4OJULM7Ew8rGzBdT5y5mX3gpu0odKc7uPVQTrnPXpDp4pGB+xIyR14mKUGiz/AvlnSYoKdw733nvGBj7dv7vMGO3r8Zr+Ui2sc8BYEKU4pVeFLuejvpHBoBhMDBWGOTj1IoH1znxfAfpxCBgznGprxv58tDKciIYDUt8FM7YOr5qW7OrF2KyGVUkSml60bJkU0kReAGjWCnMiBFCOofByplBIvwMGu/wSA9l9+Zgk7+m+uBO7AX6uhzX7GKmE8Y4Lhwgh55hZwSs2XXJjFZQCk025gAOqp11/yI66Ub1NtcQOWUIAwPza+LCWtb6IhEF/kCiUihm5o0t/+pX/G353fHXiUBREPdjR3rHMyssmsRTrtBs+54mE3XHhBeVofaABQXV3/fHAuwHCRdWuk8+yLl56X604HyEguAPbmwGww2WTShp7X7/WWxJY437fjJ/01otkPHfgDKnKkNdh3786devXuRHYrzZdcGIVFNzwlHbRv7vN+2X1Jyu3Yfbtqixs4DuTWEpqZTgxopFLKDQ/9rWmLG+d4v9K/RiT9jW/8o+IRwLnbt5552e9HJxLyfJ4gh1RKQdMGFQkB40oCqc5x/wnFRZEjpThw/HFwSnWuEC8AAGC03e85gzd2mJbwB4ORkh0/6a/RSX+jr2J1JKSCkdI9951x7TdTnFLZJq35FwNglMHvVKsCFKteV65sp2jIMLOTxAmhKSFCDl12zVoYwH2QK74hZtXopL8x3z9pbVyhNBxQ9EYAyA0MuPl8ebNIOqTTzg/7twbD5W0UMgaY+QluunH/A38LAkyQL7KORzo7Hlh+fq47HSAlMwLWYItu39znwfGndTS8zPl2b83/XCT9AXDa09qV/bz/YvXHiUxGp5GeV4bwojQAqiODgZ93r9thS/7rwdhBIeOmctPPYLUJwuz45jc1iFivXvUqFfZe5CqBG3N7Ni7pb++TrI6EiAP75NZz3rNzLIlufhtY4ARn9OOnfGDEBcF6HY/QxO2B6y/+4z8TKcWkbG8ik9GdXVjsza+8rcl0xQuGPxA+ovV1lZ3DPqmZdPyrmfhXX8xoZwO/58GXXlNck9jCzZ71LwbA3l8z7do3bzC/fu37foxS+Va9pNXs3w1MxF9oDsZcwK7kp1Uk7LFjN62FWCvxH40jEJEjixQAJNauXRB3RBZJBwaV28wX7XDxt8ozpn4JwoevVyeQDvIlNrFo16+O+d3izgVgVoMdPf7ZD3/+dC/mXVvZU7BEZMbs2oYn/VU/kzUtEe1GyrmNp3/w31OcUul5WAWzeA0AAIMdPX775j7vqQsvSdvtu7+oW2IeT5IPIOIvzNXml+tOBydvuuUMHTJ/bPMFR1SNezYs6W/8phePGjs88sBj519xD1IplU0ukBI1AieQUVtPuCzPvn+LjkcIQNCApL9DfiYQMZFLt2/u8xZrLsCaLb2mk1NGkfqMjkWWsV/tf0GzMLpmkfQ3qpzKMlABqd5EJqG3ZuenIbyoDQAAGGxfFyCVUv6I+6grlXeqaMiwYxbxF9AcWc8aALFVf65bogSuilIjk/72dqvVikEokKdTSKXUQjn97+cFSEGFl7V9KRgubaOQp6fqBai5+Ff/XQf5gvOOaO1UfuEjYwnMi871f0K64j+y5DpveeuF5Z35gBTpmje+mY74s/PDK9pC/tDIx+/teP99SCQwXw1hkTWg2lhiyxY+vvtFJ3ModDeYl6AS6L1WJh3cCCjkpBGQ0IB2p1UjIFouVh5XYe84rgSOaAqGO3Gtb3inQka5sr/tx+decfRCveSd/SmT604H7Ztuvs5b1vJZf3c+oMNMl6tZ3H/ipzAZBRe4PeEQvfKoU4/amUXCLYo9J5PRqcQW/uHmtg72zPcAbmPfKRCI5iruz2x1LKydH2zyWsoXLxtcnc8m5u/v0TgPAKcUMhl92D+Ym4FB7atW6ae6LvkRl4ObzdJWw0TSH0CY+9I/Ii6Vg3d5y1uPcxU/mJL4o7biT2MbXyQMIvVv4JRKLNB4dK6r1yKVUlrRl4N88bcqNDZCfA7EfzQZwAXWectallZK9pIsJW374IaFXxGQSikkEm5gy4qYI3UPabXMVezcin+1RNOSVoEr2w/cc9z1e0YXAc/fyFe9Xz+TUXun8k31NJ4AMAdWbvvmPm+wfZs9Lvfi21Us+l43UrT7uZvEAyA0sPQPH/uYOumclqiLRX6qIt4xXAkcYWanf5pdeJyhNRPR7nJQfMXWc67ZuZDX/ZgX4NT7b/pgeHnrZ/w9IxO2B667+O/nBdBMmvZwyf//Hjrr6oeRTTTtjPla7cWr25e55zY/9yWvJfKeIF+0RKRrKv7TdP0zsx950VKvvG3nR+8987pPtvet8wZ7NvjzO/Wlnif+cVmRL/vBHa/yjoy8KNhZ+DOKhk7hQtlBgUgrgrXDFNY3BCUuPdO97sEDez431Ors7eVX/fdXW+wy+yyFvSWuWGJSisQAENDg5D8QuRPuvfkkFQ4/xoHluRH/6sbnLW3x/F1Dn/7xeVd9OJHJ6AWT/DfppLlean/zqlZFwZMAH8WVQB00Z54aIP7jXM/e0rgOhkbui4zsvjDfuormQ6/5GdGfMuhOB2c/9PkLwke05Sq7RhwR1EyT/moR92cHp2MeceAehOOLV/5i03A2kZn3oZj6hAD6+82Y+L9s01eTL7/vq/eAgkecRU7FwlcSUadqiXTreKRLRUKdKhZ9E3nhfm3UA8c//C8/PO7hf/3Q8feuX4Fk0nb295uGzcdOpx2yWfWzP352hK16LZzbRSHPyrwAoeGn0IFedfzP14dJm5SKhoCpNKapg/iPjf1j6xxAA4tiVj0Rd3ZBDXb07HFl/1ZvaYtm7N8yvJHiTwBIkfb3jFgdi5xfall63mBHj4/+BdgciDM61QV3zuCNHToS/i9/pBQQZr7mapL0B4AULBnlXL50be7Uq3cDCSyEgx/V/PWqJ2J3bP+XulQ0+nlFqgNguFIFbAO714imAwcqVDcaFY0oGA0E9llXLN32dFfP58ZP7WqQJ8AgnQ5W//CWc71lyzYGQ6MuQPEACI06gRLxmk03LNfWe4GUJlSHnVOjkv5o3NQ/HYvqIF/c9OPzrjh30ax3ZkI2q9pX72pR5P8vaX2uK1YcCKphrv/9jLBRD6RnmJl303b/FQ++4ZpdQIrm5RTGiS8XdQ6kdK47HZy7+cacWRK/wN+Vt6Rq7PqfZtzfMQeRlUtN+fe7PnzfGR/49HyZ9NdYDwAzgRno7cXqjXfcpkOh7yitOly+ELhC0cJaJlIaIA0iTaDqf4/9IdIAlCsWrd0zbDmwL6Fw6LOrN371u8d97/aXIJ12DSuBSVfLbZ7u3vGA3TV0h1nWZhgsSYFCg07/AxoANEffatrijomDQ29b9RJ/gIkYWjkYTlcnsWXVIsnB4EQCGOzo2ePy5feTUT40OZryzAOu3UmL9nliXCWAjoaW8zLz6U706wQWTilm++A6kxuAO/fRG76kY+EL/N0jwVyLPzNbEw0rf0/+AeWZLyGT0YPt6xbM7BhVw3IlAhFe/rpjvq7bWi7lStDihgsWisyowNOEJ/+DfwZNSmmu+M6VK4Fujb6RW8K54753+0sGO3r8zga5vQY7egJk19JTF176Hrtr6Cs6GjnIDSgI9XDK5boGXPvmvhjYfpT9QBMf6j7lGnf62w+rwyHj78nf++Ozrvw+QMguotn0WUpa9KfMYOc1D9vh4vdNPGJAU9kDauf6P/DJpEgFw0XrHRFfVxx8/PwsJW2C539FRuLJVGiwY4N/9pvaPhY6ctl7g0I5IIKpedLfdOwCZialSIWMCnaX3p879erdiQSwkDxgqiY7FlUvystzX/2Gbom/PdixuwJmHj3V73eVp1H+oggwwY49Phn9ciyNbVz9w9uvy3WngwYZAYxEwoFTyne/u8KVyrtVNGxmOoJdEKaWgf5DA0q7oGz/1lvS8hJbKttD3qc1Fv/9Tv/OORUNgZX6ZzBT50Bq0bWiTWxfy2AmUvxJgCt8WP8/19wLM8G/qWC4GCitv3n61luPyCLheB7nZnT2p0z2hHTlrE2fPc2Evcv9XcMBMes57fQHgLWyOupZf8/Ie+4///oHO/tTZqEZwKoWZX7H//y7oZff95Vv6Lbo2+2uPT5AoQMzZqcl/vtZvMrjYtlxYF+qj1j62Zf94LZ/yHWng07uN41wAyK7lp7Zvta3ji5iyy/AMxYgsQKEupBv/Xk1jwbuQq4a0dzwpL/R0jPlGW3zpR2GaQBEnOvqXXQesGq1Qy89cubVDwRDhR96LRHDmGx8eI3Ff9KMNCJXCUhHvBUq7z4BIu6Yp70B2vvWebnudHD2w1841WuJ3Q3CclcONIhoLpP+mBF48Yjx86Uf3tdx7R0Jzuhcd3rBjY1Xs+zUpJBMWvvcM2/VS1vfbncNVUDKq7k/kkjBD1ywa8gPrTzi4y/v/+K7c9QdrMmkQmhEk6DVu9Svunoe4WLps/rIJZqZF9xCEJqATEIPdvT4J+ZuOwFa/ZkdLoAwSRe6Gnsh6eDSc6tbY4rL/h0/OveyZxKZhF68ya69nOKUCnz1DlsqP6tCHvEsxgXPSvz32QA6GCr4oRVt7z3jwRv/cbCjx0882YD9sMbiP9izwT/74S+caqKRuwEstyXfkpqO+vOs4v6TeP6dDhvtipXfQ4f+prM/ZbJILMhD36xDAMffuT4Mra93+aIFQU928Wm207MIipi0HS5Y7ZmPrf72zS/dmkxXGtE9cGxo0GkXrrgp+O32fyOtjxhBXIwAAbWd+ncJHX/n+jAZ/IOKhZl5snhT/ZL+xnZAFTLKFkp/CLS7CZxS2S1reBE3ZeKtWEuPXXDl9qDibjFtcU0HTQ6tQ9Lf4T+X9nflAxMNX3L6xs+dkj0hXZkvHRo7+/vNPvEP3Q3wEbZcmWazn5nX+h+65I8sGU1BqfKxjaddub2rCwu29bKaTb0mkklb8aJvVfHoCVyscDWjv9YJSbxfXgCXK0Se9xJaFh9YfffNL0ViC4NTqhFDg9ZgCz/V9b53sHUZoworRLIE1LAJVa67O4iEeCmIEjZfpGrVTEOT/rCv77+nXMn/xZNnX/UH9AINK8FFsw4KSrhEJqN93/tqsCf/sIqEPWZ29U76O9z+zZVAA7zca4ndfeaD69uBLJrdCOjs7ze57u7g7Ie/cKqJRe4G6AhbrLjpd/qrvfg75iB0RKvn50sf3HjmdV/p5JRJ08Jd+2rma3ULH7W5L6Y8XI9KwKAJklCohuK/z/Wl7EjRqoj3cpjwwPG/ONNLYC3VvUEJEafH/tPSR2kkmPd9oIUm2hS7qvciRfSbVSwC5gmyzYnrmvS3r/QPAJEjbT4FZkr0rpWhYUSMBPDE+Zfs4kLlUhgVVO/92tT6z2Ti6GiDILLFSqAi3pFk+PZsMmufXn2PataGTXvF//5R8Wd3hC1VLClSc5rxP+r6N5GQ8vcUHtZGb+js7zc5LOy8FzXDVo0alHbhPfZ1uiV6gi1V7EGn/3qI/77EQG2Hi4Fpi7/cPfvr6xo2IGPUEnzqtT2/fOriK4dEtoRaraxcF9xJd30+DuAf2NoJbp+aT/ebpPQJTkfCyuYLGx87+5Lv7i2HE5ClamfSR857/2aXL37XtET0+P4gjVRcGhf/JkXG3zMSqLB3xtmbb7p1sGOD3znQq5FKqeaK+fd5e8W/bUz8/Tnv8T+W9UdKQUc8ZQvBJblTr969sms7L/QD3qwWCCtXmewq10v8x8VpTJAvBObIpR9f3X/7e6s9AvpNw2YGyChloXZlUBqUdtwSeZdZ0vJSV6ocXPpX49VGk8+dcSoSJij15dGWxFp+oX2s3L6dAcCCPsXWBSCa/e9As/99icjYYtmZJS2Xnf3ozbfkutMB0mmX4iYwApgpwRk92NPjn7Xps6eZJeHvA7xX/NEg8T+0EpKvop71dxcu3XjmNY8uxJK/mhsABLXiIK2m2ZffT/n3dFCuULTKC334lbkNLwcG0Ih8gNF4qLj+BdSm9G8VgZmY8HpggoQjqnPS3/ipcyFDtljaYZR6CGDKDUBKXg8oC0xwRj961pUPumLpuyYWUcxsqYF92GnSfZK0v3PYN63xy8/efNOtJ/9Xamma0m4ucwISmYwGEWcpaTufvO08rzX2PTCOtKXKXvGnBtT6T/pPBDA7P7S81XOFyl33dlzzxQSyaiGW/NXOABjbFFj/HawFHRD/r+VhhQ49MVW5YoVVa+wlgQtuynWng86BLiXblIB5lPw3VvqnlH6THRpR+42ebZT4V7dXq2MRzaXyVzefccnTnalevdiT/ybJCBz9adyniIhITd9NTDP8IelwQkjkVXYNWxUJXxY/fuWTp2+86ZQxowXcQK8lV+fCZJNJe3J/aul5j970JXj6PucHK2ypmvBX6xj+TJL+2LIzsYgXDBUeC4pBT3vfOm+hlvzVzgAYTViCsjfBaDAT18v1f/hGQWSCXcOBikTecvzAlz+Y276dOxfilCxhQdL+5lV6TSYVgqEP61hEMxDUS/wPcyc58oxyxfJOYrUenFJdkNP/obwAD591zYNuqPghrzVm2Dk75+I/zhMQjJQCMI72Ws1d5zx+69lZSloQuH1zn1dXQ4BB7Zv7PBAYRHzeT790btuRR2xRkdB7/eGig3VMRGr6X78eSX9wOhqC8+2zwe6Rizad98Ftb9p2lF1Mid2zCwEwHIj2xrFqKf40nXJYwHC5AmqNfebly7evzXWnA2QyErsUmhtOqcH2dYF+6dErlcLbbL6Afaf/BiX9jYv962hIcbn8pR+dd/m2RHYtpeX0f8iyQHBKlUr8ZVsoPzvlkc11Fv/xOQGuWHbsu5VKm03nDK6//ZyNn20d7OjxQagekmplCDBTilNqTPgHO3r8M+5MtZ07eOMGBd7IAa8K8iVHgBrr8DfnSX+jI35V2FO2VPnHjRd8ZHv75nXeYlvzs0sCZPhwzrGqfdx/Bi/BXK5YFfb+/VUb72hNJEbdUIKAZp36BwUiJlu5iGIRYgdXr1p/msIDmNlZY76PVEo9v2KL3DuHKQvsHID6cffVu10luFlHwpqd4zrU+s/cO0qkYC3bfIlV1LuEY9GtZz+6/to1/be15LrTwZhHIMUpNTrNlaYx+ZUSmYSuij5xmtJusKPHP2fjZ1vPG7zxutCqZVt1NPIeO1xkDgImRWo22nBIt/8MxB/Mvrc07vl7Rj6w8czrvtK+eZ032LHBX3yjx2ZxekF2Lb1sxc57dSxyDhdLdrJGQDVL+jt8C0drlrZqf0/+I7/qeu+nOjllcpSWjn1CU84+T2Qz6olj/7A0bNUjFPJeZksVJoKqa4//iW1nq2NRbQvFB0wo3DnYvs2C5PQ/pez2bFb97qgX2irR4Aky+mhX8h3RxAermYo/zcAAoAmMOxXylI6FYfOl5xju5hG1/MuPn/KOkfEPncrI9cGOHn//KpbbWrjVnUot3hv94cI7QstajrH5EqwfuDF3/8zW8uwy/g9R7x94rTFjS+XHob1zsX17KdeVtqDFl9hNs+oESEm7euArF6tY+H9csWjBmEHsnWsc3yRfLYl7wa7hS3914fu+2NmfMoslo1OYX+5/UNqddP/6U1U09qjLlxiaqNHiP9r4JzDxKAfDhT/98blX/G+CM1pq/6c+yS7XnQ467r/xUtMWvcUVygwc3BKdGuT6n0j8xysfE1ntaaPiEfi78r8xrfF/scXS92wLnoz+Vrtc92X5w73+OT/5bGuwJ0IhFZyqlrS81u4Z+Tsy6mizJI5guADnB3a8u3/ma5lrn/Tn2JmWiHJ+8ERl2H/dA+d+YHsqlVq04S6a5TAgjcQWfnnuqPt0NHqWKxZ5el4Arn2CE8NRyAMxb/PLpfOOVdt/mxuAk2xmoQk7otkT77/133RL7C/sSNERs2m065/BVkfCypUrWx8764WTxje8EqbGmPv4jAdv/G/dEntzMFKy+1VyzOr0z7P7vWniIzADTnlGmyUx+DuGWSnKO8t5AvUBzGN11vv3hyQmIs3Ae4koCuZW74hWBHsK4MACzD4I5lCT/GguxZ/hdMQDW/dsJb/rjAfOTT+f4pRKL+L1Prts+UR1s6CBvk9QxLsThZI/4UCgRon/3nkBZauXtx5jnL09d0H6TZ39KZNLS0az0Dyn/xy67Cn33XKSM+btLl8kQuPFf3ztP8qV74PSLsEZnZVfaFqsfnqXG0yllNXmk5roLUS0T0Nn7fqvwwIgIgI0+wH7LwwFROSBqFV5qtW0RnsPmXPAjCBfAjGDLcN/YcgHYEAEKPJq83249tUuzAylnI6FTWXH0D8+cG76+fbN67w0pf3FvHZnl75HSYtMRj/due6uYPfwLXpJ3INzQeNdEQe8llba7hkJKBJ6w3H3fvn9uS44KQ0Umif5r0uBiC3R5dXSP7ZzI/7M5BlylcpOZnNDKpVSa7BFGlxhumWBWZvoXUuDHZc/EuRLH/Xa4oZHpwXWutnPjFz/h8gSJCIPAHPgmP2A/Z3D/iH/7Mr78APmwI32ISYPRASqVXO+OjT7AQCl2GuLmtILe66+7/QPfLWTU2YxJv3VfBwwtmxhENg5/9Ou7G+jSNhg75SsRsX9J3gthuFSRZm2lhuO63/RqVIaKDRL8t/K7dt5Tf9tLdDqTC5XanMfzqxwxpm2mHal8j/9+Jz3/XZr71pKi/t/RmRGm8d4fukWP1/8iQp7BIabSZvfhoj//g+rCjgRVQUd3qiwT/ZnTPBpKu83581+gECFPQS7i1fdf8Z1N7dv7vMkObxWBkA67cC99Ez3Zb8PhguvA9FOCnkOzDwn4k/j/odzcMWSpUjojmP7b1qKFVuoWadkCYuDBDIqm0xaUvx20xY/wZbKdqKs8Uac/lXII1cobQur2PpEJqPl9D+rXvyMbFJtOu+Dw+Srt+tISBExN+XJ/5AP49nnGDRT0h9zJXxkm3HFSvbejvevP/7O9eEDqxjEAKjFlLz+fvPMRZf+xBWKt6nWmAFRMGfiv++uVFzxWbfETglR9BJ0pwNs2CChAGHOTv9rsIVPuXf9Ch3W13Gx7KCo8a7/akqXU5GQsoXKTx4+a91zACCn/1mSzNrO/pR541mXPGl3Fz5mlsb1WCigIeKPBot/jW+OOoh/4LXGQv6u4Z+w4w909qfMU//fThH/mhsAANDdHWBzn/er116ScruGbtGtMQ+Og5o2+5lRcw0ydvewT62xTx53z62XoqfHl1CAMCdkE9WMY2depiOhV7hyGXRAyVgjxH/vg5lBRt0qXrHakevqteneXrRF/RuD4eLPVWg0FND0NV0zEP+anf5r3OaXxsQ/amyx8hNdLHbfd8a1z+YG4KTCpV4GAAB8Z5tFJqGJzCdcqfJ7ioYMJumO1dAdxznNZd9RJPLRV228YxVWrJBQgNBwOlesIXBKWc9dBkWOFbm5EH8mtjoaVnak/MCS4vb/TSCrskmp+69Vh0D0rqW7T/nACFWCt+qIp6aSIDf3rv+5FX/Uqs0vAWyd9dpiJiiWf1p6YaT7h2d/5A+JTEYGW9XdAEinHZDAUxf8/fZKyb4OjB0U8hi8vxFQd9c/JgoFVJyKhV8cOP9r6O4OkM3K1EABDewap3JdvXbNo8es1mHzdjtSAjH0nHT+YIbyPGLnPpfrTgeQur8aX+Ok7exPmZc89+DWYKjwDyoSov2GPE0ogs0Z96+v+M886e/Q4h/Xtlj6iT9iOx96XVX8xcBthAEAAMmkbd/c5z372nVbXLF4G0VCCgw7Z+K/zwgwLl8IVCTafVzuS5fhbUkLllCA0CAGehWIWJdL51LIC7GzPIsGcTPfcJmZPA+uXNllmJ8AM63ZIsl/tSbXnQ6eX3EJPXTm1Z9wxcq3Qke0GXbs11ws57X4zzzuP6H4Ow5MW0zbYuUnlbzteuDcDzwv4o+5yetYk0mFtibTldW5vnt1W/z8YNdwoBSZORH/cU0soJXVrXFden7o7GcuuuTBsZbGshSE+vaMT6qnV78uHLjgR6T1K2zZd2Px/0bG/dk56y1r0f7OoRt+fN7V10rb3zqSSqnOLii/dfmxjugeCnkvsyMlNzYYp5kz/mmGi22uOv3tjfmX/J9U8r6I/xSp2wl4e6aLgS464mWxHznGW5SmOKyjQ7WJrKv4V70A1Y5QDOiwOfXFf//m/9z+y19W8LIuIJeTU5BQFzoBc+dlX7Qr3/XGv1Px6DttvsREpOcg6Y8p5IFtMGSUfue5r4+PrMmCc7L26+QGyPEz/9yFZ4++fudL3nnht1ipt1JIt3DgoAg0owl/NTMAmjzpbxquf3YceG1RY4v+TyojIv6Y0xDA+NLA3rX0VNclP3LF4tt1S8zUrBSAZtcn0JUrTrfGOvzAvQ/d6aD9zaskFCDUj67q/3PMb4NjHmvw3lDxr958Tkc8xUX/y5vPuPTZ51esWbRDUBoGpd2aJ1OhB879wDOuUvmEaYtpRbBzK/4zmCfQpEl/VfGPGVsq7xN/FvGfewNgNBmmfXOfd6xauynYnb9VxSKKwcFcxyyIyAQ7hnwVCX/i+P7b3zvY0eMnMgkxAoSakxpN/jv5vtvWqljoNFcoMYFUo8V/9D8JjmGIvglmWrl9rZz8G8DWE9KVTu43D591TV/597vSZlncO3RSYJO5/tGcSX/Moyf/UmVr5fd79om/hLSaxABAdXb0yu3b+enOnitssZzTba2GnbMNdf1PZNA6ZzjwmUKhfzz+3vUrsivWSGmgUHMGRpP/nOYP6pC3xFnLhysLq0uGD7PTsTC5cuXBwhL9i0Q2q7LJpJz+G0SOuoPO/pR55OxreoMdw73e0rgB4E/lSCxJfxMe/f3RmP9Wu2ek64E3pEX8m9EAAIBsYgsnMhlNgf9+Vyq/QOEQT94quP7iX/3mRFzxnQ6bI4m9b6I7LaWBQu1P/wNwpz5w+2tUJPzWYLhgiZSazYAYmnkiIkgREfMnt55wWf75LVuort25hAkrA9o393kPnvX+dLA732uWxj1UPQEs4j/F9+Fqb39veas3Jv4bL/jIdhH/JjYAQGn39K5d6pevu/xRLpfXm6WthonsnIn/2Eoi0nakZCkaOf+4gS+uQ7JavyvLQqgFW5ElpNMusPZM5ekoWwuai9M/nNXxCNlC+eFS/IXvV8djp2WznAMGO3r89s193oNnvD8d7Mz3ektbqkYA18YYa2TGf6PFn5kdFAVea9SwH1xrn/39eRsv+Mj2REbEv7kNAACDPT1+e1+f93TX+z4ZPL/rizoeNXzYqYF1FP99/6lcuUze0pa+Vwzccn6uOx0kpFWwUIPSvzXYwu2b+2Jk1PXsB45mEfqfedyfAYBVyBCzu3/rCelK3XtzC1MzAs56f9rfOVw1AuhgI4DmqnVqI8v9phrBcux0yCjTFjXBUPHKH77qshs2vukzu5BKSRfL+WAAAMDgtm0WAMyLzfW2UNqhPDPtUECtrNHxgzDJMlzJdxSOfeGY792w/HmZGijMkkQ2q9KU5kq59NcqHn2VK5aYZni/0YwfzNWpf1prWywP6YBvRiqlcgOQ2H+zGQHL9jcC5sz1Tw1uHjOVpD9m38RDikLm1/6ewuX3dlxzS/vmPg+plJL2vvPIAEA67dDbq3/2mnfn4fAnKhbRTOQOGe+s6emfJysL0K5UsrotfkY4HLki150OOgd6xQsg1MLafAc5x5hh+wuaxYMJACuyKhIGVyp9g+df9ZvOLsim2YxGwK58aswIoPGHonmd8T+7pD9mOAaC0JGtnrPuifyeoY772q+5rbM/ZQY7enxZx/PNAKgaAUFnf0o/vX3ZA3bPcJ+OR/WEVQGzyniahvjvGxfg+S/s9nU8+tHj+m99d647HaQ4JUmBAqbfAC6lslu28CkPrl+jY5HXuGKFiad/r82uVHB083Ws4BxZjX8FgFyXnP6bzAioJgaecfXH9xkBFIDhFnPSHztndUgrEw8bWw4+UP7trq5Hzvzwjk5OmVx3OpCVg+ZuBXy49+3sT+lcdzo4buBL9+glra8Ndg9ZIqUbEvefHEfGEMDDQZhf+vTTy/JIJByIJF4qTJmxLmQnblz/L96y1ncEu4f3ru0Gxv3BgNWxCLliadADv+7Y3xw1kk0k3d4HCE2zD7dv7jODHT3+WQ/f9LHQ8tZ0MDQC5weW1KHXzYJr81s99cNriyp27jfBSPnz97Vfc9tYXo3sxfPdAzC6QnLb1zI4pUDqOlco7SDPY/Bo4H1uxB8AFAeBJc+00rD7bySTNiGlgcK0Sv+qp/+THv7iCToefavNFwMipRot/qOtB4kUqSCwn3j4rCuHsoksRPybEh7s6AmQSegHz7j6427n0OvZul+Flrfq0YZBbi6PgdSgpD84tipslA4Z5SrBnfk9Q6fd137NbZ2cMiL+C8sAqE4NHFylf9nZ86grlb5glrcZEGztfRLTXjPGFcvOxMPnv+Ke296VTSatVAUImHLp31pCOu3It6crz8Q4sLMN5U8v6W/ff1ndEiE7UnrELj36e539/QaUlWzpZs4XSWZtZ3/KbDzj/ff4BdtpS5WcDnuGPK2Y2c5F0h/Veq+liWP9YDivNarJ088GleDSgROu+KNHzvzwjkQmoXOUDkT8F1YIYC/tm/u8wfZlbnX/C18yLbH32GLREkg3Iu5/yJGpRlsdjxq3e6T7Z93vG5DhEsIU9j8CUnTswMtCS6Mjj1LIe5UrVTCd7P/ZiP9BZVOtEcXDlTc/eu7l/yNTLzHvQkgAcOYjN33Ei0euALAyGClaYijQoSaqzaO4PzMzEJhoyKt6APA9XaC//sGZl+/o7E+ZXFevFeFf4AbAqGsHx/Z/LWxUeRt5ug2+Jcy6ZIpndVGY2apohOAHg0UO3vDy4DXDua4uWZDC5Bs3Z3QWCXfSA1/8O9MaviMYLgYEmLrdjJO5/hlMmgDCiA3Mq3989nu3jWa6ytrF/BklnOhdS1lK2rM23XC0bo18A8wXsHPgShAQoA+erDpPxL8q/FYZbbzlLQh25h8J/OC6+0//wMBYGC1NkuGPBR0C2Jd+z8hk1DNd7yqzrbxZhUOaiXkmCl6TQUH7BgZpVyxafUTr6aEA1+S6u4POgQEJBQiTksUWBhHDBevYOgBT7yVRM/GvvqtVbTFyFl/58Tnv+20nBrSI/zwjnXZZStoUp9SD51zz2/tPvLTTlsof1iFvu7ckbkhrYuZgXx+Vphd/ZsAyc0CeIW9p3MDo51yh/KFyYfcb7z/9AwOd/dVYv4j/YjIAAIwl2z194RX326HCP+mWuJ4o5lWHpL9DviCpsdLAyHWv+OEX35nr7pYugcIkbtvqNMlTH7j9NSoePc6VfTuT0r/Zij8AVkppO1zcVQnszWCmHAZkQ52vdgClHVIpleCMfvCMaz5d9iunWWs/SSH9/D5DwAXM00gUbKT4MzMzWzDDREM6tLzFQKvnXMX/kKfolP5XX/aZB89J70xwRue6Jda/+EIA40IBnQO9OtedDo7P9X1XL4m/Mdg9HBCRaaTr/6D/wczkGQJz0erYi58686k8ekebGgnC3mVXjbGffP8t/6yXtr4z2DMcEKa7djGruP/o6g+8JS3K35X/j8fOveJt7Zv7vMGOHl9+oIVhZGaT1UTOzh+vPybwvPeSde/R0dBKW6zAFisOgCOCGjvcNSrpjw7M5wcYzKxCxqiwBziHoFi+08Qi32Dy7sq9uueFfWEzKU1d3B6A0VBAbvtaRiqlwPbDtlTeQWZqrYLrJv6jsQDnB5Y8E6HS8LdBadfZBQVpFCzsd/pPuBMeuPkkFQu/1Q6PWAJ0o8UfAGCd5iBQIPoPABhsXyaG6gIhm8xaMFOCMzp38pXP3b/mko9WnG1na9/pSpWcaYkob0nMqJBRYGYwV0sI69xunapliq5assg+Ga1MNKxDy1sMKdrGQfDdoFh+3cb2a/9o4DWXfT336p4XEpzRYFCWklbEXwwA7C0NfPMq/VTXJT/iQvnT5sg2b7QOdm7Ef3w+QKnidEuk8/h7bvnrXHc66PyhTA0Uqjy/Yg2BiMnSGRT24mwdYwq9f2fb5neC85g1rTG2I8VHdSj0rQRnNJAUA2AhQcRZSlYNgUxGP3zylc/d+6r3/eum09/fhXLpTa7sfwKEp5VnKLSsxZBn1KgH0wexP66vgDvQOJjcjQ/e7zmAA5wPsE9gnzytVMgob0nMeEtbPNLqd0Gx9L+26P9dmGIn5k648uKN7df+AKmUGovzi/BLCGBSOrnf5Ad/TrvzvEHHwu+0hZIjOrg0sBZx/ykP3WBmGG1VLGyCPcWLnup6392d/dKWUgAhlaI1ibXG5P/wqPLMGi4HDofxAMxO/Cde6+zYmSVxZYeLf/yjsy//NvpTBrI+sdCnTnYO9Or9SuaIcPYDn/sjHY+dCWf/xpX9eOjIthVwVb13hcreNcWOwUHgT7oeHQCtPOXp/fZaHQtXTVwGKrvyvydFFTBug2d2hV8Syd6zvGfP+M+YyGZlap8YANMqDeRUKqW+/tpVz5PRy7jiA0Sq1kl/NI0rweysjkaVK5cHw+CLQlGdH2xfJ4kri5jO/pTJDcCd/MYj36lbov801dI/qqXbf7SZio6FlR0pPqjD0QtahrdxrjttZewvFlUZKrLAfkJLhPMGb16hw/qtQaHsQLQSmtbBurF1Ew4tb11BkywqMhrlF4YCgH9PTMSKmRiW4W5VjBFAQ0VD/yd3wmX5wxomghgAUzcCEhrIuNUDt59rYvH7XKUSwLGpi/hP40qwc763cplX+f2Ozz914eXXSZKVnMBAxCffd8ujqiVyqiuUHejQoTWqXcb//sl/S1uMvyv/2cfOueJ6WZdiDABAdoLmTylOqTQA9AKdf7K0LQD/FexES885s6xN2Z3Dj9z3P0ObO7ugqsOkenkiUU9wRj8/sIVyXWlx74sBUAMyCY1k1h7f/6V/1sta3zlWFUBzJP7jjmFWhUOWC+W/+1nn+/49gazKSpc1LMa+/2kAJz185PEqFNrElWAZAkegGU9AnZH4AwAUAY7LrmRf/eOuq55Bby9JpYqw9zSOAY2BAazsWsu12Ks6+1MGXQAGABF8MQDq1lq1E/06R93Bcff2/Y9pjf+R3TNWGjgn4o/RIhemsCFYa0vxyJHPfOvXQ+gFIA0sFmXL1pPuW/8174i2d/m7hg459a9e4s+EwLTEVDBcuOWxs6+4Wk7/wvSMg96J1+wAgK4udGHASXOehYlpcvOEV2a2M5hJff/2j3LEP5uMbkNg+VCnrLqKPwBSRFwJrIqEVXio+P+QTl/Y2ZUyOcis9cV1+k+4EzffeqJWoUQwPGIJk0/9q8WAn0kf7mBcsQwbBLcCwOB3tok3Sph6+fUhK63SyMlVgpQBYq5qX5O2fcMG84s3XPaYHS70mmWthsH+XPs+iEi7csWZ1nj3K35wy1/kutNBZ7+UBi4WBgagQMSqwueoaCjOszBKZ5L0N644xalY2LEf/LhC/vZEJqORTos7VhCE+W8AAMBgT0/Q3tfnhV+0oi94Yff/6LZ4iKtNLuqW8T+V/ZkAFRRLvlnS+o1X3nvbG3Pd6WAs+UZY2OS60jbBGQ1Sl7qRMtfs9D/d5zFARinHrvdn531w+PkVW0gy/wVBWDAGAABevWyZ23pCshKQ+wj7tkCeIUzD5V7LQUH7/ZV1BGYG6U8e23/T0qcHdykwS59ALOzSP/Sm6GcPbP8r0xI90VYqwWSZ//V0/TOz0y1R5e8Z+bEJx/53tJ+6uP8FQVhQBgCyyaRNMatfXXDp48FQ4Q1kNEHRlKYG1iTuP/nfGztSDLzlbadF2EsNdvT47YMbJBSwkE//3ekA6bSDs9e4IAAx6Ua7/vc+idkppT82LulPTv+CICwsAwAA0kSusz9lnn79ZRvtSPEbKhxSjGlMDazTuZyU8oJdQwHFw+991cAXE4Pt26yEArBgk/+QSqn2zX3H6VjoGFcJ7Awnrs52mTJppexIsaK8UA4MyiIhSaiCICxMA2D09GWRyehfXnjZ37iy/wcdjRgwuwa7/jHREBZYjpBRmVcOrlqeRdIhlVKyxLAgZ7X7xdJHVDi0fLLkv7rV++9z/wemNQoouqNleNtI+2CfkY5rgiAsaAMAAGPLFgYAZ4O/ZOd2Q5sJW57W0/V/cCYWkfN9B88AefvviWxGtb95lW76XgvCNI7/KZWmtDv5vtvWqljobUG+YA8/o6L24g+ASSkTDI0UbAyfzXWng8H2ddLzXxCEBW8AAOm06+xPmV92XdrviuUPmSNaPeb9SwMbKv77SgOVK5WdWRZ/3ZNHbn/rYEeP39mfklDAAqGza+x+cd06Ho2xb92sltrMxL96+m+LgZz7v0+cfOVz7Zv7PDn9C4KwOAwAVEMB7X3rPBz98q8FO/Z8e7Q00M6V+I8zAsgOF3yOh//9NQO3XZzrTgeJjOQDYKEk/wFgRe+x+RKT2r/rXz0z/g94qmJmYlLfB4CW4W0i/oIgLB4DoFoauMs99cqLyzpwH0Hg9kBrNzq7ugGNjifdc4mtU6QVsVKfOv7B9W1Pr96lJBSwAEr/Uil18qbb/sosiZ3kKr6d8f1Ds8pTsSoa1sGu/MNvOWtHFpxSMpJaEITFZgAgm8zazv6U+Wn3JU/6Q8MfDB25xAM4qH/SHx++S+BIMTDLWk/WJf2pwY4ev31zn5QGzu/Tv0U67djZD7EfgGrjaJr2DBVmdioahlLqzjTS3D64SrxLgiAswGFAU/wOnf0p/euXvcyEnyv/HwqH/tQVSkxqZrXZsxX/ca/BUOTIMxWUyn/xkwu2f6dzAHJaw/xM/kNvL5/84M3HUijyGPuuFc4SQNSouP/oimJSBCaUK747Yct5V/5ybByx/EiCICwqD8DYtpjrSttnXv63pZ+f/94E+8FzOhbW4OkP5qlxySDBOgXLUYS8//eq+498ca47HYClNHC+kVi7lkDEzqqP6kh4CVvrGi7+Vf0PdEsUsO6ftpx35S87+/ul9E8QhEVtAAAEHk20YxsE60AoQSu7Xz5AnZL+DhcLcIFvyWgFmA3H37k+nMiupSk3ehOa4vSfTSbtqYO3Haujob8IhveV/jUq6W9vpakiYwslq0L8WQDIdQ1I4x9BEBa5AYBqq2CkUuaXnZfcZQvl/zBLWz0GbAOS/iY3IqiaD2CLZestbfkjL27+JJtMWgxIaeC8Ov1zStkyUioUirFzPG1n0eyS/vb6k3Q4BA7sT/c8T38ApxTUx8UAEARhUecA7NdCvX2wmmw3XKb/UJHQW+wkzVrqFPef7C8ZWlko5fzd/vG/fOOlz4JTCpSWDbz57w9OpVLqvy464nnlmSPYDxhE1EjX/yiB1xY3/tDwW3909lX/2dnfb3Ld3ZJPIgiCeADGdtfVT9/jBjt6fPb969m5PGntAOY5FP9qaWBglTI65LWq20967PPx9sFVWkIBaPLSv34NBn37omVJ0xZvcdYGcyL+zE6HPePvyj9y/LP3fwuplBLxFwRBDABMUBrIKfOLrkt/YocKV5oj2jxmBHMo/nu7BNpCyfeOWPLmyu7YDdWpgeukNLCJzclcV5dFb4os1D9wEITJsZqDkz8AWBWLMCv+VjaRcWvWQtaNIAhiAExEDmmb4IxessT7v8HO4W/rWNjjA/oD1O3oTYf6JzL+jj0+xcN//YqB2y4e7NjgQ7oENiXtfX0GIJz8huVvNW3xNbZYDohINSzpb6/riMf6/pdAyIKItyYgp39BEMQAmCwUkEXCDXb0FI76/m//3Pn2lzoaMZjO6ODDNfuZJOnvME8itk4preLa0587a1Mm2r56lwJYQgFNRssrtzEIzA4XgoBpFdsdIP6zGQvMgDWtMYIf/OtjZ1/1i2rpn+SOCIIgBsChSvAYmYzOpdOBKwdXMaEApR2mpLZct8xJItJ2uBh4LbG1u/0Xbq52CdwgLt1mYrS97qv6b3oZhbx32nzREc3M7T4b8R9dMNVp14Z+WP2LAfl9BEEQA+CwJJMW/f3mqe5L/odHSv9hlrV6xIfzAnDd6ymISAcjxUDFQn/1yntve+NgR48PllBAs9A5UL0vwoY+omPhCKxzU/6BaxD3p/HJf9GwCfaMbHn0jCuySKVU7kLpJCkIghgAU6O726Kvz2vdo99n9wz/j4pFDNjZeif9HfL5BIJvNQIb96LRb514942rQUkLZukS2CSn/xM33vQqFfL+2g0Xecqn/9ol/WF06qAjo8usqXfvOGLp+4eatXeWAV2CGAALf0vHunV28C09haDsX83MARmjwcw1OeTPdAtRRM73LRSFg1jsC8dsuiGaQJZkU5pb1mRhwExamT8zbfEwmP0p/SS1SvobN/VHKWXs0EjxsTOP+i8Qca47beUXqhHptJvVDyUIYgBgvuQDOHBG/7L7sqe4UP5zeF4BRtv9NwCuu/jTQR9LaVcoBmZ565/GK6E/zdL/3969R8ddnncCf573fX9z04wsG9tctglsCsFIgAEZ8CXsSF0S0nbbTUJmts1paSAs2mBjIKRpLrsda9OUbBNifAEiNwnp5pxSNElPE9gkJCmSMJCk8djcJMxlOYR0odjgi0aa2+/3vs/+MZLvFxnPRZK/n3M4HI41tpjfyM/zPu/zPm/a0sAAtgKaaGSYAiJice6jrlBmEjGNbPo74NNoVSxColQ2NXkdMQLWSUv1pzQR0RW/WPuhZbmvnD2RbCHpBiQAszsJSNvOLX3eC103/8AViv26JWrETfYDND74H/Ar2t816pt47OvtP954LnV3BxlsBVBzBv9kDK3plct+fs9HTVviMluuBHQiR/9q0fQ3mURopVypUtRKfTHLaTt07wiCfw3sWNA++Vaf5yoyB+8IIAE4ReQ6bwo6t/R5RuQWN1bcrlsiRpxz9W7t5uPVJ6xTxJyQVvPlzi193sO5TZgS2ISzo0Nd5FLZfmVtkJGKTzyVAyO1bPrbv/oPdDyqqBx8e8sVK3+THMgYymZR/q/t8y4KMxoqAQnAqfMzz5J7Za4b6V415ir+Z0Wkwse5NfCEz/q/ky9n1na86Ju2xLXjBXtfbkmPT4PYCmjs6v9RQ9zrXjzzjWtNW6LdlsoB0bHvkKhH8J8c/0NCQlo9SiJMXV14QDX/q4DC1in8jAESgFPKxNHAF39n1ffdePFG3Zbw5CgDgk52Cc4n9heSCXaP+SoS/uNFgxveT91dNoUpgQ2LBkNdg+7cH64Lk+KM+AExHWfkf407/ungo39esHd8JHflyu8REQ0x5v7XysKdHVJ9Zu7fHFER7wjgNsBTjQh35jaZt/IhHTGl76tY+APVWwP3rwjqu+9/1O/LqlhEu3Ll5edXfPK8fT1ljOavOn8eFDG7S3Mbz5aAXybr9MT73rCmv32/G1Ng4jEb5At/tm3Z6v6UiMoyo/wPAEgAanl1MJHQ2d9eE46cf+YW5XkdtlCyzKybEvz3fVsu0NGIlnIlO35W9M/OefXVYKir1yIJqJ+kDJgh7g4ufnzd17058ZuC0fGAmb2pPNjalv7JsaeVVOzOrStWL8QTr/9Vz3gbgLAFcEr++EuKsurX1/eWqOI+LyKWtTry2eAGBf+J5b5xhZL1TpuTjv46nx7q7g06N+HWwLoO/uHuYPHP156jjPm4GysSE5spfoRqmnWLiFPRMBHRQ+SEsQVU5yUAABKAU1eW0zY5kDEvdN38Azde+LiZE/eqg9ebE/z3XzJUPRqo47F17/3x+kW5nk3+5PllqK3O3FmaiIit+qyJR8POueCoxX+uX/AnImGtlFT8AlvXS8ySHR5GkAIAJAD1MtTVa5MDA8YVJRvszf9UR8JaJu8LaELw33drYGCVMqrNJLy/IhF+5T1XKxwNpJqPg80t6fEXD6w9h42+PsiPy1FX//Vq+jtg8I9uiSpbKP9d7qrbXkv1p/TEtDoAACQAVKetgKGuQffy791adoqvF+dIee9sVHBtG9NZB6OFwLTFr73gsQ3fzC3p8ZODGVQBarn6/4Pq6l889VmdiIXEyZFX/7Ue83uU+j8zC7P+KWUy6oCBNQAAaAKkOk+BG+oid/7jp1+rQ953XBBocqKnfJS/Vqv/g39JyLBVYS+w+eIHnu9avTnVn9LZNIbC1OQymN5et/jn952jyL0gJB6JHP4o6tjxf2Dnp4qGlCuVh7cu3XUxca9gjxoAUAFokKHu3qAzd5Z+4aqbs67s329OazNy3KuD6xj8q0+HKXBafBtSieiPOgbXXpBNZR36AWq3+mdX+axujYbEueB4j7Iuwb969M+qkEdO5K+Je11yAJUeAEAFgJoxH2Bn0cZjRN/jsNftSr5jPnqiVLfgzwdVhwOTiBlbKH9vZPknP1qtVuBo4Mk8Z2KWxT+/7xwi+yITmeOt/uvQ9Ld/9R/x2JUrz2xduvpSYsYzBQBUAJoyKvih1+1rV928WwXuYxRYYs1HLcfWLfgf3g9ggnwh0HNarr1gaP23hrp7A/QDnEzn/yZDmYwi5/+F1xrzRJytR/Cf4uA/q2JhdkR9xCwTt/4BACABoCbcE54cyJiRrpVvUmD/VMej+kijgrmex4/5yE2Bdu+Yr1pif3L+P69bPtTdG2Qkg+d3ovpTOrekx7/0/fPPYKU+EYwWDu/8b0TT30SPBxutXKE8Jko/RkQ0NEjo/AcAJADUvH4AS9msSl+14++DPWObdbzloFsDa7FvwnTi9waTEy1BoLy2lkfaH1vX3ktrBMNiTuxtT1GKzv3hurAj+z0VNt5hpz0a0fS3P/5bE49qVyw9+PSVq4YzUm1MxGMCACQA1MQpYcPDMpLt4NEW74NuvPiMjkVZRBzXYPjYOwj++56X+IGw0XFlQl8kZsmmUg69HDTVkx46m07bljb9n715c5baUsUe9DPAjWn627f614pd2R8X9r5MqOYAABIAmjZbATsWLOA3lvQUyJcvkGY+6qjgBk4eVczGjo4HKh79SPvjG/8uSYM6OYCrg6cal88eyETIBRlXqjiSY934V99ePCHnTCKmg7Hig9uWr3o5lR3hXsbqHwCQAND02AroDpIDGbO9++aHg72F60xL1AiJa3Dp/4hNgXbvWCV0+rzrdjz23I1D3d1Be39/CE/s2Kv/oe7eoM3M+0PTlmi3hTIddLqjgaX/ib1/cmV/jE3oTpKMak+1o/sfAJAATLf5AMmBjHmxe9V3gr1jm1U4pI7UFFjn0v+Rvszz39rrm5bIFxf95K6lI+l0hdAPcNRjfwt3dsiin244jY36S/GtI+ajdvzXNfhX478zLTHtCpOr/w6s/gEACcD0vC+AHIkwReTD5AfMxmhyUx0VXJfgT8TM5AdGnJvvzWv9yfmDGy6i4WE0BdKRj/1lUykXjsmXvbmJDlso7Z/t0KiO/0NX/5VgTCLVvf/2FC79AQAkANMT97oUZdX2K1btkoq9jrSuiFb2+BFDanJq4OiTAhW7UsVnzySMp/6q2rcwzLg06ODrfnNLevyOR+76LWX0df7uMcc8ceyvRmX/EytGiDOJqLaFwoPbOrH6BwAkADQTrg7uzG0yz3ev+o4rlu/xTms1E+Nja3re/0S/hJXygtHxQMdjf9jx5L37hwQhCajG9GwHtz/XH/JaI/+bPS8kTmo+EvOEVv+eYVfxd0qU/1e18z+LHy4AQAIw3eU6bwo6t/R5HHFfsm/nt+lY5Lj3BdSi6W9KkwJHx30zJ3H95KTAzlwfJspRv6J02urRN//YzG3pssWSPVLpnxtR+p+Y5KDCHtlC+dWnLrvtJVpDhIudAAAJAM2MUcHx/Htl+5W3vC2B+wJ7hlkrOfzq4Drt+x/7a02wJx+YeOz6RQPrluaW9PidW27yTuXSfypLdMnP7z7PGH1/sHfMMnPzgv9E859uCSnFvJFEONmFnz8AQAJAM+1o4PNdN//If2vsehUNG2EOmhn89zUFiigJgsCLRx9p/9n6K3JLNvlJGTCnZuPfWTqbTlsS9WkVC7M4EiLihjf97d/7tyYR8/xd4w8U42//A2XTaqi7F6t/AEACMKOSgN+pHg184epV37ajhSdNa4snztmmBf8DJwWWA0VOWnVr+GftP1t/xRB3B6daEpAcyJjckh7/ws13f5ij4evsWNEykW7oWf9DzyGGtFDgxrgS/I+RC3srqUZMGwIAwHXAdZDJqGQXqX/z3hVV2h9kz7vEFUrCzJrr2PQ3ldeKiFUhTxNT3o6OXT1y9R3/Qv39mtJpe0o0/hFRcjAT3hs7fasKexfY8aJlZt200j9L4M1pMcHb+W9ufd/tN6akX2c5jdU/AKACQDN0VDAR0QvvuzEvlcrnlGeU0kpYRJoR/A+9OdBVKpbEJcyclp8tGtpwGQ0Py6wfFCTCqWxKnf3q/eHR2IKHdMS7wI4XLKvmBX8iEdaapByMBZ75m4xkVDvh3D8AIAGg2TAlcHvy1p+4XfkbVDhkiI9wnWsD6ix86DKYWbuy73M4nDCG76TeXpdcsIBJZNZWfZKDgzqbzto5b+TTek7i6mCsGDArffD71MDgz0TCZL2WiHHF0j88c+UtL44Qzv0DAGELYNZcMdvfr7LptL3gsXs262hohSuWHTHrBu37H+G1sj8AOQlMImaCQulbw8tXfiIl/TpLKUfMs2oVmurv19l02l60+d73mBa9XSo+kxN9cNtfI/f9iYhF2BirjCnJWGHJ76/Y8xIRERIAAEACQLOn9EzZrFq84P8l/EjkdSaOiB8QKeamBf8DV6EkgZnbaoI9Y7MzCRDhztwmQ/S65+zC77JnftcWyo41q+YFfyISZ722uA72jH0jt+y2/4q9fwAgbAHMvvkAmVRKnu6+fY+rBKvJ004UB00P/vu+jk2wa9T32uI3XPTkPd/MctomB9fo2bIdkMpmvdySHt9W5qZMW/x3bbESHBz8G5zp8kT1XxtyJX9cKf2VTAZ7/wCABGBW6mV2yYEBsz15yzdcofw33oI2T5zzG1d+kWP+Aczs+btGfd3WckPH4xsnRgav0TO9MbBzS5+XTacrix9b/yEVifZVdud9Zmrqvn+1KOGciUd0UKz8/a+uvOXFkQ7s/QMAtgBoNm8FJAcH9c7w1lZS8UdYq8ukVJZ9/QB1W/3LlH9zEfG9ea2e3TP6rWeX3/IJIiLqT2magSNpO7f0ebklPf7ix9Z+SCdasq5c0WTdQVsvzQj+JOR0xGOp+M8VWs5Y0tFBNstph3P/AIAKwCzeChjq6rIjy+/YVXpt99VkbYE9o4gOPxlQ18tn+JhHBD27e9SqSOSGxVv6tl7w2NorKZ217c9lQjPprH97f39of/CPZV3FV2JFmhb8D3qdOBUyLEJ3jlyYrkzc94PgDwCoAMx2kx3p7UPrezgeu9cVy5aJvEY1/U1tkUqBiUeNq/h5CoL3P7Ns1S8nhgVN75WqEEv1mKMsfmL9h3QsUg3+gSVWzW36q/b9iTOJqLKl8kh8fryTXn01mBj5iwQAAFABmO2y6bRNDmTMSHJ1HxXLX/Lm7+8HmA7Bf9/lQflCQEQJIfWTC39534cpnbYkGZ62fQGSUcQk53x7TfiybZs+zhGv35V9fXjwp6YEfxISNlrEuXFbCj499O+vLy3c2SEI/gCACgCdav0Aa/SbsflzNIV+QkpdIqWy8FH6AWrS8c/v4EE7EdLMZl4rBXvG7n926c03EFXn6Q919wY0jeb7D3WtseeuXx2KL2//vknErvF3jToWYWLmWkz645N40cTq35q2Fm33jG/KLb+1Z7JHAT8MAIAE4FScD8AsFz1851y3YN4rTNQqZZ+nOh+gFk1/U3rIIiLMVsfChoR+ERQrdwyvWPkk9ffr1ERFo5kl/+RgRg919wadfTd57rJLH1ItkWvs7rEKMYVqdb3vyQZ/IhJSyrFRvi5XLn73b856pX04Jb29jM5/ACBsAZyCTYHJgYx59j99bjeV/c+z0TzV+QC1avqb6uUBTGRsoRywVkt1SP/o4l/et5bSaVu9UleYJKOaUvKn6sjlizev/4hcefmv2NPXBLvzQS2DP5188CcRsbolrKUS3PDLZbe9tGPBMCP4AwAqAKe4yVLwBZs3rAnNn5vxd+72WSmv0fv+U723XmmtVUuEpOI/rpi+sq2z5wf7/j9emesolXZ1jbaSUZ25s3RuSY9/7g/XhRNnxlLk7P2slbHjJctHHLPcnKa/yffMxKPalsrPxcfily/savFn47hlAEACACfRD2A49DNiXizFitAhjWvNDv4HZgFE5HQsoomZiORxKlb++1PLVw7RgScdhodl8lbEWgX+5CCpyd6DSwbvPo8j3j1mTsv7/d15V92pmF7Bn4iEtLIqpCuuWEznln7q/6T6Uzo7A+cqAAASAKiHTEZRb6977w++Oj90RmI7Ec+Vsk/ER96GaVrwP+iooFgSITMnroO9hVEdC/9YmB94+tIb/2nya5MyYBZmd0o2NSxEvXJClQERJlrDqWwH70gt4CHuDoiILh2461yJRj5DRB9XYc+zhQNW/Ueacti8fX8SJ4E3L2Hs7nzflmW3/rfOLTd5uSWb0PgHAEgAgA7uZO/uDdqHNqzUrbGNdrzkHzgfoGFNfyf4gRARy1pp3RIlcY7E2c1s3V1csU9tW7Hq13TIdkc8/14hGqShrsMHIKWog3fQAh7LvciHdsh3PL7utz2jP0NE1+t41LP5AokTx3xIpWS6BP/J0n+h9FyxRS2LlrxyrrMnaGwzAgAAEgCaSf0A7Y9v+EtvXluv/9aew/oBTmb1z/X6QEycFCARpeNhRcxkx4qjOh59KBgrfrfl9NOG373Ve+VETgx0bumLmdPj/6742u6lXiLyQTtWvFbPaQnb0QKJSMBE5pj3GzRhzO9BpX/FlkPGd+Pl9NYVtz08U0cqAwASAKDGbAUku0jtDP9WK2s3oLS62BXLdvK+gGkZ/A++456ExLIwk2alEzGSQpnYaLLF8pMs8hKFtJKK2xswr2NnhYjI0yHl24rTynSZeCQZjI0HJHyZiYUXk3OkIiEKjhX4p9e+P4mTIHRawlR27f361mW3fxJn/gEACQDQVOcDvOeRryyMtrU+y8ynuXKF1aGl7mkY/A/59oSYLItoImIVixB7pvqbOSE7Xjro9xciUiFDKuyRCJGUKyTFCpFiJ0TuqIF/ugV/EWtaItqVys8oJ1dZEymi9A8AhDkAMLX5AAPmlWv+fIeUyl9U0ZBmpYhE3nHTX8ODf/WFzESmOomPyRVLNhgdD4K940GQLwTkHE3+IxP/dsWK8/eOBcHoeCAl35FiIiJ1zOBf04t6TvpFwlqLOOec777wL0tvHc11znUI/gCABACmZKi7O0gODJiR5OqNdk/+dhUNW2H26R1cHFfXmwWP8f0c/lrWTGQm/znKi5QiNorIHO0ERD32/WvR9Fdd/ZM1rRHjxkt/snXFbQ8nJWOI09j3BwBsAQC9o6bAC5/Y+Ihua/2A//YeXx06JGi6lf4bknRMu6a/6k1/rVHl5wuPtpYWXzOWeJFR+gcAJABAJzMk6C218EyOmB/qsLkwGC24fbfbIfg3PvgfZd9fxyLalStPvzX+1tIrdnb42RSm/QEAYQsA3nk/QNcgueHkyt+4gv9+VwmeVlFPRMgh+B97C6JuK38+7HXCRgmREFn7+V9395Z2LBhmBH8AQAUATl5fn0c9Pf5Fj67rVAtat9hqE50mPvzmwGYF/4Y14PGh/ylNK/tP7PsH3pyYKb+152NP/YdPPzDdrkoGAEAFYCbr6fE7+/q8j3Sv3mb35D+tW2OGmF2td5dr2/TXiCZFaeifeVjwd+K8uS3G350feuqf8w8mZcAMdfei6Q8AUAGAGuvv15RO2wuf2HiHTsS+GuQLB40LbkjHP9OM3vevxZ7/vpsRIyEm3x8ygf/77/rXd1Ww7w8ASACA6n4yYPOGz5l5ib/2d+d9ZvZQ+m9g6V/IkVHMzlHB+vNHlt+xi0QUMTt8QgGAsAUA9ZB76HWbHMgYnwsb7VjxeZOIeSISoPTfoNK/kCPDokKGbeB/bGTZ6J7kQMYg+AMAKgBQf5JRRGtk0WNrzwhFWh5VEb0oyBcDZjYo/dex9O9EyGinwkYH+eIfbXvf7Q9ObsvgQwkAqABAA1KzXke0hrcnP/WG3rvnP7qyv93Eo+ZkKwEnEj1n2nn/k/4mnQh5k8F/7I+2ve/2Bzu39HkI/gCACgA0oRLQr4nTdtHQ184MRaIDKhw6PxgrTLkSMNPO+3OzJv1NBv/Q/pU/bvgDAFQAoIkpWtqS9OvtyU+9USkVu1258oKOx6ZUCTiZpr9TM/h7CP4AgAQAplkS0L8/CZApJAHTvuO/yX/mkYN/HsEfALAFADRtZwQsGvramV44Mqii4ffa/OHbAc1o+psRx/0ObfpzIuQpp0IhbUfH/8vWqz7Vj+APAKgAwPSTPqASMJrvlmJ5u2ltMURkSeTEgmKNm/4aHfwJwR8AAAnAKZcESEa98IG/eD147c3LXan857o1pkVxQCRT61ZvZtMfNfGSnwMm/FXL/gj+AEDYAgCacdcIT46kvXDz+ju8ea1fdYUSuZK//yrhaT3przlNfyLO6lhEEzEh+AMAKgAwI68RJhHu3NLnPXfV6ruCXXtXkVEv6XhEHbU5cJoEf25Wx79zvonHNCmdc+PFNII/AKACADPa5PW0Fz/xlYXkJQZMLNzu7x0PWEgRTyZ506XpTxrb8c9E5MSxYvLmz1HBaOFR+dW2D+Z6Nvm41hcAkAAAzZYLhM794brWxOnRG8kzd7lyhVzZr54SaNa+f42C/ztd/YuTwEtEjStVLCm+f8+b21e9/Hsbygj+AIAEAGg29gVc9MSGlToWvk2FvHODvXlLwry/GjDzxvzyCb8V4piJvbY4ix88ZQulL+WW3vrdQ98nAABCDwDMlr6ApGTMsytuuaewZ3SZLZT+kY3RKuIpcc4SkZv1wZ8kMPGoYk9bV6x8a2z761fmlt763c4tfR4JIfgDAKACMHulpF9nuXqJzUW/uLeTnf2mmZtYbPMFEt+3zIpPNAGc5sFfqqt+1npOjChwTwel0v/cdsXqfyQRTmWzKotLfQAAkADQKbIl0JnbZHJLevyLNt87V7fq69jRSvbMea5YIVeuWFZTSwSmcdPf/sCfiJErlSvM9EDh/+64aSTdW+nc0uflOnuCxk4cAgBAAgDTIhHIqOr1wkQXbb5zbmjO/D911q3alwhUKpaZiYjV0T4TPN2Cv5AIHRD4i+UKsTzA5eCrW1bc9hwRUao/pbPpLFb9AABIAE7takCKsmpyW2DxwNo2Mzd+nZNqIiC+JVcsk4hYrmYDatqV/kVEmBwJUTXwR8mV/DIxPUBl+7Xc8lue3bf9QWmHVT8AABIAOEoicMUv1rVWIrGPM8lHXKGU1IkWmjw+SFwtCZCwIp7CZ6UewV9EiNmJc8RaaxUJERtNrlwpE9EDrlJZu23Zbc/sD/zDMlntAAAAJABwnESAiOjix9ZeyeHwZ0jRRToWPY8qPhETuUKZhCRgYSUswkdKCGoV/EVEmB2REAkJa2VUOEQq7JG/Z6zInt6qPfO3bryy9eAVPwI/AAASADjhRICyRJNd8uc//41ES6CW2/z4jSpk3uXK/uVeW1y5sk/ETK5UJnESEHP1gj0+YMufRU3pQyXkhEl4YpFPzMIiNBnwiaka9N/OF8nTT3vR0H2uWNi65Yrq/j4CPwAAEgCoYbNgKtvBhx6Xu+SJuy+naHSJcu4GVw6csHR6cxNafEviDoi9zpErl4PjfqxEWEfDmpirWYNSxIpJeYYqu/J5HQ2/YAulbaE5iX+qjI7+62SJv9rY16+JiLIpBH4AACQAUJ/tARqu1vIPCbSXPHH35aa15YwgX1zInl4pgZXqpEEX9Vrji+QYWwDMTBJYCsZKzxBJRbdEtC2Un1TO/dic1qr93cUXty1b+fwRExMEfQAAJADQQP39OpUiyq4ZFlpzeEJw4Or8lXfv/IOAjnLyzhKZsCYp+8HWFbc9fMxji0SUog5GiR8AAAkATJuEIKWTC9p54c4OyQ4P71/u955AoBZiWpNhIqJURwfvWDDMRERDXeQQ8AEAkADADPs8JQcy+nhftLCrQw48fQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQRP8f8CDYpky/oKgAAAAASUVORK5CYII=\";\nexport const ICON_PNG_128_BASE64 = \"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\";\n\nexport function serverIcons(baseUrl: string) {\n const base = baseUrl.replace(/\\/+$/, \"\");\n return [\n { src: `${base}/icon.png`, mimeType: \"image/png\", sizes: [\"512x512\"] },\n { src: `${base}/favicon.png`, mimeType: \"image/png\", sizes: [\"128x128\"] },\n ];\n}\n"],"mappings":";;;AAWA,IAAM,aAAa;AAEnB,SAAS,SAAS,OAAyC;AACzD,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACzE,SAAO;AACT;AAEO,IAAM,gBAAN,MAAoB;AAAA,EACR;AAAA,EACA;AAAA,EAEjB,YAAY,QAAoB;AAC9B,SAAK,SAAS,OAAO,OAAO,KAAK;AACjC,SAAK,UAAU,OAAO,OAAO,QAAQ,QAAQ,EAAE;AAAA,EACjD;AAAA;AAAA,EAGA,IAAI,YAAY;AACd,WAAO,KAAK,OAAO,WAAW,YAAY;AAAA,EAC5C;AAAA;AAAA,EAGA,IAAY,WAAW;AACrB,WAAO,KAAK,OAAO,WAAW,YAAY,KAAK,KAAK,OAAO,WAAW,YAAY;AAAA,EACpF;AAAA,EAEA,IAAY,UAAkC;AAC5C,WAAO;AAAA,MACL,gBAAgB;AAAA;AAAA,MAEhB,GAAI,KAAK,WAAW,EAAE,aAAa,KAAK,OAAO,IAAI,CAAC;AAAA,MACpD,eAAe,UAAU,KAAK,MAAM;AAAA,MACpC,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAc,QAAW,UAAkB,UAAuB,CAAC,GAAe;AAChF,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,SAAS,WAAW,GAAG,IAAI,KAAK,GAAG,GAAG,QAAQ;AAE5E,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,MAAM,KAAK;AAAA,QAC1B,GAAG;AAAA,QACH,SAAS,EAAE,GAAG,KAAK,SAAS,GAAI,QAAQ,WAAW,CAAC,EAAG;AAAA,MACzD,CAAC;AAAA,IACH,SAAS,KAAc;AACrB,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAM,IAAI,MAAM,oCAAoC,KAAK,OAAO,KAAK,GAAG,EAAE;AAAA,IAC5E;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,YAAqC,CAAC;AAC1C,UAAI;AACF,oBAAa,MAAM,SAAS,KAAK;AAAA,MACnC,QAAQ;AAAA,MAER;AAEA,YAAM,SAAS,UAAU;AACzB,YAAM,aACH,OAAO,UAAU,YAAY,YAAY,UAAU,WACnD,MAAM,QAAQ,UAAU,OAAO,KAAK,UAAU,QAAQ,KAAK,IAAI,KAC/D,OAAO,WAAW,YAAY,UAC9B,OAAO,WAAW,YACjB,WAAW,QACX,OAAQ,OAAiC,YAAY,YACpD,OAA+B,WAClC,mBAAmB,SAAS,MAAM,IAAI,SAAS,UAAU;AAC3D,YAAM,UAAU,OAAO,UAAU;AAEjC,UAAI,SAAS,WAAW,KAAK;AAC3B,cAAM,WACJ,OAAO,UAAU,aAAa,WAC1B,UAAU,WACV;AACN,cAAM,WAAW,UAAU;AAC3B,cAAM,YAAY,UAAU;AAC5B,cAAM,SACJ,OAAO,aAAa,YAAY,OAAO,cAAc,WACjD,UAAU,QAAQ,UAAU,aAAa,IAAI,KAAK,GAAG,KAAK,SAAS,gBACnE;AACN,cAAM,IAAI;AAAA,UACR,iDAAiD,MAAM,oCAAoC,QAAQ;AAAA,WAAyD,OAAO;AAAA,QACrK;AAAA,MACF;AACA,UAAI,SAAS,WAAW,KAAK;AAC3B,cAAM,IAAI;AAAA,UACR,KAAK,WACD,2HACA;AAAA,QACN;AAAA,MACF;AACA,UAAI,SAAS,WAAW,KAAK;AAC3B,cAAM,IAAI,MAAM,sCAAsC,OAAO,EAAE;AAAA,MACjE;AACA,YAAM,IAAI,MAAM,mBAAmB,SAAS,MAAM,KAAK,OAAO,EAAE;AAAA,IAClE;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO,CAAC;AAAA,IACV;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAc,QAM+D;AACjF,UAAM,QAAQ,IAAI,gBAAgB;AAClC,UAAM,IAAI,UAAU,WAAW;AAC/B,QAAI,QAAQ,SAAU,OAAM,IAAI,YAAY,OAAO,QAAQ;AAC3D,QAAI,QAAQ,YAAa,OAAM,IAAI,eAAe,OAAO,WAAW;AACpE,QAAI,QAAQ,OAAQ,OAAM,IAAI,UAAU,OAAO,MAAM;AACrD,QAAI,QAAQ,MAAO,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAC1D,QAAI,QAAQ,KAAM,OAAM,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AAEvD,UAAM,SAAS,MAAM,KAAK,QAA4B,cAAc,MAAM,SAAS,CAAC,EAAE;AACtF,UAAM,OAAO,SAAS,QAAQ,QAAQ,MAAM;AAC5C,UAAM,QAAS,MAAM,QAAQ,KAAK,SAAS,IAAI,KAAK,YAAY,CAAC;AACjE,UAAM,OAAO,SAAS,KAAK,IAAI;AAC/B,UAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,MAAM;AAClE,UAAM,aAAa,MAAM,QAAQ,KAAK,UAAU,IAC3C,KAAK,WAAyB,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAC/E,CAAC;AACL,WAAO,EAAE,OAAO,OAAO,WAAW;AAAA,EACpC;AAAA,EAEA,MAAM,YAAY,YAAkD;AAClE,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,cAAc,mBAAmB,UAAU,CAAC;AAAA,IAC9C;AACA,WAAQ,KAAK,QAAQ;AAAA,EACvB;AAAA;AAAA,EAGA,OAAO,gBAAgB,UAA+B;AACpD,UAAM,OAAO,SAAS,gBAAgB;AACtC,UAAM,eAAe,MAAM,gBAAgB,CAAC;AAC5C,UAAM,QAAQ,SAAS,cAAc,MAAM,cAAc;AACzD,WAAO;AAAA,MACL,SAAS,aAAa,WAAW;AAAA,MACjC,aAAa,aAAa,gBAAgB,eAAe,CAAC;AAAA,MAC1D,OAAO,aAAa,gBAAgB,SAAS,CAAC;AAAA,MAC9C,MAAM,aAAa,kBAAkB,QAAQ;AAAA,MAC7C,oBAAoB,aAAa,kBAAkB,sBAAsB;AAAA,MACzE,IAAI,OAAO,MAAM,CAAC;AAAA,MAClB,MAAM,OAAO,QAAQ,CAAC;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,sBAAsB,UAAoD;AAC/E,UAAM,YAAY,SAAS,SAAS,SAAS;AAC7C,UAAM,YAAY,MAAM,QAAQ,SAAS,MAAM,IAAI,SAAS,SAAS,CAAC;AACtE,UAAM,cAAwB,CAAC;AAC/B,eAAW,OAAO,WAAW;AAC3B,YAAM,MAAM,SAAS,GAAG,EAAE;AAC1B,UAAI,OAAO,QAAQ,YAAY,OAAO,CAAC,YAAY,SAAS,GAAG,EAAG,aAAY,KAAK,GAAG;AAAA,IACxF;AACA,eAAW,OAAO,OAAO,KAAK,SAAS,GAAG;AACxC,UAAI,CAAC,YAAY,SAAS,GAAG,EAAG,aAAY,KAAK,GAAG;AAAA,IACtD;AAEA,UAAM,SAA8B,CAAC;AACrC,eAAW,OAAO,aAAa;AAC7B,UAAI,IAAI,WAAW,MAAM,EAAG;AAC5B,YAAM,OAAO,SAAS,UAAU,GAAG,CAAC;AACpC,UAAI,KAAK,WAAW,QAAQ,KAAK,gBAAgB,KAAM;AACvD,YAAM,UAAU,SAAS,KAAK,OAAO;AACrC,YAAM,UAAU,MAAM,QAAQ,QAAQ,OAAO,IACxC,QAAQ,QAAsB,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAC/E,CAAC;AACL,YAAM,aAAa,SAAS,KAAK,UAAU;AAC3C,YAAM,WAAW,SAAS,UAAU,KAAK,CAAC,QAAQ,SAAS,GAAG,EAAE,QAAQ,GAAG,CAAC;AAC5E,aAAO,KAAK;AAAA,QACV;AAAA,QACA,OAAO,OAAO,KAAK,cAAc,KAAK,SAAS,SAAS,SAAS,GAAG;AAAA,QACpE,MAAM,OAAO,KAAK,QAAQ,SAAS,QAAQ,MAAM,EAAE,YAAY;AAAA,QAC/D,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAAA,QAClD,aAAa,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;AAAA,QACvE,QAAQ,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAAA,QACxD,UAAU,KAAK,aAAa;AAAA,QAC5B,cAAc,KAAK,gBAAgB,SAAS,gBAAgB;AAAA,QAC5D,GAAI,QAAQ,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,QACpC,GAAI,OAAO,KAAK,UAAU,EAAE,SAAS,EAAE,WAAW,IAAI,CAAC;AAAA,MACzD,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAc,MAIK;AACvB,UAAM,MAAM,MAAM,KAAK,QAAgC,aAAa;AAAA,MAClE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,WAAQ,KAAK,QAAQ;AAAA,EACvB;AAAA,EAEA,MAAM,WAAW,WAAqD;AACpE,UAAM,MAAM,MAAM,KAAK,QAA4B,aAAa,mBAAmB,SAAS,CAAC,EAAE;AAC/F,UAAM,OAAO,SAAS,KAAK,QAAQ,GAAG;AACtC,WAAQ,SAAS,KAAK,OAAO,KAAiC,OAAO,KAAK,SAAS,KAAK,OAAO,CAAC,EAAE,SAC9F,SAAS,KAAK,OAAO,IACrB;AAAA,EACN;AAAA;AAAA,EAGA,MAAM,eACJ,WACA,SAM4B;AAC5B,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAU,WAAW,CAAC,CAAC,EAAE;AAAA,IACxD;AACA,WAAQ,KAAK,QAAQ;AAAA,EACvB;AAAA,EAEA,MAAM,iBAAiB,WAA+C;AACpE,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,aAAa,mBAAmB,SAAS,CAAC;AAAA,IAC5C;AACA,WAAQ,KAAK,QAAQ;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eACJ,WACA,aACA,iBAAiB,KACW;AAC5B,UAAM,WAAW,KAAK,IAAI,IAAI,cAAc;AAC5C,QAAI,SAAS,MAAM,KAAK,iBAAiB,SAAS;AAClD,WACE,KAAK,IAAI,IAAI,aACZ,OAAO,UAAU,eAAe,OAAO,UAAU,cAClD;AACA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,cAAc,CAAC;AAClE,eAAS,MAAM,KAAK,iBAAiB,SAAS;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,UAA6C;AACjE,UAAM,MAAM,MAAM,KAAK,QAA4B,YAAY,mBAAmB,QAAQ,CAAC,EAAE;AAC7F,UAAM,OAAO,SAAS,KAAK,QAAQ,GAAG;AACtC,WAAQ,OAAO,KAAK,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,KAAK,SAAS;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAsC;AAC1C,QAAI;AACF,YAAM,KAAK,QAAiB,kBAAkB;AAC9C,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAI,IAAI,WAAW,MAAM,EAAG,QAAO;AAEnC,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,aAAyC;AAC7C,UAAM,MAAM,MAAM,KAAK,QAAsC,kBAAkB;AAC/E,WAAQ,KAAK,QAAQ;AAAA,EACvB;AAAA,EAEA,MAAM,mBAAmB,MAMY;AACnC,UAAM,MAAM,MAAM,KAAK,QAA4B,wBAAwB;AAAA,MACzE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,UAAM,UAAU,SAAS,KAAK,QAAQ,GAAG;AACzC,WAAO,OAAO,KAAK,SAAS,QAAQ,KAAK,CAAC,EAAE,SAAS,SAAS,QAAQ,KAAK,IAAI;AAAA,EACjF;AAAA;AAAA,EAGA,MAAM,aACJ,WACA,SACA,MACkC;AAClC,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,aAAa,mBAAmB,SAAS,CAAC,WAAW,mBAAmB,OAAO,CAAC;AAAA,MAChF,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAU,IAAI,EAAE;AAAA,IAC/C;AACA,WAAO,SAAS,KAAK,QAAQ,GAAG;AAAA,EAClC;AAAA;AAAA,EAGA,MAAM,wBACJ,WACA,SACA,MACkC;AAClC,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,aAAa,mBAAmB,SAAS,CAAC,WAAW,mBAAmB,OAAO,CAAC;AAAA,MAChF,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAU,IAAI,EAAE;AAAA,IAC/C;AACA,WAAO,SAAS,KAAK,QAAQ,GAAG;AAAA,EAClC;AAAA,EAEA,MAAM,oBAAoB,WAA4D;AACpF,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,aAAa,mBAAmB,SAAS,CAAC;AAAA,IAC5C;AACA,UAAM,OAAO,SAAS,KAAK,QAAQ,GAAG;AACtC,WAAO,MAAM,QAAQ,KAAK,MAAM,IAAK,KAAK,SAA4C,CAAC;AAAA,EACzF;AAAA,EAEA,MAAM,aAAa,MAIkB;AACnC,UAAM,MAAM,MAAM,KAAK,QAA4B,mBAAmB;AAAA,MACpE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,WAAO,SAAS,KAAK,QAAQ,GAAG;AAAA,EAClC;AACF;;;AC3WO,IAAM,oBAAoB;AAAA,EAC/B,SACE;AAAA,EACF,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,mBAAmB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,cAAc,CAAC,QAAQ,OAAO;AAAA,IAC9B,qBAAqB;AAAA,IACrB,SAAS,EAAE,oBAAoB,IAAI,eAAe,GAAG,qBAAqB,EAAE;AAAA,IAC5E,SAAS,EAAE,aAAa,GAAG,YAAY,GAAG,aAAa,GAAG,UAAU,GAAG,iBAAiB,GAAG,YAAY,EAAE;AAAA,EAC3G;AACF;AAEO,SAAS,0BAA0B;AACxC,QAAM,IAAI;AACV,SAAO;AAAA,IACL,EAAE;AAAA,IACF;AAAA,IACA,eAAe,EAAE,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,EAAE,KAAK,IAAI;AAAA,IAC3D;AAAA,IACA,kBAAkB,EAAE,SAAS,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,EAAE,KAAK,IAAI;AAAA,IACjE;AAAA,IACA;AAAA,IACA;AAAA,IACA,yDAAyD,EAAE,kBAAkB,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAAA,IAC3G;AAAA,IACA,uBAAuB,EAAE,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAAA,IAClE;AAAA,IACA,iBAAiB,EAAE,UAAU,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAAA,IAC3D;AAAA,IACA,eAAe,EAAE,SAAS,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,EAAE,KAAK,IAAI;AAAA,EAChE,EAAE,KAAK,IAAI;AACb;;;ACjFA,SAAS,SAAS;;;ACKX,IAAM,qBAAqB,CAAC,QAAQ,OAAO;;;ADDlD,IAAM,QAAQ,CAAC,QAAQ,WAAW,YAAY,SAAS,OAAO,YAAY;AAC1E,IAAM,eAAuD,EAAE,MAAM,QAAQ,OAAO,QAAQ,OAAO,OAAO,OAAO,YAAY,SAAS,WAAW;AAGjJ,SAAS,cAAc,UAA+E,SAAmB;AACvH,MAAI,SAAS,WAAY,QAAO,EAAE,gBAAgB,SAAS,WAAW,YAAY,WAAW,SAAS,WAAW,UAAU;AAC3H,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,SAAS;AACzB,UAAM,MAAM,IAAI,YAAY,EAAE,KAAK;AACnC,UAAM,OAAQ,MAA4B,SAAS,GAAG,IAAI,MAAM,aAAa,GAAG;AAChF,QAAI,KAAM,MAAK,IAAI,IAAI;AAAA,EACzB;AACA,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AACjD,SAAO,EAAE,gBAAgB,UAAU,CAAC,KAAK,MAAM,UAAU;AAC3D;AAEA,SAAS,YAAY,QAAgB,KAAc;AACjD,QAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,MAAM,KAAK,GAAG,GAAG,CAAC;AAAA,EAChE;AACF;AAEO,SAAS,sBAAsB,QAAmB,QAAuB;AAE9E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV;AAAA,MACE,UAAU,EACP,OAAO,EACP,SAAS,EACT,SAAS,uEAAuE;AAAA,MACnF,aAAa,EACV,KAAK,kBAAkB,EACvB,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,QAAQ,EACL,OAAO,EACP,SAAS,EACT,SAAS,gEAAgE;AAAA,MAC5E,OAAO,EACJ,OAAO,EACP,IAAI,CAAC,EACL,IAAI,EAAE,EACN,SAAS,EACT,QAAQ,EAAE,EACV,SAAS,oDAAoD;AAAA,MAChE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,IACtF;AAAA,IACA,EAAE,OAAO,wBAAwB,cAAc,KAAK;AAAA,IACpD,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,cAAc,IAAI;AAC9C,cAAM,mBAAmB,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,sBAAsB,IAAI;AAChF,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK;AAAA,gBACT;AAAA,kBACE,yBAAyB,OAAO;AAAA,kBAChC,UAAU,OAAO,MAAM;AAAA,kBACvB,iBAAiB,iBAAiB;AAAA,kBAClC,YAAY,OAAO;AAAA,kBACnB,SAAS,OAAO;AAAA,kBAChB,WAAW,OAAO,MAAM,IAAI,CAAC,MAAM;AACjC,0BAAM,WAAW,cAAc,gBAAgB,CAAC;AAChD,2BAAO;AAAA,sBACL,IAAI,EAAE;AAAA,sBACN,MAAM,EAAE;AAAA,sBACR,MAAM,EAAE,eAAe,EAAE;AAAA,sBACzB,aAAa,EAAE,iBAAiB,EAAE,eAAe;AAAA,sBACjD,SAAS,SAAS;AAAA,sBAClB,GAAG,cAAc,GAAG,SAAS,WAAW;AAAA,sBACxC,iBAAiB,EAAE,YACf,GAAG,EAAE,UAAU,QAAQ,YAAY,EAAE,UAAU,QAAQ,cAAc,EAAE,UAAU,WAAW,GAAG,MAC/F;AAAA,sBACJ,gBAAgB,EAAE,kBAAkB;AAAA,sBACpC,OAAO,SAAS;AAAA,sBAChB,MAAM,SAAS;AAAA,sBACf,UAAU,EAAE,YAAY;AAAA,sBACxB,aAAa,EAAE;AAAA,sBACf,iBAAiB,EAAE,mBAAmB;AAAA,sBACtC,mBAAmB,EAAE,sBAAsB;AAAA,sBAC3C,MAAM,EAAE,QAAQ,CAAC;AAAA,sBACjB,iBAAiB,EAAE,cAAc;AAAA,sBACjC,cAAc,EAAE,gBAAgB;AAAA,oBAClC;AAAA,kBACF,CAAC;AAAA,kBACD,MACE;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,eAAO,YAAY,2BAA2B,GAAG;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV;AAAA,MACE,YAAY,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,IACvD;AAAA,IACA,EAAE,OAAO,uBAAuB,cAAc,KAAK;AAAA,IACnD,OAAO,SAAS;AACd,UAAI;AACF,cAAM,WAAW,MAAM,OAAO,YAAY,KAAK,UAAU;AACzD,cAAM,iBAAiB,cAAc,sBAAsB,QAAQ;AACnE,cAAM,WAAW,cAAc,gBAAgB,QAAQ;AACvD,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK;AAAA,gBACT;AAAA,kBACE,IAAI,SAAS;AAAA,kBACb,MAAM,SAAS;AAAA,kBACf,MAAM,SAAS,eAAe,SAAS;AAAA,kBACvC,aAAa,SAAS,iBAAiB,SAAS,eAAe;AAAA,kBAC/D,UAAU,SAAS,YAAY;AAAA,kBAC/B,aAAa,SAAS;AAAA,kBACtB,iBAAiB,SAAS,mBAAmB;AAAA,kBAC7C,mBAAmB,SAAS,sBAAsB;AAAA,kBAClD,aAAa,SAAS,sBAAsB,OAAO,+FAA+F;AAAA,kBAClJ;AAAA,kBACA,GAAG,cAAc,UAAU,SAAS,WAAW;AAAA,kBAC/C,iBAAiB,SAAS,aAAa;AAAA,kBACvC,gBAAgB,SAAS,kBAAkB;AAAA,kBAC3C;AAAA,kBACA,OACE;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,eAAO,YAAY,kCAAkC,GAAG;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AACF;;;AEvKA,SAAS,KAAAA,UAAS;AAGlB,IAAM,iBAAiBA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,OAAO,GAAGA,GAAE,QAAQ,GAAGA,GAAE,KAAK,CAAC,CAAC;AAE9E,IAAM,cAAcA,GAAE,OAAO;AAAA,EAC3B,YAAYA,GAAE,OAAO,EAAE,SAAS,8CAA8C;AAAA,EAC9E,OAAOA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,EACrE,eAAeA,GACZ,OAAO,EACP,IAAI,GAAG,EACP,SAAS,EACT,SAAS,mFAAmF;AAAA,EAC/F,YAAYA,GACT,OAAOA,GAAE,OAAO,GAAG,cAAc,EACjC,SAAS,EACT,SAAS,8HAAyH;AACvI,CAAC;AAEM,SAAS,qBAAqB,QAAmB,QAAuB;AAE7E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV;AAAA,MACE,OAAOA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,MACzF,QAAQA,GACL,MAAM,WAAW,EACjB,IAAI,CAAC,EACL,IAAI,EAAE,EACN,SAAS,+DAA+D;AAAA,MAC3E,SAASA,GACN,OAAO,EACP,KAAK,EACL,SAAS,EACT,SAAS,wDAAwD;AAAA,IACtE;AAAA,IACA,EAAE,OAAO,uBAAuB;AAAA,IAChC,OAAO,SAAS;AACd,UAAI;AACF,cAAM,UAAU,MAAM,OAAO,cAAc,IAAI;AAC/C,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK;AAAA,gBACT;AAAA,kBACE,SAAS,wBAAwB,QAAQ,cAAc,QAAQ,QAAQ,UAAU,CAAC;AAAA,kBAClF,WAAW,QAAQ;AAAA,kBACnB,OAAO,QAAQ;AAAA,kBACf,QAAQ,QAAQ;AAAA,kBAChB,aAAa,QAAQ;AAAA,kBACrB,SAAS,QAAQ,YAAY;AAAA,kBAC7B,QAAQ,QAAQ,UAAU,CAAC;AAAA,kBAC3B,sBAAuB,QAA0D,wBAAwB,CAAC;AAAA,kBAC1G,UACE,QAAQ,YACR;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAWA,GAAE,OAAO,EAAE,SAAS,iBAAiB;AAAA,IAClD;AAAA,IACA,EAAE,OAAO,uBAAuB,cAAc,KAAK;AAAA,IACnD,OAAO,SAAS;AACd,UAAI;AACF,cAAM,UAAU,MAAM,OAAO,WAAW,KAAK,SAAS;AACtD,YAAI,kBAA6B,CAAC;AAClC,YAAI;AACF,4BAAmB,MAAM,OAAO,oBAAoB,KAAK,SAAS;AAAA,QACpE,QAAQ;AAAA,QAER;AACA,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK;AAAA,gBACT;AAAA,kBACE,GAAI;AAAA,kBACJ;AAAA,kBACA,UAAU,gBAAgB,SACtB,kGACA;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5HA,SAAS,KAAAC,UAAS;AAKlB,IAAM,uBAAuB;AAC7B,IAAM,mBAAmB;AAEzB,SAAS,oBAAoB,QAA2B,WAAmB;AACzE,QAAM,OAAO;AAAA,IACX;AAAA,IACA,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,IAChB,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO,SACX;AAAA,MACE,OAAO,OAAO,OAAO;AAAA,MACrB,iBAAiB,OAAO,OAAO;AAAA,MAC/B,YAAY,OAAO,OAAO;AAAA,MAC1B,YAAY,OAAO,OAAO;AAAA,MAC1B,cAAc,OAAO,OAAO;AAAA,MAC5B,UAAU,OAAO,OAAO;AAAA,IAC1B,IACA;AAAA,IACJ,QAAQ,OAAO,SACX;AAAA,MACE,IAAI,OAAO,OAAO;AAAA,MAClB,QAAQ,OAAO,OAAO;AAAA,MACtB,UAAU,OAAO,OAAO;AAAA,MACxB,aAAa,OAAO,OAAO;AAAA,MAC3B,SAAS,OAAO,OAAO;AAAA,MACvB,cAAc,OAAO,OAAO;AAAA,IAC9B,IACA;AAAA,EACN;AAEA,MAAI,OAAO,UAAU,aAAa;AAChC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,OAAO;AAAA,MACjB,cAAc,OAAO;AAAA,MACrB,iBAAiB,OAAO,QAAQ,mBAAmB;AAAA,MACnD,MAAM,OAAO,UACT,wHACA;AAAA,IACN;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,eAAe,OAAO,UAAU,aAAa;AAChE,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,SAAS,OAAO,KAAK,iDAAiD,SAAS;AAAA,IAC3F;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,oBAAoB,QAAmB,QAAuB;AAE5E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV;AAAA,MACE,WAAWA,GAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,MACpE,SAASA,GACN,KAAK,CAAC,QAAQ,SAAS,IAAI,CAAC,EAC5B,SAAS,EACT,QAAQ,OAAO,EACf,SAAS,iEAAiE;AAAA,MAC7E,cAAcA,GAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI,EAAE,SAAS,sBAAsB;AAAA,MAClF,kBAAkBA,GACf,QAAQ,EACR,SAAS,EACT,QAAQ,IAAI,EACZ,SAAS,4DAA4D;AAAA,MACxE,aAAaA,GACV,OAAO,EACP,IAAI,CAAC,EACL,IAAI,gBAAgB,EACpB,SAAS,EACT,QAAQ,oBAAoB,EAC5B,SAAS,6DAA6D,gBAAgB,aAAa,oBAAoB,GAAG;AAAA,IAC/H;AAAA,IACA,EAAE,OAAO,0BAA0B;AAAA,IACnC,OAAO,SAAS;AACd,UAAI;AACF,YAAI,SAAS,MAAM,OAAO,eAAe,KAAK,WAAW;AAAA,UACvD,SAAS,KAAK;AAAA,UACd,cAAc,KAAK;AAAA,UACnB,kBAAkB,KAAK;AAAA,QACzB,CAAC;AAED,YACE,KAAK,cAAc,MAClB,OAAO,UAAU,eAAe,OAAO,UAAU,cAClD;AACA,mBAAS,MAAM,OAAO,eAAe,KAAK,WAAW,KAAK,WAAW;AAAA,QACvE;AAEA,cAAM,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU;AAChE,eAAO;AAAA,UACL,GAAI,YAAY,EAAE,SAAS,KAAc,IAAI,CAAC;AAAA,UAC9C,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK,UAAU,oBAAoB,QAAQ,KAAK,SAAS,GAAG,MAAM,CAAC;AAAA,YAC3E;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV;AAAA,MACE,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,MAClE,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,MACzF,aAAaA,GACV,OAAO,EACP,IAAI,CAAC,EACL,IAAI,gBAAgB,EACpB,SAAS,EACT,QAAQ,CAAC,EACT,SAAS,sDAAsD,gBAAgB,GAAG;AAAA,IACvF;AAAA,IACA,EAAE,OAAO,uBAAuB,cAAc,KAAK;AAAA,IACnD,OAAO,SAAS;AACd,UAAI;AACF,YAAI,KAAK,WAAW;AAClB,gBAAM,SACJ,KAAK,cAAc,IACf,MAAM,OAAO,eAAe,KAAK,WAAW,KAAK,WAAW,IAC5D,MAAM,OAAO,iBAAiB,KAAK,SAAS;AAClD,gBAAM,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU;AAChE,iBAAO;AAAA,YACL,GAAI,YAAY,EAAE,SAAS,KAAc,IAAI,CAAC;AAAA,YAC9C,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK,UAAU,oBAAoB,QAAQ,KAAK,SAAS,GAAG,MAAM,CAAC;AAAA,cAC3E;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,YAAI,KAAK,UAAU;AACjB,gBAAM,SAAS,MAAM,OAAO,gBAAgB,KAAK,QAAQ;AACzD,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK;AAAA,kBACT;AAAA,oBACE,UAAU,OAAO;AAAA,oBACjB,WAAW,OAAO;AAAA,oBAClB,QAAQ,OAAO;AAAA,oBACf,UAAU,OAAO,YAAY;AAAA,oBAC7B,aAAa,OAAO,eAAe;AAAA,oBACnC,SAAS,OAAO,WAAW;AAAA,oBAC3B,SAAS,OAAO,YAAY;AAAA,oBAC5B,UAAU,OAAO,WAAW,YAAY,OAAO,aAAa,OAAO;AAAA,oBACnE,cAAc,OAAO,gBAAgB;AAAA,oBACrC,cAAc,OAAO,gBAAgB;AAAA,oBACrC,aAAa,OAAO,eAAe;AAAA,kBACrC;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,6CAA6C,CAAC;AAAA,QAChF;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,iCAAiC,GAAG,GAAG,CAAC;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC3MA,SAAS,KAAAC,UAAS;AAIX,SAAS,gBAAgB,QAAmB,QAAuB;AAExE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV,CAAC;AAAA,IACD,EAAE,OAAO,oBAAoB,cAAc,KAAK;AAAA,IAChD,aAAa;AAAA,MACX,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,GAAG,mBAAmB,YAAY,OAAO,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,IACnH;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV,CAAC;AAAA,IACD,EAAE,OAAO,wBAAwB,cAAc,KAAK;AAAA,IACpD,YAAY;AACV,UAAI;AACF,cAAM,UAAU,MAAM,OAAO,WAAW;AACxC,cAAM,YAAY,QAAQ,mBAAmB;AAC7C,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK;AAAA,gBACT;AAAA,kBACE,YAAY,OAAO;AAAA,kBACnB,MAAM,QAAQ;AAAA,kBACd,kBAAkB,QAAQ,UAAU;AAAA,kBACpC,gBAAgB,YAAY,cAAc,QAAQ;AAAA,kBAClD,OAAO,QAAQ;AAAA,kBACf,OAAO,QAAQ,MAAM,IAAI,CAAC,UAAU;AAAA,oBAClC,IAAI,KAAK;AAAA,oBACT,MAAM,KAAK;AAAA,oBACX,SAAS,KAAK;AAAA,oBACd,OAAO,KAAK,KAAK,aAAa,KAAK,QAAQ,CAAC,CAAC;AAAA,kBAC/C,EAAE;AAAA,kBACF,UAAU,QAAQ;AAAA,kBAClB,MAAM,OAAO,YACT,kHACA;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO,EAAE,SAAS,MAAM,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2BAA2B,GAAG,GAAG,CAAC,EAAE;AAAA,MAC9F;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV;AAAA,MACE,QAAQC,GACL,OAAO,EACP,SAAS,6GAA6G;AAAA,MACzH,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MACjE,UAAUA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MACnF,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qDAAqD;AAAA,MAChG,WAAWA,GACR,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,EAAE,EACN,SAAS,EACT,SAAS,gCAAgC;AAAA,IAC9C;AAAA,IACA,EAAE,OAAO,qBAAqB;AAAA,IAC9B,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,mBAAmB,IAAI;AACnD,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,QACnE;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,gCAAgC,GAAG,GAAG,CAAC;AAAA,QACzE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACvGA,SAAS,KAAAC,UAAS;AAUlB,SAAS,cAAc,OAAkB,SAAiB;AACxD,QAAM,gBAAgB,MAAM,OAAO;AACnC,MAAI,kBAAkB,OAAW,QAAO,MAAM;AAAA,EAAC;AAC/C,MAAI,OAAO;AACX,QAAM,OAAO,MAAM;AACjB,YAAQ;AACR,SAAK,MACF,iBAAiB,EAAE,QAAQ,0BAA0B,QAAQ,EAAE,eAAe,UAAU,MAAM,QAAQ,EAAE,CAAC,EACzG,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AACA,OAAK;AACL,QAAM,QAAQ,YAAY,MAAM,GAAI;AACpC,SAAO,MAAM,cAAc,KAAK;AAClC;AAEO,SAAS,oBAAoB,QAAmB,QAAuB;AAE5E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,IACV;AAAA,MACE,WAAWA,GAAE,OAAO,EAAE,SAAS,YAAY;AAAA,MAC3C,SAASA,GAAE,OAAO,EAAE,SAAS,8DAA8D;AAAA,MAC3F,KAAKA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,oDAAoD;AAAA,MACnF,OAAOA,GACJ,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EACxB,IAAI,CAAC,EACL,SAAS,EACT,SAAS,6EAA6E;AAAA,MACzF,WAAWA,GACR,MAAMA,GAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EACzB,IAAI,CAAC,EACL,SAAS,EACT,SAAS,iEAAiE;AAAA,MAC7E,YAAYA,GACT,QAAQ,EACR,SAAS,EACT,QAAQ,IAAI,EACZ,SAAS,0HAA0H;AAAA,IACxI;AAAA,IACA,EAAE,OAAO,8BAA8B;AAAA,IACvC,OAAO,MAAM,UAAU;AACrB,YAAM,eAAe,cAAc,OAAO,mEAA8D;AACxG,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,aAAa,KAAK,WAAW,KAAK,SAAS;AAAA,UACrE,KAAK,KAAK;AAAA,UACV,OAAO,KAAK;AAAA,UACZ,WAAW,KAAK;AAAA,UAChB,YAAY,KAAK;AAAA,QACnB,CAAC;AACD,cAAM,QAAQ,OAAO,gBAAgB;AACrC,cAAM,qBAAqB,KAAK,eAAe;AAC/C,eAAO;AAAA,UACL,GAAI,SAAS,qBAAqB,CAAC,IAAI,EAAE,SAAS,KAAc;AAAA,UAChE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,QACnE;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO,EAAE,SAAS,MAAM,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,0BAA0B,GAAG,GAAG,CAAC,EAAE;AAAA,MAC7F,UAAE;AACA,qBAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAWA,GAAE,OAAO;AAAA,MACpB,SAASA,GAAE,OAAO;AAAA,MAClB,WAAWA,GAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,MAClE,sBAAsBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,iFAAiF;AAAA,IACpJ;AAAA,IACA,EAAE,OAAO,6BAA6B;AAAA,IACtC,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,wBAAwB,KAAK,WAAW,KAAK,SAAS;AAAA,UAChF,WAAW,KAAK;AAAA,UAChB,sBAAsB,KAAK;AAAA,QAC7B,CAAC;AACD,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO,EAAE,SAAS,MAAM,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,+BAA+B,GAAG,GAAG,CAAC,EAAE;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,KAAKA,GACF,OAAO,EACP,IAAI,EACJ,SAAS,wDAAwD;AAAA,MACpE,UAAUA,GACP,OAAO,EACP,SAAS,EACT,SAAS,oEAAoE;AAAA,MAChF,UAAUA,GACP,KAAK,CAAC,WAAW,UAAU,QAAQ,CAAC,EACpC,SAAS,EACT,QAAQ,SAAS,EACjB,SAAS,wFAAwF;AAAA,IACtG;AAAA,IACA,EAAE,OAAO,qBAAqB;AAAA,IAC9B,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,aAAa,IAAI;AAC7C,eAAO;AAAA,UACL,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,YACtC;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,KAAc;AACrB,cAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAO;AAAA,UACL,SAAS;AAAA,UACT,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5IO,SAAS,iBAAiB,QAAmB,QAAuB;AACzE,wBAAsB,QAAQ,MAAM;AACpC,uBAAqB,QAAQ,MAAM;AACnC,sBAAoB,QAAQ,MAAM;AAClC,kBAAgB,QAAQ,MAAM;AAC9B,sBAAoB,QAAQ,MAAM;AACpC;;;ACTO,IAAM,aAAa;AACnB,IAAM,gBAAgB;AACtB,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAE5B,SAAS,YAAY,SAAiB;AAC3C,QAAM,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AACvC,SAAO;AAAA,IACL,EAAE,KAAK,GAAG,IAAI,aAAa,UAAU,aAAa,OAAO,CAAC,SAAS,EAAE;AAAA,IACrE,EAAE,KAAK,GAAG,IAAI,gBAAgB,UAAU,aAAa,OAAO,CAAC,SAAS,EAAE;AAAA,EAC1E;AACF;","names":["z","z","z","z","z"]}
|
package/dist/http.d.ts
ADDED
package/dist/http.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
BRAND_NAME,
|
|
4
|
+
BRAND_WEBSITE,
|
|
5
|
+
ICON_PNG_128_BASE64,
|
|
6
|
+
ICON_PNG_512_BASE64,
|
|
7
|
+
WeviApiClient,
|
|
8
|
+
buildServerInstructions,
|
|
9
|
+
registerAllTools,
|
|
10
|
+
serverIcons
|
|
11
|
+
} from "./chunk-IDFFE3P7.js";
|
|
12
|
+
|
|
13
|
+
// src/http.ts
|
|
14
|
+
import { createServer } from "http";
|
|
15
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
16
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
17
|
+
import dotenv from "dotenv";
|
|
18
|
+
var ICON_512 = Buffer.from(ICON_PNG_512_BASE64, "base64");
|
|
19
|
+
var ICON_128 = Buffer.from(ICON_PNG_128_BASE64, "base64");
|
|
20
|
+
dotenv.config();
|
|
21
|
+
var PORT = Number(process.env.PORT ?? 8080);
|
|
22
|
+
var API_URL = (process.env.WEVI_API_URL || "https://api-v2.wevi.ai/api/v2").replace(/\/+$/, "");
|
|
23
|
+
var PUBLIC_URL = (process.env.MCP_PUBLIC_URL || `http://localhost:${PORT}`).replace(/\/+$/, "");
|
|
24
|
+
var ISSUER = (process.env.OAUTH_ISSUER || new URL(API_URL).origin).replace(/\/+$/, "");
|
|
25
|
+
var MCP_PATH = "/mcp";
|
|
26
|
+
var SERVER_VERSION = "0.2.1";
|
|
27
|
+
var CORS_HEADERS = {
|
|
28
|
+
"Access-Control-Allow-Origin": "*",
|
|
29
|
+
"Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
|
|
30
|
+
"Access-Control-Allow-Headers": "Authorization, Content-Type, Accept, Mcp-Session-Id, Mcp-Protocol-Version",
|
|
31
|
+
"Access-Control-Expose-Headers": "Mcp-Session-Id, WWW-Authenticate",
|
|
32
|
+
"Access-Control-Max-Age": "86400"
|
|
33
|
+
};
|
|
34
|
+
function sendJson(res, status, body, extra = {}) {
|
|
35
|
+
res.writeHead(status, { "Content-Type": "application/json", ...CORS_HEADERS, ...extra });
|
|
36
|
+
res.end(JSON.stringify(body));
|
|
37
|
+
}
|
|
38
|
+
function protectedResourceMetadata() {
|
|
39
|
+
return {
|
|
40
|
+
resource: `${PUBLIC_URL}${MCP_PATH}`,
|
|
41
|
+
authorization_servers: [ISSUER],
|
|
42
|
+
bearer_methods_supported: ["header"],
|
|
43
|
+
scopes_supported: ["wevi"],
|
|
44
|
+
resource_name: "Wevi",
|
|
45
|
+
resource_documentation: "https://docs.wevi.ai/docs/connectors"
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function unauthorized(res, description) {
|
|
49
|
+
const metadataUrl = `${PUBLIC_URL}/.well-known/oauth-protected-resource`;
|
|
50
|
+
sendJson(
|
|
51
|
+
res,
|
|
52
|
+
401,
|
|
53
|
+
{ error: "unauthorized", error_description: description },
|
|
54
|
+
{ "WWW-Authenticate": `Bearer realm="wevi", resource_metadata="${metadataUrl}", error="invalid_token", error_description="${description}"` }
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
async function readJsonBody(req) {
|
|
58
|
+
const chunks = [];
|
|
59
|
+
for await (const chunk of req) chunks.push(chunk);
|
|
60
|
+
if (chunks.length === 0) return void 0;
|
|
61
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
62
|
+
if (!raw.trim()) return void 0;
|
|
63
|
+
return JSON.parse(raw);
|
|
64
|
+
}
|
|
65
|
+
function extractBearer(req) {
|
|
66
|
+
const header = req.headers.authorization;
|
|
67
|
+
if (!header || Array.isArray(header)) return null;
|
|
68
|
+
const [scheme, token] = header.split(" ");
|
|
69
|
+
if (scheme?.toLowerCase() !== "bearer" || !token?.trim()) return null;
|
|
70
|
+
return token.trim();
|
|
71
|
+
}
|
|
72
|
+
var tokenCache = /* @__PURE__ */ new Map();
|
|
73
|
+
var TOKEN_CACHE_TTL_MS = 6e4;
|
|
74
|
+
async function isTokenValid(token, client) {
|
|
75
|
+
const cached = tokenCache.get(token);
|
|
76
|
+
if (cached && cached.expiresAt > Date.now()) return cached.ok;
|
|
77
|
+
const ok = await client.verifyCredentials();
|
|
78
|
+
tokenCache.set(token, { ok, expiresAt: Date.now() + (ok ? TOKEN_CACHE_TTL_MS : 5e3) });
|
|
79
|
+
if (tokenCache.size > 5e3) {
|
|
80
|
+
for (const [key, entry] of tokenCache) if (entry.expiresAt <= Date.now()) tokenCache.delete(key);
|
|
81
|
+
}
|
|
82
|
+
return ok;
|
|
83
|
+
}
|
|
84
|
+
async function handleMcp(req, res) {
|
|
85
|
+
const token = extractBearer(req);
|
|
86
|
+
if (!token) {
|
|
87
|
+
unauthorized(res, "Sign in to Wevi to use this connector.");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const client = new WeviApiClient({ apiKey: token, apiUrl: API_URL });
|
|
91
|
+
if (!await isTokenValid(token, client)) {
|
|
92
|
+
unauthorized(res, "Your Wevi connection has expired or was disconnected. Reconnect to continue.");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const server = new McpServer(
|
|
96
|
+
{
|
|
97
|
+
name: "Wevi",
|
|
98
|
+
title: BRAND_NAME,
|
|
99
|
+
version: SERVER_VERSION,
|
|
100
|
+
websiteUrl: BRAND_WEBSITE,
|
|
101
|
+
icons: serverIcons(PUBLIC_URL)
|
|
102
|
+
},
|
|
103
|
+
{ instructions: buildServerInstructions() }
|
|
104
|
+
);
|
|
105
|
+
registerAllTools(server, client);
|
|
106
|
+
const transport = new StreamableHTTPServerTransport({
|
|
107
|
+
sessionIdGenerator: void 0,
|
|
108
|
+
// stateless
|
|
109
|
+
enableJsonResponse: false
|
|
110
|
+
});
|
|
111
|
+
res.on("close", () => {
|
|
112
|
+
void transport.close();
|
|
113
|
+
void server.close();
|
|
114
|
+
});
|
|
115
|
+
for (const [key, value] of Object.entries(CORS_HEADERS)) res.setHeader(key, value);
|
|
116
|
+
try {
|
|
117
|
+
await server.connect(transport);
|
|
118
|
+
const body = req.method === "POST" ? await readJsonBody(req) : void 0;
|
|
119
|
+
await transport.handleRequest(req, res, body);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
122
|
+
process.stderr.write(`[Wevi MCP HTTP] request failed: ${message}
|
|
123
|
+
`);
|
|
124
|
+
if (!res.headersSent) {
|
|
125
|
+
sendJson(res, 500, { jsonrpc: "2.0", error: { code: -32603, message: "Internal server error" }, id: null });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
var httpServer = createServer(async (req, res) => {
|
|
130
|
+
const url = new URL(req.url ?? "/", PUBLIC_URL);
|
|
131
|
+
const path = url.pathname.replace(/\/+$/, "") || "/";
|
|
132
|
+
if (req.method === "OPTIONS") {
|
|
133
|
+
res.writeHead(204, CORS_HEADERS);
|
|
134
|
+
res.end();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (path === "/health" || path === "/") {
|
|
138
|
+
sendJson(res, 200, { status: "ok", name: "wevi-mcp", version: SERVER_VERSION, transport: "streamable-http", endpoint: `${PUBLIC_URL}${MCP_PATH}` });
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (path === "/icon.png" || path === "/apple-touch-icon.png") {
|
|
142
|
+
res.writeHead(200, { "Content-Type": "image/png", "Cache-Control": "public, max-age=86400", ...CORS_HEADERS });
|
|
143
|
+
res.end(ICON_512);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (path === "/favicon.png" || path === "/favicon.ico") {
|
|
147
|
+
res.writeHead(200, { "Content-Type": "image/png", "Cache-Control": "public, max-age=86400", ...CORS_HEADERS });
|
|
148
|
+
res.end(ICON_128);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (path === "/.well-known/oauth-protected-resource" || path === `/.well-known/oauth-protected-resource${MCP_PATH}`) {
|
|
152
|
+
sendJson(res, 200, protectedResourceMetadata(), { "Cache-Control": "public, max-age=300" });
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (path === MCP_PATH) {
|
|
156
|
+
if (req.method === "POST" || req.method === "GET" || req.method === "DELETE") {
|
|
157
|
+
await handleMcp(req, res);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
sendJson(res, 405, { error: "method_not_allowed" }, { Allow: "GET, POST, DELETE, OPTIONS" });
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
sendJson(res, 404, { error: "not_found" });
|
|
164
|
+
});
|
|
165
|
+
httpServer.listen(PORT, () => {
|
|
166
|
+
process.stderr.write(
|
|
167
|
+
`[Wevi MCP HTTP] listening on :${PORT} \u2192 ${PUBLIC_URL}${MCP_PATH} (API ${API_URL}, issuer ${ISSUER})
|
|
168
|
+
`
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/http.ts"],"sourcesContent":["/**\n * Remote MCP server (Streamable HTTP) for Claude connectors, ChatGPT apps and\n * any client that speaks MCP over HTTPS. Stateless: every request builds a\n * server with the caller's bearer token and tears it down afterwards.\n *\n * Auth: callers send `Authorization: Bearer <token>` where the token is either\n * an OAuth access token issued by Wevi (connectors) or a Wevi API key.\n * Unauthenticated requests get 401 + WWW-Authenticate pointing at the\n * protected-resource metadata, which is how MCP clients discover OAuth.\n *\n * Env: PORT (8080), WEVI_API_URL, MCP_PUBLIC_URL (https://mcp.wevi.ai),\n * OAUTH_ISSUER (defaults to the origin of WEVI_API_URL).\n */\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport dotenv from \"dotenv\";\nimport { WeviApiClient } from \"./client/wevi-api-client.js\";\nimport { registerAllTools } from \"./tools/index.js\";\nimport { buildServerInstructions } from \"./capabilities.js\";\nimport { BRAND_NAME, BRAND_WEBSITE, ICON_PNG_128_BASE64, ICON_PNG_512_BASE64, serverIcons } from \"./brand.js\";\n\nconst ICON_512 = Buffer.from(ICON_PNG_512_BASE64, \"base64\");\nconst ICON_128 = Buffer.from(ICON_PNG_128_BASE64, \"base64\");\n\ndotenv.config();\n\nconst PORT = Number(process.env.PORT ?? 8080);\nconst API_URL = (process.env.WEVI_API_URL || \"https://api-v2.wevi.ai/api/v2\").replace(/\\/+$/, \"\");\nconst PUBLIC_URL = (process.env.MCP_PUBLIC_URL || `http://localhost:${PORT}`).replace(/\\/+$/, \"\");\nconst ISSUER = (process.env.OAUTH_ISSUER || new URL(API_URL).origin).replace(/\\/+$/, \"\");\nconst MCP_PATH = \"/mcp\";\nconst SERVER_VERSION = \"0.2.1\";\n\nconst CORS_HEADERS: Record<string, string> = {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, DELETE, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Authorization, Content-Type, Accept, Mcp-Session-Id, Mcp-Protocol-Version\",\n \"Access-Control-Expose-Headers\": \"Mcp-Session-Id, WWW-Authenticate\",\n \"Access-Control-Max-Age\": \"86400\",\n};\n\nfunction sendJson(res: ServerResponse, status: number, body: unknown, extra: Record<string, string> = {}) {\n res.writeHead(status, { \"Content-Type\": \"application/json\", ...CORS_HEADERS, ...extra });\n res.end(JSON.stringify(body));\n}\n\nfunction protectedResourceMetadata() {\n return {\n resource: `${PUBLIC_URL}${MCP_PATH}`,\n authorization_servers: [ISSUER],\n bearer_methods_supported: [\"header\"],\n scopes_supported: [\"wevi\"],\n resource_name: \"Wevi\",\n resource_documentation: \"https://docs.wevi.ai/docs/connectors\",\n };\n}\n\nfunction unauthorized(res: ServerResponse, description: string) {\n const metadataUrl = `${PUBLIC_URL}/.well-known/oauth-protected-resource`;\n sendJson(\n res,\n 401,\n { error: \"unauthorized\", error_description: description },\n { \"WWW-Authenticate\": `Bearer realm=\"wevi\", resource_metadata=\"${metadataUrl}\", error=\"invalid_token\", error_description=\"${description}\"` },\n );\n}\n\nasync function readJsonBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n if (chunks.length === 0) return undefined;\n const raw = Buffer.concat(chunks).toString(\"utf8\");\n if (!raw.trim()) return undefined;\n return JSON.parse(raw);\n}\n\nfunction extractBearer(req: IncomingMessage): string | null {\n const header = req.headers.authorization;\n if (!header || Array.isArray(header)) return null;\n const [scheme, token] = header.split(\" \");\n if (scheme?.toLowerCase() !== \"bearer\" || !token?.trim()) return null;\n return token.trim();\n}\n\n/** Short-lived cache so a busy session does not re-verify on every request. */\nconst tokenCache = new Map<string, { ok: boolean; expiresAt: number }>();\nconst TOKEN_CACHE_TTL_MS = 60_000;\n\nasync function isTokenValid(token: string, client: WeviApiClient): Promise<boolean> {\n const cached = tokenCache.get(token);\n if (cached && cached.expiresAt > Date.now()) return cached.ok;\n const ok = await client.verifyCredentials();\n tokenCache.set(token, { ok, expiresAt: Date.now() + (ok ? TOKEN_CACHE_TTL_MS : 5_000) });\n if (tokenCache.size > 5_000) {\n for (const [key, entry] of tokenCache) if (entry.expiresAt <= Date.now()) tokenCache.delete(key);\n }\n return ok;\n}\n\nasync function handleMcp(req: IncomingMessage, res: ServerResponse) {\n const token = extractBearer(req);\n if (!token) {\n unauthorized(res, \"Sign in to Wevi to use this connector.\");\n return;\n }\n\n const client = new WeviApiClient({ apiKey: token, apiUrl: API_URL });\n\n // Reject expired or revoked credentials up front with a proper challenge so\n // OAuth clients refresh or re-authorize instead of seeing failing tool calls.\n if (!(await isTokenValid(token, client))) {\n unauthorized(res, \"Your Wevi connection has expired or was disconnected. Reconnect to continue.\");\n return;\n }\n\n const server = new McpServer(\n {\n name: \"Wevi\",\n title: BRAND_NAME,\n version: SERVER_VERSION,\n websiteUrl: BRAND_WEBSITE,\n icons: serverIcons(PUBLIC_URL),\n },\n { instructions: buildServerInstructions() },\n );\n registerAllTools(server, client);\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // stateless\n enableJsonResponse: false,\n });\n\n res.on(\"close\", () => {\n void transport.close();\n void server.close();\n });\n\n for (const [key, value] of Object.entries(CORS_HEADERS)) res.setHeader(key, value);\n\n try {\n await server.connect(transport);\n const body = req.method === \"POST\" ? await readJsonBody(req) : undefined;\n await transport.handleRequest(req, res, body);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`[Wevi MCP HTTP] request failed: ${message}\\n`);\n if (!res.headersSent) {\n sendJson(res, 500, { jsonrpc: \"2.0\", error: { code: -32603, message: \"Internal server error\" }, id: null });\n }\n }\n}\n\nconst httpServer = createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", PUBLIC_URL);\n const path = url.pathname.replace(/\\/+$/, \"\") || \"/\";\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(204, CORS_HEADERS);\n res.end();\n return;\n }\n\n if (path === \"/health\" || path === \"/\") {\n sendJson(res, 200, { status: \"ok\", name: \"wevi-mcp\", version: SERVER_VERSION, transport: \"streamable-http\", endpoint: `${PUBLIC_URL}${MCP_PATH}` });\n return;\n }\n\n // Brand assets: connector UIs fetch a favicon from the server origin.\n if (path === \"/icon.png\" || path === \"/apple-touch-icon.png\") {\n res.writeHead(200, { \"Content-Type\": \"image/png\", \"Cache-Control\": \"public, max-age=86400\", ...CORS_HEADERS });\n res.end(ICON_512);\n return;\n }\n if (path === \"/favicon.png\" || path === \"/favicon.ico\") {\n res.writeHead(200, { \"Content-Type\": \"image/png\", \"Cache-Control\": \"public, max-age=86400\", ...CORS_HEADERS });\n res.end(ICON_128);\n return;\n }\n\n // RFC 9728: root form and path-suffixed form.\n if (path === \"/.well-known/oauth-protected-resource\" || path === `/.well-known/oauth-protected-resource${MCP_PATH}`) {\n sendJson(res, 200, protectedResourceMetadata(), { \"Cache-Control\": \"public, max-age=300\" });\n return;\n }\n\n if (path === MCP_PATH) {\n if (req.method === \"POST\" || req.method === \"GET\" || req.method === \"DELETE\") {\n await handleMcp(req, res);\n return;\n }\n sendJson(res, 405, { error: \"method_not_allowed\" }, { Allow: \"GET, POST, DELETE, OPTIONS\" });\n return;\n }\n\n sendJson(res, 404, { error: \"not_found\" });\n});\n\nhttpServer.listen(PORT, () => {\n process.stderr.write(\n `[Wevi MCP HTTP] listening on :${PORT} → ${PUBLIC_URL}${MCP_PATH} (API ${API_URL}, issuer ${ISSUER})\\n`,\n );\n});\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAS,oBAA+D;AACxE,SAAS,iBAAiB;AAC1B,SAAS,qCAAqC;AAC9C,OAAO,YAAY;AAMnB,IAAM,WAAW,OAAO,KAAK,qBAAqB,QAAQ;AAC1D,IAAM,WAAW,OAAO,KAAK,qBAAqB,QAAQ;AAE1D,OAAO,OAAO;AAEd,IAAM,OAAO,OAAO,QAAQ,IAAI,QAAQ,IAAI;AAC5C,IAAM,WAAW,QAAQ,IAAI,gBAAgB,iCAAiC,QAAQ,QAAQ,EAAE;AAChG,IAAM,cAAc,QAAQ,IAAI,kBAAkB,oBAAoB,IAAI,IAAI,QAAQ,QAAQ,EAAE;AAChG,IAAM,UAAU,QAAQ,IAAI,gBAAgB,IAAI,IAAI,OAAO,EAAE,QAAQ,QAAQ,QAAQ,EAAE;AACvF,IAAM,WAAW;AACjB,IAAM,iBAAiB;AAEvB,IAAM,eAAuC;AAAA,EAC3C,+BAA+B;AAAA,EAC/B,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,iCAAiC;AAAA,EACjC,0BAA0B;AAC5B;AAEA,SAAS,SAAS,KAAqB,QAAgB,MAAe,QAAgC,CAAC,GAAG;AACxG,MAAI,UAAU,QAAQ,EAAE,gBAAgB,oBAAoB,GAAG,cAAc,GAAG,MAAM,CAAC;AACvF,MAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAC9B;AAEA,SAAS,4BAA4B;AACnC,SAAO;AAAA,IACL,UAAU,GAAG,UAAU,GAAG,QAAQ;AAAA,IAClC,uBAAuB,CAAC,MAAM;AAAA,IAC9B,0BAA0B,CAAC,QAAQ;AAAA,IACnC,kBAAkB,CAAC,MAAM;AAAA,IACzB,eAAe;AAAA,IACf,wBAAwB;AAAA,EAC1B;AACF;AAEA,SAAS,aAAa,KAAqB,aAAqB;AAC9D,QAAM,cAAc,GAAG,UAAU;AACjC;AAAA,IACE;AAAA,IACA;AAAA,IACA,EAAE,OAAO,gBAAgB,mBAAmB,YAAY;AAAA,IACxD,EAAE,oBAAoB,2CAA2C,WAAW,gDAAgD,WAAW,IAAI;AAAA,EAC7I;AACF;AAEA,eAAe,aAAa,KAAwC;AAClE,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,IAAK,QAAO,KAAK,KAAe;AAC1D,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AACjD,MAAI,CAAC,IAAI,KAAK,EAAG,QAAO;AACxB,SAAO,KAAK,MAAM,GAAG;AACvB;AAEA,SAAS,cAAc,KAAqC;AAC1D,QAAM,SAAS,IAAI,QAAQ;AAC3B,MAAI,CAAC,UAAU,MAAM,QAAQ,MAAM,EAAG,QAAO;AAC7C,QAAM,CAAC,QAAQ,KAAK,IAAI,OAAO,MAAM,GAAG;AACxC,MAAI,QAAQ,YAAY,MAAM,YAAY,CAAC,OAAO,KAAK,EAAG,QAAO;AACjE,SAAO,MAAM,KAAK;AACpB;AAGA,IAAM,aAAa,oBAAI,IAAgD;AACvE,IAAM,qBAAqB;AAE3B,eAAe,aAAa,OAAe,QAAyC;AAClF,QAAM,SAAS,WAAW,IAAI,KAAK;AACnC,MAAI,UAAU,OAAO,YAAY,KAAK,IAAI,EAAG,QAAO,OAAO;AAC3D,QAAM,KAAK,MAAM,OAAO,kBAAkB;AAC1C,aAAW,IAAI,OAAO,EAAE,IAAI,WAAW,KAAK,IAAI,KAAK,KAAK,qBAAqB,KAAO,CAAC;AACvF,MAAI,WAAW,OAAO,KAAO;AAC3B,eAAW,CAAC,KAAK,KAAK,KAAK,WAAY,KAAI,MAAM,aAAa,KAAK,IAAI,EAAG,YAAW,OAAO,GAAG;AAAA,EACjG;AACA,SAAO;AACT;AAEA,eAAe,UAAU,KAAsB,KAAqB;AAClE,QAAM,QAAQ,cAAc,GAAG;AAC/B,MAAI,CAAC,OAAO;AACV,iBAAa,KAAK,wCAAwC;AAC1D;AAAA,EACF;AAEA,QAAM,SAAS,IAAI,cAAc,EAAE,QAAQ,OAAO,QAAQ,QAAQ,CAAC;AAInE,MAAI,CAAE,MAAM,aAAa,OAAO,MAAM,GAAI;AACxC,iBAAa,KAAK,8EAA8E;AAChG;AAAA,EACF;AAEA,QAAM,SAAS,IAAI;AAAA,IACjB;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,OAAO,YAAY,UAAU;AAAA,IAC/B;AAAA,IACA,EAAE,cAAc,wBAAwB,EAAE;AAAA,EAC5C;AACA,mBAAiB,QAAQ,MAAM;AAE/B,QAAM,YAAY,IAAI,8BAA8B;AAAA,IAClD,oBAAoB;AAAA;AAAA,IACpB,oBAAoB;AAAA,EACtB,CAAC;AAED,MAAI,GAAG,SAAS,MAAM;AACpB,SAAK,UAAU,MAAM;AACrB,SAAK,OAAO,MAAM;AAAA,EACpB,CAAC;AAED,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,EAAG,KAAI,UAAU,KAAK,KAAK;AAEjF,MAAI;AACF,UAAM,OAAO,QAAQ,SAAS;AAC9B,UAAM,OAAO,IAAI,WAAW,SAAS,MAAM,aAAa,GAAG,IAAI;AAC/D,UAAM,UAAU,cAAc,KAAK,KAAK,IAAI;AAAA,EAC9C,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,YAAQ,OAAO,MAAM,mCAAmC,OAAO;AAAA,CAAI;AACnE,QAAI,CAAC,IAAI,aAAa;AACpB,eAAS,KAAK,KAAK,EAAE,SAAS,OAAO,OAAO,EAAE,MAAM,QAAQ,SAAS,wBAAwB,GAAG,IAAI,KAAK,CAAC;AAAA,IAC5G;AAAA,EACF;AACF;AAEA,IAAM,aAAa,aAAa,OAAO,KAAK,QAAQ;AAClD,QAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU;AAC9C,QAAM,OAAO,IAAI,SAAS,QAAQ,QAAQ,EAAE,KAAK;AAEjD,MAAI,IAAI,WAAW,WAAW;AAC5B,QAAI,UAAU,KAAK,YAAY;AAC/B,QAAI,IAAI;AACR;AAAA,EACF;AAEA,MAAI,SAAS,aAAa,SAAS,KAAK;AACtC,aAAS,KAAK,KAAK,EAAE,QAAQ,MAAM,MAAM,YAAY,SAAS,gBAAgB,WAAW,mBAAmB,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,CAAC;AAClJ;AAAA,EACF;AAGA,MAAI,SAAS,eAAe,SAAS,yBAAyB;AAC5D,QAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,iBAAiB,yBAAyB,GAAG,aAAa,CAAC;AAC7G,QAAI,IAAI,QAAQ;AAChB;AAAA,EACF;AACA,MAAI,SAAS,kBAAkB,SAAS,gBAAgB;AACtD,QAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,iBAAiB,yBAAyB,GAAG,aAAa,CAAC;AAC7G,QAAI,IAAI,QAAQ;AAChB;AAAA,EACF;AAGA,MAAI,SAAS,2CAA2C,SAAS,wCAAwC,QAAQ,IAAI;AACnH,aAAS,KAAK,KAAK,0BAA0B,GAAG,EAAE,iBAAiB,sBAAsB,CAAC;AAC1F;AAAA,EACF;AAEA,MAAI,SAAS,UAAU;AACrB,QAAI,IAAI,WAAW,UAAU,IAAI,WAAW,SAAS,IAAI,WAAW,UAAU;AAC5E,YAAM,UAAU,KAAK,GAAG;AACxB;AAAA,IACF;AACA,aAAS,KAAK,KAAK,EAAE,OAAO,qBAAqB,GAAG,EAAE,OAAO,6BAA6B,CAAC;AAC3F;AAAA,EACF;AAEA,WAAS,KAAK,KAAK,EAAE,OAAO,YAAY,CAAC;AAC3C,CAAC;AAED,WAAW,OAAO,MAAM,MAAM;AAC5B,UAAQ,OAAO;AAAA,IACb,iCAAiC,IAAI,WAAM,UAAU,GAAG,QAAQ,SAAS,OAAO,YAAY,MAAM;AAAA;AAAA,EACpG;AACF,CAAC;","names":[]}
|